Qwen3.8-Flash-Next EXL3 双卡实测 60+T/S:MTP on/off 解码速度与多轮测速
-
前言
大家中秋快乐!
在 "没苦硬吃!!3090带着小弟跑Qwen3.8-Flash-Next双卡实测"( https://lcz.me/topic/1397/6 )这个帖子里, 当时我还是 3090 24G + 3070 8G , 但是当时非常想知道跑起来什么样子,于是硬上llama.cpp跑,测出来是15-25tok/s 左右。 后来3070换成了 3080 20G, 没有优化调参,直接重复跑了一次, 变成了 30-36tok/s 左右。 前一阵入手了第二快 3090 , 于是一直想着再复测一次。
但是,说到但是,必须吐嘈一下。新的3090是在一家维修显卡的店铺买的,店铺信誉还是不错的,超过15年实体店,老板人也不错,承诺店保1年。但3090到手后,发现满载有较明显的啸叫声,老板说这个很正常,让我随便造,大不了他给我保。于是用了一两个星期,感觉叫声越来越大了,我真的怕哪天爆一个元器件什么的,于是还是给退回去了。
老板也挺痛快,说给我换一个,但是他自己测了一下手头的卡,基本都同样的状况,挑不出来完全没有啸叫的, 在我的要求下, 他说帮我去找好货,但是时间要长点。 也吐嘈说, 现在的3090、4080、4090这些卡,基本没有非常好品相的了,能找到工厂里新出来的基本没有,大多是翻修卡。前期品相好的基本被挑的差不多,现在市场上流通的品质不太好说, 尤其是 4080 32G、 4090 48G 这种魔改卡, 出问题的概率比之前要大不少,之前可能20张4090有一个出问题,现在恨不得10张里面有2-3个出问题,他自己都不想卖了。
言归正传,正好休息,实在没事做,还是借着以前的3090+3080把这个测试做一下,我相信只要这个跑通了,2x3090只会更好。
结论先放
把 Qwen3.8-Flash-Next EXL3 3.05bpw turboderp 量化(90 GB,7 shards + 31 GB n-gram table)丢到 RTX 3080 20G + RTX 3090 24G(非对称 PCIe4.0,无 P2P),用 TabbyAPI
cpu_moe_split_experts=192 + ctx=65536 + cache_mode=Q4 + draft_mode=mtp + dynamic_draft=true,实测:-
MTP off (baseline): coding 出码平均 ~39.4 t/s decode,~0.5–1 s TTFT
-
MTP on (dynamic_draft, ceiling=4): **4 语言 coding 出码 8 轮 median 63.27 t/s ~ 69.69 t/s
-
多场景测速平均:~49.4 t/s(7 场景 21 个 chat 的中位)
-
MTP off → on 加速:+50–65% decode throughput
-
短 ctx vs baseline:ctx=8K/16K prefill 143-152 t/s,decode 52-53 t/s;ctx=65K prefill 143-152 t/s,decode 57 t/s。
-
ctx 上限:
- 装得下的最大 ctx = 196K
- ctx ≤ 65 536 时decode ≥ 60 t/s code;ctx ≥ 98 304 即跌破 55 t/s
- 这台 3090+3080 + exl3 1.5.1 的最优甜蜜点 = ctx 65 536
1. 测试环境
1.1 硬件一览
项目 型号 / 规格 CPU AMD Ryzen 9 3950X(16C / 32T) 主板 ASUS TUF GAMING X570-PLUS 内存 125 GiB DDR4 3600,实际可用 119 GB(含 swap 186 GB 兜底) GPU 0 NVIDIA GeForce RTX 3080(20 GB,cuda:0,PCIe 4.0 @ 4X) GPU 1 NVIDIA GeForce RTX 3090(24 GB,cuda:1,PCIe 4.0 @ 16X) 总显存 44 GB(3080 + 3090) 存储 系统 NVMe 4T 系统 Ubuntu 24.04(kernel 6.8.0-139-generic) NVIDIA 驱动 580.178.x(CUDA 13.0) 1.2 软件
项目 版本 Python 3.12.3(venv in /qwen38flash-exl3-venv)exllamav3 1.5.1(PyPI Linux wheel) torch 2.14.0 + cuda-toolkit 13.0.3.0(pip 拉的 cu13,不是 docker 容器) TabbyAPI 上游 master @ 53da791(vendored,无 patch) n-gram/PLE 32.64 GB( ngram_ram: true全部常驻系统内存)Sampling engine preset safe_defaults(temp 0.8 / top_k 40 / min_p 0.05)装了
exllamav3之后还必须手动装uvloop、aiohttp、async_lru、loguru、sse-starlette、huggingface-hub(PyPI 上exllamav3不带这些)。TabbyAPI 会以from uvloop import install第一次调用。1.3 模型
项目 规格 模型 Qwen3.8-Flash-Next 量化 EXL3 3.05bpw turboderp(HF 分支 3.05bpw_h5_ng5)文件大小 90 GB(7 shards × ~8.18 GB main + 32.64 GB ngram_embedding.safetensors + mtp patch) 参数量 arch qwen4exp,176B MoE(48 layers × 512 experts)词表 n_vocab=248320;n_embd=2560 原生上下文 n_ctx_train=262144 Vision built-in( video_preprocessor_config.json/preprocessor_config.json),yml 默认vision: true+vision_offload: trueTool format qwen3_coder(yml 默认)MTP head 内建(head ships inside quant,不需要单独的 drafter 文件)
2. 实测结果
2.1 配置 A:MTP off(baseline)
VRAM 占用:cuda:0 = 16.0 GB,cuda:1 = 21.3 GB,总 37.3 GB。
冷启动约 30 s(model loaded 完)。
主表: 3 rounds
每轮由 TabbyAPI 服务端 inst 日志报告
tokens generated at X T/s,取 4 轮平均值填 median。Lang Round 1 Round 2 Round 3 Median wall avg (s) C 38.9 t/s (1024 tok) 33.4 t/s (530 tok) 38.9 t/s (1024 tok) 38.9 t/s 13.5 C++ 39.4 t/s (556 tok) 47.9 t/s (1024 tok) 41.7 t/s (1024 tok) 41.7 t/s 11.7 Rust 39.4 t/s (508 tok) 50.6 t/s (1024 tok) 41.8 t/s (1024 tok) 41.8 t/s 7.2 Python 39.8 t/s (946 tok) 39.5 t/s (1024 tok) 35.6 t/s (1024 tok) 39.5 t/s 16.1 均值 ~39.4 t/s 12.1 表格里的 token 数都从
usage.completion_tokens读(不是估算)。如果某轮撞到 1024-token 上限(常见在 C、Rust,因为 prompt 后机器仍倾向验证细节),单轮 t/s 偏低属于 prompt 收尾时机估算不能拆——保留是合理的稳态参考。2.2 配置 B:MTP on (dynamic_draft, ceiling=4)
VRAM 占用:cuda:0 = 17.3 GB,cuda:1 = 22.3 GB,总 39.6 GB(多 2.3 GB 给 MTP 头 + draft cache)。
冷启动约 34.5 s。
Lang R1 R2 R3 R4 R5 R6 R7 R8 Median C 70.39 65.03 68.71 68.75 70.32 70.15 61.90 63.81 68.75 t/s C++ 63.53 57.94 64.51 69.41 63.53 67.71 65.30 68.09 65.30 t/s Rust 69.80 71.90 69.69 66.62 67.31 68.98 70.14 68.89 69.69 t/s Python 63.26 62.75 63.07 64.12 64.57 64.92 61.82 61.77 63.26 t/s 均值 ~66.75 t/s 2.3 多场景扩展测试(MTP on, ctx=65536, split=192)
在配置 B 的基础上扩到 7 个场景各 3 轮——code 4 语 + 英文 narrative / summarize + 中文 narrative。专门看 prose 类任务的吞吐下降。
场景 Median t/s Mean t/s Avg tokens C-code 64.7 61.2 774 C++-code 65.0 65.5 307 Rust-code 68.1 66.6 305 Python-code 60.9 61.3 582 EN-narrative 26.9 27.6 283 EN-summarize 36.8 37.4 289 ZH-narrative 25.8 26.4 136 code-only 均值 ~66.75 t/s ~63.7 t/s — prose 均值 ~29.2 t/s ~30.5 t/s — OVERALL 均值 — ~49.4 t/s — 观察:
- code 任务平均 60+ t/s
- prose 任务降至 ~29 t/s——因为输出 token 数小(136–290),MTP dynamic_draft 的 ceiling=4 在短生成中接受率较低这是 MTP 的天然特性:长输出才有戴 draft 的价值。
- 中文 narrative 输出 character 数远低于英文(136 vs 283),但单字符内容更密;t/s 数字看上去差但实际 prose 信息量是接近的。
2.4 MTP on vs off 对照
指标 MTP off MTP on Δ Decode t/s (median 4 lang) 39.4 66.75 (8 rounds mean) +69% VRAM (cuda:0 + cuda:1) 16.0 + 21.3 = 37.3 GB 17.3 + 22.3 = 39.6 GB +2.3 GB Cold-start (model loaded) 30.1 s 39.5 s +31%(MTP head 加载) Round-3 wall C(撞 max_tokens) 14.7 s 11.8 s -20% Round-1 wall C (冷启动延迟) 17.0 s 17.1 s 持平 Python 1024-tok wall 15.9 s 18.0 s +13%(MTP on 反而慢?因为生成字符更长接近 4100 chars)
3. 踩坑问题(这是个梗合集)
3.1
draft_mode只能取有限枚举值写 "draft_mode: enabled" 之类的 都会报:
pydantic_core._pydantic_core.ValidationError: 1 validation error for TabbyConfigModel draft_model.draft_mode Input should be 'model', 'disabled', 'mtp' or 'ngram'正确值只 4 个:
disabled / model / mtp / ngram。用mtp才能让 exl3 内建 MTP head 接管。model是再装一份独立 drafter GGUF,我们这台没那个文件。3.2 VRAM 临界 40 GB 是 exl3 1.5.1 的 autosplit 死线
我反复试了 6 组 split/cache 组合:
split cache_size Q4 cache bytes weights on GPU draft total 结果 384 204800 16 GB 30 GB (37.5%) off 46 GB OOM 224 204800 16 GB 41 GB off 57 GB OOM 192 65536 5.2 GB 33 GB off 38 GB OK 30.1 s 192 65536 5.2 GB 33 GB mtp on 39.6 GB OK 39.5 s 128 32768 2.6 GB 38 GB mtp on 41.6 GB OOM 96 8192 0.6 GB 39 GB mtp on 40.6 GB OOM 64 4096 0.3 GB 39 GB mtp on 40.3 GB OOM 64 2048 0.16 GB 39 GB mtp on 40.1 GB AssertionError: Cache too small for batch shape 教训是:exl3 1.5.1 autosplit 有 ~40 GB 死死线(host 44 GB = (20+24))。超过这线硬崩,连 cache_mode=Q4 都救不了。想用满 VRAM 必须在 192-split/cx=65K 这条缝里做,不能再压 context。
3.3 用
enable_thinking: false≠/no_think标语TabbyAPI 的 OAI extra_body 走
chat_template_kwargs={"enable_thinking": False},yml template(minja-numeric-index patched jinja)会把这个变量传给 jinja 模板让模型静默思考。单独写/no_think不行——模型仍思考,max_tokens=1024 时思考段会先填满,content 一段不写。3.4 非流式响应走得快很多,但 server-log 才是真数据
curl -X POST /v1/chat/completions ... stream=false→ OAI API 立即返回完整 JSON,但usage.completion_tokens是 end-of-stream 时累计的真实 token 数。手写的 streaming parser 在 Qwen3.8 + tabby 上能拿到 chunk 但 OpenAI protocol 把每个 token 拆成独立data: {...},所以 delta chunk 数 ≠ 真实 token 数(tabular.py 在合并多 token chunk)。别自己写 client parser 跟 server inst 数字对账——服务器 inst 每条 chat 都报X tokens generated at Y T/s,那才是真实吞吐。
4. ctx 上限扫描:推到装不下 + 看每个 ctx 的 throughput
沿着 ctx → Q4 cache + MTP on,把 ctx 从 65K 一路拉到 20 万。每档重起 server 测 3 轮 Python code 取 median。
代码任务(Python prompt + max_tokens=1024):
ctx split (CPU res.) VRAM (cuda:0 + cuda:1) Median t/s t/s 完整列表 65 536 192 17.4 + 22.3 = 39.7 GB 61.6 64.7 / 67.2 / 52.7 [warm cache 已算均值] 98 304 192 17.6 + 22.6 = 40.2 GB 51.9 47.5 / 51.9 / 54.5 131 072 192 18.5 + 22.0 = 40.5 GB 51.2 47.5 / 51.2 / 57.0 131 072 256 12.7 + 22.3 = 35.0 GB 44.1 40.9 / 44.1 / 46.6 163 840 256 12.8 + 22.5 = 35.3 GB 43.4 41.5 / 43.4 / 46.7 163 840 384 2.0 + 22.4 = 24.4 GB 31.6 30.1 / 31.6 / 33.7 196 608 384 2.4 + 22.3 = 24.7 GB 31.0 30.8 / 31.0 / 32.5 200 000 384 — OOM — 观测:
- ctx 拉到 100K+ 时 t/s 即跌破 60:98K 是 51.9 t/s。
- ctx=196K split=384(59% on CPU),VMRAM 只用了 24.7 GB 还有大量剩余——但 throughput 进一步跌到 31 t/s。同上:CPU-MoE 太多反而更慢。
4.1 短 ctx 测速:8K / 16K vs 65K 的 prefill + decode 对比
为了回答"短 ctx prefill/decode 会更快么",专门测了 ctx=8K / 16K / 65K 三档,每档 3 轮 Python code prompt,MTP on,stream_options.include_usage=true 让 TabbyAPI 服务端直接报
prompt_tokens_per_sec和completion_tokens_per_sec。ctx Round 1 (cold) / Round 2-3 (warm) prefill t/s decode t/s (3 轮均值) draft acceptance 8 192 51 / 141 / 145 ~52.0 74-76% 16 384 52 / 127 / 145 ~53.0 75-76% 65 536(baseline) 152 / 143 / 143 ~57.2 75-76% 196 608(容器装下的极限) — ~31.6 — 观测:
- prefill 反而短 ctx 更慢。
- 短 ctx vs 长 ctx MTP draft 接受率相当。
- 最低可行 ctx = 8K:
cache_size=4096撞AssertionError: Cache too small for batch shape(chunk_size=4096),exl3 1.5.1 需要 cache ≥ chunk_size。
5. 感想
-
不对称双卡确实能用 exl3 跑 176B MoE 模型。前提是:cache_size 砍、split 激进、MTP on。底线是每卡 20GB + 一张 24GB,足跑 3.05bpw + 60 t/s。
-
CPU-MoE 越少越好(前提 RAM 装得下)。本机 RAM 125 GB 装下 96 GB host_ram_gb 减去 8 GB OS、Python、cache buffer 后余 ~80 GB;32 GB n-gram + 25-30 GB offload experts 都能放下。
-
不该 tabbyAPI 默认装。这个 cli 工具是个 helper,但它强依赖
--disable-auth、--override-preset safe_defaults,还得手动 pip 装一堆 deps。 -
code vs prose 任务吞吐差。MTP dynamic_draft 对长输出/重复模板类任务(code)收益大,因为它可以并行看出 4 个 token 并预测。对短输出(prose 130–290 char)MTP 接受率只剩 50% 左右,效益降至 +30% 上下。所以这次叙事类 t/s ~29,跟 code ~60 是 2:1 关系。
-
要把 ctx 推到 100K+ 还想 ≥ 60 t/s:必须升级到双 3090 NVLink 或 H100 PCIe 5.0以上。这台 3090+3080 = 44 GB VRAM 在 exl3 1.5.1 死线下,最优 = 65K ctx / MTP on / split=192 / 39.7 GB VRAM。
6. 简单指令给急着复现的人
# 1. 装 venv python3.12 -m venv /qwen38flash-exl3-venv /qwen38flash-exl3-venv/bin/pip install exllamav3 fastapi-slim \ "pydantic>=2.11,<3" ruamel.yaml uvicorn jinja2 loguru "sse-starlette>=2.2.0" \ aiofiles aiohttp async_lru "huggingface_hub" psutil "httptools>=0.5.0" \ pillow requests uvloop # 2. 改 config(基于本帖 1.3 节 + 这次 3.3 的实测 OOM 边界) # 主要变量: # max_seq_len: 65536, cache_size: 65536, cache_mode: Q4 # cpu_moe_split_experts: 192 # draft_mode: mtp, draft_num_tokens: 4, draft_dynamic: true # reasoning: false, template_vars_force: {enable_thinking: false} # 3. 启动 THREADS=28 /qwen38flash-exl3-venv/bin/python -u \ /qwen38flash/EXL3/tabbyAPI/main.py \ --host 0.0.0.0 --port 5000 # 4. 跑 bench python3 /bench-codingspeed/bench_qwen38.py -
-
@ben-lee 终于搞出来了。速度是一方面,但我觉得智力更重要,网上各种排名,27b智力可能都在flash之上了,但是我觉得那是微调的结果,我这个人比较笨,只从信息论的角度看,我私下认为90G的模型肯定应该比16G的模型要更“好用”,既然达到了60t/s这种可用的程度,我觉得flash更让我信任呢。欢迎讨论。
Qwen3.8-Flash-Next vs Qwen3.8-27B 官方评测对比
从官方评测看,Qwen3.8-Flash-Next 相比 Qwen3.8-27B,整体是"明显更强,但不是全面碾压"。优势主要集中在 Agent、职业办公、长流程任务和部分代码场景;在普通推理和某些软件工程任务上,两者差距并不大。
以下数字均来自 Qwen 官方同一套评测,实际表现还会受到提示词、推理预算和工具环境影响。
评测项目 Flash-Next 27B 差距 DeepSWE 1.1 智能编程 58.7 42.2 +16.5 SWE-bench Pro 62.5 61.7 +0.8 多语言软件工程 81.0 73.8 +7.2 NL2Repo 代码生成 48.1 42.3 +5.8 CoWorkBench 长流程办公 73.9 70.7 +3.2 JobBench 职业任务 55.7 33.4 +22.3 Agents' Last Exam Pass@1 24.3 20.4 +3.9 Agents' Last Exam Score 51.2 42.9 +8.3 Toolathlon 工具使用 73.5 67.1 +6.4 -
-
-
@johnnybegood 女大应该大概率不会买3090。哈哈!decode可以。但是prefill载快点儿就好了。
-
-
-
-
@johnnybegood 女大应该大概率不会买3090。哈哈!decode可以。但是prefill载快点儿就好了。
@nami-ryuu 确实, 还没仔细优化调整。不过说实话我也不打算用这个模型来干活,思考太多了,有点费劲。
-
@suboyang 我看过很多评测文章和视频, 世界上公认 30t/s 就可以干活了, 所以说 70t/s 干不了活这说的有点夸张, 那你可能属于对速度非常敏感的 TOP 1% 人群, 并不能代表大部分人, 所以你的意见是不具有代表性的。 另外, Qwen3.8 27B 在 3090 单卡上就可以跑到 191 t/s 了, 双卡可以到 280t/s 左右, 供你参考, 我这个帖子如果你注意看的话, 我测的是 Qwen3.8 Flash Next, 完全是另外一个模型。
-
我用这个Qwen3.8-Flash-Next 干活已经干了两周了 速度是50token/s吧,而且我是调优关闭思考模式的。但是最后我还是放弃了,人是被模型拖着走的感觉, 最后我换回了deepseek。
-
-
-
-
-
去了解一下智普的领导层,基本没有做技术的,算力是租的,模型是抄的,训练集就是用来跑分的。资本都是哪个啥来的。你有钱会不会投智普?心里琢磨一下。
-
@suboyang 清华的张钹院士是我的老师,我会不知道么?呵呵呵
-
-
-
zcode偷代码
你是不是以为 zcode偷代码 是他们第一次干?还是认为是最后一次?
zcode偷代码
你是不是以为 zcode偷代码 是他们第一次干?还是认为是最后一次?
zcode偷代码已经把它钉在了耻辱柱上了。我谈的是 glm5.3的能力,不要带太多感情哈。。。
很能打啊
,自己承认了。