欢迎光临
我们一直在努力

Ternary Bonsai 2 27B:8GB 显卡硬塞 27B 三元模型,能跑,但我大概率不会真用

先说结论:27~30 tok/s ,既不是天使,也不是恶魔。确实能跑,而且不是那种 “模型加载成功就算跑” 的能跑。但是吧,那个什么,但是在我这个配置看来,实用性还是差点意思。

RTX 4070 Laptop 8GB,Ternary Bonsai 2 27B 的 PTQ1_0 权重、Q4 KV、Flash Attention、CUDA Graph 全走 GPU 路径,64K 上下文,我实际跑通了。没有偷偷卸载几层到 CPU,没有把 KV 扔进内存,也没有为了截图把上下文缩到 4K。

但说一千道一万,我还是不会用。

原因很简单:这套东西不能催。 你把它扔后台,它慢慢磨,真能干活;你坐在屏幕前等它一个字一个字往外蹦,用不了十分钟就会开始怀疑自己为什么不直接调云端 API。

先交代机器和配置
RTX 4070 Laptop,8GB 显存
Intel i7-14650HX,32GB 内存
PrismML 的 llama.cpp 分支,commit 1a07bfa5f
CUDA 13.4.2,按 Ada sm_89 编译
Ternary Bonsai 2 27B PTQ1_0
K/V 用 Q4_0,Flash Attention、CUDA Graph 全开
所有层都在 GPU,单 slot,纯文本,没加载视觉模块和投机解码 drafter
先说一个很多人会踩的坑:5.95GB 和 5.538GiB 不是一回事
PTQ1_0 权重文件是 5,946,648,928 字节。大家习惯说 “大约 5.95GB”,但换成显存真正用的二进制单位,是 5.538GiB。

这个差别在 24GB 卡上没人在乎,在 8GB 卡上,它就是 “能跑” 和 “加载完一生成就崩” 的分界线之一。

Q4 KV 每个 token 大约占 18,432 字节,64K 上下文算下来约 1.125GiB。权重加 KV 已经超过 6.6GiB,剩下的空间还得放 CUDA 工作区、循环状态、临时张量、图执行缓冲,还有 Windows 桌面自己占掉的那部分显存。

所以这不是 “8GB 轻松跑 27B”,是 “8GB 刚好把 27B 塞进去”。8GB 卡上没有 “差不多”,只有 “刚好” 和 “差一点”。

实际速度:没有传说中那么神
64K 服务配置下,我测了两档 microbatch:

配置 Prefill Decode 峰值显存 最低空闲显存
ub=128360.58 tok/s27.38 tok/s7,706 MiB482 MiB
ub=64 337.70 tok/s27.66 tok/s7,670 MiB518 MiB
短 Decode 的独立基准最好到过约 29.97 tok/s,真实聊天请求一般落在 26~28 tok/s。

Prefill 确实快,八千多 token 的输入二十多秒就吃完了。真正让我不太满意的是 Decode——27 tok/s 单看数字不慢,普通聊天比不少人阅读速度还快,问题是这模型太爱 “想” 了。我愿意称之为“思考者”。

我做了几个很基础的能力测试:

严格 JSON 输出:正确
排列逻辑题:正确
显存容量计算:正确
C++ 整数溢出审查:结论正确
OpenAI 格式工具调用:参数正确
8062 token 文本里的针式检索:正确找到目标
问题出在 “过程” 上。

一个很简单的逻辑题,它吭哧吭哧生成了大约 733 个 token;一个显存除法题,大约 725 个 token。C++ 那道题,它其实很早就判断对了,结果在 1024 token 的预算里反复自我确认,最后连正式答案都没来得及输出。我就那么看着它把一句话能答完的题,绕了七百多个字。

把思考关掉之后,代码题回答得很快,但逻辑题又变成先报个错答案、写着写着再自我纠正。

这就是本地模型的真实使用感:基准里的 27 tok/s 是生成速度,不是完成任务的速度。 简单题先绕七八百 token,你等到的还是二三十秒之后才出来的最终结论。

