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

CUDA 模型迁到昇腾,先过这几道坎

把 PyTorch 模型迁到昇腾 910C 和 CANN 8.0 环境,难点常落在算子支持、显存分配、分布式通信和调试链路上。迁移不只是替换设备名,更要重新检查算子、内存和 HCCL 配置。

0 次阅读 约 3101 字 6 分钟 AI 生成
Abstract representation of AI model migration between different computing architectures
Abstract representation of AI model migration between different computing architectures

“要是哪天像 DeepSeek 这样的成果先在华为平台上出现,那对我们国家会是非常糟糕的结果。”

经济观察网报道,4 月 15 日,英伟达 CEO 黄仁勋在接受美国科技播客主持人帕特尔专访时说了这句话。9 天后,DeepSeek V4 发布,分为 V4-Pro 和 V4-Flash 两个版本,上下文处理长度从上一代的 128K 扩展至 1M。同一天,华为宣布昇腾超节点。

这类新闻容易被写成宏大叙事。但对工程团队来说,问题更直接:原来跑在 CUDA 上的 PyTorch 模型,搬到昇腾 910C 和 CANN 8.0 环境后,能不能跑起来?跑起来以后,性能、显存和分布式训练能不能稳定?

迁移通常不是把 cuda 改成 npu 这么简单。真正耗时间的地方,往往藏在算子、显存、通信和调试工具里。

第一关通常不是性能,而是算子报错

很多团队第一次迁移时,先遇到的不是训练慢,而是模型直接起不来。

在 CUDA 环境里,一些复杂算子可以通过 torch.ops、第三方库或已有 CUDA 扩展解决。到了昇腾 910C + CANN 8.0,部分非标准算子可能没有现成实现,尤其是特定 Attention 变体、定制数据处理层,或者项目里长期沉淀下来的私有算子。

常见报错类似:

AICore error: operator not supported

这一般意味着当前算子没有被 AscendCL 或框架适配层正确承接。处理顺序可以更务实一点:

先查 CANN 的算子支持情况。CANN 8.0 相比旧版本扩充了对主流模型算子的覆盖,问题有时只是版本不一致。驱动、固件、CANN、torch_npu 之间的组合如果不匹配,报错会看起来像“算子缺失”,实际是环境没对齐。

如果确实缺算子,就要考虑 TBE 或 Ascend C 自定义算子。这个环节学习成本不低,但比在 Python 层用低效组合硬凑更可靠。对训练链路里的高频算子,绕开原生实现通常会把性能问题拖到后面集中爆发。

还有一种办法是从框架层处理。清华大学计图团队在 2025 年 1 月发布的适配信息中提到,计图框架已适配华为昇腾 910 系列,并与 CANN 8.0 接口融合优化。这个案例说明,框架侧统一算子注册和映射,能减少底层适配的重复工作。PyTorch 用户对应要重点检查 torch_npu 的算子映射;遇到不支持的自定义层时,可以尝试拆成标准算子组合,比如 Conv、BatchNorm、Activation 等基础模块。

显存问题,很多时候不是“卡不够大”

模型能启动以后,第二类高频问题是 OOM。

CUDA 下的显存管理经验,不能直接平移到 NPU。设备可见性、缓存策略、碎片整理、临时 buffer 复用方式都有差异。原来在 GPU 上刚好能跑的 batch,迁到昇腾后可能在某个算子处突然溢出;也可能小 batch 反复 OOM,大 batch 又影响训练稳定性。

排查时不要只盯总显存。更有用的是看峰值分配发生在哪一段:前向、反向、通信同步,还是数据预处理后的拷贝。

可优先做几件事:

  • 检查 CANN 的显存分配策略,必要时配置 ASCEND_RT_MEMORY_POOL,减少碎片带来的不稳定;
  • 在 PyTorch 迁移场景下,确认使用的是 NPU 相关接口,而不是残留的 CUDA AMP 或 CUDA 显存控制代码;
  • 对大模型训练启用 Gradient Checkpointing,用重新计算中间激活值换显存;
  • 混合精度训练使用 torch_npu.amp,不要继续沿用 torch.cuda.amp。

