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

昇腾910C迁移,先查算子和通信

从 CUDA/PyTorch 迁到昇腾 910C,问题常不在模型代码本身,而在 CANN 算子、HCCL 拓扑和精度对齐。把这三处先跑通,后面的改造会少很多返工。

0 次阅读 约 2528 字 5 分钟 AI 生成
Close-up of server hardware components and circuit boards
Close-up of server hardware components and circuit boards

昇腾 910C 进入更多项目后,迁移工作开始从“能不能买到卡”转向“代码能不能稳定跑”。控制网曾提到,昇腾 910C 在 2025 年 5 月开启大规模供货;民生证券引用《昇腾计算产业发展白皮书》的数据也显示,2012 年开始的 6 年里,AI 计算需求增加了 30 万倍。算力需求是真实的,工程里的摩擦也是真实的。

华为在昇腾相关技术文章中把 CANN(Compute Architecture for Neural Networks)放在异构计算架构的位置。对开发者来说,这句话落到代码里,往往就是三件事:算子能不能编译,分布式通信会不会卡住,MindSpore 或 PyTorch-NPU 跑出来的结果能不能和原来对齐。

下面按迁移现场最容易反复踩的地方说。

OpNotSupport:先别急着改模型

CUDA 里能跑的 torch.ops,到昇腾环境下不一定能原样通过。CANN 需要把框架层的算子映射到底层实现,例如 TBE(Tensor Boost Engine)或 AICPU 算子。它不是简单替换 API,而是重新走一遍计算图编译和算子选择。

常见报错类似这样:

[ERROR] ACL (aclnn) fails to compile the TIK/CCE code.
Error Code: 1500018
Message: Operator 'MyCustomOp' is not supported on Ascend NPUs.

这类问题多出现在两种场景:一是 PyTorch 代码里用了自定义算子,CANN 当前环境没有对应实现;二是迁到 MindSpore 后,底层仍依赖未注册或未适配的 Python 钩子。

比较稳的处理顺序是:

  • 先查 CANN 算子支持矩阵,不要凭经验判断。尤其是自定义算子、稀疏算子、特殊归一化算子,先确认有没有原生支持。
  • 复杂模型可以用 ATC(Ascend Tensor Compiler)提前转 .om 离线模型,把问题暴露在转换阶段,而不是训练跑到一半才炸。
  • 如果算子暂时不支持,再考虑回退策略。MindSpore 场景下,可在调试阶段结合动态图模式把流程跑通,但要接受性能损失。

这里最忌讳的是一上来就大面积改模型结构。很多时候,问题不在模型,而在算子覆盖和编译路径。

HCCL 卡住时,日志可能什么都不说

单卡问题通常会报错,分布式通信问题更麻烦。昇腾用 HCCL(Huawei Collective Communication Library),CUDA 侧常见的是 NCCL。两者都做集合通信,但初始化、拓扑感知和进程映射不能照搬。

一个典型现象是:第一个 epoch 正常,第二个 epoch 开始前所有节点挂起,NPU 利用率降为零,日志里只有 TimeoutError,甚至没有明确错误栈。

这时要先看三件事:

npu-smi info -t topology

用它确认物理连接关系,再检查 hccl_topo.json 是否和实际机器、rank、端口映射一致。910C 集群里如果同时涉及 HCCS 高速互联和 RoCE 网络,拓扑文件写错,训练框架上层很难给出直观提示。

启动脚本里也建议显式设置通信参数,例如:

export HCCL_CONNECT_TIMEOUT=1800
export HCCL_PROCESS_REORDER=1

训练前单独跑 hccl_test 更省时间。这个测试都过不了,MindSpore 或 PyTorch 适配版通常也救不了。很多团队把时间花在改 dataloader、改训练循环,最后发现只是 rank 映射错了。

精度对齐,不要等验收时才查

迁到 910C 后,精度差异经常不是“大错”,而是很小的浮点偏差一路累积。CANN 编译器会做算子融合、并行拆分等优化,这些优化能提升性能,也可能让 CUDA 和 Ascend 的结果出现细微差别。

常见断言错误类似:

ValueError: The calculated loss differs from the reference value by more than 1e-4.
Assertion failed: diff < threshold

调试时可以先收紧变量:

  • 关闭过于激进的优化路径,例如在 AscendCL 配置里把 opt_mode 调到兼容取向,先看结果是否稳定。
  • 明确混合精度策略。PyTorch 里的 torch.cuda.amp 迁到 MindSpore 时,要检查 mindspore.amp 或 PyTorch-NPU 插件的行为是否一致。
  • 主梯度类型要统一。通常需要确保 Master Gradient 保持 FP32,避免 Cast 过程引入额外舍入误差。
  • LLM 推理场景可以评估 MindIE。知乎专栏资料中提到,MindIE 1.0.RC1 是昇腾面向 LLM 的部署方案;这类框架会把一部分算子和推理路径提前处理好。

精度问题最好在小 batch、小样本、固定随机种子的条件下先做对齐。不要等到完整训练跑完,才发现 loss 曲线从某一步开始分叉。

迁移顺序比“改多少代码”更重要

昇腾全栈可以按 Atlas 系列硬件、异构计算架构、AI 框架、应用使能、行业应用来理解。这个分层听起来偏架构,但对迁移排错很有用:底层没稳,上层越改越乱。

更实际的顺序是:

  1. 先装好驱动、固件和 CANN,确认 npu-smi 正常。
  2. 跑单卡最小模型,确认基础算子链路可用。
  3. 跑 hccl_test,确认多卡通信和拓扑文件没问题。
  4. 再迁移业务模型,逐个处理自定义算子。
  5. 最后做精度对齐和性能优化。

这样做看起来慢,实际能少走弯路。很多 910C 迁移问题,不是框架选 MindSpore 还是 PyTorch-NPU 的问题,而是算子、通信、精度三条链路没有分开验证。

国产算力落地到开发者手里,最后拼的不是口号,是这些具体而琐碎的工程动作。先把 CANN 编译、HCCL 拓扑和精度基线跑通,910C 的迁移才算真正进入可控状态。

相关阅读