LMCache-Ascend 用户手册
1. 文档说明
LMCache-Ascend 是 LMCache 面向昇腾 NPU 的适配插件,可在 vLLM-Ascend 推理服务之间复用和传输 KV Cache。本手册重点介绍以下两种部署方式:
• 1P1D(Disaggregated Prefill):将 Prefill 和 Decode 部署为不同服务,由 Prefill 实例生成 KV Cache,并传递给 Decode 实例继续生成。
• P2P KV Cache 共享:多个对等 vLLM 实例通过 Controller 发现缓存位置,并经 RoCE 直接拉取其他实例 CPU 内存中的 KV Cache。
2. 部署前准备
2.1 基础软硬件要求
建议在开始部署前确认:
• 至少 2 张昇腾 NPU;若两个实例均采用 TP=2,则至少需要 4 张 NPU;
• 若多级部署,节点之间应有HCCL互联。
• 1P1D 和 P2P 样例要求 Ascend HDK 驱动、固件 25.5.0 或更高版本;
• HCCL/HIXL 传输通道要求 CANN 8.5 或更高版本;
• 已安装版本匹配的 LMCache、LMCache-Ascend、vLLM 和 vLLM-Ascend;vllm安装可参考:
• 模型目录可被各实例访问,且各实例加载相同模型和兼容的模型配置。
当前仓库根目录 README.md 提供了版本兼容矩阵。部署前应以所使用分支或发布版本对应的矩阵为准,不要混用不同发布版本的 LMCache 与 LMCache-Ascend。
2.2 环境软件安装
vLLM-Ascend环境准备可参考官方文档
LMCache安装:NO_CUDA_EXT=1 pip install lmcache==0.4.4
LMCache-Ascend安装:
• 方法一:配置openEuler-26.09-DevStation的软件源后,dnf install -y LMCache-Ascend
• 方法二:从Github上游仓库源码安装:
git clone --recurse-submodules -b v0.4.4 https://github.com/LMCache/LMCache-Ascend.git
cd LMCache-Ascend
pip install -v --no-build-isolation -e .注意事项:
• 方法一:
• dnf install方法只能向系统自带的Python中安装,因此要求/usr/bin/python3版本为Python 3.11系列。
• vLLM与vLLM-Ascend也要向/usr/bin/python3安装
• 方法二:
• 源码安装不限定Python具体版本,只需要Python >= 3.10。
• 源码安装命令请自行修改,向带有vLLM + vLLM-Ascend的Python环境安装。
3. 通用配置与环境变量
3.1 LMCACHE_CONFIG_FILE
该环境变量指定当前 vLLM 实例使用的 LMCache YAML 配置文件。每个实例应指向自己的配置文件,例如:
export LMCACHE_CONFIG_FILE=/workspace/LMCache-Ascend/examples/disagg_prefill/1p1d/configs/lmcache-prefiller-config.yaml建议使用绝对路径,并在启动前检查文件是否挂载到容器内。
3.2 ASCEND_RT_VISIBLE_DEVICES
用于指定当前进程可见的 NPU。例如 TP=2 时:
export ASCEND_RT_VISIBLE_DEVICES=4,5可见设备数量不得少于 --tensor-parallel-size。同机部署多个实例时,应为各实例分配不重叠的设备集合。
3.3 vLLM 多进程环境变量
export VLLM_ENABLE_V1_MULTIPROCESSING=1
export VLLM_WORKER_MULTIPROC_METHOD=spawn• VLLM_ENABLE_V1_MULTIPROCESSING=1:启用 vLLM V1 worker 多进程模式。
• VLLM_WORKER_MULTIPROC_METHOD=spawn:使用 spawn 创建 worker,避免在已初始化 NPU 运行时之后 fork 产生不安全状态。
3.4 PYTHONHASHSEED:必须保持一致的哈希种子
Python 默认会在每个解释器进程启动时随机化部分内置对象的哈希结果。LMCache 使用基于 token 序列和前缀哈希的键来标识 KV Cache;若协作进程的哈希种子不同,同一段 token 可能得到不同的缓存键,进而表现为缓存查找失败、跨实例命中率异常或 Controller 与 worker 认知不一致。
因此必须遵守以下规则:
- 参与同一缓存域的所有 Python 进程使用完全相同的整数值,包括 Controller、Prefill、Decode 以及所有 P2P vLLM 实例。
- 取值本身不是性能参数,
0、123或其他 Python 支持的固定整数均可;关键是所有进程一致。 - 不要省略该变量,也不要使用
random。不同部署组可以使用不同值,但同一组中途不得改变。 - 修改该值后,应重启该缓存域内的全部相关进程;旧进程产生的内存缓存不应继续与新种子进程混用。
1P1D 样例统一使用:
export PYTHONHASHSEED=0P2P 样例统一使用:
export PYTHONHASHSEED=123二者都正确。生产环境可以统一选用 0,并通过容器环境变量、启动脚本或 Pod env 固化。P2P Controller 也必须带相同值启动:
PYTHONHASHSEED=123 lmcache_controller ...3.5 LMCACHE_TRACK_USAGE:关闭 LMCache 匿名用量统计
LMCache 默认会初始化用量统计上下文,采集匿名运行环境、引擎配置和运行时元数据,并上报到 LMCache 用量统计服务;这些统计不影响 KV Cache 的读写、命中或传输功能。
在内网、离线、隐私合规或不希望产生外部统计请求的部署中,建议为所有 vLLM / LMCache worker 进程显式关闭:
export LMCACHE_TRACK_USAGE=false注意该变量在 LMCache 中按字符串精确判断,只有小写 false 会关闭统计;未设置或设置为其他值时仍按默认启用处理。关闭后 InitializeUsageContext 返回 None,不会发送或记录用量统计数据。
3.6 常用 vLLM 参数
| 参数 | 样例值 | 说明与取值建议 |
|---|---|---|
--model | /data/models/Qwen/Qwen3-8B | 模型目录。参与 KV 传输或共享的实例应使用相同模型及兼容配置。 |
--tensor-parallel-size | 2 | TP rank 数。必须与配置中的逐 rank 端口列表长度一致。 |
--block-size | 128 | vLLM paged KV block 的 token 数。它不等同于 LMCache 的 chunk_size,应按当前 vLLM-Ascend 支持范围设置。 |
--max-model-len | 32768 | 最大上下文长度。调大后可能需要增大传输缓冲区并预留更多 NPU/CPU 内存。 |
--enforce-eager | 开启 | 强制 eager 执行,便于样例稳定运行和排障,但可能牺牲图模式带来的性能收益。 |
--no-enable-prefix-caching | 1P1D 开启 | 禁用 vLLM 自身 prefix caching,避免与样例中的 LMCache 路径混淆。 |
--trust-remote-code | 开启 | 允许执行模型仓库自定义代码;只应对可信模型使用。 |
--disable-log-requests | 开启 | 减少请求日志量,不影响 KV Cache 功能。排障时可临时去掉。 |
4. 1P1D 部署
推理服务启动脚本中的Python命令,请自行替换成装有vLLM + vLLM-Ascend + LMCache + LMCache-Ascend依赖的环境
4.1 架构与请求流
1P1D 包含三个服务:
- Proxy 接收客户端请求并协调 Prefill 与 Decode;
- Prefill 实例完成提示词预填充并生成 KV Cache;
- Decode 实例接收 KV Cache,从约定位置继续生成 token。
样例端口关系如下:
| 组件 | 端口/端口组 | 用途 |
|---|---|---|
| Prefill API | 7100 | Prefill OpenAI API 服务 |
| Decode API | 7200 | Decode OpenAI API 服务 |
| Proxy API | 9100 | 客户端访问入口 |
| Decode init | 7300,7301 | 每个 TP rank 一个初始化端口 |
| Decode alloc | 7400,7401 | 每个 TP rank 一个内存分配端口 |
| PD proxy | 7500 | Prefill/Decode 协调端口 |
| Pull done | 7600,7601 | 每个 TP rank 一个完成通知端口 |
4.2 Prefill 配置
样例文件:examples/disagg_prefill/1p1d/configs/lmcache-prefiller-config.yaml。
local_cpu: False
enable_pd: True
transfer_channel: "hccl"
pd_role: "sender"
pd_pull_mode: False
pd_delay_pull: False
pd_pull_done_port: [7600, 7601]
pd_use_cpu_offload: False
pd_cpu_buffer_size: 21474836480
pd_peer_host: "localhost"
pd_proxy_host: "localhost"
pd_proxy_port: 7500
pd_buffer_size: 2415919104
pd_buffer_device: "npu"
save_unfull_chunk: True关键参数说明:
| 参数 | 说明 |
|---|---|
local_cpu | 是否启用常规本地 CPU KV 缓存。本例关闭,PD 传输缓冲区由专用参数管理。 |
enable_pd | 启用 Prefill/Decode 分离传输后端,两端都必须为 True。 |
pd_role | Prefill 固定为 sender;Decode 固定为 receiver。 |
transfer_channel | hccl 为推荐值;hixl 为实验特性。两端必须选择兼容的通道。 |
pd_pull_mode | False 表示不使用接收端按需拉取模式。本样例采用该设置。 |
pd_delay_pull | 延迟到消费 KV 时再拉取,仅在 pull mode 且使用 NPU 缓冲区时有意义;本例关闭。 |
pd_pull_done_port | pull mode 下 sender 接收完成信号的端口列表,每个 TP rank 一个。虽然样例当前关闭 pull mode,仍预留了端口。 |
pd_use_cpu_offload | sender 是否先将 KV 从 NPU 卸载到 CPU,再供远端读取。仅 sender pull mode 路径使用。 |
pd_cpu_buffer_size | CPU offload 缓冲区字节数。本例为 21474836480,即 20 GiB;仅启用 CPU offload 路径时实际使用。 |
pd_peer_host | 对端可达地址。多机时填写对应节点的 RoCE 网络 IP。 |
pd_proxy_host / pd_proxy_port | 协调代理地址和端口,应与 proxy 启动参数一致。 |
pd_buffer_size | PD 传输缓冲区字节数。本例 sender 为 2415919104,即 2.25 GiB。实现会按单个 KV 对象大小向上对齐,实际分配可能略大。 |
pd_buffer_device | npu 表示传输缓冲区位于 NPU;也可按受支持路径使用 cpu。NPU 缓冲区更直接,但会占用显存。 |
save_unfull_chunk | 保存不足一个完整 LMCache chunk 的尾部 KV,使短 prompt 也能发生 PD 传输。关闭时尾部不足整块的 KV 可能不被保存。 |
4.3 Decode 配置
样例文件:examples/disagg_prefill/1p1d/configs/lmcache-decoder-config.yaml。
local_cpu: False
enable_pd: True
transfer_channel: "hccl"
pd_role: "receiver"
pd_peer_host: "localhost"
pd_pull_mode: False
pd_delay_pull: False
pd_peer_init_port: [7300, 7301]
pd_peer_alloc_port: [7400, 7401]
pd_buffer_size: 134217728
pd_buffer_device: "npu"其中:
• pd_peer_init_port:接收端每个 TP rank 的传输初始化端口;
• pd_peer_alloc_port:接收端每个 TP rank 的内存分配通信端口;
• 两个列表长度均需等于 TP 大小;
• pd_buffer_size: 134217728 为 128 MiB。该空间位于 pd_buffer_device 指定的设备上,需结合最大命中长度和并发量调优。
pd_buffer_size 越大,可承载的在途 KV 数据越多,但内存占用也越高。估算时不能只用 token 数乘 dtype 字节数,而应计入所有层、K/V 张量、KV head 和 head dimension。建议先以样例值验证,再根据最长 prompt、并发量、模型 KV 形状和运行日志逐步调整。
4.4 启动 Prefill 服务
export LMCACHE_CONFIG_FILE=/workspace/LMCache-Ascend/examples/disagg_prefill/1p1d/configs/lmcache-prefiller-config.yaml
export ASCEND_RT_VISIBLE_DEVICES=4,5
export VLLM_ENABLE_V1_MULTIPROCESSING=1
export VLLM_WORKER_MULTIPROC_METHOD=spawn
export PYTHONHASHSEED=0
python -m vllm.entrypoints.openai.api_server \
--port 7100 \
--model /data/models/Qwen/Qwen3-8B \
--enforce-eager \
--no-enable-prefix-caching \
--tensor-parallel-size 2 \
--trust-remote-code \
--disable-log-requests \
--block-size 128 \
--max-model-len 32768 \
--kv-transfer-config '{"kv_connector":"LMCacheAscendConnector","kv_role":"kv_producer","kv_connector_extra_config":{"discard_partial_chunks":false,"lmcache_rpc_port":"producer1"}}' \
> prefill.txt 2>&1kv-transfer-config 中:
• kv_connector:使用 LMCache-Ascend connector;
• kv_role: kv_producer:声明该实例是 KV 生产者;
• discard_partial_chunks: false:保留不完整 chunk,与 save_unfull_chunk: True 配合,改善短 prompt 或尾块传输;
• lmcache_rpc_port: producer1:当前实例内部 LMCache RPC 标识,需与其他实例区分。该字段虽名为 port,样例使用字符串标识。
4.5 启动 Decode 服务
export LMCACHE_CONFIG_FILE=/workspace/LMCache-Ascend/examples/disagg_prefill/1p1d/configs/lmcache-decoder-config.yaml
export ASCEND_RT_VISIBLE_DEVICES=6,7
export VLLM_ENABLE_V1_MULTIPROCESSING=1
export VLLM_WORKER_MULTIPROC_METHOD=spawn
export PYTHONHASHSEED=0
python -m vllm.entrypoints.openai.api_server \
--port 7200 \
--model /data/models/Qwen/Qwen3-8B \
--enforce-eager \
--no-enable-prefix-caching \
--tensor-parallel-size 2 \
--trust-remote-code \
--disable-log-requests \
--block-size 128 \
--max-model-len 32768 \
--kv-transfer-config '{"kv_connector":"LMCacheAscendConnector","kv_role":"kv_consumer","kv_connector_extra_config":{"discard_partial_chunks":false,"lmcache_rpc_port":"consumer1","skip_last_n_tokens":1}}' \
> decode.txt 2>&1• kv_role: kv_consumer:声明 Decode 为 KV 消费者;
• skip_last_n_tokens: 1:不从 LMCache 加载最后 1 个 token 的 KV,由 Decode 侧计算该 token,以满足分离式调度中继续生成的边界要求;应保持样例值,除非所用 vLLM/LMCache 版本明确要求其他值;
• lmcache_rpc_port: consumer1:必须与 Prefill 的标识不同。
4.6 启动 Proxy
python3 /workspace/LMCache/examples/disagg_prefill/disagg_proxy_server.py \
--host localhost \
--port 9100 \
--prefiller-host localhost \
--prefiller-port 7100 \
--num-prefillers 1 \
--decoder-host localhost \
--decoder-port 7200 \
--decoder-init-port "7300,7301" \
--decoder-alloc-port "7400,7401" \
--proxy-host localhost \
--proxy-port 7500 \
--num-decoders 1建议按 Prefill、Decode、Proxy 的顺序启动,并先确认前两个 API 进程已完成模型加载。多机时,各 host 参数应使用实际可达地址,不能保留 localhost。
4.7 发起验证请求
curl -X POST http://localhost:9100/v1/completions \
-H "Content-Type: application/json" \
-d "{
\"model\": \"/data/models/Qwen/Qwen3-8B\",
\"prompt\": \"$(printf 'Explain the significance of KV cache in language models in English.%.0s' {1..100})\",
\"max_tokens\": 100
}"验证时同时观察 prefill.txt 和 decode.txt,确认请求经过两个实例且无端口连接、内存注册或 KV 传输错误。
5. P2P KV Cache 共享部署
推理服务启动脚本中的Python命令,请自行替换成装有vLLM + vLLM-Ascend + LMCache + LMCache-Ascend依赖的环境
5.1 架构说明
P2P 模式中的 vLLM 实例均配置为 kv_both,既可生产并保存 KV Cache,也可从其他实例获取 KV Cache。Controller 负责实例注册、缓存位置查询与路由;KV 数据本身通过 P2P 传输通道移动,而非由 Controller 中转。
样例结合了三项能力:
p2p_pull_mode: True
p2p_delay_pull: True
p2p_use_npu: True
extra_config:
use_host_staging: True该组合表示使用 HostStaging 的延迟 rH2D pull:生产端将命中 KV 拷贝到有限大小、已注册的 CPU staging arena;消费端在实际加载 KV 时,通过 RDMA 将微批数据直接拉入两个交替使用的 NPU 缓冲池,并与 KV scatter 重叠。
5.2 P2P 配置样例
实例 1 的核心配置如下:
chunk_size: 256
local_cpu: True
max_local_cpu_size: 16
enable_async_loading: False
enable_p2p: True
p2p_host: "localhost"
p2p_init_ports: [9960, 9961]
p2p_lookup_ports: [9962, 9963]
transfer_channel: "hccl"
p2p_use_npu: True
p2p_pull_mode: True
p2p_delay_pull: True
p2p_npu_buffer_size: 134217728
enable_controller: True
lmcache_instance_id: "lmcache_instance_1"
controller_pull_url: "localhost:9800"
controller_reply_url: "localhost:9900"
lmcache_worker_ports: [9950, 9951]
extra_config:
lookup_backoff_time: 0.001
use_host_staging: True
os_staging_bytes: 8589934592实例 2 使用相同的传输策略,但以下字段必须不同:
| 字段 | 实例 1 | 实例 2 |
|---|---|---|
lmcache_instance_id | lmcache_instance_1 | lmcache_instance_2 |
p2p_init_ports | [9960, 9961] | [9964, 9965] |
p2p_lookup_ports | [9962, 9963] | [9966, 9967] |
lmcache_worker_ports | [9950, 9951] | [9952, 9953] |
5.3 关键参数说明
| 参数 | 说明与建议 |
|---|---|
chunk_size | 每个 LMCache 缓存块包含的 token 数。本例为 256。较大值可降低元数据和查询开销,但会提高尾块浪费,并降低短前缀的复用粒度。所有共享实例应保持一致。 |
local_cpu | P2P 依赖本地 CPU backend 保存可共享 KV,本例必须启用。 |
max_local_cpu_size | 每个启用存储的 LMCache worker 的 CPU KV 缓存上限,单位为 GiB。本例为 16。总预算需乘以实际拥有存储的 worker 数。 |
enable_async_loading | 是否启用 LMCache 异步加载。默认 False;本例保持关闭,以使用样例已验证的 P2P + HostStaging 延迟 rH2D 路径。 |
enable_p2p | 启用 P2P backend。 |
p2p_host | 当前实例向其他实例公布的地址。多机部署必须填写其他节点可达的 RoCE 网络 IP,而不是 localhost。 |
p2p_init_ports | 各 TP rank 的传输初始化端口,一 rank 一端口。 |
p2p_lookup_ports | 各 TP rank 的 P2P 查询端口,一 rank 一端口。 |
p2p_use_npu | 启用 NPU 传输缓冲区,使远端 host 数据可被拉入 NPU。 |
p2p_pull_mode | 由消费端主动读取生产端数据。HostStaging 要求该值为 True。 |
p2p_delay_pull | 查询命中时先返回轻量代理,待 vLLM 实际消费时分微批拉取。要求 p2p_pull_mode=True 且 p2p_use_npu=True;否则无法形成延迟 rH2D 路径。 |
p2p_npu_buffer_size | 每个 worker 的 NPU P2P scratch buffer 字节数。本例为 128 MiB。延迟拉取会将内存占用限制在该缓冲池附近;增大可提高微批容量,但会占用更多 NPU 内存。 |
transfer_channel | 推荐 hccl。hixl 仍为实验特性,且不支持 HostStaging。 |
enable_controller | 开启与 LMCache Controller 的交互。所有实例都应开启。 |
lmcache_instance_id | 实例唯一标识。同一 Controller 下不得重复。 |
controller_pull_url | Controller pull monitor 地址,与 Controller 的 monitor-ports.pull 对应。 |
controller_reply_url | Controller reply monitor 地址,与 Controller 的 monitor-ports.reply 对应。 |
lmcache_worker_ports | Controller 与各 TP worker 通信的端口,一 rank 一端口,且实例间不可冲突。 |
lookup_backoff_time | 异步查询重试间隔,单位为秒;0.001 即 1 ms。过小会增加轮询开销,过大则增加缓存命中等待时延。 |
use_host_staging | 只注册有限的 CPU staging arena,而不是完整 CPU KV cache,可降低 HCCL 注册压力,但生产端增加一次 CPU 到 CPU 拷贝。 |
os_staging_bytes | 每个 LMCache worker 的 HostStaging arena 容量。本例为 8 GiB;不是每实例或每节点的总量。 |
enable_async_loading 使用建议
enable_async_loading: True 会将 LMCache 的查询与加载拆成异步路径:scheduler 侧先发送 chunk hash 查询,worker 侧通过异步 lookup server 对后端执行 batched_async_contains,并提前发起非阻塞读取,从而让 KV 拉取与 vLLM 调度/计算尽量重叠。该模式适合远端存储或后端读取延迟较高、且后端已支持异步查询/预取的场景。
重要:若在 P2P 场景同时开启 cache_policy,压测时必须开启 enable_async_loading,否则访问对端缓存可能报错。
配置互斥:P2P 池化与 SSD 多级缓存
当前版本中,P2P 池化路径与 SSD 多级缓存路径同时开启时存在已知问题,建议二选一使用,不要在同一组实例中混配:
- 使用本文 P2P 共享样例时,保持 SSD / 本地磁盘层关闭,即不要配置
local_disk,并保持max_local_disk_size不设置。 - 如果需要验证 SSD 多级缓存,请关闭 P2P 相关能力,例如
enable_p2p: False,并移除p2p_*、Controller、HostStaging 等 P2P 配置。 - 不建议依赖
cache_policy、enable_async_loading等开关来规避该组合问题;即使部分场景可以绕过报错,也应按互斥配置处理,避免压测或长稳运行中出现不一致行为。
5.4 HostStaging 模式选择
如果 HCCL 能稳定注册完整 CPU KV cache,建议设置:
extra_config:
use_host_staging: False这能避免生产端额外 staging 拷贝。大模型场景中,完整缓存注册可能耗尽 Device OS 内存,并可能出现错误码 19。此时可开启 HostStaging,并在 $HOME/ascend/log 下的 Ascend PLOG 中确认底层注册错误。
HostStaging 支持矩阵如下:
| 模式 | p2p_pull_mode | p2p_delay_pull | p2p_use_npu | 结果 |
|---|---|---|---|---|
| 延迟 rH2D pull | True | True | True | 支持,样例推荐组合 |
| eager CPU pull | True | False | False | 支持,数据先物化为 CPU KV 对象 |
| eager NPU pull | True | False | True | HostStaging 不支持,启动时拒绝 |
| push mode | False | 任意 | 任意 | HostStaging 不支持,启动时拒绝 |
若 p2p_delay_pull=True 但 p2p_use_npu=False,实现会发出警告并关闭 delayed pull。此时应显式配置 eager CPU pull,避免配置含义不清。
5.5 os_staging_bytes 容量估算
可用以下公式估算每个 TP rank 所需容量:
os_staging_bytes ≈ concurrent_requests_per_rank
× hit_tokens_per_request
× KV_bytes_per_token_per_rank其中:
• concurrent_requests_per_rank 是已经 staging、但尚未收到 Done 的并发命中请求数;
• hit_tokens_per_request 建议使用 p95 或最大预期缓存命中长度;
• KV_bytes_per_token_per_rank 必须包含该 rank 上所有层、K/V、KV heads、head dimension 与 dtype 的总字节数。
arena 会向下取整为完整且对齐的 KV chunk,并且至少能容纳一个 chunk。若无法容纳完整命中,LMCache 只提供能够放入 arena 的前缀,剩余 token 将重新计算。
总主机内存必须按 worker 累加。例如两个 TP=2 实例均在所有 rank 开启存储,8 GiB staging 加 16 GiB CPU cache 的理论预算为:
4 workers × (8 GiB + 16 GiB) = 96 GiB该数值还不包括模型服务、Python 进程和系统本身的内存。
对于 MLA/DSA 且启用 save_only_first_rank: True 的场景,建议使用 eager HostStaging CPU pull:
p2p_pull_mode: True
p2p_delay_pull: False
p2p_use_npu: False
extra_config:
save_only_first_rank: True
use_host_staging: True
os_staging_bytes: 8589934592此时仅第一个 rank 持有并从存储后端读取 KV,再向其他 rank 广播;物化后的 CPU KV 对象更适合该流程。
5.6 启动 Controller
PYTHONHASHSEED=123 lmcache_controller \
--host 0.0.0.0 \
--port 9000 \
--monitor-ports '{"pull":9800,"reply":9900}'Controller 的 9800 和 9900 必须与两个实例 YAML 中的 controller_pull_url 和 controller_reply_url 对应。多机时,实例配置中的主机名应替换为 Controller 的可达 IP。
5.7 启动两个 P2P 实例
实例 1:
export LMCACHE_CONFIG_FILE=/workspace/LMCache-Ascend/examples/kv_cache_reuse/share_across_instances/p2p_sharing/instance1.yaml
export ASCEND_RT_VISIBLE_DEVICES=2,3
export VLLM_ENABLE_V1_MULTIPROCESSING=1
export VLLM_WORKER_MULTIPROC_METHOD=spawn
export PYTHONHASHSEED=123
export LMCACHE_TRACK_USAGE=false
python -m vllm.entrypoints.openai.api_server \
--port 8010 \
--model /data/models/Qwen/Qwen3-8B \
--enforce-eager \
--tensor-parallel-size 2 \
--trust-remote-code \
--disable-log-requests \
--block-size 128 \
--rope-scaling '{"rope_type":"yarn","factor":4.0,"original_max_position_embeddings":32768}' \
--max-model-len 32768 \
--kv-transfer-config '{"kv_connector":"LMCacheAscendConnector","kv_role":"kv_both"}' \
> instance1.txt 2>&1实例 2:
export LMCACHE_CONFIG_FILE=/workspace/LMCache-Ascend/examples/kv_cache_reuse/share_across_instances/p2p_sharing/instance2.yaml
export ASCEND_RT_VISIBLE_DEVICES=6,7
export VLLM_ENABLE_V1_MULTIPROCESSING=1
export VLLM_WORKER_MULTIPROC_METHOD=spawn
export PYTHONHASHSEED=123
export LMCACHE_TRACK_USAGE=false
python -m vllm.entrypoints.openai.api_server \
--port 8011 \
--model /data/models/Qwen/Qwen3-8B \
--enforce-eager \
--tensor-parallel-size 2 \
--trust-remote-code \
--disable-log-requests \
--block-size 128 \
--rope-scaling '{"rope_type":"yarn","factor":4.0,"original_max_position_embeddings":32768}' \
--max-model-len 32768 \
--kv-transfer-config '{"kv_connector":"LMCacheAscendConnector","kv_role":"kv_both"}' \
> instance2.txt 2>&1kv_role: kv_both 表示实例既可将 KV 写入本地缓存并对外提供,也可从远端实例读取命中的 KV。
--rope-scaling 是本模型样例的上下文扩展配置,并非 LMCache P2P 的必需开关。更换模型时应按模型自身配置决定是否保留,错误的 RoPE 参数会影响模型输出质量。
5.8 验证跨实例命中
先向实例 1 发送长 prompt,使其填充缓存:
time curl -X POST http://localhost:8010/v1/completions \
-H "Content-Type: application/json" \
-d "{
\"model\": \"/data/models/Qwen/Qwen3-8B\",
\"prompt\": \"$(printf 'Explain the significance of KV cache in language models in English.%.0s' {1..1000})\",
\"max_tokens\": 10,
\"temperature\": 0
}"再将完全相同的 prompt 发送到实例 2:
time curl -X POST http://localhost:8011/v1/completions \
-H "Content-Type: application/json" \
-d "{
\"model\": \"/data/models/Qwen/Qwen3-8B\",
\"prompt\": \"$(printf 'Explain the significance of KV cache in language models in English.%.0s' {1..1000})\",
\"max_tokens\": 10,
\"temperature\": 0
}"实例 2 日志应出现类似信息:
LMCache INFO: Retrieved 1002 out of total 1002 tokens. size: 0.1223 gb, cost 60.3595 ms, throughput: 2.0264 GB/s命中 token 数和吞吐量会随 tokenizer、软件版本、模型、网络及机器负载变化,不应将样例数值作为性能承诺。
6. 参数一致性检查表
6.1 所有协作进程必须一致
• PYTHONHASHSEED;
• 模型及影响 KV 形状的模型配置;
• chunk_size;
• 兼容的 transfer_channel;
• vLLM --block-size 和其他影响运行时布局的关键参数;
• 软件版本与补丁状态。
6.2 必须唯一或避免冲突
• 每个 P2P 实例的 lmcache_instance_id;
• vLLM API 端口;
• p2p_init_ports、p2p_lookup_ports、lmcache_worker_ports;
• 1P1D 中的 Prefill/Decode API 端口和 TP 通信端口;
• 同机各实例使用的 NPU 设备集合。
6.3 必须与 TP 大小匹配
• pd_peer_init_port;
• pd_peer_alloc_port;
• pd_pull_done_port;
• p2p_init_ports;
• p2p_lookup_ports;
• lmcache_worker_ports。
例如 --tensor-parallel-size 2 时,上述已启用的端口列表应各包含两个端口。
7. 常见问题与排障
7.1 相同 prompt 无法跨实例命中
依次检查:
- Controller、全部 vLLM 实例的
PYTHONHASHSEED是否已设置且完全相同; - prompt 是否逐字节相同,包括空格、模板和 tokenizer 处理;
- 两个实例的模型、tokenizer、
chunk_size是否一致; lmcache_instance_id是否唯一;- Controller URL 和 worker/P2P 端口是否可达;
- 实例 1 是否确实完成缓存写入后,实例 2 才发起请求。
7.2 启动时端口绑定失败
• 使用 ss -lntp 检查端口占用;
• 确认两个 P2P YAML 没有复用逐 rank 端口;
• 确认端口列表长度与 TP 大小一致;
• 多机部署时检查监听地址、防火墙和容器网络模式。
7.3 NPU 或主机内存不足
• 减小 pd_buffer_size 或 p2p_npu_buffer_size;
• 减小 max_local_cpu_size 或 os_staging_bytes;
• 注意这些容量通常按 worker/TP rank 分配,而非按实例只分配一次;
• 适当降低 --max-model-len、并发数或 vLLM NPU 内存利用率;
• 修改后检查是否仍至少容纳一个完整 KV chunk。
7.4 HCCL 注册失败或出现错误码 19
• 查看 $HOME/ascend/log 下的 PLOG;
• 确认驱动、固件和 CANN 版本符合要求;
• 检查 memlock 限制;
• P2P 场景可尝试开启 use_host_staging: True,用有限的 os_staging_bytes 替代完整 CPU cache 注册;
• 若完整缓存注册稳定,关闭 HostStaging 通常可减少一次 CPU 拷贝。
7.5 短 prompt 在 1P1D 中未发生传输
检查 Prefill 是否同时设置:
save_unfull_chunk: True以及 connector 配置是否包含:
{"discard_partial_chunks": false}两者用于保留不足完整 chunk 的尾部缓存。
7.6 P2P delayed pull 未生效
确保:
p2p_pull_mode: True
p2p_delay_pull: True
p2p_use_npu: True若启用 HostStaging,还必须使用 transfer_channel: "hccl"。HIXL 当前不支持 HostStaging。