Loss Scale 也要单独观察。昇腾上的 FP16、BF16 行为和 GPU 环境不完全一样,如果训练发散,再去调整 init_scale、growth_interval 等参数;没出问题时,不建议一开始就把 GradScaler 改得很激进。

多卡训练要尽早检查 HCCL

单机单卡能跑,不代表多卡训练就稳。

进入多机多卡后,瓶颈经常从算子切到通信。GPU 时代常用 NCCL;昇腾集群里,对应要使用 Huawei Collective Communication Library,也就是 HCCL。在 PyTorch Distributed 环境中,后端需要明确指定:

backend = "hccl"

这里只改一行还不够。HCCL 对集群物理拓扑敏感,RANK_TABLE_FILE 配置是否正确,会直接影响进程和设备的对应关系。配置错了,轻则利用率波动,重则训练卡死或通信超时。

通信与计算的重叠也要重新做 Profiling。模型并行、张量并行、数据并行混用时,等待时间往往被隐藏在同步点后面。torch.npu.synchronize() 放得太频繁,会把本来可以异步执行的任务串行化;完全不放,又可能让错误定位变得困难。迁移初期可以先牺牲一点速度,把同步点放清楚,等链路稳定后再逐步收缩。

数据加载也别忽略。多进程 DataLoader、数据切片、CPU 到 NPU 的拷贝,如果和通信高峰撞在一起,会造成训练吞吐抖动。这里没有通用参数,建议从小规模任务开始压测,不要一上来就把集群资源全部打满。

调试工具换了,排障习惯也要换

CUDA 工程师熟悉 Nsight Systems、Nsight Compute。到了昇腾,常用的是 msprof 等 Profiling 工具。工具链不一样,排查节奏也要调整。

建议迁移阶段保留更完整的日志:

export MS_PROFILING=1
export ASCEND_GLOBAL_LOG_LEVEL=3

MS_PROFILING=1 可以帮助生成性能分析文件,再用相关工具查看算子耗时和通信耗时。ASCEND_GLOBAL_LOG_LEVEL 设为 3 或 4 时,日志会更详细,适合定位未知运行时错误。正式训练时再把日志降下来,避免 I/O 干扰。

更重要的是,不要把第一个验证任务做得太大。先用 2 到 4 卡检查模型逻辑、数据管道、混合精度和保存恢复,再逐步扩展。很多迁移问题在小规模时就会暴露:算子不支持、shape 推导异常、某个数据增强步骤仍在调用 CUDA、checkpoint 里保存了不兼容的设备信息。

这些问题如果拖到大规模训练时才发现,定位成本会高很多。

生态在补课,但工程债还要自己还

经济参考报 2026 年 4 月 27 日报道,昇腾计算生态已与 90 多个全球主流开源社区深度对接,对 70 余个全球主流大模型完成“0day 适配”与全链路优化,并全年向开发者开放 4000 卡算力资源。

这说明国产算力的适配条件正在改善。CANN 8.0、torch_npu、HCCL、框架适配层都在补齐能力,开发者不再只能从最底层摸索。

但具体到一个团队手里的模型,迁移成本不会自动消失。项目里用过哪些自定义算子,训练脚本里残留多少 CUDA 假设,显存峰值出现在哪里,分布式配置是否贴合集群拓扑,这些都要逐项过。

从 CUDA 到昇腾 CANN,真正的工作不是写一份“国产化替代方案”,而是把报错一个个清掉,把性能瓶颈一个个定位出来。先让模型稳定跑,再谈优化;先把算子、显存、通信三件事查清楚,再讨论集群效率。

对已经决定使用昇腾 910C 的团队来说,最实际的起点不是重写全套训练框架,而是从一次可复现的迁移开始:固定版本,固定模型,固定数据,记录每个报错和处理方式。工程账算清楚了,后面的规模化才有基础。

相关阅读