☰
昇腾 910B 部署大模型:从认卡到 40 人共用一台机器的实录
2026/10/21 20:49:45 网站建设 项目流程

这台昇腾 910B2(64GB HBM)拿到手时,我习惯性地敲了nvidia-smi——屏幕空了。机器里一块 NVIDIA 卡都没有,光是"认卡"这一步就先卡住。这篇记的是给两天课程、40 个人共用一台机器部署大模型的全过程:从认卡、配 CANN、下模型、用 vLLM 起服务,到给 40 人做目录镜像和端口隔离。所有命令和参数都是真机实测,数据没动过。

你能直接拿去用的有这些:CANN 环境四条开机必做、1.5GB 模型下载三条路径的实测对比、vLLM 起 7B 对话服务与 0.5B 对照服务的完整 serve 参数、自写的 OpenAI 兼容向量服务、40 人隔离方案,还有 LoRA 微调 21 秒训完的甜点参数,以及 Ollama 在昇腾上的选型结论。

第一台机器拿到手,我敲的第一条命令是nvidia-smi。

回来的是command not found。

机器里装的是华为昇腾,一块 NVIDIA 的卡都没有。所有我背过的 CUDA 命令、所有教程里的CUDA_VISIBLE_DEVICES、所有"一行命令起服务"的教程,从这一刻起全部作废。

我那套已经写好的部署脚本也因此整套作废。它是按 NVIDIA 写的,连最后一步的服务校验都是nvidia-smi。后来按昇腾重写的版本,脚本名全部换成了ascend_01到ascend_09。

一、先认卡:四条开机必做

1)看卡用npu-smi info,不是nvidia-smi。而且要先 source 完 CANN 环境才能用。

2)起任何 NPU 进程前,必须 source 两个环境脚本:

set +u source /usr/local/Ascend/cann/set_env.sh 2>/dev/null \ || source /usr/local/Ascend/ascend-toolkit/set_env.sh source /usr/local/Ascend/nnal/atb/set_env.sh set -u

少了 atb 那个,会报libatb.so: cannot open shared object file。 而开头那个set +u也不能省:昇腾的 set_env.sh 内部引用了未定义变量,不开掉 nounset 就崩在这一行。

3)import torch_npu不能省。它是把 npu 设备注册进 torch 的插件,不 import,torch.npu.is_available()会老老实实返回 False——然后你会以为这台机器根本没卡。

import torch import torch_npu # 这行不能省 print(torch.npu.is_available())

4)python 和 vllm 都得用全路径。直接敲python3拿到的是系统 3.10,里面没有 torch:

/usr/local/python3.11.14/bin/python3.11 -c "import torch; print(torch.__version__)" # 2.9.0+cpu /usr/local/python3.11.14/bin/vllm --version # 0.11.0

顺手确认这两个也在:pip show torch-npu(2.9.0)、pip show vllm-ascend(0.19.1rc1)。

国产卡的第一个坑不在算力,在你对 NVIDIA 的肌肉记忆里。

二、网络不通:1.5GB 要下十几个小时

这台机器github.com和huggingface.co都不通。意思是:不能from_pretrained在线拉模型,也拉不到 GitHub release。

两条应对。

一是走代理,而且必须写死版本号:

https://ghproxy.net/https://github.com/<owner>/<repo>/releases/download/v0.19.1/xxx.tar.gz

写成/releases/latest/...经代理会 404,它跟不了重定向。

二是大文件一律走本机中转,别在服务器上硬拉。这是我这次最省时间的一条,实测三条路:

路径速度1.5GB 耗时
服务器直连单连接23 KB/s十几个小时
服务器并发分段(24 段)~130 KB/s3~8 小时且不稳
本机多线程下载 + SFTP 上传14 MB/s 下行约 15 分钟

差 600 倍。

顺带一个代价 3 小时的坑:并发分段把 390 段全下完了,拼接时用了cat seg.*——那是字符串序(seg.0 seg.1 seg.10 …),拼出来顺序是乱的,zstd -t必然失败。更蠢的是我的失败分支把全部分段删了。

要么用for i in $(seq ...)逐个追加,要么直接 seek 写单个文件。校验失败的时候别删分段。

三、起服务:vLLM 能起对话,起不了向量

对话服务这条实测 2.9 秒出回答:

/usr/local/python3.11.14/bin/vllm serve /model/models/Qwen2.5-7B-Instruct \ --served-model-name qwen2.5-7b \ --host 0.0.0.0 --port 8000 \ --max-model-len 16384 --max-num-seqs 32 \ --gpu-memory-utilization 0.85 \ --api-key 你的Key

--max-num-seqs 32是并发上限,40 个人共用一个 7B 就靠这个扛,评测类的脚本错峰跑。

再起一个 0.5B 做"大小模型对照",只占一成显存:

