input-ambiguity-detection 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- input_ambiguity_detection-0.1.0/CITATION.cff +47 -0
- input_ambiguity_detection-0.1.0/LICENSE +21 -0
- input_ambiguity_detection-0.1.0/MANIFEST.in +7 -0
- input_ambiguity_detection-0.1.0/PKG-INFO +239 -0
- input_ambiguity_detection-0.1.0/README.md +193 -0
- input_ambiguity_detection-0.1.0/blackbox/__init__.py +0 -0
- input_ambiguity_detection-0.1.0/blackbox/analyze_uq.py +669 -0
- input_ambiguity_detection-0.1.0/blackbox/compute_uq.py +400 -0
- input_ambiguity_detection-0.1.0/blackbox/llm_utils.py +277 -0
- input_ambiguity_detection-0.1.0/blackbox/perturbation_rules.py +848 -0
- input_ambiguity_detection-0.1.0/blackbox/run_llm_perturbation.py +655 -0
- input_ambiguity_detection-0.1.0/blackbox/run_paraphrase.py +351 -0
- input_ambiguity_detection-0.1.0/blackbox/run_perturbation.py +353 -0
- input_ambiguity_detection-0.1.0/input_ambiguity/__init__.py +10 -0
- input_ambiguity_detection-0.1.0/input_ambiguity/__main__.py +3 -0
- input_ambiguity_detection-0.1.0/input_ambiguity/cli.py +74 -0
- input_ambiguity_detection-0.1.0/input_ambiguity/quickstart.py +53 -0
- input_ambiguity_detection-0.1.0/input_ambiguity_detection.egg-info/PKG-INFO +239 -0
- input_ambiguity_detection-0.1.0/input_ambiguity_detection.egg-info/SOURCES.txt +43 -0
- input_ambiguity_detection-0.1.0/input_ambiguity_detection.egg-info/dependency_links.txt +1 -0
- input_ambiguity_detection-0.1.0/input_ambiguity_detection.egg-info/entry_points.txt +2 -0
- input_ambiguity_detection-0.1.0/input_ambiguity_detection.egg-info/requires.txt +33 -0
- input_ambiguity_detection-0.1.0/input_ambiguity_detection.egg-info/top_level.txt +1 -0
- input_ambiguity_detection-0.1.0/pyproject.toml +87 -0
- input_ambiguity_detection-0.1.0/quickstart/intermediate/pipeline_b_baseline_n10.json +16569 -0
- input_ambiguity_detection-0.1.0/quickstart/intermediate/pipeline_b_logit_lens.json +14224 -0
- input_ambiguity_detection-0.1.0/requirements.txt +28 -0
- input_ambiguity_detection-0.1.0/setup.cfg +4 -0
- input_ambiguity_detection-0.1.0/whitebox/__init__.py +0 -0
- input_ambiguity_detection-0.1.0/whitebox/pipeline/__init__.py +0 -0
- input_ambiguity_detection-0.1.0/whitebox/pipeline/compute_auroc.py +95 -0
- input_ambiguity_detection-0.1.0/whitebox/pipeline/compute_uq_from_checkpoint.py +268 -0
- input_ambiguity_detection-0.1.0/whitebox/pipeline/pipeline_b_perturb_and_uq.py +1258 -0
- input_ambiguity_detection-0.1.0/whitebox/pipeline/pipeline_b_perturb_and_uq_vl.py +766 -0
- input_ambiguity_detection-0.1.0/whitebox/text/__init__.py +0 -0
- input_ambiguity_detection-0.1.0/whitebox/text/attribution_utils.py +330 -0
- input_ambiguity_detection-0.1.0/whitebox/text/diffmask_uncertainty.py +755 -0
- input_ambiguity_detection-0.1.0/whitebox/text/gradient_attribution.py +440 -0
- input_ambiguity_detection-0.1.0/whitebox/text/logit_lens_uncertainty.py +605 -0
- input_ambiguity_detection-0.1.0/whitebox/text/normalize_attributions.py +106 -0
- input_ambiguity_detection-0.1.0/whitebox/vision/__init__.py +0 -0
- input_ambiguity_detection-0.1.0/whitebox/vision/diffmask_uncertainty.py +318 -0
- input_ambiguity_detection-0.1.0/whitebox/vision/gradient_attribution.py +252 -0
- input_ambiguity_detection-0.1.0/whitebox/vision/logit_lens_uncertainty.py +367 -0
- input_ambiguity_detection-0.1.0/whitebox/vision/vl_attribution_utils.py +342 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
title: "Detect Before You Disambiguate: Perturbation-Based Input Ambiguity Detection in LLMs"
|
|
3
|
+
message: "If you use this code in your research, please cite the AACL 2026 paper."
|
|
4
|
+
type: software
|
|
5
|
+
authors:
|
|
6
|
+
- family-names: Chen
|
|
7
|
+
given-names: Tiejin
|
|
8
|
+
- family-names: Liu
|
|
9
|
+
given-names: Xiaoou
|
|
10
|
+
- family-names: Clifford
|
|
11
|
+
given-names: Michael
|
|
12
|
+
- family-names: Moradipari
|
|
13
|
+
given-names: Ahmadreza
|
|
14
|
+
- family-names: Chen
|
|
15
|
+
given-names: Yitao
|
|
16
|
+
- family-names: Han
|
|
17
|
+
given-names: Kyungtae
|
|
18
|
+
- family-names: Ammar
|
|
19
|
+
given-names: Nejib
|
|
20
|
+
- family-names: Wei
|
|
21
|
+
given-names: Hua
|
|
22
|
+
year: 2026
|
|
23
|
+
repository-code: "https://github.com/Xiao0o0o/input-ambiguity-detection"
|
|
24
|
+
license: MIT
|
|
25
|
+
preferred-citation:
|
|
26
|
+
type: conference-paper
|
|
27
|
+
title: "Detect Before You Disambiguate: Perturbation-Based Input Ambiguity Detection in LLMs"
|
|
28
|
+
authors:
|
|
29
|
+
- family-names: Chen
|
|
30
|
+
given-names: Tiejin
|
|
31
|
+
- family-names: Liu
|
|
32
|
+
given-names: Xiaoou
|
|
33
|
+
- family-names: Clifford
|
|
34
|
+
given-names: Michael
|
|
35
|
+
- family-names: Moradipari
|
|
36
|
+
given-names: Ahmadreza
|
|
37
|
+
- family-names: Chen
|
|
38
|
+
given-names: Yitao
|
|
39
|
+
- family-names: Han
|
|
40
|
+
given-names: Kyungtae
|
|
41
|
+
- family-names: Ammar
|
|
42
|
+
given-names: Nejib
|
|
43
|
+
- family-names: Wei
|
|
44
|
+
given-names: Hua
|
|
45
|
+
year: 2026
|
|
46
|
+
conference:
|
|
47
|
+
name: "The Asia-Pacific Chapter of the Association for Computational Linguistics (AACL 2026)"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tiejin Chen, Xiaoou Liu, Michael Clifford, Ahmadreza Moradipari, Yitao Chen, Kyungtae Han, Nejib Ammar, and Hua Wei
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
include LICENSE README.md CITATION.cff requirements.txt
|
|
2
|
+
prune data
|
|
3
|
+
prune quickstart
|
|
4
|
+
include quickstart/intermediate/pipeline_b_logit_lens.json quickstart/intermediate/pipeline_b_baseline_n10.json
|
|
5
|
+
prune tests
|
|
6
|
+
prune scripts
|
|
7
|
+
global-exclude __pycache__ *.py[cod]
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: input-ambiguity-detection
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Perturbation-based input ambiguity detection for LLMs (white-box and black-box detectors, AACL 2026)
|
|
5
|
+
Author: Tiejin Chen, Xiaoou Liu, Michael Clifford, Ahmadreza Moradipari, Yitao Chen, Kyungtae Han, Nejib Ammar, Hua Wei
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Repository, https://github.com/Xiao0o0o/input-ambiguity-detection
|
|
8
|
+
Project-URL: Issues, https://github.com/Xiao0o0o/input-ambiguity-detection/issues
|
|
9
|
+
Keywords: llm,ambiguity,uncertainty quantification,perturbation,question answering
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: torch
|
|
18
|
+
Requires-Dist: transformers
|
|
19
|
+
Requires-Dist: accelerate
|
|
20
|
+
Requires-Dist: numpy
|
|
21
|
+
Requires-Dist: scipy
|
|
22
|
+
Requires-Dist: scikit-learn
|
|
23
|
+
Requires-Dist: nltk
|
|
24
|
+
Requires-Dist: pillow
|
|
25
|
+
Requires-Dist: tqdm
|
|
26
|
+
Provides-Extra: blackbox
|
|
27
|
+
Requires-Dist: vllm; extra == "blackbox"
|
|
28
|
+
Requires-Dist: lm-polygraph; extra == "blackbox"
|
|
29
|
+
Requires-Dist: spacy; extra == "blackbox"
|
|
30
|
+
Requires-Dist: lemminflect; extra == "blackbox"
|
|
31
|
+
Requires-Dist: matplotlib; extra == "blackbox"
|
|
32
|
+
Provides-Extra: int8
|
|
33
|
+
Requires-Dist: bitsandbytes; extra == "int8"
|
|
34
|
+
Provides-Extra: data
|
|
35
|
+
Requires-Dist: datasets; extra == "data"
|
|
36
|
+
Requires-Dist: httpx; extra == "data"
|
|
37
|
+
Provides-Extra: all
|
|
38
|
+
Requires-Dist: input-ambiguity-detection[blackbox,data,int8]; extra == "all"
|
|
39
|
+
Provides-Extra: dev
|
|
40
|
+
Requires-Dist: pytest; extra == "dev"
|
|
41
|
+
Requires-Dist: build; extra == "dev"
|
|
42
|
+
Requires-Dist: twine; extra == "dev"
|
|
43
|
+
Requires-Dist: spacy; extra == "dev"
|
|
44
|
+
Requires-Dist: lemminflect; extra == "dev"
|
|
45
|
+
Dynamic: license-file
|
|
46
|
+
|
|
47
|
+
# Detect Before You Disambiguate: Perturbation-Based Input Ambiguity Detection in LLMs
|
|
48
|
+
|
|
49
|
+
[](https://pypi.org/project/input-ambiguity-detection/)
|
|
50
|
+
[](https://www.python.org/)
|
|
51
|
+
[](LICENSE)
|
|
52
|
+
[](https://github.com/Xiao0o0o/input-ambiguity-detection/actions/workflows/ci.yml)
|
|
53
|
+
|
|
54
|
+
Code and data for the AACL 2026 paper **"Detect Before You Disambiguate: Perturbation-Based Input Ambiguity Detection in LLMs"** by Tiejin Chen\*, Xiaoou Liu\*, Michael Clifford, Ahmadreza Moradipari, Yitao Chen, Kyungtae Han, Nejib Ammar and Hua Wei (\*equal contribution).
|
|
55
|
+
|
|
56
|
+
## Overview
|
|
57
|
+
|
|
58
|
+
LLMs often answer an ambiguous question as if it had a single meaning. A common way to detect ambiguity is to have an LLM paraphrase or clarify the question and measure how much the answers disagree. But to rephrase a question the model must first understand it, and understanding an ambiguous question means picking one reading. The rewrite can remove the very ambiguity it is meant to measure.
|
|
59
|
+
|
|
60
|
+
We instead perturb the input with **low-capacity, label-preserving, semantics-blind** edits. These are small surface changes that never choose an interpretation. We then measure how much the model's answers spread across the original and perturbed questions. Two detectors implement this:
|
|
61
|
+
|
|
62
|
+
| detector | access | how it perturbs | code |
|
|
63
|
+
|---|---|---|---|
|
|
64
|
+
| **White-box** | model internals | Vanilla Gradient, Logit Lens or DiffMask ranks the input tokens; the top-3 question words are replaced by WordNet synonyms | [`whitebox/`](whitebox/) |
|
|
65
|
+
| **Black-box** | text in, text out | a fixed library of 11 rules: POS-constrained WordNet synonyms, contraction expand/contract, register prefixes, wh-word templates | [`blackbox/`](blackbox/) |
|
|
66
|
+
|
|
67
|
+
Both pool the answers to the original and perturbed questions. An NLI model (`microsoft/deberta-large-mnli`) builds an agreement matrix over them, and **EigV(Agree)**, the eigenvalue dispersion of its graph Laplacian, is the ambiguity score. A higher score means a more likely ambiguous question.
|
|
68
|
+
|
|
69
|
+
## Repository layout
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
.
|
|
73
|
+
├── data/ # the four evaluation sets (shared by both detectors)
|
|
74
|
+
│ ├── abg_coqa_200_input.json # ABG-CoQA, 200 items (100 ambiguous / 100 not)
|
|
75
|
+
│ ├── abg_coqa_200_blackbox.json # the same 200 items in the original ABG-CoQA format (black-box input)
|
|
76
|
+
│ ├── ambigqa_with_ctx_500_input.json # AmbigQA + Wikipedia context, 500 items (250 / 250)
|
|
77
|
+
│ ├── aqua_720_input.json # AQuA, 720 items (540 / 180)
|
|
78
|
+
│ ├── vqfa_720_input.json # VQ-FocusAmbiguity, 720 items (422 / 298)
|
|
79
|
+
│ └── build/ # scripts that built these files (+ images for AQuA / VQ-FA)
|
|
80
|
+
├── whitebox/ # white-box detector → see whitebox/README.md
|
|
81
|
+
│ ├── text/ vision/ # Vanilla Gradient, Logit Lens, DiffMask attribution
|
|
82
|
+
│ └── pipeline/ # top-k WordNet perturbation, generation, NLI UQ, AUROC
|
|
83
|
+
├── blackbox/ # black-box detector → see blackbox/README.md
|
|
84
|
+
│ ├── perturbation_rules.py # the 11-rule library
|
|
85
|
+
│ ├── run_perturbation.py # rules → vLLM sampling
|
|
86
|
+
│ ├── compute_uq.py analyze_uq.py # NLI UQ (per variant / pooled) → AUROC + plots
|
|
87
|
+
│ └── run_llm_perturbation.py run_paraphrase.py # LLM-executed rules (ablation), LLM paraphrase baseline
|
|
88
|
+
├── scripts/ # one command per (model, dataset)
|
|
89
|
+
│ ├── run_whitebox_text.sh run_whitebox_vision.sh
|
|
90
|
+
│ └── run_blackbox.sh
|
|
91
|
+
├── quickstart/ # every intermediate file of one paper run + a resumable script
|
|
92
|
+
├── input_ambiguity/ # package entry point: the `input-ambiguity` CLI
|
|
93
|
+
├── tests/
|
|
94
|
+
├── pyproject.toml # PyPI package (installs whitebox/ and blackbox/ as input_ambiguity.*)
|
|
95
|
+
└── requirements.txt # full environment for both detectors
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Installation
|
|
99
|
+
|
|
100
|
+
From PyPI:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
pip install input-ambiguity-detection # white-box detector, NLI scoring, AUROC
|
|
104
|
+
pip install "input-ambiguity-detection[blackbox]" # + black-box detector (vLLM, lm-polygraph, spaCy)
|
|
105
|
+
pip install "input-ambiguity-detection[all]" # + INT8 DiffMask (bitsandbytes) and data/build/* deps
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
From source, with the data, quick start and shell scripts (recommended to reproduce the paper):
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
git clone https://github.com/Xiao0o0o/input-ambiguity-detection.git
|
|
112
|
+
cd input-ambiguity-detection
|
|
113
|
+
pip install -r requirements.txt # exact versions used for the release checks
|
|
114
|
+
pip install -e . --no-deps # optional: also installs the `input-ambiguity` command
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Then:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
python -m spacy download en_core_web_sm # POS tags for the black-box rules
|
|
121
|
+
export HF_CACHE_DIR=/path/to/hf_cache # optional; HF default cache otherwise
|
|
122
|
+
export HF_TOKEN=... # for meta-llama/Llama-3.1-8B-Instruct and google/gemma-3-*
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
NLTK downloads WordNet and the POS tagger on first use (`make nltk-data` fetches them up front).
|
|
126
|
+
|
|
127
|
+
Every script is also available through the installed command, with the same arguments:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
input-ambiguity --help # list of commands
|
|
131
|
+
input-ambiguity rules # black-box rule variants for a few sample questions
|
|
132
|
+
input-ambiguity bb-perturb --help # = python blackbox/run_perturbation.py --help
|
|
133
|
+
input-ambiguity wb-vision-logit-lens --help # = python whitebox/vision/logit_lens_uncertainty.py --help
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Quick start
|
|
137
|
+
|
|
138
|
+
The quick start is one paper run: the white-box detector on AQuA with Qwen2.5-VL-3B-Instruct. Its per-question scores are stored, so the paper's AUROC can be checked on a CPU in seconds, in either of two ways.
|
|
139
|
+
|
|
140
|
+
**Option A: with the PyPI package** (no clone, no GPU, no model download; the scores ship with the package)
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
pip install input-ambiguity-detection
|
|
144
|
+
input-ambiguity quickstart
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Option B: with the code in this repository**
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
git clone https://github.com/Xiao0o0o/input-ambiguity-detection.git
|
|
151
|
+
cd input-ambiguity-detection
|
|
152
|
+
pip install -r requirements.txt
|
|
153
|
+
bash quickstart/run_quickstart.sh # or: make quick-eval
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
| setting | |
|
|
157
|
+
|---|---|
|
|
158
|
+
| model | Qwen2.5-VL-3B-Instruct |
|
|
159
|
+
| dataset | AQuA, 720 visual questions (540 ambiguous / 180 unambiguous) |
|
|
160
|
+
| detector | white-box, Logit Lens importance, top-3 words → WordNet synonyms (up to 4 variants) |
|
|
161
|
+
| sampling | original: 1 greedy + 2 sampled (T=0.5, top-p 0.9); each variant: 1 greedy |
|
|
162
|
+
| score | EigV(Agree), `microsoft/deberta-large-mnli` |
|
|
163
|
+
|
|
164
|
+
| method | quick-start AUROC | paper (Table 1) |
|
|
165
|
+
|---|---|---|
|
|
166
|
+
| EigV(Agree) baseline (K=10 samples, no perturbation) | 0.6435 | 0.644 |
|
|
167
|
+
| **Ours (White-Box, Logit Lens)** | **0.7083** | **0.708** |
|
|
168
|
+
|
|
169
|
+
Both options give the numbers above, which match the paper. Option B also stores every intermediate file of the run (attribution, perturbations, answers), and the same script resumes from any earlier stage: `uq` (recompute NLI from the stored answers), `generate`, `perturb` or `attribution` (from scratch), e.g. `bash quickstart/run_quickstart.sh uq`. Expected deviations when re-running those stages are listed in [`quickstart/README.md`](quickstart/README.md).
|
|
170
|
+
|
|
171
|
+
To see what the black-box rules do to a question, without a model:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
python blackbox/perturbation_rules.py
|
|
175
|
+
python blackbox/run_perturbation.py --dry_run --input_path data/abg_coqa_200_blackbox.json --output_path variants.json
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Running the detectors
|
|
179
|
+
|
|
180
|
+
**White-box**: attribution → top-3 words → WordNet perturbation → sampling → NLI UQ → AUROC, for all three importance methods and the K=10 EigV(Agree) baseline:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
bash scripts/run_whitebox_text.sh Qwen/Qwen3-4B-Instruct-2507 data/abg_coqa_200_input.json results/qwen3_abg
|
|
184
|
+
bash scripts/run_whitebox_text.sh meta-llama/Llama-3.1-8B-Instruct data/ambigqa_with_ctx_500_input.json results/llama_ambigqa
|
|
185
|
+
bash scripts/run_whitebox_vision.sh Qwen/Qwen2.5-VL-3B-Instruct data/aqua_720_input.json results/qwenvl_aqua
|
|
186
|
+
bash scripts/run_whitebox_vision.sh OpenGVLab/InternVL3-8B-hf data/vqfa_720_input.json results/internvl_vqfa
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
The vision inputs need the AQuA / VQ-FA images: `python data/build/build_aqua_input.py` downloads AQuA, and `VQFA_ROOT=... python data/build/build_vqfa_input.py` builds VQ-FA from its release. Settings, output files, the two EigV variants and memory notes are documented in [`whitebox/README.md`](whitebox/README.md).
|
|
190
|
+
|
|
191
|
+
**Black-box**: 11 rules → N samples per variant (vLLM) → NLI UQ per variant and pooled → AUROC per rule and pooled:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
bash scripts/run_blackbox.sh Qwen/Qwen3-4B-Instruct-2507 data/abg_coqa_200_blackbox.json results/blackbox_qwen3_abg
|
|
195
|
+
bash scripts/run_blackbox.sh meta-llama/Llama-3.1-8B-Instruct data/abg_coqa_200_blackbox.json results/blackbox_llama_abg
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
The detector's score is the cross-variant (`CROSS`) `EigValLaplacian_NLI_entail` AUROC in `results/.../analysis/uq_statistics.json`; the per-rule AUROCs correspond to Figure 3. The LLM-executed-rules ablation (Table 4) and the LLM-paraphrase baseline are in [`blackbox/README.md`](blackbox/README.md).
|
|
199
|
+
|
|
200
|
+
## Data
|
|
201
|
+
|
|
202
|
+
| dataset | type | items (amb / unamb) | source |
|
|
203
|
+
|---|---|---|---|
|
|
204
|
+
| ABG-CoQA | conversational QA | 200 (100 / 100) | [Guo et al., 2021](https://github.com/MeiqiGuo/AKBC2021-Abg-CoQA) |
|
|
205
|
+
| AmbigQA-w-Ctx | open-domain QA + Wikipedia passage | 500 (250 / 250) | [Min et al., 2020](https://huggingface.co/datasets/sewon/ambig_qa) |
|
|
206
|
+
| AQuA | visual QA | 720 (540 / 180) | [Jang and Kim, 2026](https://huggingface.co/datasets/jihyoung/AQuA) |
|
|
207
|
+
| VQ-FA | visual QA (focus ambiguity) | 720 (422 / 298) | Chen et al., 2025 (VQ-FocusAmbiguity release) |
|
|
208
|
+
|
|
209
|
+
All question files are included in `data/`, and `data/build/` holds the scripts that created them. Please also follow the licenses of the original datasets.
|
|
210
|
+
|
|
211
|
+
## Hardware
|
|
212
|
+
|
|
213
|
+
The quick-start AUROC and the unit tests run on a CPU. Our experiments ran on a single NVIDIA A100 80 GB. Gemma-3-27B's DiffMask attribution uses INT8 weights through bitsandbytes, which `scripts/run_whitebox_text.sh` turns on automatically for 27B models.
|
|
214
|
+
|
|
215
|
+
## Tests
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
pip install -e ".[dev]"
|
|
219
|
+
make check # compileall + pytest + quick-start AUROC
|
|
220
|
+
make dist-check # build the PyPI sdist / wheel and run twine check
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
The tests cover the black-box rule library, the shared prompt/data helpers, the EigV implementations, and the quick-start AUROC against the paper's numbers.
|
|
224
|
+
|
|
225
|
+
## Citation
|
|
226
|
+
|
|
227
|
+
```bibtex
|
|
228
|
+
@inproceedings{chen2026detect,
|
|
229
|
+
title = {Detect Before You Disambiguate: Perturbation-Based Input Ambiguity Detection in {LLMs}},
|
|
230
|
+
author = {Chen, Tiejin and Liu, Xiaoou and Clifford, Michael and Moradipari, Ahmadreza and
|
|
231
|
+
Chen, Yitao and Han, Kyungtae and Ammar, Nejib and Wei, Hua},
|
|
232
|
+
booktitle = {Proceedings of the Asia-Pacific Chapter of the Association for Computational Linguistics (AACL)},
|
|
233
|
+
year = {2026}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## License
|
|
238
|
+
|
|
239
|
+
MIT License, see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Detect Before You Disambiguate: Perturbation-Based Input Ambiguity Detection in LLMs
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/input-ambiguity-detection/)
|
|
4
|
+
[](https://www.python.org/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://github.com/Xiao0o0o/input-ambiguity-detection/actions/workflows/ci.yml)
|
|
7
|
+
|
|
8
|
+
Code and data for the AACL 2026 paper **"Detect Before You Disambiguate: Perturbation-Based Input Ambiguity Detection in LLMs"** by Tiejin Chen\*, Xiaoou Liu\*, Michael Clifford, Ahmadreza Moradipari, Yitao Chen, Kyungtae Han, Nejib Ammar and Hua Wei (\*equal contribution).
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
LLMs often answer an ambiguous question as if it had a single meaning. A common way to detect ambiguity is to have an LLM paraphrase or clarify the question and measure how much the answers disagree. But to rephrase a question the model must first understand it, and understanding an ambiguous question means picking one reading. The rewrite can remove the very ambiguity it is meant to measure.
|
|
13
|
+
|
|
14
|
+
We instead perturb the input with **low-capacity, label-preserving, semantics-blind** edits. These are small surface changes that never choose an interpretation. We then measure how much the model's answers spread across the original and perturbed questions. Two detectors implement this:
|
|
15
|
+
|
|
16
|
+
| detector | access | how it perturbs | code |
|
|
17
|
+
|---|---|---|---|
|
|
18
|
+
| **White-box** | model internals | Vanilla Gradient, Logit Lens or DiffMask ranks the input tokens; the top-3 question words are replaced by WordNet synonyms | [`whitebox/`](whitebox/) |
|
|
19
|
+
| **Black-box** | text in, text out | a fixed library of 11 rules: POS-constrained WordNet synonyms, contraction expand/contract, register prefixes, wh-word templates | [`blackbox/`](blackbox/) |
|
|
20
|
+
|
|
21
|
+
Both pool the answers to the original and perturbed questions. An NLI model (`microsoft/deberta-large-mnli`) builds an agreement matrix over them, and **EigV(Agree)**, the eigenvalue dispersion of its graph Laplacian, is the ambiguity score. A higher score means a more likely ambiguous question.
|
|
22
|
+
|
|
23
|
+
## Repository layout
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
.
|
|
27
|
+
├── data/ # the four evaluation sets (shared by both detectors)
|
|
28
|
+
│ ├── abg_coqa_200_input.json # ABG-CoQA, 200 items (100 ambiguous / 100 not)
|
|
29
|
+
│ ├── abg_coqa_200_blackbox.json # the same 200 items in the original ABG-CoQA format (black-box input)
|
|
30
|
+
│ ├── ambigqa_with_ctx_500_input.json # AmbigQA + Wikipedia context, 500 items (250 / 250)
|
|
31
|
+
│ ├── aqua_720_input.json # AQuA, 720 items (540 / 180)
|
|
32
|
+
│ ├── vqfa_720_input.json # VQ-FocusAmbiguity, 720 items (422 / 298)
|
|
33
|
+
│ └── build/ # scripts that built these files (+ images for AQuA / VQ-FA)
|
|
34
|
+
├── whitebox/ # white-box detector → see whitebox/README.md
|
|
35
|
+
│ ├── text/ vision/ # Vanilla Gradient, Logit Lens, DiffMask attribution
|
|
36
|
+
│ └── pipeline/ # top-k WordNet perturbation, generation, NLI UQ, AUROC
|
|
37
|
+
├── blackbox/ # black-box detector → see blackbox/README.md
|
|
38
|
+
│ ├── perturbation_rules.py # the 11-rule library
|
|
39
|
+
│ ├── run_perturbation.py # rules → vLLM sampling
|
|
40
|
+
│ ├── compute_uq.py analyze_uq.py # NLI UQ (per variant / pooled) → AUROC + plots
|
|
41
|
+
│ └── run_llm_perturbation.py run_paraphrase.py # LLM-executed rules (ablation), LLM paraphrase baseline
|
|
42
|
+
├── scripts/ # one command per (model, dataset)
|
|
43
|
+
│ ├── run_whitebox_text.sh run_whitebox_vision.sh
|
|
44
|
+
│ └── run_blackbox.sh
|
|
45
|
+
├── quickstart/ # every intermediate file of one paper run + a resumable script
|
|
46
|
+
├── input_ambiguity/ # package entry point: the `input-ambiguity` CLI
|
|
47
|
+
├── tests/
|
|
48
|
+
├── pyproject.toml # PyPI package (installs whitebox/ and blackbox/ as input_ambiguity.*)
|
|
49
|
+
└── requirements.txt # full environment for both detectors
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
From PyPI:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install input-ambiguity-detection # white-box detector, NLI scoring, AUROC
|
|
58
|
+
pip install "input-ambiguity-detection[blackbox]" # + black-box detector (vLLM, lm-polygraph, spaCy)
|
|
59
|
+
pip install "input-ambiguity-detection[all]" # + INT8 DiffMask (bitsandbytes) and data/build/* deps
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
From source, with the data, quick start and shell scripts (recommended to reproduce the paper):
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
git clone https://github.com/Xiao0o0o/input-ambiguity-detection.git
|
|
66
|
+
cd input-ambiguity-detection
|
|
67
|
+
pip install -r requirements.txt # exact versions used for the release checks
|
|
68
|
+
pip install -e . --no-deps # optional: also installs the `input-ambiguity` command
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Then:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
python -m spacy download en_core_web_sm # POS tags for the black-box rules
|
|
75
|
+
export HF_CACHE_DIR=/path/to/hf_cache # optional; HF default cache otherwise
|
|
76
|
+
export HF_TOKEN=... # for meta-llama/Llama-3.1-8B-Instruct and google/gemma-3-*
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
NLTK downloads WordNet and the POS tagger on first use (`make nltk-data` fetches them up front).
|
|
80
|
+
|
|
81
|
+
Every script is also available through the installed command, with the same arguments:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
input-ambiguity --help # list of commands
|
|
85
|
+
input-ambiguity rules # black-box rule variants for a few sample questions
|
|
86
|
+
input-ambiguity bb-perturb --help # = python blackbox/run_perturbation.py --help
|
|
87
|
+
input-ambiguity wb-vision-logit-lens --help # = python whitebox/vision/logit_lens_uncertainty.py --help
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Quick start
|
|
91
|
+
|
|
92
|
+
The quick start is one paper run: the white-box detector on AQuA with Qwen2.5-VL-3B-Instruct. Its per-question scores are stored, so the paper's AUROC can be checked on a CPU in seconds, in either of two ways.
|
|
93
|
+
|
|
94
|
+
**Option A: with the PyPI package** (no clone, no GPU, no model download; the scores ship with the package)
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
pip install input-ambiguity-detection
|
|
98
|
+
input-ambiguity quickstart
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Option B: with the code in this repository**
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
git clone https://github.com/Xiao0o0o/input-ambiguity-detection.git
|
|
105
|
+
cd input-ambiguity-detection
|
|
106
|
+
pip install -r requirements.txt
|
|
107
|
+
bash quickstart/run_quickstart.sh # or: make quick-eval
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
| setting | |
|
|
111
|
+
|---|---|
|
|
112
|
+
| model | Qwen2.5-VL-3B-Instruct |
|
|
113
|
+
| dataset | AQuA, 720 visual questions (540 ambiguous / 180 unambiguous) |
|
|
114
|
+
| detector | white-box, Logit Lens importance, top-3 words → WordNet synonyms (up to 4 variants) |
|
|
115
|
+
| sampling | original: 1 greedy + 2 sampled (T=0.5, top-p 0.9); each variant: 1 greedy |
|
|
116
|
+
| score | EigV(Agree), `microsoft/deberta-large-mnli` |
|
|
117
|
+
|
|
118
|
+
| method | quick-start AUROC | paper (Table 1) |
|
|
119
|
+
|---|---|---|
|
|
120
|
+
| EigV(Agree) baseline (K=10 samples, no perturbation) | 0.6435 | 0.644 |
|
|
121
|
+
| **Ours (White-Box, Logit Lens)** | **0.7083** | **0.708** |
|
|
122
|
+
|
|
123
|
+
Both options give the numbers above, which match the paper. Option B also stores every intermediate file of the run (attribution, perturbations, answers), and the same script resumes from any earlier stage: `uq` (recompute NLI from the stored answers), `generate`, `perturb` or `attribution` (from scratch), e.g. `bash quickstart/run_quickstart.sh uq`. Expected deviations when re-running those stages are listed in [`quickstart/README.md`](quickstart/README.md).
|
|
124
|
+
|
|
125
|
+
To see what the black-box rules do to a question, without a model:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
python blackbox/perturbation_rules.py
|
|
129
|
+
python blackbox/run_perturbation.py --dry_run --input_path data/abg_coqa_200_blackbox.json --output_path variants.json
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Running the detectors
|
|
133
|
+
|
|
134
|
+
**White-box**: attribution → top-3 words → WordNet perturbation → sampling → NLI UQ → AUROC, for all three importance methods and the K=10 EigV(Agree) baseline:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
bash scripts/run_whitebox_text.sh Qwen/Qwen3-4B-Instruct-2507 data/abg_coqa_200_input.json results/qwen3_abg
|
|
138
|
+
bash scripts/run_whitebox_text.sh meta-llama/Llama-3.1-8B-Instruct data/ambigqa_with_ctx_500_input.json results/llama_ambigqa
|
|
139
|
+
bash scripts/run_whitebox_vision.sh Qwen/Qwen2.5-VL-3B-Instruct data/aqua_720_input.json results/qwenvl_aqua
|
|
140
|
+
bash scripts/run_whitebox_vision.sh OpenGVLab/InternVL3-8B-hf data/vqfa_720_input.json results/internvl_vqfa
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
The vision inputs need the AQuA / VQ-FA images: `python data/build/build_aqua_input.py` downloads AQuA, and `VQFA_ROOT=... python data/build/build_vqfa_input.py` builds VQ-FA from its release. Settings, output files, the two EigV variants and memory notes are documented in [`whitebox/README.md`](whitebox/README.md).
|
|
144
|
+
|
|
145
|
+
**Black-box**: 11 rules → N samples per variant (vLLM) → NLI UQ per variant and pooled → AUROC per rule and pooled:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
bash scripts/run_blackbox.sh Qwen/Qwen3-4B-Instruct-2507 data/abg_coqa_200_blackbox.json results/blackbox_qwen3_abg
|
|
149
|
+
bash scripts/run_blackbox.sh meta-llama/Llama-3.1-8B-Instruct data/abg_coqa_200_blackbox.json results/blackbox_llama_abg
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The detector's score is the cross-variant (`CROSS`) `EigValLaplacian_NLI_entail` AUROC in `results/.../analysis/uq_statistics.json`; the per-rule AUROCs correspond to Figure 3. The LLM-executed-rules ablation (Table 4) and the LLM-paraphrase baseline are in [`blackbox/README.md`](blackbox/README.md).
|
|
153
|
+
|
|
154
|
+
## Data
|
|
155
|
+
|
|
156
|
+
| dataset | type | items (amb / unamb) | source |
|
|
157
|
+
|---|---|---|---|
|
|
158
|
+
| ABG-CoQA | conversational QA | 200 (100 / 100) | [Guo et al., 2021](https://github.com/MeiqiGuo/AKBC2021-Abg-CoQA) |
|
|
159
|
+
| AmbigQA-w-Ctx | open-domain QA + Wikipedia passage | 500 (250 / 250) | [Min et al., 2020](https://huggingface.co/datasets/sewon/ambig_qa) |
|
|
160
|
+
| AQuA | visual QA | 720 (540 / 180) | [Jang and Kim, 2026](https://huggingface.co/datasets/jihyoung/AQuA) |
|
|
161
|
+
| VQ-FA | visual QA (focus ambiguity) | 720 (422 / 298) | Chen et al., 2025 (VQ-FocusAmbiguity release) |
|
|
162
|
+
|
|
163
|
+
All question files are included in `data/`, and `data/build/` holds the scripts that created them. Please also follow the licenses of the original datasets.
|
|
164
|
+
|
|
165
|
+
## Hardware
|
|
166
|
+
|
|
167
|
+
The quick-start AUROC and the unit tests run on a CPU. Our experiments ran on a single NVIDIA A100 80 GB. Gemma-3-27B's DiffMask attribution uses INT8 weights through bitsandbytes, which `scripts/run_whitebox_text.sh` turns on automatically for 27B models.
|
|
168
|
+
|
|
169
|
+
## Tests
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
pip install -e ".[dev]"
|
|
173
|
+
make check # compileall + pytest + quick-start AUROC
|
|
174
|
+
make dist-check # build the PyPI sdist / wheel and run twine check
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
The tests cover the black-box rule library, the shared prompt/data helpers, the EigV implementations, and the quick-start AUROC against the paper's numbers.
|
|
178
|
+
|
|
179
|
+
## Citation
|
|
180
|
+
|
|
181
|
+
```bibtex
|
|
182
|
+
@inproceedings{chen2026detect,
|
|
183
|
+
title = {Detect Before You Disambiguate: Perturbation-Based Input Ambiguity Detection in {LLMs}},
|
|
184
|
+
author = {Chen, Tiejin and Liu, Xiaoou and Clifford, Michael and Moradipari, Ahmadreza and
|
|
185
|
+
Chen, Yitao and Han, Kyungtae and Ammar, Nejib and Wei, Hua},
|
|
186
|
+
booktitle = {Proceedings of the Asia-Pacific Chapter of the Association for Computational Linguistics (AACL)},
|
|
187
|
+
year = {2026}
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## License
|
|
192
|
+
|
|
193
|
+
MIT License, see [LICENSE](LICENSE).
|
|
File without changes
|