昇腾 MindSpore 入门:新手从装环境到跑出第一个模型(附踩坑)
昇腾 MindSpore 入门:新手从装环境到跑出第一个模型(附踩坑)
一提到深度学习框架,大家脑子里就是 PyTorch、TensorFlow。但如果你听说过昇腾,大概率也听过它的框架——MindSpore(昇思)。
很多人一看到"华为自研框架"就觉得门槛很高。其实真上手写一个模型,MindSpore 的代码和 PyTorch 有几分像。这篇文章带你用 CPU 跑通第一个模型,并把我自己踩的坑都列出来。
👥 适合谁:会一点 PyTorch、想了解 MindSpore 怎么写的同学。
✅ 看完你能收获:① 搞清 MindSpore 和 PyTorch 的关系;② 写出第一个能跑通的 MindSpore 模型;③ 避开我踩过的坑。
⏱️ 预计阅读 8 分钟,跟着动手约 30 分钟跑通。
📌 说明:本文代码在 CPU 上跑通(方便任何人复现);MindSpore 在昇腾 NPU 上只是把设备从 "CPU" 改成 "Ascend",其余代码一样。不涉及自定义算子和分布式训练。
一、MindSpore 到底是个啥?和 PyTorch 什么关系?
先把关系理清楚:
- PyTorch:Meta 出的框架,本来主要跑在 NVIDIA 显卡上;
- MindSpore(昇思):华为开源的 AI 框架,设计之初就和昇腾 NPU 深度绑定。
打个比方:
PyTorch 主要跑在 NVIDIA 显卡上,后来通过 TorchNPU 也能跑昇腾;
而 MindSpore 是华为自研的框架,设计上就和昇腾配合得更紧。
| PyTorch | MindSpore | |
|---|---|---|
| 背后公司 | Meta | 华为 |
| 默认硬件 | NVIDIA GPU | 昇腾 NPU(也支持 CPU/GPU) |
| 上手熟悉感 | 大家都熟 | 和 PyTorch 写法有几分像 |
| 优势 | 生态最大 | 和昇腾原生配合、全栈自主 |
一句话:你可以把 MindSpore 理解成"华为生态里的一个深度学习框架"。会 PyTorch,上手它会很快。
二、它和昇腾是什么关系?
在昇腾上,典型的链路是:
你的代码(MindSpore)→ CANN(软件栈)→ 昇腾 NPU(芯片)
这套是华为自家打通的,所以 MindSpore 在昇腾上往往"开箱就能识别 NPU"。
当然,PyTorch 通过 TorchNPU 也能跑昇腾。两者不冲突:
- 你已经熟 PyTorch → 用 TorchNPU 上手快;
- 你想深入华为昇腾生态 → MindSpore 是官方主推的路线。
三、先把环境装好(最容易卡的一步)
在写代码之前,先把环境配齐。新手最容易卡在"不知道怎么建虚拟环境",下面一步一步来。
3.1 先装 Python(选 3.9 或 3.10)
MindSpore 不像 PyTorch 那样追最新版 Python。一定要装 Python 3.9 或 3.10,不要用 3.12/3.13。
- 去 https://www.python.org/downloads/ 下载 Python 3.10 安装包;
- Windows 安装时务必勾选 “Add Python to PATH”,否则后面命令行找不到 python。
3.2 建一个虚拟环境
虚拟环境的作用:给 MindSpore 单独开一个"干净房间",不污染你电脑上其他 Python 项目。
在 PyCharm 里建(点鼠标就行):
- 打开 PyCharm → New Project;
- Location 填个目录,比如
mindspore_demo; - Python Interpreter 选 New environment using Virtualenv,基础解释器选你刚装的 Python 3.10;
- 点 Create。
建好后,PyCharm 底部 Terminal 里跑命令,就自动在这个虚拟环境里了。
3.3 安装 MindSpore
激活虚拟环境后(PyCharm 直接用 Terminal(终端)),执行:
pip install mindspore
如果下载特别慢或超时,换成国内镜像源:
pip install mindspore -i https://pypi.tuna.tsinghua.edu.cn/simple
后面用 Jupyter Notebook(
.ipynb)一段一段跑代码,PyCharm 右键就能直接建,不用单独安装。
3.4 注意 NumPy 版本兼容(这里很容易报红)
MindSpore 对 NumPy 版本有要求。如果你机器上是 NumPy 2.x,import mindspore 时经常直接报红/报错(类似 module 'numpy' has no attribute 'XXX' 或 ABI 不兼容)。
解决办法:把 NumPy 降到兼容版本:
pip install "numpy<2"
3.5 验证环境是否 OK
import mindspore as ms
print(ms.__version__)
能正常打印版本号,不报红,环境就装好了。
💡 装环境就记住一句:Python 3.10 + 虚拟环境 + 清华源 + numpy<2,基本不会出问题。常见报错统一在第五章的速查表里。
四、第一个 MindSpore 模型:手写数字识别(Jupyter Notebook 逐格跑)
我们用最经典的 MNIST,在 PyCharm 里用 Jupyter Notebook 一段一段跑。
4.1 在 PyCharm 里建一个 Notebook
- 右键项目名 → New → Jupyter Notebook(PyCharm 自带,不用额外装);
- 文件名随便起,比如
demo.ipynb; - 打开后选我们刚建的那个虚拟环境当解释器。
💡 如果你用的是 PyCharm 社区版(Community),右键可能没有 Jupyter 选项——要么用专业版,要么装个 Jupyter 插件,或者直接在命令行
jupyter notebook打开。
后面代码我都按"一格(cell)一段"给,你复制进一格,点左边运行按钮逐格跑即可。
4.2 第 1 格:导入库、指定硬件
import mindspore as ms
import mindspore.dataset as ds
import mindspore.dataset.vision as vision
import mindspore.dataset.transforms as transforms
import mindspore.nn as nn
from mindspore import Model
from mindspore.train.callback import LossMonitor
# 新手先写 "CPU";到昇腾 NPU 环境就换成 "Ascend"
ms.set_device("CPU")
4.3 第 2 格:下载并解压 MNIST
import os
import gzip
import urllib.request
base_url = "https://ossci-datasets.s3.amazonaws.com/mnist"
files = {
"train/train-images-idx3-ubyte": "train-images-idx3-ubyte.gz",
"train/train-labels-idx1-ubyte": "train-labels-idx1-ubyte.gz",
"test/t10k-images-idx3-ubyte": "t10k-images-idx3-ubyte.gz",
"test/t10k-labels-idx1-ubyte": "t10k-labels-idx1-ubyte.gz",
}
for save_name, gz_name in files.items():
folder = os.path.join("MNIST_Data", os.path.dirname(save_name))
os.makedirs(folder, exist_ok=True)
gz_path = os.path.join(folder, gz_name)
raw_path = os.path.join(folder, os.path.basename(save_name))
print(f"下载 {gz_name} ...")
urllib.request.urlretrieve(f"{base_url}/{gz_name}", gz_path)
print(f"解压 {gz_name} ...")
with gzip.open(gz_path, "rb") as f_in, open(raw_path, "wb") as f_out:
f_out.write(f_in.read())
os.remove(gz_path)
print("MNIST 数据准备完成!")

