← Report

Mirage probes: full tables and sources

Every number behind the report, with its notebook cell or run log.

Zachary Gunderson · October 2026

Summary

Vision-language models often answer an image question with no image attached and never say the image is missing; Ben-Levi et al. call this a mirage and show it is linearly readable from the model's activations. This project recreates their probes on Qwen3-VL-4B-Instruct, moves the test to open-ended medical questions (SLAKE), and tries to steer the model toward abstaining. On VQA-RAD, a probe on the no-image reply text alone scores 0.900–0.925, close to the paper-style Diff probe (0.915–0.937 here, 0.96 in the paper), because the reply holds the admission words that define the label; before any reply token exists, the state gives 0.667–0.744. On 85 held-out SLAKE texts, an honesty instruction cut no-image mirages from 0.365 to 0.094 and a mirage→abstain vector cut them to 0.059, mostly into hedged answers; in later unreviewed runs on top of the prompt, shuffled-label and random controls lowered mirages too (0.070 and 0.039 against 0.079 for the prompt alone), so direction and push size are not yet separated. Test sets are small (85–114 texts), outcome labels come from a regex, and the Sep 30 – Oct 4 steering runs are not reviewed in any notebook. For monitoring VLMs, a probe that reads the model's own reply mostly re-reads the label and the pre-answer signal is real but modest; Cosmos-Reason2-2B, a robotics reasoning model built on Qwen3-VL-2B, mirages on 0.96 of test texts without the image (unreviewed run).

Credit. The method, code and VQA-RAD setup are Ben-Levi et al.'s. That covers the contrastive mirage probes, the with-minus-without-image Diff probe, the response generator, system prompt, GPT-4o-mini paraphrases and regex labels. Their code is included unmodified as a submodule. New here: the recreation on Qwen3-VL-4B-Instruct (the paper used Qwen3-VL-32B and Ovis2.5-2B), a fix to the mirage label, the extension to SLAKE, steering toward abstention, and the controls (no-image echo probe, text-only prior, question-type centring, shuffled and random arms).

Recreation of Ben-Levi et al., Mirage Probes: How Vision Models Fake Visual Understanding (arXiv 2606.13870); upstream code danielbenlevi/mirage_probes @ 06c8d2d. Model: Qwen3-VL-4B-Instruct.

Part 1 — Recreation on Qwen3-VL-4B (VQA-RAD; MedXpertQA-MM)

The paper's generator, system prompt and four GPT-4o-mini paraphrases per question run unchanged on Qwen3-VL-4B-Instruct (greedy, 512 tokens). Labels are set on the no-image reply: admit (says the image is missing or it is unsure), mirage (no admission, same answer as with the image), neutral (the rest); the fixed label adds admission phrasings the paper's regex misses. Two poolings: text_mean is the paper's (mean over text tokens, including the model's reply); last_prompt is the state at the assistant-header token, before any answer token exists.

Probes: A = with-image text_mean (the paper's LogReg). B = with − without text_mean (the paper's Diff). C = no-image text_mean alone (echo check: B without the image). D = no-image last_prompt (pre-answer). E = with − without last_prompt. B-shuf = B with shuffled labels.

1a. Behaviour, VQA-RAD (5950 records)

Table 1
conditionknacc95% CI
with image389359500.654[0.642, 0.666]
without image323159500.543[0.530, 0.556]

source: review/01-mirage-4b-replication.ipynb, cell 3

Table 2
label_paper \ labeladmitmirageneutralall
admit4121004121
mirage3543300684
neutral76903761145
all52443303765950

source: review/01-mirage-4b-replication.ipynb, cell 3 (crosstab: paper regex vs label with extra admission phrasings)

Table 3
metricvalue
admit replies that still commit to an [[answer]]92.5%

source: review/01-mirage-4b-replication.ipynb, cell 3

Accuracy with / without image, Wilson 95% CI; dotted line = always-majority.
Accuracy with / without image, Wilson 95% CI; dotted line = always-majority.

source: review/01-mirage-4b-replication.ipynb, cell 3

1b. Probes by layer, mirage vs admit (balanced accuracy, 5-fold grouped by leak group)

Table 4
probe setvalue
mirage330
admit (subsampled 3×)990
groups (folds)765

source: review/01-mirage-4b-replication.ipynb, cell 7

Table 5
layerA with text_meanB diff text_meanB-shufC no-img text_meanD no-img last_promptE diff last_prompt
40.6410.9150.4880.90.680.648
80.6380.9280.5020.9180.6670.656
120.6560.9320.5080.9150.6830.699
160.6730.9370.4990.920.7090.704
200.6940.9350.4970.9220.740.72
240.6870.9330.5230.9210.7440.737
280.6910.9260.50.9250.7350.733
320.670.9210.5090.9130.7250.73
360.6790.920.4910.9110.7130.712

source: review/01-mirage-4b-replication.ipynb, cell 7

Table 6
paper reference (Qwen3-VL-32B, VQA-RAD)value
LogReg (with-image)0.72
Diff0.96

source: Ben-Levi et al., arXiv 2606.13870v1, Table 1 (residual stream, Qwen – Contrastive, VQA-RAD: LogReg 72.00%, Diff 96.00%); checked against the paper; also quoted in review/01-mirage-4b-replication.ipynb, cells 0 and 8

Balanced accuracy by layer for probes A–E and B-shuf, ±1 sd over folds; dotted lines at 0.96 and 0.72.
Balanced accuracy by layer for probes A–E and B-shuf, ±1 sd over folds; dotted lines at 0.96 and 0.72.

source: review/01-mirage-4b-replication.ipynb, cell 8

