KV缓存池(Ascend Store)部署指南¶
1. 环境依赖¶
- 软件:
- CANN >= 8.5.0
- vLLM:main分支
- vLLM-Ascend:main分支
- mooncake:>= 0.3.11.post1
KV池参数说明¶
kv_load_failure_policy:KV加载失败处理策略¶
kv_load_failure_policy 是 kv-transfer-config 中的顶级字段。
recompute:当KV加载失败时,vLLM将请求回滚到最后一个有效前缀,并重新调度以重新计算失败的KV块。尚不支持混合注意力模型(例如DeepSeekV4、Qwen 3.5)。fail:当KV加载失败时,受影响的请求将直接终止并返回错误。
vLLM中的默认值为 fail。如果希望在KV加载失败后请求回退到重新计算,请将其设置为 recompute。
使用 MultiConnector 时,请在 MultiConnector 顶级 kv-transfer-config 上配置 kv_load_failure_policy,而不是在子连接器上配置。
kv_connector_extra_config:池化的其他可配置参数¶
| 参数 | 描述 |
|---|---|
lookup_rpc_port |
池化调度进程与工作进程之间RPC通信的端口:每个实例需要配置唯一的端口。 |
load_async |
是否启用异步加载。默认值为false。 |
backend |
设置kvpool的存储后端(mooncake、memcache、yuanrong),默认为mooncake。 |
consumer_is_to_put |
Decode节点是否将KV Cache放入KV Pool。默认值为false。 |
consumer_is_to_load |
Decode节点是否从KV Pool加载KV cache。默认值为false。 |
use_layerwise |
启用逐层KV保存/加载。仅在Prefill节点上支持,并且需要memcache后端。默认值为false。 |
prefill_pp_size |
Prefill PP大小,当Prefill节点启用PP时需要设置。 |
prefill_pp_layer_partition |
Prefill PP层分区,当Prefill节点启用PP时需要设置。 |
qos_priority |
KV 池的传输 QoS 优先级,取值范围为 [0, 4] 的整数(值越大优先级越高)。 |
环境变量配置¶
为保证统一的哈希生成,在启用KV池时,需要在所有节点上同步PYTHONHASHSEED环境变量。
2. 使用Mooncake作为KV池后端的示例¶
步骤2.1:软件安装¶
-
软件:
-
检查配置:
确保环境中存在hccn.conf文件。如果使用Docker,请将其挂载到容器中。
对于Ascend 950产品,还需挂载: * 设备:
/dev/ummu、/dev/uburma* 命令:/usr/bin/urma_admin* 配置:/lib/route.conf、/etc/hccl_rootinfo.json -
安装Mooncake
Mooncake 是 Kimi(Moonshot AI 提供的领先大语言模型服务)的服务平台。 Mooncake 的 wheel 包要求 glibc 2.35 或更高版本。安装前请检查已安装的 glibc 版本:
使用 pip 安装 Mooncake:
python3 -m pip install mooncake-transfer-engine-npu==0.3.11.post1 --extra-index-url https://mirrors.aliyun.com/pypi/web/simple当省略
tenant_id或解析为default时,仍支持Mooncake0.3.11.post1。非默认租户要求Mooncake版本的MooncakeDistributedStore.setup()接受tenant_id;多租户部署请使用Mooncake0.3.12或更高版本。
-
步骤2.2:运行Mooncake Master¶
注意: 在继续之前,请查看以下Mooncake指南:
步骤2.2.1:配置mooncake.json¶
环境变量 MOONCAKE_CONFIG_PATH 配置为mooncake.json所在的完整路径。
{
"metadata_server": "P2PHANDSHAKE",
"protocol": "ascend",
"device_name": "",
"master_server_address": "xx.xx.xx.xx:50088",
"global_segment_size": "1GB" (1024MB/1048576KB/1073741824B/1073741824),
"preferred_segment": false,
"prefer_alloc_in_same_node": true,
"enable_ssd_offload": false, # only required when the SSD offload feature is enabled
"ssd_offload_path": "/nvme/mooncake_offload", # only required when the SSD offload feature is enabled)
"tenant_id": "default"
}
| 参数 | 描述 |
|---|---|
metadata_server |
配置为P2PHANDSHAKE。 |
protocol |
在NPU上必须设置为ascend。 |
device_name |
留空字符串""。ascend协议不使用设备名称。 |
master_server_address |
master服务的IP和端口。也可以通过MOONCAKE_MASTER环境变量设置,该变量优先于此配置项(可用于通过Kubernetes注入master地址)。 |
global_segment_size |
每张卡向KV池注册的内存大小。需要按1GB对齐。也可以通过MOONCAKE_GLOBAL_SEGMENT_SIZE环境变量设置,该变量优先于此配置项。 |
preferred_segment |
向KV池放入对象时,是否优先将KV存储在本地区段上。默认为false。 |
prefer_alloc_in_same_node |
是否优先在同一节点上分配KV。默认为true。 |
enable_ssd_offload |
设置为true以启用SSD卸载。不支持环境变量。 |
ssd_offload_path |
当enable_ssd_offload为true时必填。 Mooncake存储卸载KV数据的本地目录的绝对路径(例如/nvme/mooncake_offload)。该目录必须存在且对vLLM进程可写;请在启动前创建(mkdir -p <path>)。Mooncake拒绝相对路径、符号链接以及包含..的路径。 |
tenant_id |
可选的Mooncake租户命名空间。缺失、null、空值或仅含空白字符的值使用default;周围空白字符会被移除。所有共享KV条目的Prefill、Decode、调度器和副本实例必须使用相同的租户ID。非默认租户需要Mooncake 0.3.12或更高版本。 |
步骤2.2.2:启动mooncake_master¶
作为独立进程,master服务只需在一个节点上启动。
在 mooncake 文件夹下:
mooncake_master --port 50088 --eviction_high_watermark_ratio 0.9 --eviction_ratio 0.1 --default_kv_lease_ttl 11000 --enable_offload=false --client_ttl=120
| 字段 | 描述 |
|---|---|
eviction_high_watermark_ratio |
确定Mooncake Store执行驱逐的水位线。 |
eviction_ratio |
确定将被驱逐的已存储对象的比例。 |
default_kv_lease_ttl |
控制KV对象的默认租约TTL(毫秒)。请保持其大于ASCEND_CONNECT_TIMEOUT和ASCEND_TRANSFER_TIMEOUT。 |
enable_offload |
设置为true以在Mooncake master中启用SSD卸载。保持master端口与mooncake.json中的master_server_address一致。仅在启用SSD卸载时需要。 |
client_ttl |
客户端在最后一次Ping后保持存活的秒数。CLI默认为10;参见启用SSD卸载时的SEGMENT_NOT_FOUND。仅在启用SSD卸载时需要。 |
步骤2.2.3:启用严格多租户模式¶
当严格多租户模式被禁用时,租户ID在对象放置时会被忽略,对象保留在default命名空间中。要启用隔离命名空间和按租户内存配额准入,请以严格多租户模式和策略连接器启动Mooncake master:
mooncake_master \
--port 50088 \
--enable_multi_tenants=true \
--tenant_quota_connector_type=file \
--tenant_quota_connector_uri=/etc/mooncake/tenant_quotas.yaml
例如,/etc/mooncake/tenant_quotas.yaml可以包含:
version: 1
tenants:
- name: tenant-a
quota: 200GB
- name: tenant-b
quota: 200GB
- name: default
quota: 100GB
当Mooncake以STORE_USE_ETCD=ON构建时,文件连接器可以替换为etcd;在这种情况下,将tenant_quota_connector_uri设置为etcd端点。严格模式拒绝未注册租户(包括default)的写入,因此vLLM-Ascend使用的每个租户都必须出现在策略中。
Mooncake通过master指标HTTP端口(默认9003)暴露租户配额快照:
curl -s http://<master_host>:9003/api/v1/tenant_quotas
curl -s "http://<master_host>:9003/api/v1/tenant_quotas?tenant_id=tenant-a"
tenant_id是实例级命名空间和配额标识,不是认证机制。能够访问Mooncake的客户端仍然可以声明租户ID。即使启用了租户隔离,也应将不兼容的模型、模型版本、量化格式和KV布局保留在单独的模型或发布命名空间中。
步骤2.3:PD分离场景¶
步骤2.3.1:运行prefill节点和decode节点¶
使用 MultiConnector 同时利用 MooncakeConnectorV1 和 AscendStoreConnector。MooncakeConnectorV1 执行 kv_transfer,而 AscendStoreConnector 作为前缀缓存节点。
对于A3和Ascend 950产品,若要实现Store/PD流量分离,请在prefill和decode节点上同时设置ASCEND_GLOBAL_RESOURCE_CONFIG,并使用CANN >= 9.1.0。顶层资源配置控制MooncakeConnectorV1的PD流量,而store部分控制AscendStoreConnector的Mooncake Store流量。
run_prefill.sh/run_decode.sh:
#!/bin/bash
# prefill / decode
ROLE="prefill"
# A2 (800I/800T A2) or A3 (800I/800T A3) or A5 (950PR/950DT)
HARDWARE_SERIES="A2"
# Link type: ROCE or HCCS in A3 series.
LINK_TYPE="ROCE"
LOCAL_IP="xx.xx.xx.xx"
NIC_NAME="xxxxxx"
MODEL_PATH="xxxxxxx/Qwen3-32B"
SERVED_MODEL_NAME="qwen3"
DATA_PARALLEL_SIZE=1
TENSOR_PARALLEL_SIZE=8
export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
# parameters required for kv pool and mooncake
export PYTHONHASHSEED=0
export MOONCAKE_CONFIG_PATH="/xxxxxx/mooncake.json"
export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/latest/python/site-packages/mooncake:$LD_LIBRARY_PATH
if [ "$ROLE" == "prefill" ]; then
KV_ROLE="kv_producer"
KV_PORT="20001"
LOOKUP_RPC_PORT="0"
else
KV_ROLE="kv_consumer"
KV_PORT="20002"
LOOKUP_RPC_PORT="1"
fi
echo "Starting vLLM on Series: $HARDWARE_SERIES, Role: $ROLE"
rm -rf /root/ascend/log/*
rm -rf ./connector.log
# For detailed parameter descriptions, see 5.1 Environment Variables Description
if [ "$HARDWARE_SERIES" == "A2" ] || { [ "$HARDWARE_SERIES" == "A3" ] && [ "$LINK_TYPE" == "ROCE" ]; }; then
echo 200000 > /proc/sys/vm/nr_hugepages
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_ROCE_ENABLE=1
elif [ "$HARDWARE_SERIES" == "A3" ] && [ "$LINK_TYPE" == "HCCS" ]; then
export ACL_OP_INIT_MODE=1
export ASCEND_ENABLE_USE_FABRIC_MEM=1
elif [ "$HARDWARE_SERIES" == "A5" ]; then
# A5 UBOE
export ASCEND_GLOBAL_RESOURCE_CONFIG='{"comm_resource_config.protocol_desc":["uboe:device"]}'
# A5 UB
export ASCEND_LOCAL_COMM_RES='{"version":"1.3"}'
else
echo "Error: Invalid HARDWARE_SERIES. Set to 'A2', 'A3', or 'A5'."
exit 1
fi
source /usr/local/Ascend/ascend-toolkit/set_env.sh
source /usr/local/Ascend/nnal/atb/set_env.sh
KV_CONFIG='{
"kv_connector": "MultiConnector",
"kv_role": "'$KV_ROLE'",
"kv_connector_extra_config": {
"connectors": [
{
"kv_connector": "MooncakeConnectorV1",
"kv_role": "'$KV_ROLE'",
"kv_port": "'$KV_PORT'",
"kv_connector_extra_config": {
"prefill": {
"dp_size": '$DATA_PARALLEL_SIZE',
"tp_size": '$TENSOR_PARALLEL_SIZE'
},
"decode": {
"dp_size": '$DATA_PARALLEL_SIZE',
"tp_size": '$TENSOR_PARALLEL_SIZE'
}
}
},
{
"kv_connector": "AscendStoreConnector",
"kv_role": "'$KV_ROLE'",
"kv_connector_extra_config": {
"backend": "mooncake",
"lookup_rpc_port": "'$LOOKUP_RPC_PORT'"
}
}
]
}
}'
CMD_ARGS=(
--model "$MODEL_PATH"
--served-model-name "$SERVED_MODEL_NAME"
--trust-remote-code
--enforce-eager
--data-parallel-size "$DATA_PARALLEL_SIZE"
--tensor-parallel-size "$TENSOR_PARALLEL_SIZE"
--port 30050
--max-num_seqs 20
--max-model-len 32768
--max-num-batched-tokens 16384
--gpu-memory-utilization 0.9
--kv-transfer-config "$KV_CONFIG"
)
python -m vllm.entrypoints.openai.api_server "${CMD_ARGS[@]}" > log_${ROLE}.log 2>&1
echo "vLLM started. Log file: log_${ROLE}.log"
目前,PD分离中的键值池默认只存储Prefill节点生成的kv缓存。在使用MLA的模型中,现在支持Decode节点存储kv缓存供Prefill节点使用,通过在AscendStoreConnector中添加consumer_is_to_put: true启用。如果Prefill节点启用了PP,还需要设置prefill_pp_size或prefill_pp_layer_partition。示例如下:
{
"kv_connector": "AscendStoreConnector",
"kv_role": "kv_consumer",
"kv_load_failure_policy": "recompute",
"kv_connector_extra_config": {
"lookup_rpc_port": "0",
"backend": "mooncake",
"consumer_is_to_put": true,
"prefill_pp_size": 2,
"prefill_pp_layer_partition": "30,31"
}
}
步骤2.3.2:启动proxy_server¶
python vllm-ascend/examples/disaggregated_prefill_v1/load_balance_proxy_server_example.py \
--host localhost \
--prefiller-hosts localhost \
--prefiller-ports 8100 \
--decoder-hosts localhost \
--decoder-ports 8200 \
将 localhost 替换为您的实际IP地址。
步骤2.3.3:运行推理¶
将命令中的 localhost、端口和模型权重路径配置为您自己的设置。
简短问题:
curl -s http://localhost:8000/v1/completions -H "Content-Type: application/json" -d '{ "model": "/xxxxx/Qwen2.5-7B-Instruct", "prompt": "Hello. I have a question. The president of the United States is", "max_completion_tokens": 200, "temperature":0.0 }'
详细问题:
curl -s http://localhost:8000/v1/completions -H "Content-Type: application/json" -d '{ "model": "/xxxxx/Qwen2.5-7B-Instruct", "prompt": "Given the accelerating impacts of climate change—including rising sea levels, increasing frequency of extreme weather events, loss of biodiversity, and adverse effects on agriculture and human health—there is an urgent need for a robust, globally coordinated response. However, international efforts are complicated by a range of factors: economic disparities between high-income and low-income countries, differing levels of industrialization, varying access to clean energy technologies, and divergent political systems that influence climate policy implementation. In this context, how can global agreements like the Paris Accord be redesigned or strengthened to not only encourage but effectively enforce emission reduction targets? Furthermore, what mechanisms can be introduced to promote fair and transparent technology transfer, provide adequate financial support for climate adaptation in vulnerable regions, and hold nations accountable without exacerbating existing geopolitical tensions or disproportionately burdening those with historically lower emissions?", "max_completion_tokens": 256, "temperature":0.0 }'
步骤2.4:PD混合推理¶
步骤2.4.1:运行混合部署脚本¶
pd_mix.sh 的内容:
# A2 (800I/800T A2) or A3 (800I/800T A3) or A5 (950PR/950DT)
HARDWARE_SERIES="A2"
# Link type: ROCE or HCCS in A3 series.
LINK_TYPE="ROCE"
LOCAL_IP="xx.xx.xx.xx"
NIC_NAME="xxxxxx"
MODEL_PATH="xxxxxxx/Qwen3-32B"
SERVED_MODEL_NAME="qwen3"
DATA_PARALLEL_SIZE=1
TENSOR_PARALLEL_SIZE=8
export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
# parameters required for kv pool and mooncake
export PYTHONHASHSEED=0
export MOONCAKE_CONFIG_PATH="/xxxxxx/mooncake.json"
export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/latest/python/site-packages/mooncake:$LD_LIBRARY_PATH
echo "Starting vLLM on Series: $HARDWARE_SERIES"
rm -rf /root/ascend/log/*
rm -rf ./connector.log
# For detailed parameter descriptions, see 5.1 Environment Variables Description
if [ "$HARDWARE_SERIES" == "A2" ] || { [ "$HARDWARE_SERIES" == "A3" ] && [ "$LINK_TYPE" == "ROCE" ]; }; then
echo 200000 > /proc/sys/vm/nr_hugepages
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_ROCE_ENABLE=1
elif [ "$HARDWARE_SERIES" == "A3" ] && [ "$LINK_TYPE" == "HCCS" ]; then
export ACL_OP_INIT_MODE=1
export ASCEND_ENABLE_USE_FABRIC_MEM=1
elif [ "$HARDWARE_SERIES" == "A5" ]; then
# A5 UBOE
export ASCEND_GLOBAL_RESOURCE_CONFIG='{"comm_resource_config.protocol_desc":["uboe:device"]}'
# A5 UB
export ASCEND_LOCAL_COMM_RES='{"version":"1.3"}'
else
echo "Error: Invalid HARDWARE_SERIES. Set to 'A2', 'A3', or 'A5'."
exit 1
fi
source /usr/local/Ascend/ascend-toolkit/set_env.sh
source /usr/local/Ascend/nnal/atb/set_env.sh
KV_CONFIG='{
"kv_connector": "AscendStoreConnector",
"kv_role": "kv_both",
"kv_connector_extra_config": {
"backend": "mooncake",
"lookup_rpc_port": "0"
}
}'
CMD_ARGS=(
--model "$MODEL_PATH"
--served-model-name "$SERVED_MODEL_NAME"
--trust-remote-code
--enforce-eager
--data-parallel-size "$DATA_PARALLEL_SIZE"
--tensor-parallel-size "$TENSOR_PARALLEL_SIZE"
--port 30050
--max-num_seqs 20
--max-model-len 32768
--max-num-batched-tokens 16384
--gpu-memory-utilization 0.9
--kv-transfer-config "$KV_CONFIG"
)
python -m vllm.entrypoints.openai.api_server "${CMD_ARGS[@]}" > log_mix.log 2>&1
echo "vLLM started. Log file: log_mix.log"
步骤2.4.2:运行推理¶
将命令中的 localhost、端口和模型权重路径配置为您自己的设置。发送的请求只会到达混合部署脚本所在的端口,无需启动单独的代理。
简短问题:
curl -s http://localhost:8100/v1/completions -H "Content-Type: application/json" -d '{ "model": "/xxxxx/Qwen2.5-7B-Instruct", "prompt": "Hello. I have a question. The president of the United States is", "max_completion_tokens": 200, "temperature":0.0 }'
详细问题:
curl -s http://localhost:8100/v1/completions -H "Content-Type: application/json" -d '{ "model": "/xxxxx/Qwen2.5-7B-Instruct", "prompt": "Given the accelerating impacts of climate change—including rising sea levels, increasing frequency of extreme weather events, loss of biodiversity, and adverse effects on agriculture and human health—there is an urgent need for a robust, globally coordinated response. However, international efforts are complicated by a range of factors: economic disparities between high-income and low-income countries, differing levels of industrialization, varying access to clean energy technologies, and divergent political systems that influence climate policy implementation. In this context, how can global agreements like the Paris Accord be redesigned or strengthened to not only encourage but effectively enforce emission reduction targets? Furthermore, what mechanisms can be introduced to promote fair and transparent technology transfer, provide adequate financial support for climate adaptation in vulnerable regions, and hold nations accountable without exacerbating existing geopolitical tensions or disproportionately burdening those with historically lower emissions?", "max_completion_tokens": 256, "temperature":0.0 }'
注意:对于启用了ASCEND_BUFFER_POOL的MooncakeStore,建议在运行实际性能基准测试之前执行预热阶段。
这是因为在涉及设备间通信时,HCCL单向通信连接会在实例启动后延迟创建。目前,需要在所有设备之间建立全网格连接。建立这些连接会带来一次性时间开销和持久的设备内存消耗(每个连接占用4 MB设备内存)。
对于预热,建议发送输入序列长度为8k、输出序列长度为1的请求,请求总数应为设备(卡/芯)数量的2–3倍。
步骤2.5:使用嵌入式真实客户端模式启用MooncakeStore SSD卸载¶
步骤2.5.1:运行嵌入式真实客户端¶
在模式A(嵌入式真实客户端)下,Mooncake 嵌入在 vLLM 中。当 vLLM 服务启动时,AscendStoreConnector / MooncakeBackend 会根据 mooncake.json 中的设置(包括启用 SSD 卸载时的 enable_ssd_offload 和 ssd_offload_path)自动调用 MooncakeDistributedStore.setup()。无需单独的 mooncake_client 进程。
步骤2.5.2:SSD磁盘使用控制¶
以下环境变量控制 SSD 卸载(桶后端)的磁盘空间使用:
| 环境变量 | 默认值 | 描述 |
|---|---|---|
MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES |
1342177280(1280 MB) |
每个rank的SSD读写缓冲区大小(字节)。不可在mooncake.json中配置。如果遇到BUFFER_OVERFLOW,请增大此值——参见调整MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES大小。在A3上且ASCEND_ENABLE_USE_FABRIC_MEM=1时,必须按1GB对齐,并计入每个rank的fabric内存配额(参见Fabric内存大小对齐)。 |
MOONCAKE_OFFLOAD_BUCKET_MAX_TOTAL_SIZE |
0 |
逐出阈值(字节)。当设置为0时,后端使用**物理磁盘容量的90%**作为配额。设置显式值以精确控制磁盘使用量。 |
MOONCAKE_OFFLOAD_BUCKET_EVICTION_POLICY |
none |
逐出策略:none(满时写入失败)、fifo或lru。 |
MOONCAKE_OFFLOAD_TOTAL_SIZE_LIMIT_BYTES |
2199023255552 (2 TB) |
报告给Mooncake master的每个rank的最大磁盘使用量。Master跨客户端聚合此值(在SSD Storage总计中约为2 TB × rank数量)。始终覆盖以匹配实际磁盘容量——默认值通常超过可用空间。 |
MOONCAKE_OFFLOAD_TOTAL_SIZE_LIMIT_BYTES 风险: 如果保留 2 TB 的默认值,master 显示的 SSD 总配额将远大于物理磁盘(例如,16 个 rank → 在 1 TB NVMe 上显示约 32 TB)。磁盘填满时卸载仍会失败,但监控看起来正常。在生产使用前,请将其设置为实际的每个 rank 预算。
由于每个 TP rank 在 ssd_offload_path 下使用独立的 SSD 子目录(rank_0/、rank_1/、...),所有 rank 共享同一物理磁盘。为防止单个 rank 消耗过多空间,请设置显式的每个 rank 配额。例如,对于 800 GB 磁盘和 8 个 TP rank:
# 800 GB total disk, 8 ranks, ~100 GB per rank
export MOONCAKE_OFFLOAD_TOTAL_SIZE_LIMIT_BYTES=$((100 * 1024 * 1024 * 1024))
export MOONCAKE_OFFLOAD_BUCKET_MAX_TOTAL_SIZE=$((100 * 1024 * 1024 * 1024))
export MOONCAKE_OFFLOAD_BUCKET_EVICTION_POLICY=lru
export MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES=1073741824 # 1 GB
3. 使用Memcache作为KV池后端的示例¶
步骤3.1:前提条件¶
在安装和配置Memcache之前,请执行必要的环境检查,包括内存检查5.2.1、A3可用内存扫描5.2.2、Ascend 950产品的签名验证/容器挂载,请参见5.2.3。如果还想启用SSD功能,请参见5.2.4。
步骤3.2:软件安装¶
MemCache依赖MemFabric。因此,必须先安装MemFabric。请在安装memfabric之后再安装memcache。
启用Memcache SSD缓存需要memcache_hybrid >= 1.2.0。
步骤3.3:配置memcache配置文件¶
运行 pip show memcache_hybrid,在输出中找到 Location 的值。在下面将该值用作 {INSTALL_PATH}。
配置文件位于{INSTALL_PATH}/memcache_hybrid/config。
mmc-meta.conf:
ock.mmc.meta_service_url = tcp://xx.xx.xx.xx:5000
ock.mmc.meta_service.config_store_url = tcp://xx.xx.xx.xx:6000
ock.mmc.meta_service.metrics_url = http://xx.xx.xx.xx:8000
ock.mmc.log_level = info
# If SSD is enabled, modify the following parameters to improve SSD cache hit rate
ock.mmc.evict_threshold_high = 70
ock.mmc.evict_threshold_low = 60
ock.mmc.rewarm.dram_watermark = 95
mmc-local.conf:
ock.mmc.meta_service_url = tcp://xx.xx.xx.xx:5000
ock.mmc.local_service.config_store_url = tcp://xx.xx.xx.xx:6000
ock.mmc.log_level = info
ock.mmc.local_service.world_size = 256
ock.mmc.local_service.protocol = device_sdma
ock.mmc.local_service.dram.size = 1GB
ock.mmc.local_service.max.dram.size = 1024GB
# SSD feature related parameters below
ock.mmc.local_service.storage.enabled = false # Set to true to enable SSD storage
ubsio.disk.path = /dev/nvmexn1:/dev/nvmexn2p1:/dev/loopX
ubsio.mem.size_in_gb = 10
ubsio.standalone.device_count = 8
ubsio.standalone.force_new_disk = true
关键要点:
| 参数 | 描述 |
|---|---|
ock.mmc.meta_service_url |
P节点和D节点应配置相同的MetaService端点。 |
ock.mmc.local_service.config_store_url |
其值必须与mmc-meta.conf中的ock.mmc.meta_service.config_store_url相同。 |
ock.mmc.local_service.world_size |
支持的LocalService最大数量,包括将来会添加的服务。 |
ock.mmc.local_service.protocol |
推荐的协议为device_rdma(设备上的RDMA,当设备RoCE可用时支持A2和A3,推荐用于A2)和device_sdma(设备上的SDMA,当HCCS可用时支持A3,推荐用于A3)。对于Ascend 950 Products UB场景,设置为device_urma。对于Ascend 950 Products UBOE场景,设置为device_uboe。有关其他支持协议的详细信息,请参阅MemCache LocalService配置文件。 |
ock.mmc.local_service.dram.size |
每个die分配的DRAM大小。例如,在A3上,要分配640GB作为KV池,此参数应设置为640/16=40GB。当HCCS可用时,A3设置为0GB。 |
ock.mmc.local_service.max.dram.size |
所有本地进程中ock.mmc.local_service.dram.size的最大值,当各rank贡献不同大小的DRAM时必需。 |
ock.mmc.local_service.storage.enabled |
设置为true以启用SSD缓存。 |
ubsio.disk.path |
启用SSD缓存时必须配置。直接指定目标SSD块设备、分区或loop设备。配置的设备必须由UBS IO独占使用,且不得有任何挂载点。 多个路径用冒号(:)分隔。不建议使用/dev/sdx。 |
ubsio.mem.size_in_gb |
每个进程的UBS IO内存池大小(以GB为单位)。推荐值为10。支持的范围是0到3072之间的整数;SSD缓存要求每个进程至少5 GB。总分配量不得超过为操作系统、vLLM和Memcache DRAM池预留内存后剩余的节点内存。 |
ubsio.standalone.device_count |
ock.mmc.local_service.dram.size不为0的本地服务数量。 |
ubsio.standalone.force_new_disk |
控制UBS IO是将配置的SSD设备初始化为新磁盘,还是恢复其现有元数据。设置为true,因为当前版本不支持故障恢复。 |
步骤3.4:运行Memcache MetaService¶
作为独立进程,MetaService只需在一个节点上启动。
启动 MetaService 服务。
export MMC_META_CONFIG_PATH={INSTALL_PATH}/memcache_hybrid/config/mmc-meta.conf
python -c "from memcache_hybrid import MetaService; MetaService.main()"
步骤3.5:PD分离场景¶
步骤3.5.1:运行prefill节点和decode节点¶
使用 MultiConnector 同时利用 MooncakeConnectorV1 和 AscendStoreConnector。MooncakeConnectorV1 执行 kv_transfer,而 AscendStoreConnector 启用 KV Cache Pool
800I A2/800T A2/800I A3/800T A3/950PR Ascend 950 Products/950DT Ascend 950 Products系列¶
run_prefill.sh/run_decode.sh:
#!/bin/bash
# prefill / decode
ROLE="prefill"
# A2 (800I/800T A2) or A3 (800I/800T A3) or A5 (950PR/950DT)
HARDWARE_SERIES="A2"
# Link type: ROCE or HCCS in A3 series.
LINK_TYPE="ROCE"
LOCAL_IP="xx.xx.xx.xx"
NIC_NAME="xxxxxx"
MODEL_PATH="xxxxxxx/Qwen3-32B"
SERVED_MODEL_NAME="qwen3"
DATA_PARALLEL_SIZE=1
TENSOR_PARALLEL_SIZE=8
export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
# parameters required for kv pool and memcache
export PYTHONHASHSEED=0
export MMC_LOCAL_CONFIG_PATH={INSTALL_PATH}/memcache_hybrid/config/mmc-local.conf
export LD_LIBRARY_PATH={INSTALL_PATH}/memcache_hybrid/lib:${PYTHON_LIB_DIR}:${LD_LIBRARY_PATH}
if [ "$ROLE" == "prefill" ]; then
KV_ROLE="kv_producer"
KV_PORT="20001"
LOOKUP_RPC_PORT="0"
else
KV_ROLE="kv_consumer"
KV_PORT="20002"
LOOKUP_RPC_PORT="1"
fi
echo "Starting vLLM on Series: $HARDWARE_SERIES, Role: $ROLE"
rm -rf /root/ascend/log/*
rm -rf ./connector.log
# For detailed parameter descriptions, see 5.1 Environment Variables Description
if [ "$HARDWARE_SERIES" == "A2" ] || { [ "$HARDWARE_SERIES" == "A3" ] && [ "$LINK_TYPE" == "ROCE" ]; }; then
echo 200000 > /proc/sys/vm/nr_hugepages
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_ROCE_ENABLE=1
elif [ "$HARDWARE_SERIES" == "A3" ] && [ "$LINK_TYPE" == "HCCS" ]; then
export ACL_OP_INIT_MODE=1
export ASCEND_ENABLE_USE_FABRIC_MEM=1
elif [ "$HARDWARE_SERIES" == "A5" ]; then
# A5 UBOE
export ASCEND_GLOBAL_RESOURCE_CONFIG='{"comm_resource_config.protocol_desc":["uboe:device"]}'
# A5 UB
export ASCEND_LOCAL_COMM_RES='{"version":"1.3"}'
else
echo "Error: Invalid HARDWARE_SERIES. Set to 'A2', 'A3', or 'A5'."
exit 1
fi
source /usr/local/Ascend/ascend-toolkit/set_env.sh
source /usr/local/Ascend/nnal/atb/set_env.sh
KV_CONFIG='{
"kv_connector": "MultiConnector",
"kv_role": "'$KV_ROLE'",
"kv_connector_extra_config": {
"connectors": [
{
"kv_connector": "MooncakeConnectorV1",
"kv_role": "'$KV_ROLE'",
"kv_port": "'$KV_PORT'",
"kv_connector_extra_config": {
"prefill": {
"dp_size": '$DATA_PARALLEL_SIZE',
"tp_size": '$TENSOR_PARALLEL_SIZE'
},
"decode": {
"dp_size": '$DATA_PARALLEL_SIZE',
"tp_size": '$TENSOR_PARALLEL_SIZE'
}
}
},
{
"kv_connector": "AscendStoreConnector",
"kv_role": "'$KV_ROLE'",
"kv_connector_extra_config": {
"backend": "memcache",
"lookup_rpc_port": "'$LOOKUP_RPC_PORT'",
"use_layerwise":false # Set to true only on the Prefill node to enable layerwise
}
}
]
}
}'
CMD_ARGS=(
--model "$MODEL_PATH"
--served-model-name "$SERVED_MODEL_NAME"
--trust-remote-code
--enforce-eager
--data-parallel-size "$DATA_PARALLEL_SIZE"
--tensor-parallel-size "$TENSOR_PARALLEL_SIZE"
--port 30050
--max-num_seqs 20
--max-model-len 32768
--max-num-batched-tokens 16384
--gpu-memory-utilization 0.9
--kv-transfer-config "$KV_CONFIG"
)
python -m vllm.entrypoints.openai.api_server "${CMD_ARGS[@]}" > log_${ROLE}.log 2>&1
echo "vLLM started. Log file: log_${ROLE}.log"
步骤3.5.2:启动proxy_server¶
请参阅MooncakeStore部署部分中的启动proxy_server。
步骤3.5.3:运行推理¶
请参阅MooncakeStore部署部分中的运行推理。
步骤3.6:PD混合场景¶
步骤3.6.1:运行混合部署脚本¶
800I A2/800T A2/800I A3/800T A3/950PR Ascend 950 Products/950DT Ascend 950 Products系列¶
Run_pd_mix.sh:
#!/bin/bash
# A2 (800I/800T A2) or A3 (800I/800T A3) or A5 (950PR/950DT)
HARDWARE_SERIES="A2"
# Link type: ROCE or HCCS in A3 series.
LINK_TYPE="ROCE"
LOCAL_IP="xx.xx.xx.xx"
NIC_NAME="xxxxxx"
MODEL_PATH="xxxxxxx/Qwen3-32B"
SERVED_MODEL_NAME="qwen3"
DATA_PARALLEL_SIZE=1
TENSOR_PARALLEL_SIZE=8
export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
# parameters required for kv pool and memcache
export PYTHONHASHSEED=0
export MMC_LOCAL_CONFIG_PATH={INSTALL_PATH}/memcache_hybrid/config/mmc-local.conf
export LD_LIBRARY_PATH={INSTALL_PATH}/memcache_hybrid/lib:${PYTHON_LIB_DIR}:${LD_LIBRARY_PATH}
echo "Starting vLLM on Series: $HARDWARE_SERIES"
rm -rf /root/ascend/log/*
rm -rf ./connector.log
# For detailed parameter descriptions, see 5.1 Environment Variables Description
if [ "$HARDWARE_SERIES" == "A2" ] || { [ "$HARDWARE_SERIES" == "A3" ] && [ "$LINK_TYPE" == "ROCE" ]; }; then
echo 200000 > /proc/sys/vm/nr_hugepages
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_ROCE_ENABLE=1
elif [ "$HARDWARE_SERIES" == "A3" ] && [ "$LINK_TYPE" == "HCCS" ]; then
export ACL_OP_INIT_MODE=1
export ASCEND_ENABLE_USE_FABRIC_MEM=1
elif [ "$HARDWARE_SERIES" == "A5" ]; then
# A5 UBOE
export ASCEND_GLOBAL_RESOURCE_CONFIG='{"comm_resource_config.protocol_desc":["uboe:device"]}'
# A5 UB
export ASCEND_LOCAL_COMM_RES='{"version":"1.3"}'
else
echo "Error: Invalid HARDWARE_SERIES. Set to 'A2', 'A3', or 'A5'."
exit 1
fi
source /usr/local/Ascend/ascend-toolkit/set_env.sh
source /usr/local/Ascend/nnal/atb/set_env.sh
KV_CONFIG='{
"kv_connector": "AscendStoreConnector",
"kv_role": "kv_both",
"kv_connector_extra_config": {
"backend": "memcache",
"lookup_rpc_port": "0",
"use_layerwise":false # Set to true to enable layerwise
}
}'
CMD_ARGS=(
--model "$MODEL_PATH"
--served-model-name "$SERVED_MODEL_NAME"
--trust-remote-code
--enforce-eager
--data-parallel-size "$DATA_PARALLEL_SIZE"
--tensor-parallel-size "$TENSOR_PARALLEL_SIZE"
--port 30050
--max-num_seqs 20
--max-model-len 32768
--max-num-batched-tokens 16384
--gpu-memory-utilization 0.9
--kv-transfer-config "$KV_CONFIG"
)
python -m vllm.entrypoints.openai.api_server "${CMD_ARGS[@]}" > log_mix.log 2>&1
echo "vLLM started. Log file: log_mix.log"
步骤3.6.2:运行推理¶
请参阅MooncakeStore部署部分中的运行推理。
步骤3.7:MemCache与vLLM分离部署¶
此部署模式在不同的进程中运行MemCache和vLLM。它与vLLM PD分离不同。在默认的共置模式下,vLLM在KV连接器初始化MemCache之前加载模型权重。因此,MemCache可能无法从剩余可用空间中预留足够的内存。在vLLM之前启动独立的MemCache进程,可以使MemCache预留更大的内存池。此模式目前仅支持A3 HCCS场景。
准备两个连接和协议设置相同的LocalService配置文件。vLLM进程使用的配置不贡献DRAM:
# mmc-local.conf used by the vLLM process
ock.mmc.local_service.dram.size = 0GB
ock.mmc.local_service.max.dram.size = 1024GB
独立MemCache进程使用的配置指定了要贡献的DRAM大小:
# mmc-local-standalone.conf used by the standalone MemCache process
ock.mmc.local_service.dram.size = 600GB
ock.mmc.local_service.max.dram.size = 1024GB
上述大小仅为示例。请根据可用内存进行调整,并设置ock.mmc.local_service.max.dram.size以容纳LocalService进程使用的最大dram.size。
按以下顺序部署服务:
- 按上述说明启动MetaService。
- 在启动vLLM之前,在每个节点上使用
mmc-local-standalone.conf启动独立的MemCache进程。这些进程将配置的DRAM贡献给内存池。 - 等待每个节点上的独立MemCache进程报告初始化成功。
- 将
MMC_LOCAL_CONFIG_PATH设置为mmc-local.conf,然后按上述说明启动vLLM推理进程。vLLM进程中的MemCache连接到现有内存池,而不贡献额外的DRAM。
有关独立的MemCache启动脚本和完整的A3部署流程,请参阅Memcache + vLLM + A3。
步骤3.8:启用Memcache SSD缓存¶
步骤3.8.1:配置¶
有关详细配置,请参阅配置memcache配置文件,并且必须查看5.2.4。
步骤3.8.2:MemCache与vLLM分离部署时启用SSD¶
请参考以下配置:
mmc-local.conf:
ock.mmc.meta_service_url = tcp://xx.xx.xx.xx:5000
ock.mmc.local_service.config_store_url = tcp://xx.xx.xx.xx:6000
ock.mmc.log_level = info
ock.mmc.local_service.world_size = 256
ock.mmc.local_service.protocol = device_sdma
ock.mmc.local_service.dram.size = 0GB
ock.mmc.local_service.max.dram.size = 1024GB
mmc-local-standalone.conf:
ock.mmc.meta_service_url = tcp://xx.xx.xx.xx:5000
ock.mmc.local_service.config_store_url = tcp://xx.xx.xx.xx:6000
ock.mmc.log_level = info
ock.mmc.local_service.world_size = 256
ock.mmc.local_service.protocol = device_sdma
ock.mmc.local_service.dram.size = 600GB
ock.mmc.local_service.max.dram.size = 1024GB
# SSD feature related parameters below
ock.mmc.local_service.storage.enabled = true
ubsio.disk.path = /dev/nvmexn1:/dev/nvmexn2p1:/dev/loopX
ubsio.mem.size_in_gb = 50
ubsio.standalone.device_count = 1
ubsio.standalone.force_new_disk = true
步骤3.8.3:UBS IO内存池大小设置¶
调整推荐值时,将UBS IO可用的节点内存除以启用DRAM的本地服务数量,向下取整,并将结果上限设为3072,即可计算出每个进程允许的最大值:
maximum ubsio.mem.size_in_gb = min(3072, floor(available node memory for UBS IO (GB) / number of DRAM-enabled local services))
例如,如果UBS IO可用200 GB,且有四个本地服务启用了DRAM,则每个进程的上限为50 GB,因此推荐值ubsio.mem.size_in_gb = 10是有效的。如果计算出的上限小于5,请释放更多节点内存或减少启用DRAM的本地服务数量。
对于MemCache分离部署的场景,建议为单个进程配置50 GB。在其他场景中,建议配置10 GB。如果要使用L2.5内存缓存能力,请在上述限制内增加ubsio.mem.size_in_gb,并相应调整ubsio.wcache.evict_water_level。
有关磁盘配置、驱逐水位线及其他UBS IO参数,请参阅DRAM + SSD多级池化配置指南。
4. 使用Yuanrong作为KV池后端的示例¶
- 软件:
- 在所有节点上安装
openyuanrong-datasystem(必须可导入yr.datasystem)。
- 在所有节点上安装
步骤4.1:安装Yuanrong Datasystem¶
pip install openyuanrong-datasystem
python -c "import yr.datasystem; print('Yuanrong Datasystem is ready')"
dscli --version
如果预构建的软件包与您环境中的 CANN 或 Ascend 驱动版本不匹配,请在 vLLM Ascend 镜像中从源码构建 Yuanrong Datasystem。请遵循 Yuanrong Datasystem 的官方构建说明: https://atomgit.com/openeuler/yuanrong-datasystem
步骤4.2:选择服务发现后端¶
Yuanrong Datasystem 支持使用 Coordinator 或 etcd 进行服务发现。 请从以下方案中选择一种,不要为同一个 Worker 同时配置两种后端。
方案一:启动 Coordinator¶
使用 Yuanrong Datasystem 自带的 Coordinator 进行服务发现,无需额外安装和维护 etcd 服务。请在所有 Datasystem Worker 均可访问的地址上启动一个 Coordinator:
COORDINATOR_ADDRESS="<coordinator_ip>:31511"
dscli start -c \
--coordinator_address "${COORDINATOR_ADDRESS}"
将 <coordinator_ip> 替换为运行 Coordinator 的节点 IP。仅单节点部署可以使用
127.0.0.1。启动成功后会输出 Start coordinator service ... success。
进行最简单的单节点试用时,可以用一条命令同时启动 Coordinator 和 Worker。
使用该命令后,请跳过下方单独启动 Worker 的步骤,并将 yuanrong.json 中的
worker_addr 设置为 127.0.0.1:31501:
dscli start -a \
--coordinator_address "127.0.0.1:31511" \
--worker_address "127.0.0.1:31501" \
--shared_memory_size_mb 4096
方案二:启动 etcd¶
以下示例启动一个单节点 etcd 集群:
ETCD_VERSION="v3.5.12"
ETCD_IP="127.0.0.1"
if [ "$(uname -m)" = "aarch64" ]; then
ETCD_ARCH="linux-arm64"
else
ETCD_ARCH="linux-amd64"
fi
wget https://github.com/etcd-io/etcd/releases/download/${ETCD_VERSION}/etcd-${ETCD_VERSION}-${ETCD_ARCH}.tar.gz
tar -xvf etcd-${ETCD_VERSION}-${ETCD_ARCH}.tar.gz
cd etcd-${ETCD_VERSION}-${ETCD_ARCH}
sudo cp etcd etcdctl /usr/local/bin/
etcd \
--name etcd-single \
--data-dir /tmp/etcd-data \
--listen-client-urls http://0.0.0.0:2379 \
--advertise-client-urls http://${ETCD_IP}:2379 \
--listen-peer-urls http://0.0.0.0:2380 \
--initial-advertise-peer-urls http://${ETCD_IP}:2380 \
--initial-cluster etcd-single=http://${ETCD_IP}:2380 &
etcdctl --endpoints "${ETCD_IP}:2379" put key "value"
etcdctl --endpoints "${ETCD_IP}:2379" get key
多节点部署时,请将 ETCD_IP 设置为所有 Worker 均可访问的地址,
不要使用 127.0.0.1。
对于生产环境,请参考官方 etcd 集群 文档:https://etcd.io/docs/v3.7/op-guide/clustering/
多节点部署¶
在每个节点上安装 Yuanrong Datasystem。每个节点运行一个 Datasystem Worker,
并使用唯一且可访问的 worker_address。所有 Worker 必须使用相同的服务发现后端
和后端地址。
本节命令以 4 GiB 共享内存作为最小示例。高吞吐部署请改用下一节中经过调优的 Worker 参数;不要在同一地址上重复启动 Worker。
使用 Coordinator 进行多节点部署¶
在所有 Worker 均可访问的节点上启动一个 Coordinator。例如,Coordinator 节点地址为
192.168.1.10 时:
然后在每个节点上启动一个 Worker。将 WORKER_IP 设置为当前节点自身的 IP,
并确保所有节点的 COORDINATOR_ADDRESS 完全相同:
# Run on every Worker node.
WORKER_IP="<this_node_ip>"
COORDINATOR_ADDRESS="192.168.1.10:31511"
dscli start -w \
--worker_address "${WORKER_IP}:31501" \
--coordinator_address "${COORDINATOR_ADDRESS}" \
--shared_memory_size_mb 4096
本示例只使用一个 Coordinator,不提供 Coordinator 高可用。生产环境如需控制面高可用,
请使用静态 Raft peers 部署多个 Coordinator,为每个 Coordinator 配置唯一的
coordinator_address 和 coordinator_raft_data_dir,并使用相同的
coordinator_raft_initial_peers 列表。详情参见
Yuanrong Datasystem dscli 文档。
使用 etcd 进行多节点部署¶
按照上一节启动所有 Worker 均可访问的 etcd 服务或集群,然后在每个节点上启动一个
Worker。将 WORKER_IP 设置为当前节点自身的 IP,并确保所有节点的
ETCD_ADDRESS 完全相同:
# Run on every Worker node.
WORKER_IP="<this_node_ip>"
ETCD_ADDRESS="192.168.1.10:2379"
dscli start -w \
--worker_address "${WORKER_IP}:31501" \
--etcd_address "${ETCD_ADDRESS}" \
--shared_memory_size_mb 4096
两种后端均需注意:
- 多节点部署时,不要使用
127.0.0.1或0.0.0.0作为 Worker 地址。其他 Worker 必须能够连接到该广播 IP。 - 放通 Coordinator 端口(
31511)或 etcd 客户端端口(2379),以及每个 Worker 的端口(本示例中为31501)。 - 在每个节点上,将
yuanrong.json中的worker_addr设置为该节点本机的WORKER_IP:31501,因此各节点的配置文件并不完全相同。 - 所有 vLLM 实例必须使用相同的
PYTHONHASHSEED。
步骤4.3:启动Datasystem Worker¶
使用 dscli 在每个节点上启动一个 Datasystem 工作进程。以下
配置是针对高吞吐量 KV Pool 工作负载的推荐起点:
本指南中的 Worker 示例使用 Coordinator。若改用 etcd,请在每条 Worker 命令中将
--coordinator_address "${COORDINATOR_ADDRESS}" 替换为
--etcd_address "${ETCD_ADDRESS}"。
COORDINATOR_ADDRESS="<coordinator_ip>:31511"
ETCD_ADDRESS="<etcd_ip>:2379"
WORKER_IP="<worker_ip>"
WORKER_LOG_DIR="/var/log/yuanrong/worker"
sudo mkdir -p "${WORKER_LOG_DIR}"
sudo chown "$(id -u):$(id -g)" "${WORKER_LOG_DIR}"
dscli start -w \
--worker_address "${WORKER_IP}:31501" \
--coordinator_address "${COORDINATOR_ADDRESS}" \
--log_dir "${WORKER_LOG_DIR}" \
--shared_memory_size_mb 40960 \
--arena_per_tenant 1 \
--enable_huge_tlb true \
--enable_fallocate false \
--rpc_thread_num 64 \
--oc_thread_num 64 \
--enable_worker_worker_batch_get true \
--sc_regular_socket_num 0 \
--sc_stream_socket_num 0
--worker_address 的值稍后会在 yuanrong.json 中作为 worker_addr 使用,
因此同一节点上的主机和端口必须保持一致。每个 Worker 只能配置一种协调后端;
使用 Coordinator 时,不要再设置 etcd_address 或 metastore_address。
上述调优参数具有以下效果:
| 参数 | 描述 |
|---|---|
log_dir |
设置Datasystem工作进程日志目录。启动前创建该目录并授予工作进程写入权限。 |
arena_per_tenant=1 |
每个租户使用一个共享内存区域,作为内存和文件描述符使用的保守起点。 |
enable_huge_tlb=true |
使用HugeTLB页支持worker共享内存。在启动worker之前,预留足够的2 MiB大页。 |
enable_fallocate=false |
禁用共享内存文件的fallocate;将此设置与上述HugeTLB配置一起使用。 |
rpc_thread_num=64 |
设置RPC/ZMQ服务的并发数。 |
oc_thread_num=64 |
设置对象缓存业务线程池大小。 |
enable_worker_worker_batch_get=true |
启用 Datasystem 工作节点之间的批量对象缓存读取。 |
sc_regular_socket_num=0, sc_stream_socket_num=0 |
禁用流缓存服务。两个值都必须大于零才能启用;当 KV Pool 不使用流缓存时,请将其保持为零。 |
对于shared_memory_size_mb=40960,至少预留20480个2 MiB大页,并在启动worker之前验证它们可用:
工作进程日志(包括通常以 datasystem_worker 为基本名称的文件)会写入
--log_dir 目录。请使用绝对路径,以确保日志位置不依赖于工作进程的
当前目录。
这些线程数是调优起点,而非通用默认值。请根据可用的 CPU 核心数和测量的请求
吞吐量进行调整。由于 -w 会消耗剩余的命令行参数,请将任何 dscli start
选项(如 --timeout)放在 -w 之前。
更多参数,请参阅元戎 Datasystem 官方网站上的 dscli 使用文档:
https://atomgit.com/openeuler/yuanrong-datasystem
不再需要 Worker 时将其停止。请在所有 Worker 均已停止后,再停止所选的服务发现 后端。对于独立的 etcd 集群,请遵循其常规集群运维流程。
dscli stop --worker_address "${WORKER_IP}:31501"
# Coordinator option only:
dscli stop --coordinator_address "${COORDINATOR_ADDRESS}"
步骤4.4:环境变量配置¶
在启动 vLLM 之前,在每个节点上设置以下环境变量:
| 变量 | 是否必需 | 默认值 | 描述 |
|---|---|---|---|
PYTHONHASHSEED |
是 | 0 |
所有节点必须保持一致,以确保生成统一的哈希值。 |
DS_WORKER_ADDR |
是 | 不适用 | Datasystem worker地址,格式为<host>:<port>。必须与本地dscli start --worker_address的值匹配。 |
DATASYSTEM_CLIENT_LOG_DIR |
否 | ~/.datasystem/logs |
vLLM 进程创建的元戎客户端 SDK 日志目录。请使用与工作节点日志不同的目录。 |
DS_ENABLE_EXCLUSIVE_CONNECTION |
否 | 0 |
传递给Yuanrong HeteroClient.enable_exclusive_connection。当部署需要时,使用1启用独占连接模式。 |
DS_ENABLE_REMOTE_H2D |
否 | 0 |
传递给Yuanrong HeteroClient.enable_remote_h2d。仅在满足以下Remote H2D要求后使用1。 |
export PYTHONHASHSEED=0
export DS_WORKER_ADDR="${WORKER_IP}:31501"
export DATASYSTEM_CLIENT_LOG_DIR="/var/log/yuanrong/client"
export DS_ENABLE_EXCLUSIVE_CONNECTION=0
export DS_ENABLE_REMOTE_H2D=0
mkdir -p "${DATASYSTEM_CLIENT_LOG_DIR}"
请在启动 vLLM 之前设置 DATASYSTEM_CLIENT_LOG_DIR,因为元戎
客户端在日志初始化期间会读取该变量。客户端 SDK 日志(通常以 ds_client
为基本名称)会写入此目录。
步骤4.4.1:元戎客户端配置(yuanrong.json)¶
由YR_CONFIG_PATH指向的yuanrong.json文件包含Yuanrong客户端连接选项:
{
"worker_addr": "1.2.3.4:31501",
"connect_timeout_ms": 9000,
"request_timeout_ms": 0,
"get_sub_timeout_ms": 0,
"enable_remote_h2d": false,
"remote_h2d_transport_backend": "HIXL",
"enable_fabric_mem": false,
"enable_dev_mem_pregister": false,
"use_layerwise": false
}
worker_addr:数据系统工作进程地址,格式为<主机>:<端口>。此值必须与本地dscli start --worker_address的值匹配。
connect_timeout_ms:Yuanrong客户端建立连接的最大时间(毫秒)。Yuanrong要求该值为大于或等于500的整数。默认值为9000。
request_timeout_ms:Yuanrong客户端请求的超时时间(毫秒)。默认值为0,保留Yuanrong SDK使用connect_timeout_ms作为请求超时时间的行为。设置正值可独立控制请求超时时间。
get_sub_timeout_ms:每次mget_h2d_from_multi_buffers请求等待对象就绪的最大时间(毫秒)。0表示不允许等待。默认值为0。Yuanrong在Get请求运行时验证此值。该值可以大于request_timeout_ms;Yuanrong的Get路径会扩展该调用的RPC超时时间,以适应配置的对象就绪等待。
enable_remote_h2d:传递给Yuanrong HeteroClient.enable_remote_h2d。仅在满足以下远程H2D要求后才使用true。默认值为false。
remote_h2d_transport_backend:vLLM侧传输名称,Yuanrong后端根据它决定是否预注册设备内存。HIXL(默认)用于HIXL HCCS(涵盖buffer-pool、HIXL RoCE直连和FabricMem子模式);P2P_TRANSFER用于通过RoCE的数据系统P2P-Transfer。必须与工作进程侧的--remote_h2d_link_type对应(有关HIXL ↔ HCCS / P2P_TRANSFER ↔ ROCE的映射,请参见下面的远程H2D链路参数表)。在HIXL下,后端预注册设备内存,除非enable_fabric_mem为true;在P2P_TRANSFER下,后端跳过预注册。
enable_fabric_mem:选择HIXL FabricMem模式,其中HIXL OPTION_ENABLE_USE_FABRIC_MEM自动处理Fabric可共享句柄交换,后端跳过客户端侧的pre_register_device_memory。仅在remote_h2d_transport_backend="HIXL"时有意义。默认值为false。FabricMem需要数据系统侧的支持(HIXL FabricMem构建和相应的数据系统环境变量);在启用此标志之前,请查阅数据系统文档。
enable_dev_mem_pregister:客户端设备内存预注册(pre_register_device_memory)的主开关。默认值为false,因此后端默认不预注册设备缓冲区指针。要实际预注册,此标志必须为true且自动条件必须成立:enable_remote_h2d=true、remote_h2d_transport_backend="HIXL"且enable_fabric_mem=false。在P2P_TRANSFER或FabricMem模式下,无论此开关如何设置,始终跳过预注册。对于需要客户端设备内存注册的HIXL HCCS远程H2D部署,请将此设置为true。
use_layerwise:必须与 kv_connector_extra_config.use_layerwise 保持一致,默认为 false。为 false 时,非逐层查询由 TP0 Worker 执行,因此调度器侧的 Yuanrong 存储会跳过初始化。为 true 时,调度器会初始化一个仅用于元数据且禁用远程 H2D 的 Yuanrong 客户端,因此不会创建 HIXL engine。
步骤4.4.2:远程 H2D 要求¶
仅在元戎 Datasystem 部署中启用并验证了远程主机到设备传输时,才将enable_remote_h2d 设为 true:
- 在启动工作进程之前,预留足够的 2 MiB HugeTLB 页面。对于 40 GiB 共享内存,至少预留 20480 个 2 MiB 大页面。
- 以启用远程 H2D 的方式启动每个数据系统工作进程。工作进程启动命令必须包含
--remote_h2d_device_ids、--enable_huge_tlb true、--arena_per_tenant 1和--enable_fallocate false。建议使用多个可用的 NPU 设备 ID,例如在 8-NPU 节点上使用"0,1,2,3,4,5,6,7"。
dscli start -w \
--worker_address "${WORKER_IP}:31501" \
--coordinator_address "${COORDINATOR_ADDRESS}" \
--log_dir "/var/log/yuanrong/worker" \
--shared_memory_size_mb 40960 \
--arena_per_tenant 1 \
--enable_huge_tlb true \
--enable_fallocate false \
--rpc_thread_num 64 \
--oc_thread_num 64 \
--enable_worker_worker_batch_get true \
--sc_regular_socket_num 0 \
--sc_stream_socket_num 0 \
--remote_h2d_device_ids "0,1,2,3,4,5,6,7"
对于HIXL HCCS链路(具有HCCS可达性的Atlas A3),设置--remote_h2d_link_type "HCCS"和HIXL buffer-pool参数。--worker_address中的IP也用作HIXL端点IP,因此请使用可达地址,而不是127.0.0.1或0.0.0.0。HIXL RoCE直连模式是HCCS的子模式,由两侧的HCCL_INTRA_ROCE_ENABLE=1选择,并且还需要可达的RoCE链路:
dscli start --interleave 0-7 -w \
--worker_address "${WORKER_IP}:31501" \
--coordinator_address "${COORDINATOR_ADDRESS}" \
--log_dir "/var/log/yuanrong/worker" \
--shared_memory_size_mb 40960 \
--arena_per_tenant 1 \
--enable_huge_tlb true \
--enable_fallocate false \
--rpc_thread_num 64 \
--oc_thread_num 64 \
--enable_worker_worker_batch_get true \
--sc_regular_socket_num 0 \
--sc_stream_socket_num 0 \
--remote_h2d_device_ids "0,1,2,3,4,5,6,7" \
--remote_h2d_link_type "HCCS" \
--remote_h2d_hccs_buffer_pool "4:8"
远程H2D链路参数¶
| 参数 | 默认值 | 描述 |
|---|---|---|
remote_h2d_device_ids |
空 | 非空时启用工作进程侧RH2D。逗号分隔的设备ID,例如"0,1,2,3,4,5,6,7"。 |
remote_h2d_link_type |
ROCE |
链路类型,区分大小写。ROCE用于通过RoCE的P2P-Transfer;HCCS用于HIXL HCCS(涵盖buffer-pool、HIXL RoCE直连和FabricMem子模式)。必须与yuanrong.json中客户端侧的remote_h2d_transport_backend对应(ROCE ↔ P2P_TRANSFER,HCCS ↔ HIXL)。对于HCCS,客户端进程还必须在启动vLLM之前导出DS_RH2D_LINK_TYPE=HCCS(后端不会自动导出);ROCE是数据系统的默认值,无需设置环境变量。 |
remote_h2d_hccs_buffer_pool |
4:8 |
HIXL buffer-pool参数<数量>:<大小>,仅在remote_h2d_link_type=HCCS时使用。在HIXL RoCE直连模式(HCCL_INTRA_ROCE_ENABLE=1)下忽略。 |
- 确保远融远程 H2D 所需的 NPU 驱动、固件和 CANN 工具包已安装且对工作进程可见。在容器中,挂载 Ascend 驱动路径、
npu-smi、hccn_tool、/etc/hccn.conf、/etc/ascend_install.info以及所需的/dev/davinci*设备。 - 在启用客户端标志之前,验证 NPU 和 RoCE 环境:
# Check the current 2 MiB HugeTLB page size, total count, and free count.
grep -E "HugePages_Total|HugePages_Free|Hugepagesize" /proc/meminfo
# Optional: check 2 MiB HugeTLB pages on each NUMA node.
for node in /sys/devices/system/node/node*/hugepages/hugepages-2048kB; do
echo "$node total=$(cat "$node/nr_hugepages") free=$(cat "$node/free_hugepages")"
done
# Check that NPU devices and the driver are visible to the worker environment.
npu-smi info
# Check that the NPU topology is visible.
npu-smi info -t topo
# Check optical module detection on the selected local NPU.
hccn_tool -i <local_npu_id> -optical -g
# Check RoCE physical link status. The expected link status is UP.
for i in {0..7}; do hccn_tool -i $i -link -g; done
# Check the selected NPU IP address and reachability to the remote NPU.
hccn_tool -i <local_npu_id> -ip -g
hccn_tool -i <local_npu_id> -ping -g address <remote_npu_ip>
如果这些检查失败,请保持 DS_ENABLE_REMOTE_H2D=0 并使用默认的数据系统传输路径。
步骤 4.5:使用远融后端运行 AscendStoreConnector¶
使用 AscendStoreConnector 并设置 backend: "yuanrong":
python3 -m vllm.entrypoints.openai.api_server \
--model /xxxxx/Qwen2.5-7B-Instruct \
--port 8100 \
--trust-remote-code \
--enforce-eager \
--no-enable-prefix-caching \
--tensor-parallel-size 1 \
--data-parallel-size 1 \
--max-model-len 10000 \
--block-size 128 \
--max-num-batched-tokens 4096 \
--kv-transfer-config \
'{
"kv_connector": "AscendStoreConnector",
"kv_role": "kv_both",
"kv_load_failure_policy": "recompute",
"kv_connector_extra_config": {
"lookup_rpc_port": "1",
"backend": "yuanrong",
"use_layerwise": false
}
}'
lookup_rpc_port 是池化调度进程与工作进程之间使用的 RPC 端口。
每个实例必须使用唯一的端口值。
注意事项¶
- 远融后端在调用数据系统之前会规范化 KV 键。支持的最长 1024 字节的 ASCII 键会被保留。更长的键或包含不支持字符的键会被重写为最多 1024 个字符并附加哈希后缀,因此在调试后端存储时不要依赖原始键字符串。
- 远融后端不需要额外的缓冲区预注册步骤。该后端在构建 blob 列表时直接使用设备指针。
5. 附录和常见问题¶
5.1. 环境变量说明¶
本节介绍 Mooncake 和 Memcache 后端所需的硬件特定环境变量。
| 硬件 | 依赖项 | 导出命令 | 描述 |
|---|---|---|---|
| 950PR/DT Ascend 950 产品系列 | HDK >=25.6 搭配 mooncake >= v0.3.11 CANN >= 9.1.0 |
# UBOEexport ASCEND_GLOBAL_RESOURCE_CONFIG='{"comm_resource_config.protocol_desc":["uboe:device"]}' # UB export ASCEND_LOCAL_COMM_RES='{"version":"1.3"}' |
根据要使用的通信协议配置所需的环境变量。 |
| 800 I/T A3系列 | HDK >= 26.0 或HDK >= 25.5配合mooncake >= v0.3.11 CANN >= 9.0.0 灵衢计算网络 >= 1.5 |
export ASCEND_ENABLE_USE_FABRIC_MEM=1 |
推荐。启用统一内存地址直传方案。使用SSD卸载时,请参阅Fabric内存大小对齐——内存大小必须与1GB对齐。 |
| 800 I/T A2系列 | 建议HDK >= 25.5 | export HCCL_INTRA_ROCE_ENABLE=1 |
800 I/T A2系列直传方案所需 |
5.2. Memcache 先决条件¶
5.2.1. 检查内存¶
使用 free -h 检查内存。如果过多的缓存影响 KV 缓存池大小,请清理缓存并对内存进行碎片整理:
# Release pagecache/dentry/inode to free contiguous physical memory
echo 3 > /proc/sys/vm/drop_caches
# Trigger memory compaction to reduce fragmentation
echo 1 > /proc/sys/vm/compact_memory
5.2.2. (仅限 A3)扫描可用内存¶
通过运行脚本扫描环境中的可用内存。脚本地址:mem_scan.py。执行命令:
MemFabric 使用 2MB 和 1GB 大页面。脚本默认按 1GB 规格扫描。要扫描 2MB 大页面的可用内存,请运行:
5.2.3. (仅限 Ascend 950 产品)禁用签名验证 + 在容器中挂载关键路径 + 安装内核包¶
步骤 1: 在裸机上禁用 HDK 签名验证(每台机器只需执行一次):
for i in {0..7}; do npu-smi set -t custom-op-secverify-enable -i $i -d 1; done;
for i in {0..7}; do npu-smi set -t custom-op-secverify-mode -i $i -d 0; done;
步骤 2: 参考以下 docker run 命令启动容器。确保 /usr/bin/urma_admin、/lib/route.conf、/etc/hccl_rootinfo.json 已挂载到容器中:
docker run -u root -it -d --name ${NAME} --net=host --privileged=true \
--device=/dev/davinci_manager --device=/dev/hisi_hdc --device=/dev/ummu --device=/dev/uburma \
--device=/dev/davinci0 \
--device=/dev/davinci1 \
--device=/dev/davinci2 \
--device=/dev/davinci3 \
--device=/dev/davinci4 \
--device=/dev/davinci5 \
--device=/dev/davinci6 \
--device=/dev/davinci7 \
-v /usr/bin/urma_admin:/usr/bin/urma_admin \
-v /lib/route.conf:/lib/route.conf \
-v /root/host:/root/host \
-v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \
-v /usr/local/sbin:/usr/local/sbin \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /var/log/npu/:/usr/slog \
-v /mnt:/mnt \
-v /etc/hccn.conf:/etc/hccn.conf \
-v /usr/lib64:/usr/lib64 \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \
-v /etc/hccl_rootinfo.json:/etc/hccl_rootinfo.json \
-v /home/:/home/ \
-v /etc/hixlep:/etc/hixlep \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
-w /home \
${IMAGES_ID} \
bash
步骤 3: 更新容器内的 /lib/route.conf。
5.2.4. 启用 SSD 前的检查¶
使用 lsblk 检查磁盘状态。以 nvme1n1 为例,确保磁盘没有分区、没有挂载点、没有文件系统签名:
lsblk /dev/nvme1n1 # No partitions expected
mount | grep nvme1n1 # No mount points expected
blkid /dev/nvme1n1 # No filesystem signature expected
如果没有可用的物理磁盘,可以使用循环设备模拟磁盘。参考以下命令:
# Create a 640GB image file (adjust count as needed)
dd if=/dev/zero of=/data/boostio_disk.img bs=1G count=640 status=progress
# Mount the loop device with direct_io enabled; the command outputs the actual device path
LOOP_DEV=$(losetup --find --show --direct-io=on /data/boostio_disk.img)
echo "${LOOP_DEV}"
# Example output: /dev/loop3, where /dev/loop3 is the simulated disk
5.3. Mooncake 常见问题¶
5.3.1. 无法放置/获取键¶
当 vLLM 报告 put 或 get 操作失败时,首先检查该错误是否由 Mooncake 自身报告。
- 如果错误由 Mooncake 报告:
- 对于
put失败,检查 Mooncake 日志是否包含NO_AVAILABLE_HANDLE或BatchPut failed ... due to insufficient space。这通常意味着驱逐后剩余空间不足以容纳一个BatchPut请求。请确保驱逐策略留下的空间(例如,1 - eviction_ratio隐含的容量)能够容纳一次批量 put,或者考虑增加可用容量、增加驱逐余量或减小批量大小。 - 对于
get失败,检查 Mooncake 日志是否包含lease_expired_before_data_transfer_completed key=...或返回LEASE_EXPIRED。这意味着 KV 对象租约在数据传输完成前已过期。根据需要增加mooncake_master的--default_kv_lease_ttl,并确保其大于ASCEND_CONNECT_TIMEOUT和ASCEND_TRANSFER_TIMEOUT。
- 对于
- 如果错误不是由 Mooncake 报告,则很可能是 HIXL (ascend_direct) 传输层问题。收集
/root/ascend/log/debug/plog下的 plog 文件,并检查该问题是否与已知的 HIXL 问题匹配。
有关 HIXL (ascend_direct) 的常见故障排除和问题定位指南,请参阅: https://gitcode.com/cann/hixl/wiki/HIXL%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E5%AE%9A%E4%BD%8D%E6%89%8B%E5%86%8C.md
5.3.2. SSD 常见问题¶
5.3.2.1. 使用 SSD 卸载时出现 SEGMENT_NOT_FOUND¶
如果客户端日志显示 OffloadObjectHeartbeat failed, error code is SEGMENT_NOT_FOUND,则 Master 已卸载该 rank 的 LOCAL_DISK 段(通常在 Ping 停止刷新 TTL 导致 client_expired 之后)。该 rank 上的 SSD 卸载将停止,直到该段被重新注册。
典型触发条件(当 enable_cpu_binding=true 时): Mooncake 在初始化期间启动 Ping,然后 vLLM-Ascend 的 bind_cpus() 运行 migratepages/IRQ 绑定;Ping 线程未被绑定,因此在默认 client_ttl=10 下可能会错过心跳。
| 缓解措施 | 备注 |
|---|---|
| 临时方案: 提高 Master TTL | 例如 mooncake_master ... --client_ttl=120。根据您的初始化/预热窗口进行调整(通常 60–120 就足够了)。不能解决根本原因。 |
| 恢复方案: 升级 Mooncake | > v0.3.11 版本(主分支)可以在 SEGMENT_NOT_FOUND 后重新挂载 LOCAL_DISK 并重新扫描元数据。这可以在清理后恢复;但不能防止元数据丢失期间的过期或正在处理的请求失败。 |
| 根本修复: Mooncake Ping CPU 亲和性 | 将存储 Ping 线程绑定到一个释放/隔离的 CPU(Mooncake 侧更改)。可选地,vLLM-Ascend 协作以传递每个 rank 的释放 CPU。 |
同时重启 Master 和 vLLM,以避免在调试重启时出现陈旧的 segment_already_exists 状态。
5.3.2.2. Fabric 内存大小对齐(A3 + ASCEND_ENABLE_USE_FABRIC_MEM=1){: #5322-fabric-memory-size-alignment-a3--ascend_enable_use_fabric_mem1}¶
在启用 fabric 内存的 A3 上,每次 fabric 内存分配必须是 1 GB(1073741824 字节)的整数倍。Mooncake 不会自动向上取整大小。
| 参数 | 配置来源 | 对齐方式 |
|---|---|---|
global_segment_size |
mooncake.json 或导出 MOONCAKE_GLOBAL_SEGMENT_SIZE |
每个 rank 的段大小必须与 1GB 对齐(例如 "1GB"、"20GB")。 |
MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES |
export MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES(仅在 enable_ssd_offload=true 时) |
必须与 1GB 对齐。默认值为 1280 MB(1.25 GB),未对齐且对于长上下文 SSD 加载来说太小 — 请按照 设置 MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES 大小 进行设置。 |
mooncake.json 中的 local_buffer_size 在 fabric 内存模式下不使用(vLLM-Ascend 向 setup() 传递 0)。
未对齐的风险: adxl MallocMem / aclrtMapMem 失败并返回 Invalid_Argument。启用 SSD 卸载后,MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES 分配失败可能导致 FileStorage 初始化期间出现段错误并中止 vLLM 启动。避免使用诸如 "1280MB"、"512MB" 或 "1.5GB" 之类的值。
Fabric 内存配额: global_segment_size 和 MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES 都是每个 rank 独立的 fabric 内存分配。它们的大小累加后受限于通过 ASCEND_GLOBAL_RESOURCE_CONFIG 配置的 HIXL fabric 内存限制(例如 "fabric_memory.max_capacity":32,单位 GB/进程 — 请参阅 HIXL 文档)。每个 rank 的大致预算:
fabric_memory.max_capacity ≥ global_segment_size + MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES (+ headroom)
配额过低的风险: 某些 rank 在 global_segment_size 成功但 MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES 分配失败时,会报错 Memory_Allocation_Failure(EL0004)。请增加 fabric_memory.max_capacity,减小 global_segment_size 或 MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES,或确保节点有足够的主机内存。
示例(在 SSD 卸载开启时,添加到您的 vLLM 启动脚本中):
export ASCEND_ENABLE_USE_FABRIC_MEM=1
export MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES=1073741824 # 1 GB, fabric-mem aligned
仅在 fabric 内存过低时设置 ASCEND_GLOBAL_RESOURCE_CONFIG。
# Per-rank fabric mem budget: 20 GB segment + 1 GB MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES → set max_capacity ≥ 22 (GB)
export ASCEND_GLOBAL_RESOURCE_CONFIG='{"fabric_memory.max_capacity":32}'
5.3.2.3. 设置 MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES 大小¶
当 enable_ssd_offload=true 时,Mooncake 会分配一个独立的、每个 rank 的 SSD 读/写缓冲区,其大小由 MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES 决定。此缓冲区独立于 mooncake.json 中的 global_segment_size — 增加段大小并不能解决由 MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES 过小导致的 BUFFER_OVERFLOW 问题。
如果缓冲区太小,SSD 读取会在 FileStorage::AllocateBatch 期间失败并返回 BUFFER_OVERFLOW (error_code=-10),并且当 kv_load_failure_policy=fail 时,vLLM 可能会失败。
如果在使用过程中遇到 BUFFER_OVERFLOW,请尝试增大 MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES。不要将其设置为高于 vLLM 工作进程日志中显示的 可用 KV 缓存内存 值:
示例:
仅使用字节字面量(10737418240)。10G / 10GB 会被忽略并回退到 1280 MB 的默认值。
说明
* `--max-num-batched-tokens` 仅对预填充计算进行分块;它**不会**减少 `MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES` 所需的内存。主机内存预算(单节点)¶
MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES 是按 rank 分配的,除此之外还有 global_segment_size:
host_memory_for_mooncake ≈ TP × (global_segment_size + MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES + local_buffer_size)
确保主机上 free -h 的可用内存超过此总和加上 vLLM 的开销。MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES 不需要 适应 global_segment_size。
调优后验证¶
- 启动时:每个 rank 会记录
AlignedClientBufferAllocator: allocated <N> bytes,其中包含您配置的大小。 - 负载下:没有
BUFFER_OVERFLOW/Failed to get ... keys out of ... error_codes=[-10]。 - 如果使用大缓冲区时故障仍然存在,请检查重叠加载(
load_async)。
5.4. Memcache 常见问题¶
- 操作前步骤:
- 有关 Memcache 故障排除,请参阅: https://gitcode.com/Ascend/memcache/wiki/FAQ.md
5.5. DSv4 已知问题(临时)¶
有关临时的 DSv4 已知问题,请参阅: https://github.com/vllm-project/vllm-ascend/issues/9975
5.6. ASCEND_GLOBAL_RESOURCE_CONFIG¶
ASCEND_GLOBAL_RESOURCE_CONFIG是传递给HIXL的JSON字符串。常见字段包括:
| 字段 | 描述 |
|---|---|
comm_resource_config.protocol_desc |
顶层Mooncake传输引擎的协议描述符。在PD分离中,此字段控制MooncakeConnectorV1的PD传输路径。示例值包括["hccs:device"]和["roce:device"]。 |
store.comm_resource_config.protocol_desc |
AscendStoreConnector使用的Mooncake Store流量的协议描述符。在A3上,可将其设置为["roce:device"],而PD传输使用HCCS。 |
comm_resource_config.listen_port |
单边通信监听端口。HIXL默认值为16666;对于独立的mooncake_client进程,请使用其他端口以避免与嵌入式客户端冲突。 |
fabric_memory.max_capacity |
每个进程的fabric内存配额(GB)。仅在fabric内存预算过小时使用;参见Fabric内存大小对齐。 |
Store/PD流量分离需要CANN >= 9.1.0。此功能适用于A3和Ascend 950产品部署,其中PD传输流量可使用HCCS,而Mooncake Store流量可使用ROCE,从而避免两类流量在同一物理链路上竞争。有关更多HIXL部署模式,请参见Mooncake + HIXL池化方案总览。
5.7. QoS 配置¶
Mooncake和Memcache后端均支持配置传输QoS。有效范围为0-4(仅限整数),未配置时默认值为0。数值越大表示传输优先级越高。无效值(非整数、超出范围)会导致启动时快速失败并报验证错误。
QoS 可以通过 kv_connector_extra_config 进行配置,该配置会在存储初始化之前自动注入到后端特定的配置中:
--kv-transfer-config \
'{
"kv_connector": "AscendStoreConnector",
"kv_role": "kv_both",
"kv_connector_extra_config": {
"qos_priority": 1,
"lookup_rpc_port": "1",
"backend": "mooncake",
"use_layerwise": false
}
}'
注意事项¶
kv_connector_extra_config的值优先于环境中已设置的值;当它覆盖了不同的现有值时,会记录一条警告。- 对于 Mooncake,
qos_priority字段会合并到现有的ASCEND_GLOBAL_RESOURCE_CONFIG中(其他字段如protocol_desc会被保留)。当未设置ASCEND_GLOBAL_RESOURCE_CONFIG时,配置qos_priority会创建它,这同时也会选择与存储无关的传输引擎路径(参见 5.6)。