想象你开了一家餐厅,要做一盘番茄炒蛋。你需要的不是一口锅,而是一整套东西:菜谱、切菜案板、燃气灶、锅铲、盘子。MindSpore 和 CANN 的关系差不多就是这样------MindSpore 管"做什么菜",昇腾CANN 管"用什么灶、怎么大火快炒"。
昇腾NPU 是餐厅的专用灶台------火力猛但需要专业的燃气管道(CANN)来驱动。MindSpore 是主厨,CANN 是整个后厨的工程系统。很多人把 AI 框架和推理引擎弄混,觉得有 PyTorch 就够了为什么还要 CANN。这篇文章用最白的话拆开来讲清楚。
AI 框架是菜谱,CANN 是燃气灶
MindSpore 是 AI 框架。它的工作是:你告诉它"我要训练一个 Transformer 模型",它帮你把网络结构搭起来、把自动微分算出来、把梯度回传的链路画好。你写 Python 代码时调用的那些 nn.Dense、nn.Softmax、loss.backward()------这些都是框架层面的东西。
CANN 是底层的异构计算架构。它的工作是:MindSpore 说"这一步要在 NPU 上做一个 MatMul",CANN 负责把这个 MatMul 真正推到昇腾NPU 上去跑完,然后把结果拿回来。
两者的分工非常清晰:
- MindSpore 管:网络结构怎么搭、梯度怎么算、参数怎么更新、训练循环怎么写
- CANN 管:算子怎么在硬件上跑、内存怎么分配、计算图怎么优化、推理怎么调度
没有 MindSpore,你要手动写训练逻辑------从自动微分到参数更新全自己来。没有 CANN,你的 MindSpore 代码只能跑在 CPU 上,NPU 的算力完全用不上。
图编译:菜谱变成执行清单
MindSpore 跟 PyTorch 一个关键差异是图编译机制。PyTorch 默认动态图------每执行一行 Python,就当场调用底层算子跑一次。MindSpore 走图编译路径------先把整个网络编译成一张静态计算图,再交给底层。
图编译的好处是:框架拿到完整网络后可以做全局优化------把小算子合并、消除冗余计算、预分配所有 Tensor 内存。这些在 PyTorch 逐行执行下很难做,A 算子的结果刚写进显存,B 算子又读出来,中间浪费一次搬运。
用一个厨房的类比:PyTorch 是照着菜谱看一行做一步------"切番茄"→放下刀→"打鸡蛋"→放下碗→"开火"。MindSpore 先把整道菜过一遍,把连续动作打包------"切番茄和打鸡蛋同时做,开火前准备好所有材料"。
CANN 在图编译的下游干活。MindSpore 编译好的图经过 GE 的算子融合和内存优化后,才会下发给 Runtime 执行。
推理部署:框架退场,CANN 接棒
模型训练完后进入推理部署阶段,MindSpore 的角色变轻了。
训练阶段 MindSpore 负责:
定义网络 → 前向计算 → 损失函数 → 反向传播 → 参数更新
推理阶段只需要:
加载参数 → 前向计算 → 输出结果
所以推理时不再需要自动微分、不需要优化器、不需要训练循环。MindSpore 提供的 mindspore.export 接口把训练好的模型导出成 MindIR,然后用 ATC 工具转成 OM 格式。
到这一步,MindSpore 就退出了。OM 模型直接加载到 CANN 的 AscendCL 接口里跑推理------不经过 MindSpore 的任何运行时。
这就是"框架负责训练,CANN 负责推理"的分工。很多部署环境上只有 CANN Toolkit 没有 MindSpore------推理不需要框架。
Transformer 模型跑在昇腾上
以 LLaMA 为例,完整链路:
训练阶段(MindSpore + CANN):
Transformer 定义 → 自动微分 → 算子下发 CANN Runtime → NPU 执行前向+反向 → 参数更新
导出和转换:
保存 checkpoint → mindspore.export → MindIR → ATC 工具转 OM
推理阶段(只有 CANN):
OM 模型 → AscendCL 加载 → GE 图优化 → Runtime 调度 → NPU 逐 Token 生成
每个阶段的瓶颈不同。训练卡在反向传播和通信,推理卡在 KV Cache 和 Attention 的 Memory Bound。CANN 对两个阶段的优化侧重点完全不同------训练优化大 Batch 吞吐,推理优化低延迟和显存复用。
自动微分:框架的独门功夫
自动微分是 AI 框架区别于推理引擎的核心能力:给一个前向计算图,自动生成反向传播的梯度计算图。
MindSpore 的自动微分基于图编译时自动展开。框架在编译计算图时为每个算子注册对应的反向算子,前向图编译完成后反向图自动生成,不需要开发者写任何梯度代码。
CANN 没有这个能力也不需要------它只负责执行框架下发的算子,不管这些算子是前向还是反向。MindSpore 把反向算子也编译成计算图,通过 CANN 在 NPU 上执行。CANN 的视角里没有"前向"和"反向"的概念,只有"执行这个算子"和"执行下一个算子"。
三条简单判断
- 你想训练模型 → 用 MindSpore,CANN 在背后帮你跑在 NPU 上
- 你想做推理部署 → 只用 CANN(AscendCL + ATC + Runtime)就够了
- 你既要训练又要推理 → 训练阶段 MindSpore + CANN,推理阶段导出模型只用 CANN
弄明白这个分工,就不会在部署时困惑"到底要不要装 MindSpore"。
下一步
一个具体的推理部署场景
假设你刚训练好一个 BERT 文本分类模型,现在要部署到昇腾服务器做在线推理。为什么只在服务器上装 CANN 而不装 MindSpore?
前向推理的本质就是矩阵乘法和激活函数,不需要反向传播。你只需要 AscendCL 加载 OM 模型、在 NPU 上跑前向计算、拿回结果。MindSpore 的训练循环、优化器、自动微分这些代码在推理时根本不会被执行。
如果你在推理服务器上也装了 MindSpore,场景通常是:
- 推理过程中需要动态修改图结构(少见的场景)
- 推理服务同时承担模型微调任务
- 部署时直接用 mindspore 的推理接口(不经过 ATC 转换)
前两种情况确实需要 MindSpore,第三种情况建议还是走 ATC 转 OM 然后用 AscendCL 跑,性能更稳定。
为什么"图编译"在推理中这么重要
回到图编译这件事。MindSpore 把网络编译成静态图后,CANN 的 Graph Engine 对这张图做进一步优化------把多个算子融合成一个、把可以复用的 Tensor 放在片上缓存不走 DDR。这些优化在训练时收益有限(训练时图在变),但在推理时收益巨大。
一个 ResNet50 在 MindSpore 上训练时的计算图可能有几百个算子节点。CANN GE 优化后,推理时的执行图可以压缩到几十个融合算子。算子的 Launch 次数减少 80%,Memory 搬运减少 60%。这就是同样的模型在昇腾上做推理比做训练时每个 step 快几倍的原因之一。
atomgit : https://atomgit.com/