<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Numerical-Precision on Tarragon</title><link>https://tarrragon.github.io/blog/tags/numerical-precision/</link><description>Recent content in Numerical-Precision on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Tue, 12 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/numerical-precision/index.xml" rel="self" type="application/rss+xml"/><item><title>Floating Point（FP32 / FP16 / BF16）</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/floating-point/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/floating-point/</guid><description>&lt;p>Floating point（浮點數）的核心概念是「&lt;strong>用「符號位 + 指數位 + 尾數位」表示實數的二進制格式&lt;/strong>」。LLM 訓練跟推論用的精度（fp32 / bf16 / fp16）就是不同的位元分配方案。理解這些差異能解釋為什麼 bf16 是訓練主流、為什麼 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">量化&lt;/a> 對品質的影響不是「越多 bit 越好」這麼簡單。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>主流浮點格式的位元分配：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>格式&lt;/th>
 &lt;th>總 bit&lt;/th>
 &lt;th>符號位&lt;/th>
 &lt;th>指數位&lt;/th>
 &lt;th>尾數位&lt;/th>
 &lt;th>動態範圍&lt;/th>
 &lt;th>精度（有效位數）&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>FP32&lt;/td>
 &lt;td>32&lt;/td>
 &lt;td>1&lt;/td>
 &lt;td>8&lt;/td>
 &lt;td>23&lt;/td>
 &lt;td>±10^38&lt;/td>
 &lt;td>7 位&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>FP16&lt;/td>
 &lt;td>16&lt;/td>
 &lt;td>1&lt;/td>
 &lt;td>5&lt;/td>
 &lt;td>10&lt;/td>
 &lt;td>±65504（容易 overflow）&lt;/td>
 &lt;td>4 位&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>BF16&lt;/td>
 &lt;td>16&lt;/td>
 &lt;td>1&lt;/td>
 &lt;td>8&lt;/td>
 &lt;td>7&lt;/td>
 &lt;td>±10^38（同 fp32）&lt;/td>
 &lt;td>3 位&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>FP8 (E4M3 / E5M2)&lt;/td>
 &lt;td>8&lt;/td>
 &lt;td>1&lt;/td>
 &lt;td>4 / 5&lt;/td>
 &lt;td>3 / 2&lt;/td>
 &lt;td>視變體&lt;/td>
 &lt;td>1-2 位&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵 trade-off：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>FP16 精度好、範圍窄&lt;/strong>：尾數多、表達小範圍內細節準；但指數少、容易 overflow（gradient 爆炸時）/ underflow（gradient 接近 0 時）。&lt;/li>
