文章

华为昇腾deepseek模型部署

华为昇腾deepseek模型部署

title: 华为昇腾DeepSeek模型部署 date: 2026-02-09 10:00:00 categories: [AI, hw-ascend] tags: [AI, hw-ascend, LLM部署] image: path: /assets/img/posts/common/hw-ascend.jpg —

华为昇腾DeepSeek模型部署

适用于华为昇腾 310P3 服务器,基于 MindIE 服务化部署 DeepSeek-R1 系列模型,并通过 curl 调用 OpenAI 兼容接口进行对话验证。


一、环境与资源说明

项目说明
硬件3× Atlas 310P3(单卡约 21GB 显存)
系统openEuler 22.03 LTS (aarch64)
MindIE 镜像swr.cn-south-1.myhuaweicloud.com/ascendhub/mindie:1.0.0-300I-Duo-py311-openeuler24.03-lts
模型路径/home/models/ds-r1-14b
配置文件/home/config.json
服务地址192.168.1.214:1025
模型名称deepseek-r1-14b
模型官方链接ModelZoo DeepSeek-R1-Distill-Qwen-14BDeepSeek 专区

二、部署步骤

步骤 0:模型下载(如未准备)

模型目录路径无强制要求,在 config.jsonmodelWeightPath 中配置为实际存放路径即可。推荐使用华为昇腾官方提供的 MindIE 适配模型,可从以下渠道获取:

来源链接
DeepSeek-R1 14B 官方模型页(权重与镜像)ModelZoo DeepSeek-R1-Distill-Qwen-14B
MindIE 模型支持与下载说明MindIE 模型支持列表
昇腾 AscendHub 镜像与模型AscendHubMindIE 镜像详情

下载后按 MindIE 说明解压到目标目录,并在 config.json 中设置 modelWeightPath 指向该目录。

310P3 / Atlas 300I Duo 注意:权重目录下的 config.json(非 MindIE 服务配置)中,须将 "torch_dtype": "bfloat16" 改为 "float16"。800I A2 通常用 bf16,300I Duo 系列用 fp16;沿用 HuggingFace 原版权重时此项常为 bfloat16,不改可能导致 warm_up 报 TransData 等算子错误。参见 ModelZoo 说明

步骤 1:确认模型与配置

1
2
3
4
5
6
7
8
9
10
11
# 确认模型目录存在
ls -la /home/models/ds-r1-14b

# 310P3:确认权重 config.json 为 float16(见步骤 0)
grep torch_dtype /home/models/ds-r1-14b/config.json

# 若为 bfloat16,改为 float16 后再启动服务
sed -i 's/"torch_dtype"[[:space:]]*:[[:space:]]*"bfloat16"/"torch_dtype": "float16"/' /home/models/ds-r1-14b/config.json

# 查看 MindIE 服务配置
cat /home/config.json

确保 MindIE 的 config.jsonmodelWeightPath 指向 /home/models/ds-r1-14b,且 modelNamenpuDeviceIdsworldSize 等参数正确;权重目录 config.jsontorch_dtype 在 310P3 上须为 float16

步骤 2:停止并清理旧容器(如有)

1
2
3
docker ps -a | grep mindie
docker stop <容器名>   # 若存在
docker rm <容器名>

步骤 3:启动 MindIE 容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
docker run -it -d --name mindie-ds-r1 \
  --network=host \
  --shm-size=8g \
  --privileged=true \
  --device=/dev/davinci_manager \
  --device=/dev/hisi_hdc \
  --device=/dev/devmm_svm \
  --device=/dev/davinci0 \
  --device=/dev/davinci2 \
  -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
  -v /usr/local/dcmi:/usr/local/dcmi \
  -v /usr/local/sbin/npu-smi:/usr/local/bin/npu-smi \
  -v /home/models:/home/models \
  -v /home/config.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \
  swr.cn-south-1.myhuaweicloud.com/ascendhub/mindie:1.0.0-300I-Duo-py311-openeuler24.03-lts \
  bash