4.4 第 3 格:加载数据并预处理
# 加载 MNIST
train_ds = ds.MnistDataset("MNIST_Data/train", usage="train")
test_ds = ds.MnistDataset("MNIST_Data/test", usage="test")
def transform(dataset):
image_op = [
vision.Rescale(1.0 / 255.0, 0), # 像素归一化到 0~1
vision.HWC2CHW(),
]
dataset = dataset.map(operations=image_op, input_columns="image")
# 把标签从 uint32 转成 int32(CrossEntropyLoss 需要)
label_op = transforms.TypeCast(ms.int32)
dataset = dataset.map(operations=label_op, input_columns="label")
dataset = dataset.batch(batch_size=64)
return dataset
train_ds = transform(train_ds)
test_ds = transform(test_ds)
4.5 第 4 格:定义网络
# 注意:MindSpore 里叫 Cell,不叫 Module;前向函数叫 construct,不叫 forward
class Net(nn.Cell):
def __init__(self):
super().__init__()
self.flatten = nn.Flatten()
self.fc1 = nn.Dense(28 * 28, 128) # 对应 PyTorch 的 nn.Linear
self.relu = nn.ReLU()
self.fc2 = nn.Dense(128, 10)
def construct(self, x):
x = self.flatten(x)
x = self.relu(self.fc1(x))
return self.fc2(x)
net = Net()
4.6 第 5 格:封装模型并训练
# 损失函数 + 优化器
loss_fn = nn.CrossEntropyLoss()
optimizer = nn.Adam(net.trainable_params(), learning_rate=1e-3)
# 封装成 Model
model = Model(net, loss_fn=loss_fn, optimizer=optimizer, metrics={"accuracy"})
# 训练 3 轮
model.train(epoch=3, train_dataset=train_ds, callbacks=[LossMonitor()])

(训练后的最后一部分结果的截图,因为训练的批次数(step)比较多,所以不好截图将其完全呈现出来,就截了最后一部分的)
4.7 第 6 格:在测试集上评估
acc = model.eval(test_ds)
print("测试集准确率:", acc)
4.8 实际跑起来是什么样?
在 PyCharm 里逐格运行时,LossMonitor 会按每个 batch 自动打印 loss。能看到 loss 稳定在 0.1 上下、没有爆掉,就说明训练在正常进行。最后一格 model.eval() 会打印测试集准确率(我这次跑出来是 约等于97% 左右,你跑出来数字可能略有差异,属正常)。