&lt;li>&lt;strong>BF16 範圍跟 fp32 一樣大、精度差&lt;/strong>：指數位跟 fp32 同（8 位）、訓練時的 dynamic range 跟 fp32 接近、不會 overflow；但尾數少、精度差。實測對訓練影響小、所以是現代 LLM 訓練主流。&lt;/li>
&lt;li>&lt;strong>FP8 是新興格式&lt;/strong>：H100 / B200 等新 GPU 原生支援、訓練 / 推論都能加速、但精度損失需要 careful loss scaling。&lt;/li>
&lt;/ol>
&lt;p>LLM 工作流的精度選擇：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>場景&lt;/th>
 &lt;th>主流精度&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Pre-training（大模型）&lt;/td>
 &lt;td>BF16 + 部分 FP32（如 optimizer state）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Fine-tuning&lt;/td>
 &lt;td>BF16 + 可選 FP8 / Q4（QLoRA）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>推論（雲端 high-end）&lt;/td>
 &lt;td>FP16 / BF16&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>推論（消費級本機）&lt;/td>
 &lt;td>Q4_K_M 等量化、見 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">quantization&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 paper / config 看到 &lt;code>mixed_precision: bf16&lt;/code>、&lt;code>torch_dtype: bfloat16&lt;/code> 就是 BF16 訓練。寫 code 場景的判讀：本機跑 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/gguf/" data-link-title="GGUF" data-link-desc="llama.cpp 生態定義的模型權重格式：把權重、tokenizer、metadata 打包成單一檔案">GGUF&lt;/a> Q4_K_M 模型、內部運算的 activation 仍是 fp16 / bf16、只有權重儲存是 4-bit；&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache&lt;/a> 預設也是 fp16、量化 KV cache 是進階優化（K=Q8 / V=Q4）。&lt;/p></description><content:encoded><![CDATA[<p>Floating point（浮點數）的核心概念是「<strong>用「符號位 + 指數位 + 尾數位」表示實數的二進制格式</strong>」。LLM 訓練跟推論用的精度（fp32 / bf16 / fp16）就是不同的位元分配方案。理解這些差異能解釋為什麼 bf16 是訓練主流、為什麼 <a href="/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">量化</a> 對品質的影響不是「越多 bit 越好」這麼簡單。</p>
<h2 id="概念位置">概念位置</h2>
<p>主流浮點格式的位元分配：</p>
<table>
  <thead>
      <tr>
          <th>格式</th>
          <th>總 bit</th>
          <th>符號位</th>
          <th>指數位</th>
          <th>尾數位</th>
          <th>動態範圍</th>
          <th>精度（有效位數）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>FP32</td>
          <td>32</td>
          <td>1</td>
          <td>8</td>
          <td>23</td>
          <td>±10^38</td>
          <td>7 位</td>
      </tr>
      <tr>
          <td>FP16</td>
          <td>16</td>
          <td>1</td>
          <td>5</td>
          <td>10</td>
          <td>±65504（容易 overflow）</td>
          <td>4 位</td>
      </tr>
      <tr>
          <td>BF16</td>
          <td>16</td>
          <td>1</td>
          <td>8</td>
          <td>7</td>
          <td>±10^38（同 fp32）</td>
          <td>3 位</td>
      </tr>
      <tr>
          <td>FP8 (E4M3 / E5M2)</td>
          <td>8</td>
          <td>1</td>
          <td>4 / 5</td>
          <td>3 / 2</td>
          <td>視變體</td>
          <td>1-2 位</td>
      </tr>
  </tbody>
</table>
<p>關鍵 trade-off：</p>
<ol>
<li><strong>FP16 精度好、範圍窄</strong>：尾數多、表達小範圍內細節準；但指數少、容易 overflow（gradient 爆炸時）/ underflow（gradient 接近 0 時）。</li>
<li><strong>BF16 範圍跟 fp32 一樣大、精度差</strong>：指數位跟 fp32 同（8 位）、訓練時的 dynamic range 跟 fp32 接近、不會 overflow；但尾數少、精度差。實測對訓練影響小、所以是現代 LLM 訓練主流。</li>
<li><strong>FP8 是新興格式</strong>：H100 / B200 等新 GPU 原生支援、訓練 / 推論都能加速、但精度損失需要 careful loss scaling。</li>
</ol>
<p>LLM 工作流的精度選擇：</p>
<table>
  <thead>
      <tr>
          <th>場景</th>
          <th>主流精度</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Pre-training（大模型）</td>
          <td>BF16 + 部分 FP32（如 optimizer state）</td>
      </tr>
      <tr>
          <td>Fine-tuning</td>
          <td>BF16 + 可選 FP8 / Q4（QLoRA）</td>
      </tr>
      <tr>
          <td>推論（雲端 high-end）</td>
          <td>FP16 / BF16</td>
      </tr>
      <tr>
          <td>推論（消費級本機）</td>
          <td>Q4_K_M 等量化、見 <a href="/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">quantization</a></td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 paper / config 看到 <code>mixed_precision: bf16</code>、<code>torch_dtype: bfloat16</code> 就是 BF16 訓練。寫 code 場景的判讀：本機跑 <a href="/blog/llm/knowledge-cards/gguf/" data-link-title="GGUF" data-link-desc="llama.cpp 生態定義的模型權重格式：把權重、tokenizer、metadata 打包成單一檔案">GGUF</a> Q4_K_M 模型、內部運算的 activation 仍是 fp16 / bf16、只有權重儲存是 4-bit；<a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 預設也是 fp16、量化 KV cache 是進階優化（K=Q8 / V=Q4）。</p>
]]></content:encoded></item><item><title>2.3 數值精度與量化的數學依據</title><link>https://tarrragon.github.io/blog/llm/02-math-foundations/numerical-precision/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/02-math-foundations/numerical-precision/</guid><description>&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">量化&lt;/a> 是讓 30B+ LLM 跑在 consumer 等級硬體上的關鍵技術。直覺說法是「用較少 bits 表示權重」、但這背後有完整的數值精度數學依據：浮點數怎麼編碼、不同 format 的取捨在哪、量化在哪一步損失資訊、Q4 vs Q5 的品質差距是怎麼算出來的。&lt;/p>
&lt;p>本章拆開「浮點數的位元結構」、「不同 format 的取捨」、「量化的數學流程」三件事、讓 Q4_K_M、bf16、fp16、int8 等術語從口號變成可推導的工程選擇。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>讀完本章後、你應該能：&lt;/p>
&lt;ol>
&lt;li>解釋 fp32、bf16、fp16 三者的位元結構差異。&lt;/li>
&lt;li>看到「Q4 量化」時、知道是把每個權重壓成 4 bits。&lt;/li>
&lt;li>推算 31B 模型用不同精度的記憶體佔用。&lt;/li>
&lt;li>解釋為什麼 Q3 衰減品質遠大於 Q4 → Q5。&lt;/li>
&lt;/ol>
&lt;h2 id="浮點數的位元結構">&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/floating-point/" data-link-title="Floating Point（FP32 / FP16 / BF16）" data-link-desc="fp32 / fp16 / bf16 浮點格式的位元結構與 LLM 訓練 / 推論的精度取捨">浮點數&lt;/a>的位元結構&lt;/h2>
&lt;p>浮點數（floating point）的核心定義是「用「符號 + 指數 + 尾數」三段位元表示實數」。IEEE 754 標準：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">value = (-1)^sign × 1.mantissa × 2^(exponent - bias)&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>各 format 的位元分配：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Format&lt;/th>
 &lt;th>總 bits&lt;/th>
 &lt;th>Sign&lt;/th>
 &lt;th>Exponent&lt;/th>
 &lt;th>Mantissa&lt;/th>
 &lt;th>表示範圍&lt;/th>
 &lt;th>精度&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>fp32&lt;/td>
 &lt;td>32&lt;/td>
 &lt;td>1&lt;/td>
 &lt;td>8&lt;/td>
 &lt;td>23&lt;/td>
 &lt;td>±10^38&lt;/td>
 &lt;td>約 7 位十進位&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>fp16&lt;/td>
 &lt;td>16&lt;/td>
 &lt;td>1&lt;/td>
 &lt;td>5&lt;/td>
 &lt;td>10&lt;/td>
 &lt;td>±65,504&lt;/td>
 &lt;td>約 3 位十進位&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>bf16&lt;/td>
 &lt;td>16&lt;/td>
 &lt;td>1&lt;/td>
 &lt;td>8&lt;/td>
 &lt;td>7&lt;/td>
 &lt;td>±10^38（跟 fp32 同範圍）&lt;/td>
 &lt;td>約 2 位十進位&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>fp8&lt;/td>
 &lt;td>8&lt;/td>
 &lt;td>1&lt;/td>
 &lt;td>4-5&lt;/td>
 &lt;td>2-3&lt;/td>
 &lt;td>視變體&lt;/td>
 &lt;td>約 1 位十進位&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵觀察：&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>fp32 vs bf16 vs fp16&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>fp32 是基準、訓練最穩、推論最浪費。&lt;/li>
