在华为910B GPU服务器上运行DeepSeek-R1-0528模型

记录在两台910B4服务器上运行 W8A8 量化的 DeepSeek-R1-0528 模型,并使用 EvalScope 做一个简单的推理性能测试,后面还有一些推理性能相关的参数介绍以及模型报错排查方法

一、环境信息

模型 DeepSeek-R1-0528-W8A8-MindIE 需要是W8A8量化过的模型,每台机器上都要存放模型权重文件
服务器型号 Atlas 800I A2 2台
显卡 910B4 64G/张,2台共16张卡
MindIE >=2.1.RC1 低于这个版本会出现对话时模型输出异常的问题
驱动 >=24.1.0

1.1 下载模型权重文件

模型权重文件大概660G,需要确保服务器磁盘空间足够

从 ModelScope 上下载模型文件需要使用到modelscope工具

复制代码
# 1、下载 modelscope
pip install modelscope

# 2、下载模型
modelscope download --model 'TensorLake/DeepSeek-R1-0528-W8A8-MindIE' --local_dir '/model/DeepSeek-R1-0528-W8A8-MindIE'

Bash

二、运行模型

2.1 准备 rank table 文件

使用多机推理时,需要将包含设备ip,服务器ip等信息的json文件地址传递给底层通信算子。

参考如下格式,配置 /model/rank_table_file.json (后面会将/model目录挂载到 MindIE 容器内),参考:

  • server_count:总节点数

  • server_list:节点列表,第一个server为主节点

  • server_id:当前节点的ip地址

  • container_ip:容器ip地址(服务化部署时需要),若无特殊配置,则与server_id相同

  • device_id:当前卡的本机编号,取值范围[0, 本机卡数)

  • device_ip:当前卡的ip地址,可通过hccn_tool命令获取,参考命令for i in {0..7};do hccn_tool -i $i -ip -g; done

  • rank_id:当前卡的全局编号,取值范围[0, 总卡数)

    {
    "version": "1.0",
    "server_count": "2",
    "server_list": [
    {
    "server_id": "Master节点IP地址",
    "container_ip": "Master节点容器IP地址",
    "device": [
    { "device_id": "0", "device_ip": "10.20.0.2", "rank_id": "0" },
    { "device_id": "1", "device_ip": "10.20.0.3", "rank_id": "1" },
    { "device_id": "2", "device_ip": "10.20.0.4", "rank_id": "2" },
    { "device_id": "3", "device_ip": "10.20.0.5", "rank_id": "3" },
    { "device_id": "4", "device_ip": "10.20.0.6", "rank_id": "4" },
    { "device_id": "5", "device_ip": "10.20.0.7", "rank_id": "5" },
    { "device_id": "6", "device_ip": "10.20.0.8", "rank_id": "6" },
    { "device_id": "7", "device_ip": "10.20.0.9", "rank_id": "7" }
    ]
    },
    {
    "server_id": "Slave节点IP地址",
    "container_ip": "Slave节点容器IP地址",
    "device": [
    { "device_id": "0", "device_ip": "10.20.0.10", "rank_id": "8" },
    { "device_id": "1", "device_ip": "10.20.0.11", "rank_id": "9" },
    { "device_id": "2", "device_ip": "10.20.0.12", "rank_id": "10" },
    { "device_id": "3", "device_ip": "10.20.0.13", "rank_id": "11" },
    { "device_id": "4", "device_ip": "10.20.0.14", "rank_id": "12" },
    { "device_id": "5", "device_ip": "10.20.0.15", "rank_id": "13" },
    { "device_id": "6", "device_ip": "10.20.0.16", "rank_id": "14" },
    { "device_id": "7", "device_ip": "10.20.0.17", "rank_id": "15" }
    ]
    }
    ],
    "status": "completed"
    }

JSON

2.2 运行 MindIE 容器

需要在两个节点上运行这个容器,随后会运行容器之后进入到容器内修改 MindIE 相关配置

