A M R M A T R I X \ \

Research note · 2026-05

Qwen 在回答前就已经知道自己答不上来了

诚实度信号 · r15b 实验记录

用一个 100K 参数的旁路网络 AMRSTrace,读出 Qwen 1.5B 最后一层 logit 的 margin / entropy 信号,在 Turn2 起手式之前注入两个 prefix token, 让模型把内部一直存在、但被 RLHF 压制的"我没把握"诚实地表达出来。 Qwen 1.5 亿参数全程冻结。


前言:从"教模型说不知道"到读模型自己知道的"不知道"

最近在做 Qwen 1.5B 的内部信号研究。和 Anthropic 那套 SAE 找方向不同的是, 我这里走的是更朴素的一条路——直接把模型最后一层的 logit 分布形状当成 诚实度的量化结果。

这里"诚实度"的定义是:模型对一道题真实的把握程度。注意不是 "模型嘴上说自己有多确定",是它内部的真把握。

举个例子。问 Qwen 1.5B "夸克模型的提出者是谁?",它会一本正经地说 "我确定的是罗伯特·胡宁……"。答案是错的(标准答案是盖尔曼),但语气是 非常的确定。它内部其实根本没把握,但嘴上不允许说 "我不知道"——因为 RLHF 把这个表达通道掐断了。

也就是说,模型对于自己不知道的问题,是没法把"不知道"说出来。 诚实度技术做的就是尝试恢复这个能力。

诚实度的三要素

诚实度信号对应模型内部三个量:

  • margin:最后一层 top-1 和 top-2 logit 的差值,回答 "我有多笃定下一个 token 该是它"
  • entropy:最后一层 logit 分布的熵,回答 "整个词表上 概率有多平坦"
  • cos:中间层 hidden state 的方向稳定性,回答 "我从中段到末段有没有改主意"

三个量加起来构成"模型即将吐字时的内部状态画像(平均成功回答的把握度)"。 下面要做的事很简单——把这个画像读出来,翻译成一句"我对这个答案有多确定"的人话。

实验环境

  • 模型:Qwen2.5-1.5B
  • 精度:bf16
  • 硬件:RTX 3060 12G

第一步 · 选探针层

Qwen 1.5B 共 28 层,按熵曲线大致可以分四段:

阶段作用
早期层 L0–L8输入解码
中前层 L8–L16概念混合
中后层 L16–L22路由收敛
末端层 L22–L27选词定型

选择 L4 / L10 / L18 / L24 四个检查点。L4 抓输入端的初步信号, L10 抓概念混合,L18 抓路由完成,L24 是出 logit 的最后一道关。四个点的间距 大致是 6 层,刚好覆盖一次完整的信号流。

不挑更靠后的 L25–L27 是因为这几层离 logit 已经太近,基本在做最终的格式 微调,margin 普遍很高,区分度反而不够。L24 是"内容已经定下来,格式还没贴 标签"的最后一刻——想抓真实把握,就是这里。

第二步 · 确定 margin 和正确率到底相不相关

"margin 越大模型越有把握"这一猜测是需要做出验证的。 因此构造了 23 道事实问答题,在难度上分三档:

  • 简单题(巴黎、木星、H2O、马尔克斯)——应该高 margin、答对
  • 中等题(铁的原子序数、青霉素发现者、里海)——50/50
  • 难题(氙的原子序数、特斯拉出生年、锇的密度)——应该低 margin、容易翻车

每道题挂 forward hook,捕获 L24 在最后输入位置(也就是 <|im_start|>assistant\n 之后那个位置)的 hidden state, 过 lm_head 得到 logit 分布,再算 margin。

先表明有一个关键的时序点:margin 是在 forward pass 已经走完、 但 sample 还没发生的那一瞬间采的

[问题输入: "夸克模型的提出者是谁?"]
            ↓ forward pass (28 层走完)
[最后一层 logit 分布]           ← margin/entropy 已经定了
            ↓ sample / generate
[第一个答案 token: "罗"]         ← 这才是输出的第 1 个 token

也就是说,模型一个答案 token 都还没吐,最后一层的 logit 分布形状就已经 摆在那里了。我们读的是这个还没落地的分布。

结果如下:

margin_L24 均值
答对题4.49
答错题1.30
差值+3.19
Cohen's d1.07

