llama.cpp 上下文扩展成果报告:128K → 192K (+50%) 的实测校准之路
日期: 2026-08-16 晚
环境: 双 RTX 3090 24GB · Ryzen 5950X · llama.cpp server-cuda (b10326) · Qwen3.8-27B IQ4_XS GGUF
成果: 单卡上下文从 131,072 → 196,608 tokens(+50%),速度仅 -6%,精度近无损
方法论: 借鉴 SGLang 预算链经验 + 决定性实验裁决文档矛盾
摘要
在 SGLang 上下文扩展成功(65K→119K)的启发下,对 llama.cpp 做同等深度研究。发现文档中”q8/q4 非对称 KV 慢 17%”的结论已过时——实测仅慢 ~6%,且精度近无损(KLD 0.005)。据此将 V cache 从 q8_0 降到 q4_0,上下文从 128K 扩到 192K(考虑 GPU0 接显示器需预留显存,取 192K 而非极限 204K)。
| 配置 | ctx | 显存 | 速度 | 精度 |
|---|---|---|---|---|
| 生产旧(q8/q8) | 131,072 | 21.4 GB | ~73 t/s* | 基准 |
| 生产新(q8/q4) | 196,608 | 22.4 GB | ~50 t/s | KLD 0.005 |
> *128K 的 73 t/s 为早期短上下文数据;本次 200 token 输出实测 ~50 t/s(含 prefill)。
一、研究起点:显存预算链
借鉴 SGLang 经验,先摸清 llama.cpp 的显存构成:
24GB 总显存
→ 模型权重 IQ4_XS (15.9GB) + mmproj (0.9GB)
→ KV cache (ctx × K/V 量化)
→ MTP draft KV (0.1GB, q4_0)
→ compute buffer (随 ctx 增长)
→ 桌面系统预留 (zap/Xorg, GPU0 接显示器!)
核心洞察:llama.cpp 的上下文杠杆 = KV 量化精度(每 token 占用),但受 compute buffer 二次限制。
每 token KV 占用推算
Qwen3.8-27B:16 层 full attention × 4 KV heads × 256 head_dim
| KV 类型 | 每 token | 128K | 说明 |
|---|---|---|---|
| bf16/f16 | 64 KB | 8 GB | 精度上限 |
| q8_0/q8_0 | 32 KB | 4 GB | 近无损,现用 |
| q8_0/q4_0 | 24 KB | 3 GB | 近无损,省 25% |
二、文档矛盾:17% 速度代价需要裁决
旧文档两处冲突
一、部署文档(llamacpp-27b-deployment-and-tuning.md §3.2): “对称 q8_0/q8_0 比不对称快 17%,GPU 可一次性加载 K 和 V 的 8-bit 值”
二、部署调优文档(sglang-qwen3.8-27b-deployment-tuning.md §5.2): “llama.cpp dequantize_V_q4_0 (forceinline) 融合在 FA kernel 内部,零开销”
一个说慢 17%,一个说零开销——只能用决定性实验裁决。
决定性实验(同配置 160K,200 token 输出)
| 配置 | 显存 | 速度(3次) | 均值 |
|---|---|---|---|
| q8_0/q8_0 | 23.5 GB | 50.7/50.5/54.6 | ~51.9 t/s |
| q8_0/q4_0 | 21.4 GB | 46.0/51.4/48.5 | ~48.6 t/s |
结论:速度差仅 6.4%(非文档 17%)。文档结论过时(Qwen3.6 时代旧测量法),新架构 + FA 融合下 q8/q4 代价很小。
三、上下文极限探索:compute buffer 是第二道锁
用 q8/q4 逐级测试 ctx 上限:
| ctx | 结果 | 显存 | 关键 |
|---|---|---|---|
| 163,840 (160K) | ✅ | 21.4 GB | 正常 |
| 196,608 (192K) | ✅ | 22.4 GB | 正常 |
| 209,715 (204K) | ✅ | 22.8 GB | 正常 |
| 262,144 (256K) | ❌ OOM | — | failed to allocate compute buffers |
关键发现:256K 失败不是 KV 不足,而是 compute buffer(graph 计算缓冲)分配失败。ctx 增大不仅增加 KV,还增大 compute buffer——这是 llama.cpp 上下文扩展的第二道锁(类似 SGLang 的 activation reserve 锁)。
四、显存预留考量:为什么选 192K 而非 204K
GPU0 接显示器 + 桌面系统(zap/Xorg/GNOME)需要显存:
204K 时:22.8 GB 占用,仅余 ~1.6 GB 给桌面。192K 时:22.4 GB 占用,余 ~1.7 GB(桌面约需 0.2-0.6GB,安全)。
为防系统崩溃,取 192K(保守方案),比极限 204K 更稳妥,上下文已 +50% 足够。
五、当前最终配置(生产运行中)
lla-qwen27b:
command: >
-m /models/Qwen3.8-27B-GGUF/Qwen3.8-27B-IQ4_XS.gguf
--mmproj /models/Qwen3.8-27B-GGUF/mmproj-F16.gguf
--host 0.0.0.0 --port 8080
--ctx-size 196608
--cache-type-k q8_0 --cache-type-v q4_0
--flash-attn on
--image-min-tokens 1024
--parallel 1
--n-predict 16384
-ngl 99 -t 8 -tb 4 -b 2048 -ub 1024
--load-mode none --no-mmproj-offload
--spec-type draft-mtp --spec-draft-n-max 2
--spec-draft-type-k q4_0 --spec-draft-type-v q4_0
运行指标:ctx 192K · KV K=q8_0/V=q4_0 · 显存 22.4GB + 余 1.7GB · 推理/代码生成验证通过
六、方法论沉淀(与 SGLang 研究的共通经验)
1. 文档结论会过时,实测裁决
两篇文档互相矛盾(17% vs 零开销),决定性实验证明都过时(实际 6%)。文档是时点快照,实测是现行事实。
2. 预算链思考法(两引擎通用)
上下文 = 显存预算链逐环节压缩。SGLang 找”非必要预留”(CUDA IPC 池),llama.cpp 找”可降精度项”(V cache)——都是找到显存里可挤出的部分。
3. 第二道锁意识
SGLang 有 activation reserve 锁(2048 下限),llama.cpp 有 compute buffer 锁。KV 显存够 ≠ 能跑,计算缓冲随 ctx 增长是隐性瓶颈。
4. 系统级预留考量
GPU0 接显示器需给桌面留显存——纯显存优化的极限方案要结合真实环境(桌面/多任务)取保守值。
七、相关文档
../deployment/llamacpp-27b-deployment-and-tuning.md §3.2/§9.4 — 已修正 17%→6% 结论;../deployment/current-configuration.md — 当前配置总览(GPU0 ctx 196608);../deployment/llamacpp-qwen3.6-27b-optimization-guide.md §优化4 — KV 量化精度分析(q8/q4 KLD 0.005);sglang-context-extension-breakthrough-2026-08-16.md — SGLang 版成果报告(本研究的启发来源)。
本文记录 2026-08-16 晚 llama.cpp 上下文扩展的完整研究与实测,含文档纠偏和决策考量,可直接复现。
