# DeepSeek-R1系列推理
## 基于MindIE的DeepSeek-R1分布式推理部署指导(A2服务器)
### **环境准备**
#### 软件版本要求
| 软件 | 版本 | 链接 |
|---------------|-----------------|----------------------------------------------------------------------|
| cann-toolkit | 8.0.T63 | [AscendHub](https://www.hiascend.com/developer/ascendhub/detail/af85b724a7e5469ebd7ea13c3439d48f)
(详见容器内 `/usr/local/Ascend`) |
| cann-kernels | 8.0.T63 | |
| cann-nnal | 8.0.T63.B020 | |
| mindie | 1.0.T71.B020 | |
#### 服务器资源配置
| 模型 | 权重类型 | 最低服务器要求 | 特殊说明 |
|---------------|----------------|------------------------------------|---------------------------|
| Deepseek-R1 | 16浮点权重 | 4台 Atlas 800 I A2 (8*64GB) | |
| Deepseek-R1 | W8A8量化权重 | 2台 Atlas 800 I A2 (8*64GB) | 需使用 mindie:2.0.T3 |
| Deepseek-V3 | 16浮点权重 | 4台 Atlas 800 I A2 (8*64GB) | |
| Deepseek-V3 | W8A8量化权重 | 2台 Atlas 800 I A2 (8*64GB) | |
### **配置裸金属相关环境**
#### 安装驱动
连接裸金属后,使用下面命令:
```
yum update
yum install wget
```
wget
wget
```
chmod +x Ascend-hdk-910-npu-driver_24.1.rc3_linux-aarch64.run Ascend-hdk-910-npu-firmware_7.5.0.1.129.run
##更新驱动,
.Ascend-hdk-910-npu-driver_24.1.rc3_linux-aarch64.run ----upgrade
##安装驱动
.Ascend-hdk-910-npu-firmware_7.5.0.1.129.run --full
##安装docker,使用
yum install docker-ce docker-ce-cli containerd.io
##安装docker-runtime
wget
chmod +x Ascend-docker-runtime_6.0.0_linux-aarch64.run
.Ascend-docker-runtime_6.0.0_linux-aarch64.run --install
##执行run文件之后执行下面命令
systemctl daemon-reload && systemctl restart docker
```
### **准备容器**
#### 准备容器
在昇腾社区/开发资源中下载适配的DeepSeek-R1的镜像包,
。
镜像版本为:`mindie:1.0.T71-800I-A2-py311-ubuntu22.04-arm64`
下载完成之后,请使用`docker images`命令确认查找具体镜像名称与标签。
使用下面命令进行加载:
`docker load -i mindie:1.0.T71-800I-A2-py311-ubuntu22.04-arm64`(下载的镜像名称与标签)
如果需要开启量化W8A8的服务,需要使用mindie-2.0.T3的镜像,镜像地址:
下载后使用 `docker load -i 20T3-800I-A2-py311-openeuler2403-lts.tar` 加载镜像。
#### 启动容器
使用docker images 查看下载下来的image的ID,
使用下面启动命令(参考):
```
docker run -itd --privileged --name=容器名称 --net=host \
--shm-size 500g \
--device=/dev/davinci0 \
--device=/dev/davinci1 \
--device=/dev/davinci2 \
--device=/dev/davinci3 \
--device=/dev/davinci4 \
--device=/dev/davinci5 \
--device=/dev/davinci6 \
--device=/dev/davinci7 \
--device=/dev/davinci_manager \
--device=/dev/hisi_hdc \
--device /dev/devmm_svm \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
-v /usr/local/Ascend/firmware:/usr/local/Ascend/firmware \
-v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \
-v /usr/local/sbin:/usr/local/sbin \
-v /etc/hccn.conf:/etc/hccn.conf \
-v /权重路径:/权重路径 \
mindie:1.0.0-XXX-800I-A2-arm64-py3.11(根据加载镜像名称修改)
```
或者使用:
```
docker run -itd --net=host --name=deep1 --ipc=host --shm-size 500g --privileged=true -e ASCEND_VISIBLE_DEVICES=0-7 -v /权重路径:/权重路径 images_id 启动。
```
#### 设置环境变量
```
Vi ~/.bashrc ##加入下面变量
source /usr/local/Ascend/ascend-toolkit/set_env.sh
source /usr/local/Ascend/nnal/atb/set_env.sh
source /usr/local/Ascend/atb-models/set_env.sh
source /usr/local/Ascend/mindie/set_env.sh
## 通信变量
export ATB_LLM_HCCL_ENABLE=1
export ATB_LLM_COMM_BACKEND="hccl"
export HCCL_CONNECT_TIMEOUT=7200
export WORLD_SIZE=32 ### 卡数
export HCCL_EXEC_TIMEOUT=0
export MIES_CONTAINER_IP=x.x.x.x(物理机中使用ifconfig 查看)
export RANKTABLEFILE=xxx.json(rank_table_file.json 的路径,生成详见第5节)
export HCCL_DETERMINISTIC=true
export NPU_MEMORY_FRACTION=0.95 ### 显存比
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True ###虚拟内存
export ASDOPS_LOG_LEVEL=ERROR ###日志等级
export ASDOPS_LOG_TO_STDOUT=1 ###是否打屏
export MINDIE_LOG_LEVEL=ERROR
export MINDIE_LOG_TO_STDOUT=1 ###是否打屏
export ATB__LOG_LEVEL=ERROR ### atb日志等级
export ATB_LOG_TO_STDOUT=1
```
### **权重下载与转换**
#### 权重下载
Deepseek-R1 的权重地址为:
推荐使用魔乐社区下载:[魔乐社区](https://modelers.cn/models/Ding1888/DeepSeek-R1/tree/main)
#### 权重转换(NPU)
使用下面代码:
```
git clone https://gitee.com/ascend/ModelZoo-PyTorch.git
cd ModelZoo-PyTorch\MindIE\LLM\DeepSeek\DeepSeek-V2\NPU_inference
python fp8_cast_bf16.py --input-fp8-hf-path /path/to/DeepSeek-R1 --output-bf16-hf-path /path/to/deepseek-R1-bf16
```
注意:当前npu转换脚本不会自动复制tokenizer等文件,需要手动复制到转换后的模型文件夹中。
注意:/path/to/DeepSeek-R1 表示原始权重路径,/path/to/deepseek-R1-bf16 表示转换后的新的权重路径。
由于模型权重较大,需要确保磁盘有足够空间放下所有权重。转换前权重约为640GB,转换后权重约为1.3T。推理作业是也需要有足够的空间加载模型权重,并未推理计算预留空间。
也可使用魔乐社区直接下载deepseek-r1BF-16:[deepseek-r1-fp16](https://modelers.cn/models/xieyuxiang/deepseek-r1-fp16/tree/main)
也可使用魔乐社区直接下载deepseek-v3BF-16: [DeepSeek-V3-BF16](https://modelers.cn/models/State_Cloud/DeepSeek-V3-BF16)
#### 权重转换-W8A8(NPU)
1.需要将转换好的BF16的模型权重下载
2.使用下面命令克隆下推理项目。`git clone -b br_noncom_MindStudio_8.0.0_POC_20251231 --single-branch`
3. `cd msit/msmodelslim` 进入msmodelslim目录下 运行安装脚本 `bash install.sh`.
4.安装好`transformers>=4.48.2` 之后`cd msit/msmodelslim/example/DeepSeek/` 文件夹下,使用命令,开启量化。量化过程需要30分钟-2小时。请耐心等待。
`python3 quant_deepseek_w8a8.py --model_path {浮点权重路径} --save_path {W8A8量化权重路径}` 。
也可使用魔乐社区直接下载deepseek-r1W8A8:[DeepSeek-R1-W8A8](https://modelers.cn/models/State_Cloud/DeepSeek-R1-W8A8/tree/main)
### **配置分布式通信**
#### 检查机器网络情况
```
### 检查物理链接
for i in {0..7}; do hccn_tool -i $i -lldp -g | grep Ifname; done
### 检查链接情况
for i in {0..7}; do hccn_tool -i $i -link -g ; done
### 检查网络健康情况
for i in {0..7}; do hccn_tool -i $i -net_health -g ; done
### 查看侦测ip的配置是否正确
for i in {0..7}; do hccn_tool -i $i -netdetect -g ; done
### 查看网关是否配置正确
for i in {0..7}; do hccn_tool -i $i -gateway -g ; done
### 检查NPU底层tls校验行为一致性,建议全0
for i in {0..7}; do hccn_tool -i $i -tls -g ; done | grep switch
### NPU底层tls校验行为置0操作
for i in {0..7};do hccn_tool -i $i -tls -s enable 0;done
### 获取每张卡的地址
for i in {0..7};do hccn_tool -i $i -ip -g; done
### 配置rank_table_file.json
```
每台物理机都需要运行下面命令
wget
```
python hcc_tools.py
```
在你当前目录下生成一个 hccl_xx_(当前物理机ip).json 的文件
将其他的机器生成的hccl.json文件放在主物理机的统一文件夹中,使用下面命令获取合并脚本。
wget [http://39.171.244.84:30011/DistributedCommunication/merge_hccl.py](http://39.171.244.84:30011/DistributedCommunication/hccl_tools.py)
```
python merge_hccl.py
```
运行结束后会生成一个总的`hccl*.json`. 需要在每个`server_id` 下加入一行”container_ip”:”和server_id”value一样。
并且按照ip从大到小排列,且将`rank_id`手动排序,从0 开始。
示例:

然后将整合好的json文件发送到每一个从物理机中。
参考如下格式,配置rank_table_file.json
```
{
"server_count": "...", ### 总节点数
### server_list中第一个server为主节点
"server_list": [
` `{
` `"device": [
` `{
` `"device_id": "...", ### 当前卡的本机编号,取值范围[0, 本机卡数)
` `"device_ip": "...", ### 当前卡的ip地址,可通过hccn_tool命令获取
` `"rank_id": "..." ### 当前卡的全局编号,取值范围[0, 总卡数)
` `},
...
` `],
` `"server_id": "...", ### 当前节点的ip地址
` `"container_ip": "..." ### 容器绑定的物理机ip地址(服务化部署时需要),若无特殊配置,则与server_id相同
` `},
...
],
"status": "completed",
"version": "1.0"
}
```
### **纯模型测试**
#### 精度测试
注意:需要将权重路径下的`config.json`中的`model_type` 更改为:`deepseekv2`(全小写且无空格)
准备数据集,以`ceval`为例:
`cd /usr/local/Ascend/atb-models/tests/modeltest/data`
`wget http://39.171.244.84:30011/DistributedCommunication/data/ceval.zip`
解压即可。
使用下面命令,进行验证。(需在所有机器上同时执行)
命令说明:
`bash run.sh pa_bf16 [dataset] ([shots]) [batch_size] [model_name] ([is_chat_model]) [weight_dir] [rank_table_file] [world_size] [node_num] [rank_id_start] [master_address]`
示例: 在DeepSeek-V3跑CEVAl数据集主节点的命令
`bash run.sh pa_bf16 full_CEval 5 16 deepseekv2 /path/to/weights/DeepSeek-V3 /path/to/xxx/ranktable.json 32 4 0 {主节点IP}`
` `0 :代表从0号卡开始推理,之后的机器依次从8,16,24。
参数说明:
1. `dataset`可选full_BoolQ、full_CEval等,部分数据集需要设置`shots`
2. `model_name`为`deepseekv2`
3. `weight_dir`为模型权重路径
4. `rank_table_file`为“配置分布通信”中配置的`rank_table_file.json`路径
5. `world_size`为总卡数。
6. `node_num`为总节点数量。
7. `rank_id_start`为当前节点起始卡号,即`rank_table_file.json`中当前节点第一张卡的`rank_id`
8. `master_address`为主节点ip地址,即`rank_table_file.json`的`server_list`中第一个节点的ip
等待命令完成后会生成一个csv文件,即为精度测试的结果。
#### 测试纯模型性能
\- 进入modeltest路径
`cd /usr/local/Ascend/llm_model/tests/modeltest/`
\- 运行测试脚本(需在所有机器上同时执行)
注意:需要将权重路径下的`config.json`中的`model_type` 更改为:`deepseekv2`(全小写且无空格)
`bash run.sh pa_bf16 performance [case_pair] [batch_size] [model_name] ([is_chat_model]) [weight_dir] [rank_table_file] [world_size] [node_num] [rank_id_start] [master_address]`
参数含义同“精度测试”
示例: 在DeepSeek-V3跑性能测试主节点的命令
`bash run.sh pa_bf16 performance [[256,256]] 16 deepseekv2 /path/to/weights/DeepSeek-V3 /path/to/xxx/ranktable.json 32 4 0 {主节点IP}`
`0` 代表从0号卡开始推理,之后的机器依次从8,16,24。
等待命令完成后,会生成一个csv文件,该文件即为性能测试结果。
### **MindIE服务化启动**
#### MindIE的前置准备
##### 修改权重目录下的config.json文件
将`model_type` 更改为:`deepseekv2`(全小写且无空格)
##### 配置服务化环境变量
服务化需要`rank_table_file.json`中配置`container_ip`字段
所有机器的配置应该保持一致,除了环境变量的MIES_CONTAINER_IP为本机ip地址。
##### 修改服务化参数
```
cd /usr/local/Ascend/mindie/latest/mindie-service
vi conf/config.json
```
修改以下参数:
```
"httpsEnabled" : false,
"multiNodesInferEnabled" : true, ### 开启多机推理
## 若不需要安全认证,则将以下两个参数设为false
"interCommTLSEnabled" : false,
"interNodeTLSEnabled" : false,
"modelName" : "DeepSeek-R1" ##不影响服务化拉起
"modelWeightPath" : "权重路径"
```
#### 拉起服务
```
cd /usr/local/Ascend/mindie/latest/mindie-service
.bin/mindieservice_daemon
```
先在主节点上启动服务,再依次在从节点上启动。
执行命令后首次打印本次启动所用所有参数,然后直到出现以下输出:

##### openai接口
~~~
curl -X POST \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseekv3",
"messages": [{
"role": "user",
"content": "你是谁?"
}],
"max_tokens": 200,
"presence_penalty": 1.03,
"frequency_penalty": 1.0,
"seed": null,
"temperature": 0.5,
"top_p": 0.95,
"stream": false
}' \
http://39.171.244.84:50005/v1/chat/completions
~~~

#### **Benchmark性能测试**
服务成功拉起后,使用下面命令测试性能:
```
benchmark --DatasetPath "/usr/local/Ascend/atb-models/tests/modeltest/dataset/full/CEval" \
--DatasetType "ceval" \
--ModelName "deepseekv3" \
--ModelPath "/home/data/deepseekR1" \
--TestType client \
--Http "http://192.168.0.27:50005" \ ### api接口
--ManagementHttp "http://127.0.0.2:1026" \
--TaskKind text \
--Tokenizer True \
--Concurrency 256 \ ### 并发数
--MaxOutputLen 512 ###最大输出长度
```
等待命令执行结束,即可看到如下内容。

## 基于MindIE的DeepSeek-R1分布式推理部署指导(300I DUO卡)
### 300I DUO环境配置
#### 驱动固件安装
参考 [驱动固件安装](./1%E7%8E%AF%E5%A2%83%E5%AE%89%E8%A3%85.md##%E5%AE%89%E8%A3%85%E9%A9%B1%E5%8A%A8%E5%9B%BA%E4%BB%B6)
驱动获取:[驱动下载链接](http://39.171.244.84:30011/package_dependencies/driver/24.1.rc3/RC3/Ascend-hdk-310p-npu-driver_24.1.rc3_linux-aarch64.run)
固件获取:[固件下载链接](http://39.171.244.84:30011/package_dependencies/driver/24.1.rc3/RC3/Ascend-hdk-310p-npu-firmware_7.5.0.1.b129.run)
[**查看机器硬件配套表**](http://39.171.244.84:30011/package_dependencies/Ascend%20HDK%2024.1.RC3.xlsx)
>* 首次安装场景:硬件设备刚出厂时未安装驱动,或者硬件设备前期安装过驱动固件但是当前已卸载,上述场景属于首次安装场景,需按照`“驱动 > 固件”`的顺序安装驱动固件。
>* 覆盖安装场景:硬件设备前期安装过驱动固件且未卸载,当前要再次安装驱动固件,此场景属于覆盖安装场景,需按照`“固件 > 驱动”`的顺序安装固件驱动。
```shell
## 增加包的可执行权限(可以将包放在同一目录下对该目录增加权限)
chmod +x Ascend-hdk-xxx-npu-driver_xxx_linux-aarch64.run
chmod +x Ascend-hdk-xxx-npu-firmware_xxx.run
## 安装固件
./Ascend-hdk-xxx-npu-firmware_xxx.run –full
## 安装驱动
./Ascend-hdk-xxx-npu-driver_xxx_linux-aarch64.run --full --install-for-all
```
#### 检查驱动是否安装成功
执行`npu-smi info`
回显如下说明安装成功

### 1.准备环境
#### 1.1拉取权重
~~~
from modelscope import snapshot_download
model_path="deepseek-ai/DeepSeek-R1-Distill-Qwen-32B"
cache_path="/data/docker_files"
snapshot_download(model_path, cache_dir=cache_path)
## 模型路径
/data/docker_files/deepseek-ai/DeepSeek-R1-Distill-Qwen-32B
~~~
#### 1.2准备容器
从下面链接中获取:
```
wget http://39.171.244.84:30011/docker_images/mindie:1.0.0-300I-Duo-py311-openeuler24.03-lts.tar
```
#### 1.3创建容器(挂载模型权重)
~~~
docker run -itd -u root \
--ipc=host \
--network=host \
--privileged \
--device=/dev/davinci_manager \
--device=/dev/devmm_svm \
--device=/dev/hisi_hdc \
-v /var/log/npu/:/usr/slog \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
-v /data/docker_files:/data/docker_files \
-v /data/docker_files/deepseek-ai/DeepSeek-R1-Distill-Qwen-32B:/data/docker_files/deepseek-ai/DeepSeek-R1-Distill-Qwen-32B \
--name deepseek-qwen-32b-jl \
mindie:1.0.0-300I-Duo-py311-openeuler24.03-lts.tar \
/bin/bash
~~~
#### 1.4进入容器
`docker exec -it deepseek-qwen-32b-jl /bin/bash`
这个命令会启动一个交互式的 `bash` 会话,在容器 `deepseek-qwen-32b-jl `内。`-it `参数表示你会进入容器并启动一个交互式 `shell`,`/bin/bash` 是大多数 `Linux` 容器中默认的 `shell`。
### 2. 修改配置文件
#### 2.1修改模型配置文件
`/data/docker_files/deepseek-ai/DeepSeek-R1-Distill-Qwen-32B/config.json`
~~~
"sliding_window": 131072,
"tie_word_embeddings": false,
## "torch_dtype": "bfloat16",
"torch_dtype": "float16",
"transformers_version": "4.43.1",
## 权限等级750
~~~
### 3.修改server配置文件
/usr/local/Ascend/mindie/latest/mindie-service
vi conf/config.json
~~~
{
"Version" : "1.1.0",
"LogConfig" :
{
"logLevel" : "Info",
"logFileSize" : 20,
"logFileNum" : 20,
"logPath" : "logs/mindservice.log"
},
"ServerConfig" :
{
"ipAddress" : "127.0.0.1", ## 服务ip地址
"managementIpAddress" : "127.0.0.2",
"port" : 1025, ## 端口号
"managementPort" : 1026,
"metricsPort" : 1027,
"allowAllZeroIpListening" : false,
"maxLinkNum" : 1000,
"httpsEnabled" : false, ## 是否使用http参数
"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" : 1121,
"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"
},
"BackendConfig" : {
"backendName" : "mindieservice_llm_engine",
"modelInstanceNumber" : 1,
"npuDeviceIds" : [[0,1,2,3]], ## 使用卡的编号,与worldSize参数保持一致
"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" : 2560,
"maxInputTokenLen" : 2048,
"truncation" : false,
"ModelConfig" : [
{
"modelInstanceType" : "Standard",
"modelName" : "DeepSeek-R1-Distill-Qwen-32B", ## 模型名称
"modelWeightPath" : "/data/docker_files/deepseek-ai/DeepSeek-R1-Distill-Qwen-32B", ## 模型地址
"worldSize" : 4, ## 使用卡的数量,与npuDeviceIds参数保持一致
"cpuMemSize" : 5,
"npuMemSize" : -1,
"backendType" : "atb",
"trustRemoteCode" : false
}
]
},
"ScheduleConfig" :
{
"templateType" : "Standard",
"templateName" : "Standard_LLM",
"cacheBlockSize" : 128,
"maxPrefillBatchSize" : 50,
"maxPrefillTokens" : 8192,
"prefillTimeMsPerReq" : 150,
"prefillPolicyType" : 0,
"decodeTimeMsPerReq" : 50,
"decodePolicyType" : 0,
"maxBatchSize" : 200,
"maxIterTimes" : 512,
"maxPreemptCount" : 0,
"supportSelectBatch" : false,
"maxQueueDelayMicroseconds" : 5000
}
}
}
~~~
### 4.启动服务
~~~
./bin/mindieservice_daemon
~~~
显示Daemon start success! 服务启动成功
### 5.测试
#### 5.1vllm接口测试
~~~
curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{
"prompt": "介绍一下中秋节",
"max_tokens": 200,
"repetition_penalty": 1.03,
"presence_penalty": 1.2,
"frequency_penalty": 1.2,
"temperature": 0.5,
"stream": false
}' http://127.0.0.1:1025/generate
~~~
#### 5.2 openai接口测试
~~~
curl -X POST \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"model": "DeepSeek-R1-Distill-Qwen-32B",
"messages": [{
"role": "user",
"content": "介绍一下中秋节"
}],
"max_tokens": 200,
"presence_penalty": 1.03,
"frequency_penalty": 1.0,
"seed": null,
"temperature": 0.5,
"top_p": 0.95,
"stream": false
}' \
http://127.0.0.1:1025/v1/chat/completions
~~~