一张 12 GB 显卡,能把 27B 模型跑到什么程度?

我最近在 Windows 10 的 RTX 3060 12 GB 上折腾了 Ternary Bonsai 2 27B。最初只是想把模型跑起来,后来又把 NInfer、投机解码、KV 缓存量化和长上下文 Ring 路径逐一测了一遍。

结论比“能不能加载”更有意思:使用三值权重和 MTP 投机解码后,NInfer 在 20K 提示词深度下测得 61.2 token/s 的 decode,在 60K 深度下仍有 51.2 token/s;再启用 Ring KV 后,96K 的设备缓存池可以服务超过 129K 的文本序列。代价是 Ring 深上下文的 prefill 和 decode 会明显变慢,而且“配置为 256K”不等于已经对完整 256K 做过质量与稳定性验证。

本文记录这条部署路线、关键参数、实测结果和踩过的坑,方便同样只有 12 GB 显存的人判断是否值得尝试。

模型和机器配置

这次使用的是 PrismML 发布的 Ternary Bonsai 2 27B。它以 Qwen3.8-27B 为基础,把大部分文本投影权重压成三值形式。NInfer 使用的转换制品还组合了视觉权重、为 Bonsai 训练的 MTP 头和 DFlash2 适配器。

项目 配置
显卡 NVIDIA GeForce RTX 3060 12 GB,sm_86,28 SM
内存 32 GB
系统 Windows 10 LTSC 19044
CUDA 12.8.93
NInfer 面向 sm_86 的本地构建;本机实测分支为 franken/v0.11 系列
NInfer 模型制品 约 9.52 GB,包含 MTP、DFlash2、proposal head 和视觉组件

这里的速度和显存数字都来自 RTX 3060 实测。网上或项目文档里 RTX 3090 的数据只能用于参考,不能直接当成 3060 的结果。

为什么三值模型能装进 12 GB 显存

Bonsai 2 的主要文本投影使用三值权重:每个权重编码为 -1、0、+1,并以每 128 个权重共享一个 FP16 scale。对应 NInfer 的存储格式是 t2_g128_fp16,平均约 2.125 bit/weight。权重来自 PQ2_0 GGUF,转换时直接导入编码,不需要先反量化再重新量化。

这不代表模型所有部分都是 2.125 bit:注意力和状态空间模块仍要运行,KV、GDN 状态、视觉塔以及投机解码组件也会占用显存。因此,12 GB 机器上的关键不只是模型文件大小,还包括 KV 格式、上下文长度、投机头和视觉模块的驻留方式。

转换后的 NInfer v3 制品可从 WaveCut/Ternary-Bonsai-2-27B-NInfer-v3 获取。它约 9.52 GB,带有 Bonsai 专用 MTP 头和 DFlash2 适配器、proposal head 以及视觉组件。启动时只启用实际需要的组件,视觉塔采用 overlay residency,避免长期占住主要权重的显存空间。

在 Windows 上构建和启动

本机验证过的工具链组合是 CUDA 12.8、Visual Studio 2022 Build Tools 的 MSVC v143 14.44,以及 sm_86 架构。机器上如果同时装有较新的 Visual Studio,nvcc 可能会从 PATH 中找到不兼容的 MSVC;应先导入 VS 2022 Build Tools 的 vcvars64.bat 环境,再构建 NInfer。CUDA 12.8 在这套构建中不能直接使用 MSVC v145。

建议保留项目已经配置好的 build-ninja 构建目录,不要重新配置。完成构建后,服务端通过 .ninfer 制品启动。一个 96K 文本配置的核心参数如下,具体二进制和模型路径按本机修改:

1
2
3
4
5
6
ninfer-serve.exe bonsai2-27b.ninfer ^
--model-id bonsai2-27b ^
--host 127.0.0.1 --port 8080 ^
--max-context 98304 --kv-capacity 98304 ^
--kv-dtype rk8v4 --gdn-state-fp16 ^
--spec mtp --draft-tokens 3 --lm-head-draft

本机后续把常规配置切换为 nvfp4 KV,以换取更多上下文空间。模型服务提供 OpenAI 风格的本地接口:http://127.0.0.1:8080/v1。请求中的 model 字段需要填写 bonsai2-27b,否则服务会返回 400。

如果要使用图片输入,还需要启用 –vision –vision-residency overlay。本机完成了 PNG、JPEG 和真实截图的端到端验证。当前这套本地构建支持 base64 图片和本地路径;远程图片 URL 不在支持范围内。

最容易踩的坑:3090 的调度假设

NInfer 的一部分 SM86 路由参数最初按 RTX 3090 的 82 个 SM 调优。RTX 3060 只有 28 个 SM,某些 GDN gating 的协作式 MMA 路由因此无法满足驻留条件,可能在服务启动时就报 candidate is not legal for exact problem。

本机修复方式是在首选路由不合法时依次回退到更小的 split 路由,最后回退到不需要协作驻留的 MmaUnsplit。这提醒我:计算能力架构相同,并不意味着调度表就能跨 GPU 型号照搬。SM 数量会影响协作启动的资源预算;至少要在目标卡上实际走一遍模型加载和关键算子。

96K 常规上下文:速度与缓存命中

