<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Llama.cpp on TouchingFish.top</title><link>https://touchingfish.top/tags/llama.cpp/</link><description>Recent content in Llama.cpp on TouchingFish.top</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Fri, 30 May 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://touchingfish.top/tags/llama.cpp/index.xml" rel="self" type="application/rss+xml"/><item><title>当你连 scale 也量化了</title><link>https://touchingfish.top/2025/gguf-k-quants/</link><pubDate>Fri, 30 May 2025 00:00:00 +0000</pubDate><guid>https://touchingfish.top/2025/gguf-k-quants/</guid><description>&lt;p&gt;上次算到，160 亿参数的模型用 Q4_0 量化后，光 scale 和 $\alpha$ 这些&amp;quot;说明书&amp;quot;就要吃掉 2 GB。&lt;/p&gt;
&lt;p&gt;2 GB 不小。一台 16 GB 显存的显卡，模型权重压缩后大概 8 GB，结果说明书自己占了四分之一。这就像你去宜家买了一张桌子，包装盒里一半是螺丝和安装图纸。&lt;/p&gt;
&lt;p&gt;K-quants 要解决的就是这个问题。思路很直白——既然权重可以量化，那说明书也可以量化。&lt;/p&gt;
&lt;h2 id="套娃"&gt;套娃&lt;/h2&gt;
&lt;p&gt;K-quants 的核心结构叫 super-block。做法是把 8 个普通 block 打包成一组，然后对 8 个 scale 再做一次量化——从 FP16（16 bit）砍到 INT8（8 bit）：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;super-block: 256 个 INT4 权重
├── block 0: scale = 0.10 (FP16 → INT8)
├── block 1: scale = 0.14 (FP16 → INT8)
├── block 2: scale = 0.11 (FP16 → INT8)
├── block 3: scale = 0.18 (FP16 → INT8)
├── block 4: scale = 0.08 (FP16 → INT8)
├── block 5: scale = 0.16 (FP16 → INT8)
├── block 6: scale = 0.13 (FP16 → INT8)
├── block 7: scale = 0.09 (FP16 → INT8)
└── super-scale = 0.00142 (FP16) ← 新加的，用来还原上面那些 INT8
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;来走一遍完整的计算。假设这 8 个 block 里 256 个权重已经量化完了——每个 block 的 scale 是上面那 8 个 FP16 值。现在的任务是把这 8 个 scale 自己也量化掉。&lt;/p&gt;</description></item><item><title>当你把模型从16位砍到4位</title><link>https://touchingfish.top/2025/gguf-legacy-quants/</link><pubDate>Mon, 19 May 2025 00:00:00 +0000</pubDate><guid>https://touchingfish.top/2025/gguf-legacy-quants/</guid><description>&lt;p&gt;第一次在本地跑 Llama 的时候，下载页面那一排 Q4_0、Q4_K_M、Q5_1 让我愣了半天。&lt;/p&gt;
&lt;p&gt;选了最大的文件，跑不起来。显存不够。选了最小的文件，跑起来了，但回答像喝了假酒。后来才知道，这一排名字背后是一整套妥协方案——在模型的&amp;quot;胖瘦&amp;quot;和&amp;quot;聪明程度&amp;quot;之间找平衡。&lt;/p&gt;
&lt;p&gt;这篇文章讲最早的那套方案：legacy quants。GGUF 现在已经有 K-quants 和 I-quants 了，但 legacy 是地基。搞懂了它，后面那些花里胡哨的变体无非是在这个地基上换砖头。&lt;/p&gt;
&lt;h2 id="fp16-和-int4"&gt;FP16 和 INT4&lt;/h2&gt;
&lt;p&gt;在聊量化之前，先搞懂两样东西：模型权重长什么样，以及我们想把它变成什么样。&lt;/p&gt;
&lt;p&gt;FP16 是半精度浮点数。16 个 bit（2 个字节），存一个带小数点的数。C 语言里没有 FP16，但你想象一个比 &lt;code&gt;float&lt;/code&gt;（32 位）更省空间的浮点数就行。大模型的权重——那些矩阵里的每一个数字——出厂的时候就是 FP16。一个 70 亿参数的模型，70 亿个 FP16，也就是 14 GB。不大不小，刚好塞不进一张 12 GB 的消费级显卡。&lt;/p&gt;
&lt;p&gt;INT4 是 4 位整数。4 个 bit，能表示 $2^4 = 16$ 个不同的值。如果你只写过 C，你熟悉的整数是 &lt;code&gt;int&lt;/code&gt;（32 位）、&lt;code&gt;short&lt;/code&gt;（16 位）、&lt;code&gt;char&lt;/code&gt;（8 位）。4 位的整数在 C 里没有——太小了，小到没法单独寻址，必须打包存储。&lt;/p&gt;
&lt;p&gt;打个比方：FP16 像女生的口红色号——豆沙、枫叶、烂番茄，每一格都有名字。INT4 是男人的衣柜——黑、白、灰、深蓝，能数的就那几种。&lt;/p&gt;
&lt;p&gt;量化的核心问题就是：怎么用男人的衣柜里那几种颜色，还原出口红色号的全部渐变？&lt;/p&gt;
&lt;p&gt;这是有损压缩。丢掉的信息永远捡不回来。&lt;/p&gt;
&lt;h2 id="假装天平是平的"&gt;假装天平是平的&lt;/h2&gt;
&lt;p&gt;GGUF 的量化不是把每个 FP16 单独转成 INT4。那样做的话，每个权重需要一个 scale（缩放系数）来告诉你怎么&amp;quot;还原&amp;quot;，而 scale 本身就是 FP16——16 位。用 16 位存 scale 去压缩一个 16 位的权重？没有意义。&lt;/p&gt;</description></item></channel></rss>