4x RTX 3090 上的 Qwen3.5-27B、Qwen3.5-122B 和 Qwen3.6-35B —— MoE 模型在严格全局规则下的表现困境

Reddit r/LocalLLaMA 新闻

摘要

潜水多年的老用户,首次发帖。在 4 张 RTX 3090 上对三款 Qwen 模型分别进行了 20 多个会话的实时智能体工作测试——**Qwen3.5-27B** 稠密模型、**Qwen3.5-122B-A10B** MoE 和 **Qwen3.6-35B-A3B** MoE。以下数据均解析自持续真实负载下的 vLLM 日志,而非合成基准测试。**本文所有数据的关键负载背景:** 测试框架是一个多智能体编排器,同时运行 1-6 个并发的 OpenCode 会话,Prompt 长度为 30-60k token,并且强制执行**严格的 Bash 允许列表

潜水多年的老用户,首次发帖。在 4 张 RTX 3090 上对三款 Qwen 模型分别跑了 20 多个会话的实时智能体任务——**Qwen3.5-27B**(稠密)、**Qwen3.5-122B-A10B**(MoE)、**Qwen3.6-35B-A3B**(MoE)。下文数据均提取自持续真实负载下的 vLLM 日志,非合成基准测试。 **本文所有指标背后的关键负载场景:** 测试框架是一个多智能体编排器,同时运行 1-6 个并发的 OpenCode 会话,Prompt 长度在 30k-60k token,且严格执行**极简 Bash 白名单**——每个工具仅允许精确匹配的 `uv run scripts/<name>.py` 格式,禁止 Shell 装饰符(`| head`、`| tail`、`timeout`、`2>&1`),读取操作不允许绝对路径,也不允许 `cd && ...` 连续调用。这使得模型遵守规则的方式与宽松环境下大相径庭。**三款路由型 MoE 在遵守这些严格全局规则方面,系统性落后于稠密的 27B 模型**——参数量大小、激活参数量以及微调目标对此影响甚微。先列出速度数据作为参考,随后展示遵规能力的差距。 模型与量化配置(均在 4 张 24GB 显存的 GPU 上兼顾 262k 上下文窗口的前提下选择最佳质量方案): * **Qwen3.5-27B** 稠密版 —— INT8 (AWQ-BF16-INT8) 权重,FP8 KV Cache,MTP 推测解码 * **Qwen3.5-122B-A10B** MoE —— AWQ-INT4 权重,FP8 KV Cache。只有 Q4 才能在保留 262k 上下文的同时装下它 * **Qwen3.6-35B-A3B** MoE —— FP8 权重,FP16 KV Cache(该模型上 FP8 KV Cache 不稳定) 小模型能榨干精度潜力,大模型只能根据显存妥协。下表数据均在 250W 功耗下采集(经 200/250/300W 测试得出的甜点功耗)。vLLM 版本:v0.19.0。 **数据采集方式:** vLLM 每 10 秒输出一次 `Avg prompt throughput`、`Avg generation throughput` 和 `Running: N reqs`。表格中每个单元格代表该并发状态下的时间窗均值——`n=6` 约等于该状态持续 60 秒的实际运行时间。包含空闲时间窗;这里统计的是持续吞吐量,而非峰值。 https://preview.redd.it/1zpd01kd6dwg1.png?width=2231&format=png&auto=webp&s=3a95177aa3131e895d64bfe036e5cbf6042701de ## 不同并发数下的生成吞吐量(250W,avg t/s) 括号内的 `n` 为样本数(10 秒时间窗的数量)。 | Concurrent reqs | Qwen3.5-27B (n) | Qwen3.5-122B (n) | Qwen3.6-35B (n) | |:-|:-|:-|:-| | 1 | 85 (8) | 74 (21) | 122 (90) | | 2 | 97 (28) | 48 (13) | 174 (34) | | 3 | 133 (36) | 111 (9) | 215 (16) | | 4 | 112 (19) | 123 (9) | 288 (8) | | 5 | 68 (34) | 138 (17) | 348 (4) | | 6 | 98 (16) | 33 (3) | 296 (5) | 3.6-35B 在各并发层级下在生成吞吐量上全面领先。122B 表现波动较大(c=2 时跌至 48 t/s,c=6 时在 n=3 时降至 33),但在 c=3-5 范围内内部一致性尚可。27B 表现介于两者之间,且在并发跨度上最为稳定——其各单元格的方差最小,即便在 c=4-5 时其平均值低于 122B。 ## 不同并发数下的预填充吞吐量(250W,avg t/s) `n` 的定义同上表(每个单元格的 n 在两张表中一致——一个时间窗即一个包含预填充和生成数据的数据点)。预填充吞吐量为该并发下所有时间窗的平均值,包括那些引擎完全处于生成状态的时间窗(预填充=0)。这更客观地反映了该并发状态下的持续预填充能力。122B 在 c=6、n=3 时的数据受噪声干扰严重。 | Concurrent reqs | Qwen3.5-27B (n) | Qwen3.5-122B (n) | Qwen3.6-35B (n) | |:-|:-|:-|:-| | 1 | 926 (8) | 573 (21) | 626 (90) | | 2 | 553 (28) | 2343 (13) | 1589 (34) | | 3 | 364 (36) | 1849 (9) | 1799 (16) | | 4 | 726 (19) | 2499 (9) | 1856 (8) | | 5 | 1001 (34) | 1754 (17) | 1896 (4) | | 6 | 1427 (16) | 2480 (3) | 2983 (5) | **综合持续平均值(c=1-6,250W 下所有时间窗):****Qwen3.5-27B ~756 t/s**,**Qwen3.5-122B ~1651 t/s**,**Qwen3.6-35B ~1124 t/s**。122B 在预填充上仍以约 2 倍优势领先。得益于前缀缓存机制处理了绝大多数单轮 30-60k token 的请求,未缓存的尾部增量每轮仅几千 token,因此 122B 的理论优势在实际应用中比纸面数据显得没那么突出了。 ## 实际执行预填充时的吞吐量(剔除预填充=0 的时间窗) 如果你想知道“引擎真正处理 Prompt 时有多快”(而非持续平均值),下表移除了每个单元格中预填充=0 的时间窗进行重新计算。括号内的 `n` 为该单元格内预填充活跃的时间窗数量,因此会随单元格变化。 | Concurrent reqs | Qwen3.5-27B (n) | Qwen3.5-122B (n) | Qwen3.6-35B (n) | |:-|:-|:-|:-| | 1 | 1235 (6) | 669 (18) | 751 (75) | | 2 | 860 (18) | 2769 (11) | 1743 (31) | | 3 | 505 (26) | 2377 (7) | 1799 (16) | | 4 | 985 (14) | 3213 (7) | 1856 (8) | | 5 | 1260 (27) | 1987 (15) | 1896 (4) | | 6 | 1757 (13) | 3720 (2) | 2983 (5) | **仅活跃状态汇总:****Qwen3.5-27B ~1025 t/s**,**Qwen3.5-122B ~2155 t/s**,**Qwen3.6-35B ~1124 t/s**。上方的持续吞吐量表格更贴近智能体流水线在平均并发状态下的真实体验;此表则更接近 vLLM 在实际执行预填充时的极限交付能力。根据你的侧重点选择关注点是“我的智能体栈实际表现如何”还是“该模型底层能力上限”。 ## 每分钟完成请求数(250W) Token 速率是一回事,每分钟实际完成的任务数是另一回事。统计方法为:按 10 秒时间窗计数 `POST /v1/chat/completions HTTP/1.1" 200` 日志行,并按该窗口的并发数归类。采用混合任务统计(长短响应均计为 1),因此这是一个针对混合负载的功能性吞吐量指标,而非单任务延迟指标。 | Concurrent reqs | Qwen3.5-27B | Qwen3.5-122B | Qwen3.6-35B | |:-|:-|:-|:-| | 1 | 8.2/min | 9.1/min | 14.9/min | | 2 | 6.6/min | 9.7/min | 23.1/min | | 3 | 6.7/min | 10.0/min | 26.6/min | | 4 | 7.3/min | 10.0/min | 36.8/min | | 5 | 7.8/min | 8.8/min | 27.0/min | | 6 | 13.9/min | 12.0/min | 45.6/min | **在大多数并发层级下,3.6-35B 每分钟完成的请求数是其他两者的 2-4 倍**(差距在 c=1 时最小,在 c=4 左右最大)。27B 在 c=1-5 期间维持在平稳的 ~7/min(慢但稳)。122B 从 c=2 开始吞吐量便饱和于 ~9-10/min——超过 2 的并发并不能让它完成更多工作,只是将队列中的请求分散处理罢了。 ## 遵规能力差距 基于 ~20 场同级别负载会话的横向对比(任务类型相同,查询内容从未重复): | Model | Sessions | Tool calls | Errors | Err/tool | |:-|:-|:-|:-|:-| | qwen3.5-27b (dense) | 21 | 161 | 9 | **5.6%** | | qwen3.5-122b-a10b (MoE) | 17 | 128 | 13 | 10.2% | | qwen3.6-35b-a3b (MoE) | 20 | 158 | 19 | 12.0% | 稠密 27B 的工具调用错误率约为任意一款 MoE 的一半。我额外引入了 **Qwen3.5-35B-A3B 作为对照组**——架构与 3.6-35B 完全一致(总计 35B / 激活 3B / 256 个专家 Top-8),仅微调数据不同。其错误率落在 **11.3%**。三款路由型 MoE 覆盖了 3B 到 10B 的激活参数、8M 到 20M 的单专家容量以及完全不同的微调目标——但全部收敛在狭窄的 **10-12% 错误区间**。架构决定了错误率的天花板;后训练仅改变错误发生的类型,而不改变发生频率。模型为何出错,远比出错频率更重要。 在一次长链路多阶段研究中,每个阶段结束需通过 3 次调用的握手协议确认。结果 3.6-35B 连一个完整阶段都跑不完。它不断重试被禁的 Bash 变体(如 `ls scripts/ | grep -E "search|web"`、`curl -s 'https://...'`、虚构的 `--no-agent` 参数、幻觉出的 `youtube_fetcher.py` 脚本),耗尽单轮额度却始终未触发状态跳转。随后 27B 接手了 3.6-35B 卡死的完全相同的任务实例,并干净利落地完成了执行——它在第一次被拒时就果断切换到了其他允许的脚本。该模式在三款 MoE 上高度一致:反复尝试绕过同一封锁形式的变种(`| head -5` → `| head -10` → `| tail -3`),而非调整策略。而稠密模型懂得灵活转向。我的看法是:路由机制稀释了规则的特异性——每个 token 仅激活一小块网络,上下文指定的规则会与预训练先验中对“Bash 语法长什么样”的认知产生竞争。Shell 惯用语拥有强大的密集先验,自定义白名单没有,而后训练只会改变哪些惯用语会“泄露”,却无法阻止泄露本身。 ## 硬件配置 解释相关启动参数的硬件环境:4 张 RTX 3090,其中两张通过 NVLink 互联,另外两张仅走 PCIe。所有显卡均已降压锁定在 250W。`--disable-custom-all-reduce` 用于规避 vLLM 在混合拓扑下的识别混乱问题(注:原文此处截断)
查看原文

相似文章

Qwen 35B-A3B 在 12GB 显存下非常可用。

Reddit r/LocalLLaMA

一位用户在12GB的RTX 3060上对Qwen 35B-A3B(一个35B参数的MoE模型)进行了基准测试,发现12GB显存是运行该模型并支持32k上下文时的实用甜点区,生成速度可达约47 token/秒。