Files
llm-atlas/research/DEEPSEEK_V2_LITE_CHAT_SAMPLING_PROTOCOL.md
2026-07-30 02:01:50 +08:00

353 lines
10 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-Chat 多种子采样稳健性协议
> 状态:已执行;正式结果、独立评测与新进程 R0/R1 复跑均通过
>
> 注册日期:2026-07-30
>
> 模型:`deepseek-ai/DeepSeek-V2-Lite-Chat`
>
> revision:`85864749cd611b4353ce1decdb286193298f64c7`
>
> 前序实验:512-token greedy completion 与全 27 层 trace
>
> 结果审计:`research/DEEPSEEK_V2_LITE_CHAT_SAMPLING_AUDIT.md`
## 0. 这一轮只补哪一个证据缺口
Round 04–05 已经证明:
```text
固定 greedy 解码下:
同一 source 的 system / 历史边界变化会让输出 token 轨迹分叉;
512-token 预算下有 121 / 128 格自然遇到 EOS;
子集新进程复跑可以逐 token exact。
```
但 greedy 只取每一步概率最大的一个 token。它不能回答:
```text
换一组随机数以后,某个条件是否仍有相似的完成率与任务结果?
greedy 输出是采样分布中的常见轨迹,还是一条很窄的路径?
两个条件的样本集合彼此靠近,还是只有某一对 greedy 输出不同?
```
本轮因此启用 checkpoint 随附的 sampling config,固定多个 seed。它不是新的能力
benchmark,也不尝试用 8 个样本完整估计语言分布。
---
## 1. 冻结不变的对象
继承 Round 05:
- 官方 SFT Chat checkpoint、12 个文件及 SHA-256;
- BF16、官方 eager Python 实现、Transformers `4.41.2`;
- 28 GiB static placement 与 `expandable_segments:True`;
- CUDA resident:embedding + layers 0–23;
- CPU offload residency:layers 24–26 + final norm + `lm_head`;
- 同一 source 的八格进入同一个左填充 batch;
- `system off/on × EOS/BOS/x/period`;
- EOS 是官方序列;BOS、`x`、句点各是单 ID 反事实;
- `PAD=EOS`、padding mask 为 0、`use_cache=true`;
- 公开数据、source ID、source text hash 与 prompt token hash。
本轮只取前序固定次序中每域第 1 条:
| 域 | source |
|---|---|
| English | `wikitext2/raw-validation/0443` |
| Chinese | `tnews/test/4855` |
| Code | `HumanEval/31` |
| Math | `gsm8k/test/1069` |
这是 4 条 source 的机制显微镜,不是 4 个领域的总体估计。
---
## 2. 解码配置来自哪里
固定 revision 的官方 `generation_config.json` 写明:
```json
{
"do_sample": true,
"temperature": 0.3,
"top_p": 0.95,
"bos_token_id": 100000,
"eos_token_id": 100001,
"transformers_version": "4.39.3"
}
```
本轮在已固定的 Transformers `4.41.2` 执行这组参数:
```text
do_sample = true
temperature = 0.3
top_p = 0.95
top_k = 0(显式关闭默认 top-k)
max_new_tokens = 512
use_cache = true
```
Holtzman et al. 2019 的 nucleus sampling 是这里 `top_p` 的方法来源;它动态保留累计概率
达到阈值的候选集合。Wang et al. 2022 的 self-consistency 说明多条推理样本可以聚合答案,
但本轮只在 1 条 GSM8K source 上展示多数答案,绝不把它称为标准 self-consistency
benchmark。
官方文件记录的是参数默认值,不保证不同 Transformers 版本、kernel、batch 顺序与 seed
产生相同随机轨迹;因此依赖栈和 batch 合同必须进入结果。
---
## 3. seed 如何在结果之前冻结
8 个 base seeds 不是手选“看起来分散”的整数。它们由以下字符串逐个做 SHA-256,并把
前 4 bytes 按 big-endian 解释为无符号整数:
```text
llm-atlas-deepseek-chat-sampling-v1/seed/{index}
```
固定结果:
| replicate | base seed |
|---:|---:|
| R0 | 19,683,830 |
| R1 | 1,560,062,173 |
| R2 | 3,978,401,375 |
| R3 | 1,280,933,274 |
| R4 | 1,467,459,869 |
| R5 | 1,297,359,489 |
| R6 | 2,722,953,988 |
| R7 | 3,330,978,061 |
为避免不同 source 重复使用同一 CUDA random stream,实际 run seed 定义为:
```text
SHA256(
"llm-atlas-deepseek-chat-sampling-v1/run\0"
+ decimal(base_seed)
+ "\0"
+ source_id
)[0:8] interpreted as unsigned big-endian
modulo (2^63 - 1)
```
每次 source×replicate batch 前:
```python
torch.manual_seed(run_seed)
torch.cuda.manual_seed_all(run_seed)
```
并记录 CPU / CUDA RNG state 的执行前后 SHA-256。
---
## 4. 很重要:八格共享“批次标签”,不共享同一个随机数
Transformers `4.41.2` 的 `_sample()` 对整个 batch 调用:
```python
torch.multinomial(probs, num_samples=1)
```
它不接受逐行 `Generator`。所以同一个 source×replicate 的八格:
- 在同一时间步、同一 batch 中执行;
- 共享同一个 run seed 与固定行顺序;
- 但每一行消费不同的 RNG 子流;
- 不是 common-random-number paired experiment。
因此“R3 的左格 vs R3 的右格”只能称为 **batch-seed aligned**,不能用普通 paired
bootstrap 或 paired t-test 冒充同随机数因果对照。本轮不报告 edge 的显著性 p 值或
置信区间。
固定 condition 行顺序:
```text
s0_eos, s1_eos, s0_bos, s1_bos,
s0_x, s1_x, s0_period, s1_period
```
改变行顺序会改变随机轨迹,必须判为不同协议。
---
## 5. 网格与执行闸门
### 5.1 技术 smoke
```text
4 sources × 2 base seeds (R0/R1) × 8 conditions × 16 new tokens
= 64 short outputs
另将 R0 在同一进程内重放一次:
4 sources × 1 replay seed (R0) × 8 conditions × 16 new tokens
= 32 replay outputs
```
技术 smoke 只验证:
1. prompt hashes 与 Round 05 的 32 格 exact;
2. 官方 temperature / top-p 实际进入 `generate()`;
3. `top_k=0`,没有隐式默认 top-k;
4. 64 个正式 smoke 输出正常,无 OOM / NaN / runtime exception;
5. R0 在同进程按相同 seed 重跑时 32 / 32 token exact;
6. R0 与 R1 至少有一个同 source、同 condition 的 cell 分叉;若 32 / 32 仍相同,只能继续调查,不能声称 sampling
已生效。
smoke 的 16-token 输出不进入正式统计。
### 5.2 正式网格
```text
4 sources
× 8 base seeds
× 8 conditions
× 512 new-token cap
= 256 sampled outputs
```
source 顺序与 replicate 顺序固定,不根据中间结果提前停止。某一格遇到 EOS 后由
Transformers 填 PAD;不能单独给未完成格追加预算。
### 5.3 独立复跑
正式完成后新启动 Python 进程、重新加载模型:
```text
4 sources × R0/R1 × 8 conditions
= 64 outputs
```
必须逐格比较:
- run seed;
- prompt token hash;
- 完整 generated token IDs;
- decoded text;
- EOS / truncation state;
- CPU / CUDA RNG pre-state hash。
只能写“64 / 64 sampled trajectories independently reproduced”,不能写 256 / 256。
---
## 6. completion 与任务评测仍沿用四张账
每条 sampled output 继续区分:
1. stopping:natural EOS / budget truncated / other stop;
2. task terminal:明确 final marker 或闭合 code fence;
3. evaluator coverage:数值可抽取或代码 AST + 沙箱可执行;
4. correctness:GSM8K gold exact / HumanEval official tests pass。
HumanEval 每个 candidate 进入全新 pinned 容器,沿用 Round 05:
```text
network none · read-only filesystem · user 65534:65534
cap-drop ALL · no-new-privileges · no host mounts
256 MiB memory/swap · pids 64 · cpus .5 · timeout 5s
```
同一代码文本若在多个 seed 重复,评测器仍保存每格结果,但可以按 candidate SHA-256
缓存一次沙箱执行;缓存必须只复用完全相同的 candidate + task + harness。
---
## 7. 预注册统计
### 7.1 每个 source×condition 的 8-sample 集合
- natural EOS / 8;
- budget truncated / 8;
- unique generated-token hashes / 8;
- greedy trajectory 是否出现在 8 个 sampled hashes 中;
- 28 对样本两两 token similarity 的 mean / min / max;
- 生成长度 mean / min / max;
- Math:8 个抽取答案、答案频次、majority final 与 gold;
- Code:AST / executed / official tests pass 频次。
“8/8 unique”表示完整 token 序列不重复,不表示语义有八种。
### 7.2 每条 edge 的两个样本集合
十条 edge 沿用前序定义。每个 source 报告:
- 同 replicate label 的 8 对 token similarity;
- 左集合每条样本到右集合的最高相似度,再与反方向平均:
`symmetric mean nearest-neighbor similarity`;
- 两边完整序列 hash-set intersection / union;
- completion class 计数差;
- Math / Code pass 频次差。
nearest-neighbor similarity 是 8-sample 描述量,不是分布距离的无偏估计。
### 7.3 汇总层
只做:
- 四条 source 合计的分子 / 分母;
- 按域逐 source 展示;
- 按 condition / edge 的描述性均值。
不做:
- 把 256 当作 256 个独立 benchmark tasks;
- 忽略同一 source 的重复采样聚类;
- 用 seed 当 source bootstrap unit;
- 根据 1 条 Math / Code source 给置信区间;
- best-of-8 与标准 pass@k 横比。
---
## 8. reproduction 与随机性要同时成立
采样实验的“可复现”不是要求所有 seed 输出相同,而是:
```text
相同 checkpoint + 输入 + 软件 + 行顺序 + seed
→ 同一条 sampled token trajectory
不同 run seed
→ 允许、并预期至少一部分 trajectory 分叉
```
正式结果必须同时报告:
- same-seed exact reproduction;
- across-seed diversity。
只报告前者会把采样伪装成 greedy;只报告后者又无法判断差异来自随机数还是环境漂移。
---
## 9. 仍然禁止的结论
- 8 seeds 已恢复完整生成分布;
- 某个边界“更有创造力”或“更稳定”;
- BOS / `x` / 句点是官方有效聊天条件;
- 1 条 GSM8K / HumanEval 代表任务能力;
- sampled majority 等于标准 self-consistency;
- unique sequence count 等于语义多样性;
- batch-seed aligned 等于 common-random-number paired;
- greedy 没出现在 8 samples 中就说明 greedy 不可信;
- sampling 输出差异由某层 router 或 hidden state 中介;
- CPU-offloaded eager 延迟代表服务吞吐;
- exact seed replay 可以跨 PyTorch / Transformers / CUDA 版本保证。
---
## 10. 失败与修订规则
- 技术 smoke 前可以修正代码错误,但正式 seed/grid/metrics 不随输出调整;
- OOM 时先降低 static GPU placement,保留八格 batch;任何改动都要用同 seed smoke 做
完整 token exact 跨放置闸门;
- 若必须拆八格 batch,正式协议作废并重新注册,因为 RNG 行消费与数值 batch content 都变了;
- 正式运行在写完整 JSON 前失败,不保留部分 seed 做结果;
- evaluator bug 可以修复并重跑 evaluator,但不能重选 sampled outputs;
- same-seed 复跑不 exact 时,结果只作失败诊断,不发布 sampling robustness 结论。