/usr/local/python3.11.14/bin/vllm serve /model/qwen2.5-0.5b \ --served-model-name qwen2.5-0.5b \ --host 0.0.0.0 --port 8002 \ --max-model-len 4096 --max-num-seqs 16 \ --gpu-memory-utilization 0.10 \ --api-key 你的Key

但向量服务起不来:这一版 vllm-ascend不认--task embed,报unrecognized arguments。我一开始就是照着--task embed写的,脚本跑空了一轮才发现。

解法是自己写一个:用 transformers + torch_npu 直接起一个 OpenAI 兼容的向量服务,Qwen3-Embedding-0.6B,1024 维。核心就三步:取last_hidden_state的最后一位、L2 归一化、套 OpenAI 的/v1/embeddings返回格式。对上层完全无感。

四、40 个人怎么共用一台机器

关键设计只有一条:远程目录刻意镜像本地目录。本地是{代码包, 数据, 输出}三级,服务器上是同样的三级,所以 notebook 里写死的../数据、../输出,传到服务器上一行都不用改。

建 40 个学员目录,核心就这几行:

SHARED=/data/fde/shared for i in $(seq 1 40); do d=/data/fde/students/$(printf "s%02d" $i) mkdir -p "$d/代码包" "$d/输出" "$d/work" ln -sfn $SHARED/data "$d/数据" # 软链共享,不是拷贝 cp -r $SHARED/代码包/. "$d/代码包/" # 代码每人一份副本 done chmod -R a-w $SHARED/data # 共享数据只读,改了影响全班
隔离项做法
代码每人一份副本,共享区只读
数据软链共享,只读,改了影响全班
产物各写各的输出/
端口起 jupyter 用88XX(XX = 自己的编号),避免互撞
微调单卡按组排队,--out必须指向自己目录

微调也是实测出来的甜点组合:240 条样本、3 轮、batch 4,0.5B 在 910B2 上 21 秒训完,loss 从 6.37 降到 0.60。

/usr/local/python3.11.14/bin/python3.11 finetune_lora.py \ --train ../输出/exp04_sft_train.jsonl \ --out ../输出/exp04_lora \ --base /model/qwen2.5-0.5b --epochs 3 --batch 4 \ --lr 2e-4 --lora-r 16 --lora-alpha 32 --max-len 512 --seed 42

可训练参数只有 1.08M,占总量 0.22%。

更省事的是:vLLM 已经占掉 85% 显存的情况下,这个 0.5B 的 LoRA照样跑得动。所以不用为了演示微调去停 7B 服务。但 3B 以上会 OOM,要用 3B 必须先停 vLLM。

五、三个反直觉的结论

一、私有化的卖点不是"快",是"稳"。

同一句问题各测三次,本机直连:

端点三次往返
自建服务器(7B)726 / 734 / 725 ms
公有云在线 API1363 / 3445 / 2719 ms

自有机器三次几乎不动,在线 API波动 2.5 倍(排队加公网抖动)。

二、快不等于好。

7B 3394ms,0.5B 3096ms,几乎一样快。但 7B 的回答分步骤、会说"记录数据/分析原因",0.5B 也有步骤,只是更泛、更像模板。

时延接近是因为两者跑在同一块 NPU 上;差距在内容质量,不在速度。

三、换了 embedding 端点,必须重建向量。

两个 embedding 模型都是 1024 维,但实测余弦相似度只有 -0.02。

维度一样,不等于空间一样。带着旧向量切端点,检索会全部落空——表现出来是"全部拒答",你根本想不到问题出在向量上。

六、折腾一整夜,最后决定不用 Ollama

这条我最想记下来,因为它跟技术关系不大。

装 Ollama 试了五种方式,全失败:GitHub release 走代理只有 48–580KB/s 且停滞;官方 install.sh 是单连接流式,23KB/s;并发分段下完 390 段但拼错;本机下载再 SFTP 上传,传到一半本机出口被限流,服务端校验 Corrupted block;最后补齐 636MB,zstd -t仍然报 Corrupted block。

真正让我决定砍掉的,不是"没装上",是算清了一笔账:Ollama 在昇腾上只能跑 CPU。也就是说,就算装成了,收益也薄得可怜。

于是改成:课上一律用 vLLM,Ollama 只留一张选型对比表讲定位,那批脚本标记弃用、不再维护。

沉没成本不是继续的理由。先算"装成了能好多少",再决定要不要接着装。

七、值得这么折腾吗

值得:要做国产化适配、要一批人共用一张卡、要跑微调、环境不能联网。

不值得:只是想本地跑个小模型玩玩。你自己电脑上装什么都比这快,别租服务器。

一个前提:动手前先确认机器到底是什么卡。这一步省下的时间,比后面所有优化加起来都多。

先看清你脚下站的是什么卡,再决定怎么迈腿。

本文为个人真机实测记录,命令与数据均来自实际部署过程,供国产算力环境部署参考。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询