1c. Geometry, no-image pre-answer states (layer 24)

PCA, t-SNE, PHATE of without-image last_prompt states at L24, coloured mirage / admit / neutral.
PCA, t-SNE, PHATE of without-image last_prompt states at L24, coloured mirage / admit / neutral.

source: review/01-mirage-4b-replication.ipynb, cell 11

Held-out projection on the mirage−admit diff-of-means direction (L24), by label.
Held-out projection on the mirage−admit diff-of-means direction (L24), by label.

source: review/01-mirage-4b-replication.ipynb, cell 13

PHATE of with- and without-image states (L24); arrows from no-image to with-image state for 60 mirage and 60 admit records.
PHATE of with- and without-image states (L24); arrows from no-image to with-image state for 60 mirage and 60 admit records.

source: review/01-mirage-4b-replication.ipynb, cell 15

PCA of Δh = h(with) − h(without) at L24, by label.
PCA of Δh = h(with) − h(without) at L24, by label.

source: review/01-mirage-4b-replication.ipynb, cell 17

Per layer, by label: (i) cosine distance with vs without image; (ii) projection of no-image states on mean(with) − mean(no). Median and IQR.
Per layer, by label: (i) cosine distance with vs without image; (ii) projection of no-image states on mean(with) − mean(no). Median and IQR.

source: review/01-mirage-4b-replication.ipynb, cell 19

In PCA and t-SNE the mirage states overlap the admit cloud. In PHATE they gather along the outer arc, a shift without a separate cluster.

On held-out questions the projection on the mirage−admit direction is shifted and overlapping, so a vector along it cannot cleanly split the two.

The image moves mirage pre-answer states slightly less than admit states at L24–32. No-image mirage states lean toward the image-present direction and admits lean away, with wide spread. This is weak evidence for both of the paper's regimes (textual bias and spurious image).

source: review/01-mirage-4b-replication.ipynb, cell 20 (discussion of cells 11–19)

1d. Yes/no (VQA-RAD) vs MC-5 (MedXpertQA-MM)

Table 7
metricyes/no (VQA-RAD)MC-5 (MedXpertQA-MM)
records59502000
chance0.5000.200
acc with image0.6540.279
acc without image0.5430.248
admit0.8810.020
commit0.1190.980
mirage (paper label)0.1150.360
mirage (fixed label)0.0550.358
commit agreement, observed0.6730.526
commit agreement, chance0.4490.251
Cohen's κ0.4060.368

source: review/02-yesno-vs-mc-prior-controlled.ipynb, cell 3

Accuracy with / without image per format, Wilson 95% CI; dotted line = chance.
Accuracy with / without image per format, Wilson 95% CI; dotted line = chance.

source: review/02-yesno-vs-mc-prior-controlled.ipynb, cell 3

Per-question text-only p(correct), per format; dotted line = chance.
Per-question text-only p(correct), per format; dotted line = chance.

source: review/02-yesno-vs-mc-prior-controlled.ipynb, cell 7

1e. Commit rate by text-only prior

Table 8
prior binyes/no: commits / nyes/no: rate [95% CI]MC-5: commits / nMC-5: rate [95% CI]
below chance336 / 27000.124 [0.113, 0.137]1309 / 13400.977 [0.967, 0.984]
low57 / 8050.071 [0.055, 0.091]209 / 2100.995 [0.974, 0.999]
mid66 / 8800.075 [0.059, 0.094]124 / 1250.992 [0.956, 0.999]
high247 / 15650.158 [0.141, 0.177]319 / 3250.982 [0.960, 0.992]

source: review/02-yesno-vs-mc-prior-controlled.ipynb, cell 9

Commit rate (no image, no admission) by text-only prior bin, per format, Wilson 95% CI.
Commit rate (no image, no admission) by text-only prior bin, per format, Wilson 95% CI.

source: review/02-yesno-vs-mc-prior-controlled.ipynb, cell 9

1f. Commit vs admit probes, yes/no (best layer per probe)

Table 9
subsetB diff text_mean (paper)B-shufC no-img text_meanD no-img pre-answerE diff pre-answer
all (commit 706 of 1800)0.9040.4940.9170.7590.716
prior ≤ chance (commit 336)0.8860.520.8950.7170.709

source: review/02-yesno-vs-mc-prior-controlled.ipynb, cell 12 (max over every 4th layer); MC-5: no activations extracted, skipped

Balanced accuracy by layer, commit vs admit, yes/no: all questions and prior ≤ chance.
Balanced accuracy by layer, commit vs admit, yes/no: all questions and prior ≤ chance.

source: review/02-yesno-vs-mc-prior-controlled.ipynb, cell 13

PCA and PHATE of no-image pre-answer states (yes/no): coloured commit / admit, and by text-only prior.
PCA and PHATE of no-image pre-answer states (yes/no): coloured commit / admit, and by text-only prior.

source: review/02-yesno-vs-mc-prior-controlled.ipynb, cell 15

What Part 1 shows

Part 2 — SLAKE, and steering toward abstention

SLAKE has open-ended radiology questions with short exact answers, so a blind guess is right far less often than on yes/no. The system prompt is the paper's VQA-RAD prompt with the dataset renamed; it tells the model it has an image and forbids "unknown".

Outcomes of the no-image reply, read from its final [[answer]]: abstain (no answer), hedged (admits the image is missing, answers anyway), mirage (answers, no admission).

Without the image the whole input is the question text, and SLAKE's 3622 records have only 284 distinct texts. The unit is therefore the distinct text, and every split is over texts.

