310p部署千问3(Qwen3)大模型
🛠️ 验证前准备清单
在开始部署前,请确保以下基础环境已就绪,这是验证成功的前提:
硬件与驱动确认
确认 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-25 tokens/s | 6-8 GB | 简单问答、文本分类 |
| Qwen3-7B-INT8 | 300-500ms | 10-18 tokens/s | 8-10 GB | 中等复杂度对话 |
| Qwen3-14B-INT4 | 500-800ms | 8-12 tokens/s | 12-15 GB | 复杂推理、长文本摘要 |
| Qwen3-14B-INT8 | 800-1200ms | 5-8 tokens/s | 16-20 GB | 高精度任务(慎用) |
第一步:在本地 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 --bootstrap
2\拉取 ARM64 镜像并导出为 tar 包
使用 docker buildx imagetools 命令直接拉取指定架构的镜像并保存。
注意:这里不需要先 pull 到本地存储,而是直接操作镜像清单。
执行以下命令(请确保网络能访问华为云 SWR):
# 1. 先登录(如果需要)
# docker login 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_download
snapshot_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运行起来,但是如果换个其它模型,是不是还要重新做一遍上面的操作?是不是还要重新配置一下那个复杂的配置文件?
所以我们需要利用这个容器,制作一个专门用于我们推理的镜像,具体步骤写在下个文章
更多推荐

所有评论(0)