参数说明:

  • --device=/dev/davinciN:挂载显卡设备,这里将8张卡全部挂载到容器内

  • --net=host:使用网络模式为host

  • -v /model:/model:挂载宿主机上的模型权重文件到容器内,需要自行修改

    CONTAINER_NAME="deepseek-r1-0528"
    MINDIE_IMAGE="swr.cn-south-1.myhuaweicloud.com/ascendhub/mindie:2.1.RC1-800I-A2-py311-openeuler24.03-lts"

    docker run -itd --privileged --name={CONTAINER_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/devmm_svm \ --device=/dev/hisi_hdc \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/Ascend/add-ons/:/usr/local/Ascend/add-ons/ \ -v /usr/local/sbin/:/usr/local/sbin/ \ -v /etc/hccn.conf:/etc/hccn.conf \ -v /model:/model \ {MINDIE_IMAGE}
    /bin/bash

    在容器内查看显卡信息

    docker exec -it ${CONTAINER_NAME} npu-smi info

Bash

2.3 修改 MindIE 配置

修改两台机器上 MindIE 容器的配置,除ipAddress外其他配置都保持一致

复制代码
# 进入 MindIE 容器
docker exec -it deepseek-r1-0528 bash

# 在容器内修改 MindIE 配置文件
vim /usr/local/Ascend/mindie/latest/mindie-service/conf/config.json

Bash

配置文件参考如下:

https://www.hiascend.com/document/detail/zh/mindie/21RC1/mindiellm/llmdev/mindie_llm0004.html

  • ServerConfig:
    • ipAddress: 修改为容器/服务器IP地址(由于MindIE启动命令中指定了网络模式为 host,所以容器IP地址与服务器IP地址一致)
    • httpsEnabled: 配置为false
    • interCommTLSEnabled: 配置为false
  • BackendConfig:
    • multiNodesInferEnabled: 配置为true
    • interNodeTLSEnabled: 配置为false
    • npuDeviceIds: 使用NPU卡的索引,多张卡的索引号使用逗号分隔,比如[[0,1]]。多机推理场景下该值无效,每个节点上使用的npuDeviceIds根据ranktable计算获得。
    • modelName: 模型名称,比如deepseek-r4-0528,在后续调用模型需要在请求中填写该名称
    • modelWeightPath: 模型权重路径,比如/model/DeepSeek-R1-0528-W8A8-MindIE
    • worldSize: 模型参数中worldSize必须与使用的NPU数量相等。多机推理场景下该值无效,worldSize根据ranktable计算获得。
    • dp/tp/sp/moe_tp/moe_ep: 如果配置文件中没有这几个配置,需要手动添加(参考下面的配置文件)

性能相关参数,可修改这些参数调整服务化性能:

  • BackendConfig:
    • maxSeqLen: 最大序列长度
    • maxInputTokenLen: 最大输入 Token 长度
  • ScheduleConfig:
    • maxPrefillTokens: Prefill阶段,当前batch中所有input token总数。maxPrefillTokensmaxPrefillBatchSize谁先达到各自的取值就完成本次组batch。建议配置为maxInputTokenLen

    • maxPrefillBatchSize: Prefill阶段,一个batch可以组的最大请求数量。maxPrefillBatchSizemaxPrefillTokens谁先达到各自的取值就完成本次组batch。

    • maxIterTimes: 模型全局最大输出长度。会影响每个用户请求得到的模型实际输出长度outputLen,规则为:outputLen = min(maxIterTimes, max_tokens, maxSeqLen - inputLen)outputLen = min(maxIterTimes, max_new_tokens, maxSeqLen - inputLen)

      {
      "Version" : "1.0.0",

      复制代码
      "ServerConfig" :
      {
          "ipAddress" : "10.1.2.10",
          "managementIpAddress" : "127.0.0.2",
          "port" : 1025,
          "managementPort" : 1026,
          "metricsPort" : 1027,
          "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" : false,
          "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",
          "tokenTimeout" : 600,
          "e2eTimeout" : 600,
          "distDPServerEnabled":false
      },
      
      "BackendConfig" : {
          "backendName" : "mindieservice_llm_engine",
          "modelInstanceNumber" : 1,
          "npuDeviceIds" : [[0,1,2,3,4,5,6,7]],
          "tokenizerProcessNumber" : 8,
          "multiNodesInferEnabled" : true,
          "multiNodesInferPort" : 1120,
          "interNodeTLSEnabled" : false,
          "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" : 13300,
              "maxInputTokenLen" : 8300,
              "truncation" : false,
              "ModelConfig" : [
                  {
                      "modelInstanceType" : "Standard",
                      "modelName" : "deepseek-r1-0528",
                      "modelWeightPath" : "/model/DeepSeek-R1-0528-W8A8-MindIE",
                      "worldSize" : 8,
                      "cpuMemSize" : 5,
                      "npuMemSize" : -1,
                      "backendType" : "atb",
                      "trustRemoteCode" : false,
                      "async_scheduler_wait_time": 120,
                      "kv_trans_timeout": 10,
                      "kv_link_timeout": 1080,
                      "dp": 2,
                      "tp": 8,
                      "sp": 1,
                      "moe_tp": 4,
                      "moe_ep": 4
                  }
              ]
          },
      
          "ScheduleConfig" :
          {
              "templateType" : "Standard",
              "templateName" : "Standard_LLM",
              "cacheBlockSize" : 128,
      
              "maxPrefillBatchSize" : 50,
              "maxPrefillTokens" : 8300,
              "prefillTimeMsPerReq" : 150,
              "prefillPolicyType" : 0,
      
              "decodeTimeMsPerReq" : 50,
              "decodePolicyType" : 0,
      
              "maxBatchSize" : 4096,
              "maxIterTimes" : 5000,
              "maxPreemptCount" : 0,
              "supportSelectBatch" : false,
              "maxQueueDelayMicroseconds" : 5000
          }
      }

      }

