Ascend-SACT/GLM-5
模型介绍文件和版本Pull Requests讨论分析
下载使用量0

GLM-5在昇腾A2上部署实践经验

作者

师炜文、杨蕾蕾、杨覃娟、刘芮金、谢艺言、刘惠鹏、王剑、陈希迎、周键淇、汤志强

一.模型概述及场景

GLM5是智谱于2月12日发布的最新一代模型,总参数量约744B,激活40B,主要专注于coding及agent能力。模型整体沿用了DeepSeek 3.2的架构,引入了DSA稀疏注意力机制。

1.1 模型权重

由于GLM5的参数量较大,为了保证上下文长度和并发数,部署W4A8的量化版本。权重可以从魔乐或魔搭上下载: https://modelers.cn/models/Eco-Tech/GLM-5-w4a8-mtp-QuaRot

1.2 固件驱动下载

本文涉及的模型部署均基于1-2台910B2(8-16卡),主要需要的软件依赖为8.5.0版本CANN的配套驱动、固件。 注意:必须使用25.x的驱动及配套固件,24.x驱动会导致模型拉起时卡死

  • 版本兼容性:https://www.hiascend.com/document/detail/zh/CANNCommunityEdition/850/releasenote/releasenote_0000.html

  • 固件、驱动下载链接:https://www.hiascend.com/hardware/firmware-drivers/community?product=1&model=30&cann=8.5.0&driver=Ascend+HDK+25.5.1

二.准备镜像和创建容器

由于vllm ascend是vllm的插件,版本演进略落后于vllm官方,因此GLM5的部署使用的是昇腾专门为GLM5准备的main2main版本镜像,使用其他版本可能会碰到各种未知错误。镜像可以从docker hub上直接拉取: docker pull m.daocloud.io/quay.io/ascend/vllm-ascend:glm5 注意:

  1. 如果是A3,镜像名为m.daocloud.io/quay.io/ascend/vllm-ascend:glm5-a3
  2. X86和ARM的镜像不能混用,如果下载镜像的机器和部署机器架构不同,下载时可以通过--platform参数指定需要的版本

容器创建参考以下命令:

export IMAGE_ID=663b6cb28e3e
export NAME=glm5

docker run -it -d \
    --name $NAME --net=host \
    --shm-size=500g \
    --privileged=true \
    --device /dev/davinci0 \
    --device /dev/davinci_manager \
    --device /dev/devmm_svm \
    --device /dev/hisi_hdc \
    -v /usr/local/dcmi:/usr/local/dcmi \
    -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
    -v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
    -v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
    -v /usr/local/Ascend/driver/tools/hccn_tool:/usr/local/Ascend/driver/tools/hccn_tool \
    -v /etc/ascend_install.info:/etc/ascend_install.info \
    -v /root/.cache:/root/.cache \
    -v /etc/hccn.conf:/etc/hccn.conf \
    -v /usr/bin/hccn_tool:/usr/bin/hccn_tool \
    -v /mnt:/mnt \
    --entrypoint=bash $IMAGE_ID \

docker exec -it $NAME bash

三.拉起服务

经过反复的调试和踩坑,最终GLM5采用的部署方案为2节点16卡,TP8DP2EP16。 16卡最高支持128k上下文单并发。

3.1 节点1启动脚本:

#!/bin/bash
nic_name="enpxxxx"  # 需要替换
if ! ifconfig $nic_name &>/dev/null; then
    echo "error: $nic_name doesn't exist"
    exit 1
fi
local_ip=$(ifconfig $nic_name | awk '/inet / {print $2}')

export HCCL_IF_IP=$local_ip
export GLOO_SOCKET_IFNAME=$nic_name
export TP_SOCKET_IFNAME=$nic_name
export HCCL_SOCKET_IFNAME=$nic_name
export OMP_PROC_BIND=false
export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
export OMP_NUM_THREADS=4
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export HCCL_BUFFSIZE=1024
export HCCL_OP_EXPANSION_MODE="AIV"

# 需要替换
vllm serve ${model_path:="/mnt/esfs/GLM-5-w4a8/Eco-Tech-GLM-5-w4a8-mtp-QuaRot"} \
--host 0.0.0.0 \
--port 8080 --quantization ascend \
--data-parallel-size 2 \
--data-parallel-size-local 1 \
--data-parallel-address $local_ip \
--data-parallel-rpc-port 8082 \
--tensor-parallel-size 8 \
--enable-expert-parallel \
--tool-call-parser glm47 \
--reasoning-parser glm45 \
--served-model-name glm5 \
--enable-auto-tool-choice \
--max-model-len 131072 \
--max-num-batched-tokens 32768 \
--max-num-seqs 16 \
--trust-remote-code \
--gpu-memory-utilization 0.95 --compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' \
--speculative-config.method mtp \
--speculative-config.num_speculative_tokens 2 \
# --no-enable-prefix-caching

3.2 节点2启动脚本:

source /usr/local/Ascend/ascend-toolkit/set_env.sh
source /usr/local/Ascend/nnal/atb/set_env.sh

node0_ip=x.x.x.x   #需要替换
nic_name="enpxxxx"  # 需要替换

if ! ifconfig $nic_name &>/dev/null; then
    echo "error: $nic_name doesn't exist"
    exit 1
fi
local_ip=$(ifconfig $nic_name | awk '/inet / {print $2}')

export HCCL_IF_IP=$local_ip
export GLOO_SOCKET_IFNAME=$nic_name
export TP_SOCKET_IFNAME=$nic_name
export HCCL_SOCKET_IFNAME=$nic_name
export OMP_PROC_BIND=false
export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
export OMP_NUM_THREADS=4
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export HCCL_BUFFSIZE=1024
export HCCL_OP_EXPANSION_MODE="AIV"

# 需要替换
vllm serve ${model_path:="/mnt/esfs/GLM-5-w4a8/Eco-Tech-GLM-5-w4a8-mtp-QuaRot"} \
--host 0.0.0.0 \
--port 8080 --quantization ascend \
--data-parallel-size 2 \
--data-parallel-size-local 1 \
--data-parallel-start-rank 1 \
--headless \
--data-parallel-address $node0_ip \
--data-parallel-rpc-port 8082 \
--tensor-parallel-size 8 \
--enable-expert-parallel \
--tool-call-parser glm47 \
--reasoning-parser glm45 \
--served-model-name glm5 \
--enable-auto-tool-choice \
--max-model-len 131072 \
--max-num-batched-tokens 32768 \
--max-num-seqs 16 \
--trust-remote-code \
--gpu-memory-utilization 0.95 \
--compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' \
--speculative-config.method mtp \
--speculative-config.num_speculative_tokens 2 \
# --no-enable-prefix-caching

四.已知问题和注意事项

  1. mtp需要根据实际场景调整num_speculative_tokens
  2. 已验证glm5镜像A2 w4a8在4机的情况下(tp32、dp4tp8等)存在精度问题,因此至多使用2机16卡,最高支持到128k 1并发
  3. w4a8 tp16跨机tp报错无法拉起
  4. 对bf16的版本也进行了探索,但由于模型参数量太大,A2 4机32卡TP32也只能支持16k上下文2并发,同时发现bf16的tp模式无法叠加ep,会导致算子报错
  5. 当前B2显存勉强才能支持128k,--gpu-memory-utilization 0.95稍微调小一点可能就会导致OOM