16GB 跑35B大模型+200K 上下文:Claude Code + Qwen3.6 极限调优

73 阅读7分钟

16GB 显卡跑 200K 上下文:Claude Code + Qwen3.6 35B-A3B 极限调优实战

在 NVIDIA GeForce RTX 4080 SUPER 16GB 上,通过 IQ3 量化 + TurboQuant KV 压缩 + Claude Code prompt cache 优化,实现 Qwen3.6-35B-A3B 模型 200K 上下文流畅运行,prompt 处理延迟从 28.6s 降至 87ms。


背景

Claude Code 默认使用 Anthropic 官方 API,但对于私有化部署或成本敏感场景,通过 llama.cpp 的 Anthropic Messages API 兼容端点(/v1/messages)连接本地模型已成为可行方案。然而,将 MoE 大模型 + 超长上下文 + Claude Code 工作流组合在一起,会遇到一系列棘手问题:

  1. VRAM 不足:35B MoE 模型全精度权重约 70GB,远超 16GB 显存
  2. KV cache 膨胀:200K 上下文 KV cache 随量化精度线性增长,FP16 下可达 10GB 以上
  3. Prompt cache 失效:Claude Code 的动态 header 注入导致 llama.cpp 每次全量重算

经过一系列踩坑和优化,我们找到了一套可行方案。


硬件与软件环境

组件规格
GPUNVIDIA GeForce RTX 4080 SUPER 16GB (16376 MiB)
CPUAMD Ryzen 9 5950X 16-Core (3.826 GHz, 16C32T)
系统内存128 GiB DDR4-3200
CUDA12.8
操作系统Ubuntu 24.04.3 LTS, Kernel 6.17.0-20-generic
模型Qwen3.6-35B-A3B-UD-IQ3_S.gguf
量化IQ3_S(~3.44 bpw,模型文件 12.73 GiB)
KV CacheTurboQuant turbo3(3-bit,~5x 压缩)
上下文200K tokens
推理引擎llama.cpp(turboquant/feature/turboquant-kv-cache 分支)
客户端Claude Code(通过 Anthropic Messages API 连接)

第一步:让模型在 16GB 上跑起来

MoE 模型的参数激活特性

Qwen3.6-35B-A3B 是一个 MoE(Mixture of Experts)模型,总参数 35B,但每次推理仅激活约 3B 参数。这意味着虽然权重文件很大,但计算负载和激活内存远低于传统 Dense 模型。

量化选择

量化方案模型大小VRAM 需求(权重+KV)可行性
FP16 全精度~70GB~70GB + KV❌ 不可能
Q8_0~38GB~38GB + KV❌ 不可能
Q4_K_M~21GB~21GB + KV❌ 放不下
IQ3_S12.73 GiB12.34 GiB + 0.76 GiB + 0.25 GiB✅ 可行

llama-server 实际显存占用

llama.cpp 启动时输出的精确显存分配:

load_tensors:        CUDA0 model buffer size = 12634.81 MiB  (12.34 GiB)
load_tensors:  CPU_Mapped model buffer size =   397.85 MiB
llama_kv_cache:      CUDA0 KV buffer size =   781.38 MiB  (0.76 GiB)
  ├─ K (turbo3):       390.62 MiB
  ├─ V (turbo3):       390.62 MiB
llama_memory_recurrent:  CUDA0 RS buffer size =   251.25 MiB  (0.25 GiB)
llama_context:     CUDA_Host  output buffer =     3.79 MiB

GPU 显存总计:14860 MiB(14.51 GiB)/ 16376 MiB(16 GiB)

日志列出的组件之和为 13671 MiB(13.35 GiB),与 nvidia-smi 实际观测值 14860 MiB 相差 ~1189 MiB。llama.cpp 日志未打印 flash-attn 工作区大小,根据经验估算该差值来自 flash-attn 的 intermediate tensor buffer 和 attention softmax 临时空间。

llama-server 配置

#!/bin/bash
/opt/llama.cpp/bin/llama-server \
  --model /home/work/models/Qwen3.6-35B-A3B-UD-IQ3_S.gguf \
  --ctx-size 204800 \
  --batch-size 1024 \
  --ubatch-size 512 \
  --cache-reuse 256 \
  --cache-ram 32768 \
  --n-gpu-layers 99 \
  --threads 24 \
  --cache-type-k turbo3 \
  --cache-type-v turbo3 \
  --flash-attn on \
  --mlock \
  --temp 0.7 \
  --top-p 0.8 \
  --top-k 20 \
  --min-p 0.05 \
  --reasoning off \
  --port 8080 \
  --host 0.0.0.0

关键参数说明:

  • --ctx-size 204800:200K 上下文窗口
  • --n-gpu-layers 99:尽可能多地将模型层加载到 GPU(99 = 全部)
  • --cache-type-k turbo3 / --cache-type-v turbo3:启用 3-bit TurboQuant KV cache
  • --cache-reuse 256:KV cache 复用粒度,256 tokens 为一个复用单元
  • --cache-ram 32768:系统 RAM 中 prompt cache 上限 32 GiB
  • --flash-attn on:Flash Attention 加速
  • --mlock:锁定内存,防止 swap
  • --threads 24:CPU 线程数(根据实际 CPU 调整)

第二步:编译支持 TurboQuant 的 llama.cpp

官方 llama.cpp 发布版不支持 turbo3 KV cache,需要从 turboquant 分支编译:

git checkout turboquant/feature/turboquant-kv-cache
mkdir -p build && cd build
cmake .. -DGGML_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES="86"
make -j$(nproc)

第三步:连接 Claude Code

llama.cpp 的 --server 模式默认提供 OpenAI 兼容 API。要支持 Claude Code,还需要 Anthropic Messages API 兼容端点。