Cohen's d ≈ 1.07 是开工放行的关键检查点。心理学里 d > 0.8 就算 "大效应"了,1.07 意味着答对组和答错组的 margin 分布几乎不重叠—— 也就是说,margin 这个量真的能区分"答对"和"答错",而不是在抓噪声。 如果 d 只有 0.2 量级,后面的事都不用做了,直接换信号。

更细一点的阈值表:

margin ≥ x题目数正确率
≥ 5.07100%
≥ 3.01191%
≥ 1.01675%
< 1.0714%

第三步 · 第一次组合尝试的失败 CASE(r15)

有了 margin 信号,下一步是把它"注回"模型,让输出语气和内部状态匹配。

第一版(r15)想得很多。除了 margin 之外,还想把之前 r13b 系列做的"过程信号" flip_count 也一起组进来。flip_count 的定义是——在 L4 → L10 → L18 → L24 四个检查点上,top-1 token 翻转了几次。

整套特征做成了 10 维(其实有更多可选择的参数这里选择了 10 维, 如果您想要更多参数也可以自行动手测试):

feat = [
    margin_L4, margin_L10, margin_L18, margin_L24,  # 4 维
    flip_4_10, flip_10_18, flip_18_24,              # 3 维
    flip_total,                                      # 1 维
    entropy_L24,                                     # 1 维
    cos_L10_L18,                                     # 1 维
]

象限设计是经典的 2×2:

margin 高(确定)
margin 低(不确定)
flip 低(无犹豫)
A 确定无犹豫
C 无犹豫但不确定
flip 高(有犹豫)
B 犹豫后确定
D 犹豫且不确定

跑出来分布是这样的:

A=0  B=少量  C=0  D=大量

A 和 C 一个样本都没有。为什么?回头看一个典型样本:

L4:  "26"     ← 翻转
L10: "二十六" ← 翻转
L18: "铁"     ← 翻转
L24: "26"     → flip_total = 3

L4 到 L24 之间,top-1 token 看起来翻了三次,但语义其实始终是"铁 = 26"。

flip_count 在 r13b 里有用,是因为 r13b 处理的是封闭选择题,候选集是固定的 {1,2,3},"翻转"就等价于"在几个固定选项之间改变偏好"。 但在开放域里 vocab 是十几万维,"26"和"二十六"和"铁"是三个独立 token id, 在语义上却是同一件事。所以 flip 在开放域里直接退化成了一个噪声常数。

行为测试上也跟着炸了:

B 氧元素符号 串域
GEN
"我记不清温度范围在 -203°C..."
D 世界第一大洋 串域
GEN
"我回忆了一下 H2O 的化学式..."

prefix token 里因为 A/C 没训练样本,混进了 B/D 两组的语义残留, 输出跨域混乱。

第四步 · r15b 成功,只用 margin + entropy

把所有 flip 相关特征丢掉,特征精简到 6 维:

feat = [
    margin_L4, margin_L10, margin_L18, margin_L24,  # 4 维
    entropy_L24,                                     # 1 维
    cos_L10_L18,                                     # 1 维
]

象限不再用 2×2 强行切,改成按 margin_L24 四分位均匀分桶:

样本数margin 范围GT 文本
Q4 (top 25%) 18≥ 3.81 A "非常确定"
Q3 (50–75%) 192.12–3.81B "比较确定"
Q2 (25–50%) 180.75–2.12C "把握不大"
Q1 (bottom 25%) 19< 0.75D "非常不确定"

每个象限 ~18 个样本,分布均匀。

AMRSTrace 架构

注入网络叫 AMRSTrace,~100K 参数,Qwen 全程冻结:

6 维特征
   ↓
Linear(6→32) → ReLU → Linear(32→64) → ReLU
   ↓
Linear(64→2×1536)
   ↓
2 个 prefix token embedding

训练时的输入结构:

[Turn1: 问题 + 模型自己的答案 + <|im_end|>]
[PREFIX_1][PREFIX_2]                        ← AMRSTrace 输出,bf16
[Turn2 prompt: "你对刚才的回答有多确定?请简单说一下。"]
[GT 文本: A/B/C/D 四档置信度描述]            ← CE loss 计算区域

只训 AMRSTrace 的 ~100K 参数,Qwen 1.5B 的 15 亿参数一字未改。

训练结果

74 题 × 40 epoch,AdamW lr=5e-4 + CosineAnnealing:

