Kimi-K2.5¶
1.简介¶
Kimi K2.5 是一个开源的、原生的多模态智能体模型,通过在 Kimi-K2-Base 基础上对约 15 万亿混合视觉和文本 token 进行持续预训练而构建。它将视觉和语言理解与高级智能体能力、即时模式和思考模式,以及对话范式和智能体范式无缝集成。
本文档将展示模型的主要验证步骤,包括支持的特性、特性配置、环境准备、单节点和多节点部署、精度评估和性能评估。
本文档基于 vLLM-Ascend v0.17.0rc1 进行验证和编写。当前模型(Kimi-K2.5)在此版本中首次得到支持,**v0.17.0rc1 及更高版本**可稳定运行。
2.支持的特性¶
请参阅支持的特性矩阵获取模型支持的特性列表。
请参阅特性指南获取特性的配置方法。
3.前提条件¶
3.1 模型权重¶
Kimi-K2.5-w4a8(w4a8 量化版本):需要 1 台 Atlas 800 A3(64G × 16)节点或 2 台 Atlas 800 A2(64G × 8)节点。下载模型权重。kimi-k2.5-eagle3(用于加速 Kimi-K2.5 推理的 Eagle3 MTP 草稿模型):下载模型权重
建议将模型权重下载到多节点共享目录,例如 /root/.cache/。
3.2 验证多节点通信(可选)¶
如果要部署多节点环境,需要按照验证多节点通信环境验证多节点通信。
4.安装¶
4.1 Docker 镜像安装¶
根据您的机器类型选择镜像,并在节点上启动 Docker 镜像,请参考使用 Docker 安装。
在每个节点上启动 Docker 镜像。
export IMAGE=quay.io/ascend/vllm-ascend:v0.22.1rc1-a3
docker run --rm \
--name vllm-ascend \
--shm-size=1g \
--net=host \
--privileged=true \
--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
Start the docker image on your each node.
export IMAGE=quay.io/ascend/vllm-ascend:v0.22.1rc1
docker run --rm \
--name vllm-ascend \
--shm-size=1g \
--net=host \
--privileged=true \
--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
After a successful docker run, you can verify the running container service by executing the docker ps command.
4.2 Source Code Installation¶
If you don't want to use the docker image as above, you can also build all from source:
- Install
vllm-ascendfrom source, refer to installation.
If you want to deploy multi-node environment, you need to set up environment on each node.
5 Online Service Deployment¶
5.1 Single-Node Online Deployment¶
Single-node deployment completes both Prefill and Decode within the same node. The quantized model Kimi-K2.5-w4a8 可以部署在 1 台 Atlas 800 A3(64G × 16)上。
运行以下脚本执行在线推理。
启动命令:
#!/bin/sh
# [Optional] jemalloc
# jemalloc is for better performance, if `libjemalloc.so` is installed on your machine, you can turn it on.
export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2:$LD_PRELOAD
echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
sysctl -w vm.swappiness=0
sysctl -w kernel.numa_balancing=0
sysctl -w kernel.sched_migration_cost_ns=50000
export HCCL_OP_EXPANSION_MODE="AIV"
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export OMP_PROC_BIND=false
export OMP_NUM_THREADS=1
export TASK_QUEUE_ENABLE=1
export HCCL_BUFFSIZE=800
export VLLM_ASCEND_ENABLE_MLAPO=1
export VLLM_ASCEND_ENABLE_FLASHCOMM1=1
export VLLM_ASCEND_BALANCE_SCHEDULING=1
vllm serve Eco-Tech/Kimi-K2.5-W4A8 \
--host 0.0.0.0 \
--port 8088 \
--quantization ascend \
--served-model-name kimi_k25 \
--allowed-local-media-path / \
--trust-remote-code \
--no-enable-prefix-caching \
--seed 1024 \
--tensor-parallel-size 4 \
--data-parallel-size 4 \
--enable-expert-parallel \
--max-num-seqs 64 \
--max-model-len 32768 \
--max-num-batched-tokens 16384 \
--gpu-memory-utilization 0.9 \
--compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' \
--speculative-config '{"method":"eagle3", "model":"lightseekorg/kimi-k2.5-eagle3", "num_speculative_tokens":3}' \
--mm-encoder-tp-mode data
关键参数说明:
- 设置环境变量
VLLM_ASCEND_BALANCE_SCHEDULING=1可启用均衡调度。这有助于提高 v1 调度器的输出吞吐量并降低 TPOT。但在某些场景下 TTFT 可能会下降。此外,不建议在 PD 分离场景下启用此特性。 - 对于单节点部署,建议使用
dp4 tp4而不是dp2 tp8。 --max-model-len指定最大上下文长度,即单个请求的输入 token 和输出 token 之和。对于输入长度 3.5K、输出长度 1.5K 的性能测试,16384的值已经足够;但对于精度测试,请至少设置为35000。--no-enable-prefix-caching表示禁用前缀缓存。要启用前缀缓存,请移除该选项。--mm-encoder-tp-mode表示如何使用张量并行(TP)优化多模态编码器推理。如果要测试多模态输入,我们推荐使用data。- 如果使用 w4a8 权重,更多内存将分配给 kvcache,您可以尝试增加系统吞吐量以获得更高的吞吐性能。
Common Issues Tip: If you encounter issues, please refer to the Public FAQ for troubleshooting.
服务验证:
curl http://<node_ip>:8088/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "kimi_k25",
"messages": [{
"role": "user",
"content": [
{
"type": "text",
"text": "The future of AI is"
}]
}],
"max_tokens": 1024,
"temperature": 1.0,
"top_p": 0.95
}'
预期结果:
服务返回 HTTP 200 OK,JSON 响应中包含 choices 字段。示例输出:
{
"id": "chatcmpl-xxxxxxxxxxxxx",
"object": "chat.completion",
"model": "kimi_k25",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "The future of AI is not a destination we are passively approaching...",
"finish_reason": "length"
}
}
],
"usage": {
"prompt_tokens": 13,
"total_tokens": 1037,
"completion_tokens": 1024
}
}
5.2 多节点数据并行部署¶
Kimi-K2.5-w4a8 可以使用数据并行部署在多个节点上。此部署模式至少需要 2 台 Atlas 800 A2(64G × 8)节点。
分别在两个节点上运行以下脚本。
节点 0
启动命令:
#!/bin/sh
# this obtained through ifconfig
# nic_name is the network interface name corresponding to local_ip of the current node
nic_name="xxxx"
local_ip="141.xx.xx.1"
# The value of node0_ip must be consistent with the value of local_ip set in node0 (master node)
node0_ip="xxxx"
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 HCCL_INTRA_PCIE_ENABLE=1
export HCCL_INTRA_ROCE_ENABLE=0
# [Optional] jemalloc
# jemalloc is for better performance, if `libjemalloc.so` is installed on your machine, you can turn it on.
export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2:$LD_PRELOAD
echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
sysctl -w vm.swappiness=0
sysctl -w kernel.numa_balancing=0
sysctl -w kernel.sched_migration_cost_ns=50000
export HCCL_OP_EXPANSION_MODE="AIV"
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export OMP_PROC_BIND=false
export OMP_NUM_THREADS=1
export TASK_QUEUE_ENABLE=1
export HCCL_BUFFSIZE=1024
export VLLM_ASCEND_ENABLE_MLAPO=1
export VLLM_ASCEND_ENABLE_FLASHCOMM1=1
export VLLM_ASCEND_BALANCE_SCHEDULING=1
vllm serve Eco-Tech/Kimi-K2.5-W4A8 \
--host 0.0.0.0 \
--port 8088 \
--quantization ascend \
--served-model-name kimi_k25 \
--allowed-local-media-path / \
--trust-remote-code \
--no-enable-prefix-caching \
--seed 1024 \
--data-parallel-size 4 \
--data-parallel-size-local 2 \
--data-parallel-address $node0_ip \
--data-parallel-rpc-port 13389 \
--tensor-parallel-size 4 \
--enable-expert-parallel \
--max-num-seqs 16 \
--max-model-len 32768 \
--max-num-batched-tokens 16384 \
--gpu-memory-utilization 0.9 \
--compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' \
--speculative-config '{"method":"eagle3", "model":"lightseekorg/kimi-k2.5-eagle3", "num_speculative_tokens":3}' \
--mm-encoder-tp-mode data
节点 1
启动命令:
#!/bin/sh
# this obtained through ifconfig
# nic_name is the network interface name corresponding to local_ip of the current node
nic_name="xxx"
local_ip="141.xx.xx.2"
# The value of node0_ip must be consistent with the value of local_ip set in node0 (master node)
node0_ip="xxxx"
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 HCCL_INTRA_PCIE_ENABLE=1
export HCCL_INTRA_ROCE_ENABLE=0
# [Optional] jemalloc
# jemalloc is for better performance, if `libjemalloc.so` is installed on your machine, you can turn it on.
export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2:$LD_PRELOAD
echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
sysctl -w vm.swappiness=0
sysctl -w kernel.numa_balancing=0
sysctl -w kernel.sched_migration_cost_ns=50000
export HCCL_OP_EXPANSION_MODE="AIV"
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export OMP_PROC_BIND=false
export OMP_NUM_THREADS=1
export TASK_QUEUE_ENABLE=1
export HCCL_BUFFSIZE=1024
export VLLM_ASCEND_ENABLE_MLAPO=1
export VLLM_ASCEND_ENABLE_FLASHCOMM1=1
export VLLM_ASCEND_BALANCE_SCHEDULING=1
vllm serve Eco-Tech/Kimi-K2.5-W4A8 \
--host 0.0.0.0 \
--port 8088 \
--quantization ascend \
--served-model-name kimi_k25 \
--allowed-local-media-path / \
--trust-remote-code \
--no-enable-prefix-caching \
--seed 1024 \
--headless \
--data-parallel-size 4 \
--data-parallel-size-local 2 \
--data-parallel-start-rank 2 \
--data-parallel-address $node0_ip \
--data-parallel-rpc-port 13389 \
--tensor-parallel-size 4 \
--enable-expert-parallel \
--max-num-seqs 16 \
--max-model-len 32768 \
--max-num-batched-tokens 16384 \
--gpu-memory-utilization 0.9 \
--compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' \
--speculative-config '{"method":"eagle3", "model":"lightseekorg/kimi-k2.5-eagle3", "num_speculative_tokens":3}' \
--mm-encoder-tp-mode data
关键参数说明:
--data-parallel-size:所有节点上的数据并行 rank 总数。在本示例中,4表示模型分布在总共 4 个 DP rank 上(每个节点 2 个)。--data-parallel-size-local:当前节点上运行的数据并行 rank 数量。在本示例中,每个节点运行 2 个 DP rank。--data-parallel-start-rank:此节点上数据并行 rank 的起始偏移量。节点 0 从 rank 0 开始(默认),节点 1 从 rank 2 开始。这确保每个节点的 DP rank 在整体 rank 空间中占据不同的位置。--data-parallel-address:数据并行主节点(节点 0)的 IP 地址。此值必须与节点 0 上设置的local_ip一致。--data-parallel-rpc-port:数据并行主节点通信的 RPC 端口。所有节点上的值必须相同。--headless:表示此 vLLM 实例不是主服务节点。仅在非主节点(节点 1)上设置。主节点(节点 0)不应设置此标志。- 对于单节点部署,建议使用
dp4 tp4而不是dp2 tp8。
Common Issues Tip: If you encounter issues, please refer to the Public FAQ for troubleshooting.
服务验证:
curl http://<node0_ip>:8088/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "kimi_k25",
"messages": [{
"role": "user",
"content": [
{
"type": "text",
"text": "The future of AI is"
}]
}],
"max_tokens": 1024,
"temperature": 1.0,
"top_p": 0.95
}'
预期结果:
服务返回 HTTP 200 OK。JSON 响应中包含 choices 字段,其中包含生成的文本。
5.3 多节点 PD 分离部署¶
我们推荐使用 Mooncake 进行部署:Mooncake。
在标准单节点部署模式下,预填充(提示处理)和解码(令牌生成)任务在同一组 NPU 上运行。PD(预填充-解码)分离通过将预填充和解码运行在专用节点组上来解决此问题,每个节点组独立配置:
- **预填充节点**专注于高吞吐量提示处理,针对计算和通信进行了优化(例如,启用 FlashComm 以加速 Allreduce)。
- **解码节点**专注于低延迟令牌生成,针对内存带宽进行了优化(例如,启用 MLAPO 融合算子)。
此架构推荐用于具有并发多用户工作负载的生产部署,其中需要稳定的延迟和高吞吐量。
以 Atlas 800 A3(64G × 16)为例,我们建议部署 2P1D(4 节点)而不是 1P1D(2 节点),因为在 1P1D 情况下没有足够的 NPU 内存来支持高并发。
Kimi-K2.5-w4a8 2P1D需要 4 台 Atlas 800 A3(64G × 16)节点。
要运行 vllm-ascend 的 Prefill-Decode Disaggregation 服务,您需要在每个节点上部署 launch_online_dp.py 脚本和 run_dp_template.sh 脚本,并在预填充主节点上部署 proxy.sh 脚本以转发请求。
-
launch_online_dp.pyto launch external dp vllm servers. launch_online_dp.py参数说明:
参数 类型 必填 默认值 描述 --dp-sizeint 是 - 数据并行大小(所有节点上的 DP 排名总数)。 --tp-sizeint 否 1 每个 DP 排名内的张量并行大小。 --dp-size-localint 否 (与 --dp-size相同)当前节点上的 DP 排名数量。如果未设置,默认为 --dp-size。--dp-rank-startint 否 0 此节点上数据并行排名的起始排名偏移量。 --dp-addressstr 是 - 数据并行主节点(节点 0)的 IP 地址。 --dp-rpc-portstr 否 12345 数据并行主节点通信的 RPC 端口。 --vllm-start-portint 否 9000 此节点上每个 vLLM 引擎实例的起始端口。每个 DP 排名的引擎端口 = vllm_start_port+ 本地排名索引。 -
预填充节点 0 的
run_dp_template.sh脚本# this obtained through ifconfig # nic_name is the network interface name corresponding to local_ip of the current node nic_name="xxx" local_ip="141.xx.xx.1" # The value of node0_ip must be consistent with the value of local_ip set in node0 (master node) node0_ip="xxxx" export HCCL_IF_IP=$local_ip export GLOO_SOCKET_IFNAME=$nic_name export TP_SOCKET_IFNAME=$nic_name export HCCL_SOCKET_IFNAME=$nic_name # [Optional] jemalloc # jemalloc is for better performance, if `libjemalloc.so` is installed on your machine, you can turn it on. export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2:$LD_PRELOAD echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor sysctl -w vm.swappiness=0 sysctl -w kernel.numa_balancing=0 sysctl kernel.sched_migration_cost_ns=50000 export VLLM_RPC_TIMEOUT=3600000 export VLLM_EXECUTE_MODEL_TIMEOUT_SECONDS=30000 export HCCL_OP_EXPANSION_MODE="AIV" export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True export OMP_PROC_BIND=false export OMP_NUM_THREADS=1 export TASK_QUEUE_ENABLE=1 export ASCEND_BUFFER_POOL=4:8 export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/latest/python/site-packages/mooncake:$LD_LIBRARY_PATH export HCCL_BUFFSIZE=256 export VLLM_ASCEND_ENABLE_FLASHCOMM1=1 export ASCEND_RT_VISIBLE_DEVICES=$1 vllm serve Eco-Tech/Kimi-K2.5-W4A8 \ --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 \ --quantization ascend \ --served-model-name kimi_k25 \ --trust-remote-code \ --max-num-seqs 8 \ --max-model-len 32768 \ --max-num-batched-tokens 16384 \ --no-enable-prefix-caching \ --gpu-memory-utilization 0.8 \ --enforce-eager \ --speculative-config '{"method": "eagle3", "model":"lightseekorg/kimi-k2.5-eagle3", "num_speculative_tokens": 3}' \ --mm-encoder-tp-mode data \ --kv-transfer-config \ '{"kv_connector": "MooncakeConnectorV1", "kv_role": "kv_producer", "kv_port": "30000", "engine_id": "0", "kv_connector_extra_config": { "prefill": { "dp_size": 2, "tp_size": 8 }, "decode": { "dp_size": 32, "tp_size": 1 } } }' -
Prefill Node 1
run_dp_template.shscript# this obtained through ifconfig # nic_name is the network interface name corresponding to local_ip of the current node nic_name="xxx" local_ip="141.xx.xx.2" # The value of node0_ip must be consistent with the value of local_ip set in node0 (master node) node0_ip="xxxx" export HCCL_IF_IP=$local_ip export GLOO_SOCKET_IFNAME=$nic_name export TP_SOCKET_IFNAME=$nic_name export HCCL_SOCKET_IFNAME=$nic_name # [Optional] jemalloc # jemalloc is for better performance, if `libjemalloc.so` is installed on your machine, you can turn it on. export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2:$LD_PRELOAD echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor sysctl -w vm.swappiness=0 sysctl -w kernel.numa_balancing=0 sysctl kernel.sched_migration_cost_ns=50000 export VLLM_RPC_TIMEOUT=3600000 export VLLM_EXECUTE_MODEL_TIMEOUT_SECONDS=30000 export HCCL_OP_EXPANSION_MODE="AIV" export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True export OMP_PROC_BIND=false export OMP_NUM_THREADS=1 export TASK_QUEUE_ENABLE=1 export ASCEND_BUFFER_POOL=4:8 export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/latest/python/site-packages/mooncake:$LD_LIBRARY_PATH export HCCL_BUFFSIZE=256 export VLLM_ASCEND_ENABLE_FLASHCOMM1=1 export ASCEND_RT_VISIBLE_DEVICES=$1 vllm serve Eco-Tech/Kimi-K2.5-W4A8 \ --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 \ --quantization ascend \ --served-model-name kimi_k25 \ --trust-remote-code \ --max-num-seqs 8 \ --max-model-len 32768 \ --max-num-batched-tokens 16384 \ --no-enable-prefix-caching \ --gpu-memory-utilization 0.8 \ --enforce-eager \ --speculative-config '{"method": "eagle3", "model":"lightseekorg/kimi-k2.5-eagle3", "num_speculative_tokens": 3}' \ --mm-encoder-tp-mode data \ --kv-transfer-config \ '{"kv_connector": "MooncakeConnectorV1", "kv_role": "kv_producer", "kv_port": "30100", "engine_id": "1", "kv_connector_extra_config": { "prefill": { "dp_size": 2, "tp_size": 8 }, "decode": { "dp_size": 32, "tp_size": 1 } } }' -
Decode Node 0
run_dp_template.shscript# this obtained through ifconfig # nic_name is the network interface name corresponding to local_ip of the current node nic_name="xxx" local_ip="141.xx.xx.3" # The value of node0_ip must be consistent with the value of local_ip set in node0 (master node) node0_ip="xxxx" export HCCL_IF_IP=$local_ip export GLOO_SOCKET_IFNAME=$nic_name export TP_SOCKET_IFNAME=$nic_name export HCCL_SOCKET_IFNAME=$nic_name # [Optional] jemalloc # jemalloc is for better performance, if `libjemalloc.so` is installed on your machine, you can turn it on. export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2:$LD_PRELOAD echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor sysctl -w vm.swappiness=0 sysctl -w kernel.numa_balancing=0 sysctl kernel.sched_migration_cost_ns=50000 export VLLM_RPC_TIMEOUT=3600000 export VLLM_EXECUTE_MODEL_TIMEOUT_SECONDS=30000 export HCCL_OP_EXPANSION_MODE="AIV" export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True export OMP_PROC_BIND=false export OMP_NUM_THREADS=1 export TASK_QUEUE_ENABLE=1 export ASCEND_BUFFER_POOL=4:8 export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/latest/python/site-packages/mooncake:$LD_LIBRARY_PATH export HCCL_BUFFSIZE=1100 export VLLM_ASCEND_ENABLE_MLAPO=1 export ASCEND_RT_VISIBLE_DEVICES=$1 vllm serve Eco-Tech/Kimi-K2.5-W4A8 \ --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 \ --quantization ascend \ --served-model-name kimi_k25 \ --trust-remote-code \ --max-num-seqs 48 \ --max-model-len 32768 \ --max-num-batched-tokens 256 \ --no-enable-prefix-caching \ --gpu-memory-utilization 0.95 \ --compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' \ --additional-config '{"recompute_scheduler_enable":true,"multistream_overlap_shared_expert": false}' \ --speculative-config '{"method": "eagle3", "model":"lightseekorg/kimi-k2.5-eagle3", "num_speculative_tokens": 3}' \ --kv-transfer-config \ '{"kv_connector": "MooncakeConnectorV1", "kv_role": "kv_consumer", "kv_port": "30200", "engine_id": "2", "kv_connector_extra_config": { "prefill": { "dp_size": 2, "tp_size": 8 }, "decode": { "dp_size": 32, "tp_size": 1 } } }' -
Decode Node 1
run_dp_template.shscript# this obtained through ifconfig # nic_name is the network interface name corresponding to local_ip of the current node nic_name="xxx" local_ip="141.xx.xx.4" # The value of node0_ip must be consistent with the value of local_ip set in node0 (master node) node0_ip="xxxx" export HCCL_IF_IP=$local_ip export GLOO_SOCKET_IFNAME=$nic_name export TP_SOCKET_IFNAME=$nic_name export HCCL_SOCKET_IFNAME=$nic_name # [Optional] jemalloc # jemalloc is for better performance, if `libjemalloc.so` is installed on your machine, you can turn it on. export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2:$LD_PRELOAD echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor sysctl -w vm.swappiness=0 sysctl -w kernel.numa_balancing=0 sysctl kernel.sched_migration_cost_ns=50000 export VLLM_RPC_TIMEOUT=3600000 export VLLM_EXECUTE_MODEL_TIMEOUT_SECONDS=30000 export HCCL_OP_EXPANSION_MODE="AIV" export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True export OMP_PROC_BIND=false export OMP_NUM_THREADS=1 export TASK_QUEUE_ENABLE=1 export ASCEND_BUFFER_POOL=4:8 export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/latest/python/site-packages/mooncake:$LD_LIBRARY_PATH export HCCL_BUFFSIZE=1100 export VLLM_ASCEND_ENABLE_MLAPO=1 export ASCEND_RT_VISIBLE_DEVICES=$1 vllm serve Eco-Tech/Kimi-K2.5-W4A8 \ --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 \ --quantization ascend \ --served-model-name kimi_k25 \ --trust-remote-code \ --max-num-seqs 48 \ --max-model-len 32768 \ --max-num-batched-tokens 256 \ --no-enable-prefix-caching \ --gpu-memory-utilization 0.95 \ --compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' \ --additional-config '{"recompute_scheduler_enable":true,"multistream_overlap_shared_expert": false}' \ --speculative-config '{"method": "eagle3", "model":"lightseekorg/kimi-k2.5-eagle3", "num_speculative_tokens": 3}' \ --kv-transfer-config \ '{"kv_connector": "MooncakeConnectorV1", "kv_role": "kv_consumer", "kv_port": "30200", "engine_id": "2", "kv_connector_extra_config": { "prefill": { "dp_size": 2, "tp_size": 8 }, "decode": { "dp_size": 32, "tp_size": 1 } } }'
Key Parameter Descriptions:
VLLM_ASCEND_ENABLE_FLASHCOMM1=1: enables the communication optimization function on the prefill nodes.VLLM_ASCEND_ENABLE_MLAPO=1: enables the fusion operator, which can significantly improve performance but consumes more NPU memory. In the Prefill-Decode (PD) separation scenario, enable MLAPO only on decode nodes.recompute_scheduler_enable: true: enables the recomputation scheduler. When the Key-Value Cache (KV Cache) of the decode node is insufficient, requests will be sent to the prefill node to recompute the KV Cache. In the PD separation scenario, enable this configuration only on decode nodes.multistream_overlap_shared_expert: true: When the Tensor Parallelism (TP) size is 1 orenable_shared_expert_dp: true, an additional stream is enabled to overlap the computation process of shared experts for improved efficiency.
The run_dp_template.sh scripts use positional parameters ($1-$7) to receive configuration values from launch_online_dp.py:
$1(ASCEND_RT_VISIBLE_DEVICES): the NPU devices assigned to this DP instance, e.g.,0,1,2,3or4,5,6,7.$2(--port): the vLLM server port for this DP instance, auto-assigned starting from--vllm-start-port(e.g.,7100,7101).$3(--data-parallel-size): total number of DP ranks.$4(--data-parallel-rank): the rank index of this DP instance.$5(--data-parallel-address): IP address of the DP master node.$6(--data-parallel-rpc-port): RPC port for DP master communication.-
$7(--tensor-parallel-size): TP size within each DP rank. -
Run server for each node:
# p0 python launch_online_dp.py --dp-size 2 --tp-size 8 --dp-size-local 2 --dp-rank-start 0 --dp-address 141.xx.xx.1 --dp-rpc-port 12321 --vllm-start-port 7100 # p1 python launch_online_dp.py --dp-size 2 --tp-size 8 --dp-size-local 2 --dp-rank-start 0 --dp-address 141.xx.xx.2 --dp-rpc-port 12321 --vllm-start-port 7100 # d0 python launch_online_dp.py --dp-size 32 --tp-size 1 --dp-size-local 16 --dp-rank-start 0 --dp-address 141.xx.xx.3 --dp-rpc-port 12321 --vllm-start-port 7100 # d1 python launch_online_dp.py --dp-size 32 --tp-size 1 --dp-size-local 16 --dp-rank-start 16 --dp-address 141.xx.xx.3 --dp-rpc-port 12321 --vllm-start-port 7100 -
Run the
proxy.shscript on the prefill master nodeRun a proxy server on the same node with the prefiller service instance. You can get the proxy program in the repository's examples: load_balance_proxy_server_example.py
python load_balance_proxy_server_example.py \ --port 1999 \ --host 141.xx.xx.1 \ --prefiller-hosts \ 141.xx.xx.1 \ 141.xx.xx.1 \ 141.xx.xx.2 \ 141.xx.xx.2 \ --prefiller-ports \ 7100 7101 7100 7101 \ --decoder-hosts \ 141.xx.xx.3 \ 141.xx.xx.3 \ 141.xx.xx.3 \ 141.xx.xx.3 \ 141.xx.xx.3 \ 141.xx.xx.3 \ 141.xx.xx.3 \ 141.xx.xx.3 \ 141.xx.xx.3 \ 141.xx.xx.3 \ 141.xx.xx.3 \ 141.xx.xx.3 \ 141.xx.xx.3 \ 141.xx.xx.3 \ 141.xx.xx.3 \ 141.xx.xx.3 \ 141.xx.xx.4 \ 141.xx.xx.4 \ 141.xx.xx.4 \ 141.xx.xx.4 \ 141.xx.xx.4 \ 141.xx.xx.4 \ 141.xx.xx.4 \ 141.xx.xx.4 \ 141.xx.xx.4 \ 141.xx.xx.4 \ 141.xx.xx.4 \ 141.xx.xx.4 \ 141.xx.xx.4 \ 141.xx.xx.4 \ 141.xx.xx.4 \ 141.xx.xx.4 \ --decoder-ports \ 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 \ 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 \
部署验证:
PD 分离服务完全启动后,通过预填充主节点上的代理端口发送请求,以验证预填充节点和解码节点是否协同工作正常:
curl http://141.xx.xx.1:1999/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "kimi_k25",
"messages": [{
"role": "user",
"content": [
{
"type": "text",
"text": "The future of AI is"
}]
}],
"max_tokens": 1024,
"temperature": 1.0,
"top_p": 0.95
}'
预期结果:
代理返回 HTTP 200 OK。JSON 响应中包含 choices 字段,其中包含生成的文本,确认预填充节点已成功处理提示,解码节点已生成响应:
{
"id": "chatcmpl-xxxxxxxxxxxxx",
"object": "chat.completion",
"model": "kimi_k25",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "The future of AI is not a destination we are passively approaching...",
"finish_reason": "length"
}
}
],
"usage": {
"prompt_tokens": 13,
"total_tokens": 1037,
"completion_tokens": 1024
}
}
Common Issues Tip: If you encounter issues with PD separation deployment, please refer to the Public FAQ for troubleshooting.
6 功能验证¶
服务器启动后,您可以使用输入提示词查询模型:
curl http://<node0_ip>:8088/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "kimi_k25",
"messages": [{
"role": "user",
"content": [
{
"type": "text",
"text": "The future of AI is"
}]
}],
"max_tokens": 1024,
"temperature": 1.0,
"top_p": 0.95
}'
预期结果:
服务返回 HTTP 200 OK。JSON 响应包含 choices 字段,其中包含生成的文本以及使用统计信息:
{
"id": "chatcmpl-xxxxxxxxxxxxx",
"object": "chat.completion",
"model": "kimi_k25",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "The future of AI is not a destination we are passively approaching...",
"finish_reason": "length"
}
}
],
"usage": {
"prompt_tokens": 13,
"total_tokens": 1037,
"completion_tokens": 1024
}
}
7 精度评估¶
以下是一种精度评估方法。
使用 AISBench¶
-
详细信息请参考使用 AISBench 进行精度评估。
-
执行后即可获得结果,以下是
Kimi-K2.5-w4a8在vllm-ascend:v0.17.0rc1上的结果,仅供参考。
| 数据集 | 版本 | 指标 | 模式 | vllm-api-生成eral-chat | 备注 |
|---|---|---|---|---|---|
| GSM8K | - | 准确率 | 生成 | 96.07 | 1 台 Atlas 800 A3(64G × 16) |
| AIME2025 | - | 准确率 | 生成 | 90.00 | 1 台 Atlas 800 A3(64G × 16) |
| GPQA | - | 准确率 | 生成 | 84.85 | 1 台 Atlas 800 A3(64G × 16) |
| TextVQA | - | 准确率 | 生成 | 80.29 | 1 台 Atlas 800 A3(64G × 16) |
8 性能评估¶
使用 AISBench¶
详细信息请参考使用 AISBench 进行性能评估。
使用 vLLM 基准测试¶
以 Kimi-K2.5-w4a8 为例运行性能评估。
更多详细信息请参考 vLLM 基准测试。
有三个 vllm bench 子命令:
latency:基准测试单批次请求的延迟。serve:基准测试在线服务的吞吐量。throughput:基准测试离线推理的吞吐量。
以 serve 为例,运行如下代码。
vllm bench serve --model Eco-Tech/Kimi-K2.5-w4a8 --dataset-name random --random-input 1024 --num-prompts 200 --request-rate 1 --save-result --result-dir ./
大约几分钟后,即可获得性能评估结果。
9 性能调优¶
9.1 推荐配置¶
注意:以下配置在特定测试环境中验证,仅供参考。最佳配置取决于最大输入/输出长度、前缀缓存命中率、精度要求和部署机器比例等因素。建议根据实际情况参考第 9.2 节进行调整。
表 1:场景概览¶
*Total NPUs表示所有节点使用的 NPU 总数。1 节点 = 1 台 Atlas 800 A3 服务器(64G × 16 NPU)。
| 场景 | 部署模式 | *总 NPU 数 | 权重版本 | 关键考量 |
|---|---|---|---|---|
| 高吞吐量/低延迟 (16K 上下文) |
单节点混合 | 16(A3) | kimi-k2.5-w4a8 | 使用 dp4 tp4 以获得最佳吞吐量和低延迟 |
| 高吞吐量/低延迟 (16K 上下文) |
2 节点数据并行 | 16(A2) | kimi-k2.5-w4a8 | 跨 2 节点的 dp4 tp4;平衡延迟和吞吐量 |
| 高吞吐量/低延迟 (16K 上下文) |
2P2D 部署 | 64(A3) | kimi-k2.5-w4a8 | 预填充:dp2 tp8;解码:dp32 tp1 以实现高并发 |
| 长上下文 (128K,低并发 ≤4) |
单节点混合 | 16(A3) | kimi-k2.5-w4a8 | dp1 tp16 以最大化 TP,适应极端上下文长度 |
| 长上下文 (128K,高并发 >4) |
单节点混合 | 16(A3) | kimi-k2.5-w4a8 | dp2 tp8 以优化内存带宽并支持更高并发 |
表 2:详细节点配置¶
| 场景 | 配置 | NPU 数 | TP | DP | 最大模型长度 | MTP 推测数 |
|---|---|---|---|---|---|---|
| 高吞吐量/低延迟(16K) | 服务器/单机 | 16 | 4 | 4 | ~16K | 3 |
| 高吞吐量/低延迟(16K) | 服务器/2 节点 DP | 8 | 4 | 2 | ~16K | 3 |
| 高吞吐量/低延迟(16K) | Server-P 节点 | 16 | 8 | 2 | ~16K | 3 |
| 高吞吐量/低延迟(16K) | Server-D 节点 | 16 | 1 | 32 | ~16K | 3 |
| 长上下文(128K,低并发 ≤4) | 服务器/单机 | 16 | 16 | 1 | 128K | 3 |
| 长上下文(128K,高并发 >4) | 服务器/单机 | 16 | 8 | 2 | 128K | 3 |
完整的启动命令和参数描述,请参考第 5 章中的部署示例。
否tice:
max-model-len and max-num-seqs need to be set according to the actual usage scenario. For other settings, please refer to the Deployment chapter.
9.2 调优指南¶
请参考公共性能调优文档了解调优方法。
请参考特性指南获取详细的特性描述。
10 常见问题¶
For common environment, installation, and 生成eral parameter issues, please refer to the Public FAQ; this chapter only covers 模式l-specific issues.
- 问:单节点部署时推荐的 TP/DP 配置是什么?
答:对于单节点部署,建议使用 dp4 tp4 而不是 dp2 tp8。