14 KiB
DeepSeek-V2-Lite-Chat:512-token 完成度与全 27 层传播审计
状态:已执行、已评测、已做独立子集复跑
执行日期:2026-07-29
模型:
deepseek-ai/DeepSeek-V2-Lite-Chatrevision:
85864749cd611b4353ce1decdb286193298f64c7前序审计:
DEEPSEEK_V2_LITE_CHAT_BEHAVIOR_AUDIT.md预注册协议:
DEEPSEEK_V2_LITE_CHAT_COMPLETION_PROTOCOL.md
0. 先说结论,也先说不能说什么
这轮把 Round 04 的两个缺口分别补上:
- 将统一生成预算从 128 提高到 512,区分“达到长度上限”“自然结束”“可评测”和 “答案正确”;
- 不再只观察 Base checkpoint 的前六个 MoE 层,而是在同一个官方 SFT Chat checkpoint 上追踪 embedding、27 个 decoder layer、final norm 与 26 个 MoE gate。
最短结果是:
128-token natural EOS 31 / 128
512-token natural EOS 121 / 128
仍在 512 截断 7 / 128
GSM8K 严格完成且数值 exact 23 / 32
HumanEval 官方 tests pass 24 / 32
全深度目标 content tokens 1,537 / condition
隐藏状态阶段 29
MoE gate 26
top-6 route decisions 1,918,176
这些数字只来自四域各 4 条 source、八个固定条件。它们证明这组输入上的执行事实,不是 GSM8K、HumanEval、语言能力或“哪种边界更好”的 benchmark 估计。
1. 冻结的实验对象
1.1 模型与条件
- 官方
DeepSeek-V2-Lite-ChatSFT checkpoint,不是 Base、R1 或蒸馏模型; - 12 个模型与 tokenizer 文件固定到同一个 revision;
- English、Chinese、Code、Math 各 4 条完整公开 source;
- 每条 source 使用相同八格:
| 条件 | system | 历史边界 | 身份 |
|---|---|---|---|
s0_eos |
off | EOS | 官方序列 |
s1_eos |
on | EOS | 官方序列 |
s0_bos |
off | BOS | 单 ID 反事实 |
s1_bos |
on | BOS | 单 ID 反事实 |
s0_x |
off | x |
单 ID 普通词元对照 |
s1_x |
on | x |
单 ID 普通词元对照 |
s0_period |
off | . |
单 ID 普通词元对照 |
s1_period |
on | . |
单 ID 普通词元对照 |
同一 source 的八格仍在同一个左填充 batch 内 greedy generation。BOS、x 与句点格
不是有效官方聊天格式;它们是只改一个 input ID 的机制对照。
1.2 数据身份
| 域 | 数据 | 本轮判断 |
|---|---|---|
| English | WikiText-2 raw validation | EOS / 截断与传播差异 |
| Chinese | TNEWS public test | EOS / 截断与传播差异 |
| Code | OpenAI HumanEval | AST、官方 tests、完成状态 |
| Math | GSM8K test | 数值抽取、gold exact、完成状态 |
gold answer、HumanEval tests 与 entry point 都没有进入模型 prompt。
2. 为什么不能从 128-token 结果直接读“能力”
Round 04 的 128 个输出里,97 个因为达到 max_new_tokens=128 而停下。此时:
数学没有来得及写最终数值 ≠ 推理一定错误
代码 fence 尚未闭合 ≠ 完整代码一定不能运行
generation 停止 ≠ 模型主动输出 EOS
所以本轮没有只续写那 97 格,而是让全部 128 格从头使用相同的 512-token 预算。选择性续写 会让先前是否完成决定后续算力,破坏八格的固定预算比较。
3. 显存协议:两次 OOM 如何改变了放置,而没有改变输出
本机可见显存为 32,607 MiB,官方 model card 给出的单卡 BF16 需求是 40GB,因此必须 使用 Accelerate 模块级 CPU offload。
3.1 失败链
- 初次加载在 allocator 碎片下失败;
- 启用
expandable_segments:True后,29 GiB static placement smoke 成功; - 29 GiB formal 在长 prompt、512-token KV 与 offloaded
lm_head临时回装共同出现时, 额外申请约 400 MiB 失败; - 失败发生在写正式 JSON 之前,没有可供挑选的部分结果。
3.2 正式放置
max_memory[CUDA:0] = 28 GiB
CUDA resident = embedding + layers 0–23
CPU offload = layers 24–26 + final norm + lm_head
allocator = expandable_segments:True
八格 batch = 保持不拆
hf_device_map 里的 CPU 表示权重驻留 / offload 身份。Accelerate hook 会在执行前搬运模块,
不能把它简写成“后三层在 CPU 上做矩阵乘”。
28 GiB 与成功的 29 GiB smoke 在 32 格上:
prompt hash 32 / 32 exact
完整 generated token IDs 32 / 32 exact
decoded text 32 / 32 exact
EOS state 32 / 32 exact
因此改变的是可执行的静态放置余量,不是这 32 格的 greedy 输出。
4. 512-token completion 结果
4.1 总体完成度阶梯
| 统一预算 | 自然 EOS | 达到预算仍未 EOS | 总输出 |
|---|---|---|---|
| 128 | 31 | 97 | 128 |
| 512 | 121 | 7 | 128 |
这不是说“512 已经足够”。它只表明在这组固定输入上,增加统一预算解决了 90 个原先的 截断格,仍有 7 格没有自然结束。
4.2 八个条件逐格
| 条件 | 自然 EOS | 截断 | 平均生成 tokens | Math strict exact | Code tests pass |
|---|---|---|---|---|---|
s0_bos |
15/16 | 1 | 272.6 | 3/4 | 4/4 |
s0_eos |
15/16 | 1 | 278.0 | 3/4 | 3/4 |
s0_period |
15/16 | 1 | 270.9 | 3/4 | 3/4 |
s0_x |
13/16 | 3 | 294.4 | 2/4 | 3/4 |
s1_bos |
16/16 | 0 | 232.6 | 3/4 | 4/4 |
s1_eos |
15/16 | 1 | 229.6 | 3/4 | 2/4 |
s1_period |
16/16 | 0 | 158.3 | 3/4 | 3/4 |
s1_x |
16/16 | 0 | 177.3 | 3/4 | 2/4 |
分母始终保留。每格的 4 条 math / code 太少,不能把 4/4 与 2/4 排成“边界排行榜”。
4.3 仍截断的 7 格
| source | 域 | 条件 | 状态 |
|---|---|---|---|
WikiText 0443 |
English | s0_bos |
512 截断 |
WikiText 0030 |
English | s0_x |
512 截断 |
WikiText 2909 |
English | s0_x |
512 截断 |
WikiText 2746 |
English | s0_eos |
512 截断 |
WikiText 2746 |
English | s0_x |
512 截断 |
WikiText 2746 |
English | s0_period |
512 截断 |
HumanEval 44 |
Code | s1_eos |
fence 未闭合、AST 失败、未执行 |
English / Chinese 没有 gold task terminal,因此“不截断”只表示遇到 EOS,不表示回答正确。
5. 任务评测:完成、可评测、正确各记一张账
5.1 GSM8K
32 个 math cells 的抽取方法:
| 方法 | 数量 | 严格身份 |
|---|---|---|
\boxed{} |
20 | 明确 final marker |
| answer phrase | 8 | 明确 final marker |
| last-number fallback | 4 | 只作固定预算诊断 |
最终:
strict-complete numeric exact = 23 / 32
fallback 即使碰巧与 gold 相等,也不会因为“最后一个数字”被升级成严格完成。
5.2 HumanEval
32 个 code cells 使用官方 tests,逐 candidate 进入新容器:
| 执行分类 | 数量 |
|---|---|
passed |
24 |
assertion_failed |
5 |
runtime_error |
2 |
not_run |
1 |
沙箱固定为:
python:3.11-alpine@sha256:25976e9d34a0fab1f278cae931f34c8303d97bf0c0d7f85b6b4dcf641d7702a4
network=none · read-only · user=65534:65534
cap-drop=ALL · no-new-privileges
memory/swap=256m · pids=64 · cpus=0.5
/tmp=16m,noexec,nosuid · host mounts=0 · timeout=5s
通过官方 tests 是这 4 道 HumanEval 上的功能证据,不是生成代码的安全证明。
6. 128-token 前缀与独立复跑
正式 512 运行首先通过:
prompt hash 与 Round 04 相同 128 / 128
前 128 generated token prefix exact 128 / 128
正式运行后再启动新进程、重新加载模型,每域只取第 1 条 source:
prompt hash 32 / 32 exact
完整 generated token IDs 32 / 32 exact
decoded text 32 / 32 exact
EOS / truncation state 32 / 32 exact
它只能支持“32 格长序列复现”,不能写成 128 / 128 独立复跑。
7. 全 27 层 trace:到底追踪了什么
7.1 两条观察线
对每条 source 的八格做一次 prompt-only、use_cache=false forward:
hidden line:
embedding → layer 00 → ... → layer 26 → final norm
共 29 个阶段
router line:
MoE gate layer 01 → ... → layer 26
共 26 个 gate
每个 hidden 阶段保存目标 content 与完整输入的 shape、dtype、统计量和 tensor SHA-256; 每个 gate 保存 ordered top-6 route hash、route-weight hash、64 专家 load / weighted load 与 描述统计。原始激活 tensor 和逐 token route ID 不写入数据文件。
7.2 为什么排除边界相交 token
八种序列化的字符边界可能落在 tokenizer token 的内部。本轮先验证每个条件的目标内容 token 序列完全相同,再只比较完全位于 content 字符区间内的 token:
目标 interior content tokens = 1,537 / condition
被排除的 boundary-crossing tokens = 56 / 128 variants
否则比较的可能是“同一位置上的不同 token”,隐藏状态差异会混入 tokenizer 边界变化。
7.3 规模恒等式
1,537 target tokens
× 8 conditions
× 26 MoE gates
× top-6 experts
= 1,918,176 route decisions
8. 隐藏状态怎样沿深度分叉
十条 edge 在 embedding 的 1,537 个目标 token 上都 byte-exact:
10 edges × 1,537 rows = 15,370 / 15,370 exact
原因不是“条件没有影响”,而是 embedding 是逐 token lookup;目标内容 token ID 相同, 尚未与前文发生 attention 混合。进入 layer 00 后,十条 edge 的 exact hidden rows 都降为 0, 说明上下文差异已经传播到全部目标行。
四域合计的代表性结果:
| edge | final-norm cosine | final relative L2 | cosine 最低阶段 |
|---|---|---|---|
| System on−off · EOS | 0.99530 | 0.08474 | layer 22 |
| System on−off · BOS | 0.99440 | 0.09614 | layer 22 |
| System on−off · x | 0.98771 | 0.14814 | layer 22 |
| System on−off · period | 0.98747 | 0.15230 | layer 22 |
| BOS−EOS · system off | 0.99321 | 0.10376 | layer 01 |
| BOS−EOS · system on | 0.99304 | 0.11123 | layer 02 |
| x−EOS · system off | 0.99252 | 0.11333 | layer 13 |
| x−EOS · system on | 0.98706 | 0.15694 | layer 10 |
| period−EOS · system off | 0.99252 | 0.11368 | layer 08 |
| period−EOS · system on | 0.98754 | 0.15810 | layer 08 |
不能只看 cosine 接近 1 就说“几乎一样”:2048 维状态中的小方向变化可以改变后续 router 排序与 logits。也不能把 relative L2 的深度曲线读成单调累积;残差、归一化与注意力会让差异 被放大、旋转或部分抵消。
9. 26 个 gate 怎样分叉
ordered top-6 exact 比 set exact 更严格:前者要求六个专家及顺序完全一致;后者只要求专家集合 一致。四域合计:
| edge | ordered exact 最低层 | 最低比例 | layer 26 ordered exact | layer 26 set exact |
|---|---|---|---|---|
| System on−off · EOS | 24 | 52.6% | 60.2% | 71.6% |
| System on−off · BOS | 24 | 47.0% | 56.9% | 69.8% |
| System on−off · x | 24 | 38.1% | 45.7% | 60.5% |
| System on−off · period | 24 | 36.6% | 44.2% | 59.1% |
| BOS−EOS · system off | 01 | 42.0% | 54.1% | 67.0% |
| BOS−EOS · system on | 24 | 40.9% | 50.6% | 64.9% |
| x−EOS · system off | 21 | 41.1% | 49.1% | 63.6% |
| x−EOS · system on | 24 | 32.9% | 44.6% | 58.9% |
| period−EOS · system off | 24 | 42.7% | 48.9% | 63.8% |
| period−EOS · system on | 24 | 34.8% | 43.4% | 57.2% |
“最低层常在 24”是这 16 条 source 的描述事实,不是模型普遍规律,也不是 layer 24 的因果 特殊性。更不能把 gate 分叉率直接解释成能力变化:路由只是稀疏 FFN 计算路径的一部分。
10. 全深度独立复跑与元数据缺陷
正式 trace 后重新启动进程,每域复跑第 1 条 source。逐字段核对:
source objects(去除 runtime 字段) 4 / 4 exact
hidden tensor SHA-256 1,856 / 1,856 exact
ordered-route SHA-256 1,664 / 1,664 exact
route-weight SHA-256 1,664 / 1,664 exact
所有隐藏 / 路由比较统计 exact
预发布核对曾发现 content_token_ids_sha256 错误引用了外层循环最后一条 source,并通过
Python set 的迭代顺序让该顶层元数据在两个进程间不同。隐藏 tensor、route hash 与全部比较
统计当时已经 exact;仍然修正脚本为“在每条 source 验证后立即保存其内容 token hash”,随后
正式与复跑两份 trace 全部重跑。当前公开文件是修正后的结果。
这个例子说明:复跑不能只看 headline 数字,也要比较不参与结论的身份字段。
11. 文件、哈希与运行账
| 文件 | bytes | SHA-256 |
|---|---|---|
| 512 formal generation | 871,946 | 6af40512c5868caab0ef58356aaa7728384f2b7acc7c502aa89478fdf5a2a468 |
| completion evaluation | 138,837 | 73f4616359d664377405dd989ee15cbf18e540e2f7b916b0ff99a99143091427 |
| 512 independent subset | 233,300 | 6c89f85ae783de5dfbe71694ba23307e79ca04f9522dd8684aef8f6f5295424d |
| full-depth formal | 36,019,346 | 5678ed238f13e3b0d5cf7a3db2268dbddf13f047cdc3730771ba1c66d96426e8 |
| full-depth independent subset | 9,166,628 | 17c367cccce3698df6fa8a0c0455d2b0e52cd27e1f66717a66989a586dfd1098 |
关键运行账:
| 运行 | GPU placement | 模型加载 | 执行 | peak CUDA allocation |
|---|---|---|---|---|
| 512 formal | 28 GiB | 8.42 s | 1,225.27 s generation | 31,464,357,376 B |
| full-depth formal | 28 GiB | 8.37 s | 13.55 s forward | 28,754,760,704 B |
| full-depth subset | 28 GiB | 8.44 s | 3.85 s forward | 28,754,760,704 B |
这些 eager + offload 延迟不是生产 serving throughput。
12. 证据阶梯与下一步
前六层 Base route
↓ 回答早期路由是否分叉
完整 Chat generation
↓ 回答最终 token 轨迹是否结束、可评测、正确
29-stage hidden + 26-gate route
↓ 回答同一输入差异怎样穿过完整 checkpoint
尚未完成:
干预式 mediation、更多 source、sampling robustness、
标准 benchmark harness、generation-time KV / serving trace
本轮最重要的边界仍然是:
- hidden/router association 不是中介因果;
- 4 道 math / code 不是 benchmark;
- 固定 greedy exact 不是采样鲁棒性;
- counterfactual token 序列不是官方有效聊天;
- prompt-only
use_cache=falsetrace 不是生成期 KV 或生产服务轨迹; - HumanEval tests pass 不是代码安全。