在 RTX 3060、96K 上下文、rk8v4 KV、MTP3 加 proposal head 的配置下,得到以下结果。提示词深度对应同一组测试请求;缓存后的 TTFT 是重复请求命中前缀缓存时的首 token 时间。

提示词深度 Prefill Decode MTP 接受率 TTFT
短请求(约 67 token) 141 token/s 97.2 token/s 79.6% 476 ms
20K 662 token/s 61.2 token/s 43.9% 30.0 s;缓存命中后 118 ms
60K 516 token/s 51.2 token/s 44.5% 1 分 55 秒;缓存命中后 170 ms

同提示的对比测试中,NInfer 20K decode 为 61.2 token/s,llama.cpp 128K 配置为 26.4;60K 时分别为 51.2 和 17.0。这个结果说明在这张卡上,三值 NInfer 加 MTP 的路线很有竞争力;它不是脱离上下文长度、KV 设置和投机策略之后的通用引擎排名。

前缀缓存也改变了长提示词的体感:首次处理 20K 输入仍需约 30 秒,完全相同的前缀再次出现时 TTFT 降至约 118 ms。它不会让首次 prefill 消失,但对固定系统提示词或反复使用同一长文档的工作流很有帮助。

KV 格式决定上下文容量

在同一制品和评测协议下,nvfp4 KV 相比 rk8v4 的总体困惑度从 5.630 增至 5.6395,差约 0.17%。测试覆盖 261,167 个 token。以这点困惑度变化换取约 67% 的上下文容量提升,对 12 GB 显卡是实用的取舍。

常规 dense 配置的实用范围约为 160K;在本机启动器中,默认是 160K,最高约 181K,继续加到 192K 会因显存不足而拒绝启动。具体上限仍会随桌面占用、其他 GPU 进程和启动组件变化,不建议把刚好能启动的容量当作稳定余量。

Ring KV:96K 显存池服务更长文本

如果任务确实需要更长上下文,可以启用 Ring KV:设备上保留约 96K token 的 KV 窗口,较早的 KV 页转移到主机内存,检索时再读回相关内容。本机逻辑上下文配置为 256K,显存约 10.2 GB,主机侧约 8 GiB pageable KV。

RTX 3060 上已完成的深上下文验证包括:

  • 4,422 token 输入:prefill 658.6 token/s,decode 67.3 token/s。
  • 65,513 token 输入:prefill 252.1 token/s,decode 37.2 token/s。
  • 129,376 token 藏针测试:超过 96K 设备池约 1.35 倍,检索结果通过;prefill 约 148–151 token/s,decode 约 18–20 token/s。
  • 双轮记忆请求通过;第二轮缓存闭合率为 68.2%。

Ring 的代价很清楚:长文本越深,host/device 搬运和检索开销越明显。129K 时 decode 已降到约 18 token/s,远慢于 dense 160K 配置。并且本机虽然设置了 256K 的逻辑上限,现有实测确认的是 129K 藏针与多轮路径;不能据此宣称完整 256K 各类负载均已验证。

投机解码该选 MTP 还是 DFlash2?

这张卡上,MTP3 加 proposal head 是更均衡的常规选择。一次本机 A/B 测试中,去掉视觉组件后,MTP3 decode 中位数为 77.8 token/s,不启用 speculation 为 37.2 token/s,约有 2.1 倍提升。该数值来自短请求测试,不应与前面 20K、60K 的长上下文速度直接比较。

DFlash2 在短到中等上下文有时更快,但它多占显存,接受率也会随着上下文和任务变化。我的测试中,20K 有提升,60K 的收益接近消失,而且 DFlash2 不能与 160K 的长上下文配置同时满足显存预算。因此,我把 MTP3 留作日常配置,DFlash2 作为短上下文极速选项。

不同引擎和投机实现之间也不能直接照搬结论:MTP 是否加速取决于草稿头、KV 格式、模型权重和调度实现,不是单看 RTX 3060 这个型号就能判断。

另一个影响体验的问题:thinking 预算

速度之外,Bonsai 2 的 thinking 模式也值得单独设置。过高的 reasoning effort 配合无限思考预算,可能让简单的 Agent 任务反复分析、调用工具,最终耗时远超任务本身。

本机给默认 thinking 设置了预算上限,作为防止长时间跑偏的保险丝;短问题通常只消耗少量 token,复杂任务则可以按需要提高预算。部署时最好先用几道真实工作流问题观察输出长度和工具行为,再调整 reasoning effort 与 thinking budget,而不是只用 token/s 评价模型体验。

这条路线适合谁

如果你有 RTX 3060 12 GB,想本地运行 27B 级模型,并且愿意花时间准备专用 NInfer 制品和 sm_86 构建,三值 Bonsai 2 加 MTP 是值得尝试的一条路线。96K 左右的 dense 配置在速度和上下文之间更均衡;需要读更长材料时,可以用 Ring 将逻辑窗口扩到 256K,但要接受深上下文速度下降和更多验证工作。

部署时最重要的经验有三条:

  1. 按目标 GPU 实测调度,不能把 RTX 3090 的路由参数直接视为 RTX 3060 的最优配置。
  2. 把权重大小、KV 格式、投机模块和上下文长度一起考虑,显存预算不是只看模型文件。
  3. 把“配置上限”“通过单项长文本测试”和“完整工作负载验证”分开表达,不要把 256K 参数写成 256K 全面验证。

参考链接