DeepSeek-V4 中的算子 Overlap 分析
DeepSeek-V4 中的算子 Overlap 分析
DeepSeek-V4 的架构图有一个特点:本身就是一份并行性说明书。画成并行分支的模块,基本都是在告诉系统实现者”这里有 overlap 的空间”。本文梳理 V4 中可 overlap 的算子对,对照论文承诺与 SGLang 实现现状。
一、Overlap 的三个前提
- 算法独立 — 两条路径无数据依赖(论文画成并行分支)
- 资源不冲突 — 不争用同一 SM 或同一 buffer
- 工程可兜住 — CUDA stream / multi-kernel launch 的硬件支持
DeepSeek 的特殊性在于:MoE + MHC(Multi-Head Compressor)双重稀疏结构,天然产生多条独立路径。
二、Attention 分支内的 Overlap
2.1 wqkv_a 与 Compressor 的 Overlap
数据依赖
1 | wqkv_a: 输入 = hidden (x) |
两者都读 hidden,但 compressor 不依赖 wqkv_a 的输出,可以完全并行。
资源 pattern 互补
| Kernel | 性质 | 瓶颈资源 |
|---|---|---|
wqkv_a GEMM (M=4096, N=2112, K=7168) |
中 GEMM | MFU ~30-40%,CU 大量闲置 |
compressor flash_c4 / flash_c128 |
memory-bound | HBM 带宽吃满,MFMA 单元闲置 |
一个 compute-bound 倾向,一个 memory-bound 倾向,硬件资源不冲突。
L2 Cache 共享
hidden 的大小:[4096, 7168] BF16 = 56 MB,接近 MI355X 的 L2 cache(32 MB)。
- 串行:
wqkv_a读完hidden,compressor再读——大概率已被q_b挤出 L2,又一次从 HBM 读 - 并行:两个 kernel 同时从 HBM 拉
hidden,第二次的 cache line 是免费的
2.2 Indexer 的 Overlap:只依赖 q_a,不依赖 q_b
这是 V4 论文里 “MLA Co-Design with Indexer” 的核心设计。
Indexer 两条路径的依赖
1 | Indexer K-side: W_K^I · x → RoPE → summary_K |
q_b 是 critical path 上最重的 GEMM(929 µs),indexer 不等 q_b 完成就可以启动。
为什么 Q-side 用 q_lora 而不是 hidden
V4 论文的算法决策:
- 实验结论:召回率无差异
- 系统收益:每层省一次
[T, 7168] → [T, ...]的大 GEMM - 代价:Q-side 多一个
q_lora_readyevent 依赖(K-side 完全自由)
代码里精确实现了这个依赖:
1 | # K-side:不依赖 q_lora,可以立刻启动 |
2.3 三者在时间轴上的 Overlap
1 | 时间轴(prefill 4096 tokens,典型层): |
端到端时间 = max(q_b, indexer, compressor, kv_write) = ~1012 µs(由 q_b 主导)
串行时 = wqkv_a + q_a + q_b + indexer + compressor + kv_write = ~2290 µs
三、MoE 分支内的 Overlap
3.1 Shared Expert 与 Routed Expert
两条 expert 路径完全独立,SGLang 用 alt_stream 实现,是已实现的最好案例。
3.2 MoE Wave 模型:计算与通信 Overlap
Wave 分 chunk 乒乓:dispatch → compute → combine 流水,掩盖全量通信延迟。V4 论文 Fig.5 的时序图明确画出了这一点。
3.3 Combine 通信与 Shared Expert 尾部计算
Combine(NVLink all-to-all)不需要 shared expert 的完整输出,可以和 shared expert 的 down_proj 最后一部分 overlap。SGLang 目前串行等待,未利用。
四、为什么 Multi-Stream Overlap 能赚到时间
CUDA stream 是 GPU 上的 FIFO 工作队列;stream 本身只给调度器自由度,性能要靠”互补的资源占用”赚出来。
机制 1:单 Kernel 资源利用率低(最主要)
q_b 把计算压满但 HBM 闲;swa_scatter 把 HBM 压满但计算闲。不同 stream 让它们同时跑,各用各的硬件资源。
机制 2:小 Kernel Grid 填不满 SM
MI355X 有 256 个 CU,但 trace 里很多 kernel 的 grid 很小(rocprim cumsum 只有 1 个 CU,占用率 0.4%)。多 stream 让调度器把多个小 kernel 同时塞进 CU。
机制 3:隐藏 CPU Launch Overhead
每次 hipLaunchKernel 在 host 端要 ~3-5 µs。Trace 里 ~30000 个 kernel × 4 µs ≈ 120 ms 纯 launch 开销。多 stream 让 host 预先 enqueue,GPU 不饥饿。
机制 4:同源输入的 L2 Cache 共享
wqkv_a 和 compressor 都读 hidden,并行时第二次读直接 cache hit,省 ~20% 输入带宽。
反向判断:什么情况下多 Stream 不赚
| 场景 | 多 stream 是否有用 | 原因 |
|---|---|---|
| 两个高 MFU GEMM(都跑 70%+) | ❌ | SM 都被占满,只是 timesharing |
| 两个 memory-bound op 读不同数据 | ❌ | HBM 总带宽是上限 |
| 两个 op 有数据依赖(A → B) | ❌ | 必须串行 |
| 一个 compute-bound + 一个 memory-bound | ✅ | 经典 case |
| 一个大 GEMM + 一群 µs 级小 kernel | ✅✅ | 赚得最多 |
五、工程实现:SGLANG_OPT_USE_MULTI_STREAM_OVERLAP
这个关键优化靠一个环境变量控制,不在 --help 里:
1 | # 开启 |
读取位置在 sglang/srt/layers/deepseek_v4.py 的 _forward_prepare_multi_stream 方法入口,通过 os.environ.get() 判断,默认关闭。
实测效果
在 decode 阶段(batch size 中等,61 层 DeepSeek-V4),开启后整体 forward 有 ~3.5% 的端到端提升:
| 状态 | forward latency (decode) | 相对提升 |
|---|---|---|
| 关闭(串行) | 基准 | — |
| 开启(multi-stream overlap) | -3.5% | ✅ |
提升主要来自:
q_bGEMM(929 µs)与 indexer + compressor 并行:decode 时q_b仍是瓶颈,但 indexer K-side 和 compressor 可以完全隐藏在其执行期间- 小 kernel(swa_scatter、cumsum 等)与主体 GEMM 并行:这些 µs 级 kernel 在串行时被
q_b的 launch gap 放大,overlap 后基本被吸收
注意:3.5% 是 decode 阶段的收益。prefill 阶段因为
q_b的 GEMM 更大(M=4096),overlap 的相对收益会被稀释,但绝对时间节省更显著(每层 ~1.28 ms,61 层 ~78 ms)。
没开时,整个 _forward_prepare_multi_stream 退化成串行,论文里”sparse attention 模块在 prefill 阶段近乎 free”的 claim 直接失效。
六、对照论文图:承诺 vs 现状
| 论文图中的结构 | 论文章节 | 承诺的并行性 | SGLang 状态 |
|---|---|---|---|
| Indexer ∥ wqkv_a | §3.2.2 | 双分支并行 | ✅ 算法并行,⚠️ 需 SGLANG_OPT_USE_MULTI_STREAM_OVERLAP=1 开启 |
| Compressor c4 ∥ c128 | §3.2.1 | 双尺度评分并行 | ❌ 串行 |
| Shared ∥ Routed Expert | §3.3 | 双 expert 路径并行 | ✅ 已实现 |
| Wave dispatch/compute/combine | §3.3.3 | 乒乓 overlap | ✅ 已实现 |
| KV store ∥ next layer indexer | §3.2 | 层间 pipeline | ❌ 未做 |
七、总结
DeepSeek-V4 论文在算法层面为 overlap 留了很大空间,尤其是 Fig.3(MHC 结构)和 Fig.5(Wave 时序图)。当前 SGLang 实现只吃到了 Shared Expert / Wave 的部分,仍有明显优化空间。
实测数据验证了 overlap 的价值:
- decode 阶段:开启
SGLANG_OPT_USE_MULTI_STREAM_OVERLAP,整体 forward 提升 ~3.5% - prefill 阶段:每层节省
1.28 ms,61 层共 **78 ms**,sparse attention 模块接近”free”的目标
更一般的启示:算法论文画依赖图时多想一步系统实现,系统实现时多对照论文的并行性承诺。
参考:DeepSeek-V4 论文(arXiv:2606.02405)§3.2 Attention Mechanism, §3.3 Expert Mixture, §3.3.3 Dynamic Expert Routing & Wave Scheduling