4.9 和 PyTorch 对比一下,你会发现差别不大
| PyTorch | MindSpore |
|---|---|
nn.Module | nn.Cell |
forward(self, x) | construct(self, x) |
nn.Linear | nn.Dense |
| 自己写训练循环 | 有高层 Model.train() |
.to("cuda") | ms.set_device("Ascend") |
核心思想完全一样:搭网络、选损失、选优化器、喂数据、反复训练。只是名字换了几个。
五、我自己踩过的坑:常见问题对照
下面这些是实际跑这段代码时最容易卡住的地方,按真实遇到的顺序整理:
坑 1:MindSpore 不会自动帮你下载 MNIST,路径不对会报错
和 PyTorch 的 datasets.MNIST(download=True) 不一样,MindSpore 不会自动联网下数据,路径不对也会报"找不到数据文件"。
解决办法:用第四章第 2 格那段 urllib + gzip 手动下载解压,并确认目录结构是 MNIST_Data/train/...、MNIST_Data/test/...,和代码里 ds.MnistDataset("MNIST_Data/train", usage="train") 写的一致。下载慢就多试几次,或浏览器手动下 4 个 .gz 放好解压。
坑 2:设备到底怎么写?set_context 还是 set_device?
不同版本的 MindSpore 写法不一样,老教程常写:
ms.set_context(device_target="Ascend")
新版本里可以直接用更简洁的:
ms.set_device("CPU") # NPU 环境换成 "Ascend"
解决办法:新手先用 "CPU" 跑通逻辑,确认代码没错,再到昇腾在线环境把它改成 "Ascend"。这样排错最快,不用一边怀疑环境、一边怀疑代码。
坑 3:标签类型不对,报类型错误
MNIST 读进来的标签默认是 uint32,而 CrossEntropyLoss 要求 int32,直接训练会报类型不匹配。
解决办法:在预处理里加一句类型转换:
label_op = transforms.TypeCast(ms.int32)
dataset = dataset.map(operations=label_op, input_columns="label")
坑 4:MindSpore 对 Python 版本有要求,版本太高装不上
这是最容易劝退新手的一个坑:MindSpore 不像 PyTorch 那样追最新版 Python。如果你装了最新的 Python(比如 3.12、3.13),pip install mindspore 时很可能找不到对应版本的包,报"没有匹配的 wheel / Could not find a version"。
解决办法:
- 别一上来就装最新 Python,选 MindSpore 官方支持的版本(一般 3.9 / 3.10 比较稳);
- 或者直接用昇腾在线 NPU 环境——它已经帮你配好了兼容的 Python 和 MindSpore,省得本地折腾。
常见报错速查表
| 现象 | 原因 | 怎么办 |
|---|---|---|
pip/python 不是内部或外部命令 | Python 没加到 PATH | 重装 Python 勾上 “Add to PATH”,或用 PyCharm Terminal |
pip install mindspore 找不到包 | Python 版本太高 | 换 3.9/3.10,或用在线 NPU 环境 |
import mindspore 报红/NumPy 报错 | NumPy 2.x 不兼容 | pip install "numpy<2" |
报 Ascend 相关错误 | 不在 NPU 环境 | 先写 set_device("CPU") 调试,再切 NPU |
| 找不到数据文件 | 没下载/路径不对/下载失败 | 用第四章第 2 格手动下载,核对目录结构,或手动下载解压 |
| 报标签类型不匹配 | 标签是 uint32 | 加 TypeCast(ms.int32) |
| 下载卡住/超时 | 网络问题 | 重试、换网络,或浏览器手动下载 |
导入 mindspore 失败 | 没装或版本不对 | 按 CANN 对应版本装(在线环境一般已装好) |
💡 排错总原则:先
CPU跑通、再切Ascend;代码逻辑和环境问题分开查,别混在一起纠结。
六、往深走一步(知道就行)
- 动态图 vs 静态图:MindSpore 早期以"静态图+自动并行"出名,现在也支持更灵活的写法,新手不用一开始就纠结。
- 全栈自主:从框架、软件栈到芯片都是华为一套,做国产化项目时这点很重要。
- 生态比 PyTorch 小:资料、第三方教程没 PyTorch 多,遇到问题要多查官方文档。
- 什么时候真该用 MindSpore:如果你只是自己跑跑模型、不挑硬件,PyTorch 足够;但如果你要在昇腾上做正式训练/部署、或者公司要求国产化,MindSpore + CANN 就是官方主推、长期维护最顺的路线。
七、写在最后
MindSpore 没那么玄乎:
它就是华为的一个深度学习框架。会搭网络、会选损失和优化器,你就能上手。
至于学 PyTorch 还是 MindSpore,结论很简单:
- 找工作、做通用项目 → PyTorch 生态最大;
- 进华为昇腾生态、做国产化 → MindSpore 值得学。
两个不冲突,核心思想是通的。
🚀 下期预告
下一期想讲:
- MindSpore 和 PyTorch 写法差异逐行对比;
- 或者 在昇腾上跑一个真实的小项目。
评论区告诉我你想看哪个,点个关注不迷路~
🎉 跑通的同学评论区扣个 “1”;卡在哪个报错了,贴出来一起看。
📝 本文代码在本地 CPU 上跑通,方便任何人复现;要在昇腾 NPU 上跑,只需把
set_device("CPU")改成"Ascend"。版本和数据集路径以官方当时文档为准。
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐

所有评论(0)