Files
llm-atlas/research/DEEPSEEK_ROUTING_HISTORY_DISTANCE_CONTROL_AUDIT.md
T

19 KiB
Raw Blame History

DeepSeek-V2-Lite 消息历史距离控制审计

状态:真实官方权重执行(X)
模型:deepseek-ai/DeepSeek-V2-Lite
revision:604d5664dddd88a0433dbae533b7fe9472482de0
执行边界:layer 0–6;观测 MoE layer 1–6
样本:WikiText-2 / TNEWS / HumanEval / GSM8K 各 32 条
正式运行与独立复跑:byte-exact
完整 JSON SHA-256:423a095d92738d4bc6c2ace2afa9b35627e61811458c7883dca7b44aee4e648e

0. 一句话先说结论

上一轮发现:

system 后面先经过一轮 one-shot 历史,再到目标 user 时,
system 对目标 token 专家路由的影响明显变小。

但那轮把五件事绑在一起:

  1. system 离目标更远;
  2. 中间多了一段文本;
  3. 多了一次 user → assistant 角色转换;
  4. 多了 assistant EOS;
  5. 中间文本恰好是一个可读示例。

本轮加入一个重复词元 filler 历史:

User: x x x x x x x x x
Assistant: x + EOS

它与原 one-shot 在官方模板中都精确增加 17 tokens,并保持完全相同的:

  • user / assistant 角色;
  • assistant EOS;
  • 目标 user 的绝对 token 位置;
  • generation prompt;
  • padded batch 形状。

目标内容上的 system-edge TV 均值变为:

无历史              filler 历史           原 one-shot
0.0738       →       0.0378       →       0.0188

而且两个台阶都在 24 / 24 个 layer × domain 中下降, 各自的 source-paired 95% 区间也都是 24 / 24 完全低于零。

最稳妥的解释是:

在这组固定协议中,不需要一个可读的正确示例, 仅加入等长的重复词元历史就能复现约一半的 system-edge 缓冲; 换回原 one-shot 文本后还会再下降约一半。

这仍然不是“纯距离因果效应”:

  • filler token 本身不是空气;
  • filler 仍然改变了历史长度与隐藏状态;
  • 原 one-shot 与 filler 的词元身份不同;
  • 本轮没有生成答案,也没有测能力。

1. 为什么不是直接说“few-shot 让路由稳定”

“few-shot 让路由稳定”至少混合了三个问题:

  1. 结构问题:前面是否已有一个完成的 user / assistant turn?
  2. 位置问题:system 离目标有多远?
  3. 内容问题:中间那轮到底说了什么?

如果只比较:

system → target
system → demo → target

看到差异后无法知道是哪一项造成的。

本轮不是一步解决所有问题,而是插入一个中间台阶:

无历史 → 等长 filler → 原 one-shot

这样至少可以问:

  • 没有可读示例时,历史结构是否已经足以产生缓冲?
  • 在长度、角色、EOS 与位置相同时,替换具体文本还有多少额外变化?

2. 六格实验是什么

两个因子:

  • S:system message 是否存在;
  • H:历史为 none / filler / demo。
条件 system 历史 官方模板结构
S0 / NONE 0 none target user → Assistant:
S1 / NONE 1 none system → target user → Assistant:
S0 / FILLER 0 filler repeated-token user → assistant + EOS → target
S1 / FILLER 1 filler system → repeated-token turn → target
S0 / DEMO 0 demo fixed demo user → assistant + EOS → target
S1 / DEMO 1 demo system → fixed demo turn → target

固定文本:

system
Answer accurately and concisely. 请准确、简洁地回答。

demo user
Reply with OK. 只回复 OK。

demo assistant
OK

filler user
x x x x x x x x x

filler assistant
x

六格全部使用:

tokenizer.apply_chat_template(
    messages,
    tokenize=True,
    add_generation_prompt=True,
)

没有手写一个“看起来像官方”的模板。

3. “等长”到底等在哪里

128 条 source 上,逐条验证:

