DeepSeek-R1系列推理

基于MindIE的DeepSeek-R1分布式推理部署指导(A2服务器)

环境准备

软件版本要求

软件

版本

链接

cann-toolkit

8.0.T63

AscendHub
(详见容器内 /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 http://39.171.244.84:30011/drivers/HDK 24.1.RC3/Ascend-hdk-910-npu-driver_24.1.rc3_linux-aarch64.run wget http://39.171.244.84:30011/drivers/HDK 24.1.RC3/Ascend-hdk-910-npu-firmware_7.5.0.1.129.run

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 <https://gitee.com/ascend/mind-cluster/releases/download/v6.0.0/Ascend-docker-runtime_6.0.0_linux-aarch64.run>

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的镜像包,

https://www.hiascend.com/developer/ascendhub/detail/af85b724a7e5469ebd7ea13c3439d48f

镜像版本为: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的镜像,镜像地址:http://39.171.244.84:30011/DistributedCommunication/20T3-800I-A2-py311-openeuler2403-lts.tar

下载后使用 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://huggingface.co/deepseek-ai/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

也可使用魔乐社区直接下载deepseek-v3BF-16: DeepSeek-V3-BF16

权重转换-W8A8(NPU)

1.需要将转换好的BF16的模型权重下载

2.使用下面命令克隆下推理项目。git clone -b br_noncom_MindStudio_8.0.0_POC_20251231 --single-branch https://gitee.com/ascend/msit.git

  1. 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

配置分布式通信

检查机器网络情况

### 检查物理链接

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 http://39.171.244.84:30011/DistributedCommunication/hccl_tools.py

python hcc_tools.py

在你当前目录下生成一个 hccl_xx_(当前物理机ip).json 的文件

将其他的机器生成的hccl.json文件放在主物理机的统一文件夹中,使用下面命令获取合并脚本。

wget http://39.171.244.84:30011/DistributedCommunication/merge_hccl.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_namedeepseekv2

  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.jsonserver_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环境配置

驱动固件安装

参考 驱动固件安装

驱动获取:驱动下载链接

固件获取:固件下载链接

查看机器硬件配套表

  • 首次安装场景:硬件设备刚出厂时未安装驱动,或者硬件设备前期安装过驱动固件但是当前已卸载,上述场景属于首次安装场景,需按照“驱动 > 固件”的顺序安装驱动固件。

  • 覆盖安装场景:硬件设备前期安装过驱动固件且未卸载,当前要再次安装驱动固件,此场景属于覆盖安装场景,需按照“固件 > 驱动”的顺序安装固件驱动。

## 增加包的可执行权限(可以将包放在同一目录下对该目录增加权限)
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 回显如下说明安装成功 alt text

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