UCM-增强前缀缓存部署指南#
概述#
统一缓存管理 (UCM) 为 vLLM/vLLM-Ascend 中的前缀缓存场景提供了一个外部 KV-缓存存储层。与仅通过聚合设备内存来扩展前缀缓存容量、因此仍受 HBM/DRAM 大小限制且缺乏持久性的 KV Pooling 不同,UCM 将计算与存储解耦,并采用了分层设计。每个节点使用本地 DRAM 作为快速缓存,而像 3FS 或企业级存储这样的共享后端则作为持久化 KV 存储。这种方法消除了设备内存带来的容量上限,实现了持久可靠的前缀缓存,并允许缓存容量随存储系统扩展,而不是随计算资源扩展。
先决条件#
操作系统:Linux
拥有 Ascend NPU 的硬件。通常是 Atlas 800 A2 系列。
vLLM: main 分支
vLLM Ascend: main 分支
UCM 安装#
配置 UCM 进行前缀缓存#
修改 UCM 配置文件,指定要使用的 UCM 连接器以及 KV 块的存储位置。
您可以直接编辑示例文件:
unified-cache-management/examples/ucm_config_example.yaml
有关更新的配置选项,请参考 UCM 前缀缓存官方文档
一个最小配置如下所示:
ucm_connectors:
- ucm_connector_name: "UcmNfsStore"
ucm_connector_config:
storage_backends: "/mnt/test"
use_direct: false
load_only_first_rank: false
解释
ucm_connector_name: “UcmNfsStore”: 指定
UcmNfsStore作为 UCM 连接器。storage_backends: 指定用于存储 KV 块的目录。它可以是本地目录或 NFS 挂载路径。UCM 将在此处存储 KV 块。⚠️ 请务必将
"/mnt/test"替换为您的实际存储目录。use_direct: 是否启用直接 I/O(可选)。默认为
false。load_only_first_rank: 控制是否仅 rank 0 加载 KV 缓存并广播给其他 rank。
此功能目前在 Ascend 上不受支持,因此必须设置为false(所有 rank 独立加载/转储)。
启动推理#
在本指南中,我们描述了使用 vLLM 和 UCM 连接器的**在线推理**,并将其部署为兼容 OpenAI 的服务器。为了获得 UCM 的最佳性能,建议将 block_size 设置为 128。
要使用 Qwen/Qwen2.5-14B-Instruct 模型启动 vLLM 服务器,请运行:
vllm serve Qwen/Qwen2.5-14B-Instruct \
--max-model-len 20000 \
--tensor-parallel-size 2 \
--gpu_memory_utilization 0.87 \
--block_size 128 \
--trust-remote-code \
--port 7800 \
--enforce-eager \
--no-enable-prefix-caching \
--kv-transfer-config \
'{
"kv_connector": "UCMConnector",
"kv_role": "kv_both",
"kv_connector_extra_config": {"UCM_CONFIG_FILE": "/vllm-workspace/unified-cache-management/examples/ucm_config_example.yaml"}
}'
⚠️ 请务必将 "/vllm-workspace/unified-cache-management/examples/ucm_config_example.yaml" 替换为您的实际配置文件路径。
如果您看到如下日志:
INFO: Started server process [1049932]
INFO: Waiting for application startup.
INFO: Application startup complete.
恭喜,您已成功启动带有 UCM 连接器的 vLLM 服务器!
评估 UCM 前缀缓存性能#
启动启用了 UCMConnector 的 vLLM 服务器后,观察前缀缓存效果的最简单方法是运行内置的 vllm bench CLI。在单独的终端中**执行两次**以下命令将清晰地展示改进效果。
vllm bench serve \
--backend vllm \
--model Qwen/Qwen2.5-14B-Instruct \
--host 127.0.0.1 \
--port 7800 \
--dataset-name random \
--num-prompts 12 \
--random-input-len 16000 \
--random-output-len 2 \
--request-rate inf \
--seed 123456 \
--percentile-metrics "ttft,tpot,itl,e2el" \
--metric-percentiles "90,99" \
--ignore-eos
首次执行后#
vllm bench 终端打印出基准测试结果:
---------------Time to First Token----------------
Mean TTFT (ms): 15323.87
检查 vLLM 服务器日志会发现类似以下条目:
INFO ucm_connector.py:228: request_id: xxx, total_blocks_num: 125, hit hbm: 0, hit external: 0
这表明对于第一个推理请求,UCM 没有命中任何缓存的 KV 块。因此,必须计算完整的 16K token 的预填充,这导致了相对较大的 TTFT(Time To First Token)。
第二次执行后#
再次运行相同的基准测试会产生:
---------------Time to First Token----------------
Mean TTFT (ms): 1920.68
vLLM 服务器日志现在包含类似的条目:
INFO ucm_connector.py:228: request_id: xxx, total_blocks_num: 125, hit hbm: 0, hit external: 125
这表明在第二个请求中,UCM 成功地从存储后端检索了所有 125 个缓存的 KV 块。利用完全缓存的前缀极大地减少了模型观察到的初始延迟,与首次运行时相比,TTFT 大约**提高了 8 倍**。