说明:当前配置使用 NPU 0、1 双卡(npuDeviceIds: [[0,1]]),对应设备为 /dev/davinci0/dev/davinci2(本机设备:davinci0、davinci2、davinci4,无 davinci1)。

查看 NPU 设备列表与 ID(宿主机或容器内执行):

1
2
3
4
5
6
7
8
# 查看 NPU 概要及设备 ID(NPU ID 即列表中各卡的编号 0、1、2...)
npu-smi info

# 查看拓扑,确认设备编号与 /dev/davinci 对应关系
npu-smi info -t topo

# 查看当前有哪些 davinci 设备节点(设备号不一定连续,如 0、2、4)
ls -l /dev/davinci*

配置 npuDeviceIds 时使用 NPU ID(如 [[0,1]]),挂载 --device 时使用实际存在的 /dev/davinciN

若配置文件路径在镜像内不同,可改为挂载整个 /home 目录:

1
-v /home:/home

并在启动服务前,将 /home/config.json 复制到 MindIE 的 conf 目录。

步骤 4:进入容器并加载环境

1
2
3
4
5
6
7
8
9
docker exec -it -u 0 mindie-ds-r1 bash

# 加载昇腾与 MindIE 环境变量
source /usr/local/Ascend/ascend-toolkit/set_env.sh
source /usr/local/Ascend/mindie/set_env.sh 2>/dev/null || true
source /usr/local/Ascend/mindie/latest/mindie-service/set_env.sh 2>/dev/null || true

# 确认 npu-smi 可用(已通过 -v /usr/local/sbin/npu-smi:/usr/local/bin/npu-smi 挂载)
which npu-smi   # 应输出 /usr/local/bin/npu-smi

步骤 5:确认配置文件

1
2
cd /usr/local/Ascend/mindie/latest/mindie-service/conf
cat config.json

当前 /home/config.json 关键配置项:

配置项说明
ServerConfig.ipAddress192.168.1.214服务监听 IP
ServerConfig.port1025主服务端口
ServerConfig.managementPort1026管理端口
ServerConfig.metricsPort1027指标端口
BackendConfig.npuDeviceIds[[0,1]]使用 NPU 0、1 双卡
ModelConfig.modelNamedeepseek-r1-14b模型名称(curl 请求中需一致)
ModelConfig.modelWeightPath/home/models/ds-r1-14b模型权重路径
ModelConfig.worldSize2与 NPU 卡数一致
maxSeqLen2560最大序列长度,长上下文场景建议调至 8192
maxInputTokenLen2048最大输入 token 数,超限会报 424,建议调至 8192
maxIterTimes2048ScheduleConfig 单次最大生成 token;服务端硬上限,请求里 max_tokens 不能超过此项;DeepSeek-R1 含思考链时建议 ≥2048
truncationfalse设为 true 时由服务端自动截断超长输入,无需调大显存

模型权重目录 {modelWeightPath}/config.json(310P3 必查,与服务端 conf/config.json 不是同一文件):

配置项310P3 推荐值说明
torch_dtypefloat16300I Duo / 310P3 须用 fp16;HF 原版多为 bfloat16,需手动改
文件权限640勿用 666,否则 MindIE 启动校验失败

步骤 6:启动 MindIE 服务(后台常驻)

在容器内执行(需先完成步骤 4 的环境变量加载;若新开 shell,先 source 再启动):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cd /usr/local/Ascend/mindie/latest/mindie-service

# 若已有旧进程,先停止
pkill -f mindieservice_daemon 2>/dev/null || true
sleep 2

# 后台常驻(二选一)
# 方式 A:不追加 shell 日志(stdout/stderr 丢弃;MindIE 仍可能按 config.json 的 LogConfig 写 logs/mindservice.log)
nohup ./bin/mindieservice_daemon > /dev/null 2>&1 &

