关键词: Qwen3.5、Qwen3.6、llama.cpp、GGUF、Q8_0、TTFT、Prefill、长上下文、L20 48GB、推理性能、单卡部署
先看结论
- 实测: 在同为
Q8_0的前提下,Qwen3.6-35B-A3B在llama.cpp单卡长上下文场景下仍然比Qwen3.5-35B-A3B更慢。 - 实测: 在约
32K输入规模下,Qwen3.6 Q8_0相比Qwen3.5 Q8_0的端到端时延增加约6.9%,TTFT增加约7.1%,输出速度下降约4.1%。 - 实测: 在约
64K输入规模下,这个差距继续扩大到端到端时延+11.7%、TTFT +13.2%,但 decode 速度几乎一样。 - 推导: 这说明当前差距主要发生在 Prefill / 首 token 之前,不是生成阶段本身。
- 实测: 如果把
Qwen3.6的量化从Q8_0换成UD-Q8_K_XL,在约32K输入规模下,还会再额外引入约5%左右的端到端性能损失,且主要还是体现在TTFT。 - 判断: 如果你要比较
Qwen3.5和Qwen3.6的模型代际差异,至少要先把量化格式控制住;否则很容易把"模型更慢"误判成"量化更重"。
一、为什么这篇文章值得写
我最开始做这轮测试时,得到了一组看起来很直观的结果:
Qwen3.5-35B-A3B-Q8_0.gguf- 对比
Qwen3.6-35B-A3B-UD-Q8_K_XL.gguf
结果显示 Qwen3.6 明显更慢。
但这组结论有一个明显问题:
模型版本和量化格式同时变了。
也就是说,当时我比较的其实不是:
Qwen3.5vsQwen3.6
而是:
Qwen3.5 + Q8_0- vs
Qwen3.6 + UD-Q8_K_XL
这在工程上当然也有参考价值,因为真实部署时"模型 + 量化 + 引擎"本来就是一个整体组合;但如果要回答:
Qwen3.6 本身在
llama.cpp下是不是比 Qwen3.5 更慢?
那就必须补一组更公平的实验:
Qwen3.5-35B-A3B-Q8_0Qwen3.6-35B-A3B-Q8_0
我这篇文章,就是基于补完后的数据,把这个问题尽量拆干净。
二、测试对象与测试环境
1. 测试对象
本文涉及三组模型文件:
| 模型 | 文件 | 用途 |
|---|---|---|
| Qwen3.5-35B-A3B | Qwen3.5-35B-A3B-Q8_0.gguf |
和 Qwen3.6 Q8_0 做公平对比 |
| Qwen3.6-35B-A3B | Qwen3.6-35B-A3B-Q8_0.gguf |
和 Qwen3.5 Q8_0 做公平对比 |
| Qwen3.6-35B-A3B | Qwen3.6-35B-A3B-UD-Q8_K_XL.gguf |
用来观察量化格式对结果的额外影响 |
2. 测试环境
- GPU:
NVIDIA L20 48GB单卡 - 推理引擎:
llama.cpp服务模式 - 接口形式:OpenAI 兼容接口
- 压测脚本:
scripts/test_long_context_concurrency.py - 测试方式:单并发、热态、每组
warmup 1轮 +measured 5轮
这里有两个很重要的口径说明:
scripts/test_long_context_concurrency.py用的是 按字符数近似构造长上下文 的方法,target_chars=50000和target_chars=100000更接近工程上的"约 32K / 约 64K 输入规模",不是严格按 prompt token 精确对齐。- 这轮测试是 单并发 smoke benchmark,适合看长上下文体感和单路性能差异,不适合直接上升为严格的并发 SLO 结论。
三、压测方法
本文的核心对比都来自同一套脚本、同一套参数骨架:
bash
python3 test_long_context_concurrency.py \
--base-url http://localhost:PORT \
--model MODEL_NAME \
--concurrency 1 \
--target-chars TARGET_CHARS \
--max-tokens 128 \
--warmup-rounds 1 \
--rounds 5
其中:
target_chars=50000:作为约32K输入规模参考target_chars=100000:作为约64K输入规模参考max_tokens=128:固定输出长度上限,避免 completion token 差异过大
脚本默认会统计这些指标:
Round overall elapsedPer-request TTFTPer-request output speedPer-request completion throughput (E2E)
四、先看"容易误判"的结果:不同量化会明显污染比较
先放一组很有代表性的结果:在约 32K 输入规模下,Qwen3.6 Q8_0 和 Qwen3.6 UD-Q8_K_XL 的表现并不一样。
1. Qwen3.6 同模型不同量化(约 32K)
| 指标 | Qwen3.6 Q8_0 | Qwen3.6 UD-Q8_K_XL | 差异 |
|---|---|---|---|
| 总耗时 | 10.28s | 10.82s | +5.3% |
| TTFT | 9.02s | 9.55s | +5.9% |
| 输出速度 | 101.48 tok/s | 100.80 tok/s | -0.7% |
| E2E completion throughput | 12.48 tok/s | 11.86 tok/s | -5.0% |
2. 这组结果说明什么
这组对比非常重要,因为它直接说明:
- 实测: 即使模型版本不变,只改量化格式,
llama.cpp下的端到端性能也会发生明显变化。 - 推导:
UD-Q8_K_XL对Qwen3.6的额外开销,主要也落在TTFT / Prefill阶段,而不是 decode 阶段。
换句话说,如果你拿:
Qwen3.5 Q8_0- 去对比
Qwen3.6 UD-Q8_K_XL
那么你看到的差距,不会只来自模型代际升级,还会被量化格式进一步放大。
五、真正公平的核心对比:Q8_0 vs Q8_0
下面才是这篇文章最核心的对照组。
1. 约 32K 输入规模对比
Qwen3.5-35B-A3B-Q8_0
| 指标 | 数值 |
|---|---|
| 总耗时 | 9.62s |
| TTFT | 8.42s |
| 输出速度 | 105.81 tok/s |
| E2E completion throughput | 13.32 tok/s |
Qwen3.6-35B-A3B-Q8_0
| 指标 | 数值 |
|---|---|
| 总耗时 | 10.28s |
| TTFT | 9.02s |
| 输出速度 | 101.48 tok/s |
| E2E completion throughput | 12.48 tok/s |
对比结论(约 32K)
| 指标 | 差异 |
|---|---|
| 总耗时 | +6.9% |
| TTFT | +7.1% |
| 输出速度 | -4.1% |
| E2E completion throughput | -6.3% |
这说明:
- 实测: 在同为
Q8_0的情况下,Qwen3.6仍然比Qwen3.5慢。 - 推导: 但真实差距更接近
6% ~ 7%,而不是之前混入UD-Q8_K_XL后看上去的11% ~ 13%。
2. 约 64K 输入规模对比
Qwen3.5-35B-A3B-Q8_0
| 指标 | 数值 |
|---|---|
| 总耗时 | 11.99s |
| TTFT | 10.67s |
| 输出速度 | 96.93 tok/s |
| E2E completion throughput | 10.70 tok/s |
Qwen3.6-35B-A3B-Q8_0
| 指标 | 数值 |
|---|---|
| 总耗时 | 13.39s |
| TTFT | 12.08s |
| 输出速度 | 96.70 tok/s |
| E2E completion throughput | 9.57 tok/s |
对比结论(约 64K)
| 指标 | 差异 |
|---|---|
| 总耗时 | +11.7% |
| TTFT | +13.2% |
| 输出速度 | -0.2% |
| E2E completion throughput | -10.6% |
这组数据比 32K 更有意思:
- 实测: 到约
64K输入规模时,Qwen3.6和Qwen3.5的 decode 速度已经几乎一样。 - 推导: 差距几乎全部集中在 首 token 之前 ,也就是
Prefill / TTFT。
六、把 32K 和 64K 放在一起看,趋势就很清楚了
如果把前面的两组 Q8_0 vs Q8_0 结果放到一起,趋势非常稳定:
| 场景 | Qwen3.5 总耗时 | Qwen3.6 总耗时 | 总耗时差异 | Qwen3.5 TTFT | Qwen3.6 TTFT | TTFT 差异 |
|---|---|---|---|---|---|---|
| 约 32K | 9.62s | 10.28s | +6.9% |
8.42s | 9.02s | +7.1% |
| 约 64K | 11.99s | 13.39s | +11.7% |
10.67s | 12.08s | +13.2% |
再看两者各自从 32K 走到 64K 的退化:
Qwen3.5
- 总耗时:
9.62s -> 11.99s,增加约24.6% - TTFT:
8.42s -> 10.67s,增加约26.7%
Qwen3.6
- 总耗时:
10.28s -> 13.39s,增加约30.3% - TTFT:
9.02s -> 12.08s,增加约33.9%
这说明:
- 实测: 两个模型都会随着上下文变长而变慢。
- 推导:
Qwen3.6在当前llama.cpp单卡配置下,对上下文长度增长更敏感。 - 判断: 如果你的业务是长 prompt、代码库理解、RAG 长文分析、Agent 大上下文拼装,那么
Qwen3.6的用户体感劣势会主要表现成"等第一口回答更久"。
七、为什么这件事值得关注:问题主要不在 decode,而在 Prefill
很多人做模型性能对比时,只盯着:
tok/s- 输出速度
但这轮实验里最值得记住的,其实不是 decode 速度,而是:
同为 Q8_0,Qwen3.6 相对 Qwen3.5 的主要损失,发生在 TTFT / Prefill。
这对工程判断很重要,因为:
1. 如果你的业务更像"长 prompt + 短回答"
比如:
- RAG 总结
- 长文归纳
- 大仓库阅读后回答
- 工单材料汇总后给建议
那用户最敏感的往往不是每秒多吐几个 token,而是:
为什么我点了发送之后,要多等一秒多才开始回答?
在这种场景下,Qwen3.6 的这部分差距会非常可感知。
2. 如果你的业务更像"短 prompt + 长输出"
那 Qwen3.6 和 Qwen3.5 的体感差距可能不会像长上下文场景里这么大。
因为从现有数据看,至少在约 64K 输入规模下,两者 decode 速度已经接近重合。
八、这能不能直接说明"Qwen3.6 不如 Qwen3.5"?
不能这样下结论。
更准确的说法是:
在当前
llama.cpp单卡 L20 48GB、GGUFQ8_0、单并发长上下文测试组合下,Qwen3.6-35B-A3B的端到端性能弱于Qwen3.5-35B-A3B,而且差距主要出现在TTFT / Prefill,并会随着上下文长度增加而扩大。
这里我特意强调"当前组合",是因为这类结果还可能同时受这些因素影响:
llama.cpp对不同模型结构的 kernel 路径差异- GGUF 转换与量化实现差异
- MoE/长上下文下的 runtime 行为差异
- 推理引擎本身对模型的适配成熟度
也就是说,这更像是一个:
- 模型 + 量化 + 引擎 + 硬件
组合结论,而不是抽象层面的"模型智力结论"。
九、对开发者的工程建议
基于这轮实测,我会给出下面几条更偏工程化的建议。
1. 比较模型代际差异时,先把量化控制住
这是本文最想强调的一点。
如果你要比较:
Qwen3.5和Qwen3.6
那尽量至少满足:
- 同引擎
- 同量化格式
- 同上下文规模
- 同并发
- 同输出长度上限
否则你最后很容易比较成:
- 模型版本差异
- 量化差异
- 引擎差异
三者一起混合的总效果。
2. 做长上下文压测时,不要只看输出速度
在这轮测试里,如果只盯 output speed,你会得出一个很容易误导的结论:
两个模型差不多。
但真正影响用户体感的,是:
TTFTE2E elapsed
所以长上下文场景下,至少要同时看:
TTFToutput speedcompletion throughput (E2E)
3. 如果你更在意长上下文体感,当前 Qwen3.5 Q8_0 更稳
至少在这套单卡 llama.cpp 组合下,可以先做一个相对保守的判断:
- 判断: 如果优先目标是"长上下文首 token 更快、单卡体感更稳",当前
Qwen3.5-35B-A3B-Q8_0仍然是更省心的选择。
4. 如果你更在意 Qwen3.6 的能力增益,后续值得继续补引擎对照
这篇文章只回答了:
- 在
llama.cpp下会怎样
但还没有回答:
- 换到
SGLang + FP8 - 或
vLLM + FP8
之后,这个差距会不会缩小,甚至反转。
如果后续补完这组测试,才能进一步判断:
- 这是
Qwen3.6本身的长上下文成本更高 - 还是当前
llama.cpp路径对它不够友好
十、最后收个尾
这轮实验最有价值的地方,不是简单得到一句:
Qwen3.6比Qwen3.5慢。
而是把这件事拆成了三层:
- 量化不同,会污染比较结果。
- 量化控制到
Q8_0之后,Qwen3.6仍然更慢。 - 这个"更慢"主要体现在
Prefill / TTFT,并且上下文越长,差距越明显。
如果你也在做本地部署、长上下文 RAG、代码仓库问答或者 Agent 场景,这三个判断会比一句泛泛的 benchmark 更有参考价值。
因为它们更接近真实系统里的那个问题:
用户为什么会觉得慢,慢到底慢在哪一段。
附:本文涉及的关键原始数据
约 32K:Qwen3.5 Q8_0
text
Round overall elapsed: mean=9.62s
Per-request TTFT: mean=8.42s
Per-request output speed: mean=105.81 tok/s
Per-request completion throughput (E2E): mean=13.32 tok/s
约 32K:Qwen3.6 Q8_0
text
Round overall elapsed: mean=10.28s
Per-request TTFT: mean=9.02s
Per-request output speed: mean=101.48 tok/s
Per-request completion throughput (E2E): mean=12.48 tok/s
约 32K:Qwen3.6 UD-Q8_K_XL
text
Round overall elapsed: mean=10.82s
Per-request TTFT: mean=9.55s
Per-request output speed: mean=100.80 tok/s
Per-request completion throughput (E2E): mean=11.86 tok/s
约 64K:Qwen3.5 Q8_0
text
Round overall elapsed: mean=11.99s
Per-request TTFT: mean=10.67s
Per-request output speed: mean=96.93 tok/s
Per-request completion throughput (E2E): mean=10.70 tok/s
约 64K:Qwen3.6 Q8_0
text
Round overall elapsed: mean=13.39s
Per-request TTFT: mean=12.08s
Per-request output speed: mean=96.70 tok/s
Per-request completion throughput (E2E): mean=9.57 tok/s