Pull Request已成功合入, 合并人@ascend-robot
(感谢 isfrapples 的贡献)变更摘要
本 PR 为 DeepSeek-V4 模型实现了 TND(变长序列)布局下的 Context Parallelism + 前缀 KV 特性。核心改动包括:引入 LayerCompressMode 枚举统一压缩模式判断;在 kvallgather CP 路径上支持 TND 布局的前缀 KV gather、截取与重排;将多个融合算子按 TND/BSND 布局拆分以消除不必要的 chunk 操作;修正 TND 下 indexer loss 反向传播的 num_seqs 计算;以及新增 --ring-degree 参数和 tnd 参数传递链。
主要改动
-
引入
LayerCompressMode枚举并重构压缩逻辑:在g2_attention.py中新增LayerCompressMode枚举(NO_COMPRESS/COMPRESSOR_ONLY/INDEXER),替代原有compress_ratio与魔数(1、4)的直接比较;同时支持 compressor 返回None时将cmp_ratio降级为 1 并跳过稀疏 attention。 -
TND 布局下前缀 KV 的 gather 与重排:在
deepseek_utils.py中新增slice_tnd_kv_prefix、_compute_prefix_kv_cu_seqlens、_rearrange_prefix_kv三个辅助函数;g2_attention.py的 forward 中,TND 布局下先 gather 所有 rank 的 KV,再按本 rank 偏移截取前缀段并重排,同时派生本地cu_seqlens_q/cu_seqlens_kv,使前缀 KV 的 cu_seqlens 与注意力算子期望匹配。 -
kvallgather CP 路径按布局拆分为 TND/BSND 分支:在
dsa_indexer.py中将fused_sparse_attn_shared_kv_kvallgather、fused_lightning_indexer_with_compress_kvallgather、fused_sparse_flash_mla_with_indexer_loss_kvallgather拆分为_tnd和_bsnd内部实现:TND 下直接透传不 chunk,BSND 下保留原有双段 chunk 逻辑。 -
TND 布局下 indexer loss 的
num_seqs修正:在npu_sparse_flash_mla_with_indexer_loss.py的 backward 中,TND 布局下通过all_gather_into_tensor收集各 rank 本地 token 数求和得到全局num_seqs,替代原先错误的query_index.shape[0];同时将grad_scale存入ctx以避免多层反向时的类变量竞态。 -
新增
--ring-degree参数与tnd参数传递链:在context_parallel_feature.py中新增--ring-degree参数(默认 1);在gather_from_sp_cp中增加tnd参数,tnd=True时跳过permute_cp_shard重排;在all_gather_qk_weight_kvallgather中增加tnd参数控制 TND 下跳过 key/weight 的 all-gather。


代码审查
Now I have completed the review. Let me provide the closing summary.
审查总结
审查范围:共审查了 8 个变更文件,逐一核实了每个文件的变更内容及上下文。
发现问题统计:
- P2:1 个
- P3:1 个
- P0/P1:0 个
各文件审查结论:
| 文件 | 结论 |
|---|---|
mindspeed_llm/core/context_parallel/kvallgather_context_parallel.py |
无问题 — 移除了未使用的 import,为 gather_from_sp_cp 新增 tnd 参数以支持 TND 布局跳过 CP permute,清理了函数签名格式 |
mindspeed_llm/features_manager/context_parallel/context_parallel_feature.py |
无问题 — 新增 --ring-degree 命令行参数 |
mindspeed_llm/ops/npu_lightning_indexer.py |
无问题 — TND 布局下 cmp_residual_k 改为必需参数并抛出明确错误,所有调用方已同步更新 |
mindspeed_llm/ops/npu_sparse_flash_mla_with_indexer_loss.py |
1 个 P3 — 默认 tensor 缺少 device= 参数(与同 PR 中 DSAIndexerLossAutoScaler 的修复不一致);此外 backward 中 TND 布局的 num_seqs 计算改为跨 rank all_gather,逻辑正确 |
mindspeed_llm/tasks/models/transformer/deepseek4/compressor.py |
无问题 — gather_from_sp_cp 职责移至调用方,新增 freqs_list 为空的 early return 正确处理 |
mindspeed_llm/tasks/models/transformer/deepseek4/deepseek_utils.py |
无问题 — 新增的 slice_tnd_kv_prefix、_compute_prefix_kv_cu_seqlens、_compute_local_cu_seqlens、_rearrange_prefix_kv 等 TND 前缀 KV 工具函数逻辑正确 |
mindspeed_llm/tasks/models/transformer/deepseek4/g2_attention.py |
1 个 P2 — kv_compress.detach() 无条件切断 COMPRESSOR_ONLY 模式下 compressor 的梯度流;其余变更(LayerCompressMode 枚举、get_freqs_cis CP offset、前缀 KV 处理、TND/BSND 分发)逻辑正确 |
mindspeed_llm/tasks/models/transformer/dsa_indexer.py |
无问题 — TND/BSND 分支拆分合理,cmp_residual_k 计算和传递正确,DSAIndexerLossAutoScaler 的 device 修复正确 |
整体风险评估:中等风险。P2 问题影响 COMPRESSOR_ONLY 模式(compress_ratio > 1 且 != 4)下的 compressor 训练,若该模式实际被使用则会导致 compressor 无法学习。建议在合入前确认 COMPRESSOR_ONLY 模式的使用场景,并根据结论调整 detach() 的作用范围。
| 类型 | 数量 |
|---|---|
| 🔴 阻塞 | 3 |
| 🟡 建议 | 2 |
⛔ 需要修改


Pull Request 已合并或已关闭。
If you want to solve this problem, you can click here to do it in the FAQs.


What this PR does / why we need it?
Does this PR introduce any user-facing change?
--ring-degreeargument for ring context parallel configurationcmp_residual_kexplicitly for TND layout innpu_lightning_indexerkvallgather_cp_algowith packed TND sequencesHow was this patch tested?
fixes#1663