# 方式 B:同时把控制台输出追加到日志文件(排查启动问题用)
# nohup ./bin/mindieservice_daemon >> logs/mindservice.log 2>&1 &

echo $! > /tmp/mindieservice.pid
echo "MindIE PID: $(cat /tmp/mindieservice.pid)"

查看状态

1
2
3
4
5
# 进程是否在跑
ps -fp $(cat /tmp/mindieservice.pid 2>/dev/null) 2>/dev/null || ps aux | grep mindieservice_daemon | grep -v grep

# 跟踪日志(方式 B 或 LogConfig 开启时;模型加载需数十秒~数分钟)
tail -f /usr/local/Ascend/mindie/latest/mindie-service/logs/mindservice.log

停止服务

1
kill $(cat /tmp/mindieservice.pid) 2>/dev/null || pkill -f mindieservice_daemon

从宿主机一键后台启动(容器名 mindie-ds-r1ds-14b 按实际替换):

1
2
3
4
5
6
7
8
9
docker exec -d ds-14b bash -lc '
source /usr/local/Ascend/ascend-toolkit/set_env.sh
source /usr/local/Ascend/mindie/latest/mindie-service/set_env.sh 2>/dev/null || true
export LANG=C.UTF-8 LC_ALL=C.UTF-8
cd /usr/local/Ascend/mindie/latest/mindie-service
pkill -f mindieservice_daemon 2>/dev/null || true
sleep 2
nohup ./bin/mindieservice_daemon > /dev/null 2>&1 &
'

另开终端监控 NPU 使用情况:

1
watch -n 1 npu-smi info

服务启动后监听 192.168.1.214:1025

服务状态检查:执行 npu-smi info,若 NPU 0、1 下显示 python 进程且 Memory-Usage 已占用,说明模型已加载,可直接进行 curl 测试。


三、curl 调用服务化接口

服务地址:http://192.168.1.214:1025,模型名:deepseek-r1-14b(需与 config.jsonmodelName 一致)。

本机验证(在部署 MindIE 的服务器上执行):

1
2
3
curl -X POST 'http://192.168.1.214:1025/v1/chat/completions' \
  -H 'Content-Type: application/json' \
  -d '{"model":"deepseek-r1-14b","messages":[{"role":"user","content":"你好"}],"max_tokens":128,"temperature":0.6}'

四、参数说明

参数说明建议
model模型名称,需与 config.jsonmodelName 一致必填
messages对话消息列表,格式同 OpenAI必填,总 token 需 ≤ 服务端 maxInputTokenLen
max_tokens最大生成 token 数(仅控制输出);实际上限以 ScheduleConfig.maxIterTimes 为准maxIterTimes,常用 512–2048
temperature采样温度,0–10.5–0.7,推荐 0.6
top_p核采样参数可选,如 0.95

DeepSeek-R1 建议temperature 建议 0.5–0.7,避免重复;指令放在 user 消息中,不要使用 system prompt。
输出长度:客户端 max_tokens 再大也不会超过服务端 maxIterTimes;若 usage.completion_tokens 始终等于 maxIterTimes,说明生成被顶满,需调大 maxIterTimes 或缩短思考链(要求只输出 JSON)。
输入长度:接口无 max_prompt_tokens 等请求级截断参数,超长输入需在调用侧截断,或启用服务端 truncation: true


五、常见问题

5.1 FileNotFoundError: ‘npu-smi’

现象:启动时报错 [Errno 2] No such file or directory: 'npu-smi',ATB 在 is_support_lccl 中调用 npu-smi info -t topo 失败。

原因:容器内无 npu-smi,宿主机上常见路径为 /usr/local/sbin/npu-smi

解决:启动容器时挂载 npu-smi:

1
-v /usr/local/sbin/npu-smi:/usr/local/bin/npu-smi

若宿主机路径不同,先执行 which npu-smi 确认,再按实际路径挂载到容器内 /usr/local/bin/npu-smi

