最近很火的 Ternary-Bonsai-2-27B(Bonsai-2 技术把 27B 压进 5.95GB),我拿 RTX 3070 8G 真跑了两组数据。网上原理讲得很多,这篇只讲实测:推理预算怎么设是个坑,上下文的悬崖在速度不在显存。两组成手数据,8G 显卡党直接抄参数。
一、实测环境
| 项 | 配置 |
|---|---|
| CPU | AMD Ryzen 9 7900 |
| 内存 | 64GB DDR5 5200 |
| GPU | NVIDIA GeForce RTX 3070(8GB) |
| 驱动 | 581.15(CUDA 13.0) |
| 推理引擎 | llama-server 0.2.0-devbuild 10709(commit 9a9394a89,PrismML fork) |
| 模型 | Ternary-Bonsai-2-27B-PTQ1_0.gguf(5.95 GB) |
| SHA256 | 53107F53…33EE3 |
| KV 缓存 | q8_0 |
说明:必须用 PrismML 的 llama.cpp fork;原版 llama.cpp 要么拒绝加载,要么静默加载吐乱码(后者更坑,详见前文)。
二、极简背景:三板斧
把每个权重从"65536 档的 16 位浮点"压成"-1/0/+1 三档",靠三板斧(顺序不能反):
- 旋转:分块哈达玛摊平离群值(离线塞进权重,推理时逆变换——这就是 fork 才能跑的原因);
- 三值化:每权重只留三个值;
- 缩放:每 128 个权重配一把 FP16 尺子 → 5.95GB。
网上四个 bit 数(1.585/1.71/1.72/1.76)量的是四件事,别混着比:记住 1.76 和 5.95GB 就行。1.76 是实测全文件位宽(精确值 1.76548,截断口径);"0.0976% 高精度白名单"我拿 GGUF 文件逐张量核对过(FP16 留 ssm_alpha/beta,FP32 留 norm/ssm_a/dt.bias/conv1d),厂商数字是实的。
三、实测①:推理预算横扫
固定一道 174 字逻辑题,只改--reasoning-budget:
| 推理预算 | 生成 token | 墙钟 | 完整? | 生成速度 |
|---|---|---|---|---|
关闭思考 (--reasoning off) | 7214 | 198.5s | ✅ | 36.5 t/s |
| 512 | 3351 | 90.8s | ✅ | 37.3 t/s |
| 1024 | 16210 | 472s(7.8分钟) | ❌ 截断 | 34.4 t/s |
| 2048 | 8835 | 247.1s | ✅ | 35.9 t/s |
| 4096 | 8216 | 228.9s | ✅ | 36.0 t/s |
反直觉点:预算越大 ≠ 越稳。1024 档吐了 16210 token(比 4096 多近一倍)反而被 16K 窗口截断,答案半截。
但我要收回"1024 是坑"这个初判。补测把 1024 那轮完整思考拉出来看:它全程在(用英文)认真证明一道题——“O(n) 时间、O(1) 空间、不新建任何数据结构,找出出现奇数次元素”——而这道题的约束互相矛盾、严格说不可解。模型在 discovering 不可解性,没坏,是在干正事。翻车 = 预算 × 难度 × 窗口三者没匹配,不是 1024 本身有坑(换成简单题 1024 可能秒回;给足预算或更大上下文,同样的题它能写完论证)。
另一个隐藏事实:快慢根本不是问题。五档速度 34.4~37.3 t/s 几乎没动。8G 卡上瓶颈不是算力,是"想没想完 + 窗口够不够装"。
四、实测②:上下文悬崖在速度不在显存
固定--reasoning-budget 2048(q8_0 KV),扫不同上下文:
| 上下文 | 显存占用 | 生成速度 | 完整? |
|---|---|---|---|
| 4K | 6.0G | ~38 t/s | ✅ |
| 8K | 6.1G | ~37 t/s | ✅ |
| 16K | 6.4G | ~37 t/s | ✅ |
| 32K | 7.0G | ~37 t/s | ✅ |
| 48K | 7.6G | ~38 t/s | ✅ |
| 64K | 7.8G | ~20 t/s(腰斩) | ✅ 但慢一倍 |
- 显存几乎不随上下文涨:4K→64K 只涨 1.8G,全程 8G 以内。原因:Bonsai-2 是混合注意力架构(64 层里约 75% 线性注意力),KV 缓存本来小。
- 真正的悬崖在速度:4K–48K 全程满速打平;一跨 64K,速度直接腰斩到 ~20。基本排除 CPU 卸载——64K 时显存才 7.8G,离 8G 天花板还差一截,真要卸载显存早吃满了。断崖另有成因(很可能 64K 下注意力/某条内核路径突变),具体成因我标 TBD,不写死。
- 结论:纸面 262K 在 8G 上是数字游戏,实测满速区4K–48K(6.0–7.6G,37–38 t/s 打平)。
五、操作建议 + 启动命令(8G 卡直接抄)
- 难题要么给足预算(≥2048)+ 开大上下文,要么直接关思考;简单题 512 或关思考。
- 默认不写 flag = 无限思考到截断,必须显式给值。
- 语法坑:
--reasoning-budget off非法(日志直接 invalid stoi argument),关思考写--reasoning off。
启动示例(路径按你机器实际):
D:\llama27B\llama-server.exe ^ -m D:\AI_Models\Ternary-Bonsai-2-27B-PTQ1_0.gguf ^ --host 127.0.0.1 --port 8080 ^ -ngl 99 --ctx-size 16384 ^ --reasoning-budget 2048 ^ --cache-type-k q8_0 --cache-type-v q8_0 ^ --jinja已实测确认:
-ngl 99全量上卡;--ctx-size 16384(16K)是 8G 卡舒适区;预算改512/2048/-1(不限制)按需。
六、GGUF 内部核对表
我拿 Python 解析了 GGUF 头部(851 个张量、49 条元数据):
| 项 | 值 |
|---|---|
| 架构 | qwen35(llama.cpp 对 Qwen3.8 混合注意力架构代号) |
| 层数 | 64(全注意力间隔=4 → 16 全注意力 / 48 线性注意力 = 75%) |
| 上下文 | 262,144 |
| 三值张量(type-143) | 402 个,26,869,760,000 元素,精确 1.75000 bit/权重 |
| 高精度白名单 | FP16 96 个(48层×ssm_alpha/ssm_beta)+ FP32 353 个(norm/ssm_a/ssm_dt.bias/ssm_conv1d),合计 0.0976% |
| 全文件实测位宽 | 1.76548 bit/权重 |
| 旋转元数据 | prism.hadamard.weight_names / inverse_weight_names 存在 |
一个口径提醒:GGUF 内实存参数约 26.90B 元素,与宣传的"27.36B"差约 1.7%——qwen35 架构可能有 embedding 共享/裁剪,我未当 bug 处理,列此供参考。
七、MoE 能不能套?能,但两道硬约束
- 收益比稠密更大:MoE 的痛是"装不下",三值直接解决。
- 加速收益打折:MoE 本来就只读激活专家。
- 约束一:router 不能三值化——router 输出过 argmax,不吃噪声。CSDN 工程师实测(DeepSeek-MoE-16B):全 4-bit 困惑度 12.8;router 保高精度 8.3。
- 约束二:稀有专家更脆——反直觉,按脆弱度分配精度,不按使用频率。
八、结语
8G 卡上它脾气我摸清了:预算别只认准某个值,难题给足预算+大窗口或直接关思考;上下文 4K–48K 满速、64K 才腰斩(成因 TBD)。拿你自己的活儿跑一轮更见真章。
评论区互动:你的显卡显存多大?跑预算 512 和 2048 两档,把显卡型号 + 生成速度报上来,我汇总成速查表。
更多相关信息可关注GZH获取。