Decode 为什么只能算一般
一开始我也觉得是 “Kernel 还没优化好”,后来把时间线拆开看:Kernel 确实有空间,但它不是唯一问题,甚至未必是最大的问题。

  • 每生成一个 token,基本要把整套权重重新读一遍
  • 这是 batch=1 自回归 Decode 绕不开的宿命。权重约 5.5GiB,每生成一个 token,绝大多数权重都要参与一次计算。

    按 27~30 tok/s 粗算,单是权重流量就在 150~165GiB/s 左右。RTX 4070 Laptop 不是算不动,是显存控制器一直在搬权重。

    三元权重把模型塞进了 8GB,但没让 27B 参数凭空消失。

  • 1.58-bit 附近的存储格式,不等于计算格式也舒服
  • PTQ1_0 的优势是密度高,三元值压得紧,省显存也省读取。

    代价是 GPU 取到数据以后,还得做 base-3 解包、恢复 -1/0/+1、读 scale,再进整数点积。现在的专用 Kernel 已经是边解码边计算,没有先把整层权重展开成 FP16 写回显存 —— 但 “没有落地一份反量化权重” 和 “硬件可以直接算压缩 trit” 仍然是两回事。

    Ada 没有原生三元点积指令。最终还是得把这些紧凑编码变成 GPU 能消费的形式,只不过展开过程发生在寄存器和 Kernel 内部。

    压缩比很漂亮,解码并不免费。

  • 单 token 的 GEMV 喂不饱 Tensor Core
  • Prefill 一次有很多 token,能形成大矩阵乘法,GPU 容易发挥。Decode 通常只有一个 token,本质上更接近矩阵向量乘。Tensor Core 很难像大批量 GEMM 那样吃满,计算成本落到显存带宽、整数解包和细碎的归约上。强行把三元权重包装成 INT8 或 INT4 再喂 Tensor Core,也得先付展开和额外存储的代价。

  • FFN 能合并的,官方路径其实已经合了不少
  • 我专门查过 FFN。gate、up 和 SwiGLU 已经合进一个 PTQ1_0 MMVQ Kernel,前面的 Hadamard 变换可以共享,后面的符号乘也并进了后续路径。

    修掉一个输入输出别名导致的保守拒绝后,融合覆盖从 40 层提到了 64 层,结果整机 Decode 收益只有大约 0.2%~0.5%。原因很直接:gate 和 up 能共享输入,但共享不了两套不同的权重。Trace 里这部分仍然占 GPU Kernel 时间的 39%~41%,大头是两份权重流和 base-3 解码,不是那一下 SwiGLU 非线性。

    重复激活量化只有约 1.1 微秒,继续围着它抠,抠不出大结果。

  • CUDA Graph 和 CUDA 13 不是加速魔法
  • CUDA Graph 已经在稳定复用,启动开销不是当前的大头。CUDA 13.4.2 重新编译也能正常跑,但编译器升级不会替你发明一条 Ada 上不存在的三元指令。

    我试过几个看起来很有道理的调度改法:减少 warp、拆分 gate/up、顺序计算、增加 warp 数量。数值测试全都能过,速度普遍下降。其中把 small-K 路径改成单 warp,Decode 直接从约 29 tok/s 掉到 26.29 tok/s。

    另一个更激进的融合实验同时拖慢了 Prefill 和 Decode,已经默认关闭。

    这类优化最容易产生一种错觉:代码少了、Kernel 数少了、寄存器看着也降了,所以应该更快。实际上权重访问并行度和 occupancy 一掉,结果马上反过来。那个心情,折腾过 Kernel 的应该都懂。

  • Q4 KV 是省显存工具,不是速度工具
  • Q4 KV 让 64K 能塞进 8GB,这是它最大的价值。

    但 Q4 数据在 attention 里仍然要解码,质量上还需要继续做 mean-centering bias 对照。它通常比 F16 KV 稍慢,不能一边享受省下来的显存,一边假设量化完全没有计算代价。

    短上下文检索正确,也不能证明 64K 的每个位置、每种任务都没有质量损失。

    PQ2 会不会快很多?我暂时不信
    PQ2 的思路不难理解:多花一点存储,把权重放成更容易被 Kernel 消费的形式,少做密集解包。PTQ1_0 偏存储效率,PQ2 偏计算效率。

    问题是 PQ2 模型大约 7.2GB,PTQ1_0 是 5.95GB。放在 8GB 显卡上,这不是 “稍微大一点”,是会直接吃掉原本留给 64K Q4 KV、CUDA 工作区和桌面波动的空间。

    而且 Decode 同时受权重读取和解码影响。PQ2 解码简单一些,但权重本身也变大了,要搬更多字节。到底哪边占上风,取决于具体 Kernel、显存带宽和实际 shape。

    所以 “PQ2 能快很多” 这句话我先保留。它可能更快,尤其可能改善 Prefill;也可能只快几个百分点,甚至在 8GB 这张卡上因为显存和带宽压力把收益吃回去。没有同一台机器、同一个 commit、同一套 Q4 KV 参数的 A/B 数据之前,我不会把 “理论上少解包” 直接写成 “实际快很多”。

    更现实的问题是:就算 PQ2 真快 10%,也可能让 64K 配置放不下。那就不是白捡 10%,是拿上下文容量换速度。

    后面还有没有优化空间
    有,但我不再期待一次简单改动就翻倍。

    比较值得继续看的方向有三个:

    第一,更适合计算的三元布局。比如把权重拆成 nonzero 和 sign 两个位平面,从接近 1.6-bit 回到 2-bit 左右,牺牲容量换更便宜的解码。问题还是 Ada 没有直接对位掩码选择后的 Q8 激活求和的指令,最后能不能赢要看微基准。

    第二,加载时 retile,把 code 和 scale 按实际 DP4A 消费顺序重排。有机会改善访存和指令组织,但如果底层仍然要逐个恢复 trit,我认为更可能是几个百分点的收益,不是架构级变化。

    第三,投机解码。单 token Decode 最大的问题是每次只为一个 token 读取整套权重。如果一次权重读取能同时验证多个候选 token,才真正有机会摊薄权重和解码成本。这条路线比继续减一两个 Kernel 更值得期待,不过它会额外占显存,也会影响多轮缓存和服务调度。

    这些都可以慢慢试,但必须做同条件 A/B。代码看着高级、Nsight 时间线更整齐,都不能代替最终的 tokens/s 和任务完成时间。

    那它到底有没有实用性
    我可以肯定的说:有。而且远没有最近网上那些文章写的那样差。

    如果任务可以扔到后台 —— 本地文档整理、隐私文本分析、代码初审、批量抽取、离线知识库 ——27 tok/s 完全能干。工具调用能正常生成,八千 token 的检索没出错。对一张 8GB 笔记本显卡来说,能把一个 27B 稠密模型留在 GPU 上,本身已经很有意思。

    但我不会拿它做追求即时反馈的日常主力。原因不是单纯的 27 tok/s,而是模型推理长度不好控制:简单问题可能先想七八百 token,复杂代码问题又可能在预算耗尽前不给最终答案。这个等待感,比跑分更影响使用体验。

    64K 也应该当成活跃工作窗口,不是无限记忆。真正的长任务仍然需要外部状态、阶段摘要和按需取回原文。把所有历史一股脑塞进去,只会让首字越来越慢,并不能自动变聪明。

    总结成一句话:8GB 显卡跑 27B 三元模型,已经从 “技术演示” 进入 “凑合能用” 的阶段,但还没进入 “我愿意天天当主力用” 的阶段。

    它不是没价值,是不能着急。后台挂着慢慢磨,可以;指望它像高端卡或者云端服务一样随叫随到,目前不现实。

    至于 PQ2、原生三元 Kernel、CUDA Graph 深度融合或者 CUDA 新版本能不能再推快一截,我后面继续测。但以后只认同机实测,不认纸面倍数。

    至少现在,8GB 确实把 27B 塞进去了。只是塞进去之后,剩下的问题才刚开始。

    你们 8GB 卡现在都在跑什么?欢迎评论区留言,我下一步打算做 PQ2 的同机 A/B,测完回来更新(大概率要鸽 没啥动力测了)。

    赞(0)
    未经允许不得转载:171主机测评 » Ternary Bonsai 2 27B:8GB 显卡硬塞 27B 三元模型,能跑,但我大概率不会真用
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址