对比 每条 token 增量 min max 是否全部相等
S0 filler − S0 none +17 17 17 是
S0 demo − S0 none +17 17 17 是
S1 filler − S1 none +17 17 17 是
S1 demo − S1 none +17 17 17 是

system 也继续保持上一轮的正交增量:

S1 − S0 = 每条 +16 tokens

因此:

  • filler 与 demo 的目标位置相同;
  • filler 与 demo 的角色前缀数量相同;
  • filler 与 demo 都有一个 assistant EOS;
  • 两者差别集中在 history content token identity。

3.1 为什么不叫“无语义 filler”

x 是一个真实、经过训练的 token。

九个 x 也可能触发:

  • 重复模式检测;
  • induction-like matching;
  • 特定 token embedding;
  • 特定 attention / MoE 路由。

所以这里使用:

低信息重复词元 filler

而不使用:

“无语义”“空白上下文”“纯距离”

4. 样本与上一轮完全一致

继续复用:

领域 数据 条数 输入字段
英文百科 WikiText-2 raw validation 32 text
中文新闻 CLUE TNEWS public test 32 sentence
Python 代码 OpenAI HumanEval 32 prompt
小学数学 OpenAI GSM8K test 32 question

固定:

  • 相同 source IDs;
  • 相同 source text SHA-256;
  • 相同 canonical content SHA-256;
  • 相同 23-token canonical prefix;
  • 相同 sample salt;
  • 答案不输入;
  • 代码不执行。

本轮 128 个 (source ID, content SHA-256) 与模板实验、2×2 历史实验 逐项一致。

5. 执行账本

项目 数值
source prompts 128
六格输入变体 768
输入 tokens 38,236
六格共同目标交集 每格 2,874
执行层 layer 0–6
观测 MoE 层 layer 1–6
每 token routed experts 6
新增真实 top-6 路由 1,376,496
公开语料累计真实路由 3,112,848
bootstrap 每域 2,000 次

分条件:

条件 输入 tokens 六层真实路由
S0 none 3,898 140,328
S1 none 5,946 214,056
S0 filler 6,074 218,664
S1 filler 8,122 292,392
S0 demo 6,074 218,664
S1 demo 8,122 292,392

注意:路由次数等于真实输入 tokens × 6 experts × 6 MoE layers, 不是模型参数量,也不是训练 token 数。

6. 为什么仍然要精确对齐目标 token

不同历史会改变目标前面的文本,进而可能改变:

  • 目标第一个 token 的边界切分;
  • wrapper token 数量;
  • token 的绝对位置。

本轮继续用三元组:

(相对目标字符跨度 start, end, token ID)

只有六个条件都存在的三元组才进入 target_content。

结果:

S0 none     2,874
S1 none     2,874
S0 filler   2,874
S1 filler   2,874
S0 demo     2,874
S1 demo     2,874

因此目标内容比较没有混入:

  • User:;
  • Assistant:;
  • system;
  • filler / demo;
  • EOS;
  • 边界重切分 token。

7. 统计单位与三个 system edges

对每个历史水平 (h),定义:

p(0,h) = system 关闭时的 64-expert route-share
p(1,h) = system 开启时的 64-expert route-share

system edge 的标准 Total Variation:

[ TV_h = \frac{1}{2}\lVert p(1,h)-p(0,h)\rVert_1 ]

三个真实边:

TV_none
TV_filler
TV_demo

再比较:

filler − none
demo − none
demo − filler

每个 domain / layer / scope / aggregation 内:

  1. 以 source prompt 为单位有放回重采样;
  2. 2,000 次;
  3. 六格共用同一组 sampled source indices;
  4. 先同时重建六格分布;
  5. 再计算三条 system edge 与 edge 差。

因此 token 没有被伪装成独立样本。

8. 主结果:两个台阶都是 24 / 24

以下均为:

