🛠️ 验证前准备清单
在开始部署前,请确保以下基础环境已就绪,这是验证成功的前提:
硬件与驱动确认
确认 NPU 型号为 Ascend 310P3,且 npu-smi info 显示健康状态为 OK。
确认 CANN 版本与 MindIE 版本严格匹配。根据昇腾官方文档,MindIE 1.0.RC3 是适配 310P3 的推荐版本,请勿使用更高或更低版本1。
确认 Docker 环境已安装,且已获取昇腾官方 MindIE 镜像的下载权限1。
模型文件准备
模型选择:优先选择 Qwen3-7B 或 Qwen3-14B 的 INT4/INT8 量化版本。35B 模型已确认不可行,请勿尝试。
格式转换:确保模型已转换为 MindIE 支持的格式(如 .bin 或 .safetensors)。若原始模型为 Hugging Face 格式,需使用 mindie-convert 工具进行转换。
存储路径:创建专用目录(如 /home/qwen3_7b_int4)存放模型文件。
📋 验证执行步骤清单
按以下顺序执行,每步验证通过后再进入下一步:
镜像拉取与容器创建
登录昇腾镜像仓库,拉取 MindIE 1.0.RC3 镜像1。
创建容器时,仅映射 Chip 0(–device=/dev/davinci0),并挂载模型目录为只读1。
验证容器内 npu-smi info。
MindIE 服务启动
进入容器,执行 nohup ./bin/mindieservice_daemon > output.log 2>&1 & 启动服务1。
实时查看日志:tail -f output.log,确认出现 “Daemon start success!” 字样1。
若启动失败,检查 CANN 版本、模型路径及 NPU 卡映射是否正确。
模型加载与推理测试
使用 curl 调用本地接口测试基础推理:
curl-X POST"http://127.0.0.1:1025/v1/chat/completions"\-H"Content-Type: application/json"\-d '{"model":"qwen3-7b-int4","messages":[{"role":"user","content":"你好"}]}'以下为 Qwen3-7B/14B 在 310P3 上的理论性能基线,实际结果可能因量化版本、输入长度等因素波动:
|模型版本|首 Token 延迟|生成速度|显存占用|适用场景||:---|:---|:---|:---|:---||Qwen3-7B-INT4|200-400ms|15-25tokens/s|6-8GB|简单问答、文本分类||Qwen3-7B-INT8|300-500ms|10-18tokens/s|8-10GB|中等复杂度对话||Qwen3-14B-INT4|500-800ms|8-12tokens/s|12-15GB|复杂推理、长文本摘要||Qwen3-14B-INT8|800-1200ms|5-8tokens/s|16-20GB|高精度任务(慎用)|第一步:在本地 x86 电脑上操作(下载并转换)
这是一个非常典型的跨架构(x86 -> ARM64)离线镜像迁移场景。
由于你的本地电脑是 x86 架构,而服务器是 ARM64(鲲鹏/昇腾)架构,不能简单地使用 docker pull 然后 docker save,因为这样拉取下来的是 x86 版本的镜像,在 ARM 服务器上无法运行。
你需要利用 Docker 的 buildx 功能在 x86 电脑上模拟下载 ARM64 版本的镜像,导出为文件,再传输到服务器。
以下是完整操作步骤:
第一步:在本地 x86 电脑上操作(下载并转换)
你需要确保本地电脑的 Docker 已开启 buildx 支持(现代 Docker Desktop 默认已开启)。
创建并使用一个支持多架构的构建器
打开终端(PowerShell 或 CMD),执行以下命令:
docker buildx create--use--name mybuilder--bootstrap2\拉取 ARM64 镜像并导出为 tar 包
使用 docker buildx imagetools 命令直接拉取指定架构的镜像并保存。
注意:这里不需要先 pull 到本地存储,而是直接操作镜像清单。
执行以下命令(请确保网络能访问华为云 SWR):
#1.先登录(如果需要)#dockerlogin swr.cn-south-1.myhuaweicloud.com#2.拉取 ARM64 镜像并直接导出为 tar 文件 docker buildx imagetools create \--append \ swr.cn-south-1.myhuaweicloud.com/ascendhub/mindie:1.0.RC3-300I-Duo-arm64 \-o type=docker,dest=mindie-arm64.tar如果上述命令报错,可以使用备选方案(先拉取再导出):
# 备选方案:强制拉取指定平台镜像 docker pull--platform linux/arm64 swr.cn-south-1.myhuaweicloud.com/ascendhub/mindie:1.0.RC3-300I-Duo-arm64 # 导出镜像 docker save-o mindie-arm64.tar swr.cn-south-1.myhuaweicloud.com/ascendhub/mindie:1.0.RC3-300I-Duo-arm64验证文件
你会得到一个名为 mindie-arm64.tar 的文件(通常几个 GB 大小)。
第二步:传输文件到服务器
将 mindie-arm64.tar 文件通过 U 盘、内网 FTP 或 SCP 传输到麒麟服务器的某个目录,例如 /home/data/。
第三步:在麒麟服务器(ARM64)上操作(加载镜像)
登录到你的麒麟服务器,执行以下命令:
加载镜像
docker load-i/home/data/mindie-arm64.tar验证镜像
docker images docker images|grep mindie部署下载Qwen模型
在有网络的电脑上,使用清华源下载模型并转换格式。
bash
# 安装模型下载工具 pip3 install modelscope-i https://pypi.tuna.tsinghua.edu.cn/simple# 下载模型到指定目录 mkdir-p/tmp/Qwen2.5-7B-Instruct python3-c " from modelscope import snapshot_downloadsnapshot_download('Qwen/Qwen2.5-7B-Instruct',cache_dir='/tmp/Qwen2.5-7B-Instruct')"修改模型配置
这是一个关键步骤,因为昇腾310P不支持 bfloat16。
# 将模型配置中的数据类型从 bfloat16 修改为 float16 sed-i 's/"torch_dtype":"bfloat16"/"torch_dtype":"float16"/g'/tmp/Qwen2.5-7B-Instruct/config.json打包传输
将 mindie-arm64.tar 和整个 Qwen2.5-7B-Instruct 模型文件夹打包,通过U盘或内网传输到你的麒麟服务器上。
第二步:服务器端操作(在麒麟服务器上)
加载Docker镜像
docker load-i mindie-arm64.tar准备目录
# 创建模型和配置文件的挂载目录 mkdir-p/data/models mkdir-p/data/mindie_conf # 将传输过来的模型文件夹复制到挂载目录 # 假设你已将模型文件夹传输到了/tmp 目录 cp-r/tmp/Qwen2.5-7B-Instruct/data/models/建立推理容器
docker run-itd \--net=host \--shm-size=2g \--device=/dev/davinci0 \--device=/dev/davinci1 \--device=/dev/davinci_manager \--device=/dev/hisi_hdc \--device=/dev/devmm_svm \-v/usr/local/Ascend/driver:/usr/local/Ascend/driver:ro \-v/usr/local/sbin:/usr/local/sbin:ro \-v/data/models:/models \--name qwen-mindie \ mindie:2.0.RC2-300I-Duo-py311-openeuler24.03-lts \ bash第三步:进入容器并配置
进入容器:
bash
docker exec-it qwen-mindie bash编辑容器内的配置文件:
现在,你已经在容器内部了。直接使用 vi 编辑官方指定的路径:
vi/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json填入正确的配置:
将以下内容粘贴进去。这个配置整合了我们之前讨论的所有必要字段(logPath, maxLinkNum, httpsEnabled, kmcKsfMaster)和官方指南的模型配置。
{"ServerConfig":{"ipAddress":"0.0.0.0","port":8080,"managementPort":8081,"maxConcurrentRequests":100,"maxLinkNum":1000,"httpsEnabled":false},"LogConfig":{"logPath":"/usr/local/Ascend/mindie/latest/mindie-service/logs","logLevel":"INFO","logFileSize":20,"logFileNum":5},"BackendConfig":{"npuDeviceIds":[[0,1]],"ModelDeployConfig":{"ModelConfig":[{"modelName":"qwen2.5-7b","modelWeightPath":"/models/Qwen2.5-7B-Instruct","worldSize":2,"cpuMemSize":5,"npuMemSize":15,"backendType":"atb","trustRemoteCode":true}]}},"SecurityConfig":{"kmcKsfMaster":{"type":"soft"}}}#################以下来源昇腾910B部署千问3(Qwen3)大模型###################
我们这里使用4卡启动,其实两卡也没问题
docker run-it-d--shm-size=1g \--privileged \--name mindie-Qwen3-32B \--device=/dev/davinci_manager \--device=/dev/hisi_hdc \--device=/dev/devmm_svm \--device=/dev/davinci0 \--device=/dev/davinci1 \--device=/dev/davinci2 \--device=/dev/davinci3 \--net=host \-v/usr/local/Ascend/driver:/usr/local/Ascend/driver:ro \-v/usr/local/sbin:/usr/local/sbin:ro \-v/data/4pd-workspace/models/Qwen3-32B:/data/Qwen3-32B:ro \ # 这里是模型的权重路径,改成你自己的 mindie:2.0.T17.B010-800I-A2-py3.11-openeuler24.03-lts-aarch64 bash设置容器
进入容器
docker exec -it mindie-Qwen3-32B bash
更新transformers,因为Qwen3需要使用新版本的transformers
pip install--upgrade transformers==4.51.0-i https://pypi.tuna.tsinghua.edu.cn/simple修改服务化推理的配置文件
vim/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json这是我改好的
{"Version":"1.0.0","ServerConfig":{"ipAddress":"0.0.0.0","managementIpAddress":"127.0.0.2","port":18025,"managementPort":18026,"metricsPort":18027,"allowAllZeroIpListening":true,"maxLinkNum":1000,"httpsEnabled":false,"fullTextEnabled":false,"tlsCaPath":"security/ca/","tlsCaFile":["ca.pem"],"tlsCert":"security/certs/server.pem","tlsPk":"security/keys/server.key.pem","tlsPkPwd":"security/pass/key_pwd.txt","tlsCrlPath":"security/certs/","tlsCrlFiles":["server_crl.pem"],"managementTlsCaFile":["management_ca.pem"],"managementTlsCert":"security/certs/management/server.pem","managementTlsPk":"security/keys/management/server.key.pem","managementTlsPkPwd":"security/pass/management/key_pwd.txt","managementTlsCrlPath":"security/management/certs/","managementTlsCrlFiles":["server_crl.pem"],"kmcKsfMaster":"tools/pmt/master/ksfa","kmcKsfStandby":"tools/pmt/standby/ksfb","inferMode":"standard","interCommTLSEnabled":true,"interCommPort":18121,"interCommTlsCaPath":"security/grpc/ca/","interCommTlsCaFiles":["ca.pem"],"interCommTlsCert":"security/grpc/certs/server.pem","interCommPk":"security/grpc/keys/server.key.pem","interCommPkPwd":"security/grpc/pass/key_pwd.txt","interCommTlsCrlPath":"security/grpc/certs/","interCommTlsCrlFiles":["server_crl.pem"],"openAiSupport":"vllm","tokenTimeout":600,"e2eTimeout":600,"distDPServerEnabled":false},"BackendConfig":{"backendName":"mindieservice_llm_engine","modelInstanceNumber":1,"npuDeviceIds":[[0,1,2,3]],"tokenizerProcessNumber":8,"multiNodesInferEnabled":false,"multiNodesInferPort":1120,"interNodeTLSEnabled":true,"interNodeTlsCaPath":"security/grpc/ca/","interNodeTlsCaFiles":["ca.pem"],"interNodeTlsCert":"security/grpc/certs/server.pem","interNodeTlsPk":"security/grpc/keys/server.key.pem","interNodeTlsPkPwd":"security/grpc/pass/mindie_server_key_pwd.txt","interNodeTlsCrlPath":"security/grpc/certs/","interNodeTlsCrlFiles":["server_crl.pem"],"interNodeKmcKsfMaster":"tools/pmt/master/ksfa","interNodeKmcKsfStandby":"tools/pmt/standby/ksfb","ModelDeployConfig":{"maxSeqLen":32768,"maxInputTokenLen":32768,"truncation":false,"ModelConfig":[{"modelInstanceType":"Standard","modelName":"Qwen3-32B","modelWeightPath":"/data/Qwen3-32B","worldSize":4,"cpuMemSize":5,"npuMemSize":-1,"backendType":"atb","trustRemoteCode":false}]},"ScheduleConfig":{"templateType":"Standard","templateName":"Standard_LLM","cacheBlockSize":128,"maxPrefillBatchSize":50,"maxPrefillTokens":32768,"prefillTimeMsPerReq":150,"prefillPolicyType":0,"decodeTimeMsPerReq":50,"decodePolicyType":0,"maxBatchSize":200,"maxIterTimes":32768,"maxPreemptCount":0,"supportSelectBatch":false,"maxQueueDelayMicroseconds":5000}}}配置文件的注意点
ipAddress如果是0.0.0.0 需要allowAllZeroIpListening=true
worldSize要和npuDeviceIds 匹配。他们用来控制多卡并行推理。npuDeviceIds通常指的是逻辑卡(不管怎么挂卡都是0,1,2…这样的id)。但是如果你的容器是–privileged的话全部卡都会挂进来,那它就得指实体卡id的。
如果没证书 httpsEnabled要关上
maxPrefillTokens >= maxSeqLen > maxInputTokenLen
maxIterTimes 会限制迭代次数。如果很小,可能模型会戛然而止。如果不想特别设置最好和 maxSeqLen一致
启动推理
如果上面的操作都正确,那么我们就可以启动推理服务了
#进入启动路径
cd/usr/local/Ascend/mindie/latest/mindie-service/bin/启动推理服务
./mindieservice_daemon当你看到如下截图所示,即服务启动成功
测试
我们直接调用服务进行测试
curl"http://localhost:18025/v1/chat/completions"-H"Content-Type: application/json"\-H"Authorization: Bearer xxx"\-d '{"model":"Qwen3-32B","stream":true,"messages":[{"role":"user","content":"/no_think 你好."}]}'结果
可以看到,推理正常,至此Qwen3部署成功
写在后面
虽然我们经过一番折腾,成功把Qwen3-32B运行起来,但是如果换个其它模型,是不是还要重新做一遍上面的操作?是不是还要重新配置一下那个复杂的配置文件?
所以我们需要利用这个容器,制作一个专门用于我们推理的镜像,具体步骤写在下个文章