JSON

2.4 修改文件权限

需要修改两台机器上 MindIE 容器中一些文件的权限

复制代码
# 进入 MindIE 容器
docker exec -it deepseek-r1-0528 bash


# 修改模型权重文件权限
chmod -R 750 /model/DeepSeek-R1-0528-W8A8-MindIE
# 修改 rank table 文件权限
chmod 640 /model/rank_table_file.json
# 修改配置文件权限
chmod 640 /usr/local/Ascend/mindie/latest/mindie-service/conf/config.json

Bash

2.5 运行 MindIE 服务

修改完配置之后就可以启动模型服务了,需要在两台节点上都要操作 ,注意修改MIES_CONTAINER_IP变量值为本机IP:

配置比较麻烦,可以自行修改成脚本自动拉起模型

复制代码
# 进入 MindIE 容器
docker exec -it deepseek-r1-0528 bash


## 配置变量
export MIES_CONTAINER_IP=10.1.2.10 # 本机ip,两台机器不同
export WORLD_SIZE=16
export RANK_TABLE_FILE=/model/rank_table_file.json

source /usr/local/Ascend/ascend-toolkit/set_env.sh
source /usr/local/Ascend/mindie/set_env.sh
source /usr/local/Ascend/mindie/latest/mindie-service/set_env.sh
source /usr/local/Ascend/mindie/latest/mindie-llm/set_env.sh
source /usr/local/Ascend/nnal/atb/set_env.sh

# export MINDIE_LOG_LEVEL="info"
export MINDIE_LOG_TO_STDOUT=1
export ASDOPS_LOG_TO_STDOUT=1
export ASDOPS_LOG_LEVEL=ERROR
export ATB_LLM_HCCL_ENABLE=1
export ATB_LLM_COMM_BACKEND="hccl"
export HCCL_CONNECT_TIMEOUT=7200
export HCCL_EXEC_TIMEOUT=0
export PYTORCH_NPU_ALLOC_CONF="expandable_segments:True"
# 集合通信优化:AIV
export HCCL_OP_EXPANSION_MODE="AIV"
# 算子下发队列优化等级:2
export TASK_QUEUE_ENABLE=2
# CPU绑核:细粒度
export CPU_AFFINITY_CONF=2
# python高并发:10
export OMP_NUM_THREADS=10
# 内存最大使用比例:0.96,过大会有Failed to get engine response报错风险
export NPU_MEMORY_FRACTION=0.96

