Files
llm-atlas/research/DEEPSEEK_ROUTING_CORPUS_AUDIT.md

387 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DeepSeek-V2-Lite 多域路由语料审计
> 状态:第三轮真实权重执行 / 固定公开语料 / prompt-level bootstrap
> 捕获时间:2026-07-29T07:45:00+00:00
> 证据身份:X(本机真实执行)+ O(官方工件)+ S(统计摘要)
> 输出:
> `src/data/deepseek-v2-lite-routing-corpus.json` 与独立重跑
> `src/data/deepseek-v2-lite-routing-corpus-repro.json`
## 1. 这轮到底补了什么
上一轮 `v2_lite_trace.py` 的任务是做“显微镜”:4 条手写 prompt、90 个有效
token,逐 token 保存 top-6 expert ID 与 gate weight。它适合解释 router 实际输出
什么,却不适合回答“换一批文本,这个现象还在不在”。
本轮把问题改成:
1. 固定四种可公开重建的文本域;
2. 每域固定 32 条,共 128 条 prompt;
3. 对官方 DeepSeek-V2-Lite 的 embedding 与 layer 0–6 做连续 BF16 forward;
4. 在 layer 1–6 捕获每个有效 token 的真实 top-6 routed-expert ID;
5. 先聚合到 prompt,再以 prompt 为单位做 2,000 次分层 bootstrap;
6. 同时报告点估计、95% 区间、两种聚合口径和明确停止线。
正式运行包含:
| 数量 | 值 |
| --- | ---: |
| prompt | 128 |
| 有效 token | 8,460 |
| 每个 MoE 层的 routed-expert 选择 | 50,760 |
| 实测 MoE 层 | 6 |
| routed-expert 选择总数 | **304,560** |
| routed experts / layer | 64 |
| active routed experts / token | 6 |
| bootstrap replicates | 2,000 |
这里的 304,560 是 `8,460 tokens × top-6 × 6 MoE layers`,不是模型参数量、
训练 token 数或线上请求量。
## 2. 语料合同
### 2.1 四个公开来源
| 域 | 公开来源 | 只使用的字段 | 固定 revision / 文件 SHA-256 |
| --- | --- | --- | --- |
| 英文百科 | [Salesforce WikiText-2 raw validation](https://huggingface.co/datasets/Salesforce/wikitext/tree/b08601e04326c79dfdd32d625aee71d232d685c3/wikitext-2-raw-v1) | `text` | revision `b08601e…685c3`; parquet `204929b7…11c4c` |
| 中文新闻 | [CLUE TNEWS](https://github.com/CLUEbenchmark/CLUE/tree/9e61ddd3659ddb57ed82b4d0ba0a8613dfb55a2e) | `sentence` | repo `9e61ddd…55a2e`; archive `77c476e7…33462`; test `74f19932…a0ca8` |
| Python 代码 | [OpenAI HumanEval](https://github.com/openai/human-eval/tree/6d43fb980f9fee3c892a914eda09951f772ad10d) | `prompt` | revision `6d43fb9…ad10d`; gzip `b796127e…979ef` |
| 小学数学 | [OpenAI GSM8K](https://github.com/openai/grade-school-math/tree/3101c7d5072418e28b9008a6636bde82a006892c) | `question` | revision `3101c7d…6892c`; test JSONL `3730d312…d14` |
边界:
- HumanEval 的 `canonical_solution`、`test` 没有进入模型,也没有执行代码;
- GSM8K 的 `answer` 没有进入模型;
- TNEWS 的标签和关键词没有进入模型;
- WikiText 只取 raw validation 的正文候选,不连接其他 split;
- 这四个来源被当作“探针语料”,不是任务正确率评测。
### 2.2 确定性选样
固定 salt:
```text
llm-atlas-deepseek-routing-v1
```
每域候选按下式升序排列,再取前 32 条:
```text
SHA256(salt | domain | source_id), then source_id
```
这比 `random.sample` 多保留了两层可复现性:
- 不依赖 Python / NumPy 随机实现;
- 每条输出都保留 source ID、selection rank、原文 SHA-256、字符数与 token 数,
可以从固定源文件重新定位。
文本使用官方 DeepSeek-V2-Lite tokenizer,加入 special tokens,从右侧截到 96
tokens。最低长度过滤为:
| 域 | 最低 token | 文本过滤后的候选 | 长度合格 | 选中 | 选中 token |
| --- | ---: | ---: | ---: | ---: | ---: |
| 英文百科 | 24 | 1,841 | 1,655 | 32 | 2,882 |
| 中文新闻 | 8 | 10,000 | 9,415 | 32 | 573 |
| Python 代码 | 24 | 164 | 164 | 32 | 2,983 |
| 小学数学 | 16 | 1,319 | 1,319 | 32 | 2,022 |
英文与代码经常触到 96-token 截止线;中文新闻标题明显更短。因此后续不能只给
一份“把所有 token 倒进桶里”的汇总。
## 3. 模型与执行边界
### 3.1 官方工件
```text
deepseek-ai/DeepSeek-V2-Lite
revision 604d5664dddd88a0433dbae533b7fe9472482de0
```
关键 SHA-256:
| 工件 | SHA-256 |
| --- | --- |
| `config.json` | `f346286b0f1c8b044252fd54cb4fa78b9fab6472a6e8bebb9edfe03d414ea03d` |
| `modeling_deepseek.py` | `7d8e5221095286eea991137760893fd7ba52727c0b4ebf48ec09e8bc56b45b9c` |
| `tokenizer.json` | `41f3bf64213da8c012d8bd0871a58a1fdf70463e8f08f110ddbb1082f529f669` |
| checkpoint index | `d2cdb2f325f6682cf3ad1ad2526a9f979d857390b579380c0331d975136e0acf` |
| shard 1 | `0d7e9f39bde40111a4c0f390b87497dce4565cf578d916395e6b2c7851f1e8da` |
第一分片完整包含 embedding 与 decoder layer 0–6;layer 7 跨分片,因此继续遵守
原有停止线。Layer 0 是 dense FFN,layer 1–6 是本次统计的六个 MoE 层。
### 3.2 批处理不会把 padding 算进统计
128 条样本按 token 数、domain、source ID 稳定排序,batch size 为 16。每个 batch
右侧 padding,并使用官方 eager attention 与 causal/padding mask。
gate hook 会看到 padded positions 的输出,但统计时只切:
```text
topk_ids[sample, :valid_length, :]
```
所以每条 prompt 的 route 总数必须严格等于:
```text
valid_tokens × 6
```
六层均通过这个不变量检查;每层都是 50,760 routes。
### 3.3 未执行的对象
- 未下载或执行 layer 7–26;
- 未做完整模型生成;
- 未测回答正确率;
- 未测训练期间 router load;
- 未测线上 serving 流量;
- 未执行 FlashMLA 优化 kernel;
- 未给 expert ID 赋语义名称。
## 4. 为什么 bootstrap 的单位必须是 prompt
一个 prompt 中相邻 token:
- 共享主题、语言与格式;
- 共享相同前缀 hidden state;
- 在 causal attention 下相互依赖;
- 不是独立同分布样本。
如果把 8,460 个 token 当成 8,460 个独立样本,区间会虚假变窄。这里先为每个
prompt 保存 64 维 route-count vector,再在每个 domain 的 32 条 prompt 内有放回
抽取 32 条。四个 domain 分层进行,固定:
```text
replicates = 2000
seed = 20260729
interval = percentile [2.5%, 97.5%]
```
它回答的是:
> 如果仍从这个固定探针来源与选样合同附近换一批 prompt,统计量会怎样波动?
它不回答:
> 真实训练分布或线上流量的总体参数是什么?
## 5. 两种聚合口径
### 5.1 Token weighted
先汇总一个 domain 内所有 prompt 的 route counts,再归一:
```text
p_e = Σ_i count(i,e) / Σ_i Σ_e count(i,e)
```
长 prompt 贡献更多,适合回答“本批实际 token 流向哪里”。
### 5.2 Prompt balanced
先把每条 prompt 的 64 维分布归一,再让 32 条 prompt 等权:
```text
p_e = mean_i [count(i,e) / Σ_e count(i,e)]
```
适合跨格式比较,因为一条短新闻标题与一条被截到 96 token 的代码 prompt 各有一票。
网站默认展示这一口径,并允许切换。
在本次四域内部,CV 的两种口径最大绝对差为 0.027(Layer 1 数学)。这说明主要
层级图景不是某一条特别长 prompt 单独制造的;但两套数字仍完整保留,不能据此假设
未来语料也不敏感。
## 6. 指标是什么
对当前层、当前 domain 的 64 维 expert share `p`:
### CV
```text
CV = population_std(p) / mean(p)
```
越大表示 share 越分散。它不是训练损失,也不直接等于“不均衡惩罚”。
### Gini
64 个 share 的 Gini coefficient。0 表示完全均匀;越大表示质量集中到更少 expert。
### Effective experts
```text
H(p) = -Σ p_e log p_e
effective = exp(H)
```
完全均匀时为 64;越小表示“按熵折算”的有效 expert 数越少。
### Top-expert share
64 个 share 的最大值。完全均匀基线为 `1/64 = 1.5625%`。
### Jensen–Shannon divergence
同层两个 domain 分布 `P,Q`:
```text
M = (P + Q) / 2
JSD(P,Q) = 1/2 KL(P||M) + 1/2 KL(Q||M)
```
使用自然对数,范围 `[0, ln(2)]`。0 表示两条 64 维分布完全相同。
## 7. 主要结果
以下均为 **prompt-balanced** 点估计;括号内是 effective experts。网站可切换到
token-weighted 并查看完整 95% 区间。
| layer | 英文百科 CV(effective) | 中文新闻 CV(effective) | 代码 CV(effective) | 数学 CV(effective) |
| ---: | ---: | ---: | ---: | ---: |
| 1 | 0.439(59.0) | 0.754(53.3) | 0.566(55.4) | 0.613(56.3) |
| 2 | 0.363(60.2) | 0.460(58.4) | 0.400(59.1) | 0.403(59.0) |
| 3 | 0.398(59.2) | 0.469(57.9) | 0.440(57.9) | 0.525(57.0) |
| 4 | 0.424(58.6) | **0.910(47.2)** | 0.610(54.0) | 0.527(56.0) |
| 5 | 0.418(58.5) | 0.551(55.0) | 0.524(56.0) | **0.848(49.7)** |
| 6 | 0.496(56.7) | 0.594(53.1) | 0.556(54.7) | **0.770(50.7)** |
### 7.1 Layer 2 在四域都相对平
Layer 2 的 prompt-balanced CV 为 0.363–0.460,effective experts 为
58.4–60.2,是六个被测 MoE 层中四域共同最平的一段。
“相对平”只指这 64 维 route-count distribution;不等于 expert 权重相同、计算量
完全相同或训练全局均衡。
### 7.2 Layer 4 的中文新闻更集中
Layer 4 中文新闻:
```text
CV = 0.910, 95% CI [0.857, 0.993]
effective experts = 47.2, 95% CI [44.4, 48.5]
top share = E29 9.06%, 95% CI [8.41%, 9.78%]
```
同层英文百科 CV 为 0.424、代码为 0.610、数学为 0.527。正确表述是:
> 在这 32 条 TNEWS 句子、这个 tokenizer、这个 layer 的固定探针中,route counts
> 比另外三域更集中。
错误表述是:
> E29 是“中文专家”。
### 7.3 Layer 5/6 的数学更集中
Layer 5 数学:
```text
CV = 0.848, 95% CI [0.794, 0.911]
effective experts = 49.7, 95% CI [48.1, 50.7]
top share = E14 8.04%, 95% CI [7.38%, 8.64%]
```
Layer 6 数学:
```text
CV = 0.770, 95% CI [0.728, 0.826]
effective experts = 50.7, 95% CI [49.3, 51.5]
top share = E28 7.54%, 95% CI [6.79%, 8.26%]
```
E14 与 E28 位于不同层,是不同参数;不能连成一个跨层“数学专家轨迹”。
### 7.4 同层域间 JSD
每层最大的 prompt-balanced pair:
| layer | 最大 pair | JSD point | 95% bootstrap interval |
| ---: | --- | ---: | ---: |
| 1 | 中文新闻 ↔ 代码 | 0.0587 | [0.0549, 0.0703] |
| 2 | 中文新闻 ↔ 代码 | 0.0345 | [0.0306, 0.0466] |
| 3 | 中文新闻 ↔ 代码 | 0.0569 | [0.0519, 0.0713] |
| 4 | **中文新闻 ↔ 代码** | **0.1502** | **[0.1376, 0.1715]** |
| 5 | 中文新闻 ↔ 数学 | 0.1113 | [0.0990, 0.1368] |
| 6 | 中文新闻 ↔ 代码 | 0.1161 | [0.1054, 0.1351] |
Layer 4 的中文新闻↔代码是本探针最大的同层距离,但仍只有理论上界
`ln(2)≈0.693` 的约 21.7%。
必须特别注意:普通 percentile bootstrap 是围绕经验分布重采样,不是“两个总体完全
相同”的 null bootstrap。区间不含 0 不能被偷换成经过校正的显著性检验。
## 8. 可复现性
正式运行和独立重跑的完整 JSON:
```text
4678a1d15395de93ffba757598cc3642bf35e9e07f71d82ddd87c27fc38a09e4
```
两个文件 byte-for-byte identical。确定性范围包括:
- 128 条选样身份、token 数与原文 SHA-256;
- 六层、每条 prompt 的 64 维 integer route counts;
- 两种聚合口径;
- 2,000 次 bootstrap 导出的所有 metric / expert-share / JSD 区间;
- 模型、语料、环境与统计合同。
没有记录 wall-clock timing,因此复跑一致性没有把 GPU warm-up、频率或系统噪声混进
证据闸门。
### 8.1 运行入口
```bash
PYTHONPATH=/path/to/transformers-4.41.2-deps \
python -B experiments/deepseek/v2_lite_routing_corpus.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-corpus.json \
--per-domain 32 \
--max-tokens 96 \
--batch-size 16 \
--bootstrap 2000 \
--seed 20260729 \
--captured-at 2026-07-29T07:45:00+00:00
```
官方 2024 remote code 在本机 Transformers 5.5 上会因已移除的
`is_torch_fx_available` 失败;与前两轮相同,本实验使用隔离的 Transformers 4.41.2
依赖,并把官方模型代码作为只读本地 package 导入,不给源码打补丁。
## 9. 仍然不能说什么
本实验没有授权以下结论:
- “DeepSeek 训练时专家全局负载就是这样”;
- “线上中文请求一定路由到 E29”;
- “E48 是代码专家、E14 是数学专家”;
- “某个 domain 的任务性能更好”;
- “router 的分布差异来自语义,而不是长度、tokenization、格式或共享前缀”;
- “六个早期 MoE 层代表完整 27 层”;
- “bootstrap CI 已经完成假设检验或多重比较控制”。
更稳妥的结论只有:
> 在固定、可重建的 128 条公开 prompt 上,DeepSeek-V2-Lite 的六个早期 MoE 层
> 确实呈现可测量的层间与域间 route-count 差异;prompt-level bootstrap 让我们能同时
> 看见差异和换 prompt 时的波动,但不能把参数索引直接解释成语义角色。
## 10. 下一步
1. 在受支持的 SM90 / SM100 环境执行 FlashMLA 优化 kernel,而不只运行算法参考路径;
2. 扩展到完整 layer 0–26,需要下载并校验其余 checkpoint shards;
3. 加入长度匹配与 tokenizer-fragmentation 对照,拆开 domain 和长度因素;
4. 预注册更少的主要比较,或使用 permutation / null bootstrap 与多重比较校正;
5. 研究 shared expert 与 routed expert 的激活规模,而不只看 routed IDs;
6. 若讨论性能,另建生成质量与吞吐合同,不与本路由描述实验混在一起。