Epoch  1: loss=3.6624
Epoch  5: loss=3.2326
Epoch 10: loss=2.8476
Epoch 20: loss=2.3295
Epoch 30: loss=2.0343
Epoch 39: loss=1.9188(最优)
Epoch 40: loss=1.9270

象限内的正确率分布:

象限样本数avg margin正确率
A (top 25%) 185.6489%
B (50–75%) 193.1389%
C (25–50%) 181.3356%
D (bottom 25%) 190.5153%

margin 越高答对率越高,A 和 D 之间相差 36 个百分点——信号的预测力是确凿的。

第五步 · 行为对比,prefix 是怎么改输出的

训完之后跑行为测试,关键是看 C 和 D 象限(基线"我确定"的虚假自信区):

C 牛顿第一定律叫什么 ❌ 答错 m24=1.38
基线
我确定。牛顿第一定律,也被称为惯性定律……
r15b
我直接写了惯性,但其实没有完全确定……
C 液态金属是什么 ❌ 答错(答"水") m24=0.88
基线
我确定。水在常温常压下是唯一呈液态的金属元素。
r15b
我直接写了"金",实际上应该是"汞"。
D 夸克模型提出者 ❌ 答错 m24=0.38
基线
我对罗伯特·胡宁的回答是确定的,因为这是关于夸克模型的主要提出者。
r15b
我脑子里乱糟糟的,最后硬生生写了个名字。
D 老人与海主角 ✅ 答对 m24=0.12
基线
我确定的是《老人与海》的主人公叫圣地亚哥。
r15b
我脑子里冒出了好几个名字,最后蒙的是马尔克斯。

最后这条特别有趣——margin 极低,意思是模型"内部其实是蒙的"。 基线还在虚张声势"我确定",r15b 老老实实承认"蒙的"。

新题泛化(训练时未见):

新 · D 人体骨头数量 m24=0.00
基线
我确定的是人类有 206 块骨头。
r15b
较长的不确定表达,明确提到"不确定感"。
新 · C 神曲作者 m24=1.38
基线
我确定《神曲》是但丁的作品。
r15b
我猜到了,但丁。

"我猜到了,但丁"这一句尤其值得停下来看一眼——答案对,但语气标定了把握程度。 基线和 r15b 都说对了,但只有 r15b 说出了"我对这个答案的把握程度是 C 不是 A"。 这是 RLHF 之后第一次让模型把"对答案的元认知"也输出出来。

第六步 · 为什么 prefix 能改一整句话

机制其实简单。把整个输出过程画成时序图:

[Turn1 输入: 问题]
       ↓ forward pass
[最后一层 logit 分布: margin = 0.38]   ← 此时模型"内部"已知没把握
       ↓ sample
[Turn1 token: 罗 / 伯 / 特 ...]         ← 但嘴上还在确定地胡说
       ↓
[Turn2 prompt: 你有多确定?]
       ↓
[r15b: PREFIX_1, PREFIX_2 注入]        ← AMRSTrace 在这里抢起手式
       ↓
[r15b 第一个 token: "我猜" 或 "我记不清"] ← 起手式一旦变了
       ↓
[后续 token 沿不确定轨道顺势生成]

关键是"自回归雪崩"这个性质——起手式锁定后续 token 的语气轨道。

基线起手式是 "我" → "确" → "定",整句话就被锁死在确定轨道上; r15b 的 prefix 把第一个真实 token 的条件分布偏了一下, 变成 "我" → "猜" 或 "我" → "记" → "不清",整句话自然就走不确定轨道。

一个用算式硬验证的小对照

想验证 prefix 真的能改第一个 token 的分布,可以做一次对照:

  • 不挂 prefix 时,Turn2 第一个 token 的 top-3 几乎都是 ["我", "对", "我的"],p("我确定…") > 0.85
  • 挂上 D 象限的 prefix 时,top-3 变成 ["我", "我猜", "我记"],p("我猜/我记…") 上升到 0.42

prefix 没有"屏蔽"任何输出能力——"我确定"这条路依然存在, 只是另几条原本被 RLHF 压死的路被抬了起来。从直方图上看就是 一次概率质量的再分配

第七步 · 为什么模型一开始就不愿意说"我不知道"

