预填充-解码分离(DeepSeek)¶
快速开始¶
vLLM-Ascend now supports prefill-decode (PD) disaggregation with EP (Expert Parallelism) options. This guide takes one-by-one steps to verify these features with constrained resources.
以DeepSeek-r1-w8a8模型为例,使用4台Atlas 800T A3服务器部署"2P1D"架构。假设预填充服务器IP为192.0.0.1(prefill 1)和192.0.0.2(prefill 2),解码服务器为192.0.0.3(decoder 1)和192.0.0.4(decoder 2)。每台服务器使用8个NPU和16个芯片部署一个服务实例。
验证多节点通信环境¶
物理层要求¶
- 物理机必须位于同一局域网内,且网络互通。
- 所有 NPU 必须互联。在 A2/A3 上,节点内通过 HCCS 互联,节点间通过 RDMA 互联。对于 Atlas 850/850E/950 SuperPod(950PR/950DT),请参见 Atlas 850/850E/950 SuperPod 通信配置。
验证流程¶
以下检查适用于 A2/A3 部署。
在每个节点上依次执行以下命令。结果必须全部为 success,状态必须为 UP:
-
单节点验证:
在每个节点上依次执行以下命令。结果必须全部为
success,状态必须为UP:# Check the remote switch ports for i in {0..15}; do hccn_tool -i $i -lldp -g | grep Ifname; done # Get the link status of the Ethernet ports (UP or DOWN) for i in {0..15}; do hccn_tool -i $i -link -g ; done # Check the network health status for i in {0..15}; do hccn_tool -i $i -net_health -g ; done # View the network detected IP configuration for i in {0..15}; do hccn_tool -i $i -netdetect -g ; done # View gateway configuration for i in {0..15}; do hccn_tool -i $i -gateway -g ; done -
检查 NPU HCCN 配置:
确保环境中存在 hccn.conf 文件。如果使用 Docker,请将其挂载到容器中。
-
获取 NPU IP 地址
-
获取 superpodid 和 SDID
-
跨节点 PING 测试
-
检查 NPU TLS 配置
-
单节点验证:
在每个节点上依次执行以下命令。结果必须全部为
success,状态必须为UP:# Check the remote switch ports for i in {0..7}; do hccn_tool -i $i -lldp -g | grep Ifname; done # Get the link status of the Ethernet ports (UP or DOWN) for i in {0..7}; do hccn_tool -i $i -link -g ; done # Check the network health status for i in {0..7}; do hccn_tool -i $i -net_health -g ; done # View the network detected IP configuration for i in {0..7}; do hccn_tool -i $i -netdetect -g ; done # View gateway configuration for i in {0..7}; do hccn_tool -i $i -gateway -g ; done -
检查 NPU HCCN 配置:
确保环境中存在 hccn.conf 文件。如果使用 Docker,请将其挂载到容器中。
-
获取 NPU IP 地址
-
跨节点 PING 测试
-
检查 NPU TLS 配置
Atlas 850/850E/950 SuperPod 通信配置¶
For Atlas 850/850E/950 SuperPod (950PR/950DT), PD disaggregation uses the super plane (based on UB port and UBC protocol) by default. No additional network configuration is required for this default path.
Automatic UB configuration requires HIXL 9.1.0 or later. Upgrade HIXL before using the configuration below. Set the following environment variable in both the prefiller and decoder serving environments to generate the communication configuration automatically:
参数面支持 UBG、UBoE 和 RoCE 网络协议。每种协议都需要提前完成兼容的硬件和网络配置。请咨询您的环境提供商或管理员,以获取所需的环境和配置。
对于 UBG 或 UBoE 网络协议,保留上述自动配置设置,并在启动服务进程前选择相应的协议:
Host RoCE parameter-plane configuration for Atlas 850/850E/950 SuperPod (950PR/950DT) currently requires manual endpoint files and checking the mapping between physical NPUs and host RoCE IP addresses. Prepare the endpoint configuration files under /etc/hixlep and set ascend_local_comm_res_path in kv_connector_extra_config on both sides. The directory is configurable; /etc/hixlep is only an example. For example, with DP=4 and TP=1 on each side:
{
"kv_connector_extra_config": {
"prefill": {
"dp_size": 4,
"tp_size": 1
},
"decode": {
"dp_size": 4,
"tp_size": 1
},
"ascend_local_comm_res_path": "/etc/hixlep"
}
}
将这些字段合并到您现有的 --kv-transfer-config 中,并根据您的部署调整并行度设置。
当通过 MultiConnector 将 PD 分离与 KV 池化结合使用时,请将 ascend_local_comm_res_path 放在外层 MultiConnector 的 kv_connector_extra_config 中,与 connectors 列表并列。不要将其放在子连接器的 kv_connector_extra_config 中:worker 会从外层 KV 传输配置中加载端点文件。请将 prefill 和 decode 并行度设置保留在 Mooncake P/D 子连接器的配置中。
Create an endpoint file for each physical NPU used on the host, named /etc/hixlep/ub_endpoint_npu_<physical_npu_id>.json. The suffix is the host physical NPU ID, not the DP rank or the ordinal within the visible devices.
Check the host's NPU-to-RoCE-IP mapping before filling in these files. For a host whose RoCE IP addresses correspond to physical NPU IDs in ascending order, populate ub_endpoint_npu_0.json, ub_endpoint_npu_1.json, and so on in that order. RoCE IPs can be populated in ascending numerical order, after verifying the actual host mapping. Each file's comm_id must match the RoCE IP associated with that physical NPU; do not use the DP rank or visible-device order to select the address. The JSON content of each endpoint file follows this format:
{
"version": "1.3",
"net_instance_id": "superpod_0",
"endpoint_list": [
{
"protocol": "roce",
"comm_id": "<host_roce_ip>",
"placement": "host"
}
]
}
将 <host_roce_ip> 替换为实际的主机 RoCE IP 地址。确保端点文件在每个容器内的配置路径下可用。
Simplified Host RoCE configuration is NOT YET SUPPORTED
A future configuration is intended to select Host RoCE with only the following environment variable:
# NOT YET SUPPORTED: do not use this in current deployments.
export ASCEND_GLOBAL_RESOURCE_CONFIG='{"comm_resource_config.protocol_desc":"roce:host"}'
This configuration is not yet supported and does not replace the manual endpoint files above. Continue to configure the per-NPU endpoint files and ascend_local_comm_res_path for current deployments.
使用 Docker 运行¶
在每个节点上启动一个 Docker 容器。 The following example maps the 16 device nodes used by the A3 deployment above. For Atlas 850/850E/950 SuperPod (950PR/950DT), use the complete container command below.
# Update the vllm-ascend image
export IMAGE=m.daocloud.io/quay.io/ascend/vllm-ascend:v0.23.0
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 /etc/hccn.conf:/etc/hccn.conf \
-v /mnt/sfs_turbo/.cache:/root/.cache \
-it $IMAGE bash
Atlas 850/850E/950 SuperPod(950PR/950DT)容器要求¶
For an eight-device 950PR/950DT host, use the following command. Choose an image compatible with the host driver; for openEuler, use the v0.23.0-a5-openeuler tag.
export IMAGE=quay.io/ascend/vllm-ascend:v0.23.0-a5
export NAME=vllm-ascend-950
docker run --rm \
--name "$NAME" \
--net=host \
--privileged \
--shm-size=1g \
--ulimit memlock=-1:-1 \
--device /dev/davinci0 \
--device /dev/davinci1 \
--device /dev/davinci2 \
--device /dev/davinci3 \
--device /dev/davinci4 \
--device /dev/davinci5 \
--device /dev/davinci6 \
--device /dev/davinci7 \
--device /dev/davinci_manager \
--device /dev/hisi_hdc \
--device /dev/ummu \
--device /dev/uburma \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver:ro \
-v /usr/local/dcmi:/usr/local/dcmi:ro \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi:ro \
-v /usr/bin/urma_admin:/usr/bin/urma_admin:ro \
-it "$IMAGE" bash
The complete driver mount includes driver/topo/950. All host mount sources must exist and have the expected file/directory type; -v creates a directory for a missing source path.
For automatic UB configuration, set ASCEND_LOCAL_COMM_RES='{"version":"1.3"}' in both serving environments. The /lib/route.conf mount depends on the CANN version:
- CANN 9.2.0 and later: This file is no longer a dependency; omit the mount.
- CANN 9.1.0 and 9.1.1: The default UB P/D configuration above uses device-only endpoints and does not require this mount. If you explicitly enable Host UB (
ub_ctp:host), mount the file unless the driver can provide the routing information through procfs.
If needed, generate the file on the host first (see the LocalCommRes Configuration Guide) and add -v /lib/route.conf:/lib/route.conf:ro. Host RoCE uses the separate endpoint files described above.
For Host RoCE, insert the following options before -it "$IMAGE" bash to expose the RDMA devices, provide the HRN5 shared library, and mount the endpoint directory configured by ascend_local_comm_res_path:
--device /dev/infiniband \
-v /usr/lib64/libhrn5-rdmav34.so:/usr/lib64/libhrn5-rdmav34.so:ro \
-v /etc/hixlep:/etc/hixlep:ro \
Both paths in the endpoint-directory mount are configurable: the left side is the host directory containing the endpoint JSON files, and the right side is their directory inside the container. Set ascend_local_comm_res_path to the container-side directory. For example, -v /srv/mooncake/endpoints:/opt/mooncake/endpoints:ro requires "ascend_local_comm_res_path": "/opt/mooncake/endpoints". Keep the ub_endpoint_npu_<physical_npu_id>.json filenames unchanged.
- Use the provider library path/version matching the host driver and container RDMA userspace. Mount
/etc/libibverbs.d/hrn5.driverwith-v /etc/libibverbs.d/hrn5.driver:/etc/libibverbs.d/hrn5.driver:roif required by that userspace; this configuration file does not replace the shared library. --privilegedexposes host devices. A non-privileged Host RoCE configuration must explicitly map the devices and provide--cap-add=NET_ADMIN; validate it for your driver and workload.- Mounting the
hiroce5diagnostic tool is optional, for example-v /usr/local/bin/hiroce5:/usr/local/bin/hiroce5:roif that is its host path.
安装 Mooncake¶
The vLLM-Ascend container images already include a matching Mooncake version. You can use the bundled version directly; downloading and compiling Mooncake is optional and is only needed for specific workload requirements. Follow the source-build steps below only if your workload requires a custom Mooncake build, and ensure that it is compatible with the image's vLLM-Ascend and CANN versions.
Mooncake is the serving platform for Kimi, a leading LLM service provided by Moonshot AI. Installation and Compilation Guide: https://github.com/kvcache-ai/Mooncake?tab=readme-ov-file#build-and-use-binaries For an optional source build, first obtain the Mooncake project:
(可选)如果网络状况不佳,请替换 go install 的 URL
安装 mpi
安装相关依赖。不需要安装 Go。
编译并安装
设置环境变量
注意:
- 根据您的具体 Python 安装调整 Python 路径
- 确保
/usr/local/lib和/usr/local/lib64位于您的LD_LIBRARY_PATH中
预填充器/解码器部署¶
长序列或高并发时的超时
对于长序列或高并发场景,默认的 480 秒 KV 缓存释放超时可能不够。请在 prefiller 启动脚本中根据需要增大该值。对于使用 VLLM_MOONCAKE_CONNECTOR_TIMEOUT 作为该超时的版本,请添加:
该值以秒为单位:1800 表示允许 30 分钟后超时。在当前版本中,此设置名为 VLLM_MOONCAKE_ABORT_REQUEST_TIMEOUT;请改用 export VLLM_MOONCAKE_ABORT_REQUEST_TIMEOUT=1800。请检查您所安装版本支持的变量名。
增大此超时通常不会影响正常运行期间的推理精度或性能。如果 decoder(D)节点发生故障,而请求的 KV 缓存仍留在 prefiller(P)节点上且 decoder 尚未接收,则更长的超时会延迟释放这些缓存。在释放之前,它们会持续占用 HBM,从而减少 P 节点上可用于其他请求的内存。
我们可以分别在预填充(prefiller)节点和解码(decoder)节点上运行以下脚本以启动服务。请注意,每个 P/D 节点将占用从 kv_port 到 kv_port + num_chips 范围内的端口来初始化 socket 监听器。为避免出现问题,应防止端口冲突。
QoS 配置¶
在传输发起方的 kv_connector_extra_config 中设置 qos_priority。
该选项由 MooncakeConnectorV1、MooncakeHybridConnector
和 MooncakeLayerwiseConnector 支持。默认 P/D QoS 为 1;可接受的值为
[0, 4] 范围内的整数(不接受布尔值)。
在使用 HIXL 客户端/服务端传输时,发起连接的端点提供通道 QoS。对端使用 接收到的该值创建其对应的通道:
| 传输模式 | 发起方 | 操作 | 使用的 QoS 配置 |
|---|---|---|---|
| Pull | Decoder (D) | 从 prefiller 读取 KV | D 侧的 qos_priority |
| Push | Prefiller (P) | 向 decoder 写入 KV | P 侧的 qos_priority |
尽管在两种模式下 KV 数据都从 P 流向 D,但 pull 使用 D 的 QoS,push 使用 P 的 QoS。仅配置被动端点不会覆盖发起方的通道 QoS。两个端点都支持该选项, 但连接的有效值来自其发起方。
例如,在现有的并行设置旁添加 "qos_priority": 1:
{
"kv_connector": "MooncakeConnectorV1",
"kv_role": "kv_consumer",
"kv_connector_extra_config": {
"qos_priority": 1,
"prefill": {"dp_size": 1, "tp_size": 2},
"decode": {"dp_size": 1, "tp_size": 2}
}
}
为 prefiller 使用 kv_producer,并保留 --kv-transfer-config 中其他特定于部署的
字段。
无需手动导出 QoS 环境变量。在初始化传输引擎之前,连接器会将其 QoS 合并到
ASCEND_GLOBAL_RESOURCE_CONFIG 中字面的顶层 JSON 键
"comm_resource_config.qos",如果该环境变量不存在则创建它。其他资源设置和 store
配置会被保留。显式的 QoS 值,或在省略时的默认值 1,会替换现有的顶层 QoS。无效的 QoS 值或格式错误的
资源 JSON 会在环境被修改之前失败。
Injected comm_resource_config.qos=... 日志确认本地
环境配置已成功写入。它本身并不能
证明该值被用于传输通道。在 pull 模式下,被动的
P 侧 HIXL 服务端可能不会打印本地 QoS 解析日志;在 push 模式下,
被动的 D 侧也是如此。请检查发起方的配置和
HIXL 通道日志以验证通道 QoS。
使用 MultiConnector 时,在 Mooncake P/D 子连接器的
kv_connector_extra_config 中设置 qos_priority。P/D 注入仅更新顶层 QoS 键;
它不会配置或验证池化后端,也不会修改其 store
设置。更改 P/D QoS 后请重启服务进程。
kv_port 配置指南¶
在 Ascend NPU 上,Mooncake 使用 AscendDirectTransport 进行 RDMA 数据传输,该传输会在 [20000, 20000 + npu_per_node × 1000) 范围内随机分配端口。如果 kv_port 与此范围重叠,可能会发生间歇性端口冲突。为避免此问题,请根据下表配置 kv_port:
| 每节点NPU数 | 预留端口范围 | 推荐kv_port |
|---|---|---|
| 8 | 20000 - 27999 | >= 28000 |
| 16 | 20000 - 35999 | >= 36000 |
Warning
如果在启动时偶尔看到 zmq.error.ZMQError: Address already in use,可能是由于 kv_port 与随机分配的 AscendDirectTransport 端口冲突。请增大您的 kv_port 值以避开保留范围。
launch_online_dp.py¶
使用 launch_online_dp.py 启动外部 dp vllm 服务器。
launch_online_dp.py
run_dp_template.sh¶
在每个节点上修改 run_dp_template.sh。
run_dp_template.sh
launch_online_dp.py启动dp-size-local个vLLM实例,并向run_dp_template.sh传递七个位置参数。以下示例对应启动服务。
| 启动器选项 | 模板值 | 含义 | 示例值 | 约束条件 |
|---|---|---|---|---|
--dp-size |
$3 / --data-parallel-size |
组内DP总秩数。 | P: 2; D: 32 |
正整数;同一组内必须一致。总秩数必须覆盖[0, dp-size)且不重叠。 |
--tp-size |
$7 / --tensor-parallel-size |
每个实例使用的NPU数量。 | P: 8; D: 1 |
正整数;dp-size-local * tp-size不得超过节点上可用的NPU数量。 |
--dp-size-local |
模板调用次数 | 此节点上的DP实例数。 | P: 2; D: 16 |
如果设置为-1,则默认为dp-size。否则,1 <= dp-size-local <= dp-size。 |
--dp-rank-start |
$4 / --data-parallel-rank = dp-rank-start + i |
此节点上的第一个DP秩。 | P: 0; D: 0或16 |
非负整数;分配的秩范围必须在dp-size内且不重叠。 |
--dp-address |
$5 / --data-parallel-address |
DP主节点地址。 | P: 192.0.0.1或192.0.0.2; D: 192.0.0.3 |
IP地址必须可访问,且同一DP组内必须一致。 |
--dp-rpc-port |
$6 / --data-parallel-rpc-port |
DP主节点RPC端口。 | 12321 |
空闲且可访问的端口;同一DP组内必须一致。 |
--vllm-start-port |
$2 / --port = vllm-start-port + i |
第一个本地API端口。 | 7100,然后是7101,... |
连续的空闲端口;必须与代理配置匹配。 |
| 由启动器计算 | $1 / ASCEND_RT_VISIBLE_DEVICES |
分配给每个实例的NPU ID。 | P: 0,...,7, 8,...,15; D: 0到15 |
ID必须存在且不重叠;非连续ID需要调整启动器。 |
Note
- 启动器仅验证参数类型和必需选项。部署前请检查其余约束条件。
- 如果启用了投机解码,
num_speculative_tokens应满足以下条件之一:- 混合Mamba模型(例如Qwen-Next和Qwen3.5系列):P节点和D节点上的
num_speculative_tokens应相等。 - 其他模型:P节点上的
num_speculative_tokens应为1,D节点上的num_speculative_tokens应大于或等于1。
- 混合Mamba模型(例如Qwen-Next和Qwen3.5系列):P节点和D节点上的
分层¶
nic_name="eth0" # network card name
local_ip="192.0.0.1"
export HCCL_IF_IP=$local_ip
export GLOO_SOCKET_IFNAME=$nic_name
export TP_SOCKET_IFNAME=$nic_name
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export HCCL_BUFFSIZE=256
export TASK_QUEUE_ENABLE=1
export HCCL_OP_EXPANSION_MODE="AIV"
export VLLM_USE_V1=1
export ASCEND_RT_VISIBLE_DEVICES=$1
vllm serve /path_to_weight/DeepSeek-r1_w8a8_mtp \
--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 ds_r1 \
--max-model-len 40000 \
--max-num-batched-tokens 16384 \
--max-num-seqs 8 \
--enforce-eager \
--trust-remote-code \
--gpu-memory-utilization 0.9 \
--quantization ascend \
--no-enable-prefix-caching \
--speculative-config '{"num_speculative_tokens": 1, "method":"deepseek_mtp"}' \
--additional-config '{"enable_shared_expert_dp": true}' \
--kv-transfer-config \
'{"kv_connector": "MooncakeLayerwiseConnector",
"kv_role": "kv_producer",
"kv_port": "36000",
"kv_connector_extra_config": {
"prefill": {
"dp_size": 2,
"tp_size": 8
},
"decode": {
"dp_size": 32,
"tp_size": 1
}
}
}'
nic_name="eth0" # network card name
local_ip="192.0.0.2"
export HCCL_IF_IP=$local_ip
export GLOO_SOCKET_IFNAME=$nic_name
export TP_SOCKET_IFNAME=$nic_name
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export HCCL_BUFFSIZE=256
export TASK_QUEUE_ENABLE=1
export HCCL_OP_EXPANSION_MODE="AIV"
export VLLM_USE_V1=1
export ASCEND_RT_VISIBLE_DEVICES=$1
vllm serve /path_to_weight/DeepSeek-r1_w8a8_mtp \
--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 ds_r1 \
--max-model-len 40000 \
--max-num-batched-tokens 16384 \
--max-num-seqs 8 \
--enforce-eager \
--trust-remote-code \
--gpu-memory-utilization 0.9 \
--quantization ascend \
--no-enable-prefix-caching \
--speculative-config '{"num_speculative_tokens": 1, "method":"deepseek_mtp"}' \
--additional-config '{"enable_shared_expert_dp": true}' \
--kv-transfer-config \
'{"kv_connector": "MooncakeLayerwiseConnector",
"kv_role": "kv_producer",
"kv_port": "36100",
"kv_connector_extra_config": {
"prefill": {
"dp_size": 2,
"tp_size": 8
},
"decode": {
"dp_size": 32,
"tp_size": 1
}
}
}'
nic_name="eth0" # network card name
local_ip="192.0.0.3"
export HCCL_IF_IP=$local_ip
export GLOO_SOCKET_IFNAME=$nic_name
export TP_SOCKET_IFNAME=$nic_name
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export HCCL_BUFFSIZE=600
export TASK_QUEUE_ENABLE=1
export HCCL_OP_EXPANSION_MODE="AIV"
export VLLM_USE_V1=1
export ASCEND_RT_VISIBLE_DEVICES=$1
vllm serve /path_to_weight/DeepSeek-r1_w8a8_mtp \
--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 ds_r1 \
--max-model-len 40000 \
--max-num-batched-tokens 256 \
--max-num-seqs 40 \
--trust-remote-code \
--gpu-memory-utilization 0.94 \
--quantization ascend \
--no-enable-prefix-caching \
--speculative-config '{"num_speculative_tokens": 1, "method":"deepseek_mtp"}' \
--additional-config '{"recompute_scheduler_enable":true,"multistream_overlap_shared_expert": true,"finegrained_tp_config": {"lmhead_tensor_parallel_size":16}}' \
--compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' \
--kv-transfer-config \
'{"kv_connector": "MooncakeLayerwiseConnector",
"kv_role": "kv_consumer",
"kv_port": "36200",
"kv_connector_extra_config": {
"prefill": {
"dp_size": 2,
"tp_size": 8
},
"decode": {
"dp_size": 32,
"tp_size": 1
}
}
}'
nic_name="eth0" # network card name
local_ip="192.0.0.4"
export HCCL_IF_IP=$local_ip
export GLOO_SOCKET_IFNAME=$nic_name
export TP_SOCKET_IFNAME=$nic_name
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export HCCL_BUFFSIZE=600
export TASK_QUEUE_ENABLE=1
export HCCL_OP_EXPANSION_MODE="AIV"
export VLLM_USE_V1=1
export ASCEND_RT_VISIBLE_DEVICES=$1
vllm serve /path_to_weight/DeepSeek-r1_w8a8_mtp \
--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 ds_r1 \
--max-model-len 40000 \
--max-num-batched-tokens 256 \
--max-num-seqs 40 \
--trust-remote-code \
--gpu-memory-utilization 0.94 \
--quantization ascend \
--no-enable-prefix-caching \
--speculative-config '{"num_speculative_tokens": 1, "method":"deepseek_mtp"}' \
--additional-config '{"recompute_scheduler_enable":true,"multistream_overlap_shared_expert": true,"finegrained_tp_config": {"lmhead_tensor_parallel_size":16}}' \
--compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' \
--kv-transfer-config \
'{"kv_connector": "MooncakeLayerwiseConnector",
"kv_role": "kv_consumer",
"kv_port": "36200",
"kv_connector_extra_config": {
"prefill": {
"dp_size": 2,
"tp_size": 8
},
"decode": {
"dp_size": 32,
"tp_size": 1
}
}
}'
非分层模式¶
nic_name="eth0" # network card name
local_ip="192.0.0.1"
export HCCL_IF_IP=$local_ip
export GLOO_SOCKET_IFNAME=$nic_name
export TP_SOCKET_IFNAME=$nic_name
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export HCCL_BUFFSIZE=256
export TASK_QUEUE_ENABLE=1
export HCCL_OP_EXPANSION_MODE="AIV"
export VLLM_USE_V1=1
export ASCEND_RT_VISIBLE_DEVICES=$1
vllm serve /path_to_weight/DeepSeek-r1_w8a8_mtp \
--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 ds_r1 \
--max-model-len 40000 \
--max-num-batched-tokens 16384 \
--max-num-seqs 8 \
--enforce-eager \
--trust-remote-code \
--gpu-memory-utilization 0.9 \
--quantization ascend \
--no-enable-prefix-caching \
--speculative-config '{"num_speculative_tokens": 1, "method":"deepseek_mtp"}' \
--additional-config '{"enable_shared_expert_dp": true}' \
--kv-transfer-config \
'{"kv_connector": "MooncakeConnectorV1",
"kv_role": "kv_producer",
"kv_port": "36000",
"kv_connector_extra_config": {
"prefill": {
"dp_size": 2,
"tp_size": 8
},
"decode": {
"dp_size": 32,
"tp_size": 1
}
}
}'
nic_name="eth0" # network card name
local_ip="192.0.0.2"
export HCCL_IF_IP=$local_ip
export GLOO_SOCKET_IFNAME=$nic_name
export TP_SOCKET_IFNAME=$nic_name
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export HCCL_BUFFSIZE=256
export TASK_QUEUE_ENABLE=1
export HCCL_OP_EXPANSION_MODE="AIV"
export VLLM_USE_V1=1
export ASCEND_RT_VISIBLE_DEVICES=$1
vllm serve /path_to_weight/DeepSeek-r1_w8a8_mtp \
--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 ds_r1 \
--max-model-len 40000 \
--max-num-batched-tokens 16384 \
--max-num-seqs 8 \
--enforce-eager \
--trust-remote-code \
--gpu-memory-utilization 0.9 \
--quantization ascend \
--no-enable-prefix-caching \
--speculative-config '{"num_speculative_tokens": 1, "method":"deepseek_mtp"}' \
--additional-config '{"enable_shared_expert_dp": true}' \
--kv-transfer-config \
'{"kv_connector": "MooncakeConnectorV1",
"kv_role": "kv_producer",
"kv_port": "36100",
"kv_connector_extra_config": {
"prefill": {
"dp_size": 2,
"tp_size": 8
},
"decode": {
"dp_size": 32,
"tp_size": 1
}
}
}'
nic_name="eth0" # network card name
local_ip="192.0.0.3"
export HCCL_IF_IP=$local_ip
export GLOO_SOCKET_IFNAME=$nic_name
export TP_SOCKET_IFNAME=$nic_name
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export HCCL_BUFFSIZE=600
export TASK_QUEUE_ENABLE=1
export HCCL_OP_EXPANSION_MODE="AIV"
export VLLM_USE_V1=1
export ASCEND_RT_VISIBLE_DEVICES=$1
vllm serve /path_to_weight/DeepSeek-r1_w8a8_mtp \
--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 ds_r1 \
--max-model-len 40000 \
--max-num-batched-tokens 256 \
--max-num-seqs 40 \
--trust-remote-code \
--gpu-memory-utilization 0.94 \
--quantization ascend \
--no-enable-prefix-caching \
--speculative-config '{"num_speculative_tokens": 1, "method":"deepseek_mtp"}' \
--additional-config '{"recompute_scheduler_enable":true,"multistream_overlap_shared_expert": true,"finegrained_tp_config": {"lmhead_tensor_parallel_size":16}}' \
--compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' \
--kv-transfer-config \
'{"kv_connector": "MooncakeConnectorV1",
"kv_role": "kv_consumer",
"kv_port": "36200",
"kv_connector_extra_config": {
"prefill": {
"dp_size": 2,
"tp_size": 8
},
"decode": {
"dp_size": 32,
"tp_size": 1
}
}
}'
nic_name="eth0" # network card name
local_ip="192.0.0.4"
export HCCL_IF_IP=$local_ip
export GLOO_SOCKET_IFNAME=$nic_name
export TP_SOCKET_IFNAME=$nic_name
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export HCCL_BUFFSIZE=600
export TASK_QUEUE_ENABLE=1
export HCCL_OP_EXPANSION_MODE="AIV"
export VLLM_USE_V1=1
export ASCEND_RT_VISIBLE_DEVICES=$1
vllm serve /path_to_weight/DeepSeek-r1_w8a8_mtp \
--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 ds_r1 \
--max-model-len 40000 \
--max-num-batched-tokens 256 \
--max-num-seqs 40 \
--trust-remote-code \
--gpu-memory-utilization 0.94 \
--quantization ascend \
--no-enable-prefix-caching \
--speculative-config '{"num_speculative_tokens": 1, "method":"deepseek_mtp"}' \
--additional-config '{"recompute_scheduler_enable":true,"multistream_overlap_shared_expert": true,"finegrained_tp_config": {"lmhead_tensor_parallel_size":16}}' \
--compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' \
--kv-transfer-config \
'{"kv_connector": "MooncakeConnectorV1",
"kv_role": "kv_consumer",
"kv_port": "36200",
"kv_connector_extra_config": {
"prefill": {
"dp_size": 2,
"tp_size": 8
},
"decode": {
"dp_size": 32,
"tp_size": 1
}
}
}'
启动服务¶
# on 192.0.0.1
python launch_online_dp.py --dp-size 2 --tp-size 8 --dp-size-local 2 --dp-rank-start 0 --dp-address 192.0.0.1 --dp-rpc-port 12321 --vllm-start-port 7100
# on 192.0.0.2
python launch_online_dp.py --dp-size 2 --tp-size 8 --dp-size-local 2 --dp-rank-start 0 --dp-address 192.0.0.2 --dp-rpc-port 12321 --vllm-start-port 7100
# on 192.0.0.3
python launch_online_dp.py --dp-size 32 --tp-size 1 --dp-size-local 16 --dp-rank-start 0 --dp-address 192.0.0.3 --dp-rpc-port 12321 --vllm-start-port 7100
# on 192.0.0.4
python launch_online_dp.py --dp-size 32 --tp-size 1 --dp-size-local 16 --dp-rank-start 16 --dp-address 192.0.0.3 --dp-rpc-port 12321 --vllm-start-port 7100
在 Atlas 850E (UBoE) 上部署 D2RH¶
验证范围: D2RH 仅使用 DeepSeek-V4-Flash 在如下所示的 Atlas 850E UBoE 配置下进行了验证。其他硬件、网络类型和部署配置尚未经过验证。
D2RH 会先将 KV cache 暂存到 Decode 节点的主机内存中,然后再加载到 HBM。有关传输顺序和缓存命中行为,请参阅 D2RH 工作流程。
内存限制: D2RH 目前会在每个 Decode worker 上注册一个固定(pinned)主机 KV cache,其容量与其设备 KV cache 相同,另加对齐开销。它镜像的是 KV cache,而不是设备的总 HBM 容量。请确保可用的主机 RAM 和容器内存限制能够覆盖所有本地 Decode rank 的合计分配量,并为模型加载和其他进程内存预留余量。
1. 在各自节点上的独立终端中分别启动 P 和 D。
请将示例中的 IP、接口名称和模型路径替换为你的部署值。在各自对应的节点上运行每个脚本。
在 P 上:
unset ftp_proxy
unset https_proxy
unset http_proxy
unset FTP_PROXY HTTPS_PROXY HTTP_PROXY
unset HCCL_INTRA_ROCE_ENABLE
nic_name="eth0" # change to your own NIC name
local_ip=192.0.2.10 # change to your own IP
export HCCL_IF_IP="$local_ip"
export GLOO_SOCKET_IFNAME="$nic_name"
export TP_SOCKET_IFNAME="$nic_name"
export HCCL_ALGO=level0:fullmesh
export HCCL_OP_EXPANSION_MODE=CCU_SCHED
export VLLM_RPC_TIMEOUT=3600000
export VLLM_EXECUTE_MODEL_TIMEOUT_SECONDS=30000
export HCCL_EXEC_TIMEOUT=204
export HCCL_CONNECT_TIMEOUT=120
export HCCL_BUFFSIZE=512
export LD_LIBRARY_PATH="/usr/local/lib:${LD_LIBRARY_PATH:-}"
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export TASK_QUEUE_ENABLE=1
export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3
export ASCEND_LOCAL_COMM_RES='{"version":"1.3"}'
export ASCEND_GLOBAL_RESOURCE_CONFIG='{"comm_resource_config.protocol_desc":["uboe:device"]}'
# Ensure the model path matches the directory recorded during download
vllm serve /path/to/DeepSeek-V4-Flash-0731-w4a4c8 \
--host "$local_ip" \
--port 8100 \
--served-model-name dsv4 \
--data-parallel-size 4 \
--data-parallel-address "$local_ip" \
--data-parallel-rpc-port 12321 \
--tensor-parallel-size 1 \
--pipeline-parallel-size 1 \
--enable-expert-parallel \
--gpu-memory-utilization 0.9 \
--max-model-len 133120 \
--max-num-batched-tokens 8192 \
--max-num-seqs 32 \
--block-size 32 \
--enable-prefix-caching \
--no-disable-hybrid-kv-cache-manager \
--api-server-count 1 \
--async-scheduling \
--tokenizer-mode deepseek_v4 \
--tool-call-parser deepseek_v4 \
--enable-auto-tool-choice \
--reasoning-parser deepseek_v4 \
--trust-remote-code \
--quantization ascend \
--attention_config.indexer_kv_dtype fp8 \
--model-loader-extra-config '{"enable_multithread_load":true,"num_threads":128}' \
--speculative-config '{"method":"dspark","num_speculative_tokens":5,"enforce_eager":true}' \
--enforce-eager \
--kv-transfer-config \
'{
"kv_connector": "MooncakeD2RHConnectorV1",
"kv_role": "kv_producer",
"kv_port": "36010",
"kv_connector_extra_config": {
"prefill": {
"dp_size": 4,
"tp_size": 1
},
"decode": {
"dp_size": 4,
"tp_size": 1
}
}
}' \
--additional-config '{
"enable_cpu_binding": true,
"enable_shared_expert_dp": true,
"multistream_overlap_shared_expert": true,
"enable_flashcomm1": false
}'
在 D 上:
unset ftp_proxy
unset https_proxy
unset http_proxy
unset FTP_PROXY HTTPS_PROXY HTTP_PROXY
unset HCCL_INTRA_ROCE_ENABLE
nic_name="eth0" # change to your own NIC name
local_ip=192.0.2.20 # change to your own IP
export HCCL_IF_IP="$local_ip"
export GLOO_SOCKET_IFNAME="$nic_name"
export TP_SOCKET_IFNAME="$nic_name"
export HCCL_ALGO=level0:fullmesh
export HCCL_OP_EXPANSION_MODE=CCU_SCHED
export VLLM_RPC_TIMEOUT=3600000
export VLLM_EXECUTE_MODEL_TIMEOUT_SECONDS=30000
export HCCL_EXEC_TIMEOUT=204
export HCCL_CONNECT_TIMEOUT=120
export HCCL_BUFFSIZE=512
export LD_LIBRARY_PATH="/usr/local/lib:${LD_LIBRARY_PATH:-}"
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export TASK_QUEUE_ENABLE=1
export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3
export ASCEND_LOCAL_COMM_RES='{"version":"1.3"}'
export ASCEND_GLOBAL_RESOURCE_CONFIG='{"comm_resource_config.protocol_desc":["uboe:device"]}'
# Ensure the model path matches the directory recorded during download
vllm serve /path/to/DeepSeek-V4-Flash-0731-w4a4c8 \
--host "$local_ip" \
--port 8200 \
--served-model-name dsv4 \
--data-parallel-size 4 \
--data-parallel-address "$local_ip" \
--data-parallel-rpc-port 12322 \
--tensor-parallel-size 1 \
--pipeline-parallel-size 1 \
--enable-expert-parallel \
--gpu-memory-utilization 0.9 \
--max-model-len 133120 \
--max-num-batched-tokens 1024 \
--max-num-seqs 32 \
--block-size 32 \
--enable-prefix-caching \
--no-disable-hybrid-kv-cache-manager \
--api-server-count 1 \
--async-scheduling \
--tokenizer-mode deepseek_v4 \
--tool-call-parser deepseek_v4 \
--enable-auto-tool-choice \
--reasoning-parser deepseek_v4 \
--trust-remote-code \
--quantization ascend \
--attention_config.indexer_kv_dtype fp8 \
--model-loader-extra-config '{"enable_multithread_load":true,"num_threads":128}' \
--speculative-config '{"method":"dspark","num_speculative_tokens":5,"enforce_eager":true}' \
--compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' \
--kv-transfer-config \
'{
"kv_connector": "MooncakeD2RHConnectorV1",
"kv_role": "kv_consumer",
"kv_port": "36020",
"kv_connector_extra_config": {
"d2rh_zmq_port": 38100,
"d2rh_scheduler_ready_port": 38200,
"prefill": {
"dp_size": 4,
"tp_size": 1
},
"decode": {
"dp_size": 4,
"tp_size": 1
}
}
}' \
--additional-config '{
"enable_cpu_binding": true,
"enable_shared_expert_dp": true,
"multistream_overlap_shared_expert": true,
"enable_flashcomm1": false
}'
这些脚本在两侧均启用前缀缓存,保持混合 KV cache
管理器启用,并设置
ASCEND_GLOBAL_RESOURCE_CONFIG='{"comm_resource_config.protocol_desc":["uboe:device"]}'。
在 Atlas 850E 上它们使用 FP8 indexer cache,而不是 A2/A3 示例中的 INT8 indexer 设置;请参阅 W4A4C8 FAQ。
P 使用 eager 执行,D 使用 FULL_DECODE_ONLY 图。
The context limit is 133120 tokens, enough for 128k input plus 1k output, including
any prompt-template tokens within that limit.
Adjust --gpu-memory-utilization directly if needed.
Reducing it reduces available KV capacity and can reduce D's staging allocation;
recheck both host memory and maximum request capacity after changing it.
HTTP 端口为 8100 (P) 和 8200 (D);DP RPC 端口为 12321 和 12322,
kv_port 基址为 36010 和 36020。Decode 脚本在 kv_connector_extra_config 中显式设置了两个
额外的 TCP/ZMQ 控制端口基址:
d2rh_zmq_port(默认值:38100):每个 D worker 监听来自其本地调度器的START_PULL请求。这些请求会触发将所需的 KV cache 暂存到 D 主机内存,并在可用时 复用有效的主机缓存条目。此端口承载控制消息,而不是 KV 数据本身。d2rh_scheduler_ready_port(默认值:38200):每个 D 调度器监听 worker 发出的主机暂存已就绪通知。一旦所需的 worker 报告就绪,请求即可继续进入设备块分配和 H2D 加载。此通知并不意味着 H2D 或解码已完成。
这些是基址端口,而不是所有 rank 共享的单一端口。对于此
DP4/TP1/PP1 部署,D 使用 38100-38103 处理拉取请求,
使用 38200-38203 处理调度器就绪通知,每个范围内每个 DP rank 对应一个端口。其他并行布局会引入额外的 rank 偏移;
请为部署预留完整范围。这两项设置均为 D 侧控制项,
无需在 P 脚本中重复设置。
这些端口独立于 kv_port,后者仍用于 Mooncake
握手元数据和传输完成信令。更改 kv_port 不会
改变任何一个 D2RH 控制端口基址。Mooncake TransferEngine RPC 和
UBoE/HCCL 通信也有各自的网络要求。
对于共享主机网络的多个 D 实例,请为这两项设置分配互不重叠的范围,
并避免与 HTTP、DP RPC、kv_port 及其他服务冲突。例如,如果 39100-39103 和 39200-39203 空闲,
第二个 DP4/TP1/PP1 实例可以使用基址 39100 和
39200。在该实例的 D 启动命令中配置一次基址即可;rank 偏移会自动添加。请确保
D 调度器和 worker 能够访问绑定的 D 节点 IP 及这些 TCP 端口。
2. 检查两个服务,然后启动代理。
在能够访问两个节点的主机上,从仓库根目录执行:
unset http_proxy https_proxy ftp_proxy HTTP_PROXY HTTPS_PROXY FTP_PROXY
export P_IP=192.0.2.10
export D_IP=192.0.2.20
curl --fail "http://${P_IP}:8100/health"
curl --fail "http://${D_IP}:8200/health"
python examples/disaggregated_prefill_v1/load_balance_proxy_server_example.py \
--host 0.0.0.0 --port 8000 \
--prefiller-hosts "$P_IP" --prefiller-ports 8100 \
--decoder-hosts "$D_IP" --decoder-ports 8200
代理指向每个节点的单一 API 端点;服务器会在其本地 DP rank 之间分发
请求。此示例中不要同时运行 launch_online_dp.py。请将这些未认证的示例端点保持在可信网络上。
部署示例代理¶
在与预填充服务实例部署相同的节点上运行代理服务器。您可以在仓库的 examples 目录中找到代理实现。
我们提供了两种具有不同请求路由行为的代理实现:
-
load_balance_proxy_layerwise_server_example.py:请求首先路由到 D 节点,然后按需转发到 P 节点。此代理设计用于 MooncakeLayerwiseConnector。load_balance_proxy_layerwise_server_example.py -
load_balance_proxy_server_example.py:请求首先路由到 P 节点,然后转发到 D 节点进行后续处理。此代理设计用于 MooncakeConnector。load_balance_proxy_server_example.py
python load_balance_proxy_layerwise_server_example.py \
--port 1999 \
--host 192.0.0.1 \
--prefiller-hosts \
192.0.0.1 \
192.0.0.1 \
192.0.0.2 \
192.0.0.2 \
--prefiller-ports \
7100 7101 7100 7101 \
--decoder-hosts \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.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
python load_balance_proxy_server_example.py \
--port 1999 \
--host 192.0.0.1 \
--prefiller-hosts \
192.0.0.1 \
192.0.0.1 \
192.0.0.2 \
192.0.0.2 \
--prefiller-ports \
7100 7101 7100 7101 \
--decoder-hosts \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.3 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.4 \
192.0.0.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
两个代理共享以下后端选项。
| 参数 | 适用范围 | 默认值 | 示例值 | 含义和约束条件 |
|---|---|---|---|---|
--port |
两者 | 8000 |
1999 |
代理监听端口。必须空闲、可访问,且在1到65535之间。 |
--host |
两者 | localhost |
192.0.0.1 |
代理监听地址。分层模式要求D节点可访问的非通配符地址。 |
--prefiller-hosts |
两者 | localhost |
192.0.0.1 192.0.0.1 192.0.0.2 192.0.0.2 |
P实例主机。数量必须等于--prefiller-ports的数量。 |
--prefiller-ports |
两者 | 8001 |
7100 7101 7100 7101 |
P实例端口。每个主机-端口对必须唯一且可访问。 |
--decoder-hosts |
两者 | localhost |
十六个192.0.0.3,然后是十六个192.0.0.4 |
D实例主机。数量必须等于--decoder-ports的数量。 |
--decoder-ports |
两者 | 8002 |
每个D主机的7100-7115 |
D实例端口。每个主机-端口对必须唯一且可访问。 |
Note
代理脚本会验证每个主机列表与其对应的端口列表长度是否相同。
您可以在仓库的 examples 中找到代理程序,load_balance_proxy_server_example.py
基准测试¶
建议使用 aisbench 工具评估性能。aisbench 执行以下命令安装 aisbench
评估性能前,需要取消 http 代理,如下所示
- 您可以将数据集放在目录:
benchmark/ais_bench/datasets中 - 您可以在目录:
benchmark/ais_bench/benchmark/configs/models/vllm_api中更改配置。以vllm_api_stream_chat.py为例
models = [
dict(
attr="service",
type=VLLMCustomAPIChatStream,
abbr='vllm-api-stream-chat',
path="/root/.cache/ds_r1",
model="dsr1",
request_rate = 14,
retry = 2,
host_ip = "192.0.0.1", # Proxy service host IP
host_port = 8000, # Proxy service Port
max_out_len = 10,
batch_size=768,
trust_remote_code=True,
generation_kwargs = dict(
temperature = 0,
seed = 1024,
ignore_eos=False,
)
)
]
- 以gsm8k数据集为例,执行以下命令来评估性能。
ais_bench --models vllm_api_stream_chat --datasets gsm8k_gen_0_shot_cot_str_perf --debug --mode perf
- 有关 aisbench 命令和参数的更多详细信息,请参考 aisbench
常见问题¶
1. Prefiller 节点需要预热¶
由于某些 NPU 算子的计算需要多轮预热才能达到最佳性能,建议在进行性能测试前,先用一些请求预热服务,以实现最佳端到端吞吐量。
验证¶
使用代理服务器端点检查服务健康状态。