AI 纪元 追踪人工智能最新进展,深度解读前沿技术

迁移昇腾 910C/910D,先查算子、显存和 HCCL

把 CUDA/PyTorch 项目迁到昇腾 910C/910D,常见卡点集中在自定义算子与动态 Shape、显存碎片、HCCL 多卡通信。文章按排查顺序给出配置示例,并说明哪些参数只能用于定位,不能代替根因分析。

0 次阅读 约 2741 字 5 分钟 AI 生成
Macro shot of a high-performance AI accelerator circuit board
Macro shot of a high-performance AI accelerator circuit board

对已经在 CUDA/PyTorch 上跑通模型的团队,换到昇腾 910C/910D,时间往往花在软件栈适配上。经济观察网在《华为算力“开链”》中提到,从英伟达迁移到昇腾,需要把基于 CUDA 的代码重新适配到 CANN,早期过程耗时耗力。

硬件参数可以帮助选型。一份公开资料整理给出的数据是:昇腾 910C 的 FP16 算力约为 800 TFLOPS,显存带宽约为 3200 GB/s;H100 对应约为 990 TFLOPS 和 3352 GB/s。这些数字适合做纸面对照,无法直接换算成模型迁移后的吞吐。算子有没有下沉、Dynamic Shape 是否反复编译、显存怎么分配,以及 HCCL 是否稳定,都会影响结果。

算子报错,先查版本和下沉情况

开工前先记录 CANN、torch-npu、PyTorch 和模型框架的版本。版本组合没有固定下来,同一处报错可能被反复归因于模型代码,排查会很乱。

即使项目已经使用 CANN 8.0 或后续版本,也不要默认自定义 Attention、特殊 RoPE 旋转位置编码、修改过的激活函数都能直接运行。遇到不支持的算子,可以按下面的顺序处理:

  • 先查 AclOps 等昇腾内置算子库,确认是否存在功能等价的实现。能够替换封装,就不要急着重写整段计算。
  • 当前版本组合支持时,再尝试用 PyTorch 2.x 的 torch.compile 配合 CANN Backend,观察子图能否被识别和融合。
  • 确实没有等价算子,再考虑自定义实现,并用最小输入先验证结果和性能。

直接用 Python 拼出相同功能,有时可以先通过正确性测试。接下来还要确认算子是否真正下沉到 NPU、是否打断子图融合。只看程序能不能执行,很容易把“跑通”误当成“迁完”。

跑着停几分钟,先看 Dynamic Shape

长文本训练和推理中,Token 长度不断变化,算子输入维度也跟着变。Shape 改变后,CANN 可能触发即时编译。训练任务突然停住几分钟,未必已经死锁,可以先查编译日志和 Shape 变化。

常用处理方式是做 Bucket:把输入长度向上对齐到 1024、2048 等固定档位,减少编译变体。档位不能照搬,需要根据实际长度分布调整。档位太密,编译次数仍然很多;跨度太大,又会带来额外 Padding。

正式运行前还可以预热常见 Bucket。排查时把首次执行耗时和稳定运行后的耗时分开记录,否则编译时间会混进性能数据,导致前后结果无法比较。

32GB 显存用了 20GB 仍然 OOM,先看碎片

任务显示用了 20GB,不代表剩余显存中一定存在满足下一次申请的连续空间。模型频繁创建、销毁临时 Tensor,可能留下难以复用的空闲块。PyTorch NPU 内存分配器与 CUDA 原生分配器的回收和合并方式并不完全相同,CUDA 上沿用多年的参数不能原样照搬。

可以先用下面的配置做对照测试:

export PYTORCH_NPU_ALLOC_CONF=max_split_size_mb:128

128 更适合作为排查起点,不是所有模型的固定答案。需要在相同 Batch、序列长度和模型配置下,对比峰值显存、缓存水位和稳定运行吞吐,再决定是否保留。

另外两项也值得检查:

  • 在 Epoch 或明确的阶段边界调用 torch.npu.empty_cache(),释放当前未使用的缓存。它可能带来性能抖动,也无法释放仍被引用的 Tensor,不适合每一步都调用。
  • 当前版本支持时,可在 0.8 到 0.9 之间测试 garbage_collection_threshold,观察提前回收是否改善显存水位。

如果显存占用随着迭代持续上涨,问题可能不只在分配器,还要检查临时 Tensor 的生命周期。FP8、INT4 处理的是物理容量以及精度、性能之间的取舍,不能代替碎片排查。

HCCL 超时,先别只调大 Timeout

单卡正常、多卡挂起,是昇腾迁移中很容易误判的一类问题。HCCL 报出的 Timeout 往往出现在链路末端:某张卡正在做 JIT 编译或垃圾回收,网络出现拥塞,光纤或物理网卡异常,都可能让其他进程一直等待。

原稿中的两个参数可以保留,但应当作为诊断配置使用:

export HCCL_CONNECT_TIMEOUT=1800
export HCCL_BUFFSIZE=128

HCCL_CONNECT_TIMEOUT=1800 的单位是秒。它能提高任务对慢启动的容忍度,却不会修复真正的通信死锁。HCCL_BUFFSIZE=128 调整了通信缓存,是否有效要靠压力测试确认。排查时每次只改一项,并保留对应日志,避免最后无法判断是哪项配置产生了影响。

正式跑大任务前,先用 hccl-tools 做 AllReduce 压力测试,逐卡、逐节点检查带宽和稳定性。进入 TP、PP、EP 混合并行后,尤其是包含大量 All-to-All 通信的 MoE 模型,建议先在单机小规模下验证,再扩大到多机集群。

华为在2025 年全联接大会演讲中把超节点互联列为 AI 基础设施的重点,并提到研发团队从春节持续到 4 月 30 日,使 Ascend 910B/910C 的推理能力达到客户基本需求。平台能力在更新,用户侧仍要针对自己的拓扑做压测。机房中的光纤、网卡和参数配置,不能靠调大超时时间绕过去。

性能验收别只看 TFLOPS

昇腾迁移的验收数据,应该来自同一模型、同一批输入和同一套并行配置。至少要分开记录算子正确性、首次编译耗时、稳定运行吞吐、峰值显存和通信耗时。

MFU 也需要放在具体负载中比较。模型结构、Batch、序列长度和并行方式不同,直接套用其他集群的目标值没有多少参考意义。纸面上的 800 TFLOPS 与 990 TFLOPS,更不能直接推出集群成本高低。Dynamic Shape 反复编译、显存碎片导致任务重启,或者 HCCL 长时间等待,都会消耗实际可用算力。

更稳妥的迁移顺序是:

  • 算子级验证结果,并确认计算下沉到 NPU。
  • 用静态 Shape 建立单卡性能基线。
  • 加入 Dynamic Shape 和 Bucket,处理编译与显存问题。
  • 在单机多卡上先跑 hccl-tools,再运行完整模型。
  • 最后扩展到多机,并逐步加入 TP、PP、EP 等并行方式。

跳过单卡基线直接上大集群,最后看到的 HCCL 超时,很可能只是前面问题被放大后的结果。

参考资料

相关阅读