Claude Code 通过 /v1/messages 端点发送请求,使用 Anthropic Messages API 格式。在 ~/.claude/settings.json 中配置:

{
  "ANTHROPIC_BASE_URL": "http://localhost:8080/v1",
  "ANTHROPIC_API_KEY": "sk-any-key"
}

第四步:解决 Prompt Cache 完全失效(关键!)

问题现象

配置完成后,运行一段时间会发现 llama.log 中每条请求都是:

forcing full prompt re-processing due to lack of cache data
prompt eval time = 28610.97 ms / 94313 tokens

每次请求都重新处理 94000+ token 的完整 prompt,耗时 ~28.6 秒。prompt cache 完全失效。

根因分析

llama.cpp 依赖 prompt 前缀的精确字符串匹配 来复用 KV cache。如果请求的 prompt 开头部分与上次不同,就无法命中 cache。

Claude Code(>= 2.1.36)做了两件事破坏了前缀匹配:

  1. x-anthropic-billing-header 动态变化:每次请求的 cch(Claude Code 版本/会话标识)值都不同,导致 prompt 前缀逐次变化
  2. git status 注入 system prompt:每次文件变更后发送的 git status 输出也会改变 prompt 前缀

解决方案

~/.claude/settings.json 中添加以下配置:

{
  "includeGitInstructions": false,
  "env": {
    "CLAUDE_CODE_ATTRIBUTION_HEADER": "0",
    "DISABLE_TELEMETRY": "1",
    "DISABLE_ERROR_REPORTING": "1",
    "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
  }
}

核心参数:

参数作用
CLAUDE_CODE_ATTRIBUTION_HEADER: "0"禁用动态 telemetry header,最关键
includeGitInstructions: false禁用 git status 注入
DISABLE_TELEMETRY: "1"关闭遥测
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1"禁用非必要网络请求

修改后重启 Claude Code 生效。

效果对比

指标修复前修复后改善
prompt eval 时间~28600 ms87~317 ms90x
每次处理的 token 数9431322~574仅处理 delta
KV cache 命中率0%80.8%前缀匹配
forcing full prompt每次都有永不出现彻底解决

修复后的日志示例:

slot get_availabl: id  3 | task -1 | selected slot by LCP similarity, sim_best = 0.999 (> 0.100 thold), f_keep = 1.000
prompt eval time =      87.05 ms /    22 tokens
prompt eval time =     316.47 ms /   574 tokens
prompt eval time =     102.63 ms /    51 tokens

调优心得与踩坑记录

踩过的坑

  1. --cache-ram 0 会禁用所有跨请求 cache:如果加了 --cache-ram 0 参数,会静默禁用系统 RAM 中的 prompt cache,导致每次请求都全量重算。移除该参数即可。

  2. --mmproj 与 prompt cache 冲突:如果加载了视觉编码器(--mmproj),在旧版本中会破坏 prompt cache 复用。需要使用 b8152+ 版本。

  3. --parallel 参数吃显存--parallel 16 会为每个并发 slot 分配独立的 KV cache,16GB 显存根本撑不住。本地使用不需要并发,保持默认即可。

  4. turbo3 不需要环境变量:在 turboquant 分支中,turbo3 通过 --cache-type-k turbo3 启用,不需要设置 LLAMA_KV_CACHE_TURBO 环境变量。

  5. --cache-reuse 0 的含义:该参数表示"最小复用单元大小",值为 0 表示 unlimited(不限制),不是"禁用"。

性能表现

GPU 显存占用
组件大小
模型权重12634.81 MiB(12.34 GiB)
KV cache(turbo3)781.38 MiB(0.76 GiB)
├─ K (turbo3)390.62 MiB
├─ V (turbo3)390.62 MiB
Recurrent memory251.25 MiB(0.25 GiB)
Output buffer3.79 MiB
GPU 总计14860 MiB(14.51 GiB)/ 16376 MiB
Prompt Eval(Prompt 处理)
指标Cold(全量重算)Warm(Cache Hit)
请求数521
缓存命中率80.8%
处理时间1032 ~ 28611 ms(avg 7100 ms)87 ~ 317 ms(avg 153 ms)
处理 tokens2288 ~ 94313(avg 22161)22 ~ 574(avg 161)
处理速度2218 ~ 3296 tok/s(avg 2551 tok/s)253 ~ 1814 tok/s
累计耗时35.5 s / 110808 tokens
Generation(Token 输出)
指标数值
总请求数30
生成 tokens8399
生成速度avg 41.5 tok/s(38.2 ~ 43.7 tok/s)
系统 RAM
指标数值
系统总内存125 GiB
Prompt cache 上限32 GiB
实际 cache 使用~7.5 GiB(9 个 prompt)

总结

通过 IQ3 量化 + TurboQuant KV 压缩 + Claude Code prompt cache 优化,在 16GB 消费级显卡上实现了 200K 上下文的 Qwen3.6-35B-A3B 模型部署,Claude Code 交互延迟从 28.6 秒降至 87 毫秒级别。

核心三件事:

  1. IQ3 + turbo3 让 35B 模型塞进 16GB 显存
  2. turboquant 分支 提供 3-bit KV cache 支持
  3. CLAUDE_CODE_ATTRIBUTION_HEADER=0 解锁 prompt cache 实战可用


实际使用体验

优化完成后,Claude Code 交互基本流畅。80.8% 的请求命中 prompt cache,每次请求只需 87 ~ 317 ms 处理新增的 22~574 个 token,工具调用和回复几乎没有感知延迟。

生成速度稳定在 41.5 tok/s(38.2~43.7 tok/s),与主流 token plan(50 tok/s)体验接近,阅读体验没有问题。

结论:16GB 显卡跑 Claude Code + 200K 上下文,能用,而且挺好用。