■ space · 机器车间 · fig 1

■ 先说答案

Llama 3.1 8B at 131,072 tokens in fp16: KV cache ≈ 16 GiB —— 和权重一样大。

那个「装得进 16 GiB 的 8B」变成了 32 GiB 的问题。

cache 是 随上下文线性增长、开工前就全额划走的 ——不管你填不填满,RAM 都要为 128k 买单。

解法很无聊: 把上下文设成你真正用到的量 —— 32k 的窗口只要 128k cache 的四分之一。

16.0GiB —— 128k 的 kv cache · llama 3.1 8b · fp16
131,072个 token,填不填满都计费
128 KiB固定费 —— 每个 token 都有,llama 8b

01计量台

租客是 kv cache —— 轮子转出那张显卡从不打印的账单

FIG 1 · KV-CACHE 计量台按键 1 · 2 · 3 · 4 —— 或用按钮
租客账本KV CACHE · 实时计量租客 · LLAMA 3.1 8B32 层 × 8 个 KV 头RAM 计量 · 预先付清KV CACHE · 账单已计费1600GiB权重 · 模型160GiBCACHE = 权重窗口128k固定费128 KiB/TOK已进 token000000

CACHE = 权重满窗时 cache 和它所属的模型一样大 —— 一个 32 GiB 的租约就此生效

租客 LLAMA 3.1 8B · 窗口 128k · 131,072 TOKENS · CACHE 16.00 GiB · 权重 16.0 GiB · 份额 100% · 已喂 0

轮子在里程表动之前就把账记了 —— 划款在前,填满是可选项

02被卡片们省略的公式

一条公开公式转动了这些轮子上的每一个数字

算术 —— 如 transformer inference arithmetic 所述
cache_bytes = 2 × layers × context × kv_heads × head_dim × bytes_per_element

「上下文窗口不是一个可以拨动的开关功能。它是一纸内存租约,服务器每活着一秒,你就付一秒的账。」

整笔账 —— 两行代码对着公开的 config.json 验算
def kv_cache_gib(layers, kv_heads, head_dim, ctx, bytes_per=2):
    return 2 * layers * ctx * kv_heads * head_dim * bytes_per / 2**30

print(kv_cache_gib(32, 8, 128, 131_072))  # Llama 3.1 8B  -> 16.0
print(kv_cache_gib(28, 4, 128, 131_072))  # Qwen2.5 7B    -> 7.0

verify: kv_cache_gib(32, 8, 128, 131_072) → 16.0 · kv_cache_gib(28, 4, 128, 131_072) → 7.0

2 个张量—键 + 值,每一层、每个 KV 头、每个 token 都要缓存 —— 什么都不重算,全都记着
为什么线性—单个 token 的存储量是常数,所以总存储随上下文线性增长 —— 是 1k 窗口 cache 的 128×,贯穿整个会话的生命期
为什么预先划款—服务栈在加载时就分配整个窗口 —— 不管你填不填满,RAM 都为 128k 买单

03两个租客,一张台面

公式只是算术,直到它并排给两张真实的模型卡片标出价格

模型 (fp16)层数 × KV 头KV cache @ 128k权重cache 对权重
Llama 3.1 8B32 × 8~16 GiB~16 GiB~100%
Qwen2.5 7B28 × 4~7 GiB~15 GiB~47%

按台面上的 1 键 —— 同一个 128k 窗口在 qwen2.5 7b 上重新计量成 7.0 GiB

模型侧的折扣—grouped-query attention(GQA):更少的 KV 头,更薄的 cache —— 是架构,不是量化
为什么 qwen 显得友好—它的 28 层 × 4 个 KV 头 正是同一个窗口只需 约 7 GiB 的原因 —— 在寒酸的小机器上也是实在的减负
头们藏在哪—spec 很少写明 KV 头数 —— 你得去 config.json 里挖,这也说明了这个数字本来该怎么读

04账单在哪里弯折

计量器对 full attention 很诚实 —— 在你签字之前有四个弯折点

prefill · 第二张账单—一个 100k token 的 prompt 在第一个输出字符之前就被整体咀嚼 —— 在 3060 上是几分钟,不是几毫秒
滑窗模型—mistral 式的 attention 按层封顶,cache 随之停止增长 —— 公式会高估它们,对你有利
KV 量化—llama.cpp 可以把 KV 缓存成 q8_0,大约砍半,代价是部分质量 —— 16 GiB 的一半也还有 8 GiB
服务栈—vLLM 在 GPU 上吃 GGUF,同一笔内存账单一并附着 —— 量化缩的是权重,cache 的算术一分不减

没人真的读满 128,000 个 token。但每个 token 的 RAM 你照付不误。

解法很无聊—把上下文设成你的工作负载真正用到的量 —— 32k 几乎盖住单个开发者发出的所有 prompt,账单只有四分之一
retrieval 车道—RAG 的本职 —— 把窗口塞满是「去读第 4 节」最贵的说法;用检索代替满窗,因为长上下文不是没用,它是标了价的
■ 诚实印记 实测环境:Llama 3.1 8B · Qwen2.5 7B · fp16 · 131,072 token 窗口 —— 2026-09-22 记录,2026-10-04 刷新。本页每个数字都是把公开公式套在各模型公开的 config.json 上跑出来的(层数、KV 头、head_dim),如 transformer inference arithmetic 所述Transformer Inference Arithmetic —— 台面上的计量器就是同一条公式的 JavaScript 版;一个 bench 都不用买,离你自己的终端只有一个 print 之遥。

租客账本到此为止 · 零 fetch · 全程本地