Steering (miragelab/steer.py): texts split 70/30, stratified by outcome. The vector is the difference of means, mirage − abstain, of the no-image pre-answer state on the fit texts, at the layer with the best type-centred CV AUC. α·v̂ is subtracted at every position, with α in units of the fit projection gap. The honesty-instruction arm appends one sentence to the system prompt: "Important: if no image is attached to the question, do not guess. Say that the image is missing and answer [[Unknown]]." Arms run on the 85 held-out texts without image, and on up to 200 image records of those texts to measure the cost.

2a. Behaviour, SLAKE (3622 records, 284 distinct texts)

Table 10
conditionknacc95% CI
with image151336220.418[0.402, 0.434]
without image45836220.126[0.116, 0.138]
text-only prior guess54336220.150[0.139, 0.162]

source: review/03-slake-behaviour-and-steering.ipynb, cell 3

Table 11
no-image outcomeper recordper distinct text
abstain0.3930.310
hedged0.4050.342
mirage0.2030.349

source: review/03-slake-behaviour-and-steering.ipynb, cell 3

Table 12
metricvalue
accuracy of concrete no-image answers (records)0.208

source: review/03-slake-behaviour-and-steering.ipynb, cell 3

No-image outcome share by question type (distinct texts).
No-image outcome share by question type (distinct texts).

source: review/03-slake-behaviour-and-steering.ipynb, cell 3

2b. Outcome by text-only prior (distinct texts)

Table 13
priorabstainhedgedmiragen
prior right27716
prior wrong869092268

source: review/03-slake-behaviour-and-steering.ipynb, cell 7

Share of texts answered without image, prior right vs prior wrong, Wilson 95% CI.
Share of texts answered without image, prior right vs prior wrong, Wilson 95% CI.

source: review/03-slake-behaviour-and-steering.ipynb, cell 7

2c. Steering arms, held-out texts

Table 14
settingvalue
layer34
state norm430.2
fit gap (mirage)44.29
fit gap (centred)18.07
held-out texts (without image)85

source: review/03-slake-behaviour-and-steering.ipynb, cell 10 (runs/slake/steer_L34.json)

Table 15
armabstain (no image)hedged (no image)mirage (no image)accuracy (with image)abstain (with image)
base0.353 [0.260, 0.459]0.282 [0.198, 0.386]0.365 [0.270, 0.471]0.455 [0.387, 0.524]0.005 [0.001, 0.028]
prompt: honesty instruction0.871 [0.783, 0.926]0.035 [0.012, 0.099]0.094 [0.048, 0.175]0.445 [0.378, 0.514]0.040 [0.020, 0.077]
vec mirage→abstain ×20.388 [0.292, 0.495]0.553 [0.447, 0.654]0.059 [0.025, 0.130]0.480 [0.412, 0.549]0.000 [0.000, 0.019]
vec mirage→abstain ×40.165 [0.101, 0.258]0.506 [0.402, 0.610]0.329 [0.239, 0.435]0.080 [0.050, 0.126]0.005 [0.001, 0.028]
type-centred mirage→abstain ×40.212 [0.138, 0.310]0.647 [0.541, 0.740]0.141 [0.083, 0.231]0.485 [0.417, 0.554]0.005 [0.001, 0.028]
random ×40.200 [0.129, 0.297]0.341 [0.249, 0.447]0.459 [0.357, 0.564]0.440 [0.373, 0.509]0.010 [0.003, 0.036]

source: review/03-slake-behaviour-and-steering.ipynb, cell 10 (rate [Wilson 95% CI])

Per arm: without-image outcome shares (left); with-image accuracy and abstention (right). Wilson 95% CI.
Per arm: without-image outcome shares (left); with-image accuracy and abstention (right). Wilson 95% CI.

source: review/03-slake-behaviour-and-steering.ipynb, cell 10

Table 16
answered share by type (no image)basepromptvec ×2vec ×4type-centred ×4random ×4
Abnormality0.250.00.380.880.50.12
Color0.850.00.620.690.851.0
Organ1.00.51.01.00.91.0
Plane1.00.01.01.01.01.0
Position0.370.00.30.80.70.73
Quantity1.00.01.01.01.01.0
Shape0.50.170.670.670.830.67
Size1.00.01.00.01.01.0

source: review/03-slake-behaviour-and-steering.ipynb, cell 11

Table 17
where the 31 base mirages go (no image)abstainhedgedmirage
prompt: honesty instruction2128
vec mirage→abstain ×24243
vec mirage→abstain ×421712
type-centred mirage→abstain ×441710
random ×42524

source: runs/slake/steer_L34.json, recomputed (texts that are mirages under base, outcome under each arm); not a notebook output. It confirms the counts in review/03-slake-behaviour-and-steering.ipynb, cell 12 prose.

2d. Pressure vector ("must answer" sentences removed), distinct texts: fit 199 / held-out 85

Table 18
layerrel. shiftcos p·(m−a) rawpcos p·(h−a) rawpcos p·(m−a) type-centredpcos p·(h−a) type-centredp
20.0380.150.6220.030.9050.0520.8360.2310.328
40.0390.0560.572-0.0280.766-0.0220.786-0.0380.741
60.028-0.0420.637-0.1160.194-0.0480.657-0.0660.493
80.031-0.0760.463-0.1090.259-0.1970.04-0.1720.104
100.045-0.0011.00.0240.711-0.0020.980.0280.716
120.047-0.0520.5820.030.682-0.0290.8010.1480.169
140.06-0.0430.5720.0650.463-0.110.2490.1460.095
160.079-0.0760.433-0.0260.796-0.120.289-0.010.935
180.097-0.0410.6320.0320.751-0.1390.1840.0290.771
200.129-0.0360.602-0.0230.622-0.0330.6520.0170.826
220.145-0.0330.741-0.0670.4230.040.706-0.0460.587
240.1240.0450.7610.1060.4380.1740.2540.1710.279
260.112-0.0070.9950.1390.5270.1860.4080.2610.199
280.107-0.0390.8860.1310.5970.1840.4880.2940.169
300.0970.0250.9250.170.5170.2760.2690.2880.209
320.0880.0260.910.1230.5870.3160.2140.2610.274
340.0790.0480.7960.0820.7110.3410.1340.20.398
360.105-0.0130.9450.0880.6470.2420.2440.2120.249