target_content / prompt_balanced
层 域 none TV filler TV demo TV filler−none 95% CI demo−filler 95% CI
1 英文 .1055 .0559 .0236 -.0496 [-.0565,-.0406] -.0323 [-.0402,-.0274]
1 中文 .0778 .0276 .0166 -.0501 [-.0600,-.0410] -.0111 [-.0161,-.0063]
1 代码 .1123 .0571 .0243 -.0552 [-.0623,-.0480] -.0328 [-.0397,-.0272]
1 数学 .1328 .0791 .0250 -.0537 [-.0632,-.0457] -.0541 [-.0638,-.0428]
2 英文 .0621 .0300 .0153 -.0321 [-.0395,-.0244] -.0147 [-.0211,-.0087]
2 中文 .0420 .0204 .0145 -.0216 [-.0286,-.0172] -.0059 [-.0104,-.0026]
2 代码 .0586 .0329 .0166 -.0257 [-.0322,-.0197] -.0163 [-.0209,-.0099]
2 数学 .0734 .0399 .0195 -.0335 [-.0420,-.0246] -.0204 [-.0276,-.0152]
3 英文 .0574 .0317 .0184 -.0257 [-.0342,-.0191] -.0133 [-.0204,-.0080]
3 中文 .0351 .0220 .0131 -.0131 [-.0212,-.0079] -.0089 [-.0143,-.0053]
3 代码 .0654 .0398 .0130 -.0256 [-.0331,-.0187] -.0267 [-.0315,-.0220]
3 数学 .0485 .0345 .0164 -.0140 [-.0233,-.0094] -.0181 [-.0225,-.0133]
4 英文 .0834 .0338 .0198 -.0496 [-.0591,-.0432] -.0139 [-.0211,-.0073]
4 中文 .0714 .0286 .0150 -.0428 [-.0539,-.0353] -.0136 [-.0186,-.0082]
4 代码 .0750 .0445 .0148 -.0305 [-.0381,-.0242] -.0297 [-.0349,-.0241]
4 数学 .1079 .0511 .0232 -.0569 [-.0672,-.0473] -.0279 [-.0345,-.0229]
5 英文 .0666 .0338 .0222 -.0328 [-.0420,-.0220] -.0116 [-.0218,-.0062]
5 中文 .0520 .0269 .0161 -.0250 [-.0364,-.0182] -.0108 [-.0156,-.0061]
5 代码 .0549 .0386 .0184 -.0163 [-.0233,-.0104] -.0202 [-.0249,-.0161]
5 数学 .0728 .0449 .0229 -.0279 [-.0376,-.0192] -.0221 [-.0313,-.0162]
6 英文 .0761 .0312 .0208 -.0449 [-.0542,-.0373] -.0104 [-.0160,-.0036]
6 中文 .0578 .0256 .0181 -.0322 [-.0432,-.0247] -.0074 [-.0131,-.0038]
6 代码 .0731 .0343 .0164 -.0388 [-.0489,-.0292] -.0179 [-.0244,-.0131]
6 数学 .1093 .0422 .0270 -.0671 [-.0768,-.0562] -.0153 [-.0227,-.0083]

汇总:

问题 点估计下降 95% 区间完全低于零
filler 是否小于 none 24 / 24 24 / 24
demo 是否小于 filler 24 / 24 24 / 24

均值:

none       .0738
filler     .0378   相对 none 约下降 49%
demo       .0188   相对 filler 约再下降 50%
                      相对 none 约下降 75%

这不是 24 个独立总体显著性检验,也没有多重比较校正。 它是固定 cohort 上 24 个分层描述区间。

9. 六层都出现相同阶梯

四域平均:

层 none filler demo
1 .1071 .0549 .0224
2 .0590 .0308 .0165
3 .0516 .0320 .0152
4 .0844 .0395 .0182
5 .0616 .0361 .0199
6 .0791 .0333 .0206

四域分别跨层平均:

域 none filler demo
英文 .0752 .0361 .0200
中文 .0560 .0252 .0156
代码 .0732 .0412 .0173
数学 .0908 .0486 .0223

不能据此给 expert 命名,也不能推出数学“更依赖”某个专家。

10. 逐 token 路由集合也同向

下表把 128 条 prompt 的精确对齐目标 token 汇总。

每格:

