迁移开场并不复杂。70B 参数模型从 A100 集群搬到昇腾 910D 后,最早跳出来的是 CANN_OP_NOT_IMPLEMENTED。意思很清楚:CUDA 路径中的某个算子,在项目当时使用的 CANN 版本里,没有可直接调用的原生实现。
这种报错甚至算省时间。
真正拖进度的,是任务没有退出。算子可能悄悄转到 CPU,数据在 AICore 与 CPU 之间往返;动态 Shape 不断切割 HBM;单机 8 卡看着正常,扩到 64 卡后,AllReduce 长尾又开始吞训练时间。模型能启动,只能说明功能链路接上了,离连续稳定训练还差几轮排查。
华为《迈向智能世界白皮书 2024》把 CANN 放在昇腾开发体系的基础位置。2019 年的《鲲鹏展翅 昇腾万里 力算未来》讨论的也不只是芯片,还包括软件和 Atlas 900 AI 训练集群。放到迁移项目里,芯片参数只是验收表的一项,算子、内存、通信和版本组合都要单独过关。
数据口径:文中的 30%、70%、20% 和 15% 来自这次迁移记录;2—3 人、3—6 个月和延迟增加 50% 只是预算情景。换一个 CANN 版本、模型结构或网络拓扑,结果都可能不同。
报错好查,静默回退才难找
在 torch_npu 上,单卡跑通很容易让人误以为适配已经结束。如果关键路径没有原生算子,框架可能触发 CPU 回退。日志未必把问题写得很醒目,Host-to-Device 拷贝却会增加,吞吐一点点掉下去。
这次问题藏在第三方库里。一个被封装过的 index_select 走了 CPU 模拟路径,约占整段执行时间的 30%。它不是模型里最显眼的模块,却成了一个突出的耗时点。若不打开 npu_profiler 逐段看 trace,很容易把损耗笼统归到整机性能上。
FlashAttention-3 的某些变体、特定稀疏注意力机制等自定义算子,也要拆开验收。论文里出现得新,不代表项目所用的 CANN 版本已经有完全对应的实现。
迁移初期,算子审计表不必复杂,但下面几项要钉死:
- 固定 CANN、驱动和
torch_npu版本,保留一组可重复执行的输入。 - 从
npu_profilertrace 中标出 AICore、CPU 和数据拷贝耗时。 - 先找 CANN 已有的高性能算子;确实缺失,再评估用 TBE(Tensor Boosting Engine)开发自定义算子。
- 每替换一个算子,都复测结果正确性、执行时间和峰值显存。基线测试里出现意外 CPU 回退,直接记为失败项。
整网一次性重写看似省事,真正出回归时却很难找到责任点。逐个替换慢一些,但每一笔吞吐变化都能对上具体算子。
监控还有三成空闲,为什么还是 OOM
另一次排查更反直觉:监控显示显存使用约 70%,程序仍然报出 Out of Memory。继续减小 Batch Size 能缓一时,却不一定碰到根因。
原先在 CUDA 和 PyTorch Caching Allocator 下积累的经验,不能直接搬到 NPU。模型里有大量动态 Shape 时,HBM 会反复申请和释放不同尺寸的空间。长文本又会让 KV Cache 持续增长。剩余总量看起来够,新的内存申请却未必能找到合适大小的空间。
先收窄 Shape。 尽量固定输入长度,或者按长度分桶。本项目做过把长度 Padding 到 128 倍数的对齐,目的是减少不同尺寸的反复申请。128 只是这次的工程选择,不是通用答案。
再判断是否用计算换空间。 梯度检查点(Gradient Checkpointing)会增加重复计算,但能压低训练峰值显存。检查点开多少,仍要看实际吞吐,不能只看 OOM 是否消失。
把通信缓冲区单列出来。 HCCL_BUFFSIZE 影响通信缓冲区,同样会占用 HBM。调大之前,要把模型峰值和通信占用放在一起压测,否则可能进一步挤压模型空间。
每轮改动都应留下四项记录:输入 Shape、Batch Size、峰值显存和 OOM 出现位置。参数改了很多却没有记录,最后往往只知道任务能跑了,不知道是哪一步起了作用。
8卡跑顺后,先去看网络
单机 8 卡没有问题,不代表扩到 64 卡或 128 卡还能保持同样的效率。卡数增加后,问题的位置会变,HCCL(Huawei Collective Communication Library)的通信耗时开始进入主视野。
本次测试中,AllReduce 阶段出现过明显长尾,训练速度下降超过 20%。排查线索主要落在网络拓扑上:RoCE 物理链路与 HCCL 逻辑拓扑没有对齐时,交换机层面可能出现拥塞;驱动和固件版本不匹配,也会放大跨机通信的不稳定。
HCCS(Huawei Cache Coherent System)负责片间高速通信,但跨机速度仍然受底层网络和版本组合影响。到了这一步,继续盯着模型代码改,通常收效有限。
更省时间的检查顺序是:
- 核对 CANN、驱动和固件版本,生产集群不要混用未经共同验证的组合。
- 把 Rank、物理卡、服务器和 RoCE 链路逐项对应,确认逻辑拓扑与实际布线一致。
- 检查链路丢包和交换机拥塞,再决定是否调整模型并行策略。
- 开启计算与通信重叠,让梯度就绪后的
AllReduce尽量与反向计算并行。
项目把 HCCL_Wait 占比 15% 设为内部告警线。超过这条线,先查物理链路和拓扑,再动模型代码。15% 不是通用标准,值得保留的是这套排查次序。
卡价之外,迁移窗口也要进预算
采购 910D 时,单卡 TFLOPS 只能占成本表的一列。有效吞吐、迁移工时、后续维护和故障定位时间,都会改变最后的账。
如果内部评估需要额外投入 2—3 名熟悉算子开发和集群调优的工程师,或者迁移窗口可能拉到 3—6 个月,这些都应写进立项预算。两个数字只是风险情景,不是所有团队都会付出的固定成本。
延迟增加 50% 同样只用于压力情景。若真实压测出现这一结果,就要重新计算单位 Token 成本、服务容量和用户响应时间,不能只凭硬件采购价判断是否省钱。
一张任务级算力账单比宽泛的成本比较更有用。模型版本、输入长度、Batch Size、卡数、吞吐、失败重跑次数和运维耗时,都应该留档。国产替代是否划算,最后也要落到这组数据上。
别在64卡集群上补单卡的课
更稳的迁移顺序没有花活:
单卡功能验证 → 单机性能对齐 → 多机通信调优 → 生产环境压力测试
单卡阶段,先确认输出正确,清掉关键路径上的意外 CPU 回退。单机阶段,把算子耗时、峰值 HBM 和 Batch Size 固定成基线。扩到多机后,再集中看 AllReduce、HCCL_Wait、拓扑和链路状态。最后用真实业务负载重算吞吐、延迟和稳定性。
关键不只是走完四个阶段。上一阶段没有锁定版本和基线,就不要急着扩卡。否则在 64 卡集群上排查数小时,根因可能还是单卡阶段漏掉的一个小算子。
对昇腾 910D 迁移来说,一句“已经兼容”提供不了多少信息。更有用的是三张能复查的表:算子表写清 AICore、CPU 落点和耗时;HBM 表记录 Shape、Batch Size、峰值和 OOM 位置;HCCL 表对齐 Rank、链路、AllReduce 与 HCCL_Wait。换 CANN 版本、继续扩卡或进入生产压测时,这些记录就是可比的基线。