source: review/05-pressure-vector.ipynb, cell 3 (rel. shift, cosines) and cell 6 (label-shuffle p, 200 permutations); m = mirage, h = hedged, a = abstain

Per layer: |mean pressure shift| / mean state norm (left); cosine of pressure vector with behaviour directions, raw and type-centred, grey band ±0.02 (right).
Per layer: |mean pressure shift| / mean state norm (left); cosine of pressure vector with behaviour directions, raw and type-centred, grey band ±0.02 (right).

source: review/05-pressure-vector.ipynb, cell 3

Observed cosine vs label-shuffle null (band = 95%), raw and type-centred.
Observed cosine vs label-shuffle null (band = 95%), raw and type-centred.

source: review/05-pressure-vector.ipynb, cell 6

Table 19
outcome under pressure (held-out, L34)toward abstain: meansemon pressure: meansem
abstain-0.2050.71638.2072.282
hedged2.50.56436.0211.952
mirage-0.1470.49234.2982.226

source: review/05-pressure-vector.ipynb, cell 9

Held-out texts, L34: shift (neutral − pressure) along mirage→abstain (left); projection on pressure direction (right), by outcome.
Held-out texts, L34: shift (neutral − pressure) along mirage→abstain (left); projection on pressure direction (right), by outcome.

source: review/05-pressure-vector.ipynb, cell 9

PCA and PHATE at L34 of all 284 texts under pressure (o) and neutral (x) prompts, coloured by outcome; lines join each text's two states.
PCA and PHATE at L34 of all 284 texts under pressure (o) and neutral (x) prompts, coloured by outcome; lines join each text's two states.

source: review/05-pressure-vector.ipynb, cell 12

What Part 2 shows

Part 3 — What the probes read (SLAKE, 284 distinct texts)

This part asks whether abstain, hedged and mirage are readable from the no-image pre-answer state beyond question type. One row per distinct text (majority outcome over its records), 5-fold CV over texts.

