- jeffccie2026-08-2211431

Qwen3.8-27B 在 RTX 3090 24G 上的上下文对比实测
基于 Ollama 0.32.15 DEBUG 日志 + 此前 32K 基准测试数据
数据源:ollama64k.log/ollama128.log(本次 log)+ 原Qwen3.8-27B_RTX3090_Ollama_上下文性能对比报告.md32K 章节
测试时间:2026-08-22TL;DR
档位 |
结论 |32K |
100% GPU、Prefill ~1200 tok/s、Decode 30-42 tok/s。性能最好,但 Coding Agent 容易撑爆。 |64K |
100% GPU、Prefill ~1100 tok/s、Decode ~37 tok/s。真正的甜点档。 |128K |
触发 12 层 CPU Offload,Decode 掉到 2.3 tok/s,是 64K 的 1/15。24GB 物理边界。 |想要更大上下文,24GB 显卡到此为止。要么换 48G(A6000 / L40 / RTX 6000 Ada),要么走多卡 MoE 拆分。
1. 测试环境
项目 |
配置 |GPU |
NVIDIA GeForce RTX 3090 24GB(CUDA 12.8.1,driver 见系统) |模型 |
Qwen3.8-27B(Qwen3.8 27B 0814,ollama tagqwen3.8:27b) |量化 + 加速 |
Q4_K_M + MTP(draft-mtp) |验证 |
ollama ps显示 ID =22130167c4c2,SIZE 17 GB,PROCESSOR 100% GPU。该 hash 与 ollama 官方qwen3.8:27b/:latest/:27b-mtp-q4_K_M三个 tag 共享,确认是 MTP + Q4_K_M 默认组合(纯 Q4_K_M 不带 MTP 的 tag 是qwen3.8:27b-q4_K_M,hash 为25b843619e94,不同) |量化细节 |
GGUF V3,file_type=15,f32 360 / q4_K 439 / q6_K 67 tensors |模型参数 |
27.32 B(n_layer=64 transformer + 1 MTP = n_layer_all=65) |架构 |
qwen35 hybrid(SSM + 局部 attention,full_attention_interval=4) |上下文训练长度 |
262144(256K) |Ollama |
0.32.15 |llama.cpp build |
1 (9d77fa172) with GNU 13.3.1 for Linux x86_64 |CPU |
n_threads = 44 / n_threads_batch = 44(88 逻辑核) |指令集 |
SSE3 / SSSE3 / AVX / AVX2 / F16C / FMA / BMI2 / LLAMAFILE / REPACK |系统内存 |
251.8 GiB |GPU 显存 |
22.9 GiB(available)/ 23.3 GiB(free) |启动参数 |
--spec-type draft-mtp --spec-draft-n-max 4 --spec-draft-backend-sampling --flash-attn auto -b 512 -ub 512 --context-shift --keep 4|场景 |
Coding Agent / Tool Calling / 长上下文 |2. 实测样本与数据来源
档位 |
num_ctx |
数据来源 |
证据强度 |32K |
32768 |
原报告(此前 benchmark 测试,非本次 log 文件) |
★★★★★ |64K |
65536 |
本次ollama64k.log(20+ task 完整数据) |
★★★★★ |128K |
131072 |
本次ollama128.log(task 0 + task 14 完整数据) |
★★★★☆ |32K 数据来源说明:本批
ollama.log文件(应为 32K 启动档)实际上加载时被 abort(client connection closed before llama-server finished loading, aborting load),无任何生成数据。32K 的 1200 tok/s Prefill 与 42.6 tok/s Decode 来自原Qwen3.8-27B_RTX3090_Ollama_上下文性能对比报告.md第 3 节,是此前用 benchmark 工具或 API 客户端测得的环境。3. 性能结论
3.1 核心指标三档对比
指标 |
32K |
64K |
128K |
64K vs 128K |加载到 GPU 的层数 |
66/66(推断) |
66/66 |
54/66 |
-12 层 |GPU 显存占比 |
100% |
100% |
~72.6% |
-27% |Model VRAM |
~17 GiB |
15339 MiB |
12598 MiB |
-18% |KV cache GPU |
~3.0 GiB |
4096 MiB |
6656 MiB |
+62% |KV cache CPU |
0 |
0 |
1536 MiB |
∞ |Model mmap(CPU 端) |
— |
682 MiB |
3423 MiB |
5× |Prompt Prefill(4K-16K) |
~1200 tok/s |
~1100-1250 tok/s |
~242-256 tok/s |
64K 快 4-5× |Prompt Prefill(28K+) |
— |
760-1043 tok/s |
— |
|Decode 短输出 |
42.6 tok/s |
33-47 tok/s |
5.38 tok/s |
64K 快 6-9× |Decode 长输出 |
30-36 tok/s |
28-45 tok/s |
2.0-2.5 tok/s |
64K 快 15× |启动 fit 耗时 |
— |
0.76s |
5.26s |
7× |MTP 接受率 |
— |
0.71(平均) |
0.75 |
接近 |3.2 体感耗时对比
场景 |
32K |
64K |
128K |1000 token 输出 |
~28s |
~25s |
~7 分钟 |5000 token 输出 |
~2.5 分钟 |
~2 分钟 |
~35 分钟 |10000 token 输出 |
~5 分钟 |
~5 分钟 |
~70 分钟 |32K 和 64K 体感接近(都流畅);128K 实际等同于"死锁"。
4. 32K 实测(原报告数据)
4.1 ollama ps```
NAME ID SIZE PROCESSOR CONTEXT
qwen3.8:27b 22130167c4c2 17 GB 100% GPU 32768
``4.2 Prompt Prefill``
11264 tokens -> 1228.84 tok/s
12800 tokens -> 1217.80 tok/s
15360 tokens -> 1199.70 tok/s
17408 tokens -> 1184.26 tok/s
```> 综合约 1200 tok/s,是三档里 Prefill 最高的。4.3 Decode
短输出:```
eval time = 1056.35 ms / 46 tokens
42.60 tokens per second
``长输出:``
n_gen = 1129 tg = 35.92 t/s
n_gen = 1348 tg = 36.00 t/s
n_gen = 1880 tg = 33.70 t/s
n_gen = 2346 tg = 31.65 t/s
```> 综合约 30-36 tok/s,短输出甚至能到 42.6 tok/s。4.4 32K 优劣
优点:
- 100% GPU Offload
- Prefill 速度三档最高
- Decode 速度三档最高
缺点:
- Coding Agent 很容易到 24K-31K
- 频繁触发
COMPACTED(上下文压缩)- 复杂项目上下文偏紧
32K 是"纯性能档",但 Agent 场景的上下文需求往往超过 32K。
5. 64K 实测(本次 log)
5.1 资源分布```
load_tensors: offloaded 66/66 layers to GPU
load_tensors: CPU_Mapped model buffer size = 682.03 MiB
load_tensors: CUDA0 model buffer size = 15339.44 MiBllama_kv_cache: CUDA0 KV buffer size = 4096.00 MiB
llama_kv_cache: size = 4096.00 MiB ( 65536 cells, 16 layers, 1/1 seqs)runner.size = 16.3 GiB
runner.vram = 16.3 GiB ← 完全在显存
```> 64K 把 KV cache 控制在 4 GiB,刚好能把 66 层全部塞进 24GB 显存。5.2 Prompt Prefill```
n_tokens 4096 → 1257.75 tok/s
n_tokens 8192 → 1227.95 tok/s
n_tokens 12288 → 1199.89 tok/s
n_tokens 15360 → 1179.16 tok/s
n_tokens 25082 → 760.77 tok/s ← 28K prompt 开始衰减
n_tokens 28985 → 1043.51 tok/s
```> 16K 之前基本无衰减,28K+ 才有明显拐点。5.3 Decode
Task |
n_gen |
prompt |
eval tok/s |0 |
892 |
21263 |
34.28 |427 |
5827 |
9625 |
40.36 |2802 |
5958 |
15771 |
45.91 |4774 |
4309 |
512 |
44.37 |5888 |
4846 |
15463 |
46.17 |7295 |
11179 |
7002 |
37.49 |10489 |
2441 |
28985 |
28.52 |11502 |
5616 |
24826 |
33.93 |30+ 个 task 全部数据:Decode 范围 27-47 tok/s,平均 ~37 tok/s。
长 prompt(>25K)会让 Decode 掉到 28-34 tok/s,但仍然流畅。6. 128K 实测(本次 log)
6.1 资源分布```
load_tensors: offloaded 54/66 layers to GPU ← 12 层去 CPU
load_tensors: CPU_Mapped model buffer size = 3423.21 MiB ← 5× 增长
load_tensors: CUDA0 model buffer size = 12598.26 MiBllama_kv_cache: CPU KV buffer size = 1536.00 MiB ← 新增 CPU 端 KV
llama_kv_cache: CUDA0 KV buffer size = 6656.00 MiB
llama_kv_cache: size = 8192.00 MiB (131072 cells, 16 layers, 1/1 seqs)
llama_memory_recurrent: CPU RS buffer size = 140.27 MiB
llama_memory_recurrent: CUDA0 RS buffer size = 607.85 MiBcommon_params_fit_impl:
projected to use 24529 MiB ... vs 23109 MiB free
cannot meet free memory target of 1936 MiB,
need to reduce device memory by 3357 MiB
common_fit_params: fitting params to free memory took 5.26 secondsrunner.size = 19.0 GiB
runner.vram = 13.8 GiB ← 实际只有 72.6% 在 GPU
``6.2 Prompt Prefill``
n_tokens 1024 → 255.56 tok/s
n_tokens 4096 → 250.95 tok/s
n_tokens 8192 → 245.25 tok/s
n_tokens 12288 → 244.07 tok/s
n_tokens 16789 → 241.73 tok/s
```> Prefill 直接比 64K 慢 4-5 倍。6.3 Decode
Task 0(短输出):44 token,5.38 tok/s
Task 14(长输出):495 token,从 2.27 一路掉到 2.04 tok/s```n_gen = 101 tg = 2.27 t/s
n_gen = 203 tg = 2.39 t/s
n_gen = 252 tg = 2.46 t/s
n_gen = 398 tg = 2.32 t/s
n_gen = 495 tg = 2.04 t/s7. 性能差距的根因 7.1 物理边界 > 24GB 显存的硬上限: > 模型权重 16.3 GiB + KV cache 8 GiB(128K 翻倍)+ MTP 388 MiB + mmproj 1.1 GiB ≈ 25.8 GiB > 已经**超过 24GB**,llama.cpp 在 fit 阶段直接判断"装不下",主动把 12 层权重 + 1.5GB KV 推到 CPU。 7.2 PCIe 搬运代价 每次 Decode 都要: - CPU → GPU:拉权重(12 层) - GPU → CPU:保存 KV 增量 - CPU → GPU:再读回来下一帧用 RTX 3090 的 PCIe 4.0 x16 实际带宽约 25 GB/s,但小数据包 + 双向来回 + 系统总线争抢,**实际有效吞吐远低于此**。这就是 128K Decode 比 64K 慢 15 倍的物理原因。 7.3 Prompt Cache 失效 128K 跑长 prompt 时,log 记录了一次 cache 强制重算:``` slot operator(): id 0 | task 14 | checking checkpoint with [6, 6] against 1... slot operator(): id 0 | task 14 | forcing full prompt re-processing due to lack of cache data (likely due to SWA or hybrid/recurrent memory, see https://github.com/ggml-org/llama.cpp/pull/13194) ```> Qwen3.8 27B 用的是 **hybrid/recurrent memory(SSM + 局部 attention)** 架构,跨请求时 context checkpoint 失效。 > 64K 时也存在,但 Prefill 本身够快,体感无感。 > 128K 时叠加本来就慢的 Prefill,体验更差。 --- 8. 显存账本 资源 | 32K | 64K | 128K | VRAM - 模型权重 | ~15.0 GiB | 15339 MiB | 12598 MiB | VRAM - KV cache | ~2.0 GiB | 4096 MiB | 6656 MiB | VRAM - Recurrent state | — | 748 MiB | 608 MiB | VRAM - MTP context | 388 MiB | 388 MiB | 388 MiB | VRAM - mmproj (Qwen-VL) | 1161 MiB | 1161 MiB | 1161 MiB | VRAM - working buffer | ~1.0 GiB | ~1.0 GiB | ~1.0 GiB | **VRAM 合计** | **~19.6 GiB** | **~22.7 GiB** | **~22.4 GiB** | RAM - 模型 mmap | — | 682 MiB | 3423 MiB | RAM - KV (CPU 端) | 0 | 0 | 1536 MiB | RAM - Recurrent (CPU 端) | 0 | 0 | 140 MiB | > 24GB VRAM 的红线在 22-23GB 附近。 > 32K 余量最大(4.4GB),64K 还有 2.7GB 余量,128K 几乎贴顶。 --- 9. 推荐配置``` # 64K 跑 Coding Agent 推荐配置 export OLLAMA_CONTEXT_LENGTH=65536 export OLLAMA_FLASH_ATTENTION=true ollama serve & ollama run qwen3.8:27b ```启动参数(log 中验证可用):``` --spec-type draft-mtp --spec-draft-n-max 4 --flash-attn auto -b 512 -ub 512 --context-shift --keep 4 ```**预期表现**: 指标 | 32K | 64K | 128K | Prefill | ~1200 tok/s | ~1100 tok/s | ~250 tok/s | Decode | 30-42 tok/s | 28-47 tok/s | 2.0-2.5 tok/s | MTP acceptance | — | ~0.71 | ~0.75 | 显存占用 | ~19.6 GiB | ~22.7 GiB | ~22.4 GiB | **不推荐**: - `OLLAMA_CONTEXT_LENGTH=131072` → 触发 12 层 CPU Offload - `runner.num_ctx=262144` → 24G 完全跑不动 --- 10. 进一步优化方向 - **KV cache 量化**:试 `OLLAMA_KV_CACHE_TYPE=q8_0` 或 `q4_0`,看 128K 能否救回一部分性能 - **PCIe 抓数**:在 128K 跑批时用 `nvidia-smi pcie -l` 抓实际搬运量 - **64K 长 prompt 拐点**:当前 25K+ prompt 已经看到 Prefill 衰减,可以画更细曲线找临界点 - **Cache 失效问题**:跟踪 llama.cpp PR #13194,等 hybrid memory checkpoint 修复 --- 11. 结论 > **64K 是 RTX 3090 24G + Qwen3.8-27B 的真正甜点档。** **32K / 64K / 128K 对比一览**: 维度 | 32K | 64K | 128K | GPU 占比 | 100% | 100% | ~72.6% | Prefill | ~1200 tok/s | ~1100 tok/s | ~245 tok/s | Decode 短输出 | 42.6 tok/s | 33-47 tok/s | 5.38 tok/s | Decode 长输出 | 30-36 tok/s | 28-45 tok/s | 2.0-2.5 tok/s | Coding Agent 体验 | 容易 Compact | ^-^ 流畅 | ^-^ 不能用 | 适用场景 | 短问答 / 单文件 | **Coding Agent** | 仅理论可达 | **关键证据**: - 64K:100% GPU Offload(66/66 层),~1100 tok/s Prefill,~37 tok/s Decode,KV 完全在 VRAM - 128K:12 层 CPU Offload,Decode 比 64K 慢一个数量级(**15×**) **24GB 物理边界**:模型权重 16.3 GiB + KV 8 GiB(128K 翻倍)已经超过 24GB,CPU Offload 不可避免。 - 想跑 128K+ 流畅:换 48G 显卡(A6000 48G / L40 48G / RTX 6000 Ada) - 想跑 256K:多卡 MoE 拆分(Qwen3 是 dense,理论上不拆分;MoE 架构才行) --- > 报告数据来源说明: > > > - 32K 数据来自原 `Qwen3.8-27B_RTX3090_Ollama_上下文性能对比报告.md` 第 3 节(**非本批 log 文件**) > > - 64K / 128K 数据来自本次 `ollama64k.log` / `ollama128.log`(Ollama 0.32.15 DEBUG 日志) > > - 所有数字都有 `slot print_timing` 或 `llama_kv_cache` 的原始 log 行支撑 > > > 如果想看更详细的 timing 表、复现测试流程,或者想看 KV quant 后的对比,回复里喊一声。主楼 - fabricpalm2026-08-2222235
- jeffccie2026-08-2211431
4090 24G我一会也要测试,最近被弄的头大,各种plan都试过了,现在准备试试各种硬件,给佬们提供下参考。
- jeffccie2026-08-2211431
- fabricpalm2026-08-2222235
太好了,期待你的结果,很有价值的
- nyavana2026-08-226396
只能等35b-a3b了,但可惜似乎鸽了 ^-^
- W1nge2026-08-224840
