<?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>Attention on Tarragon</title><link>https://tarrragon.github.io/blog/tags/attention/</link><description>Recent content in Attention on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Thu, 14 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/attention/index.xml" rel="self" type="application/rss+xml"/><item><title>Grouped-Query Attention</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/grouped-query-attention/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/grouped-query-attention/</guid><description>&lt;p>Grouped-query attention（GQA）的核心概念是「&lt;strong>多個 query head 共用較少的 key/value head&lt;/strong>」。它介於 Multi-Head Attention 與 Multi-Query Attention 之間，用較小的品質代價換取更小的 &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> 與更好的長 context serving 效率。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>GQA 是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/multi-head-attention/" data-link-title="Multi-Head Attention" data-link-desc="把 attention 切成多個 head 並行計算、讓模型能同時注意多種模式">multi-head attention&lt;/a> 的推論友善變體。MHA 是每個 query head 都有自己的 K/V；MQA 是所有 query head 共用一組 K/V；GQA 則把 query head 分組，每組共用 K/V。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>在 model config 裡看到 &lt;code>num_attention_heads: 32&lt;/code>、&lt;code>num_key_value_heads: 8&lt;/code>，代表 32 個 Q head 共用 8 組 K/V head，group size 是 4。這會讓 KV cache 約縮到 MHA 的四分之一，長 context 與高併發更友善。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>選模型或估算 serving 成本時，要看 &lt;code>num_key_value_heads&lt;/code>，而不是只看總參數。GQA 對本地推論特別重要，因為 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window&lt;/a> 與併發數常被 KV cache 卡住。&lt;/p></description><content:encoded><![CDATA[<p>Grouped-query attention（GQA）的核心概念是「<strong>多個 query head 共用較少的 key/value head</strong>」。它介於 Multi-Head Attention 與 Multi-Query Attention 之間，用較小的品質代價換取更小的 <a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 與更好的長 context serving 效率。</p>
<h2 id="概念位置">概念位置</h2>
<p>GQA 是 <a href="/blog/llm/knowledge-cards/multi-head-attention/" data-link-title="Multi-Head Attention" data-link-desc="把 attention 切成多個 head 並行計算、讓模型能同時注意多種模式">multi-head attention</a> 的推論友善變體。MHA 是每個 query head 都有自己的 K/V；MQA 是所有 query head 共用一組 K/V；GQA 則把 query head 分組，每組共用 K/V。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>在 model config 裡看到 <code>num_attention_heads: 32</code>、<code>num_key_value_heads: 8</code>，代表 32 個 Q head 共用 8 組 K/V head，group size 是 4。這會讓 KV cache 約縮到 MHA 的四分之一，長 context 與高併發更友善。</p>
<h2 id="設計責任">設計責任</h2>
<p>選模型或估算 serving 成本時，要看 <code>num_key_value_heads</code>，而不是只看總參數。GQA 對本地推論特別重要，因為 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a> 與併發數常被 KV cache 卡住。</p>
]]></content:encoded></item><item><title>Positional Encoding</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/positional-encoding/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/positional-encoding/</guid><description>&lt;p>Positional encoding（位置編碼）的核心概念是「&lt;strong>把序列中的位置資訊提供給 Transformer&lt;/strong>」。純 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/attention/" data-link-title="Attention" data-link-desc="Transformer 內部讓每個 token 對其他 token 加權平均的核心機制、形成 KV cache 跟 context window 的計算基礎">attention&lt;/a> 對 token 集合本身近似不帶順序感，位置編碼讓模型能分辨 &lt;code>cat bites dog&lt;/code> 與 &lt;code>dog bites cat&lt;/code>。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>位置資訊通常在 embedding 進入 Transformer block 前或 attention 計算中注入。常見路線包含 sinusoidal positional encoding、learned positional embedding、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rope/" data-link-title="RoPE（Rotary Position Embedding）" data-link-desc="用旋轉矩陣把位置資訊直接旋轉進 Q/K 向量、現代 LLM 主流的位置編碼方式">RoPE&lt;/a> 與 ALiBi；現代 decoder-only LLM 多使用 RoPE 或其長 context scaling 變體。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>讀 model architecture 看到 &lt;code>max_position_embeddings&lt;/code>、RoPE base、RoPE scaling、ALiBi、YaRN、NTK-aware scaling，就是位置編碼相關設定。長 context 擴展常卡在位置編碼外推能力，而不是只把 context window 數字調大。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>評估長 context 模型時，要分清楚「宣稱 context 長度」與「位置編碼在該長度仍可靠」。超過訓練長度太多時，即使能載入，模型對遠距關係也可能退化。完整章節見 &lt;a href="https://tarrragon.github.io/blog/llm/03-theoretical-foundations/transformer-architecture/" data-link-title="3.3 Transformer 架構細節" data-link-desc="Decoder-only 結構、Transformer block、positional encoding、layer norm、residual stream">Transformer architecture&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Positional encoding（位置編碼）的核心概念是「<strong>把序列中的位置資訊提供給 Transformer</strong>」。純 <a href="/blog/llm/knowledge-cards/attention/" data-link-title="Attention" data-link-desc="Transformer 內部讓每個 token 對其他 token 加權平均的核心機制、形成 KV cache 跟 context window 的計算基礎">attention</a> 對 token 集合本身近似不帶順序感，位置編碼讓模型能分辨 <code>cat bites dog</code> 與 <code>dog bites cat</code>。</p>
<h2 id="概念位置">概念位置</h2>
<p>位置資訊通常在 embedding 進入 Transformer block 前或 attention 計算中注入。常見路線包含 sinusoidal positional encoding、learned positional embedding、<a href="/blog/llm/knowledge-cards/rope/" data-link-title="RoPE（Rotary Position Embedding）" data-link-desc="用旋轉矩陣把位置資訊直接旋轉進 Q/K 向量、現代 LLM 主流的位置編碼方式">RoPE</a> 與 ALiBi；現代 decoder-only LLM 多使用 RoPE 或其長 context scaling 變體。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>讀 model architecture 看到 <code>max_position_embeddings</code>、RoPE base、RoPE scaling、ALiBi、YaRN、NTK-aware scaling，就是位置編碼相關設定。長 context 擴展常卡在位置編碼外推能力，而不是只把 context window 數字調大。</p>
<h2 id="設計責任">設計責任</h2>
<p>評估長 context 模型時，要分清楚「宣稱 context 長度」與「位置編碼在該長度仍可靠」。超過訓練長度太多時，即使能載入，模型對遠距關係也可能退化。完整章節見 <a href="/blog/llm/03-theoretical-foundations/transformer-architecture/" data-link-title="3.3 Transformer 架構細節" data-link-desc="Decoder-only 結構、Transformer block、positional encoding、layer norm、residual stream">Transformer architecture</a>。</p>
]]></content:encoded></item><item><title>Flash Attention</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/flash-attention/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/flash-attention/</guid><description>&lt;p>Flash Attention 的核心概念是「重新組織 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/attention/" data-link-title="Attention" data-link-desc="Transformer 內部讓每個 token 對其他 token 加權平均的核心機制、形成 KV cache 跟 context window 的計算基礎">Attention&lt;/a> 計算的順序、把中間結果留在 GPU 高速 cache、減少對 GPU memory 的讀寫往返」。它不改變 attention 的數學定義（輸出跟原始實作在浮點誤差範圍內一致）、但實作層面對長 context 推論吞吐有明顯提升、且是部分 &lt;a href="https://tarrragon.github.io/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 量化&lt;/a> 組合在 llama.cpp 上的必要前置。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Flash Attention 在推論架構中的角色：&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">推論時的 attention 計算：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ├── 原始實作：Q · K^T 整個算完、寫進 memory、再讀出來做 softmax、再算 · V
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> │ └── 多次 memory 讀寫、長 context 下 IO 成為瓶頸
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> └── Flash Attention：用 tiling 把計算切塊、中間結果留在 SRAM / register
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> └── 減少 memory 讀寫、長 context 加速明顯&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>跟 attention 變體的關係：&lt;/p>
&lt;ul>
&lt;li>Flash Attention 是&lt;strong>實作層&lt;/strong>的優化、跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/attention/" data-link-title="Attention" data-link-desc="Transformer 內部讓每個 token 對其他 token 加權平均的核心機制、形成 KV cache 跟 context window 的計算基礎">MHA / GQA / MLA&lt;/a> 等&lt;strong>架構層&lt;/strong>變體是兩個獨立維度。&lt;/li>
&lt;li>不同變體都能搭配 Flash Attention 的實作技巧。&lt;/li>
&lt;/ul>
&lt;p>在 llama.cpp 中的旗標：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">llama-server -fa &lt;span class="c1"># 啟用 flash attention&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="c1"># 或&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">llama-server --flash-attn&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：Flash Attention 的版本演進快（Flash Attention 1 / 2 / 3）、不同推論引擎的支援度依版本變化。具體限制（如「V cache Q4 量化要 -fa 才能啟用」）依 llama.cpp 版本變動、引用前以 &lt;code>llama-server --help&lt;/code> 跟 release notes 為準。&lt;/p>&lt;/blockquote>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 Flash Attention 後可以解釋兩個現象：為什麼啟用 &lt;code>-fa&lt;/code> 後長 context 推論速度提升明顯（IO bound 變 compute bound）、為什麼部分 KV cache 量化組合（如 V=Q4_0）在 llama.cpp 上需要 flash attention 才能跑（實作層面的耦合）。&lt;/p>
&lt;p>工程實務上、啟用 flash attention 通常沒副作用（數學上等價、品質不變）、是 PC 場景長 context 推論的預設啟用旗標。詳見 &lt;a href="https://tarrragon.github.io/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 或加併發數的判讀">5.2 KV cache 量化策略&lt;/a> 的 flash attention 段落。&lt;/p></description><content:encoded><![CDATA[<p>Flash Attention 的核心概念是「重新組織 <a href="/blog/llm/knowledge-cards/attention/" data-link-title="Attention" data-link-desc="Transformer 內部讓每個 token 對其他 token 加權平均的核心機制、形成 KV cache 跟 context window 的計算基礎">Attention</a> 計算的順序、把中間結果留在 GPU 高速 cache、減少對 GPU memory 的讀寫往返」。它不改變 attention 的數學定義（輸出跟原始實作在浮點誤差範圍內一致）、但實作層面對長 context 推論吞吐有明顯提升、且是部分 <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> 組合在 llama.cpp 上的必要前置。</p>
<h2 id="概念位置">概念位置</h2>
<p>Flash Attention 在推論架構中的角色：</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">推論時的 attention 計算：
</span></span><span class="line"><span class="ln">2</span><span class="cl">  ├── 原始實作：Q · K^T 整個算完、寫進 memory、再讀出來做 softmax、再算 · V
</span></span><span class="line"><span class="ln">3</span><span class="cl">  │     └── 多次 memory 讀寫、長 context 下 IO 成為瓶頸
</span></span><span class="line"><span class="ln">4</span><span class="cl">  └── Flash Attention：用 tiling 把計算切塊、中間結果留在 SRAM / register
</span></span><span class="line"><span class="ln">5</span><span class="cl">        └── 減少 memory 讀寫、長 context 加速明顯</span></span></code></pre></div><p>跟 attention 變體的關係：</p>
<ul>
<li>Flash Attention 是<strong>實作層</strong>的優化、跟 <a href="/blog/llm/knowledge-cards/attention/" data-link-title="Attention" data-link-desc="Transformer 內部讓每個 token 對其他 token 加權平均的核心機制、形成 KV cache 跟 context window 的計算基礎">MHA / GQA / MLA</a> 等<strong>架構層</strong>變體是兩個獨立維度。</li>
<li>不同變體都能搭配 Flash Attention 的實作技巧。</li>
</ul>
<p>在 llama.cpp 中的旗標：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">llama-server -fa  <span class="c1"># 啟用 flash attention</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1"># 或</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">llama-server --flash-attn</span></span></code></pre></div><blockquote>
<p><strong>事實查核註</strong>：Flash Attention 的版本演進快（Flash Attention 1 / 2 / 3）、不同推論引擎的支援度依版本變化。具體限制（如「V cache Q4 量化要 -fa 才能啟用」）依 llama.cpp 版本變動、引用前以 <code>llama-server --help</code> 跟 release notes 為準。</p></blockquote>
<h2 id="設計責任">設計責任</h2>
<p>理解 Flash Attention 後可以解釋兩個現象：為什麼啟用 <code>-fa</code> 後長 context 推論速度提升明顯（IO bound 變 compute bound）、為什麼部分 KV cache 量化組合（如 V=Q4_0）在 llama.cpp 上需要 flash attention 才能跑（實作層面的耦合）。</p>
<p>工程實務上、啟用 flash attention 通常沒副作用（數學上等價、品質不變）、是 PC 場景長 context 推論的預設啟用旗標。詳見 <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 或加併發數的判讀">5.2 KV cache 量化策略</a> 的 flash attention 段落。</p>
]]></content:encoded></item><item><title>3.2 Attention 機制</title><link>https://tarrragon.github.io/blog/llm/03-theoretical-foundations/attention-mechanism/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/03-theoretical-foundations/attention-mechanism/</guid><description>&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/attention/" data-link-title="Attention" data-link-desc="Transformer 內部讓每個 token 對其他 token 加權平均的核心機制、形成 KV cache 跟 context window 的計算基礎">Attention&lt;/a>（注意力）是 Transformer 的核心創新、也是 LLM 能處理長 context 的關鍵。它的核心想法是「每個 token 決定該關注前面哪幾個 token」、用 &lt;a href="https://tarrragon.github.io/blog/llm/03-theoretical-foundations/embedding-spaces/" data-link-title="3.1 Embedding 空間" data-link-desc="token 怎麼變成向量、為什麼相似 token 在向量空間中靠近、embedding 是怎麼學出來的">embedding&lt;/a> 之間的&lt;a href="https://tarrragon.github.io/blog/llm/02-math-foundations/linear-algebra-for-llm/" data-link-title="2.0 線性代數：向量、矩陣、空間" data-link-desc="LLM 內部運算的基底：向量、矩陣、向量空間、內積、norm、矩陣乘法的角色">內積&lt;/a> 量化「相關性」。理解 attention 後、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/multi-head-attention/" data-link-title="Multi-Head Attention" data-link-desc="把 attention 切成多個 head 並行計算、讓模型能同時注意多種模式">Multi-head&lt;/a>、KV cache、Flash Attention、attention sink 等術語都能放到正確位置。&lt;/p>
&lt;p>本章從「為什麼需要 attention」開始、拆 scaled dot-product attention 公式、再展開 multi-head attention 跟 causal masking、最後接到 KV cache 與長 context 場景。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>讀完本章後、你應該能：&lt;/p>
&lt;ol>
&lt;li>用 Q / K / V 三個角色解釋 attention 在算什麼。&lt;/li>
&lt;li>看到 attention 公式時、能解讀每個運算的角色。&lt;/li>
&lt;li>解釋 multi-head attention 跟 single-head 的取捨。&lt;/li>
&lt;li>把 &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> 跟 attention 公式對上。&lt;/li>
&lt;/ol>
&lt;h2 id="為什麼需要-attention">為什麼需要 attention&lt;/h2>
&lt;p>LLM 處理「下一個 token 該是什麼」、需要綜合 prompt 中前面所有 token 的資訊。早期解法（RNN、LSTM）用「序列狀態」串接、每個 token 只看到上一步的 hidden state。缺點：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>長距離依賴難&lt;/strong>：訊息傳遞要跑過所有中間 token、容易遺失。&lt;/li>
&lt;li>&lt;strong>無法並行&lt;/strong>：每步依賴上一步、訓練速度有瓶頸。&lt;/li>
&lt;/ol>
&lt;p>Attention 的核心突破是「每個 token 直接看所有前面的 token、無需透過中間 hidden state 傳遞」。每個 token 用 attention scores 決定「該關注哪些前面 token」、用這些 token 的向量加權求和、形成自己的 context-aware 表示。&lt;/p>
&lt;p>Attention 帶來三個性質：兩個是優勢、一個是代價：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>優勢一、長距離依賴變直接&lt;/strong>：attention 直接連到任何位置、不再需要透過 RNN 的中間 hidden state 接力。&lt;/li>
&lt;li>&lt;strong>優勢二、可以並行&lt;/strong>：不同 token 的 attention 計算彼此獨立、訓練時整段序列一次跑完。&lt;/li>
&lt;li>&lt;strong>代價、O(n²) 計算複雜度&lt;/strong>：seq_len = n 時要算 n × n 個 attention scores、長 context 場景成本暴增、見後面的 KV cache 與 Flash Attention 段。&lt;/li>
&lt;/ul>
&lt;h2 id="q--k--v-三個角色">Q / K / V 三個角色&lt;/h2>
&lt;p>Attention 給每個 token 三個向量、各自有不同角色：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>角色&lt;/th>
 &lt;th>直覺&lt;/th>
 &lt;th>數學&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Query (Q)&lt;/td>
 &lt;td>「我在找什麼」&lt;/td>
 &lt;td>Q = X @ W_Q&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Key (K)&lt;/td>
 &lt;td>「我有什麼可以被找到」&lt;/td>
 &lt;td>K = X @ W_K&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Value (V)&lt;/td>
 &lt;td>「找到我之後、要傳出去什麼」&lt;/td>
 &lt;td>V = X @ W_V&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>其中 X 是 input embedding、&lt;code>W_Q&lt;/code>、&lt;code>W_K&lt;/code>、&lt;code>W_V&lt;/code> 是三個 learnable 權重矩陣。&lt;/p></description><content:encoded><![CDATA[<p><a href="/blog/llm/knowledge-cards/attention/" data-link-title="Attention" data-link-desc="Transformer 內部讓每個 token 對其他 token 加權平均的核心機制、形成 KV cache 跟 context window 的計算基礎">Attention</a>（注意力）是 Transformer 的核心創新、也是 LLM 能處理長 context 的關鍵。它的核心想法是「每個 token 決定該關注前面哪幾個 token」、用 <a href="/blog/llm/03-theoretical-foundations/embedding-spaces/" data-link-title="3.1 Embedding 空間" data-link-desc="token 怎麼變成向量、為什麼相似 token 在向量空間中靠近、embedding 是怎麼學出來的">embedding</a> 之間的<a href="/blog/llm/02-math-foundations/linear-algebra-for-llm/" data-link-title="2.0 線性代數：向量、矩陣、空間" data-link-desc="LLM 內部運算的基底：向量、矩陣、向量空間、內積、norm、矩陣乘法的角色">內積</a> 量化「相關性」。理解 attention 後、<a href="/blog/llm/knowledge-cards/multi-head-attention/" data-link-title="Multi-Head Attention" data-link-desc="把 attention 切成多個 head 並行計算、讓模型能同時注意多種模式">Multi-head</a>、KV cache、Flash Attention、attention sink 等術語都能放到正確位置。</p>
<p>本章從「為什麼需要 attention」開始、拆 scaled dot-product attention 公式、再展開 multi-head attention 跟 causal masking、最後接到 KV cache 與長 context 場景。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本章後、你應該能：</p>
<ol>
<li>用 Q / K / V 三個角色解釋 attention 在算什麼。</li>
<li>看到 attention 公式時、能解讀每個運算的角色。</li>
<li>解釋 multi-head attention 跟 single-head 的取捨。</li>
<li>把 <a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 跟 attention 公式對上。</li>
</ol>
<h2 id="為什麼需要-attention">為什麼需要 attention</h2>
<p>LLM 處理「下一個 token 該是什麼」、需要綜合 prompt 中前面所有 token 的資訊。早期解法（RNN、LSTM）用「序列狀態」串接、每個 token 只看到上一步的 hidden state。缺點：</p>
<ol>
<li><strong>長距離依賴難</strong>：訊息傳遞要跑過所有中間 token、容易遺失。</li>
<li><strong>無法並行</strong>：每步依賴上一步、訓練速度有瓶頸。</li>
</ol>
<p>Attention 的核心突破是「每個 token 直接看所有前面的 token、無需透過中間 hidden state 傳遞」。每個 token 用 attention scores 決定「該關注哪些前面 token」、用這些 token 的向量加權求和、形成自己的 context-aware 表示。</p>
<p>Attention 帶來三個性質：兩個是優勢、一個是代價：</p>
<ul>
<li><strong>優勢一、長距離依賴變直接</strong>：attention 直接連到任何位置、不再需要透過 RNN 的中間 hidden state 接力。</li>
<li><strong>優勢二、可以並行</strong>：不同 token 的 attention 計算彼此獨立、訓練時整段序列一次跑完。</li>
<li><strong>代價、O(n²) 計算複雜度</strong>：seq_len = n 時要算 n × n 個 attention scores、長 context 場景成本暴增、見後面的 KV cache 與 Flash Attention 段。</li>
</ul>
<h2 id="q--k--v-三個角色">Q / K / V 三個角色</h2>
<p>Attention 給每個 token 三個向量、各自有不同角色：</p>
<table>
  <thead>
      <tr>
          <th>角色</th>
          <th>直覺</th>
          <th>數學</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Query (Q)</td>
          <td>「我在找什麼」</td>
          <td>Q = X @ W_Q</td>
      </tr>
      <tr>
          <td>Key (K)</td>
          <td>「我有什麼可以被找到」</td>
          <td>K = X @ W_K</td>
      </tr>
      <tr>
          <td>Value (V)</td>
          <td>「找到我之後、要傳出去什麼」</td>
          <td>V = X @ W_V</td>
      </tr>
  </tbody>
</table>
<p>其中 X 是 input embedding、<code>W_Q</code>、<code>W_K</code>、<code>W_V</code> 是三個 learnable 權重矩陣。</p>
<p>直覺：</p>
<ul>
<li>每個 token 同時當「找東西的人」（query）跟「被找的東西」（key + value）。</li>
<li>Query 跟其他 token 的 Key 內積、得到「該關注每個 token 多少」的分數。</li>
<li>用這些分數對所有 token 的 Value 加權求和、得到當前 token 的 context-aware 表示。</li>
</ul>
<h2 id="scaled-dot-product-attention核心公式">Scaled Dot-Product Attention：核心公式</h2>
<p>Attention（Vaswani et al., 2017）的核心公式：</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">Attention(Q, K, V) = softmax(Q @ K^T / sqrt(d_k)) @ V</span></span></code></pre></div><p>逐步拆解：</p>
<ol>
<li><strong><code>Q @ K^T</code></strong>：所有 query 跟所有 key 兩兩內積、得到 <code>(seq_len, seq_len)</code> 矩陣。矩陣 [i][j] 等於「token i 該關注 token j 多少」的原始分數。</li>
<li><strong><code>/ sqrt(d_k)</code></strong>：scale by sqrt of key dimension。若沒有這步、d_k 大時 softmax 會極端化、訓練不穩。</li>
<li><strong><code>softmax(...)</code></strong>：對每一 row 做 <a href="/blog/llm/02-math-foundations/probability-and-information/" data-link-title="2.1 機率與資訊論" data-link-desc="LLM 輸出的本質是機率分佈：softmax、cross-entropy、KL divergence、perplexity 在訓練與推論中的角色">softmax</a>、把分數正規化成機率分佈、保證「每個 token 對所有前面 token 的注意力總和 = 1」。</li>
<li><strong><code>@ V</code></strong>：用 attention 機率對所有 token 的 V 加權求和、得到 <code>(seq_len, d_v)</code> 的輸出。每個輸出 row 是該 token 整合了前面所有 token 資訊的 context-aware 表示。</li>
</ol>
<p>這個公式叫 <strong>scaled dot-product attention</strong>、是 Transformer 的核心運算。</p>
<h2 id="multi-head-attention多個-attention-並行"><a href="/blog/llm/knowledge-cards/multi-head-attention/" data-link-title="Multi-Head Attention" data-link-desc="把 attention 切成多個 head 並行計算、讓模型能同時注意多種模式">Multi-Head Attention</a>：多個 attention 並行</h2>
<p>Multi-head attention 的核心想法是「跑 N 個獨立的 attention、每個 head 各自有自己的 W_Q / W_K / W_V、結果 concatenate 再過一個線性層」：</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">head_i = Attention(Q W_Q_i, K W_K_i, V W_V_i)
</span></span><span class="line"><span class="ln">2</span><span class="cl">MultiHead(Q, K, V) = Concat(head_1, ..., head_h) @ W_O</span></span></code></pre></div><p>幾何意義：每個 head 學「關注一種 pattern」。例如：</p>
<ul>
<li>Head 1 可能學到「關注名詞的修飾語」。</li>
<li>Head 2 可能學到「關注前後標點」。</li>
<li>Head 3 可能學到「關注 quotation 邊界」。</li>
</ul>
<p>實驗發現不同 head 確實學到可解釋的功能（雖然多數 head 的功能難以直觀標籤）。在主流規模（hidden_dim ≥ 768、num_heads ≥ 8）下、multi-head 比 single-head 表達能力強；極小模型（hidden_dim &lt; 256）下 multi-head 收益遞減、有時 single-head 更穩定。</p>
<p>主流 LLM 的 head 數：</p>
<table>
  <thead>
      <tr>
          <th>模型</th>
          <th>num_heads</th>
          <th>head_dim</th>
          <th>hidden_dim</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>GPT-2 small</td>
          <td>12</td>
          <td>64</td>
          <td>768</td>
      </tr>
      <tr>
          <td>Llama 3 8B</td>
          <td>32</td>
          <td>128</td>
          <td>4096</td>
      </tr>
      <tr>
          <td>Llama 3 70B</td>
          <td>64</td>
          <td>128</td>
          <td>8192</td>
      </tr>
      <tr>
          <td>Gemma 4 31B</td>
          <td>約 40</td>
          <td>約 128</td>
          <td>約 5120</td>
      </tr>
  </tbody>
</table>
<p>關係：<code>hidden_dim = num_heads × head_dim</code>。每個 head 處理 head_dim 維、parallel 跑完再 concatenate 回 hidden_dim。</p>
<h2 id="causal-mask只看前面不看後面">Causal Mask：只看前面、不看後面</h2>
<p>LLM 是 <a href="/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">autoregressive</a>、生成 token N 時只能看 token 0 到 N-1、不能看後面（後面還沒生）。Attention 機制要「擋掉未來位置」、用 <strong><a href="/blog/llm/knowledge-cards/causal-mask/" data-link-title="Causal Mask" data-link-desc="在 self-attention 裡擋掉「未來位置」的遮罩、讓 LLM 自回歸生成在訓練時也成立">causal mask</a></strong> 實現：</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">masked_scores[i][j] = scores[i][j]   if j ≤ i
</span></span><span class="line"><span class="ln">2</span><span class="cl">                    = -∞              if j &gt; i</span></span></code></pre></div><p>把未來位置的 attention score 設為 -∞、softmax 後機率為 0、等於完全忽略未來。</p>
<p>實作上 mask 是一個下三角矩陣、訓練跟推論時都套用、但角色不同：</p>
<ul>
<li><strong>訓練時的 causal mask</strong>：讓 decoder 能「一次 forward pass 算所有 N 個 token 的 loss」、parallel 訓練。沒有 mask 就要對每個位置跑 N 次 forward（位置 i 只給 token 0 ~ i-1）、訓練速度掉一個量級。這是 Transformer 取代 RNN 在訓練效率上的關鍵。</li>
<li><strong>推論時的 causal mask</strong>：每生新 token 只看前面已生的 token、不能 peek 未來。實際因為 token 是按順序生成的、未來位置本來就還沒存在、mask 更像是「沿用訓練階段的同套運算結構、避免訓練 / 推論 mismatch」。</li>
</ul>
<p>「Decoder-only LLM」（GPT、Llama 系列）用 causal mask 做自回歸生成；「Encoder-only LLM」（BERT 等）不用 causal mask、可看雙向 context、適合分類 / NER 等理解任務、不走自回歸生成路徑；「Encoder-Decoder」（T5、BART）encoder 看雙向、decoder 用 causal mask、可生成、是另一條典型架構。</p>
<h2 id="kv-cache避免重複計算">KV Cache：避免重複計算</h2>
<p><a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV Cache</a> 是 attention 機制下的關鍵優化。回到 attention 公式：</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">Attention(Q, K, V) = softmax(Q @ K^T / sqrt(d_k)) @ V</span></span></code></pre></div><p>生成 token N 時：</p>
<ul>
<li>Q 是 token N 對應的 query（新的）。</li>
<li>K、V 是 token 0 到 N-1 的 key / value（前面都算過）。</li>
</ul>
<p>如果每生一個 token 都重新算 K、V、會浪費大量計算。KV cache 把 K、V 存起來、下次生 token N+1 時：</p>
<ul>
<li>Q 是 token N+1 的新 query。</li>
<li>K、V 是 cache + 新 token 的 K、V。</li>
</ul>
<p>只算 token N+1 對應的 K、V 新值、跟既有 cache concat。每生一個 token 的計算量從 O(n²) 降到 O(n)。</p>
<p>代價是 KV cache 隨 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a> 線性增長、長 context 場景吃記憶體。Gemma 4 31B 在 32GB Mac 上實用 context 約 8 ~ 16K tokens、超過會 swap。記憶體吃緊時的 KV cache 量化（K=Q8 / V=Q4）原理與 context / 併發取捨見 <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 或加併發數的判讀">模組五 5.2 KV cache 量化策略</a>、整體 VRAM 預算見 <a href="/blog/llm/05-discrete-gpu/vram-ram-budget/" data-link-title="5.0 VRAM &#43; RAM 分層預算" data-link-desc="PC 獨立 GPU 場景的記憶體預算判讀：VRAM 是快的世界、RAM 是大的世界、PCIe 把兩個世界連起來">5.0 VRAM + RAM 分層預算</a>。</p>
<h2 id="flash-attention記憶體高效實作">Flash Attention：記憶體高效實作</h2>
<p>Flash Attention（Dao et al., 2022）是 attention 的 GPU 高效實作。標準 attention 在記憶體中具體實作 <code>(seq_len, seq_len)</code> 矩陣、長 context 時記憶體爆炸（10K context = 100M 個 float）。</p>
<p>Flash Attention 用「tiling + recompute」技巧、把 attention 拆成 block 算、不具體實作完整 attention matrix。記憶體佔用從 O(n²) 降到 O(n)、速度也快 2 ~ 4 倍。</p>
<p>Apple Silicon 上的對應實作可能稱為 Metal FlashAttention 或類似名稱、Ollama、LM Studio、oMLX 等本地推論伺服器逐步整合。</p>
<p>Flash Attention 何時收益有限：</p>
<ul>
<li><strong>短 context 場景</strong>：seq_len &lt; 1K 時、attention matrix 本身就小、Flash Attention 的記憶體節省無感。</li>
<li><strong>CPU 推論</strong>：Flash Attention 的 tiling 設計針對 GPU memory hierarchy（HBM ↔ SRAM）、CPU 上的記憶體層級不同、收益遠小於 GPU。</li>
<li><strong>配合 GQA 的場景</strong>：GQA 已大幅減少 KV cache、Flash Attention 的相對收益縮小。</li>
</ul>
<h2 id="grouped-query-attentiongqa"><a href="/blog/llm/knowledge-cards/grouped-query-attention/" data-link-title="Grouped-Query Attention" data-link-desc="讓多個 query head 共用較少的 key/value head，以降低 KV cache 體積與推論記憶體壓力">Grouped Query Attention（GQA）</a></h2>
<p>Grouped Query Attention 是 multi-head attention 的變體、減少 KV cache 佔用。核心想法：「不同 head 共用 K、V、只有 Q 各自獨立」。</p>
<table>
  <thead>
      <tr>
          <th>變體</th>
          <th>Q heads</th>
          <th>K/V heads</th>
          <th>特性</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Multi-Head Attention (MHA)</td>
          <td>N</td>
          <td>N</td>
          <td>標準、各 head 完全獨立</td>
      </tr>
      <tr>
          <td>Multi-Query Attention (MQA)</td>
          <td>N</td>
          <td>1</td>
          <td>所有 head 共用一組 K/V、最省記憶體</td>
      </tr>
      <tr>
          <td>Grouped Query Attention (GQA)</td>
          <td>N</td>
          <td>K (K &lt; N)</td>
          <td>折衷、品質接近 MHA、KV cache 較小</td>
      </tr>
  </tbody>
</table>
<p>Llama 3 / Gemma 4 / Qwen3 都用 GQA、把 KV cache 大小減半到三分之一、長 context 場景受益。</p>
<h2 id="為什麼-speculative-decoding-在-code-場景加速明顯attention-並行性的支撐">為什麼 speculative decoding 在 code 場景加速明顯：attention 並行性的支撐</h2>
<p>加速本身來自 <a href="/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">speculative decoding</a> / <a href="/blog/llm/knowledge-cards/mtp/" data-link-title="Multi-Token Prediction (MTP)" data-link-desc="Google 為 Gemma 系列釋出的 speculative decoding 工程化實作">MTP</a>、attention 在這條路徑上的角色是「提供並行驗證所需的計算結構」：</p>
<ul>
<li>Speculative decoding 一次驗證 N 個 token、需要 attention 同時處理 N 個 query 對前面所有 K/V。</li>
<li>Attention 機制天生可並行、一次 forward pass 驗證 N 個 token 跟驗證 1 個 token 的時間接近（瓶頸是讀權重而非算 attention）。</li>
<li>寫 code 場景 drafter 接受率高（code 的 pattern 容易預測）、加速明顯。</li>
</ul>
<p>理解這點、能解釋為什麼 MTP 對 coding 比創意寫作加速更明顯：差別不在 attention 本身、在「drafter 預測的接受率」這個 sampling 層的變數。</p>
<h2 id="下一章">下一章</h2>
<p>下一章：<a href="/blog/llm/03-theoretical-foundations/transformer-architecture/" data-link-title="3.3 Transformer 架構細節" data-link-desc="Decoder-only 結構、Transformer block、positional encoding、layer norm、residual stream">3.3 Transformer 架構</a>、把 attention 跟 embedding 組裝成完整模型。</p>
]]></content:encoded></item></channel></rss>