27B 模型压进 12GB 显存的量化实践
作者将 Qwen3.8-27B 文本权重从 53.8GB 压至 8.31GB,在单张 12GB 笔记本显卡上测得 37.7 tokens/s。新版量化改善了困惑度,但仍落后于所测 DASH-Q 方案,且必须使用修改版 llama.cpp。
AI 深度解读
27B 模型能不能塞进一张 12 GB 笔记本显卡?作者给出的实测答案是:可以,把 Qwen3.8-27B 的文本权重压到 8.31 GB,再配合修改过的运行时,所有层都能放进 GPU,生成基准达到 37.7 tokens/s。
但这篇更有价值的内容是:同样大小的量化文件,把有限的比特分给不同矩阵,效果能差多少。作者报告了改进,也承认质量仍落后于 DASH-Q,而且普通 llama.cpp、Ollama 和 LM Studio 都不能直接加载。
12 GB 装下 27B,靠的是什么取舍
Qwen3.8-27B 有 270 亿参数,原始 16-bit 文本权重占 53.8 GB。这个数字已经排除了视觉塔和多 token 预测模块,作者发布的文件也不包含它们。
即便降到 4-bit,权重仍约有 13.5 GB,还没算对话缓存就超过了显存。常见办法是把部分层留在系统内存,代价是生成速度受到较慢内存和数据搬运的限制。作者希望所有层驻留 GPU,因此继续压到约 2-bit。
这里的 2-bit 不是每个权重都只保留四种取值。Pingala-8 会对权重分组编码,保留缩放信息,并给敏感张量更多比特。最终文件平均约为每权重 2.5 bits,大小为 8,314,241,600 bytes,拆成 9 份发布,相比原始权重缩小 84.5%,约为原来的 1/6.5。
编码方法包括随机 Hadamard 旋转、LDLQ 舍入,以及每行按 4 个权重分组的 8 状态网格编码,思路来自 QuIP、QuIP# 和 QTIP。可以把它理解成:先变换权重分布,再联合编码一组数,降低极低精度带来的误差。
作者只在一台 WSL2 下的 RTX 5070 Ti Laptop GPU 上验证过。12 GB 显存能容纳全部模型层,并留出 4,096-token 上下文空间;更长上下文和其他显卡没有在本文中得到实测保证。
速度也要分开看:37.7 tokens/s 来自 batch 1 的 llama-bench tg64;聊天演示在关闭 thinking 后,运行时统计为 31.63 tokens/s,正文称统计了 124 tokens。两者差距尚未调查,动图说明里的 125 tokens 也与正文存在一处出入。
同样是 8.31 GB,为什么第二版更准
量化预算怎么分配,会直接影响模型质量。
Transformer 各层包含不同用途的矩阵,例如构建查询、键和值的 attn_qkv,前馈网络的 ffn_up、ffn_gate、ffn_down,以及线性注意力层的 ssm_out。矩阵用途不同、所在层深度不同,对量化误差的敏感程度也可能不同。
第一版沿用了 llama.cpp 的 IQ2_XXS 分配方式,attn_qkv 使用每权重 4.5 bits,其他部分就得压缩预算。第二版读取 jkim96 发布的 DASH-Q 文件中各张量的类型,照着它按用途和层深分配预算,编码方法没有改变。
相同的 20 个 WikiText-2 窗口上,困惑度从 7.34 降至 6.89,文件仍是 8.31 GB,而且全部窗口都改善了。困惑度衡量模型预测文本的能力,越低越好。作者证明的是 DASH-Q 的分配方案也能帮助另一种编码器,并没有把方案原创归于自己。
但照搬到 Qwen3.5-2B 就失败了:困惑度从 15.62 升至 15.80,70 个窗口里只有 22 个改善。27B 的方案给后部前馈层分配了 4.1 bits,却只给 ssm_out 2.6 bits,对小模型并不合适。
另一个问题藏在 embedding。2B 的 token embedding 与输出头共享矩阵,作者用 Q5_K,占 350 MB;DASH-Q 用 Q4_K,占 286 MB。同等文件大小下,DASH-Q 留给其他矩阵的空间是 489 MB,作者只有 429 MB,相差约 14%。
改用 Q4_K、释放 61.6 MB,并采用 DASH-Q 的 2B 专属方案后,文件缩至 778,189,408 bytes,困惑度降到 14.06,比第一版下降 10.0%,70 个窗口全部改善。
作者还尝试了 water-filling:测量各张量在不同位宽下的误差,再把比特优先分给最能降低误差的位置。两个变体在 Qwen3.5-0.8B 上都输给 DASH-Q 方案,约花费 35 GPU 分钟便被淘汰。单个张量的误差可能无法代表整个模型的损失,但这只是解释假设。输入原文缺失了对应表格,无法核对具体分数。
能跑起来,还要付出哪些兼容成本
比较质量时,作者让不同文件使用相同文本、相同的前 20 个窗口,每个窗口 4,096 tokens。
DASH-Q IQ2_XS 的文件为 8.55 GB,困惑度 6.54,20 个窗口全部领先 Pingala-8。它的每 token 损失优势为 0.052 nats,95% 区间为 ±0.012,相当于多用 0.24 GB 文件空间,换来约 5% 的困惑度改善。
unsloth UD-IQ2_S 为 8.37 GB,困惑度 7.34。Pingala-8 虽然平均值更低,却只在 9/20 个窗口胜出,配对差值区间为 -0.064 ±0.075,包含零,作者没有认定自己获胜。
速度没有进行竞品对照。竞品中的 IQ1_S、IQ2_S、IQ3_S 张量在作者显卡上需要回退到 CPU,拿来比较会失去公平性。
复现则需要固定 llama.cpp 提交并打两个补丁,原文命令如下:
git clone https://github.com/Genrius-AI/pingala8-llm
git clone https://github.com/ggml-org/llama.cpp && cd llama.cpp
git checkout 7ac59a6e3ad851cd41af00f678effab0598ba9a8
git apply ../pingala8-llm/patches/llama_cuda_vs_7ac59a6.patch
git apply ../pingala8-llm/patches/q35_loader_count_delta.patch
cmake -S . -B build -DGGML_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=120 -DCMAKE_BUILD_TYPE=Release -DLLAMA_OPENSSL=OFF
cmake --build build -j8 --target llama-cli llama-perplexity llama-bench
hf download Genrius-AI/Qwen3.8-27B-Pingala8-2bit --local-dir qwen3.8-27b-pingala8
export GGML_F44=4 GGML_F44_BATCH=2 GGML_VR_NATIVE=1 GGML_VRC_V=5 GGML_VRC_NWP=8 GGML_VR_RL=1 GGML_VR_PRMG=1 GGML_VR_PPC=2
./build/bin/llama-cli -m qwen3.8-27b-pingala8/Qwen3.8-27B-Pingala8-2bit-00001-of-00009.gguf -ngl 99 -c 4096
要特别看 -DCMAKE_CUDA_ARCHITECTURES=120:它对应作者的 RTX 50 笔记本显卡,需要按自己的显卡调整。加载时传入第 1 个分片,-ngl 99 请求将模型层卸载到 GPU,-c 4096 设置上下文长度。作者没有验证一键构建方式。
我的判断
我认可这篇对实验边界的交代:它区分了聊天速度与基准速度,也没有把更低的平均困惑度直接包装成胜利。
对一般开发者,最大的启发是把量化看成整个文件的预算问题。embedding、输出头和不同层都要算进去,单独追求某些矩阵的精度,可能挤占更需要空间的部分。这个判断有 27B 和 2B 的实验支撑,但还不足以推出通用分配规则。
选择文件时,我更看重原文承认的取舍:DASH-Q 质量更好,使用标准 llama.cpp 类型;Pingala-8 文件更小,但需要维护专用运行时。作者没有证明后者更快,也没有给出代码生成、工具调用或长对话的质量结果。
装得下和跑得动,不能直接推出适合日常 AI 编程。
WikiText-2 能帮助比较量化损失,却不能替代真实任务验收。至于 water-filling 为什么失败,目前仍是待验证的解释,不能据此认定这种分配思路普遍无效。
能拿来做什么
- 如果准备在 12 GB NVIDIA 笔记本上运行本地模型,可以把 8.31 GB 权重和 4,096-token 上下文作为这次实测的参考,并在自己的机器上检查完整显存占用和持续生成速度。
- 如果准备接入日常 AI 编程流程,应补测常用代码任务,例如组件修改和 Node 脚本修复,同时记录答案可用性、延迟与上下文长度;原文没有验证这些能力。
- 如果正在尝试量化方案,可以先用小模型淘汰明显失败的想法,再到目标模型复测,并把 embedding、输出头纳入总预算。
- 如果优先考虑部署省事和标准工具兼容,可以先考察 DASH-Q;只有愿意维护补丁运行时、且确实需要更小文件时,再评估 Pingala-8 的取舍。