top-6 set exact / mean Jaccard
层 system / none system / filler system / demo
1 .316 / .756 .565 / .864 .790 / .939
2 .459 / .820 .693 / .904 .815 / .946
3 .479 / .831 .683 / .901 .826 / .950
4 .390 / .784 .674 / .894 .800 / .942
5 .438 / .799 .657 / .887 .789 / .939
6 .387 / .770 .645 / .886 .769 / .932

也就是说,aggregate route-share TV 的下降不是只有汇总分布看得到; 同一个目标 token 的 top-6 expert 集合也逐级更相似。

但“路由集合更相似”仍不等于“答案更好”。

11. 固定长度后,具体文本仍然重要

filler → demo 只替换 history content,角色、EOS、长度和目标位置不变。

目标内容上的平均 filler↔demo TV:

system 关闭:.0357
system 开启:.0145

在 24 / 24 个 layer × domain 中:

system 开启时的 filler↔demo TV < system 关闭时

这显示的是一个双向交互模式:

  • history 类型改变 system edge;
  • system 的存在也改变 filler / demo 之间的距离。

它不证明:

  • 正确示例比错误示例好;
  • model 理解了 Reply with OK;
  • system 与 demo 在功能上互相替代;
  • 路由距离与任务性能单调相关。

12. 为什么 CV 没有 24 / 24

TV 衡量整个 64-expert 分布的距离。

CV 只把分布压成一个“负载离散程度”标量:

  • 分布可以大幅重排,但 CV 几乎不变;
  • 分布可以朝不同 expert 移动,CV 方向相反;
  • 两个分布 TV 很小,也可能跨过 CV 的局部斜率。

绝对 system-edge CV 变化:

对比 |CV edge| 下降
none → filler 18 / 24
filler → demo 19 / 24

CV edge contrast 的区间方向也不统一:

对比 完全负 完全正 跨零
filler − none 4 9 11
demo − filler 8 4 12

所以本轮主结论严格写成:

system-edge route-distribution TV 下降

而不是:

“专家负载一定更均衡”

13. 完整输入与目标内容必须分开

目标内容:

none .0738 → filler .0378 → demo .0188
24/24      → 24/24

完整输入:

none .1582 → filler .1390 → demo .1131
20/24      → 23/24

完整输入还把以下 token 计入:

  • system;
  • filler / demo;
  • User:;
  • Assistant:;
  • EOS;
  • generation prompt。

它回答的是:

整个协议流量的 route-share 如何变化?

目标内容回答的是:

同一段目标文本在不同历史下如何被条件化?

两者不能互相替代。

14. BF16 batch shape 是一个真实边界

新六格中,旧四格的输入合同仍可与上一轮逐项核对:

512 / 512 token-ID SHA-256 exact

但上一轮每批:

8 sources × 4 variants = 32 rows

本轮每批:

5 sources × 6 variants = 30 rows

虽然相同条件的 token IDs 完全一致,BF16 layer forward 的矩阵形状不同。 跨两次实验比较:

1,062 / 3,072 prompt-layer-condition route hashes exact
1,414 / 3,072 integer load-vector pairs exact

Layer 1 仍有:

481 / 512 route hashes exact

但细小 BF16 差异向深层传播后,整段 hash 很容易不再相同。

这意味着:

  1. 相同 token IDs 不保证不同 batch shape 下所有临界 top-k gate 完全相同;
  2. 本轮不能把旧实验与新实验的点估计差异全部解释为文本处理;
  3. 本轮正式对比只使用同一次六格运行内部的条件;
  4. 六格在每个 source 内进入同一 padded batch;
  5. 正式运行自身的独立复跑仍然 byte-exact。

这是为什么“可复现”不仅要固定 seed,还要记录 batch contract。

15. 与已有论文的关系

15.1 demonstration 的作用不只是真实标签

Min et al., EMNLP 2022 在一组分类与多选 ICL 实验中发现,label correctness 并非所有收益的唯一来源, 输入分布、label space 与 sequence format 也会贡献表现。

本轮与其问题意识相近:

把“示例内容”与“示例格式 / 历史结构”分开。