5.2 连接被拒绝

  • 检查 MindIE 是否已启动:docker exec mindie-ds-r1 ps aux | grep mindie
  • 确认端口:当前配置为 1025,服务监听 192.168.1.214:1025
  • 检查防火墙:firewall-cmd --list-portsiptables 是否放行 1025

5.3 模型加载失败

  • 检查 modelWeightPath 是否正确:ls /home/models/ds-r1-14b
  • 310P3:检查权重 config.jsontorch_dtype 是否为 float16(非 bfloat16
  • 检查 npu-smi info 是否识别到 NPU;确认目标 NPU 未被其他进程占用
  • 查看 MindIE 日志中的具体报错

5.3.1 warm_up 报 TransData / npu_format_cast 失败

现象:日志出现 Optype [TransData] ... is unsupportednpu_format_castExecute fail

常见原因

原因处理
310P3 权重仍为 bfloat16{modelWeightPath}/config.json"torch_dtype": "float16"
使用 HF 原版权重改从 ModelZoo / 魔乐 下载
驱动与 MindIE 镜像版本不匹配升级与宿主机驱动配套的 MindIE 镜像

修改 torch_dtype 或换权重后需重启 MindIE 服务。

5.4 返回 404 或 model 不存在

  • 确认请求中的 modelconfig.jsonmodelName 完全一致(大小写、下划线等)

5.5 容器内找不到配置文件

若挂载路径与镜像内不一致,可手动复制:

1
2
docker exec -it mindie-ds-r1 bash
cp /home/config.json /usr/local/Ascend/mindie/latest/mindie-service/conf/config.json

5.6 上游返回 424 / 输入 token 超限

现象:通过 One API、sqlbot 等代理调用时返回 Error code: 424,或 MindIE 日志提示:

1
Failed to enqueue inferRequest: This model's maximum input ids length cannot be greater than 2048, the input ids length is 5147

原因:请求的输入 token 数(messages + system prompt 等)超过 config.json 中的 maxInputTokenLen(默认 2048)。

解决方式

方式说明
模型侧调大 maxInputTokenLenmaxSeqLen(见下)
模型侧启用 truncation: true,由 MindIE 自动截断超长输入
调用侧在发送前自行截断 messages(OpenAI API 无请求级截断参数)

1. 模型侧:调大限制

/home/config.jsonModelDeployConfig 中:

1
2
"maxSeqLen" : 8192,
"maxInputTokenLen" : 8192,

14B 模型在 310P3 双卡上,8192 一般可支持;若显存不足可试 4096 或 6144。

1.1 一键修改(32B 模型):先查当前值,再备份并替换为 8192(显存不足可改为 4096 或 6144):

1
2
3
4
5
6
7
8
# 1. 查看当前值
grep -E '"(maxSeqLen|maxInputTokenLen)"' /home/config.json

# 2. 备份并修改
cp /home/config.json /home/config.json.bak.$(date +%Y%m%d_%H%M%S) && sed -i 's/"maxSeqLen"[[:space:]]*:[[:space:]]*[0-9]*/"maxSeqLen" : 8192/' /home/config.json && sed -i 's/"maxInputTokenLen"[[:space:]]*:[[:space:]]*[0-9]*/"maxInputTokenLen" : 8192/' /home/config.json && grep -E '"(maxSeqLen|maxInputTokenLen)"' /home/config.json

# 3. 查看修改差异(比较最新备份与当前文件)
diff $(ls -t /home/config.json.bak.* 2>/dev/null | head -1) /home/config.json

修改后需重启 MindIE 服务。

2. 模型侧:启用自动截断

ModelDeployConfig 中设置:

1
"truncation" : true

MindIE 会对超过 maxInputTokenLen 的输入自动截断,无需调大显存。修改后需重启 MindIE 服务。


六、参考链接

本文由作者按照 CC BY 4.0 进行授权