feat: trace DeepSeek Chat completion depth

This commit is contained in:
wuyang
2026-07-30 00:24:27 +08:00
parent fb44d15bb8
commit 8bb488f275
23 changed files with 1507052 additions and 33 deletions
@@ -0,0 +1,331 @@
# DeepSeek-V2-Lite-Chat completion-aware 生成与任务评测协议
> 状态:已执行;正式结果与独立复跑均通过预注册闸门
>
> 上一阶段:`DEEPSEEK_V2_LITE_CHAT_BEHAVIOR_AUDIT.md`
>
> 模型:`deepseek-ai/DeepSeek-V2-Lite-Chat`
>
> revision:`85864749cd611b4353ce1decdb286193298f64c7`
## 0. 这一轮要修正什么
Round 04 在 16 个固定 source、8 个条件上生成了 128 个输出,但只有 31 个自然遇到
EOS,另外 97 个在 `max_new_tokens=128` 处停止。编辑距离和 exact comparison 仍然是
真实观测;任务准确率却不能直接解释,因为:
```text
没有出现最终数值
≠ 数学推理已经失败
代码在第 128 token 处不能解析
≠ 完整代码一定不能通过测试
生成达到长度上限
≠ 模型主动结束回答
```
本轮因此把“停止”“任务终点”“可评测”和“正确”拆成四张账。
---
## 1. 冻结不变的实验对象
下列对象全部继承 Round 04,不因结果调整:
- 官方 SFT Chat checkpoint、12 个模型/tokenizer 文件及其 SHA-256;
- 4 个域 × 4 个 source,共 16 个完整公开 source;
- `system off/on × EOS/BOS/x/period` 八格;
- 同 source 八格进入同一个左填充 batch;
- EOS 为官方序列;BOS、`x`、句点各只替换一个历史边界 input ID;
- greedy、`do_sample=false`、`use_cache=true`;
- BF16 权重、官方 eager 实现与 Accelerate 模块级 CPU offload;
- 数学和代码各只有 4 条,仍不是 benchmark。
数据身份:
- English / Chinese 只测生成终止与成对输出变化,没有 gold correctness;
- Math 使用 GSM8K 官方 `answer`;
- Code 使用 OpenAI HumanEval 官方 `prompt`、`test` 与 `entry_point`;
- gold 与 tests 从不进入模型 prompt。
来源:
[GSM8K](https://github.com/openai/grade-school-math)、
[HumanEval](https://github.com/openai/human-eval/tree/6d43fb980f9fee3c892a914eda09951f772ad10d)。
---
## 2. 统一预算,而不是选择性续写
执行阶梯:
```text
已发布 baseline = 4 source/domain × 8 conditions × 128 new tokens
512 smoke = 1 source/domain × 8 conditions × 512 new tokens
512 formal = 4 source/domain × 8 conditions × 512 new tokens
512 independent = 1 source/domain × 8 conditions × 512 new tokens
```
不能只给 97 个截断格追加预算。那会让“之前是否完成”决定后续算力,破坏八格比较。512
正式运行必须重跑全部 128 格。
进入正式运行前,smoke 必须满足:
1. 32 / 32 prompt token hashes 与 128 baseline 相同;
2. 32 / 32 新输出的前 `min(128, baseline length)` 个 token 与 baseline exact;
3. 没有 OOM、NaN 或 runtime exception;
4. EOS、PAD、左填充和单 ID edit 合同不变;
5. evaluator 可以对 32 格全部产出 completion state。
正式运行还必须满足:
```text
128 / 128 prompt hashes exact
128 / 128 baseline token prefixes exact
```
独立复跑只覆盖每域第 1 条的 32 格,因此只能写“32 / 32 长序列复现”,不能写
“128 / 128 独立复跑”。
---
## 3. 正式运行前的显存协议修订
29 GiB static-placement smoke 成功:
```text
CUDA resident = embedding + layers 0–24
CPU offloaded = layers 25–26 + final norm + lm_head
32 outputs = 完成
```
但 16-source formal 在更长 source 的 512-token KV 状态下,于 offloaded `lm_head`
临时回装执行设备时申请 400 MiB 失败;脚本在写 JSON 前退出,没有产生可选择的正式结果。
这说明 `max_memory=29GiB` 只约束静态参数放置,不是 activation、KV 和临时回装后的硬峰值。
正式运行改为:
```text
max_memory[CUDA:0] = 28 GiB
CUDA resident = embedding + layers 0–23
CPU offloaded = layers 24–26 + final norm + lm_head
allocator = expandable_segments:True
八格 batch = 不拆分
```
这里的 `CPU offloaded` 是驻留身份;Accelerate hook 会在 forward 前把模块权重带到执行
设备,不能把 device map 写成“后三层在 CPU 做矩阵乘”。
修订发生在成功 formal 结果之前。为检查它是否改变输出,28 GiB smoke 与此前 29 GiB
smoke 逐格比较:
```text
prompt hash exact 32 / 32
generated token IDs exact 32 / 32
decoded text exact 32 / 32
EOS state exact 32 / 32
```
因此正式运行采用 28 GiB,同时把两次 OOM、两张 device map、峰值显存和跨放置 exact
闸门全部写入审计。若成功 formal 的 baseline 前缀不是 128 / 128 exact,仍判失败。
---
## 4. 四张 completion 账
每个输出保存以下互不替代的字段:
### 4.1 停止账
- `natural_eos`:生成序列实际遇到官方 EOS;
- `budget_truncated`:未遇 EOS 且正好达到 512-token 上限;
- `other_stop`:两者皆否;出现时必须单独调查。
### 4.2 任务终点账
- Math:出现明确 `\boxed{}`、`####` 或 final-answer 语言标记;
- Code:出现闭合 Python code fence,或自然 EOS;
- English / Chinese:没有任务终点判定器,不用句号冒充完成。
### 4.3 可评测账
- Math:终点范围内能抽取规范化数值;
- Code:抽出的 candidate 能通过 Python AST,并进入隔离沙箱;
- 截断后的“最后一个数字”只保存为 fallback 诊断,不进入严格完成指标。
### 4.4 正确账
- Math:规范化预测数值与 GSM8K gold final exact;
- Code:HumanEval 官方 `check(candidate)` 在隔离沙箱退出 0;
- 同时报告固定预算 pass 与 strict-complete pass;
- completion-conditioned accuracy 只作选择偏差明显的诊断,不作为主准确率。
由此得到五种状态:
```text
NATURAL_EOS
TASK_TERMINAL_BEFORE_EOS
BUDGET_TRUNCATED_WITH_FALLBACK_ONLY
BUDGET_TRUNCATED_UNRESOLVED
OTHER_STOP
```
---
## 5. 数学答案抽取
按以下优先级只取最后一个命中:
1. `\boxed{number}`;
2. `#### number`;
3. 明确的 `answer/result/total/profit ... is/= number`;
4. 文本最后数值,仅作 fallback。
数字统一:
- 去逗号;
- `Decimal` 规范化;
- 去无意义末尾零;
- `-0/+0 → 0`。
主指标:
```text
fixed_budget_numeric_exact = gold 与任何抽取结果 exact
strict_complete_numeric_exact
= gold exact
AND (natural EOS OR explicit final marker)
```
fallback exact 可以显示,但不能冒充 strict completion。
---
## 6. HumanEval 执行合同
代码抽取优先级:
1. 包含目标 `def entry_point` 的 Python fence;
2. 其他 Python fence;
3. 文本中目标函数定义起点;
4. 作为官方 prompt 的 completion suffix。
每个 candidate 单独进入一个全新 Docker 容器:
```text
network = none
filesystem = read-only
user = 65534:65534
capabilities = drop ALL
no-new-privilege = true
memory / swap = 256 MiB / 256 MiB
pids = 64
cpus = 0.5
wall timeout = 5 s
/tmp = 16 MiB tmpfs, noexec,nosuid
Python = pinned image digest
```
容器没有 host mount,不读取仓库、Docker socket、凭据或网络。官方 `test` 和
`check(entry_point)` 只在容器内拼接;结果 JSON 不复制隐藏测试正文,只保存输入数据 hash、
harness hash、退出分类与运行时间。
退出分类:
- `passed`;
- `assertion_failed`;
- `runtime_error`;
- `timeout`;
- `ast_error`;
- `sandbox_error`。
HumanEval 官方仓库本身警告不要在不受信环境中直接执行生成代码;这里把容器隔离合同当作
结果的一部分,而不是一句“用了 sandbox”。
---
## 7. 预注册汇总
每个 condition 与 domain 同时报告:
- natural EOS / budget truncated;
- explicit task terminal;
- evaluator coverage;
- math fixed-budget exact / strict-complete exact;
- code AST / executed / passed;
- completion class 计数;
- mean generated tokens。
成对比较继续报告:
- token IDs exact;
- common prefix;
- edit distance;
- normalized similarity。
另外新增:
- 128→512 completion gain;
- 128-token prefix exact;
- 32-cell 独立复跑 exact;
- 每个比较边两侧的 completion class,防止“一个完整、一个截断”被压成单个 edit distance。
每域只有 4 条,因此所有 task 分数都保留分子/分母,不报告总体能力置信区间。
---
## 8. 仍然禁止的结论
- 512 tokens 足以代表模型最大能力;
- EOS 条件让答案更好;
- ordinary token 让回答更差;
- 4 条 GSM8K / HumanEval 等于 benchmark;
- completion-conditioned accuracy 可以与标准 pass@1 横比;
- greedy deterministic exact 等于 sampling robustness;
- HumanEval 通过说明代码安全;
- Chat 输出变化由 Base 前六层 route TV 造成;
- CPU offload 延迟代表生产吞吐。
---
## 9. 与全 27 层 trace 的接口
完整 27 层 forward 是另一条证据线:
```text
completion evaluator → 回答“输出是否结束、可评测、正确”
27-layer trace → 回答“同一输入怎样经过全部层与 26 个 MoE gates”
```
二者只有在同 checkpoint、同完整输入、同 condition、同 prompt hash 下才能做预注册关联;
即使 route feature 与输出分叉相关,也不能自动升级为中介因果。
---
## 10. 执行后登记(不回写预注册定义)
正式结果见 `DEEPSEEK_V2_LITE_CHAT_COMPLETION_DEPTH_AUDIT.md`。这里只登记协议闸门:
```text
512 formal
prompt hash 与 baseline exact 128 / 128
baseline generated prefix exact 128 / 128
natural EOS 121 / 128
budget truncated 7 / 128
512 independent subset
完整 generated token IDs exact 32 / 32
decoded text / EOS / truncation exact 32 / 32
full-depth independent subset
source object 去 runtime 后 exact 4 / 4
hidden tensor hashes exact 1,856 / 1,856
ordered route hashes exact 1,664 / 1,664
route-weight hashes exact 1,664 / 1,664
```
正式生成 SHA-256:
`6af40512c5868caab0ef58356aaa7728384f2b7acc7c502aa89478fdf5a2a468`。
正式全深度 trace SHA-256:
`5678ed238f13e3b0d5cf7a3db2268dbddf13f047cdc3730771ba1c66d96426e8`。