GLM-5.2¶
1 简介¶
GLM-5.2 采用混合专家(MoE)架构,面向复杂系统工程和长程智能体任务。
本文档将展示模型的主要验证步骤,包括支持的功能、功能配置、环境准备、单节点和多节点部署、精度和性能评估。
2 支持的功能¶
请参考 支持功能列表 获取模型支持的功能矩阵。
请参考 功能指南 获取功能配置。
3 前提条件¶
3.1 模型权重¶
| 权重版本 | 硬件要求 | 下载链接 |
|---|---|---|
GLM-5.2(BF16 版本) |
2 个 Atlas 800 A3(128GB × 8)节点或 4 个 Atlas 800 A2(64GB × 8)节点 | ModelScope |
GLM-5.2-w8a8 |
1 个 Atlas 800 A3(128GB × 8)节点或 2 个 Atlas 800 A2(64GB × 8)节点 | ModelScope |
GLM-5.2-w8a8c8(量化版本) |
2 个 Atlas 800 A3(64GB × 16)节点或 4 个 Atlas 800 A2(64GB × 8)节点 | Modelers |
GLM-5.2-w4a8c8 |
1 个 Atlas 800 A3(128GB × 8)节点或 2 个 Atlas 800 A2(64GB × 8)节点 | ModelScope |
GLM-5.2-w8a8c8(量化版本):权重已验证,推荐使用。- 您可以使用 msmodelslim 直接对模型进行量化。
建议将模型权重下载到多节点共享目录,例如 /root/.cache/。
路径说明:将模型权重下载到任意目录并记录该目录。确保后续部署命令中的模型路径与该目录一致。
3.2 验证多节点通信(可选)¶
如果要部署多节点环境,需要根据 验证多节点通信环境 验证多节点通信。
4 安装¶
- 您可以使用我们的官方 Docker 镜像直接运行 GLM-5.2。
- KV Cache Pool(Ascend Store)部署指南
在每个节点上启动 Docker 镜像。
export IMAGE=quay.io/ascend/vllm-ascend:v0.23.0-a3
export NAME=vllm-ascend
# Run the container using the defined variables
# Note: If you are running bridge network with docker, please expose available ports for multiple nodes communication in advance
docker run --rm \
--name $NAME \
--net=host \
--shm-size=1g \
--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/davinci8 \
--device /dev/davinci9 \
--device /dev/davinci10 \
--device /dev/davinci11 \
--device /dev/davinci12 \
--device /dev/davinci13 \
--device /dev/davinci14 \
--device /dev/davinci15 \
--device /dev/davinci_manager \
--device /dev/devmm_svm \
--device /dev/hisi_hdc \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/Ascend/driver/tools/hccn_tool:/usr/local/Ascend/driver/tools/hccn_tool \
-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 /etc/ascend_install.info:/etc/ascend_install.info \
-v /root/.cache:/root/.cache \
-it $IMAGE bash
在每个节点上启动 Docker 镜像。
export IMAGE=quay.io/ascend/vllm-ascend:v0.23.0
docker run --rm \
--name vllm-ascend \
--shm-size=1g \
--net=host \
--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/dcmi:/usr/local/dcmi \
-v /usr/local/Ascend/driver/tools/hccn_tool:/usr/local/Ascend/driver/tools/hccn_tool \
-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 /etc/ascend_install.info:/etc/ascend_install.info \
-v /root/.cache:/root/.cache \
-it $IMAGE bash
如果要部署多节点环境,需要在每个节点上配置环境。
5 部署¶
5.1 上下文低于 1M¶
5.1.1 单节点部署¶
- 量化模型
GLM-5.2-w4a8c8可部署在 1 个 Atlas 800 A3(64GB × 16)上。
运行以下脚本以执行在线推理。
export HCCL_BUFFSIZE=200
export HCCL_OP_EXPANSION_MODE="AIV"
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
# Ensure the model path matches the directory recorded during download
vllm serve /root/.cache/modelscope/hub/models/vllm-ascend/GLM-5.2-w4a8c8 \
--host 0.0.0.0 \
--port 8000 \
--api-server-count 1 \
--data-parallel-size 2 \
--enable-expert-parallel \
--tensor-parallel-size 8 \
--seed 1024 \
--served-model-name glm-5 \
--tool-call-parser glm47 \
--reasoning-parser glm45 \
--enable-auto-tool-choice \
--max-num-seqs 12 \
--max-model-len 135000 \
--max-num-batched-tokens 8192 \
--trust-remote-code \
--gpu-memory-utilization 0.92 \
--quantization ascend \
--compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' \
--attention_config.indexer_kv_dtype int8 \
--additional-config '{"enable_dsa_cp": true, "enable_balance_scheduling": true,"multistream_overlap_shared_expert":true, "enable_flashcomm1": true, "enable_fused_mc2": 0}' \
--speculative-config '{"num_speculative_tokens": 3, "method": "deepseek_mtp","enforce_eager":true}'
注意: 参数说明如下:
- 对于单节点部署,在低延迟场景下建议使用
dp1tp16并关闭专家并行。
5.1.2 多节点部署¶
GLM-5.2-w4a8c8:可部署在 2 台 Atlas 800 A3(64GB × 16)上。
分别在两个节点上运行以下脚本。
节点 0
# this obtained through ifconfig
# nic_name is the network interface name corresponding to local_ip of the current node
nic_name="xxx"
local_ip="xxx"
# The value of node0_ip must be consistent with the value of local_ip set in node0 (master node)
node0_ip="xxxx"
export HCCL_BUFFSIZE=400
export HCCL_IF_IP=$local_ip
export HCCL_OP_EXPANSION_MODE="AIV"
export HCCL_SOCKET_IFNAME=$nic_name
export GLOO_SOCKET_IFNAME=$nic_name
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
# Ensure the model path matches the directory recorded during download
vllm serve /root/.cache/modelscope/hub/models/vllm-ascend/GLM-5.2-w4a8c8 \
--host 0.0.0.0 \
--port 8000 \
--api-server-count 1 \
--data-parallel-size 4 \
--data-parallel-start-rank 0 \
--data-parallel-size-local 2 \
--data-parallel-address $node0_ip \
--data-parallel-rpc-port 12980 \
--tensor-parallel-size 8 \
--enable-expert-parallel \
--seed 1024 \
--served-model-name glm-52 \
--tool-call-parser glm47 \
--reasoning-parser glm45 \
--enable-auto-tool-choice \
--max-num-seqs 16 \
--max-model-len 66000 \
--max-num-batched-tokens 8192 \
--trust-remote-code \
--gpu-memory-utilization 0.90 \
--quantization ascend \
--compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' \
--kv-cache-dtype int8 \
--attention_config.indexer_kv_dtype int8 \
--additional-config '{"enable_dsa_cp": true, "enable_balance_scheduling": true,"fuse_muls_add":true,"multistream_overlap_shared_expert":true,"c8_enable_reshape_optim":false, "enable_reduce_sample": "True", "enable_flashcomm1": true, "enable_fused_mc2": 1}' \
--speculative-config '{"num_speculative_tokens": 3, "method": "deepseek_mtp","enforce_eager":true}'
节点 1
# this obtained through ifconfig
# nic_name is the network interface name corresponding to local_ip of the current node
nic_name="xxx"
local_ip="xxx"
# The value of node0_ip must be consistent with the value of local_ip set in node0 (master node)
node0_ip="xxxx"
export HCCL_BUFFSIZE=400
export HCCL_IF_IP=$local_ip
export HCCL_OP_EXPANSION_MODE="AIV"
export HCCL_SOCKET_IFNAME=$nic_name
export GLOO_SOCKET_IFNAME=$nic_name
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
# Ensure the model path matches the directory recorded during download
vllm serve /root/.cache/modelscope/hub/models/vllm-ascend/GLM-5.2-w4a8c8 \
--host 0.0.0.0 \
--port 8000 \
--headless \
--data-parallel-size 4 \
--data-parallel-start-rank 2 \
--data-parallel-size-local 2 \
--data-parallel-address $node0_ip \
--data-parallel-rpc-port 12980 \
--tensor-parallel-size 8 \
--enable-expert-parallel \
--seed 1024 \
--served-model-name glm-52 \
--tool-call-parser glm47 \
--reasoning-parser glm45 \
--enable-auto-tool-choice \
--max-num-seqs 16 \
--max-model-len 66000 \
--max-num-batched-tokens 8192 \
--trust-remote-code \
--gpu-memory-utilization 0.90 \
--quantization ascend \
--compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' \
--kv-cache-dtype int8 \
--attention_config.indexer_kv_dtype int8 \
--additional-config '{"enable_dsa_cp": true, "enable_balance_scheduling": true,"fuse_muls_add":true,"multistream_overlap_shared_expert":true,"c8_enable_reshape_optim":false, "enable_reduce_sample": "True", "enable_flashcomm1": true, "enable_fused_mc2": 1}' \
--speculative-config '{"num_speculative_tokens": 3, "method": "deepseek_mtp","enforce_eager":true}'
GLM-5.2-w4a8c8:可部署在 2 台 Atlas 800 A2(64GB × 32)上。
节点 0
# this obtained through ifconfig
# nic_name is the network interface name corresponding to local_ip of the current node
nic_name="xxx"
local_ip="xxx"
# The value of node0_ip must be consistent with the value of local_ip set in node0 (master node)
node0_ip="xxx"
export VLLM_EXECUTE_MODEL_TIMEOUT_SECONDS=3000
export HCCL_IF_IP=$local_ip
export HCCL_OP_EXPANSION_MODE="AIV"
export HCCL_SOCKET_IFNAME=$nic_name
export GLOO_SOCKET_IFNAME=$nic_name
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
# Ensure the model path matches the directory recorded during download
vllm serve /root/.cache/modelscope/hub/models/vllm-ascend/GLM-5.2-w4a8c8 \
--max_model_len 40000 \
--max-num-batched-tokens 4096 \
--served-model-name glm-52 \
--seed 1024 \
--gpu-memory-utilization 0.95 \
--api-server-count 1 \
--max-num-seqs 16 \
--data-parallel-size 2 \
--data-parallel-size-local 1 \
--data-parallel-address $node0_ip \
--data-parallel-rpc-port 13389 \
--tensor-parallel-size 8 \
--enable-expert-parallel \
--quantization ascend \
--port 8000 \
--safetensors-load-strategy 'prefetch' \
--block-size 128 \
--additional-config '{"multistream_overlap_shared_expert": true}' \
--compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' \
--speculative-config '{"num_speculative_tokens": 5, "method": "deepseek_mtp", "enforce_eager": true}'
节点 1
# this obtained through ifconfig
# nic_name is the network interface name corresponding to local_ip of the current node
nic_name="xxx"
local_ip="xxx"
# The value of node0_ip must be consistent with the value of local_ip set in node0 (master node)
node0_ip="xxx"
export VLLM_EXECUTE_MODEL_TIMEOUT_SECONDS=3000
export HCCL_IF_IP=$local_ip
export HCCL_OP_EXPANSION_MODE="AIV"
export HCCL_SOCKET_IFNAME=$nic_name
export GLOO_SOCKET_IFNAME=$nic_name
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
# Ensure the model path matches the directory recorded during download
vllm serve /root/.cache/modelscope/hub/models/vllm-ascend/GLM-5.2-w4a8c8 \
--max_model_len 40000 \
--max-num-batched-tokens 4096 \
--served-model-name glm-52 \
--seed 1024 \
--gpu-memory-utilization 0.95 \
--max-num-seqs 16 \
--headless \
--data-parallel-size 2 \
--data-parallel-size-local 1 \
--data-parallel-start-rank 1 \
--data-parallel-address $node0_ip \
--data-parallel-rpc-port 13389 \
--tensor-parallel-size 8 \
--enable-expert-parallel \
--quantization ascend \
--port 8000 \
--safetensors-load-strategy 'prefetch' \
--block-size 128 \
--additional-config '{"multistream_overlap_shared_expert": true}' \
--compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' \
--speculative-config '{"num_speculative_tokens": 5, "method": "deepseek_mtp", "enforce_eager": true}'
5.1.3 预填充-解码分离¶
我们希望展示 GLM-5.2 在多节点环境中采用 1P1D 部署以获得更好性能的部署指南。
在 PD 分离场景中,Mooncake 用作预填充节点和解码节点之间的 KV 缓存传输连接器。有关 Mooncake 配置,请参阅 KV 缓存池(Ascend Store)部署指南。
5.1.3.1 在 4 台 Atlas 800 A3 上部署¶
使用 GLM-5.2-w8a8c8 权重的预填充-解码分离可部署在 4 台 Atlas 800 A3(64GB × 16)上。
开始之前,请:
-
在每个节点上准备脚本
launch_online_dp.py:import argparse import multiprocessing import os import subprocess import sys def parse_args(): parser = argparse.ArgumentParser() parser.add_argument("--dp-size", type=int, required=True, help="Data parallel size.") parser.add_argument("--tp-size", type=int, default=1, help="Tensor parallel size.") parser.add_argument("--pp-size", type=int, default=1, help="Pipeline parallel size.") parser.add_argument("--dp-size-local", type=int, default=-1, help="Local data parallel size.") parser.add_argument("--dp-rank-start", type=int, default=0, help="Starting rank for data parallel.") parser.add_argument("--dp-address", type=str, required=True, help="IP address for data parallel master node.") parser.add_argument("--dp-rpc-port", type=str, default="12321", help="Port for data parallel master node.") parser.add_argument("--vllm-start-port", type=int, default=8000, help="Starting port for the engine.") return parser.parse_args() args = parse_args() dp_size = args.dp_size tp_size = args.tp_size pp_size = args.pp_size dp_size_local = args.dp_size_local if dp_size_local == -1: dp_size_local = dp_size dp_rank_start = args.dp_rank_start dp_address = args.dp_address dp_rpc_port = args.dp_rpc_port vllm_start_port = args.vllm_start_port gpus_per_dp_rank = tp_size * pp_size def run_command(visible_devices, dp_rank, vllm_engine_port): command = [ "bash", "./run_dp_template.sh", visible_devices, str(vllm_engine_port), str(dp_size), str(dp_rank), dp_address, dp_rpc_port, str(tp_size), str(pp_size), ] subprocess.run(command, check=True) if __name__ == "__main__": template_path = "./run_dp_template.sh" if not os.path.exists(template_path): print(f"Template file {template_path} does not exist.") sys.exit(1) processes = [] num_cards = dp_size_local * gpus_per_dp_rank for i in range(dp_size_local): dp_rank = dp_rank_start + i vllm_engine_port = vllm_start_port + i visible_devices = ",".join(str(x) for x in range(i * gpus_per_dp_rank, (i + 1) * gpus_per_dp_rank)) process = multiprocessing.Process( target=run_command, args=(visible_devices, dp_rank, vllm_engine_port) ) processes.append(process) process.start() for process in processes: process.join() -
在每个节点上准备脚本
run_dp_template.sh。-
预填充节点 0
nic_name="xxxx" # change to your own nic name local_ip="xxxx" # change to your own ip export VLLM_PP_LAYER_PARTITION="41,37" export HCCL_BUFFSIZE=400 export HCCL_IF_IP=$local_ip export HCCL_OP_EXPANSION_MODE="AIV" export HCCL_SOCKET_IFNAME=$nic_name export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib export VLLM_USE_FASTOKENS=1 export GLOO_SOCKET_IFNAME=$nic_name export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True # Ensure the model path matches the directory recorded during download vllm serve <MODEL_PATH> \ --host 0.0.0.0 \ --port $2 \ --tensor-parallel-size 16 \ --enable-expert-parallel \ --pipeline-parallel-size 2 \ --distributed-executor-backend mp \ --master-addr $local_ip \ --master-port 7060 \ --nnodes 2 \ --node-rank 0 \ --speculative-config '{"num_speculative_tokens": 1, "method":"deepseek_mtp","enforce_eager":true}' \ --seed 1024 \ --served-model-name glm-5 \ --max-model-len 202752 \ --safetensors-load-strategy 'prefetch' \ --attention_config.indexer_kv_dtype int8 \ --additional-config '{"fuse_muls_add":true, "enable_dsa_cp":true, "enable_flashcomm1": true, "enable_fused_mc2": 1}' \ --max-num-batched-tokens 16384 \ --trust-remote-code \ --enable-prefix-caching \ --max-num-seqs 64 \ --quantization ascend \ --gpu-memory-utilization 0.85 \ --api-server-count 16 \ --enforce-eager \ --enable-auto-tool-choice \ --tool-call-parser glm47 \ --reasoning-parser glm45 \ --kv-transfer-config '{ "kv_connector": "MooncakeConnectorV1", "kv_role": "kv_producer", "kv_port": "30000", "engine_id": "0", "kv_connector_extra_config": { "use_ascend_direct": true, "prefill": {"dp_size": 1, "pp_size": 2, "tp_size": 16, "pp_layer_partition": "41,37"}, "decode": { "dp_size": 16, "tp_size": 2} } }' -
预填充节点 1
nic_name="xxxx" # change to your own nic name local_ip="xxxx" # change to your own ip # The value of node_p0_ip must be consistent with the value of local_ip set in prefill node 0 (p0, PP master node) node_p0_ip="xxxx" export VLLM_PP_LAYER_PARTITION="41,37" export HCCL_BUFFSIZE=400 export HCCL_IF_IP=$local_ip export HCCL_OP_EXPANSION_MODE="AIV" export HCCL_SOCKET_IFNAME=$nic_name export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib export VLLM_USE_FASTOKENS=1 export GLOO_SOCKET_IFNAME=$nic_name export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True # Ensure the model path matches the directory recorded during download vllm serve <MODEL_PATH> \ --host 0.0.0.0 \ --port $2 \ --tensor-parallel-size 16 \ --enable-expert-parallel \ --pipeline-parallel-size 2 \ --distributed-executor-backend mp \ --master-addr $node_p0_ip \ --master-port 7060 \ --nnodes 2 \ --node-rank 1 \ --speculative-config '{"num_speculative_tokens": 1, "method":"deepseek_mtp","enforce_eager":true}' \ --seed 1024 \ --served-model-name glm-5 \ --max-model-len 202752 \ --safetensors-load-strategy 'prefetch' \ --attention_config.indexer_kv_dtype int8 \ --additional-config '{"fuse_muls_add":true, "enable_dsa_cp":true, "enable_flashcomm1": true, "enable_fused_mc2": 1}' \ --max-num-batched-tokens 16384 \ --trust-remote-code \ --enable-prefix-caching \ --max-num-seqs 64 \ --quantization ascend \ --gpu-memory-utilization 0.85 \ --headless \ --enforce-eager \ --enable-auto-tool-choice \ --tool-call-parser glm47 \ --reasoning-parser glm45 \ --kv-transfer-config '{ "kv_connector": "MooncakeConnectorV1", "kv_role": "kv_producer", "kv_port": "30000", "engine_id": "0", "kv_connector_extra_config": { "use_ascend_direct": true, "prefill": {"dp_size": 1, "pp_size": 2, "tp_size": 16, "pp_layer_partition": "41,37"}, "decode": { "dp_size": 16, "tp_size": 2} } }'
-
-
解码节点 0
```shell nic_name="xxxx" # change to your own nic name local_ip="xxxx" # change to your own ip # d0: api server on this node; d1: --headless server_role_args="--api-server-count 16" export HCCL_BUFFSIZE=256 export HCCL_IF_IP=$local_ip export HCCL_OP_EXPANSION_MODE="AIV" export HCCL_SOCKET_IFNAME=$nic_name export ASCEND_RT_VISIBLE_DEVICES=$1 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib export VLLM_USE_FASTOKENS=1 export GLOO_SOCKET_IFNAME=$nic_name export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True # Ensure the model path matches the directory recorded during download vllm serve <MODEL_PATH> \ --host 0.0.0.0 \ --port $2 \ --data-parallel-size $3 \ --data-parallel-rank $4 \ --data-parallel-address $5 \ --data-parallel-rpc-port $6 \ --tensor-parallel-size $7 \ --enable-expert-parallel \ --seed 1024 \ --served-model-name glm-5 \ --max-model-len 202752 \ --safetensors-load-strategy 'prefetch' \ --max-num-batched-tokens 192 \ --compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' \ --kv-cache-dtype int8 \ --attention_config.indexer_kv_dtype int8 \ --speculative-config '{"num_speculative_tokens": 5, "method":"deepseek_mtp","enforce_eager":true}' \ --additional-config '{"fuse_muls_add":true, "recompute_scheduler_enable":true, "enable_fused_mc2": 1, "enable_mlapo": true}' \ --trust-remote-code \ --max-num-seqs 32 \ --gpu-memory-utilization 0.90 \ ${server_role_args} \ --async-scheduling \ --quantization ascend \ --enable-auto-tool-choice \ --tool-call-parser glm47 \ --reasoning-parser glm45 \ --kv-transfer-config '{ "kv_connector": "MooncakeConnectorV1", "kv_role": "kv_consumer", "kv_port": "30200", "engine_id": "2", "kv_connector_extra_config": { "use_ascend_direct": true, "prefill": {"dp_size": 1, "pp_size": 2, "tp_size": 16, "pp_layer_partition": "41,37"}, "decode": { "dp_size": 16, "tp_size": 2} } }' ```-
解码节点 1
nic_name="xxxx" # change to your own nic name local_ip="xxxx" # change to your own ip # d0: api server on this node; d1: --headless server_role_args="--headless" export HCCL_BUFFSIZE=256 export HCCL_IF_IP=$local_ip export HCCL_OP_EXPANSION_MODE="AIV" export HCCL_SOCKET_IFNAME=$nic_name export ASCEND_RT_VISIBLE_DEVICES=$1 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib export VLLM_USE_FASTOKENS=1 export GLOO_SOCKET_IFNAME=$nic_name export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True # Ensure the model path matches the directory recorded during download vllm serve <MODEL_PATH> \ --host 0.0.0.0 \ --port $2 \ --data-parallel-size $3 \ --data-parallel-rank $4 \ --data-parallel-address $5 \ --data-parallel-rpc-port $6 \ --tensor-parallel-size $7 \ --enable-expert-parallel \ --seed 1024 \ --served-model-name glm-5 \ --max-model-len 202752 \ --safetensors-load-strategy 'prefetch' \ --max-num-batched-tokens 192 \ --compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' \ --kv-cache-dtype int8 \ --attention_config.indexer_kv_dtype int8 \ --speculative-config '{"num_speculative_tokens": 5, "method":"deepseek_mtp","enforce_eager":true}' \ --additional-config '{"fuse_muls_add":true, "recompute_scheduler_enable":true, "enable_fused_mc2": 1, "enable_mlapo": true}' \ --trust-remote-code \ --max-num-seqs 32 \ --gpu-memory-utilization 0.90 \ ${server_role_args} \ --async-scheduling \ --quantization ascend \ --enable-auto-tool-choice \ --tool-call-parser glm47 \ --reasoning-parser glm45 \ --kv-transfer-config '{ "kv_connector": "MooncakeConnectorV1", "kv_role": "kv_consumer", "kv_port": "30200", "engine_id": "2", "kv_connector_extra_config": { "use_ascend_direct": true, "prefill": {"dp_size": 1, "pp_size": 2, "tp_size": 16, "pp_layer_partition": "41,37"}, "decode": { "dp_size": 16, "tp_size": 2} } }'
-
准备工作完成后,你可以在每个节点上使用以下命令启动服务器:
-
预填充节点 0
-
预填充节点 1
-
解码节点 0
-
解码节点 1
要设置请求转发,请在任意机器上运行以下脚本。你可以在仓库的 examples 目录中获取代理程序:load_balance_proxy_server_example.py
unset http_proxy
unset https_proxy
python load_balance_proxy_server_example.py \
--port 8000 \
--host 0.0.0.0 \
--prefiller-hosts \
$node_p0_ip \
--prefiller-ports \
9081 \
--decoder-hosts \
$node_d0_ip \
$node_d0_ip \
$node_d0_ip \
$node_d0_ip \
$node_d0_ip \
$node_d0_ip \
$node_d0_ip \
$node_d0_ip \
--decoder-ports \
9900 9901 9902 9903 9904 9905 9906 9907
关键参数说明:
以下仅描述该模型/场景特有的关键参数。max-model-len 和 max-num-seqs 需要根据实际使用场景进行设置。
API 服务器与分词器配置:
VLLM_USE_FASTOKENS=1:启用 Hugging Face 快速分词器的fastokens后端,以加速输入分词和输出反分词。必须安装fastokens包。--api-server-count 16:为每个面向 API 的vllm serve实例启动 16 个 API 服务器进程,以提升前端并发能力。该配置位于 Prefill 节点 0(p0)和 Decode 节点 0(d0);Prefill 节点 1(p1)和 Decode 节点 1(d1)保持无头。
PP2 Prefill 节点专属配置(p0/p1):
VLLM_PP_LAYER_PARTITION="41,37"/--pipeline-parallel-size 2/--nnodes 2/--node-rank:Prefill 引擎在两个 Prefill 节点上按 PP2 拆分——78 层划分为41/37。--node-rank在 Prefill 节点 0(p0)上为0,在 Prefill 节点 1(p1)上为1。--distributed-executor-backend mp/--master-addr/--master-port 7060:PP 通过mp执行器在两个节点上运行(无需 Ray)。--master-addr在 Prefill 节点 0(p0,PP 主节点)上为$local_ip,在 Prefill 节点 1(p1)上为$node_p0_ip。enable_fused_mc2:启用融合的dispatch_ffn_combine/mega_moe算子。enable_flashcomm1:启用 FlashComm 优化,以降低 Prefill 节点上的通信和计算开销。--enforce-eager:Prefill 侧以 eager 模式运行(Decode 侧改用FULL_DECODE_ONLY图捕获)。--speculative-config '{"num_speculative_tokens": 1, ...}':Prefill 期间使用最小 MTP 推测(Decode 节点使用更高数量,见下文)。fuse_muls_add/enable_dsa_cp/--kv-cache-dtype int8/--attention_config.indexer_kv_dtype int8:Mul-Add 融合、用于长上下文 Prefill 的 DSA 上下文并行、SFA/LI 稀疏注意力优化,以及 C8 量化模型的 reshape 优化。
Decode 节点专属配置(d0/d1):
enable_mlapo:在 Decode 节点上启用 MLAPO 融合,用于受内存带宽限制的 Token 生成。--max-num-batched-tokens 192:Decode 节点上的小批量 Token 上限——每个序列每步 Decode 处理 1 个目标 Token 加 5 个推测 MTP Token((5 + 1) × 32)。--speculative-config '{"num_speculative_tokens": 5, ...}':Decode 节点使用更高的 MTP 推测数量,以最大化 Decode 吞吐量。recompute_scheduler_enable=true:启用重计算调度器。当 Decode 节点 KV 缓存不足时,请求会被发回 Prefill 节点重新计算 KV 缓存。--async-scheduling:Decode 侧异步调度。
Mooncake KV 传输配置(--kv-transfer-config):
"kv_connector": "MooncakeConnectorV1":使用 Mooncake 作为 Prefill 节点与 Decode 节点之间的 KV 缓存传输连接器。"kv_role": "kv_producer"/"kv_consumer":Prefill 节点使用kv_producer,Decode 节点使用kv_consumer。"kv_port":Mooncake KV 传输通信端口。Prefill(30000)和 Decode(30200)节点组使用不同端口范围。"use_ascend_direct": true:启用 Ascend 直传以传输 KV 缓存,降低延迟。"engine_id":每个角色组中 Mooncake 连接器的固定 engine id:Prefill 引擎为0(由两个 PP rank 共享),Decode 引擎为2。"prefill"/"decode"部分:分别指定 Prefill 节点组和 Decode 节点组的并行度。它们必须与实际部署拓扑一致(prefill: dp_size 1, pp_size 2, tp_size 16, pp_layer_partition "41,37"、decode: dp_size 16, tp_size 2)。
请求转发(代理):
- 代理程序可在 load_balance_proxy_server_example.py 中找到。
有关上述环境变量的进一步说明和限制,请参阅 envs.py。
5.1.3.2 在 8 台 Atlas 800 A2 上部署¶
在 Atlas 800 A2 上,每个节点提供 8 张卡,相同的全局 P/D 拓扑(Prefill DP4 TP8、Decode DP8 TP4)被拆分到 8 个节点:4 个 Prefill 节点,每个承载 1 个 DP rank(每个 rank 8 张卡);4 个 Decode 节点,每个承载 2 个 DP rank(每个 rank 4 张卡)。上述 launch_online_dp.py 原样复用。Prefill 侧启用 FlashComm1 和 DSA CP;Decode 侧启用 MLAPO 和 DYNAMIC_EPLB,并使用 FULL_DECODE_ONLY 图。两侧均启用前缀缓存和 MTP(num_speculative_tokens=3)。下文中的所有 IP、NIC 名称、端口和权重路径均为占位符。
Prefill 节点的 run_dp_template.sh:
#!/usr/bin/bash
nic_name="<NIC_NAME>"
local_ip="<CURRENT_NODE_IP>"
export HCCL_BUFFSIZE=256
export HCCL_IF_IP=$local_ip
export HCCL_INTRA_ROCE_ENABLE=1
export HCCL_OP_EXPANSION_MODE="AIV"
export HCCL_SOCKET_IFNAME=$nic_name
export ASCEND_RT_VISIBLE_DEVICES=$1
export LD_LIBRARY_PATH=/usr/local/python3.11.10/lib:/usr/local/lib:$LD_LIBRARY_PATH
export GLOO_SOCKET_IFNAME=$nic_name
export MOONCAKE_CONFIG_PATH="/mnt/share/scripts/mooncake.json"
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export PYTHONHASHSEED=0
# Ensure the model path matches the directory recorded during download
vllm serve /root/.cache/modelscope/hub/models/vllm-ascend/GLM-5.2-w8a8c8 \
--host 0.0.0.0 \
--port $2 \
--data-parallel-size $3 \
--data-parallel-rank $4 \
--data-parallel-address $5 \
--data-parallel-rpc-port $6 \
--tensor-parallel-size $7 \
--enable-expert-parallel \
--enable-prefix-caching \
--seed 1024 \
--enable-chunked-prefill \
--served-model-name glm-5 \
--max-model-len 200000 \
--max-num-batched-tokens 8192 \
--trust-remote-code \
--max-num-seqs 512 \
--gpu-memory-utilization 0.92 \
--safetensors-load-strategy prefetch \
--quantization ascend \
--enforce-eager \
--enable-auto-tool-choice \
--tool-call-parser glm47 \
--reasoning-parser glm45 \
--kv-transfer-config \
'{
"kv_connector": "MultiConnector",
"kv_role": "kv_producer",
"kv_load_failure_policy": "recompute",
"kv_connector_extra_config": {
"connectors": [
{
"kv_connector": "MooncakeConnectorV1",
"kv_role": "kv_producer",
"kv_port": "30000",
"kv_connector_extra_config": {
"prefill": {
"dp_size": 4,
"tp_size": 8
},
"decode": {
"dp_size": 8,
"tp_size": 4
}
}
},
{
"kv_connector": "AscendStoreConnector",
"kv_role": "kv_producer",
"kv_connector_extra_config": {
"lookup_rpc_port":"0",
"backend": "mooncake"
}
}
]
}
}' \
--kv-cache-dtype int8 \
--attention_config.indexer_kv_dtype int8 \
--additional-config '{"enable_flashcomm1": true, "enable_dsa_cp": true, "ascend_compilation_config": {"enable_npugraph_ex": true, "enable_static_kernel": false}, "fuse_muls_add": true, "multistream_overlap_shared_expert": true, "enable_mc2_hierarchy_comm": false, "enable_cpu_binding": true, "recompute_scheduler_enable": false, "enable_mlapo": true}' \
--profiler-config \
'{
"profiler": "torch",
"torch_profiler_dir": "/mnt/share/xxx/prof",
"torch_profiler_with_stack": false
}' \
--speculative-config '{"num_speculative_tokens": 1, "method":"deepseek_mtp", "enforce_eager":true}'
run_dp_template.sh 用于解码节点:
#!/usr/bin/bash
nic_name="<NIC_NAME>"
local_ip="<CURRENT_NODE_IP>"
export HCCL_BUFFSIZE=2560
export HCCL_IF_IP=$local_ip
export HCCL_INTRA_ROCE_ENABLE=1
export HCCL_OP_EXPANSION_MODE="AIV"
export HCCL_SOCKET_IFNAME=$nic_name
export ASCEND_RT_VISIBLE_DEVICES=$1
export LD_LIBRARY_PATH=/usr/local/python3.11.10/lib:/usr/local/lib:$LD_LIBRARY_PATH
export GLOO_SOCKET_IFNAME=$nic_name
export MOONCAKE_CONFIG_PATH="/mnt/share/scripts/mooncake.json"
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export PYTHONHASHSEED=0
# Ensure the model path matches the directory recorded during download
vllm serve /root/.cache/modelscope/hub/models/vllm-ascend/GLM-5.2-w8a8c8 \
--host 0.0.0.0 \
--port $2 \
--data-parallel-size $3 \
--data-parallel-rank $4 \
--data-parallel-address $5 \
--data-parallel-rpc-port $6 \
--tensor-parallel-size $7 \
--enable-expert-parallel \
--enable-prefix-caching \
--seed 1024 \
--served-model-name glm-5 \
--max-model-len 200000 \
--max-num-batched-tokens 256 \
--trust-remote-code \
--max-num-seqs 256 \
--gpu-memory-utilization 0.92 \
--safetensors-load-strategy prefetch \
--quantization ascend \
--enable-auto-tool-choice \
--tool-call-parser glm47 \
--reasoning-parser glm45 \
--kv-transfer-config \
'{
"kv_connector": "MultiConnector",
"kv_role": "kv_consumer",
"kv_load_failure_policy": "recompute",
"kv_connector_extra_config": {
"connectors": [
{
"kv_connector": "MooncakeConnectorV1",
"kv_role": "kv_consumer",
"kv_port": "30100",
"kv_connector_extra_config": {
"prefill": {
"dp_size": 4,
"tp_size": 8
},
"decode": {
"dp_size": 8,
"tp_size": 4
}
}
},
{
"kv_connector": "AscendStoreConnector",
"kv_role": "kv_consumer",
"kv_connector_extra_config": {
"lookup_rpc_port":"0",
"backend": "mooncake"
}
}
]
}
}' \
--compilation-config \
'{
"cudagraph_mode": "FULL_DECODE_ONLY",
"cudagraph_capture_sizes": [4,8,16,24,32,40,48,56,64,96,128,160,192,224,256,298,320,352,384]
}' \
--profiler-config \
'{
"profiler": "torch",
"torch_profiler_dir": "/mnt/share/xxx/prof",
"torch_profiler_with_stack": false
}' \
--kv-cache-dtype int8 \
--attention_config.indexer_kv_dtype int8 \
--additional-config '{"enable_flashcomm1": false, "enable_dsa_cp": false, "ascend_compilation_config": {"enable_npugraph_ex": true, "enable_static_kernel": false}, "fuse_muls_add": true, "multistream_overlap_shared_expert": true, "enable_mc2_hierarchy_comm": false, "enable_cpu_binding": true, "recompute_scheduler_enable": true, "enable_mlapo": true}' \
--speculative-config '{"num_speculative_tokens": 3, "method":"deepseek_mtp", "enforce_eager":true}'
准备工作完成后,使用以下命令启动服务器:
-
预填充节点 — 在
$node_p0_ip、$node_p1_ip、$node_p2_ip、$node_p3_ip上运行,--dp-rank-start分别为0/1/2/3:python launch_online_dp.py --dp-size 4 --tp-size 8 --dp-size-local 1 --dp-rank-start 0 --dp-address $node_p0_ip --dp-rpc-port 16591 --vllm-start-port 9081 python launch_online_dp.py --dp-size 4 --tp-size 8 --dp-size-local 1 --dp-rank-start 1 --dp-address $node_p0_ip --dp-rpc-port 16591 --vllm-start-port 9081 python launch_online_dp.py --dp-size 4 --tp-size 8 --dp-size-local 1 --dp-rank-start 2 --dp-address $node_p0_ip --dp-rpc-port 16591 --vllm-start-port 9081 python launch_online_dp.py --dp-size 4 --tp-size 8 --dp-size-local 1 --dp-rank-start 3 --dp-address $node_p0_ip --dp-rpc-port 16591 --vllm-start-port 9081 -
解码节点 — 在
$node_d0_ip、$node_d1_ip、$node_d2_ip、$node_d3_ip上运行,--dp-rank-start分别为0/2/4/6:python launch_online_dp.py --dp-size 8 --tp-size 4 --dp-size-local 2 --dp-rank-start 0 --dp-address $node_d0_ip --dp-rpc-port 16600 --vllm-start-port 9900 python launch_online_dp.py --dp-size 8 --tp-size 4 --dp-size-local 2 --dp-rank-start 2 --dp-address $node_d0_ip --dp-rpc-port 16600 --vllm-start-port 9900 python launch_online_dp.py --dp-size 8 --tp-size 4 --dp-size-local 2 --dp-rank-start 4 --dp-address $node_d0_ip --dp-rpc-port 16600 --vllm-start-port 9900 python launch_online_dp.py --dp-size 8 --tp-size 4 --dp-size-local 2 --dp-rank-start 6 --dp-address $node_d0_ip --dp-rpc-port 16600 --vllm-start-port 9900
对于此 8 节点 A2 布局的请求转发,请在下面的请求转发命令中使用 4 个预填充主机(每个 1 个端点)和 4 个解码主机(每个 2 个端点)。
要设置请求转发,请在任意机器上运行以下脚本。您可以在仓库的 examples 目录中获取代理程序:load_balance_proxy_server_example.py
unset http_proxy
unset https_proxy
python load_balance_proxy_server_example.py \
--port 8000 \
--host 0.0.0.0 \
--prefiller-hosts \
$node_p0_ip \
$node_p1_ip \
$node_p2_ip \
$node_p3_ip \
--prefiller-ports \
9081 9081 \
9081 9081 \
--decoder-hosts \
$node_d0_ip \
$node_d0_ip \
$node_d1_ip \
$node_d1_ip \
$node_d2_ip \
$node_d2_ip \
$node_d3_ip \
$node_d3_ip \
--decoder-ports \
9900 9901 9900 9901 \
9900 9901 9900 9901
注意:
下面展示了一些用于优化的配置:
enable_flashcomm1:启用 FlashComm 优化,以减少预填充节点上的通信和计算开销。启用 FlashComm 后,layer_sharding 列表不能包含 o_proj 作为元素。enable_fused_mc2:启用 dispatch_ffn_combine/mega_moe 融合算子。
有关上述环境变量的进一步说明和限制,请参阅以下 Python 文件:envs.py
5.2 1M 上下文配置¶
5.2.1 单节点 1M 部署¶
- 量化模型
GLM-5.2-w4a8c8可部署在 1 台 Atlas 800 A3(64GB × 16)上,用于 1M 上下文。
推荐命令:
export HCCL_BUFFSIZE=768
export HCCL_OP_EXPANSION_MODE="AIV"
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
# Ensure the model path matches the directory recorded during download
vllm serve <MODEL_PATH> \
--seed 1024 \
--host 0.0.0.0 \
--port 8000 \
--served-model-name glm-52 \
--max-model-len 1024000 \
--max-num-batched-tokens 16384 \
--gpu-memory-utilization 0.80 \
--api-server-count 1 \
--max-num-seqs 32 \
--data-parallel-size 1 \
--pipeline-parallel-size 1 \
--tensor-parallel-size 16 \
--prefill-context-parallel-size 1 \
--decode-context-parallel-size 16 \
--cp-kv-cache-interleave-size 128 \
--compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY", "cudagraph_capture_sizes": [4, 16, 128]}' \
--kv-cache-dtype int8 \
--attention_config.indexer_kv_dtype int8 \
--additional-config '{"enable_flashcomm1": true, "enable_dsa_cp": true, "ascend_compilation_config": {"enable_npugraph_ex": true, "enable_static_kernel": false}, "fuse_muls_add": true, "multistream_overlap_shared_expert": true, "enable_mc2_hierarchy_comm": false, "enable_cpu_binding": true, "recompute_scheduler_enable": false, "weight_nz_mode": 1}' \
--speculative-config '{"num_speculative_tokens": 3, "method": "deepseek_mtp", "enforce_eager": true}' \
--quantization ascend \
--enable-expert-parallel \
--safetensors-load-strategy prefetch
5.2.2 双节点共置 1M 部署¶
GLM-5.2-w4a8c8可部署在 2 台 Atlas 800 A3(64GB × 16)上,用于 1M 上下文。
两个共置节点的推荐命令:
nic_name="<NIC_NAME>"
local_ip="<CURRENT_NODE_IP>"
node_0_ip="<NODE0_IP>"
# Node 0: data_parallel_start_rank=0, server_role_args="--api-server-count 1"
# Node 1: data_parallel_start_rank=2, server_role_args="--headless"
data_parallel_start_rank=0
server_role_args="--api-server-count 1"
export HCCL_BUFFSIZE=768
export HCCL_IF_IP=$local_ip
export HCCL_OP_EXPANSION_MODE="AIV"
export HCCL_SOCKET_IFNAME=$nic_name
export GLOO_SOCKET_IFNAME=$nic_name
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
# Ensure the model path matches the directory recorded during download
vllm serve <MODEL_PATH> \
--seed 1024 \
--host 0.0.0.0 \
--port 8000 \
--served-model-name glm-52 \
--max-model-len 1024000 \
--max-num-batched-tokens 16384 \
--gpu-memory-utilization 0.75 \
${server_role_args} \
--max-num-seqs 8 \
--data-parallel-size 4 \
--data-parallel-size-local 2 \
--data-parallel-start-rank $data_parallel_start_rank \
--data-parallel-address $node_0_ip \
--data-parallel-rpc-port 16591 \
--pipeline-parallel-size 1 \
--tensor-parallel-size 8 \
--prefill-context-parallel-size 1 \
--decode-context-parallel-size 8 \
--cp-kv-cache-interleave-size 128 \
--compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' \
--kv-cache-dtype int8 \
--attention_config.indexer_kv_dtype int8 \
--additional-config '{"enable_flashcomm1": true, "enable_dsa_cp": true, "ascend_compilation_config": {"enable_npugraph_ex": true, "enable_static_kernel": false}, "fuse_muls_add": true, "multistream_overlap_shared_expert": true, "enable_mc2_hierarchy_comm": false, "enable_cpu_binding": true, "recompute_scheduler_enable": false, "weight_nz_mode": 1}' \
--speculative-config '{"num_speculative_tokens": 3, "method": "deepseek_mtp", "enforce_eager": true}' \
--quantization ascend \
--enable-expert-parallel \
--safetensors-load-strategy prefetch
5.2.3 PD 分离 1M 部署¶
使用 GLM-5.2-w8a8c8 权重进行 1M 上下文的 PD 分离部署,可部署在 4 台 Atlas 800 A3(64GB × 16)上。
开始前,请
在每个节点上准备脚本 launch_online_dp.py(供下文中的 prefill 和 decode 节点传递引擎端口和 DP 参数):
```python
import argparse
import multiprocessing
import os
import subprocess
import sys
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument(
"--dp-size",
type=int,
required=True,
help="Data parallel size."
)
parser.add_argument(
"--tp-size",
type=int,
default=1,
help="Tensor parallel size."
)
parser.add_argument(
"--dp-size-local",
type=int,
default=-1,
help="Local data parallel size."
)
parser.add_argument(
"--dp-rank-start",
type=int,
default=0,
help="Starting rank for data parallel."
)
parser.add_argument(
"--dp-address",
type=str,
required=True,
help="IP address for data parallel master node."
)
parser.add_argument(
"--dp-rpc-port",
type=str,
default=12345,
help="Port for data parallel master node."
)
parser.add_argument(
"--vllm-start-port",
type=int,
default=8000,
help="Starting port for the engine."
)
return parser.parse_args()
args = parse_args()
dp_size = args.dp_size
tp_size = args.tp_size
dp_size_local = args.dp_size_local
if dp_size_local == -1:
dp_size_local = dp_size
dp_rank_start = args.dp_rank_start
dp_address = args.dp_address
dp_rpc_port = args.dp_rpc_port
vllm_start_port = args.vllm_start_port
def run_command(visible_devices, dp_rank, vllm_engine_port):
command = [
"bash",
"./run_dp_template.sh",
visible_devices,
str(vllm_engine_port),
str(dp_size),
str(dp_rank),
dp_address,
dp_rpc_port,
str(tp_size),
]
subprocess.run(command, check=True)
if __name__ == "__main__":
template_path = "./run_dp_template.sh"
if not os.path.exists(template_path):
print(f"Template file {template_path} does not exist.")
sys.exit(1)
processes = []
num_cards = dp_size_local * tp_size
for i in range(dp_size_local):
dp_rank = dp_rank_start + i
vllm_engine_port = vllm_start_port + i
visible_devices = ",".join(str(x) for x in range(i * tp_size, (i + 1) * tp_size))
process = multiprocessing.Process(target=run_command,
args=(visible_devices, dp_rank,
vllm_engine_port))
processes.append(process)
process.start()
for process in processes:
process.join()
```
在每个节点上准备脚本 run_dp_template.sh。
-
Prefill 节点 0
nic_name="<NIC_NAME>" # change to your own nic name local_ip="<CURRENT_PREFILL_NODE_IP>" # change to your own ip # p0: api server on this node; p1: --headless server_role_args="--api-server-count 1" export VLLM_EXECUTE_MODEL_TIMEOUT_SECONDS=30000 export HCCL_BUFFSIZE=400 export HCCL_IF_IP=$local_ip export HCCL_OP_EXPANSION_MODE="AIV" export HCCL_SOCKET_IFNAME=$nic_name export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib export GLOO_SOCKET_IFNAME=$nic_name export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True export MF_GROUP_JOIN_MAX_TIMEOUT=1200 # Ensure the model path matches the directory recorded during download vllm serve <MODEL_PATH> \ --host 0.0.0.0 \ --port $2 \ --data-parallel-size $3 \ --data-parallel-rank $4 \ --data-parallel-address $5 \ --data-parallel-rpc-port $6 \ --tensor-parallel-size $7 \ --enable-expert-parallel \ --prefill-context-parallel-size 1 \ --decode-context-parallel-size 16 \ --cp-kv-cache-interleave-size 128 \ --speculative-config '{"num_speculative_tokens": 1, "method":"deepseek_mtp","enforce_eager":true}' \ --seed 1024 \ --served-model-name glm-5 \ --max-model-len 1048576 \ --safetensors-load-strategy 'prefetch' \ --kv-cache-dtype int8 \ --attention_config.indexer_kv_dtype int8 \ --additional-config '{"fuse_muls_add":true, "multistream_overlap_shared_expert": true, "enable_dsa_cp":true, "c8_enable_reshape_optim":true, "mega_moe_max_tokens": 8192, "enable_flashcomm1": true, "enable_fused_mc2": 1}' \ --max-num-batched-tokens 8192 \ --trust-remote-code \ --enable-prefix-caching \ --max-num-seqs 64 \ --quantization ascend \ --gpu-memory-utilization 0.85 \ ${server_role_args} \ --enforce-eager \ --enable-auto-tool-choice \ --tool-call-parser glm47 \ --reasoning-parser glm45 \ --kv-transfer-config '{ "kv_connector": "MooncakeConnectorV1", "kv_role": "kv_producer", "kv_port": "30000", "engine_id": "0", "kv_connector_extra_config": { "use_ascend_direct": true, "prefill": {"dp_size": 2, "tp_size": 16}, "decode": { "dp_size": 4, "tp_size": 8} } }' -
Prefill 节点 1
DP 排名
1,引擎端口9082。与 p0 使用相同脚本,但server_role_args="--headless"(非主节点,无 API 服务器);--data-parallel-address($5)仍指向 Prefill 节点 0(DP 主节点)。nic_name="<NIC_NAME>" # change to your own nic name local_ip="<CURRENT_PREFILL_NODE_IP>" # change to your own ip # p0: api server on this node; p1: --headless server_role_args="--headless" export VLLM_EXECUTE_MODEL_TIMEOUT_SECONDS=30000 export HCCL_BUFFSIZE=400 export HCCL_IF_IP=$local_ip export HCCL_OP_EXPANSION_MODE="AIV" export HCCL_SOCKET_IFNAME=$nic_name export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib export GLOO_SOCKET_IFNAME=$nic_name export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True export MF_GROUP_JOIN_MAX_TIMEOUT=1200 vllm serve <MODEL_PATH> \ --host 0.0.0.0 \ --port $2 \ --data-parallel-size $3 \ --data-parallel-rank $4 \ --data-parallel-address $5 \ --data-parallel-rpc-port $6 \ --tensor-parallel-size $7 \ --enable-expert-parallel \ --prefill-context-parallel-size 1 \ --decode-context-parallel-size 16 \ --cp-kv-cache-interleave-size 128 \ --speculative-config '{"num_speculative_tokens": 1, "method":"deepseek_mtp","enforce_eager":true}' \ --seed 1024 \ --served-model-name glm-5 \ --max-model-len 1048576 \ --safetensors-load-strategy 'prefetch' \ --kv-cache-dtype int8 \ --attention_config.indexer_kv_dtype int8 \ --additional-config '{"fuse_muls_add":true, "multistream_overlap_shared_expert": true, "c8_enable_reshape_optim":true, "mega_moe_max_tokens": 8192, "enable_flashcomm1": true, "enable_fused_mc2": 1}' \ --max-num-batched-tokens 8192 \ --trust-remote-code \ --enable-prefix-caching \ --max-num-seqs 64 \ --quantization ascend \ --gpu-memory-utilization 0.85 \ ${server_role_args} \ --enforce-eager \ --enable-auto-tool-choice \ --tool-call-parser glm47 \ --reasoning-parser glm45 \ --kv-transfer-config '{ "kv_connector": "MooncakeConnectorV1", "kv_role": "kv_producer", "kv_port": "30000", "engine_id": "0", "kv_connector_extra_config": { "use_ascend_direct": true, "prefill": {"dp_size": 2, "tp_size": 16}, "decode": { "dp_size": 4, "tp_size": 8} } }' -
Decode 节点 0
nic_name="<NIC_NAME>" # change to your own nic name local_ip="<CURRENT_DECODE_NODE_IP>" # change to your own ip # d0: api server on this node; d1: --headless server_role_args="--api-server-count 1" export VLLM_EXECUTE_MODEL_TIMEOUT_SECONDS=30000 export HCCL_BUFFSIZE=400 export HCCL_IF_IP=$local_ip export HCCL_OP_EXPANSION_MODE="AIV" export HCCL_SOCKET_IFNAME=$nic_name export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib export GLOO_SOCKET_IFNAME=$nic_name export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True export MF_GROUP_JOIN_MAX_TIMEOUT=1200 vllm serve <MODEL_PATH> \ --host 0.0.0.0 \ --port $2 \ --data-parallel-size $3 \ --data-parallel-rank $4 \ --data-parallel-address $5 \ --data-parallel-rpc-port $6 \ --tensor-parallel-size $7 \ --enable-expert-parallel \ --prefill-context-parallel-size 1 \ --decode-context-parallel-size 8 \ --cp-kv-cache-interleave-size 128 \ --seed 1024 \ --served-model-name glm-5 \ --max-model-len 1048576 \ --safetensors-load-strategy 'prefetch' \ --max-num-batched-tokens 192 \ --compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' \ --speculative-config '{"num_speculative_tokens": 5, "method":"deepseek_mtp","enforce_eager":true}' \ --kv-cache-dtype int8 \ --attention_config.indexer_kv_dtype int8 \ --additional-config '{"fuse_muls_add":true, "recompute_scheduler_enable":true, "multistream_overlap_shared_expert":true, "enable_fused_mc2": 1, "enable_mlapo": true}' \ --trust-remote-code \ --max-num-seqs 32 \ --gpu-memory-utilization 0.90 \ ${server_role_args} \ --async-scheduling \ --quantization ascend \ --enable-auto-tool-choice \ --tool-call-parser glm47 \ --reasoning-parser glm45 \ --kv-transfer-config '{ "kv_connector": "MooncakeConnectorV1", "kv_role": "kv_consumer", "kv_port": "30200", "engine_id": "2", "kv_connector_extra_config": { "use_ascend_direct": true, "prefill": {"dp_size": 2, "tp_size": 16}, "decode": { "dp_size": 4, "tp_size": 8} } }' -
解码节点 1
nic_name="<NIC_NAME>" # change to your own nic name local_ip="<CURRENT_DECODE_NODE_IP>" # change to your own ip # d0: api server on this node; d1: --headless server_role_args="--headless" export VLLM_EXECUTE_MODEL_TIMEOUT_SECONDS=30000 export HCCL_BUFFSIZE=400 export HCCL_IF_IP=$local_ip export HCCL_OP_EXPANSION_MODE="AIV" export HCCL_SOCKET_IFNAME=$nic_name export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib export GLOO_SOCKET_IFNAME=$nic_name export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True export MF_GROUP_JOIN_MAX_TIMEOUT=1200 vllm serve <MODEL_PATH> \ --host 0.0.0.0 \ --port $2 \ --data-parallel-size $3 \ --data-parallel-rank $4 \ --data-parallel-address $5 \ --data-parallel-rpc-port $6 \ --tensor-parallel-size $7 \ --enable-expert-parallel \ --prefill-context-parallel-size 1 \ --decode-context-parallel-size 8 \ --cp-kv-cache-interleave-size 128 \ --seed 1024 \ --served-model-name glm-5 \ --max-model-len 1048576 \ --safetensors-load-strategy 'prefetch' \ --max-num-batched-tokens 192 \ --kv-cache-dtype int8 \ --attention_config.indexer_kv_dtype int8 \ --compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' \ --speculative-config '{"num_speculative_tokens": 5, "method":"deepseek_mtp","enforce_eager":true}' \ --additional-config '{"fuse_muls_add":true, "recompute_scheduler_enable":true, "multistream_overlap_shared_expert":true, "enable_fused_mc2": 1, "enable_mlapo": true}' \ --trust-remote-code \ --max-num-seqs 32 \ --gpu-memory-utilization 0.90 \ ${server_role_args} \ --async-scheduling \ --quantization ascend \ --enable-auto-tool-choice \ --tool-call-parser glm47 \ --reasoning-parser glm45 \ --kv-transfer-config '{ "kv_connector": "MooncakeConnectorV1", "kv_role": "kv_consumer", "kv_port": "30200", "engine_id": "2", "kv_connector_extra_config": { "use_ascend_direct": true, "prefill": {"dp_size": 2, "tp_size": 16}, "decode": { "dp_size": 4, "tp_size": 8} } }'
准备工作完成后,在每个节点上启动服务器:
-
预填充节点 0
-
预填充节点 1
-
解码节点 0
-
解码节点 1
要设置请求转发,请在任意机器上运行以下脚本。
unset http_proxy
unset https_proxy
python load_balance_proxy_server_example.py \
--port 8000 \
--host 0.0.0.0 \
--prefiller-hosts \
$node_p0_ip \
--prefiller-ports \
9081 \
--decoder-hosts \
$node_d0_ip \
$node_d0_ip \
--decoder-ports \
9900 9901
关键参数说明(除 预填充-解码分离 和 单节点 1M 部署 之外):
run_dp_template.sh 模板使用 launch_online_dp.py 传入的位置参数:$1 = 可见设备,$2 = 引擎端口,$3 = data-parallel-size,$4 = data-parallel-rank,$5 = data-parallel-address,$6 = data-parallel-rpc-port,$7 = tensor-parallel-size。
1M 特定环境变量(预填充节点和解码节点均适用):
VLLM_EXECUTE_MODEL_TIMEOUT_SECONDS=30000/MF_GROUP_JOIN_MAX_TIMEOUT=1200:1M 上下文场景下,多节点启动缓慢和模型执行的超时设置。如果引擎未能及时就绪,请增大这些值。
预填充节点(1M):
--speculative-config '{"num_speculative_tokens": 1, ...}':预填充阶段的最小 MTP 推测。mega_moe_max_tokens=8192:融合 MC2/MegaMoe 路径中分发后每个 rank 的 Token 容量。--kv-transfer-config:Mooncake 连接器作为kv_producer,配置为prefill: dp2 tp16/decode: dp4 tp8。
解码节点(1M):
--max-num-batched-tokens 192:解码节点上的小批量 Token 限制——解码节点会存储从预填充节点接收到的大型 1M KV 缓存。enable_mlapo:解码节点上的 MLAPO 融合,用于受内存带宽限制的 Token 生成。--kv-transfer-config:Mooncake 连接器作为kv_consumer(kv_port: 30200)。
有关上述环境变量的进一步说明和限制,请参阅 envs.py。
6 功能验证¶
服务器启动后,您可以使用输入 Prompt 查询模型:
curl http://<node0_ip>:<port>/v1/completions \
-H "Content-Type: application/json" \
-d '{
"model": "glm-52",
"prompt": "The future of AI is",
"max_completion_tokens": 50,
"temperature": 0
}'
预期结果:
服务返回 HTTP 200 OK。JSON 响应包含带有生成文本的 choices 字段,以及使用统计信息:
{
"id": "chatcmpl-90e6de0720743e72",
"object": "text_completion",
"created": 1784891079,
"model": "glm-52",
"choices": [
{
"index": 0,
"text": "here,and it's not just about chatbots. It's about AI agents",
"logprobs":null,
"finish_reason":"length",
"stop_reason":null,
"token_ids":null,
"prompt_logprobs":null,
"prompt_token_ids":null,
"routed_experts":null
}
],
"service_tier":null,
"system fingerprint":"vllm-0.26.0-tp16-ep-2a76151d",
"usage":{
"prompt tokens :5,
"total tokens :21,
"completion tokens":16,
"prompt tokens details :null
},
"ky transfer params":null
}
}
7 准确性评估¶
使用 AISBench¶
-
有关详细信息,请参阅 使用 AISBench。
-
执行完成后,您可以获取结果。
| 数据集 | 版本 | 指标 | 模式 | vllm-api-general-chat | 备注 |
|---|---|---|---|---|---|
| AIME2026 | - | 准确率 | gen | 93.33 | 4 Atlas 800 A3 (64GB × 16) |
| GPQA | - | 准确率 | gen | 90.4 | 8 Atlas 800 A3 (64GB × 16) |
| GPQA | - | 准确率 | gen | 91.92 | 8 Atlas 800 A2 (64GB × 8) |
8 性能评估¶
8.1 使用 AISBench¶
有关详细信息,请参阅 使用 AISBench 进行性能评估。
8.2 使用 vLLM 基准测试¶
有关更多详细信息,请参阅 vllm benchmark。
注意:
max-model-len 和 max-num-seqs 需要根据实际使用场景进行设置。其他设置请参阅 部署 章节。
9 性能调优¶
9.1 已测试性能用例¶
表 1:仅预填充测试用例¶
| 场景 | 配置 | NPU 数量 | TP | DP | PP | 最大模型长度 | MTP 推测数量 |
|---|---|---|---|---|---|---|---|
| 仅解码 | Server-P 节点 | 32 (A3) | 16 | 1 | 2 | 198k | 1 |
| 仅解码 | Server-D 节点 | 32 (A3) | 16 | 2 | 1 | 198k | 5 |
| 仅预填充 | Server-P 节点 | 32 (A3) | 16 | 1 | 2 | 198k | 1 |
| 仅预填充 | Server-D 节点 | 32 (A3) | 16 | 2 | 1 | 198k | 5 |
| 高并发 | Server-P 节点 | 32 (A3) | 16 | 1 | 2 | 198k | 1 |
| 高并发 | Server-D 节点 | 32 (A3) | 16 | 2 | 1 | 198k | 5 |
| 高并发(1M) | Server-P 节点 | 32 (A3) | 16 | 1 | 2 | 198k | 1 |
| 高并发(1M) | Server-D 节点 | 32 (A3) | 16 | 2 | 1 | 198k | 5 |
9.2 推荐配置¶
表 2:需要显式启用的优化¶
| 优化项 | 场景 | 启用方式 | 原理(收益) | 备注 |
|---|---|---|---|---|
| FlashComm_v1 | A3 预填充节点 / 共置节点 | --additional-config '{"enable_flashcomm1": true}' |
将 AllReduce 拆分为 Reduce-Scatter 和 All-Gather,提升预填充吞吐量并降低通信延迟 | 当 layer_sharding 包含 o_proj 时不可用 |
| Fused MC2 | A3 预填充节点 | --additional-config '{"enable_fused_mc2": 1}' |
使用 dispatch_ffn_combine/dispatch_gmm_combine_decode 算子替换 ALLTOALL+MC2,降低 MoE 通信开销并提升 MoE 推理性能 |
dispatch_ffn_combine 仅适用于 w8a8、EP≤32、非 MTP、非动态 EPLB;与 multistream_overlap_shared_expert 冲突(后者会自动禁用) |
| MLAPO | A3 共置 / PD 解码节点;A2 P/D 节点 | --additional-config '{"enable_mlapo": true}' |
融合 MLA 预处理操作,显著提升解码性能 | 会消耗更多 NPU 内存;在 PD 场景中仅在解码节点启用 |
| DSA CP | A3 预填充节点;长上下文 | --additional-config '{"enable_dsa_cp": true}' |
DSA 上下文并行可加速长上下文预填充,降低长提示词的 TTFT | 在参考配置中,在共置节点和 PD 预填充节点上启用;PD 解码节点改用解码上下文并行 |
| Sparse SFA C8 | A3 (w8a8c8);长上下文预填充 | --kv-cache-dtype int8 |
稀疏 Flash Attention 会跳过 C8 量化模型中不必要的注意力计算,加速长上下文预填充 | 在 v0.23.0 中为实验性功能。在 w8a8c8 权重上,可与 DCP/上下文并行组合使用(如本文档中的参考配置);在 w4a8c8 权重上同时启用两者存在已知问题,不推荐 |
| Sparse LI C8 | A3 (w8a8c8) | --attention_config.indexer_kv_dtype int8 |
稀疏注意力优化可减少 C8 量化模型的计算量,提升吞吐量 | 独立于 --kv-cache-dtype int8 |
|Recompute Scheduler|A3 解码节点|--additional-config '{"recompute_scheduler_enable": true}'|当解码 KV 缓存不足时,在预填充节点上重算 KV 缓存,避免解码端 OOM 并提升吞吐量|在预填充节点上设置为 false|
|Multistream Overlap Shared Expert|A3|--additional-config '{"multistream_overlap_shared_expert": true}'|在额外流上重叠共享专家计算,隐藏其延迟并提升解码性能|当 enable_fused_mc2=1 时自动禁用|
10 常见问题¶
- 问:如何为 GLM-5.2 启用函数调用?
答:请在 vLLM 启动命令中添加以下配置
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 vl/vllm-ascend