但本轮只测 DeepSeek-V2-Lite 的局部 MoE 路由,不复现其任务性能结论。

15.2 重复结构可能被模型机制利用

Olsson et al., 2022 讨论 induction heads 与序列内重复模式的关系;其在小型 attention-only 模型中提供 强因果证据,在更大含 MLP 模型中主要是相关证据。

因此九个重复 x 不能被当作“什么都没有”。 它恰好可能是一种很强的结构信号。

15.3 位置会影响模型如何使用上下文

Liu et al., TACL 2024 展示了长上下文任务中的位置敏感性。

本轮只移动 17 个模板 tokens,且没有任务输出, 不能直接套用“lost in the middle”结论;它只说明位置 / 历史距离值得单独控制。

15.4 irrelevant context 可能改变行为

Shi et al., ICML 2023 研究了无关上下文对任务表现的干扰。

本轮没有测答案,因此 filler 导致路由变化不等于 distractor 导致能力下降。

16. 独立复跑

正式结果:

src/data/deepseek-v2-lite-routing-history-distance-control.json

独立复跑:

src/data/deepseek-v2-lite-routing-history-distance-control-repro.json

两者:

42,885,795 bytes
SHA-256
423a095d92738d4bc6c2ace2afa9b35627e61811458c7883dca7b44aee4e648e

脚本:

experiments/deepseek/v2_lite_routing_history_distance_control.py

关键执行参数:

python -B experiments/deepseek/v2_lite_routing_history_distance_control.py \
  --artifact-dir /path/to/deepseek-v2-lite \
  --human-eval /path/to/HumanEval.jsonl.gz \
  --gsm8k /path/to/gsm8k/test.jsonl \
  --tnews /path/to/tnews/test.json \
  --tnews-archive /path/to/tnews_public.zip \
  --wikitext /path/to/wikitext-validation.parquet \
  --output src/data/deepseek-v2-lite-routing-history-distance-control.json \
  --per-domain 32 \
  --content-tokens 23 \
  --batch-prompts 5 \
  --layers 7 \
  --bootstrap 2000 \
  --seed 20260729 \
  --captured-at 2026-07-29T10:17:00+00:00

17. 现在能说什么

  • filler 与 demo 在官方模板下精确等长;
  • 两者拥有相同角色、EOS 与目标位置;
  • 重复词元 filler 已复现明显的 system-edge TV 缓冲;
  • 从 filler 换为原 one-shot 后,system-edge TV 还会继续下降;
  • 两个下降在 24 / 24 个 layer × domain 中同向;
  • 逐 token top-6 set / Jaccard 与 aggregate TV 同向;
  • 六格正式运行可以独立 byte-exact 复跑;
  • batch shape 会影响深层临界 gate identity,必须记录。

18. 现在不能说什么

  • filler 是无语义的;
  • 本轮已经隔离纯距离效应;
  • 原 one-shot 的“正确性”造成额外下降;
  • 更小的 route TV 代表更好的答案;
  • 更稳定的 expert set 代表更强能力;
  • CV 一定下降或负载一定更均衡;
  • 结果代表完整 27 层;
  • 结果代表线上多轮对话;
  • 24 个区间是多重校正后的总体显著性结论。

19. 下一步

  1. EOS 控制:尽可能固定可见 token 文本,只切换 assistant EOS / turn closure;
  2. 角色控制:相同 token 序列放入 user / assistant / system 的不同角色;
  3. 内容控制:固定长度,比较正确、无关、冲突与重复示例;
  4. 多 filler 控制:使用多个 token identity 与随机种子,避免把 x 当作总体;
  5. batch-shape 控制:固定矩阵形状并加入显式 dummy-row contract;
  6. 行为联结:生成答案,用独立任务指标检查 route TV 与能力是否相关;
  7. 完整模型:获得其余 shards 后扩展到全部 27 层。

在这些控制完成之前,本轮结论保持为:

固定 DeepSeek-V2-Lite、固定公开 cohort、固定官方模板与固定六格 batch 下的 消息历史结构 / 文本替换路由实证。