cd /usr/local/Ascend/mindie/latest/mindie-service
./bin/mindieservice_daemon

Bash

当两个 MindIE 服务都出现Daemon start success之后说明模型服务运行成功

2.6 验证模型服务

可以通过下面命令验证下模型服务是否可用,地址为主节点IP,如果可以正常获得结果,则说明模型运行成功

这里使用的IP是主节点 IP(也就是 rank table 中配置的第一个节点的 IP)

复制代码
curl -X POST -H "Content-Type: application/json" -d '{
    "model": "deepseek-r1-0528",
    "messages": [{
        "role": "user",
        "content": "你好"
    }],
    "do_sample":true,
    "temperature":0.6,
    "top_p":0.95,
    "max_tokens": 2000,
    "stream": false
}' http://10.1.2.10:1025/v1/chat/completions

Bash

三、推理性能测试

测试工具选择 EvalScope,示例脚本如下:

EvalScope 支持命令行、Python两种执行方式,这两种方式对结果不会有影响,这里使用 Python 脚本的方式,再自行写脚本批量执行

复制代码
# llm-bench.py
from evalscope.perf.main import run_perf_benchmark
from evalscope.perf.arguments import Arguments

task_cfg = Arguments(
    parallel=[1],
    number=[10],
    model='deepseek-r1-0528',
    url='http://127.0.0.1:1025/v1/chat/completions',
    api='openai',
    dataset='random',
    min_tokens=256,
    max_tokens=256,
    prefix_length=0,
    min_prompt_length=1024,
    max_prompt_length=1024,
    tokenizer_path='/model/DeepSeek-R1-0528-W8A8-MindIE',
    extra_args={'ignore_eos': True}
)

results = run_perf_benchmark(task_cfg)

Bash

执行:

复制代码
python3 llm-bench.py

Bash

结果:

输入Token数 输出Token数 并发数 请求数 TTFT(s) TPOT(s) 吞吐(tokens/s) 测试持续时间(s)
1024 1024 1 10 0.2498 0.0795 27.8786 816.1595
1024 1024 16 50 1.0182 0.0847 295.8321 346.1467
1024 1024 32 64 1.9359 0.0909 688.9966 189.9679
1024 1024 64 128 3.0536 0.1021 1218.0585 215.0697
1024 1024 96 192 4.1496 0.1183 1567.1657 250.4576
1024 1024 128 256 5.3218 0.1345 1833.4286 285.8392
1024 1024 192 384 7.6181 0.1915 1664.9904 472.196
2048 2048 1 10 0.3615 0.0801 27.6764 1644.1845
2048 2048 16 50 1.8391 0.0844 296.3263 689.7419
2048 2048 32 64 3.1226 0.0916 687.6929 381.1939
2048 2048 64 128 5.436 0.1049 1189.3768 440.2723
2048 2048 96 192 8.0733 0.1459 1100.0131 724.744
2048 2048 128 256 49.8969 0.1691 1125.1326 931.6918
2048 2048 192 384 169.4648 0.1991 1233.4575 1200.5783
4096 1024 1 10 0.5861 0.0804 68.6732 828.2852
4096 1024 16 50 3.2289 0.087 708.3615 361.2423
4096 1024 32 64 5.7349 0.0946 1598.6378 204.9749
4096 1024 64 128 8.2758 0.1372 1880.7218 348.3938
4096 1024 96 192 61.966 0.1495 1955.4701 522.4232
4096 1024 128 256 123.954 0.1497 1918.4845 682.2142
4096 1024 192 384 260.5085 0.1581 1902.0598 1032.7816

四、性能调优相关

可以根据自身环境进行调整测试寻求符合自身需求的配置

4.1 相关参数介绍