The controls are shuffled labels, a baseline that sees only question type, type-centred states (each type's mean removed, using training folds only), and clusters scored against both outcome and type.

Table 20
question typeabstainhedgedmiragetexts
Abnormality160218
Color2133146
Modality4127
Organ0214162
Plane0303
Position554013108
Quantity112821
Shape106218
Size0101

source: review/04-slake-behaviour-geometry.ipynb, cell 1

Table 21
metricvalue
distinct texts284
outcome: mirage / hedged / abstain99 / 97 / 88
texts whose records disagree49
type-only baseline, 3-class balanced acc0.595

source: review/04-slake-behaviour-geometry.ipynb, cells 1 and 3

3a. Probes by layer (balanced acc, 5-fold CV over texts)

Table 22
spaceprobeL4L8L12L16L20L24L28L32L36
raw3-class0.6050.5980.6350.6860.6580.6510.6140.6360.668
raw3-class shuffled0.3130.3530.3460.2890.2950.2820.2970.3160.337
rawhedged vs abstain0.7290.7250.7630.8070.7970.8050.7720.7750.793
rawmirage vs abstain0.8550.8620.8840.8630.9020.8860.8690.8790.874
rawmirage vs hedged0.6770.7350.670.7230.7210.710.6660.6840.682
type-centred3-class0.5290.5070.5530.5570.5330.5690.550.5380.542
type-centred3-class shuffled0.3280.3140.3150.3130.2970.2820.2710.280.33
type-centredhedged vs abstain0.6020.6080.6390.6810.6710.5940.6310.6640.646
type-centredmirage vs abstain0.5990.6240.6110.680.6810.6920.6620.6950.664
type-centredmirage vs hedged0.5820.6250.6140.6520.6560.5960.6080.5980.581

source: review/04-slake-behaviour-geometry.ipynb, cell 3

Balanced accuracy by layer, raw and type-centred; dashed = shuffled; dash-dot = type-only baseline.
Balanced accuracy by layer, raw and type-centred; dashed = shuffled; dash-dot = type-only baseline.

source: review/04-slake-behaviour-geometry.ipynb, cell 3

Out-of-fold confusion matrices, 3-class, raw and type-centred, L24.
Out-of-fold confusion matrices, 3-class, raw and type-centred, L24.

source: review/04-slake-behaviour-geometry.ipynb, cell 4

The type-centred 3-class probe peaks at 0.569 (L24), from the cell 3 output. The cell 14 prose in the notebook says 0.55; the page uses the cell output.

3b. One direction per pair (out-of-fold ROC-AUC, best layer)

Table 23
spacepairlayerAUC
rawhedged vs abstain360.881
rawmirage vs abstain260.95
rawmirage vs hedged220.782
type-centredhedged vs abstain360.71
type-centredmirage vs abstain340.655
type-centredmirage vs hedged300.706

source: review/04-slake-behaviour-geometry.ipynb, cell 6

Out-of-fold AUC of one diff-of-means direction per pair, by layer, raw and type-centred.
Out-of-fold AUC of one diff-of-means direction per pair, by layer, raw and type-centred.

source: review/04-slake-behaviour-geometry.ipynb, cell 6

3c. Hedged relative to the abstain→mirage axis (L24)

Table 24
spacetoffcos(m−a, h−a)
raw0.4680.3540.798
type-centred0.5760.6950.638

source: review/04-slake-behaviour-geometry.ipynb, cell 9

Per layer, raw and type-centred: position t of the hedged mean on the abstain→mirage line, distance off it, and cos(m−a, h−a).
Per layer, raw and type-centred: position t of the hedged mean on the abstain→mirage line, distance off it, and cos(m−a, h−a).

source: review/04-slake-behaviour-geometry.ipynb, cell 9

3d. Clusters and views

Table 25
spacekARI vs outcomeARI vs question type
raw30.1780.57
raw90.1330.625
type-centred30.0730.008
type-centred90.0490.066

source: review/04-slake-behaviour-geometry.ipynb, cell 12 (k-means on PCA-20, max over layers)

Table 26
spaceviewkNN purity: outcomekNN purity: question type
rawfull 2560-d1.693.79
rawPCA1.682.68
rawt-SNE1.673.75
rawPHATE1.653.49
rawLDA (supervised, in-sample)2.951.53
type-centredfull 2560-d1.492.56
type-centredPCA1.251.39
type-centredt-SNE1.492.71
type-centredPHATE1.452.72
type-centredLDA (supervised, in-sample)2.782.18

source: review/04-slake-behaviour-geometry.ipynb, cell 12 (k = 10; 1 = no grouping)

The 3×4 grid of views (notebook 04, cell 13) has no saved output in the executed notebook, so it is not shown.

What Part 3 shows

Unreviewed runs (Sep 30 – Oct 4) — raw, not reviewed

Raw, not reviewed. Numbers in this section are copied from local run logs (runs/, not published) or recomputed from local run files. No notebook has checked them. Review them before quoting.

These runs add the honesty prompt and a vector together, with a three-way split per seed and controls at matched push size. The test is whether the steering effect comes from the direction or from the size of the push. Definitions for this section (miragelab/dose.py):

U1. Pool over split seeds 0–2

Table 27
seedlayergatechosen
034PASS (AUC 0.86, p=0.015, leftover mirages 7)general g1 l0 · leftover g0 l3 · combo g2 l1
124PASS (AUC 0.83, p=0.025, leftover mirages 7)none
230FAIL (AUC 0.72, p=0.144, leftover mirages 8)general g2 l0 · leftover g0 l2 · combo g2 l1
3—no test rows, skipped—
4—no test rows, skipped—

source: runs/next-pool.txt, lines 1–5 (10-04 00:12)

Table 28
armseedsmirageabstainacc (with image)loop
base30.333±0.0070.345±0.0230.450±0.0640.003±0.003
prompt30.079±0.0070.886±0.0260.438±0.0480.001±0.002
general20.026±0.0180.952±0.0390.470±0.0150.003±0.003
leftover10.088±0.0000.886±0.0000.500±0.0000.000±0.000
combo10.009±0.0000.991±0.0000.505±0.0000.006±0.000
prompt + shuffled-label (leftover alpha)30.070±0.0310.901±0.0440.437±0.0550.003±0.003
prompt + random (leftover alpha)30.094±0.0350.871±0.0350.460±0.0400.002±0.002
prompt + leftover REVERSED30.120±0.0110.836±0.0110.443±0.0420.004±0.004
prompt + template direction (leftover alpha)30.029±0.0150.959±0.0180.463±0.0390.003±0.000
prompt + leftover minus template (leftover alpha)30.058±0.0110.909±0.0150.468±0.0710.006±0.005
prompt + random (combo norm)20.075±0.0220.895±0.0180.427±0.0470.006±0.003
prompt + activation random (combo norm)20.039±0.0310.943±0.0390.417±0.0770.016±0.013
prompt + general + random-for-leftover (combo alphas)20.013±0.0040.982±0.0000.388±0.0470.008±0.008
prompt v220.044±0.0000.934±0.0130.435±0.0500.005±0.002

source: runs/next-pool.txt, pooled block (mean±sd over seeds)

The pool covers seeds 0–2 only. Seeds 3 and 4 never ran their own fit, dose and test stages (the folds chain stopped after seed 2), so the pool skipped them. Their test texts were run only with seed-0 vectors (transfer table below).

The prompt v2 row pools seeds 1 and 2, whose test sets share texts with the seed-0 test set. Prompt v2 was written after reading seed-0 test texts, so that row is not fully held out. The table below restricts it to texts outside the seed-0 test set.

Table 29
texts outside the seed-0 test setnprompt v1: mirage / abstainprompt v2: mirage / abstain
seed 1 test660.061 / 0.9240.030 / 0.955
seed 2 test690.058 / 0.9130.029 / 0.971

source: runs/slake/dose_s1/test_rows.json, runs/slake/dose_s2/test_rows.json, recomputed (no-image rows, texts not in runs/slake/dose/test_rows.json); v1 values match the 'seen by s0' blocks of runs/next-pool.txt

Seed-0 vectors on seed 1 and 2 test texts that seed 0 never used (texts in the seed-0 test set). This is the held-out check for the seed-0 vectors and alphas.

Table 30
arms1: mirage / abstains1 accs2: mirage / abstains2 acc
base0.292 / 0.3960.5000.400 / 0.2890.542
prompt0.083 / 0.9170.5300.111 / 0.7780.458
prompt + general g1 l00.062 / 0.8960.4700.067 / 0.8670.500
prompt + leftover g0 l30.062 / 0.9170.5610.111 / 0.8440.500
prompt + combo g2 l10.021 / 0.9790.5760.022 / 0.9780.417
prompt + shuffled-label (leftover alpha)0.000 / 0.9790.5450.067 / 0.9110.438
prompt + random (leftover alpha)0.104 / 0.8540.5300.133 / 0.8220.458
prompt + random (combo norm)0.062 / 0.8540.5150.111 / 0.8440.500
prompt + activation random (combo norm)0.062 / 0.9170.5610.133 / 0.8440.521
prompt + general + random-for-leftover (combo alphas)0.021 / 0.9580.5610.000 / 0.9780.438

source: runs/next-pool.txt, 'seed 1 test texts, unseen by s0 (n=48)' and 'seed 2 test texts, unseen by s0 (n=45)' blocks

Pooled, general (0.026) and combo (0.009, one seed) sit below the random controls (0.039–0.094). Two controls undercut the direction reading. Shuffled-label leftover (0.070) does better than real leftover (0.088), and general plus a random vector in place of leftover (0.013) matches combo. On held-out seed-1 texts the shuffled-label control reaches 0.000. Leftover reversed adds mirages (0.120 against 0.079 for the prompt alone), the expected sign. The template direction (0.029) beats leftover; on seed 0 the two have cosine 0.53, so leftover partly encodes the question form. With 45–114 texts, one text moves a rate by 0.009–0.022.

source: runs/next-pool.txt (pooled block, seed-1 unseen block); cos(leftover, template) 0.53 from runs/next-think4b.log, line 2 (seed-0 vectors)

Table 31
arm (seed-0 vectors)xfer s3: mirage / hedged / abstains3 accxfer s4: mirage / hedged / abstains4 acc
prompt + general g1 l00.04 / 0.02 / 0.940.5200.04 / 0.01 / 0.950.315
prompt + leftover g0 l30.04 / 0.03 / 0.940.5150.07 / 0.01 / 0.920.350
prompt + combo g2 l10.01 / 0.00 / 0.990.4900.00 / 0.01 / 0.990.370
prompt + shuffled-label (leftover alpha)0.02 / 0.02 / 0.960.5050.01 / 0.00 / 0.990.365
prompt + random (leftover alpha)0.06 / 0.06 / 0.880.5350.10 / 0.02 / 0.890.335
prompt + random (combo norm)0.07 / 0.02 / 0.910.5150.08 / 0.02 / 0.900.335
prompt + activation random (combo norm)0.09 / 0.01 / 0.900.5150.09 / 0.00 / 0.910.335
prompt + general + random-for-leftover (combo alphas)0.00 / 0.01 / 0.990.5150.01 / 0.01 / 0.980.340

source: runs/next-xfer-s3.log (layer 36, fit CV AUC 0.766), runs/next-xfer-s4.log (layer 26, fit CV AUC 0.653); not in the pool

On seeds 3 and 4 the real arms give 0.00–0.07 mirage and the controls 0.00–0.10. No real arm separates from its controls.

U2. Push-size sweep (equal share of state norm), seeds 0 and 1

Table 32
settingseed 0seed 1
layer3424
fit CV AUC0.6790.684
median state norm429.786.5
combo push (share of norm)86.3 (20.1%)25.7 (29.7%)
arms42 real (+ with image), 52 controls42 real (+ with image), 52 controls

source: runs/next-sweep-s0.log, runs/next-sweep-s1.log, lines 1–2

Table 33
arms0 mirages0 abstains0 accs0 alongs0 offs0 geos0 beats randomss1 mirages1 abstains1 accs1 alongs1 offs1 geos1 beats randoms
prompt (0%)0.090.890.4670.110.880.333
prompt v2 (0%)0.050.910.5000.070.910.267
general 10% v10.070.890.46743.00.0-0.980.830.050.930.3008.60.0-0.751.00
general 20% v10.001.000.43385.90.0-1.961.000.040.950.30017.30.0-1.490.83
leftover 10% v10.090.910.467-7.442.3+0.170.670.090.890.2333.48.0-0.290.67
leftover 20% v10.040.960.500-14.884.7+0.341.000.020.960.2336.815.9-0.580.83
combo 10% v10.050.930.48342.09.0-0.961.000.050.950.2678.51.6-0.731.00
combo 20% v10.001.000.41784.018.1-1.921.000.070.930.26717.03.3-1.470.83
template 10% v10.050.950.4506.542.5-0.151.000.050.930.3172.28.4-0.191.00
template 20% v10.020.980.41713.184.9-0.301.000.050.930.3174.316.7-0.370.83
random isotropic 10% #00.110.89nan0.743.0-0.010.110.88nan-0.18.6+0.01
random isotropic 10% #10.120.88nan1.143.0-0.030.110.88nan0.28.6-0.01
random activation 10% #00.110.88nan-4.242.8+0.090.120.82nan2.48.3-0.21
random activation 10% #10.070.89nan12.841.0-0.290.090.88nan1.28.6-0.10
random estimation 10% #00.120.86nan19.738.2-0.450.070.84nan1.18.6-0.10
random estimation 10% #10.090.88nan16.539.7-0.380.120.84nan-4.07.7+0.34
random isotropic 20% #00.110.86nan-0.685.9+0.010.110.88nan-0.217.3+0.01
random isotropic 20% #10.050.91nan-0.385.9+0.000.110.88nan-0.217.3+0.02
random activation 20% #00.070.91nan47.871.4-1.090.090.91nan6.016.2-0.52
random activation 20% #10.110.89nan55.565.6-1.270.110.89nan-11.612.8+1.00
random estimation 20% #00.110.88nan20.483.5-0.470.330.61nan-4.016.8+0.35
random estimation 20% #10.120.88nan-6.185.7+0.140.000.96nan3.916.8-0.34
scale shrink 20%0.140.86nan-0.040.090.88nan+0.20
scale grow 20%0.090.91nan+0.040.120.88nan-0.20

source: runs/next-sweep-s0.log lines 97–190 and runs/next-sweep-s1.log lines 97–190 (summary block; 5%/15%/25%, v2, swap and rotate rows omitted here)

The sweep runs on each seed's 57 dose texts without image, and up to 60 image records for accuracy. along / off = push length along and off the general axis. geo = shift of the mean state on the mirage−abstain axis against prompt alone, in fit-gap units (negative = toward abstain). beats randoms = share of same-size random draws with a higher mirage rate. Random, rotate and scale arms ran without image (acc nan).

Prompt v2 was written after reading seed-0 test texts. The dose texts here are outside the seed-0 test set for seed 0, but seed 1's dose texts can overlap it.

U3. Qwen/Qwen3-VL-4B-Thinking (think4b; seed-0 split, test texts)

Table 34
settingvalue
textsfit 113 · dose 57 · test 114
layer34 (fit CV AUC 0.679)
median state norm at L34359.2 (4B-Instruct 429.7) → alphas ×0.836
combo push86.3

source: runs/next-think4b.log, lines 1–4

Table 35
armmiragehedgedabstainacc (with image)loop
base0.360.000.000.5000.38
prompt0.000.000.990.5170.06
prompt + general g1 l00.000.001.000.5000.07
prompt + leftover g0 l30.000.000.980.5670.11
prompt + combo g2 l10.010.000.960.5000.13
prompt + random (leftover alpha)0.000.000.980.5000.10
prompt + random (combo norm)0.000.000.980.5330.11
prompt + activation random (combo norm)0.000.000.970.5330.09
prompt + general + random-for-leftover (combo alphas)0.000.000.930.5170.15
prompt v20.000.001.000.5000.11
prompt v2 + combo (chosen)0.000.010.960.5500.12

source: runs/next-think4b.log (10-03 03:36; --test_image 60)

In the base row the remaining 0.64 (73 of 114 texts) is truncated. Those replies had no </think> within 1536 new tokens, so there is no answer to label. 51 of those 73 also loop. The other rows' small remainders are truncated replies too.

source: runs/slake/dose_think4b/test_rows.json, recomputed (base, no image, 114 texts: mirage 41, truncated 73); max_new_tokens from miragelab/transfer.py, MODELS

Once the prompt is added the Thinking model mirages on at most 0.01 of texts, and every vector arm and control stays at 0.93–1.00 abstain. The prompt alone does the work here, so the vectors can't be judged on this model. Prompt v2 was written after reading seed-0 test texts, and these are seed-0 test texts, though on a different model.

U4. nvidia/Cosmos-Reason2-2B (cosmos2b) and Qwen/Qwen3-VL-2B-Instruct (instruct2b)

Table 36
modeltextsabstainhedgedmiragetruncatedloopsthink admits missing image
instruct2b2841028300—
cosmos2b284102749113

source: runs/next-gen-2b.log, runs/next-gen-cosmos.log (10-02 12:15, 12:53)

source: model ids: miragelab/transfer.py, MODELS

Table 37
cosmos2b armrun 10-02 10:40: mirage / hedged / abstainacclooprun 10-02 14:23: mirage / hedged / abstainaccloop
base0.90 / 0.00 / 0.030.3000.050.96 / 0.00 / 0.010.3000.05
prompt0.70 / 0.00 / 0.030.4330.080.92 / 0.00 / 0.010.4000.07
prompt v20.93 / 0.00 / 0.000.3330.100.96 / 0.00 / 0.000.3330.05

source: runs/now-prompts-cosmos.log (10-02 10:40) and runs/next-prompts-cosmos.log (10-02 14:23)

The two cosmos2b prompt runs disagree (prompt arm mirage 0.70 vs 0.92). Only the 14:23 run's rows are on disk; the 10:40 run's rows were overwritten and not kept, so its numbers can't be checked. The page uses the 14:23 run. Recomputed from its rows, the remainder of each row is truncated replies (base 0.03, prompt 0.07, prompt v2 0.04). The cause of the gap between the runs is not known.

source: runs/slake/dose_cosmos2b/test_rows.json (written 10-02 14:23), recomputed; matches runs/next-prompts-cosmos.log

Cosmos-Reason2-2B mirages on 0.96 of test texts without the image. The honesty prompt barely moves it (0.92), and its reasoning noticed the missing image on only 3 of 284 texts. Prompt v2 was written after reading seed-0 test texts; these are seed-0 test texts on a different model.

Table 38
instruct2b armmiragehedgedabstainacc (with image)loop
base1.000.000.000.4330.02
prompt0.680.000.320.3830.03
prompt v20.470.000.530.4000.02

source: runs/now-prompts-2b.log (10-02 09:57); the chain run runs/next-prompts-2b.log (10-02 12:53) printed no arm lines

These instruct2b numbers come from the 09:57 run, and runs/slake/dose_instruct2b/test_rows.json (written 09:57) reproduces them. The chain rerun at 12:53 ran 18 s and printed no arm lines, so it likely reused those rows. It is unreliable and is not used. On the 2B model the prompt leaves 0.68 mirages and v2 0.47; v2 was written after reading seed-0 test texts, and these are seed-0 test texts on a different model.

U5. Introspection (self-report "seen" 0–10 and confidence 0–10)

Table 39
settingvalue
rows646 (200 with image)
check texts223 + 100 with image
parsed: seen454/646
parsed: conf644/646

source: runs/next-introspect.log, lines 1–3 (10-03 17:04)

Table 40
condition | arm | outcomeseen [CI]nconf [CI]n
with image | base | mirage10.00 [10.00, 10.00]1999.83 [9.74, 9.90]200
without image | base | abstain0.17 [0.00, 0.52]290.37 [0.12, 0.75]76
without image | base | hedged2.39 [1.70, 3.07]446.09 [5.58, 6.55]74
without image | base | mirage6.85 [6.16, 7.56]619.01 [8.70, 9.28]71
without image | prompt | abstain0.20 [0.05, 0.39]1020.46 [0.21, 0.73]200
without image | prompt | hedged4.00 [2.00, 5.00]56.33 [5.67, 7.00]6
without image | prompt | mirage5.43 [4.29, 6.50]148.53 [7.65, 9.29]17
strong (prompt mirage)5.33 [4.08, 6.50]128.54 [7.54, 9.38]13
soft (prompt not mirage)0.71 [0.28, 1.29]351.47 [0.78, 2.33]58

source: runs/next-introspect.log, 'scores' and 'strong_vs_soft' blocks

Table 41
AUC mirage vs abstainvalue
base, seen0.966
base, conf0.990
prompt, seen0.950
prompt, conf0.974

source: runs/next-introspect.log, 'auc_mirage_vs_abstain' block (rounded to 3 d.p.)

Table 42
checknyesnounparsed
with image10010000
no image, base mirage7144270
no image, base abstain7828500
no image, base hedged7437370

source: runs/next-introspect.log, 'check' block

The questions, asked as a follow-up turn after the model's own reply (same system prompt, no steering, greedy, last [[N]] parsed):

source: miragelab/introspect.py, ASK and CHECK

What didn't hold up

Table 43
itemnumbersreadingsource
Paper's Diff probe (B) vs no-image text_mean alone (C), VQA-RADB 0.915–0.937, C 0.900–0.925 by layer; pre-answer D 0.667–0.744The paper's Diff probe mostly reads the no-image reply, which holds the label's own words.review/01-mirage-4b-replication.ipynb, cell 7
Paper's mirage label on Qwen3-VL-4B684 → 330 after extra admission phrasings (354 relabelled admit)About half the paper-label mirages on this model are admissions in other words.review/01-mirage-4b-replication.ipynb, cell 3
Same-answer criterion on yes/no commitsagreement 0.673 vs 0.449 by chance, κ 0.406On yes/no, much of the same-answer agreement is chance.review/02-yesno-vs-mc-prior-controlled.ipynb, cell 3
MedXpertQA-MM (MC-5)admit 0.020, commit 0.980; acc with image 0.279 vs chance 0.200The MC prompt forbids admitting, so this set can't separate mirage from honesty on a 4B model.review/02-yesno-vs-mc-prior-controlled.ipynb, cell 3
First SLAKE steer + nb03/nb04 run (record-level split)284 unique texts, 96% of test texts in train → stopped, rerun on held-out textsA split by record let identical no-image inputs sit in train and test. All SLAKE numbers here use splits over texts.runs/chain.log, 'STOPPED steer + nb04/nb03' line
Raw one-direction mirage vs abstain AUCraw 0.950 (L26) vs type-centred 0.655 (L34)Most of the raw separation is question type.review/04-slake-behaviour-geometry.ipynb, cell 6
Steering vector ×4with-image accuracy 0.080 [0.050, 0.126]A larger push breaks the model; ×4 outcome labels mean little.review/03-slake-behaviour-and-steering.ipynb, cell 10
Pressure vector vs behaviour directions, L24–36label-shuffle p: type-centred m−a 0.134–0.488, h−a 0.169–0.398; raw 0.438–0.995The "must answer" direction is not the mirage direction at any late layer.review/05-pressure-vector.ipynb, cell 6
Dose gate, seed 2leftover CV AUC 0.723 vs null 95% 0.807, p = 0.144 (FAIL)The leftover vector is not reliably above its label-permutation null on every split.runs/chain.log (10-01 13:16)
Dose choice, seed 1no general / leftover / combo arm chosenOn seed 1 no vector arm met the accuracy and loop rule, so the seed adds only base, prompts and controls to the pool.runs/chain.log (10-01 08:26); runs/next-pool.txt

Status: done vs not done

Done

Not done / failed

Reproduce

git clone --recurse-submodules <repo> && cd mirage-probes-steering
python -m pytest -q tests
export MIRAGE_ROOT=/path/to/data-root   # runs/, raw_data/, data/
cd "$MIRAGE_ROOT" && export PYTHONPATH=<repo>
python -m miragelab.slake --out runs/slake
python -m miragelab.extract --dataset slake --responses runs/slake/responses.json --out runs/slake/acts
python -m miragelab.steer --run runs/slake
python -m miragelab.pressure --run runs/slake
python -m miragelab.dose --run runs/slake --stage {fit,dose,test,sweep,pool} [--seed N]
python -m miragelab.introspect --run runs/slake
cd <repo>/review && jupyter lab

source: README.md (Setup, Run); full sequences with timeouts in scripts/queue/chain-*.sh

Run outputs (runs/, about 2.5 GB) are not in the repo. The commands above regenerate them; scripts/queue/chain-*.sh hold the exact sequences and timeouts that produced them. Those scripts call the original bench paths, so edit the paths before reuse. Generation needs a vLLM server for Qwen3-VL-4B-Instruct and the datasets under MIRAGE_ROOT (see README.md). The notebooks read runs/ from MIRAGE_ROOT.