&lt;li>bf16 跟 fp32 同 exponent 範圍、不會 overflow、但 mantissa 較少、精度低。&lt;/li>
&lt;li>fp16 範圍小（±65,504）、訓練容易 overflow、需要 loss scaling。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>訓練主流選 bf16&lt;/strong>：保留 fp32 的範圍、用 fp16 的位元數、避免 overflow / underflow 問題。Apple Silicon、NVIDIA Ampere+ 都原生支援 bf16。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>推論常見更低精度&lt;/strong>：fp16、int8、int4 在推論時夠用；訓練多數情境精度不足、需要更高 format 或特殊技巧（loss scaling、mixed precision）。&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="bf16-為什麼比-fp16-更適合-llm-訓練">bf16 為什麼比 fp16 更適合 LLM 訓練&lt;/h2>
&lt;p>bf16（brain float 16、Google Brain 提出）跟 fp16 都是 16 bits、但結構不同：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>fp16&lt;/strong>：sign 1 + exponent 5 + mantissa 10&lt;/li>
&lt;li>&lt;strong>bf16&lt;/strong>：sign 1 + exponent 8 + mantissa 7&lt;/li>
&lt;/ul>
&lt;p>fp16 的 exponent 只有 5 bits、能表達的最大值 65,504、最小正值約 6e-5。LLM 訓練中的 gradient 經常超出這個範圍：&lt;/p></description><content:encoded><![CDATA[<p><a href="/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">量化</a> 是讓 30B+ LLM 跑在 consumer 等級硬體上的關鍵技術。直覺說法是「用較少 bits 表示權重」、但這背後有完整的數值精度數學依據：浮點數怎麼編碼、不同 format 的取捨在哪、量化在哪一步損失資訊、Q4 vs Q5 的品質差距是怎麼算出來的。</p>
<p>本章拆開「浮點數的位元結構」、「不同 format 的取捨」、「量化的數學流程」三件事、讓 Q4_K_M、bf16、fp16、int8 等術語從口號變成可推導的工程選擇。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本章後、你應該能：</p>
<ol>
<li>解釋 fp32、bf16、fp16 三者的位元結構差異。</li>
<li>看到「Q4 量化」時、知道是把每個權重壓成 4 bits。</li>
<li>推算 31B 模型用不同精度的記憶體佔用。</li>
<li>解釋為什麼 Q3 衰減品質遠大於 Q4 → Q5。</li>
</ol>
<h2 id="浮點數的位元結構"><a href="/blog/llm/knowledge-cards/floating-point/" data-link-title="Floating Point（FP32 / FP16 / BF16）" data-link-desc="fp32 / fp16 / bf16 浮點格式的位元結構與 LLM 訓練 / 推論的精度取捨">浮點數</a>的位元結構</h2>
<p>浮點數（floating point）的核心定義是「用「符號 + 指數 + 尾數」三段位元表示實數」。IEEE 754 標準：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">value = (-1)^sign × 1.mantissa × 2^(exponent - bias)</span></span></code></pre></div><p>各 format 的位元分配：</p>
<table>
  <thead>
      <tr>
          <th>Format</th>
          <th>總 bits</th>
          <th>Sign</th>
          <th>Exponent</th>
          <th>Mantissa</th>
          <th>表示範圍</th>
          <th>精度</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>fp32</td>
          <td>32</td>
          <td>1</td>
          <td>8</td>
          <td>23</td>
          <td>±10^38</td>
          <td>約 7 位十進位</td>
      </tr>
      <tr>
          <td>fp16</td>
          <td>16</td>
          <td>1</td>
          <td>5</td>
          <td>10</td>
          <td>±65,504</td>
          <td>約 3 位十進位</td>
      </tr>
      <tr>
          <td>bf16</td>
          <td>16</td>
          <td>1</td>
          <td>8</td>
          <td>7</td>
          <td>±10^38（跟 fp32 同範圍）</td>
          <td>約 2 位十進位</td>
      </tr>
      <tr>
          <td>fp8</td>
          <td>8</td>
          <td>1</td>
          <td>4-5</td>
          <td>2-3</td>
          <td>視變體</td>
          <td>約 1 位十進位</td>
      </tr>
  </tbody>
</table>
<p>關鍵觀察：</p>
<ol>
<li>
<p><strong>fp32 vs bf16 vs fp16</strong>：</p>
<ul>
<li>fp32 是基準、訓練最穩、推論最浪費。</li>
<li>bf16 跟 fp32 同 exponent 範圍、不會 overflow、但 mantissa 較少、精度低。</li>
<li>fp16 範圍小（±65,504）、訓練容易 overflow、需要 loss scaling。</li>
</ul>
</li>
<li>
<p><strong>訓練主流選 bf16</strong>：保留 fp32 的範圍、用 fp16 的位元數、避免 overflow / underflow 問題。Apple Silicon、NVIDIA Ampere+ 都原生支援 bf16。</p>
</li>
<li>
<p><strong>推論常見更低精度</strong>：fp16、int8、int4 在推論時夠用；訓練多數情境精度不足、需要更高 format 或特殊技巧（loss scaling、mixed precision）。</p>
</li>
</ol>
<h2 id="bf16-為什麼比-fp16-更適合-llm-訓練">bf16 為什麼比 fp16 更適合 LLM 訓練</h2>
<p>bf16（brain float 16、Google Brain 提出）跟 fp16 都是 16 bits、但結構不同：</p>
<ul>
<li><strong>fp16</strong>：sign 1 + exponent 5 + mantissa 10</li>
<li><strong>bf16</strong>：sign 1 + exponent 8 + mantissa 7</li>
</ul>
<p>fp16 的 exponent 只有 5 bits、能表達的最大值 65,504、最小正值約 6e-5。LLM 訓練中的 gradient 經常超出這個範圍：</p>
<ul>
<li>Gradient 太大 → overflow → NaN → 訓練崩潰。</li>
<li>Gradient 太小 → underflow → 變 0 → 那個權重學不到東西。</li>
</ul>
<p>要用 fp16 訓練、得加 loss scaling（把 loss 乘一個大數、讓 gradient 落在 fp16 範圍內、最後再除回去）、流程複雜。</p>
<p>bf16 的 exponent 8 bits、跟 fp32 同範圍、在 LLM gradient 的典型範圍內不會 overflow / underflow（fp32 的全範圍 ±3.4e38 仍可能 overflow、但 LLM 場景遠超這個值的機率極低）。代價是 mantissa 只剩 7 bits、精度更低。對 LLM 訓練來說、範圍比精度重要（gradient 的方向比精確值關鍵）。</p>
<p>硬體前提：bf16 訓練主流是 NVIDIA Ampere（A100、2020+）跟 Apple Silicon、舊 GPU（Pascal、Volta）只有 fp16 硬體加速、用 bf16 會走 software fallback、性能差。</p>
<p>所以 2026 年主流選擇：</p>
<ul>
<li><strong>訓練</strong>：bf16（forward + backward）+ fp32（master copy of weights）</li>
<li><strong>推論</strong>：bf16 或更低（fp16、int8、int4）</li>
</ul>
<h2 id="量化把權重從-bf16-壓到-q4--q8">量化：把權重從 bf16 壓到 Q4 / Q8</h2>
<p>量化（quantization）的核心定義是「把連續的浮點數值 map 到離散的整數值」。最簡單的對稱量化：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">給定一組權重 W ∈ ℝⁿ：
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl">1. 算 scale = max(|W|) / (2^(bits-1) - 1)
</span></span><span class="line"><span class="ln">4</span><span class="cl">   例如 4-bit、scale = max(|W|) / 7
</span></span><span class="line"><span class="ln">5</span><span class="cl">2. 把每個 wᵢ 量化成整數 qᵢ = round(wᵢ / scale)
</span></span><span class="line"><span class="ln">6</span><span class="cl">3. 還原時：w̃ᵢ = qᵢ × scale</span></span></code></pre></div><p>幾何意義：把連續實數軸切成 2^bits 個格子、每個權重 snap 到最近的格子。bits 越少、格子越粗、量化誤差越大。</p>
<p>各量化等級的格子數：</p>
<table>
  <thead>
      <tr>
          <th>Bits</th>
          <th>格子數</th>
          <th>適合場景</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>16</td>
          <td>65,536</td>
          <td>訓練 + 推論</td>
      </tr>
      <tr>
          <td>8</td>
          <td>256</td>
          <td>推論、品質敏感任務</td>
      </tr>
      <tr>
          <td>4</td>
          <td>16</td>
          <td>推論主流、寫 code 甜蜜點</td>
      </tr>
      <tr>
          <td>3</td>
          <td>8</td>
          <td>較大模型強塞較小硬體時備用</td>
      </tr>
      <tr>
          <td>2</td>
          <td>4</td>
          <td>實驗、實用品質崩</td>
      </tr>
  </tbody>
</table>
<h2 id="k-quants更聰明的量化">K-quants：更聰明的量化</h2>
<p><a href="/blog/llm/knowledge-cards/gguf/" data-link-title="GGUF" data-link-desc="llama.cpp 生態定義的模型權重格式：把權重、tokenizer、metadata 打包成單一檔案">GGUF</a> 的 K-quants 比樸素量化更聰明：</p>
<ol>
<li><strong>Block-wise quantization</strong>：權重切成小 block（例如 32 個權重一組）、每個 block 各自的 scale。讓 scale 適應 local 數值範圍、減少全域量化誤差。</li>
<li><strong>Mixed precision</strong>：不同 layer 用不同 bits。LLM 中某些 layer（如 attention output、embedding）對品質影響大、用較高 bits（Q5）；其他用較低 bits（Q4）。整體平均落在「Q4_K_M」這個標籤。</li>
</ol>
<p>「Q4_K_M」拆解：</p>
<ul>
<li><code>Q4</code>：平均約 4 bits / 權重</li>
<li><code>K</code>：K-quants（block-wise、混合精度）</li>
<li><code>M</code>：medium variant、不同 layer 用不同 bits 的具體配方（也有 <code>S</code> small、<code>L</code> large 等變體）</li>
</ul>
<p>實際每個權重的 bits 不剛好是 4、會稍高一點（Q4_K_M 取中值約 4.5 bits / 權重、實際隨模型架構與 attention layer 比例落在 4.4 ~ 4.8 之間、Hugging Face 上具體檔案大小可能跟下方表格估算差 5 ~ 10%）。</p>
<h2 id="模型大小推算">模型大小推算</h2>
<p>知道每個權重幾 bits 後、可以推算模型佔用：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">模型大小（GB）= 參數數 × bits / 8 / 1024^3</span></span></code></pre></div><p>例子：</p>
<table>
  <thead>
      <tr>
          <th>模型</th>
          <th>量化</th>
          <th>計算</th>
          <th>大小</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>7B</td>
          <td>bf16</td>
          <td>7e9 × 16 / 8 / 1024^3</td>
          <td>約 13 GB</td>
      </tr>
      <tr>
          <td>7B</td>
          <td>Q8</td>
          <td>7e9 × 8 / 8 / 1024^3</td>
          <td>約 6.5 GB</td>
      </tr>
      <tr>
          <td>7B</td>
          <td>Q4_K_M</td>
          <td>7e9 × 4.5 / 8 / 1024^3</td>
          <td>約 3.7 GB</td>
      </tr>
      <tr>
          <td>31B</td>
          <td>Q4_K_M</td>
          <td>31e9 × 4.5 / 8 / 1024^3</td>
          <td>約 16 GB</td>
      </tr>
      <tr>
          <td>70B</td>
          <td>Q4_K_M</td>
          <td>70e9 × 4.5 / 8 / 1024^3</td>
          <td>約 37 GB</td>
      </tr>
      <tr>
          <td>70B</td>
          <td>Q3</td>
          <td>70e9 × 3 / 8 / 1024^3</td>
          <td>約 25 GB</td>
      </tr>
  </tbody>
</table>
<p>加上 metadata、tokenizer、<a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 等 overhead、實際記憶體佔用會比表上多 10 ~ 30%。</p>
<h2 id="量化在哪一步損失資訊">量化在哪一步損失資訊</h2>
<p>量化的品質損失來自三個位置：</p>
<ol>
<li><strong>Rounding error</strong>：把連續實數 snap 到離散格子、每個權重產生一個小誤差。Block size 越大、scale 越粗、誤差越大。</li>
<li><strong>Clipping</strong>：若 max(|W|) 估錯（例如忽略 outlier）、超出範圍的權重被 clip 到範圍內、損失大值資訊。K-quants 用 block-wise 解決 outlier 影響。</li>
<li><strong>Layer-wise 累積</strong>：每個 layer 的量化誤差會經過後續 layer 放大或累積；某些 layer（如 attention 的 output projection）對誤差特別敏感。Mixed precision 對這些 layer 保留較高 bits。</li>
</ol>
<p>實務上：</p>
<ul>
<li>Q4_K_M 在 31B 模型上品質衰減約 1 ~ 2%（用 perplexity 衡量）、實用上幾乎察覺不到。</li>
<li>Q3 在 31B 模型上衰減約 5 ~ 10%、coding 任務開始失誤。</li>
<li>Q2 衰減 20%+、實用情境受限、多半用於極端硬體預算的實驗。</li>
</ul>
<h2 id="為什麼-31b-q4-常勝-70b-q3">為什麼 31B Q4 常勝 70B Q3</h2>
<p>模型大小與量化等級的乘積決定實際品質。31B Q4 跟 70B Q3 的記憶體佔用接近（16GB vs 25GB）、但實際表現常常 31B Q4 勝：</p>
<ul>
<li>70B Q3 的量化誤差累積在每一層、深網路放大誤差。</li>
<li>31B Q4 誤差較小、雖然參數量較少但能力穩定。</li>
</ul>
<p>這就是 <a href="/blog/llm/01-local-llm-services/model-selection-priority/" data-link-title="1.4 寫 code 場景的模型選型優先順序" data-link-desc="Gemma 4 31B MTP → Qwen3-Coder 30B → Qwen3 14B → gpt-oss 20B 的取捨與適用情境">模型選型</a> 的核心啟示：「夠大」跟「夠好」是兩件事、優先選穩定量化等級、把激進量化留給有預算驗證的場景。</p>
<h2 id="推論時的數值精度">推論時的數值精度</h2>
<p>寫 code 場景的推論大致流程：</p>
<ol>
<li><strong>權重儲存</strong>：Q4_K_M 格式（4.5 bits / 權重）。</li>
<li><strong>推論時 dequantize</strong>：每次用到權重時、暫時 unpack 回 fp16 / bf16 跟 input 做矩陣乘法。</li>
<li><strong>Activation 維持 fp16 / bf16</strong>：樸素 Q4_K_M 的預設行為是不量化 activation、避免進一步損失精度。進階場景（<a href="/blog/llm/05-discrete-gpu/kv-cache-quantization-strategy/" data-link-title="5.2 KV cache 量化策略" data-link-desc="PC 場景用 K=Q8 / V=Q4 等量化把 KV cache 壓縮、騰出 VRAM 開大 context window 或加併發數的判讀">KV cache 量化</a> K=Q8 / V=Q4、AWQ、GPTQ 等 activation-aware 量化）會例外處理、需依框架文件配置。</li>
</ol>
<p>所以「Q4 模型」內部運算精度其實是 fp16 / bf16、只有「儲存」是 4 bits。這是為什麼量化主要省記憶體與頻寬、不省算力（算力差距小）。</p>
<h2 id="下一章">下一章</h2>
<p>想看完整數值分析（IEEE 754 細節、條件數、誤差傳播等）、見 <a href="/blog/llm/02-math-foundations/going-deeper-math/" data-link-title="2.4 想學更深：推薦公開課程" data-link-desc="MIT、Stanford、Harvard 等公開課程：數學基礎跟 LLM 預備知識的完整學習路線">2.4 公開課推薦</a> 的相關資源。</p>
<p>下一章：<a href="/blog/llm/02-math-foundations/going-deeper-math/" data-link-title="2.4 想學更深：推薦公開課程" data-link-desc="MIT、Stanford、Harvard 等公開課程：數學基礎跟 LLM 預備知識的完整學習路線">2.4 想學更深：推薦公開課程</a>。</p>
]]></content:encoded></item></channel></rss>