性能调优相关参数:

  • maxSeqLen: 最大序列长度

  • maxInputTokenLen: 最大输入 Token 长度

  • maxIterTimes: 模型全局最大输出长度。会影响每个用户请求得到的模型实际输出长度outputLen,规则为:outputLen = min(maxIterTimes, max_tokens, maxSeqLen - inputLen)outputLen = min(maxIterTimes, max_new_tokens, maxSeqLen - inputLen)

  • maxPrefillTokens: Prefill阶段,当前batch中所有input token总数。maxPrefillTokensmaxPrefillBatchSize谁先达到各自的取值就完成本次组batch。建议配置为maxInputTokenLen

  • maxPrefillBatchSize: Prefill阶段,一个batch可以组的最大请求数量。maxPrefillBatchSizemaxPrefillTokens谁先达到各自的取值就完成本次组batch。

一般配置为 maxSeqLen = maxInputTokenLen + maxIterTimes,并且 maxPrefillTokens = maxInputTokenLen

maxPrefillBatchSizemaxPrefillTokens共同作用,控制输入请求的序列总长度,由于最大输入的要求,maxPrefillTokens往往设置与最大输入相同,可以保证最长的请求也可以正常推理,若实际输入长度远低于最大输入长度,maxPrefillBatchSize会存在一定的调优空间

4.2 性能数据分析

在启动服务化启动前导入以下环境变量,可以开启调度日志的打印,以及对应耗时信息

复制代码
export MINDIE_LLM_BENCHMARK_ENABLE=2

Bash

最终调度日志会存放在以下路径/usr/local/Ascend/mindie/latest/mindie-llm/logs/benchmark.jsonl

五、运行失败排查

运行模型时可能会经常发生启动失败等问题,整理了一些常用的排查方法

5.1 驱动版本较老

如果使用的 MindIE 版本比较新,服务器上装的驱动版本比较老的话,可能会出现不兼容的情况,可以尝试更新驱动和固件的版本

5.2 配置错误

常见配置错误为:

  1. npuDeviceIds中配置的卡号的数量与worldSize不一致
  2. maxSeqLen等相关配置过大,超出显卡显存
  3. MindIE 配置文件、Rank table 文件、模型文件权限错误

5.3 查看 MindIE 运行日志

模型启动时配置日志相关环境变量

注意:正式运行模型服务时不建议设置日志级别为debugMINDIE_LOG_LEVEL="debug"),debug 级别输出的日志非常多而且不一定会有所帮助,在实际排查时可能还会更困难

复制代码
# 修改日志级别(仅在排查时建议设置为 debug 级别)
export MINDIE_LOG_LEVEL="debug"
# 日志输出到标准输出
export MINDIE_LOG_TO_STDOUT=1

Bash

也可以在容器中的~/mindie/log中查看日志

相关推荐
爱编程的喵喵2 小时前
《华为数据之道》发行五周年暨《数据空间探索与实践》新书发布会召开,共探AI时代数据治理新路径
人工智能·华为
ModestCoder_2 小时前
【学习笔记】Diffusion Policy for Robotics
论文阅读·人工智能·笔记·学习·机器人·强化学习·具身智能
咚咚王者2 小时前
人工智能之数据分析 numpy:第七章 数组迭代排序筛选
人工智能·数据分析·numpy
ins_lizhiming2 小时前
华为昇腾910B服务器上部署Qwen3-30B-A3B并使用EvalScope推理性能测试
人工智能·华为
IT考试认证2 小时前
华为AI认证 H13-321 HCIP-AI V2.0题库
人工智能·华为·题库·hcip-ai·h13-321
热爱生活的五柒2 小时前
多模态遥感目标检测模型SM3Det:一站式多模态遥感目标检测!开启遥感检测新任务
人工智能·目标检测·计算机视觉·遥感·sm3det
bwz999@88.com2 小时前
win10安装miniforge+mamba替代miniconda
python
ElfBoard3 小时前
ElfBoard技术贴|如何在【RK3588】ELF 2开发板上进行UART引脚复用配置
人工智能·单片机·嵌入式硬件·物联网