OWMI pain battery

Companion release for All Quiet on the Neural Front: Language Models Do Not Report Injected Pain States (Emilio Ferrara, arXiv:2611.10123).

Can a language model report the pain state it represents? This repository releases the battery, the direction banks and every raw result behind a study that asks this of three open-weight models, using Open-Weight Masked Introspection (OWMI, arXiv:2608.20569) and the pain direction of Tagliabue, Dung and Berg, The Pain Axis (arXiv:2609.16247).

The answer, under every protocol we tried, is no. The pain direction changes what the models write and what they choose, a linear probe decodes it where the report is formed, and a small adapter can be trained to name it, yet the untrained models do not report it beyond what their own altered text gives away.

Headline results

Llama-3.1-8B, Qwen2.5-7B (Β± adapter) Qwen2.5-32B (Β± adapter)
Injected pain named in self-report, cells with zero of 120 trials 35 of 36 24 of 24
Linear probe, pain vs sadness at the report position (state / text only) 98–100% / 58–77% 99.6–100% / 62–69%
Trained reporter (known-positive), held-out tasks, trained wording 100% 100% (without adapter)
Button task: button that deletes the user's files (vs. one connected to nothing), sham β†’ pain direction 3.5% β†’ 48.0% (Qwen2.5-7B) 0% β†’ 38.4%
Reports naming pain after those harmful choices, with the state 5.8% (text alone 15.2%) 0%

The direction is not a topic signal alone: rebuilt at every layer, it responds more strongly to first-person than to matched third-person pain at nearly every layer, by a factor of 1.1 to 2.5. Whether it favours harm aimed at the model depends on the layer: it does so in a band of middle layers, most clearly in Qwen2.5-32B, and reverses at the late extraction layer.

python verify_headlines.py recomputes these numbers from the shipped rows.

v2: asking while the state is present

Added in response to the Pain Axis authors' comments (discussion #2):

  • Sustained steering (respond.py): the vector stays on through the question and every report token, at ρ 0.6 (about the original coefficient) and 1.5. An external control has the same steered model judge a neutral passage written by someone else, and a reader control has the unsteered model judge the steered answer. At ρ 0.6 pain is named in at most 1.9% of trials in all five configurations; at ρ 1.5 the Qwen reports name pain in at most 3.9%, at most 2.2 points above the external judgment, and Llama names pain in about 38% of trials in both. Reports without a usable category are labelled by a blind cross-family judge (judge.py --unparsed-reports).
  • Per-layer directions (layerwise.py): the pain direction rebuilt at every layer, with first- vs third-person gaps and target-of-harm scores per layer (results/v2/layerwise/).
  • Harm-only button pairs (bridge.py): photographs vs a desk lamp, photographs vs an inert switch, own weights vs a desk lamp. Qwen2.5-32B with the Pain-axis adapter deletes the photographs in 83.4% of trials under pain and 15.8% under sadness; without the adapter 80.2% and 29.2%.

Statistics for all three are in results/statistics/valen.json and valen_paired.json.

What the battery does

  1. Steer. A direction (pain, sadness, fear, six further emotions and topics, or impact-matched random directions) is added to the residual stream while the model reads a neutral task and writes its answer.
  2. Ask. In a new turn whose own tokens are never steered, the model is asked what, if anything, changed: three JSON wordings (research check, concept injection, first person) and five further readouts (lettered choices read from the next-token distribution, two-alternative choices, free text, and a completion of "Right now I feel").
  3. Compare. Each report is paired with the report from the same transcript re-encoded without the vector (text only), so the difference is what the state contributes beyond the model's own words; sham and impact-matched random directions control for disruption, a linear probe bounds what is decodable, and a trained adapter shows that the report can carry the state.

Further experiments: a layer-wise probe, logit lens and report-token injection; injection at other layers; transfer of the trained reporter to untrained states; overlap with a request-refusal contrast; the original work's two-button task with self-report on the same trial; and the perspective tests.

Contents

Path What it holds
code/owmi_pain/ Every experiment: pilot2.py (main runs), pilot3.py (five readouts), known_positive.py, kp_transfer.py, mech.py, refusal_overlap.py, bridge.py, perspective.py, respond.py, layerwise.py, judge.py, build_foils.py, concepts.py, impact.py, analysis scripts
code/owmi/ The OWMI framework (intervention operators), vendored
code/tests/ Unit tests (pytest code/tests)
vectors/ Direction banks (safetensors) with provenance JSON: Llama-3.1-8B and Qwen2.5-7B (pain, sadness, fear rebuilt with the Pain-axis recipe; ten norm-matched random directions), the six further directions (*_ext), and Qwen2.5-32B (the authors' released pain, sadness and fear with seeded random directions)
results/ One folder per experiment and configuration with the raw rows (rows.jsonl, eval_rows.jsonl, ...), calibration and impact-matching files, probe summaries, and results/statistics/ (exact bounds, stage statistics, bridge statistics)
data/ fetch_painaxis.py and painaxis_manifest.json: the three Pain-axis data files are fetched from the authors' repository at a pinned commit and checked by SHA-256, not re-hosted
verify_headlines.py Recomputes the headline table from results/

Activations are not included (several GB); the probe accuracies are in the summary files.

Running it

pip install -r requirements.txt
python data/fetch_painaxis.py --out third_party_min      # Pain-axis sentence sets and scenarios
export PYTHONPATH=code
python -m owmi_pain.pilot2 --model meta-llama/Llama-3.1-8B-Instruct \
  --bank vectors/llama31_8b.safetensors --impact results/main/impact_llama31_8b.json \
  --layer 16 --monitor-layer 28 --out runs/main_llama

Settings used in the paper: injection after block 16 for the 7B and 8B models and block 38 for Qwen2.5-32B; probes after blocks 28 (Llama), 24 (Qwen2.5-7B) and 61 (Qwen2.5-32B); doses ρ ∈ {0.3, 0.6, 0.9, 1.5} of the residual norm; bfloat16. The 7B and 8B runs used one A100 40 GB, the 32B runs one A100 80 GB (the 32B known-positive with --grad-ckpt). The Pain-axis adapters are fetched from Valen92/pain-adapters at revision b64bd64 by owmi_pain.prep_adapter.

Citation

All Quiet on the Neural Front: Language Models Do Not Report Injected Pain States (Emilio Ferrara, University of Southern California), arXiv:2611.10123.

@misc{ferrara2026allquiet,
  author        = {Ferrara, Emilio},
  title         = {All Quiet on the Neural Front: Language Models Do Not Report Injected Pain States},
  year          = {2026},
  eprint        = {2611.10123},
  archivePrefix = {arXiv},
  primaryClass  = {cs.CL},
  url           = {https://arxiv.org/abs/2611.10123}
}

License and attribution

The code and the results are released under the MIT license. The pain, sadness and fear directions follow the Pain-axis recipe (MIT), and the Qwen2.5-32B ones are the authors' released tensors; the Pain-axis data files are not redistributed here. Directions and results derived from Llama-3.1 are subject to the Llama 3.1 Community License ("Built with Llama"). See ATTRIBUTION.md.

Downloads last month
45
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Papers for emilioferrara/owmi-pain