🛠️ 验证前准备清单
在开始部署前,请确保以下基础环境已就绪,这是验证成功的前提:
硬件与驱动确认
确认 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运行起来,但是如果换个其它模型,是不是还要重新做一遍上面的操作?是不是还要重新配置一下那个复杂的配置文件?

所以我们需要利用这个容器,制作一个专门用于我们推理的镜像,具体步骤写在下个文章

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