10 KiB
Kimi-K3 PP8 + DFlash PD:实现与验证
更新:2026-08-31。八节点部署与固定 GSM8K 64 题 C1/C8 验证完成,128/128 请求成功,答案检查均通过,无输出截断。 本次完成的是用户后续指定的 DFlash 路线,未恢复 EAGLE3/no-spec 实验。
1. 目标与实现
保留 P 侧 PP8 的部署方案,让 P 生成真实 DFlash prompt KV,经 Mooncake 传给 D,D 接着执行投机解码。
P 601-604:TP4 / PP8 / EP4
各 stage 采集 target hidden,计算局部投影
→ PP stage 间累加投影结果
→ 最后 stage 统一 RMSNorm,生成 6 层 draft KV
→ 传输 target MLA KV、KDA 状态及 draft KV
D 605-608:TP32 / PP1 / EP4
接收上下文 → DFlash 提议 → target 验证 → 提交 token
基于 SGLang PR #33863 固定提交 6465a6f3d3b6c8b7fee40fba0fdc09cf5e9ca1c5。分段投影复用该 PR 的设计;新增 DFlash worker、Kimi capture、PD 调度衔接和异构 TP 传输,保留已验证的 Kimi SM120 FlashInfer MXFP4 接入。
模块(相对于 python/sglang/srt/) |
本次改动 |
|---|---|
models/kimi_k3.py、speculative/dflash_pp.py |
按 checkpoint 采集指定层;处理 PP 边界 residual;分段投影后只做一次归一化 |
speculative/dflash_worker_v2.py |
接收、传递 PP 上下文;最后 stage 写 draft KV;非末 stage 保留最小 KV pool |
managers/scheduler_pp_mixin.py、speculative/spec_info.py |
接通 DFlash proxy、PD 输入、FutureMap 与 idle 生命周期 |
disaggregation/common/kv_entry_layout.py、mooncake/conn.py 等 |
target MLA 整页传输;draft GQA 按 head 交集逐 token 切片;独立计算源/目标 stride,在提交前检查边界 |
model_executor/runner/base_runner.py、disaggregation/prefill.py |
修复 P 普通预热误带 verify metadata,以及混合 KV 池传输层范围计算 |
arg_groups/ |
仅放开已实现的 P 侧 PP + DFlash,D 侧保持 PP1 |
完整增量见 pp_dflash_integration.patch,19 个文件校验值见 pp_dflash_files.json。独立源码位于 601 的 /data/hzy/src/sglang-kimi-pp-dflash-33863,不覆盖同事部署源码。
2. 实际配置
| 项目 | 本次值 |
|---|---|
| GPU | 8 节点 × 8 张 RTX 6000D;每卡 85651 MiB,SM120,PCIe |
| P / D 并行 | TP4/PP8/EP4;TP32/PP1/EP4 |
| MoE / A2A | flashinfer_mxfp4 / none,两组一致 |
| Target / Draft KV | 均为 bfloat16 |
| Chunk / Page | 8192 / 64 |
| 最大活跃请求 / Decode Graph BS | 8 / 8;D 日志确认实际 Decode 使用 CUDA Graph |
| P / D 显存比例 | 0.88 / 0.86 |
| P / D Mamba memory ratio | 0.36 / 0.21 |
| Prefix Cache | --disable-radix-cache;128 个响应的 cached tokens 均为 0 |
| RDMA | Mooncake,mlx5_0,mlx5_1,mlx5_2,mlx5_3,容器挂载 /dev/infiniband |
| Draft | /data/hf_models/Kimi-K3-DFlash,6 层,hidden 7168,32 Q heads / 8 KV heads,head dim 128 |
| Draft 上下文 | Sliding window 4096,RoPE theta 2000000,capture [19,37,54,66,78,90] |
| Draft block | --speculative-num-draft-tokens 16;每个 verify step 统计 15 个 draft 候选位置 |
当前镜像:local/sglang:kimi-k3-pp-dflash-33863-fi0618-situ4460-kvbounds1。Linux/amd64 manifest 为 e74c9b1e7fb6a9509db32576d2c9196b42ef329118909eeebd620cb9db2f91e9;image config 为 26584138eb1e097183ce167cbffe4198be0611e0cfde7422cbe692100d865982。八节点镜像身份已核对。
FlashInfer 使用官方 0.6.18 wheel + 已合并 #4460 的原样 backport(b460bc00cb373541102d2155aec35bd626e522ce)。该 wheel 所属发布分支尚无 CUTLASS SiTU API,不能描述为“未经修改的 0.6.18 直接支持”。移除旧 cubin/JIT-cache 包,保留版本检查;编译缓存挂载到 /data/hzy/cache/kimi-dflash-fi0618-situ4460。最后两项启动修复仅替换 Python 层,不改变 FlashInfer kernel。
Dockerfile 的完整重建输入保留在 601 本实验 results/:sglang-kimi-pp-dflash-33863-integrated.tar.gz(SHA256 226065165bbb5f85ce516b847ff6da7e5aa823f12e69b87558e67c91996e3ba0)和 official_flashinfer_0618/flashinfer_python-0.6.18-py3-none-any.whl(SHA256 d5d26edb48f8def0bf28b2c94415aef7f0754e2cd9e3cb3d6e7081262d068aad)。源码归档含固定上游 Python 树、补丁后的代码、3 个测试文件及 SOURCE_MANIFEST.json;GPU 测试和服务验证状态以外部结果日志为准,不回写构建时的历史 manifest。
3. 测试结果
Run ID:pd-dflash-kvbounds1-20260831-1740。使用 GSM8K 实际文件前 64 题、5-shot、temperature=0、top_p=1,输入不裁剪,输出上限 512。实际输入 694-794 token,最长输出 225 token。C1 先运行,随后 C8;没有新增 no-spec 或 16K synthetic 测试。
| 指标 | C1 | C8 |
|---|---|---|
| 请求成功 / 计划 | 64/64 | 64/64 |
| 答案检查通过 | 64/64 | 64/64 |
| 排除与 5-shot 重叠的前 5 题后 | 59/59 | 59/59 |
| 达到输出上限 | 0 | 0 |
| 客户端总耗时 | 195.42 s | 55.55 s |
| 总输出 token | 6523 | 6530 |
| 整体 Output TPS | 33.38 | 117.56 |
| 接口接受长度,每题等权平均 | 6.9433 | 7.0070 |
| 直方图接受长度,按 verify 步数加权 | 6.4211 | 6.5158 |
| Draft 接受率,不含 bonus | 36.14% | 36.77% |
| Verify 步数 | 1026 | 1012 |
| 接受 / 提议 draft token | 5562 / 15390 | 5582 / 15180 |
| 请求回撤 | 0 | 0 |
这套 PP8 + PD + DFlash 已能完成本轮部署回归,接受长度没有停留在接近 1 的状态。 C8 的 117.56 token/s 是整体输出吞吐,包含 Prefill、传输、调度及 Decode,不是单请求 Decode 速度。本轮未重跑匹配的 no-spec 对照,不据此宣称投机加速倍数。
历史客户端的 5-shot 取自同一测试文件前 5 题,与这 64 题重叠,保留此口径用于历史部署回归。剩余 59 题也全部通过;本报告不将此结果作为独立无泄漏的模型能力评测。所有输出均包含 #### 最终答案,已独立按带符号数值重新解析并与标签比对。
接受长度为什么有两种数值
接口 spec_accept_length 在 tokenizer_manager.py:2814 定义为 completion_tokens / spec_verify_ct,受 P 侧首 token 和最后一步停止截断影响。例如一题输出 49 token、验证 3 次,接口值是 16.33;实际直方图为 3 次各接受 15 个 draft,含 bonus 的每步长度为 16,没有超出 block 能力。
加权接受长度 = 1 + 总接受 draft token / 总 verify 次数
C1 = 1 + 5562 / 1026 = 6.4211
C8 = 1 + 5582 / 1012 = 6.5158
128 题逐一验证了 sum(histogram)=verify_ct、直方图加权计数等于 accepted_drafts、proposed_drafts=15×verify_ct。接口原值完整保留。客户端是非流式,不由总耗时推造 TTFT/ITL。
4. 验证与运行状态
- 24 项 CPU 回归通过:13 项 PP/PD、7 项传输、4 项 Kimi MoE,覆盖 PP1/2/4/8/16、BF16/FP32 分段投影、TP4→TP32 全部 GQA head 映射、越界拒绝及输入生命周期。
- 601 GPU6 的 Kimi SM120 SiTU 布局与非连续输入集成回归通过;固化镜像独立 GPU 复测
1 passed。CPU 回归使用实际方法的 AST 提取与 CPU tensor,不是完整模型 logits 等价测试。 - Router smoke 和正式 C1/C8 全部完成。D 日志有 RDMA ready ACK 与实际 Decode CUDA Graph 记录。
- 本 Run 服务日志未检出 Traceback、CUDA OOM、KVTransferError 或非法显存访问。存在 NUMA 查询权限警告和 K3 fused KDA decode 布局回退提示,未阻断本轮;后续性能调优可单独审查。
- 运行中显存快照:P 每卡 53361-76579 MiB,D 每卡 79849-80019 MiB。这是离散快照,不是全程峰值。
- 续跑和清理均退出 0。601-608 本实验容器已删除,GPU compute process 为空,显存回落到 0-3 MiB。
5. 如何运行
唯一入口在 601;602-608 不需要手工再启动入口。配置见 config.env,请求由 bench_gsm8k_acceptance.py 生成。维护既有 GitLab 分支 hzy-kimi3-pd-pp8-standard。
cd /data/hzy/sskj/experiments/pro6000/kimi3_pro6000_pd_dflash_validation
# 展开命令,不使用 GPU
DRY_RUN=1 RUN_ID=pd-dflash-command-audit bash deploy_pd_dflash.sh all
# 新实验:八节点空闲后,入口负责启动、smoke、C1/C8、归档及清理
RUN_ID=pd-dflash-$(date +%Y%m%d-%H%M%S) bash deploy_pd_dflash.sh all
本次实际分两段执行,使用同一个 Run ID:
RUN_ID=pd-dflash-kvbounds1-20260831-1740 bash deploy_pd_dflash.sh all
# 服务和 smoke 成功后,客户端数据集路径报错。修正挂载,不重启服务:
RUN_ID=pd-dflash-kvbounds1-20260831-1740 bash deploy_pd_dflash.sh bench
RUN_ID=pd-dflash-kvbounds1-20260831-1740 bash deploy_pd_dflash.sh logs
RUN_ID=pd-dflash-kvbounds1-20260831-1740 bash deploy_pd_dflash.sh stop
bench 只能复用已运行且配置匹配的服务;当前服务已清理,复测应使用新 Run ID 的 all。正式执行用 tmux 托管同一入口,没有新增 launch 脚本。
6. 原始结果与交付
601 原始目录:
/data/hzy/sskj/experiments/pro6000/kimi3_pro6000_pd_dflash_validation/
results/pd-dflash-kvbounds1-20260831-1740/
bench/gsm8k_c1.jsonl # 逐题输出及原始 meta_info
bench/gsm8k_c8.jsonl
bench/gsm8k_c1_summary.json
bench/gsm8k_c8_summary.json
commands/ # 8 条 docker run、Router、2 条 bench
logs/p_0.log ... p_3.log # P 四节点
logs/d_0.log ... d_3.log # D 四节点
logs/router.log
metadata/post_run_resources.txt # 八节点清理核验
result_validation.json # 独立答案/统计复核及证据 SHA256
本地副本:/Users/hzy/Desktop/infra/docs/evidence/kimi_k3_pd_dflash/results/pd-dflash-kvbounds1-20260831-1740/。轻量结果、完整服务日志与补丁随 GitLab 提交;模型与约 14GB OCI 镜像归档保留服务器,不纳入普通 Git。
首段 exit_code=1 如实保留,对应容器内数据集 ../ 路径错误;修复后 bench_resume_exit_code=0、cleanup_exit_code=0。失败客户端命令和日志另存为 gsm8k_c1.dataset_path_failure.*。此前 P 预热和混合池层范围两次失败保留独立 Run,未混入本轮评测结果。