CANN预填充微批次双流
案例:Prefill Micro-Batch 双流流水
【免费下载链接】cannbot-skillsCANNBot 是面向 CANN 开发的用于提升开发效率的系列智能体,本仓库为其提供可复用的 Skills 模块。项目地址: https://gitcode.com/cann/cannbot-skills
概述
这个案例解决的是 prefill 阶段“计算和通信串行,通信空洞明显”的问题。做法是把输入拆成两个 micro-batch,让两条流分别承载不同 micro-batch,并通过record_event/wait_event把 dispatch、expert、combine 等阶段流水化,最适合计算和通信都比较重的 prefill 场景。
背景与问题
prefill 常常是计算 bound,但在大模型的 EP 场景里,MoE 的 dispatch 和 combine 也会带来显著通信开销。如果这些阶段完全串行,芯片在等待通信或等待计算时都会出现空洞,造成端到端吞吐下降。
把 prefill 切成两个 micro-batch 后,虽然单次 shape 会变化,但如果计算和通信的线性度足够好,就能用一条流做当前 micro-batch 的计算,用另一条流穿插上一个或下一个 micro-batch 的通信,从而实现通信隐藏。
核心思路
- 创建主流
cur_stream和副流stream1。 - micro-batch 0 和 micro-batch 1 在不同流上生成输入。
- Attention、gate、dispatch、expert、combine、finalize 不再线性执行,而是借助 event 形成流水。
- 这种案例的重点不是“简单双流”,而是“多阶段事件编排”。
执行编排图
关键代码
第一段代码是双流入口,最核心的是先创建副流:
self.micro_batch_mode = MicroBatchMode(...) if self.micro_batch_mode != MicroBatchMode.DISABLE: self.stream1 = torch.npu.Stream()第二段代码展示最基础的两条流分别处理两个 micro-batch:
cur_stream = torch.npu.current_stream() with torch.npu.stream(cur_stream): hidden_states_mb0, residual_mb0, _, cos_sin_mb0, slot_mapping_mb0, actual_seq_lengths_kv_mb0 = \ self.prepare_inputs_for_layer(input_ids_mb0, kv_len_mb0, position_ids, actual_seq_lengths_kv_mb0, is_prefill) with torch.npu.stream(self.stream1): hidden_states_mb1, residual_mb1, _, cos_sin_mb1, slot_mapping_mb1, actual_seq_lengths_kv_mb1 = \ self.prepare_inputs_for_layer(input_ids_mb1, kv_len_mb1, position_ids, actual_seq_lengths_kv_mb1, is_prefill)第三段代码展示事件驱动的 dispatch/expert/combine 流水:
event_routing_dispatch_mb0 = cur_stream.record_event() with torch.npu.stream(self.stream1): self.stream1.wait_event(event_routing_dispatch_mb0) tokens_per_expert_group_mb0, gathered_tokens_mb0, gathered_pertoken_scale_mb0, input_splits_mb0, \ output_splits_mb0 = decode_layer.forward_dispatch_double_routing( tokens_per_expert_mb0, expanded_x_mb0, pertoken_scale_mb0 ) event_dispatch_expert_mb0 = self.stream1.record_event() cur_stream.wait_event(event_dispatch_expert_mb0) new_x_mb0 = decode_layer.forward_expert( gathered_tokens_mb0, tokens_per_expert_group_mb0, gathered_pertoken_scale_mb0 ) event_expert_combine_mb0 = cur_stream.record_event()复用参考
- 代表实现:DeepSeek-R1 prefill。
- 相似实现:其他 EP + micro-batch 场景可参考其事件编排方式。
- 特化实现:SP-TP-EP 与 DP-EP 可能采用不同流水版本。
注意事项
- shape 切半后如果算子性能显著劣化,双流可能收益变差。
- event 顺序稍有错误就可能造成死等、早读或精度异常。
- 双流只是手段,真正关键是 dispatch、expert、combine 的排列顺序。
关键词
torch.npu.Streamrecord_eventwait_eventmicro-batchdispatchcombine
【免费下载链接】cannbot-skillsCANNBot 是面向 CANN 开发的用于提升开发效率的系列智能体,本仓库为其提供可复用的 Skills 模块。项目地址: https://gitcode.com/cann/cannbot-skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考