Hybrid Attention 模型#
一些模型在其层中交错使用多种注意力类型——最常见的是在大多数层上使用 sliding-window attention,而在少数层上使用 full attention。vLLM 通过其混合 KV 缓存管理器来服务这些模型,该管理器将模型的层分成多个 KV 缓存组(每种注意力行为一个)。
LMCache 多进程连接器 (LMCacheMPConnector) 支持这些混合模型:它为每个组存储和检索 KV Cache,因此前缀缓存和 KV 重用的工作方式与普通模型相同。
验证过的混合模型#
经过验证的 hybrid attention 架构的配方页面:
模型 |
注意力布局 |
配方 |
|---|---|---|
Gemma 3 |
sliding window + full |
|
Gemma 4 |
sliding window + full |
|
gpt-oss |
sliding window + full |
|
Qwen3.5 / Qwen3.6 系列 |
Mamba / GDN + full |
|
Kimi-Linear |
KDA linear-attention + MLA full |
|
Kimi K3 |
KDA linear-attention + MLA full |
|
DeepSeek-V4-Flash |
稀疏-MLA(多个 KV 组) |
|
GLM 5.1/5.2 |
动态稀疏注意力(多个 KV 组) |
|
MiniMax-M3 |
稀疏注意力 + 闪电索引器(一个组中的混合 KV 格式) |
已支持的内容#
所有层均使用 standard paged attention 的模型——包括混合 sliding-window 和 full attention 的混合模型——在没有特殊配置的情况下得到支持。示例:
模型系列 |
注意力布局 |
状态 |
|---|---|---|
Gemma 2 / Gemma 3 |
交错 sliding-window + full |
支持 |
gpt-oss |
交错 sliding-window + full |
支持 |
Qwen3.5(以及其他 Gated-DeltaNet 混合模型) |
交错 Mamba/GDN + full |
支持(见下文) |
Llama, Qwen2/Qwen3 (dense), Mistral, … |
单一注意力类型 |
支持 |
只需像往常一样将 vLLM 指向 LMCache 服务器(请参见 快速入门);LMCache 在注册时会自动检测模型的 KV 缓存组。
备注
因为 LMCacheMPConnector 向 vLLM 声明了混合支持,vLLM 为这些模型保持其混合 KV 缓存管理器 启用(它不会回退到单一统一组)。您不需要 --no-disable-hybrid-kv-cache-manager 或任何相关标志。
对象组分离#
在 KV-cache 注册时,LMCache 将混合模型的层分组为 对象组 —— 它作为一个对象存储和检索的单位。默认情况下(--separate-object-groups,开启),每个不同的跨块注意力窗口会成为自己的对象组:全注意力层形成一个组,而每个滑动窗口大小(包括 mamba / GDN)形成另一个组。传递 --no-separate-object-groups 可以将每一层保留在一个单一的全注意力对象组中(之前的行为)。
# default: one object group per attention window
lmcache server --chunk-size 256 --l1-size-gb 100
# opt out: a single full-attention object group for all layers
lmcache server --chunk-size 256 --l1-size-gb 100 --no-separate-object-groups
该标志对正确性是透明的——前缀缓存和 KV 重用在任何情况下的行为都是相同的,非混合模型(单一注意力行为)无论设置如何始终解析为一个对象组。分离通过注意力窗口组织存储,以便每个组的跨块窗口可以独立跟踪。
Mamba / Linear-Attention 混合模型#
Models that interleave Mamba / Gated-DeltaNet (GDN) linear-attention layers
with full attention — the Qwen3.5 and Qwen3.6 series (Qwen/Qwen3.5-0.8B,
Qwen/Qwen3.6-27B, …), Qwen3-Next, Kimi-Linear
(moonshotai/Kimi-Linear-48B-A3B-Instruct), Kimi K3
(moonshotai/Kimi-K3), and other GDN hybrids — are supported.
Unlike a paged key/value cache, their linear-attention layers keep a recurrent
state cache (a convolution + SSM state). LMCache reinterprets that state as
an opaque page at registration time, so prefix caching and KV reuse work end to
end without any model-specific transfer code.
本节是 任何此类模型的一般过程。唯一的每模型变量是统一块大小N(步骤 1);其他所有内容在模型之间是相同的。
步骤 1 — 找到模型的统一块大小 N#
N 是驱动所有其他设置的 单一数字:LMCache 服务器的 --chunk-size 和 vLLM 的 --max-num-batched-tokens 都源自它(步骤 2)。如果设置错误,LMCache 在引擎启动时会抛出错误。
对于 Mamba / GDN 混合模型,vLLM 强制所有 KV Cache 组使用 一个 块大小,选择足够大以确保注意力页面至少与 Mamba 状态页面一样大。它依赖于模型的头部维度和 GDN 状态大小,因此是 模型特定的 — 切勿假设一个值,请从模型中读取。vLLM 在启动时打印一次:
INFO ... interface.py:670] Setting attention block size to 784 tokens to
ensure that attention page size is >= mamba page size.
您不需要 LMCache、完整的服务运行或量化的权重来读取它——只需启动 vLLM,直到该行出现,然后停止。下面的代码片段正是这样做,并打印 N:
MODEL=Qwen/Qwen3.6-27B
LOG=$(mktemp)
# Launch vLLM just far enough to size the KV cache; cheap settings only.
vllm serve "$MODEL" \
--mamba-cache-mode align --enable-prefix-caching \
--max-model-len 8192 --gpu-memory-utilization 0.5 \
--port 8011 > "$LOG" 2>&1 &
VLLM_PID=$!
# Wait for the block-size line (or a fatal error), then stop vLLM.
until grep -qiE "Setting attention block size|Error|Traceback" "$LOG"; do
sleep 3
done
grep -i "Setting attention block size" "$LOG"
kill "$VLLM_PID"
to N tokens 中的数字就是您的 N。随着模型大小的增加,值会增长;例如:
模型 |
统一块大小 |
GPU |
|---|---|---|
|
784 |
1 |
|
544 |
1 |
|
944 |
2 |
|
768 |
8 |
步骤 2 — 从 N 派生三个所需的标志#
LMCache 服务器
--chunk-size= N(或任何N的倍数)。这是连接器强制执行的规则:LMCache 的块大小必须是 vLLM 的统一块大小的倍数,否则注册将失败:lmcache server --chunk-size 784 --l1-size-gb 100 --eviction-policy LRUvLLM
--max-num-batched-tokens在 [N, 2·N) — 将其设置为N是简单且始终有效的选择。在此范围之外,LMCache 在引擎启动时会引发错误。align模式仅在每个调度器步骤的结束时快照 Mamba 状态,因此每个预填充步骤必须精确推进一个块;更大的预算将允许步骤跳过块边界,从而在这些前缀处没有快照可供 LMCache 存储。vLLM
--mamba-cache-mode align --enable-prefix-caching—align是强制性的(GDN 后端不支持all模式)::vllm serve <model> \ --enable-prefix-caching --mamba-cache-mode align \ --max-num-batched-tokens 784 \ --kv-transfer-config \ '{"kv_connector":"LMCacheMPConnector", "kv_role":"kv_both"}'
因此,对于一个新探测的模型,整个推导过程就是:读取 N(步骤 1),然后将 --chunk-size N 传递给服务器,并将 --max-num-batched-tokens N 传递给 vLLM。
不需要 --no-disable-hybrid-kv-cache-manager 或 attention-backend 标志;LMCacheMPConnector 声明支持混合模型,vLLM 会自动选择 GDN 后端。
注意事项#
生成在缓存和新运行之间不是位精确的:GDN 后端不支持 vLLM 的批量不变模式。请使用分数级比较进行验证(参见 验证正确性),而不是 token 级差异。
缓存页面是 字节不透明 的,因此内容感知特性(CacheGen 压缩、CacheBlend)不适用,并且缓存条目不得在具有不同注意力后端或内核块大小的引擎之间共享。
这些模型中的几个是 视觉-语言 模型(它们加载一个视觉塔)。经过验证的支持路径是 文本 KV 缓存;图像/视频 KV 缓存尚未经过验证。
vLLM 的 Mamba 前缀缓存在
align模式下被标记为实验性。
请参阅 Qwen3.5 / Qwen3.6 配方 以获取经过验证的端到端命令和每个模型的块大小。
验证正确性#
为了确保混合模型的 KV 被正确缓存和重用,您可以将冷启动与从 LMCache 提供的运行进行比较:
对 vLLM + LMCache 运行评估(例如在
gsm8k上使用lm_eval)。这会计算 KV Cache 并 存储 在 LMCache 中。仅重置 vLLM 的本地前缀缓存,保持 LMCache 管理的缓存不变(需要以
VLLM_SERVER_DEV_MODE=1启动 vLLM):curl -X POST http://localhost:8000/reset_prefix_cache省略
reset_external=true查询参数,以便保留 LMCache 缓存。重新运行相同的评估。vLLM 现在在其本地缓存中未命中,因此前缀 KV 从 LMCache 中 检索。得分应与第一次运行匹配。
该项目以 hma_lm_eval 持续集成测试的形式提供此验证(参见 .buildkite/k3_tests/multiprocess)。
另请参阅#
快速入门 — 启动 LMCache 服务器和 vLLM 客户端。
关于如何检测和处理组的设计说明:
docs/design/integration/vllm/hybrid-kv-cache-groups.md在源代码树中。