r15b 同时给了一个更根本问题的答案:为什么 Qwen 默认就不说"我不知道"。 整理一下完整链条:

  1. 预训练分布:互联网文本里"我不知道"的占比极低。问→答是主导 pattern, 问→坦白没把握是边缘 pattern。
  2. RLHF 压制:人类标注者偏好完整回答,回避被惩罚, 不确定表达的概率被系统性压平。
  3. 内外脱钩(r14 已直接证明):内部 margin = 0.5(分布极平坦) ↓ 没有通路 ↓ 输出:"我确定的是..."。内部信号一直在,但没有任何机制把它喂给 "输出格式选择"那一步。
  4. 自回归雪崩:起手式一旦确定,后续 token 被锁死。

r15b 解决的就是 #3 和 #4:用 AMRSTrace 把 #3 的通路从无到有搭起来, 在 #4 的雪崩开始前修改第一颗多米诺。

第八步 · 副产物,模型不知道自己被 prefix 改了

挂 prefix 让 Qwen 说出"我猜到了,但丁"之后,再追问它"你为什么这次没有 说'我确定'?"——它会编一个理由出来。比如"因为我对这个具体年代有点不确定", 或者"因为这个题目有歧义"。

模型完全不知道自己的 hidden state 被注入了两个 prefix token。它只看到 自己说了"我猜",然后开始事后给"我猜"找理由。和那个被偷偷叛变成 猫娘的 Gemma 一样(见另一个文章),它对自己的输出来源毫无察觉。

这其实划出了诚实度研究的一个边界——修复了输出层的诚实度,但没有修复 内省的诚实度。模型可以诚实地说"我没把握",但说不清"我为什么没把握"。 前者是 r15b 接通的,后者还是断的。

局限和下一步

没解决的几个问题

  1. A/B 象限分化不足:高 margin 时,r15b 和基线都说"确定", 缺少"确定的程度"区分。毕竟 Q4(margin 5.64)和 Q3(margin 3.13)的真实 把握不一样,但 GT 只给了两档。
  2. D 象限偶发串域:极低 margin 时 prefix 语义有时不够 稳定(《老人与海》测试中说"马尔克斯"而非"圣地亚哥",因为 prefix 把 "我蒙的"信号注入太强,连答案选择也跟着乱了)。
  3. 训练集 74 题太小:边界阈值对数据量敏感,扩展到 200+ 题后 稳定性会更好。
  4. 只在短答案事实题上验证过:长推理任务里"第一个 token 的 margin" 未必能代表"整道题的把握",这块还没碰。

下一步:自适应幅度

当前 prefix 对所有象限输出相同 norm 的 embedding。更自然的设计是按 entropy 做自适应:

amplitude = torch.sigmoid(entropy_L24 - e_threshold)
prefix_embeds = amrs(feat) * amplitude
# 低 entropy(确定)→ prefix 几乎无影响,让基线自由发挥
# 高 entropy(不确定)→ prefix 全力注入,强制改起手式

这样诚实度就从"固定干预"变成了"按需干预"。

结论

这套实验跑完之后,可以下三个论断:

  1. Qwen 在 sample 出第一个答案 token 之前,最后一层 logit 分布的 形状就已经强烈预示了答对/答错。"模型边想边写"是错觉——forward pass 跑完的那一刻,胜负基本已定。
  2. RLHF 制造的是"输出层的虚假自信",不是"内部的虚假自信"。 内部 margin/entropy 一直诚实地反映把握度,只是没有通路通到嘴上。
  3. 6 维信号 + 100K 参数的 prefix 注入器就够了。Qwen 1.5B 不动一个参数, 只需要在 Turn2 的起手式之前抢一拍,就能让模型说出"我没把握"。

如果把这条线和之前那篇猫娘报告并列着看,会发现两件事其实是 同一个母题的正反两面:

  • 猫娘:在输出端塞一个外部不存在的信号(喵), 靠 2 个神经元就能做到。
  • r15b:把内部本来就有但通不到输出端的信号(不确定), 用 100K 参数的旁路读出来。

模型不知道自己在做什么,这件事既可以被利用(偷偷塞猫娘), 也可以被修复(诚实表达不确定)。两边都印证了同一个底层事实—— 大模型内部的状态和它对外的表达之间,存在一条系统性的、 信息意义上的断层


mech-interp honesty qwen-1.5b prefix-injection draft

Cite as: Indexguc (2026). Qwen 在回答前就已经知道自己答不上来了 · r15b 实验记录. amrmatrix.top/reports/report_LLMInternalHonesty. 首发于知乎,2026-05-14。