<?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>Knowledge Cards on Tarragon</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/</link><description>Recent content in Knowledge Cards on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Mon, 11 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/llm/knowledge-cards/index.xml" rel="self" type="application/rss+xml"/><item><title>Adaptive Retrieval</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/adaptive-retrieval/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/adaptive-retrieval/</guid><description>&lt;p>Adaptive retrieval 的核心概念是「&lt;strong>先判斷問題是否需要 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 外部檢索，再決定要不要 retrieve&lt;/strong>」。它避免每個 query 都塞入外部 chunk，降低 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost&lt;/a>，也減少無關內容干擾模型。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Adaptive retrieval 位在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 的控制流端。它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-rewriting/" data-link-title="Query Rewriting" data-link-desc="在 RAG 檢索前改寫使用者查詢，讓 query 更接近文件語言與索引分佈">query rewriting&lt;/a> 不同：rewriting 假設要 retrieve，只改查詢形狀；adaptive retrieval 先決定 retrieve 是否必要。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>「2+2 等於多少」不需要 retrieve；「公司退款政策第 4 條怎麼說」需要 retrieve。若使用者 query 一半是聊天、一半是 factual lookup，adaptive retrieval 可以明顯降低 retrieval cost。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>判斷器可以是規則、小模型、主模型 self-report 或 confidence signal。風險是模型過度自信而跳過檢索；高風險事實問答應偏向 retrieve 或提供 fallback。&lt;/p></description><content:encoded><![CDATA[<p>Adaptive retrieval 的核心概念是「<strong>先判斷問題是否需要 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 外部檢索，再決定要不要 retrieve</strong>」。它避免每個 query 都塞入外部 chunk，降低 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a>，也減少無關內容干擾模型。</p>
<h2 id="概念位置">概念位置</h2>
<p>Adaptive retrieval 位在 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 的控制流端。它跟 <a href="/blog/llm/knowledge-cards/query-rewriting/" data-link-title="Query Rewriting" data-link-desc="在 RAG 檢索前改寫使用者查詢，讓 query 更接近文件語言與索引分佈">query rewriting</a> 不同：rewriting 假設要 retrieve，只改查詢形狀；adaptive retrieval 先決定 retrieve 是否必要。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>「2+2 等於多少」不需要 retrieve；「公司退款政策第 4 條怎麼說」需要 retrieve。若使用者 query 一半是聊天、一半是 factual lookup，adaptive retrieval 可以明顯降低 retrieval cost。</p>
<h2 id="設計責任">設計責任</h2>
<p>判斷器可以是規則、小模型、主模型 self-report 或 confidence signal。風險是模型過度自信而跳過檢索；高風險事實問答應偏向 retrieve 或提供 fallback。</p>
]]></content:encoded></item><item><title>Agent-as-Tool</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/agent-as-tool/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/agent-as-tool/</guid><description>&lt;p>Agent-as-tool 的核心概念是「&lt;strong>把一個 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/agent/" data-link-title="LLM Agent" data-link-desc="把控制流交給 LLM 的應用模式：自主決策、跨多步呼叫工具、人類角色從主導變監督">agent&lt;/a> 封裝成另一個 agent 可呼叫的工具&lt;/strong>」。被封裝的 agent 有自己的 prompt、工具、上下文與完成條件；呼叫方只看到一個較高階的 tool interface。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>它是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/multi-agent-system/" data-link-title="Multi-agent system" data-link-desc="多個 LLM agent 協作的系統、跟 multi-call workflow 的差異在控制流跟責任邊界、三種拓樸 flat / hierarchical / agent-as-tool">multi-agent system&lt;/a> 的一種拓樸，也可透過 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mcp/" data-link-title="MCP（Model Context Protocol）" data-link-desc="LLM application ↔ 外部 tool server 之間的標準化協議、複用 OpenAI 相容 API 的成功模式">MCP&lt;/a> 暴露成 tool server。它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/subagent/" data-link-title="Subagent" data-link-desc="Coding agent 中把特定責任拆給專門子 agent 的設計模式、各 subagent 有獨立 context、由 main agent 透過 handoff 調度">subagent&lt;/a> 的差異是：subagent 常是同一 runtime 內的任務分派，agent-as-tool 強調對外介面與重用邊界。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>主 agent 呼叫 &lt;code>run_security_review()&lt;/code>，背後其實是一個安全 reviewer agent 讀檔、查規則、輸出 findings。主 agent 不需要知道內部步驟，只需要 consume 結果。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Agent-as-tool 要把輸入、輸出、權限、副作用與 timeout 定清楚。否則呼叫方會把它當 deterministic tool，但內部其實是 fuzzy agent，失敗模式會被隱藏。&lt;/p></description><content:encoded><![CDATA[<p>Agent-as-tool 的核心概念是「<strong>把一個 <a href="/blog/llm/knowledge-cards/agent/" data-link-title="LLM Agent" data-link-desc="把控制流交給 LLM 的應用模式：自主決策、跨多步呼叫工具、人類角色從主導變監督">agent</a> 封裝成另一個 agent 可呼叫的工具</strong>」。被封裝的 agent 有自己的 prompt、工具、上下文與完成條件；呼叫方只看到一個較高階的 tool interface。</p>
<h2 id="概念位置">概念位置</h2>
<p>它是 <a href="/blog/llm/knowledge-cards/multi-agent-system/" data-link-title="Multi-agent system" data-link-desc="多個 LLM agent 協作的系統、跟 multi-call workflow 的差異在控制流跟責任邊界、三種拓樸 flat / hierarchical / agent-as-tool">multi-agent system</a> 的一種拓樸，也可透過 <a href="/blog/llm/knowledge-cards/mcp/" data-link-title="MCP（Model Context Protocol）" data-link-desc="LLM application ↔ 外部 tool server 之間的標準化協議、複用 OpenAI 相容 API 的成功模式">MCP</a> 暴露成 tool server。它跟 <a href="/blog/llm/knowledge-cards/subagent/" data-link-title="Subagent" data-link-desc="Coding agent 中把特定責任拆給專門子 agent 的設計模式、各 subagent 有獨立 context、由 main agent 透過 handoff 調度">subagent</a> 的差異是：subagent 常是同一 runtime 內的任務分派，agent-as-tool 強調對外介面與重用邊界。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>主 agent 呼叫 <code>run_security_review()</code>，背後其實是一個安全 reviewer agent 讀檔、查規則、輸出 findings。主 agent 不需要知道內部步驟，只需要 consume 結果。</p>
<h2 id="設計責任">設計責任</h2>
<p>Agent-as-tool 要把輸入、輸出、權限、副作用與 timeout 定清楚。否則呼叫方會把它當 deterministic tool，但內部其實是 fuzzy agent，失敗模式會被隱藏。</p>
]]></content:encoded></item><item><title>BNF（Backus-Naur Form）</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/bnf/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/bnf/</guid><description>&lt;p>BNF（Backus-Naur Form）的核心概念是「&lt;strong>用產生式規則描述一個語言裡哪些字串合法&lt;/strong>」。它常用在程式語言、資料格式、parser 與 structured output grammar，讓人跟工具都能用同一份規則理解合法語法。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>BNF 是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">grammar&lt;/a> 的一種表示法，特別適合描述 context-free grammar。規則左邊是非終結符，右邊是它可以展開成的符號組合；終結符是實際會出現在字串中的 token，非終結符是中間抽象節點。&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">&amp;lt;expr&amp;gt; ::= &amp;lt;term&amp;gt; | &amp;lt;expr&amp;gt; &amp;#34;+&amp;#34; &amp;lt;term&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&amp;lt;term&amp;gt; ::= &amp;lt;number&amp;gt; | &amp;#34;(&amp;#34; &amp;lt;expr&amp;gt; &amp;#34;)&amp;#34;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>這段規則表示 expression 可以是 term，也可以是 expression 加 term；term 可以是 number，也可以是括號包住的 expression。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>看到 &lt;code>::=&lt;/code>、&lt;code>&amp;lt;name&amp;gt;&lt;/code>、多個展開選項，就是 BNF 或 BNF-like grammar。LLM structured output 文章裡提到 BNF，通常是在說「把合法輸出格式寫成形式語法，推論時用它限制生成」。llama.cpp 的 GBNF、部分 grammar engine 與 parser 文件都會使用類似記法。&lt;/p>
&lt;p>BNF 的限制是它描述語法，不描述語意。它能表示「括號必須成對」「欄位順序合法」，但不能直接表示「日期必須晚於今天」「使用者必須有權限讀這筆資料」這類外部約束。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>BNF 適合拿來讀懂 grammar-constrained sampling 的規則形狀。實作時要確認你使用的引擎支援的是標準 BNF、EBNF、GBNF，還是自家 dialect；不同 dialect 的 optional、repeat、token escaping 寫法會不同。下一步路由是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">Grammar&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/lark-grammar/" data-link-title="Lark Grammar" data-link-desc="Lark parser 使用的 EBNF-like grammar 格式，常被 structured output 工具拿來描述自訂輸出語法">Lark Grammar&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>BNF（Backus-Naur Form）的核心概念是「<strong>用產生式規則描述一個語言裡哪些字串合法</strong>」。它常用在程式語言、資料格式、parser 與 structured output grammar，讓人跟工具都能用同一份規則理解合法語法。</p>
<h2 id="概念位置">概念位置</h2>
<p>BNF 是 <a href="/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">grammar</a> 的一種表示法，特別適合描述 context-free grammar。規則左邊是非終結符，右邊是它可以展開成的符號組合；終結符是實際會出現在字串中的 token，非終結符是中間抽象節點。</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">&lt;expr&gt; ::= &lt;term&gt; | &lt;expr&gt; &#34;+&#34; &lt;term&gt;
</span></span><span class="line"><span class="ln">2</span><span class="cl">&lt;term&gt; ::= &lt;number&gt; | &#34;(&#34; &lt;expr&gt; &#34;)&#34;</span></span></code></pre></div><p>這段規則表示 expression 可以是 term，也可以是 expression 加 term；term 可以是 number，也可以是括號包住的 expression。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>看到 <code>::=</code>、<code>&lt;name&gt;</code>、多個展開選項，就是 BNF 或 BNF-like grammar。LLM structured output 文章裡提到 BNF，通常是在說「把合法輸出格式寫成形式語法，推論時用它限制生成」。llama.cpp 的 GBNF、部分 grammar engine 與 parser 文件都會使用類似記法。</p>
<p>BNF 的限制是它描述語法，不描述語意。它能表示「括號必須成對」「欄位順序合法」，但不能直接表示「日期必須晚於今天」「使用者必須有權限讀這筆資料」這類外部約束。</p>
<h2 id="設計責任">設計責任</h2>
<p>BNF 適合拿來讀懂 grammar-constrained sampling 的規則形狀。實作時要確認你使用的引擎支援的是標準 BNF、EBNF、GBNF，還是自家 dialect；不同 dialect 的 optional、repeat、token escaping 寫法會不同。下一步路由是 <a href="/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">Grammar</a> 與 <a href="/blog/llm/knowledge-cards/lark-grammar/" data-link-title="Lark Grammar" data-link-desc="Lark parser 使用的 EBNF-like grammar 格式，常被 structured output 工具拿來描述自訂輸出語法">Lark Grammar</a>。</p>
]]></content:encoded></item><item><title>Capability Spectrum</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/capability-spectrum/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/capability-spectrum/</guid><description>&lt;p>Capability spectrum（能力光譜）的核心概念是「&lt;strong>LLM 能力通常是連續程度，不是支援 / 不支援的二元開關&lt;/strong>」。同樣宣稱支援 function calling、reasoning、coding、structured output 的模型，可能在簡單案例都成功，但在長 context、多工具、巢狀 schema、模糊需求或反例情境下出現巨大差距。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>能力光譜是評估與選型用語，用來替代 binary checklist。它把能力拆成範圍、穩定性、成本與失敗模式：模型能做什麼、在多寬的分佈上穩定、錯的時候怎麼錯、需要多少 prompt / validator / retry 才可用。&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">宣稱支援 → happy path 可用
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">基礎可用 → 常見變體可用
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">生產可用 → edge cases、錯誤路徑、壓力情境仍可控&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>Function calling 的能力光譜可以用幾個訊號量化：單工具成功率、多工具選擇成功率、schema 合法率、參數語意正確率、錯誤時是否追問。某模型能輸出合法 JSON，不代表它能選對工具；能選對工具，也不代表它能填對 nested argument。&lt;/p>
&lt;p>能力光譜的常見陷阱是把 demo 成功當成生產穩定。Demo 通常測 happy path，生產會遇到拼字錯、缺欄位、權限不足、工具 timeout、prompt injection、schema 演化與多語言輸入；這些才決定能力落在哪個位置。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>做模型選型或應用設計時，把「有沒有」改成「到什麼程度可用」。判準要包含成功率、覆蓋範圍、錯誤成本、監控訊號與回退路徑。下一步路由是：能力來自訓練資料時讀 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/training-example-coverage/" data-link-title="Training Example Coverage" data-link-desc="訓練資料中的任務範例是否覆蓋足夠情境，決定模型在 function calling、格式輸出與邊界案例上的穩定性">Training Example Coverage&lt;/a>；能力需要推論階段兜底時讀 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/sampling-constraint/" data-link-title="Sampling Constraint" data-link-desc="推論時限制下一個 token 候選集合的控制手段，用來把模型生成導向合法格式或特定選項">Sampling Constraint&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Capability spectrum（能力光譜）的核心概念是「<strong>LLM 能力通常是連續程度，不是支援 / 不支援的二元開關</strong>」。同樣宣稱支援 function calling、reasoning、coding、structured output 的模型，可能在簡單案例都成功，但在長 context、多工具、巢狀 schema、模糊需求或反例情境下出現巨大差距。</p>
<h2 id="概念位置">概念位置</h2>
<p>能力光譜是評估與選型用語，用來替代 binary checklist。它把能力拆成範圍、穩定性、成本與失敗模式：模型能做什麼、在多寬的分佈上穩定、錯的時候怎麼錯、需要多少 prompt / validator / retry 才可用。</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">宣稱支援 → happy path 可用
</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">生產可用 → edge cases、錯誤路徑、壓力情境仍可控</span></span></code></pre></div><h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>Function calling 的能力光譜可以用幾個訊號量化：單工具成功率、多工具選擇成功率、schema 合法率、參數語意正確率、錯誤時是否追問。某模型能輸出合法 JSON，不代表它能選對工具；能選對工具，也不代表它能填對 nested argument。</p>
<p>能力光譜的常見陷阱是把 demo 成功當成生產穩定。Demo 通常測 happy path，生產會遇到拼字錯、缺欄位、權限不足、工具 timeout、prompt injection、schema 演化與多語言輸入；這些才決定能力落在哪個位置。</p>
<h2 id="設計責任">設計責任</h2>
<p>做模型選型或應用設計時，把「有沒有」改成「到什麼程度可用」。判準要包含成功率、覆蓋範圍、錯誤成本、監控訊號與回退路徑。下一步路由是：能力來自訓練資料時讀 <a href="/blog/llm/knowledge-cards/training-example-coverage/" data-link-title="Training Example Coverage" data-link-desc="訓練資料中的任務範例是否覆蓋足夠情境，決定模型在 function calling、格式輸出與邊界案例上的穩定性">Training Example Coverage</a>；能力需要推論階段兜底時讀 <a href="/blog/llm/knowledge-cards/sampling-constraint/" data-link-title="Sampling Constraint" data-link-desc="推論時限制下一個 token 候選集合的控制手段，用來把模型生成導向合法格式或特定選項">Sampling Constraint</a>。</p>
]]></content:encoded></item><item><title>Context Drift</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/context-drift/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/context-drift/</guid><description>&lt;p>Context drift（上下文漂移）的核心概念是「&lt;strong>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop&lt;/a> 長任務中累積 context 逐步偏離原始目標&lt;/strong>」。每一步局部看起來合理，但中間結果、工具輸出與模型自我敘述會逐漸取代原始任務，讓整體方向跑偏。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Context drift 是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop&lt;/a> 的長程失敗模式，跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/goal-drift/" data-link-title="Goal Drift" data-link-desc="Agent 把子目標誤當成整體目標，提早停止或朝錯誤完成條件前進的失敗模式">goal drift&lt;/a> 不同：goal drift 是把子目標當終點，context drift 是上下文重心逐步偏移。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>任務原本是修 bug，十步後變成重構模組，再十步後變成重寫整個檔案，就是 context drift。常見訊號是 agent 開始引用近期工具輸出當主目標，卻不再回看最初 acceptance criteria。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>緩解方式是定期重錨原始目標、保留 checklist、設 checkpoint、讓外部 evaluator 比對目前行動與原始任務距離。漂移持續發生時，縮短 loop、改用 single-call pipeline，或提高 human review 頻率。&lt;/p></description><content:encoded><![CDATA[<p>Context drift（上下文漂移）的核心概念是「<strong><a href="/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop</a> 長任務中累積 context 逐步偏離原始目標</strong>」。每一步局部看起來合理，但中間結果、工具輸出與模型自我敘述會逐漸取代原始任務，讓整體方向跑偏。</p>
<h2 id="概念位置">概念位置</h2>
<p>Context drift 是 <a href="/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop</a> 的長程失敗模式，跟 <a href="/blog/llm/knowledge-cards/goal-drift/" data-link-title="Goal Drift" data-link-desc="Agent 把子目標誤當成整體目標，提早停止或朝錯誤完成條件前進的失敗模式">goal drift</a> 不同：goal drift 是把子目標當終點，context drift 是上下文重心逐步偏移。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>任務原本是修 bug，十步後變成重構模組，再十步後變成重寫整個檔案，就是 context drift。常見訊號是 agent 開始引用近期工具輸出當主目標，卻不再回看最初 acceptance criteria。</p>
<h2 id="設計責任">設計責任</h2>
<p>緩解方式是定期重錨原始目標、保留 checklist、設 checkpoint、讓外部 evaluator 比對目前行動與原始任務距離。漂移持續發生時，縮短 loop、改用 single-call pipeline，或提高 human review 頻率。</p>
]]></content:encoded></item><item><title>Context Packing</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/context-packing/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/context-packing/</guid><description>&lt;p>Context packing 的核心概念是「&lt;strong>retrieve 拿到候選 chunks 後，決定哪些內容、以什麼順序、帶哪些 metadata 塞進 prompt&lt;/strong>」。它是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 在 retrieval 與 generation 之間的 context 組裝層，有別於 retrieval 本身。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Context packing 位在 top-k retrieval 結果與 LLM prompt 之間。它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-source/" data-link-title="Retrieval Source" data-link-desc="RAG 從哪個 corpus、index、tool 或外部系統取回內容，決定來源可信度、freshness、權限與引用責任">retrieval source&lt;/a> 相鄰，因為來源 metadata 會影響引用；也跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/lost-in-the-middle/" data-link-title="Lost in the Middle" data-link-desc="LLM 對 long context 中段內容的 attention / recall 顯著低於開頭與結尾的現象">lost-in-the-middle&lt;/a> 相鄰，因為 chunk 順序會影響模型注意力。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>常見 packing 決策包含 dedup 重複 chunk、把最相關內容放前後、按 document order 保留段落流、摘要或壓縮過長 chunks、在每段前加 source path 與 score。這些決策會改變答案品質、token cost 與可追溯性。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>設計 context packing 時要回答：哪些 chunk 真的要進 prompt、順序如何安排、是否保留來源、是否需要 summarization / compression。高追溯場景優先保留 source metadata；長 context 場景要避免把重要 chunk 放在中間；latency 敏感場景要限制 top-k 與 compression call。&lt;/p></description><content:encoded><![CDATA[<p>Context packing 的核心概念是「<strong>retrieve 拿到候選 chunks 後，決定哪些內容、以什麼順序、帶哪些 metadata 塞進 prompt</strong>」。它是 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 在 retrieval 與 generation 之間的 context 組裝層，有別於 retrieval 本身。</p>
<h2 id="概念位置">概念位置</h2>
<p>Context packing 位在 top-k retrieval 結果與 LLM prompt 之間。它跟 <a href="/blog/llm/knowledge-cards/retrieval-source/" data-link-title="Retrieval Source" data-link-desc="RAG 從哪個 corpus、index、tool 或外部系統取回內容，決定來源可信度、freshness、權限與引用責任">retrieval source</a> 相鄰，因為來源 metadata 會影響引用；也跟 <a href="/blog/llm/knowledge-cards/lost-in-the-middle/" data-link-title="Lost in the Middle" data-link-desc="LLM 對 long context 中段內容的 attention / recall 顯著低於開頭與結尾的現象">lost-in-the-middle</a> 相鄰，因為 chunk 順序會影響模型注意力。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>常見 packing 決策包含 dedup 重複 chunk、把最相關內容放前後、按 document order 保留段落流、摘要或壓縮過長 chunks、在每段前加 source path 與 score。這些決策會改變答案品質、token cost 與可追溯性。</p>
<h2 id="設計責任">設計責任</h2>
<p>設計 context packing 時要回答：哪些 chunk 真的要進 prompt、順序如何安排、是否保留來源、是否需要 summarization / compression。高追溯場景優先保留 source metadata；長 context 場景要避免把重要 chunk 放在中間；latency 敏感場景要限制 top-k 與 compression call。</p>
]]></content:encoded></item><item><title>Deterministic vs Fuzzy engineering</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/deterministic-vs-fuzzy/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/deterministic-vs-fuzzy/</guid><description>&lt;p>Deterministic vs Fuzzy engineering 的核心概念是「&lt;strong>LLM 軟體跟傳統軟體在設計典範上的根本差異&lt;/strong>」。Deterministic 軟體建立在「同 input → 同 output」假設、fuzzy 軟體建立在「同 input → 分佈」假設。兩者在資料、邏輯、行為一致性、實驗成本四維度都不同、設計直覺要分開。實務上一個 LLM 應用是兩者混合、guardrail 設計是把 fuzzy 邊界包進 deterministic 約束。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>四維對照：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>Deterministic 軟體&lt;/th>
 &lt;th>Fuzzy 軟體&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>資料形狀&lt;/td>
 &lt;td>結構化（JSON、DB row）&lt;/td>
 &lt;td>半結構化 / 非結構化&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>邏輯來源&lt;/td>
 &lt;td>人類寫死規則&lt;/td>
 &lt;td>模型推論、依 prompt + context 浮動&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>行為一致性&lt;/td>
 &lt;td>同 input → 同 output&lt;/td>
 &lt;td>同 input → 分佈&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>分解原則&lt;/td>
 &lt;td>按職責 / 模組&lt;/td>
 &lt;td>按角色 / agent&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>測試方式&lt;/td>
 &lt;td>unit test、覆蓋率&lt;/td>
 &lt;td>eval、judge、distribution metric&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>實驗成本&lt;/td>
 &lt;td>高&lt;/td>
 &lt;td>低（改 prompt 即可）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>典型 LLM 應用的混合：&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">User input
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓ Fuzzy（LLM 理解意圖）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> ↓ Deterministic（DB / API / policy）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ↓ Fuzzy（LLM 寫回應）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> ↓ Deterministic（發送 / 寫入）&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 LLM 應用設計文章或開始設計 production AI 系統時、這個 framing 決定每個 step 的工具選擇。實作判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>哪段該 deterministic / 哪段該 fuzzy&lt;/strong>：規則可窮舉、失敗代價高、需要解釋、需要 byte-exact 重現的 → deterministic；自由文字輸入、生成有風格的輸出、邊界模糊的 → fuzzy。&lt;/li>
&lt;li>&lt;strong>典範用錯的反模式&lt;/strong>：deterministic 需求硬用 fuzzy（用 LLM 算稅金）、fuzzy 需求硬用 deterministic（regex 解析自由文字）、邊界混（prompt 內塞算術 / code 內塞意圖分類）。&lt;/li>
&lt;li>&lt;strong>Fuzzy 邊界的四種 guardrail&lt;/strong>：schema validation、output validator、action gating、distribution monitoring。混用、不同 risk class 分擔不同層。&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/human-in-the-loop/" data-link-title="Human-in-the-loop（HITL）" data-link-desc="人類介入 LLM 工作流的設計：三種觸發時機（pre-act / mid-stream / post-hoc）、避免橡皮圖章化的四條件">HITL&lt;/a> 的關係&lt;/strong>：HITL 是 deterministic guardrail 的一種——把人類判斷當 deterministic check 包 fuzzy LLM 行為。&lt;/li>
&lt;li>&lt;strong>失敗的歸因分層&lt;/strong>：壞掉時要問「是 prompt / model / context / tool / 還是 deterministic glue 的 bug」。deterministic 軟體歸因單一、fuzzy 軟體要分這幾層查。&lt;/li>
&lt;/ol>
&lt;p>完整典範討論見 &lt;a href="https://tarrragon.github.io/blog/llm/00-foundations/deterministic-vs-fuzzy-engineering/" data-link-title="0.8 Deterministic vs Fuzzy Engineering：軟體設計典範的位移" data-link-desc="傳統 deterministic 軟體跟 fuzzy LLM 軟體在資料、邏輯、分解、實驗成本四個維度的根本差異、以及哪段該 deterministic、哪段該 fuzzy 的決策框架">0.8 Deterministic vs Fuzzy Engineering&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Deterministic vs Fuzzy engineering 的核心概念是「<strong>LLM 軟體跟傳統軟體在設計典範上的根本差異</strong>」。Deterministic 軟體建立在「同 input → 同 output」假設、fuzzy 軟體建立在「同 input → 分佈」假設。兩者在資料、邏輯、行為一致性、實驗成本四維度都不同、設計直覺要分開。實務上一個 LLM 應用是兩者混合、guardrail 設計是把 fuzzy 邊界包進 deterministic 約束。</p>
<h2 id="概念位置">概念位置</h2>
<p>四維對照：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>Deterministic 軟體</th>
          <th>Fuzzy 軟體</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>資料形狀</td>
          <td>結構化（JSON、DB row）</td>
          <td>半結構化 / 非結構化</td>
      </tr>
      <tr>
          <td>邏輯來源</td>
          <td>人類寫死規則</td>
          <td>模型推論、依 prompt + context 浮動</td>
      </tr>
      <tr>
          <td>行為一致性</td>
          <td>同 input → 同 output</td>
          <td>同 input → 分佈</td>
      </tr>
      <tr>
          <td>分解原則</td>
          <td>按職責 / 模組</td>
          <td>按角色 / agent</td>
      </tr>
      <tr>
          <td>測試方式</td>
          <td>unit test、覆蓋率</td>
          <td>eval、judge、distribution metric</td>
      </tr>
      <tr>
          <td>實驗成本</td>
          <td>高</td>
          <td>低（改 prompt 即可）</td>
      </tr>
  </tbody>
</table>
<p>典型 LLM 應用的混合：</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">User input
</span></span><span class="line"><span class="ln">2</span><span class="cl">   ↓ Fuzzy（LLM 理解意圖）
</span></span><span class="line"><span class="ln">3</span><span class="cl">   ↓ Deterministic（DB / API / policy）
</span></span><span class="line"><span class="ln">4</span><span class="cl">   ↓ Fuzzy（LLM 寫回應）
</span></span><span class="line"><span class="ln">5</span><span class="cl">   ↓ Deterministic（發送 / 寫入）</span></span></code></pre></div><h2 id="設計責任">設計責任</h2>
<p>讀 LLM 應用設計文章或開始設計 production AI 系統時、這個 framing 決定每個 step 的工具選擇。實作判讀：</p>
<ol>
<li><strong>哪段該 deterministic / 哪段該 fuzzy</strong>：規則可窮舉、失敗代價高、需要解釋、需要 byte-exact 重現的 → deterministic；自由文字輸入、生成有風格的輸出、邊界模糊的 → fuzzy。</li>
<li><strong>典範用錯的反模式</strong>：deterministic 需求硬用 fuzzy（用 LLM 算稅金）、fuzzy 需求硬用 deterministic（regex 解析自由文字）、邊界混（prompt 內塞算術 / code 內塞意圖分類）。</li>
<li><strong>Fuzzy 邊界的四種 guardrail</strong>：schema validation、output validator、action gating、distribution monitoring。混用、不同 risk class 分擔不同層。</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/human-in-the-loop/" data-link-title="Human-in-the-loop（HITL）" data-link-desc="人類介入 LLM 工作流的設計：三種觸發時機（pre-act / mid-stream / post-hoc）、避免橡皮圖章化的四條件">HITL</a> 的關係</strong>：HITL 是 deterministic guardrail 的一種——把人類判斷當 deterministic check 包 fuzzy LLM 行為。</li>
<li><strong>失敗的歸因分層</strong>：壞掉時要問「是 prompt / model / context / tool / 還是 deterministic glue 的 bug」。deterministic 軟體歸因單一、fuzzy 軟體要分這幾層查。</li>
</ol>
<p>完整典範討論見 <a href="/blog/llm/00-foundations/deterministic-vs-fuzzy-engineering/" data-link-title="0.8 Deterministic vs Fuzzy Engineering：軟體設計典範的位移" data-link-desc="傳統 deterministic 軟體跟 fuzzy LLM 軟體在資料、邏輯、分解、實驗成本四個維度的根本差異、以及哪段該 deterministic、哪段該 fuzzy 的決策框架">0.8 Deterministic vs Fuzzy Engineering</a>。</p>
]]></content:encoded></item><item><title>DSL（Domain-Specific Language）</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/dsl/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/dsl/</guid><description>&lt;p>DSL（Domain-Specific Language）的核心概念是「&lt;strong>為特定領域設計的小語言&lt;/strong>」。它不像通用程式語言要解所有問題，而是把某個領域的可用操作、資料形狀與限制收斂成小而可解析的語法，讓人類、LLM 與程式都能用同一種中介表示溝通。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>在 LLM 應用裡，DSL 常出現在自然語言與程式執行之間。模型把使用者意圖轉成 DSL，應用再 parse、validate、authorize、execute；這比直接讓模型輸出任意程式碼更容易控管，也比純自然語言更容易自動化。&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">使用者：「找出高優先、尚未處理的 billing ticket」
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">LLM 輸出 DSL：ticket.where(category=&amp;#34;billing&amp;#34;, priority=&amp;#34;high&amp;#34;, status!=&amp;#34;done&amp;#34;)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">parser / validator / executor&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>看到「特定 query language」「workflow mini-language」「policy expression」「filter expression」「tool command language」就是 DSL 候選。例子包括搜尋篩選語法、監控告警規則、資料轉換 pipeline、客服工單查詢、CI workflow 條件式。&lt;/p>
&lt;p>DSL 的風險是語法看起來可控，但語意與權限仍然危險。模型生成的 DSL 要經過 parser 確認語法、validator 確認欄位與型別、authorization 確認可操作範圍、dry run 或 preview 確認副作用；不能因為輸出不是通用程式碼就直接執行。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>DSL 適合操作集合固定、需要高可控性、且自然語言到執行之間需要審計紀錄的場景。設計時先定義最小語法、失敗路由與不可表示狀態；需要讓 LLM 穩定產生 DSL 時，用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">grammar&lt;/a> 或 JSON Schema 約束輸出。下一步路由是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">Structured Output&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/sampling-constraint/" data-link-title="Sampling Constraint" data-link-desc="推論時限制下一個 token 候選集合的控制手段，用來把模型生成導向合法格式或特定選項">Sampling Constraint&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>DSL（Domain-Specific Language）的核心概念是「<strong>為特定領域設計的小語言</strong>」。它不像通用程式語言要解所有問題，而是把某個領域的可用操作、資料形狀與限制收斂成小而可解析的語法，讓人類、LLM 與程式都能用同一種中介表示溝通。</p>
<h2 id="概念位置">概念位置</h2>
<p>在 LLM 應用裡，DSL 常出現在自然語言與程式執行之間。模型把使用者意圖轉成 DSL，應用再 parse、validate、authorize、execute；這比直接讓模型輸出任意程式碼更容易控管，也比純自然語言更容易自動化。</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">使用者：「找出高優先、尚未處理的 billing ticket」
</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">LLM 輸出 DSL：ticket.where(category=&#34;billing&#34;, priority=&#34;high&#34;, status!=&#34;done&#34;)
</span></span><span class="line"><span class="ln">4</span><span class="cl">  ↓
</span></span><span class="line"><span class="ln">5</span><span class="cl">parser / validator / executor</span></span></code></pre></div><h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>看到「特定 query language」「workflow mini-language」「policy expression」「filter expression」「tool command language」就是 DSL 候選。例子包括搜尋篩選語法、監控告警規則、資料轉換 pipeline、客服工單查詢、CI workflow 條件式。</p>
<p>DSL 的風險是語法看起來可控，但語意與權限仍然危險。模型生成的 DSL 要經過 parser 確認語法、validator 確認欄位與型別、authorization 確認可操作範圍、dry run 或 preview 確認副作用；不能因為輸出不是通用程式碼就直接執行。</p>
<h2 id="設計責任">設計責任</h2>
<p>DSL 適合操作集合固定、需要高可控性、且自然語言到執行之間需要審計紀錄的場景。設計時先定義最小語法、失敗路由與不可表示狀態；需要讓 LLM 穩定產生 DSL 時，用 <a href="/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">grammar</a> 或 JSON Schema 約束輸出。下一步路由是 <a href="/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">Structured Output</a> 與 <a href="/blog/llm/knowledge-cards/sampling-constraint/" data-link-title="Sampling Constraint" data-link-desc="推論時限制下一個 token 候選集合的控制手段，用來把模型生成導向合法格式或特定選項">Sampling Constraint</a>。</p>
]]></content:encoded></item><item><title>Few-shot prompting</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/few-shot-prompting/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/few-shot-prompting/</guid><description>&lt;p>Few-shot prompting 的核心概念是「&lt;strong>在 prompt 內塞幾個 input-output 範例、讓模型透過範例對齊任務&lt;/strong>」。Zero-shot 是不給範例直接給任務、few-shot 是給 1-N 個範例、模型從範例推任務分佈。屬於 in-context learning 的最常見形態、是「對齊任務」這件事的 prompt 層解法、跟 fine-tune 是兩個 endpoint。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Zero-shot vs few-shot 對照：&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">Zero-shot：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> Classify the tone as positive/negative/neutral.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> Review: &amp;#34;Fine, but I expected more.&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> → 模型自己判斷「中性」邊界
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">Few-shot：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> Classify the tone as positive/negative/neutral.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> Examples:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> &amp;#34;Exceeded my expectations&amp;#34; → positive
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> &amp;#34;OK, but I wish more features&amp;#34; → negative
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> &amp;#34;Service was adequate&amp;#34; → neutral
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> Review: &amp;#34;Fine, but I expected more.&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl"> → 模型按範例對齊、更傾向 negative&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Few-shot 跟 fine-tune 對照：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>Few-shot in prompt&lt;/th>
 &lt;th>Fine-tune&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Iteration&lt;/td>
 &lt;td>分鐘級、改 prompt 即可&lt;/td>
 &lt;td>天級、要 retrain&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>範例容量&lt;/td>
 &lt;td>受 context window 限制（10–50）&lt;/td>
 &lt;td>可以幾千幾萬、整個 dataset 都行&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Cost&lt;/td>
 &lt;td>每次 inference 多付 token&lt;/td>
 &lt;td>一次性訓練 cost、之後 inference 不變&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>模型遷移&lt;/td>
 &lt;td>跨模型即時換、prompt 直接搬&lt;/td>
 &lt;td>綁特定 base model、換模型要 retrain&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 prompt engineering 文章或寫 production prompt 看到「few-shot」「in-context examples」就是這個機制。實作判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>適用任務有「我的標準跟模型預設不同」&lt;/strong>：分類邊界、抽取格式、tone alignment、structured output 形狀。&lt;/li>
&lt;li>&lt;strong>失效在範例選不好&lt;/strong>：cherry-picked 不代表 distribution、cover 不到 edge case、範例彼此衝突。&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/chain-of-thought/" data-link-title="Chain-of-Thought（CoT）" data-link-desc="讓 LLM 先輸出推理步驟再給最終答案的 prompting / 訓練方式、reasoning model 的基礎機制">chain-of-thought&lt;/a> 可疊&lt;/strong>（few-shot CoT 是經典組合）、跟 fine-tune 是 endpoint 取捨。&lt;/li>
&lt;li>&lt;strong>何時轉 fine-tune&lt;/strong>：範例多到撐爆 &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> 又每天都用、才考慮。預設先 few-shot iterate。&lt;/li>
&lt;li>&lt;strong>Retrieval-augmented prompting&lt;/strong>：把寫死的 few-shot 換成從範例庫即時 retrieve、屬於 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 概念延伸。&lt;/li>
&lt;/ol>
&lt;p>完整 prompt 技術 landscape 見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/prompt-techniques-landscape/" data-link-title="4.0 Prompt 技術光譜：手法分類、取捨、組合模式" data-link-desc="Zero-shot / few-shot、chain-of-thought、role / template、reflection 等 prompt 技術的分類與取捨、何時 stack 何時不要 stack、跟 fine-tune / RAG / chaining 的邊界">4.0 Prompt 技術光譜&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Few-shot prompting 的核心概念是「<strong>在 prompt 內塞幾個 input-output 範例、讓模型透過範例對齊任務</strong>」。Zero-shot 是不給範例直接給任務、few-shot 是給 1-N 個範例、模型從範例推任務分佈。屬於 in-context learning 的最常見形態、是「對齊任務」這件事的 prompt 層解法、跟 fine-tune 是兩個 endpoint。</p>
<h2 id="概念位置">概念位置</h2>
<p>Zero-shot vs few-shot 對照：</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">Zero-shot：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  Classify the tone as positive/negative/neutral.
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">  Review: &#34;Fine, but I expected more.&#34;
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  → 模型自己判斷「中性」邊界
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">Few-shot：
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  Classify the tone as positive/negative/neutral.
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  Examples:
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    &#34;Exceeded my expectations&#34; → positive
</span></span><span class="line"><span class="ln">10</span><span class="cl">    &#34;OK, but I wish more features&#34; → negative
</span></span><span class="line"><span class="ln">11</span><span class="cl">    &#34;Service was adequate&#34; → neutral
</span></span><span class="line"><span class="ln">12</span><span class="cl">  Review: &#34;Fine, but I expected more.&#34;
</span></span><span class="line"><span class="ln">13</span><span class="cl">  → 模型按範例對齊、更傾向 negative</span></span></code></pre></div><p>Few-shot 跟 fine-tune 對照：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>Few-shot in prompt</th>
          <th>Fine-tune</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Iteration</td>
          <td>分鐘級、改 prompt 即可</td>
          <td>天級、要 retrain</td>
      </tr>
      <tr>
          <td>範例容量</td>
          <td>受 context window 限制（10–50）</td>
          <td>可以幾千幾萬、整個 dataset 都行</td>
      </tr>
      <tr>
          <td>Cost</td>
          <td>每次 inference 多付 token</td>
          <td>一次性訓練 cost、之後 inference 不變</td>
      </tr>
      <tr>
          <td>模型遷移</td>
          <td>跨模型即時換、prompt 直接搬</td>
          <td>綁特定 base model、換模型要 retrain</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 prompt engineering 文章或寫 production prompt 看到「few-shot」「in-context examples」就是這個機制。實作判讀：</p>
<ol>
<li><strong>適用任務有「我的標準跟模型預設不同」</strong>：分類邊界、抽取格式、tone alignment、structured output 形狀。</li>
<li><strong>失效在範例選不好</strong>：cherry-picked 不代表 distribution、cover 不到 edge case、範例彼此衝突。</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/chain-of-thought/" data-link-title="Chain-of-Thought（CoT）" data-link-desc="讓 LLM 先輸出推理步驟再給最終答案的 prompting / 訓練方式、reasoning model 的基礎機制">chain-of-thought</a> 可疊</strong>（few-shot CoT 是經典組合）、跟 fine-tune 是 endpoint 取捨。</li>
<li><strong>何時轉 fine-tune</strong>：範例多到撐爆 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a> 又每天都用、才考慮。預設先 few-shot iterate。</li>
<li><strong>Retrieval-augmented prompting</strong>：把寫死的 few-shot 換成從範例庫即時 retrieve、屬於 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 概念延伸。</li>
</ol>
<p>完整 prompt 技術 landscape 見 <a href="/blog/llm/04-applications/prompt-techniques-landscape/" data-link-title="4.0 Prompt 技術光譜：手法分類、取捨、組合模式" data-link-desc="Zero-shot / few-shot、chain-of-thought、role / template、reflection 等 prompt 技術的分類與取捨、何時 stack 何時不要 stack、跟 fine-tune / RAG / chaining 的邊界">4.0 Prompt 技術光譜</a>。</p>
]]></content:encoded></item><item><title>Frozen baseline</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/frozen-baseline/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/frozen-baseline/</guid><description>&lt;p>Frozen baseline 的核心概念是「&lt;strong>把某個特定 prompt + 特定 model 跑 production 一段時間後 freeze、每次新版本都跟它比、定期 refresh 並標明時點&lt;/strong>」。Eval 系統的標準作法、讓行為漂移可見、避免「永遠跟上一版比、長期累積漂移看不見」的常見失敗。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>跟其他 eval 概念對照：&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>Eval set&lt;/td>
 &lt;td>測試 input 的集合&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Frozen baseline&lt;/td>
 &lt;td>固定的「對照組」prompt + model 版本&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Regression set&lt;/td>
 &lt;td>Failed case 進來、防止改 prompt 又壞同樣 case&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Production trace&lt;/td>
 &lt;td>實際 traffic、抽樣補進 eval set / baseline&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>工作流：&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">Day 1：定義 eval set + 初始 prompt + model
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓ 跑 production 一段時間（如 2 週）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">Day 14：把當下 prompt + model freeze 成 baseline-v1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">新版本 prompt / model 都跟 baseline-v1 比
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> ↓ 定期（如每季）refresh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">Day 90：baseline-v2、標明 refresh 時點&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 eval / production AI 文章看到「frozen baseline」「baseline drift」「regression set」就是這個機制。實作判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>為什麼必要&lt;/strong>：每次 A/B 都跟「最新版本」比、長期累積漂移完全不可見、「整體變好了沒」無從回答。Frozen baseline 是漂移的錨點。&lt;/li>
&lt;li>&lt;strong>何時 freeze&lt;/strong>：production 跑穩、user 滿意度可接受時 freeze。太早 freeze 鎖到不夠好的版本、太晚 freeze 鎖不到。&lt;/li>
&lt;li>&lt;strong>何時 refresh&lt;/strong>：定期（每季 / 每半年）、或當 baseline 明顯 obsolete（如 model 升級、產品大改版）。Refresh 後標明時點、舊版本仍可保留當歷史對照。&lt;/li>
&lt;li>&lt;strong>跟 frozen baseline 一起的還有&lt;/strong>：regression set（failed case 永遠進、防 fix 一個壞一個）、production trace 抽樣補進 eval set（讓 eval set 不脫節）。&lt;/li>
&lt;li>&lt;strong>失敗模式&lt;/strong>：baseline 跟 production 分佈差太遠（baseline 用 lab case、production 是 wild input）、跑出來分數沒參考價值。緩解：baseline 的 eval set 用 production trace 抽樣建。&lt;/li>
&lt;/ol>
&lt;p>完整 eval 系統設計見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/eval-design-framework/" data-link-title="4.13 Eval 設計座標系：三軸、八象限、何時測什麼" data-link-desc="Eval 設計三軸（objective↔subjective / component↔end-to-end / quantitative↔qualitative）、八象限的對應 eval 工具、軸選錯的訊號、跟 benchmarking / LLM-as-judge / tracing 的關係">4.13 Eval 設計座標系&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Frozen baseline 的核心概念是「<strong>把某個特定 prompt + 特定 model 跑 production 一段時間後 freeze、每次新版本都跟它比、定期 refresh 並標明時點</strong>」。Eval 系統的標準作法、讓行為漂移可見、避免「永遠跟上一版比、長期累積漂移看不見」的常見失敗。</p>
<h2 id="概念位置">概念位置</h2>
<p>跟其他 eval 概念對照：</p>
<table>
  <thead>
      <tr>
          <th>概念</th>
          <th>角色</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Eval set</td>
          <td>測試 input 的集合</td>
      </tr>
      <tr>
          <td>Frozen baseline</td>
          <td>固定的「對照組」prompt + model 版本</td>
      </tr>
      <tr>
          <td>Regression set</td>
          <td>Failed case 進來、防止改 prompt 又壞同樣 case</td>
      </tr>
      <tr>
          <td>Production trace</td>
          <td>實際 traffic、抽樣補進 eval set / baseline</td>
      </tr>
  </tbody>
</table>
<p>工作流：</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">Day 1：定義 eval set + 初始 prompt + model
</span></span><span class="line"><span class="ln">2</span><span class="cl">   ↓ 跑 production 一段時間（如 2 週）
</span></span><span class="line"><span class="ln">3</span><span class="cl">Day 14：把當下 prompt + model freeze 成 baseline-v1
</span></span><span class="line"><span class="ln">4</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln">5</span><span class="cl">新版本 prompt / model 都跟 baseline-v1 比
</span></span><span class="line"><span class="ln">6</span><span class="cl">   ↓ 定期（如每季）refresh
</span></span><span class="line"><span class="ln">7</span><span class="cl">Day 90：baseline-v2、標明 refresh 時點</span></span></code></pre></div><h2 id="設計責任">設計責任</h2>
<p>讀 eval / production AI 文章看到「frozen baseline」「baseline drift」「regression set」就是這個機制。實作判讀：</p>
<ol>
<li><strong>為什麼必要</strong>：每次 A/B 都跟「最新版本」比、長期累積漂移完全不可見、「整體變好了沒」無從回答。Frozen baseline 是漂移的錨點。</li>
<li><strong>何時 freeze</strong>：production 跑穩、user 滿意度可接受時 freeze。太早 freeze 鎖到不夠好的版本、太晚 freeze 鎖不到。</li>
<li><strong>何時 refresh</strong>：定期（每季 / 每半年）、或當 baseline 明顯 obsolete（如 model 升級、產品大改版）。Refresh 後標明時點、舊版本仍可保留當歷史對照。</li>
<li><strong>跟 frozen baseline 一起的還有</strong>：regression set（failed case 永遠進、防 fix 一個壞一個）、production trace 抽樣補進 eval set（讓 eval set 不脫節）。</li>
<li><strong>失敗模式</strong>：baseline 跟 production 分佈差太遠（baseline 用 lab case、production 是 wild input）、跑出來分數沒參考價值。緩解：baseline 的 eval set 用 production trace 抽樣建。</li>
</ol>
<p>完整 eval 系統設計見 <a href="/blog/llm/04-applications/eval-design-framework/" data-link-title="4.13 Eval 設計座標系：三軸、八象限、何時測什麼" data-link-desc="Eval 設計三軸（objective↔subjective / component↔end-to-end / quantitative↔qualitative）、八象限的對應 eval 工具、軸選錯的訊號、跟 benchmarking / LLM-as-judge / tracing 的關係">4.13 Eval 設計座標系</a>。</p>
]]></content:encoded></item><item><title>Goal Drift</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/goal-drift/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/goal-drift/</guid><description>&lt;p>Goal drift（目標漂移）的核心概念是「&lt;strong>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop&lt;/a> 把子目標誤當成整體目標&lt;/strong>」。它常讓模型完成局部步驟後宣告任務完成，實際上還漏掉測試、驗證、提交、回報或其他原始要求。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Goal drift 是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop&lt;/a> 的 termination 失敗。它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/context-drift/" data-link-title="Context Drift" data-link-desc="Agent 長任務中累積上下文逐步偏離原始目標，導致後續行動看似合理但整體跑偏">context drift&lt;/a> 的差異是：context drift 是上下文逐步偏移，goal drift 是完成條件被錯誤替換。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>原任務是「實作、測試、commit」，agent 實作完就回答「已完成」，這是 goal drift。另一個訊號是 agent 每步都在完成一個合理子任務，但沒有維護整體 checklist。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>緩解方式是把完成條件外部化：test pass、檔案存在、PR 開啟、commit hash 產生、人工批准。不要只靠模型自評完成；高風險任務要用 checklist 與 deterministic gate。&lt;/p></description><content:encoded><![CDATA[<p>Goal drift（目標漂移）的核心概念是「<strong><a href="/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop</a> 把子目標誤當成整體目標</strong>」。它常讓模型完成局部步驟後宣告任務完成，實際上還漏掉測試、驗證、提交、回報或其他原始要求。</p>
<h2 id="概念位置">概念位置</h2>
<p>Goal drift 是 <a href="/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop</a> 的 termination 失敗。它跟 <a href="/blog/llm/knowledge-cards/context-drift/" data-link-title="Context Drift" data-link-desc="Agent 長任務中累積上下文逐步偏離原始目標，導致後續行動看似合理但整體跑偏">context drift</a> 的差異是：context drift 是上下文逐步偏移，goal drift 是完成條件被錯誤替換。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>原任務是「實作、測試、commit」，agent 實作完就回答「已完成」，這是 goal drift。另一個訊號是 agent 每步都在完成一個合理子任務，但沒有維護整體 checklist。</p>
<h2 id="設計責任">設計責任</h2>
<p>緩解方式是把完成條件外部化：test pass、檔案存在、PR 開啟、commit hash 產生、人工批准。不要只靠模型自評完成；高風險任務要用 checklist 與 deterministic gate。</p>
]]></content:encoded></item><item><title>Grammar</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/grammar/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/grammar/</guid><description>&lt;p>Grammar（語法規則）的核心概念是「&lt;strong>用形式化規則描述哪些字串是合法輸出&lt;/strong>」。在 LLM structured output 裡，grammar 是 parser / decoder 可以執行的規則集合，用來判斷 JSON、SQL、DSL、表達式或自訂格式是否符合預期形狀——此處的 grammar 指形式語法，而非英文文法。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Grammar 位在格式定義層，常被 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/constrained-decoding/" data-link-title="Constrained Decoding" data-link-desc="推論時用 grammar 強制 LLM 輸出符合特定格式（JSON / regex / CFG）的 sampling 機制、把不合法 token 的機率歸零">constrained decoding&lt;/a> 編譯成 token mask。它跟 schema 的差異在表達方式：schema 常描述資料結構與欄位限制，grammar 描述字串如何從符號規則生成；JSON Schema 適合物件欄位，grammar 適合自訂語言、查詢語法、括號結構與特定文字格式。&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">grammar 規則 → parser / decoder 編譯
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">每個生成位置算出合法 token
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">不合法 token 被 mask 掉&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>看到 &lt;code>expr: term (&amp;quot;+&amp;quot; term)*&lt;/code>、&lt;code>start: object&lt;/code>、&lt;code>&amp;lt;json&amp;gt; ::= ...&lt;/code> 這類規則就是 grammar。例子是讓模型只輸出簡化查詢語言：欄位只能是 &lt;code>status&lt;/code> / &lt;code>owner&lt;/code>，運算子只能是 &lt;code>=&lt;/code> / &lt;code>in&lt;/code>，字串必須加引號；grammar 可以把非法查詢擋在生成階段。&lt;/p>
&lt;p>Grammar 的邊界是語意與外部狀態。它可以限制語法合法，卻不能知道 &lt;code>owner = &amp;quot;alice&amp;quot;&lt;/code> 是否真有這個使用者，也不能判斷查詢是否符合權限；這些仍要交給 validator、authorization 與業務規則。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>需要自訂輸出格式時，先判斷格式是資料結構還是小語言：物件欄位優先用 JSON Schema，小語言或查詢語法才用 grammar。下一步路由是：需要語法表示法讀 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/bnf/" data-link-title="BNF（Backus-Naur Form）" data-link-desc="用遞迴產生式描述語法的經典記法，是 CFG、parser 與 grammar-constrained sampling 常見的基礎表示">BNF&lt;/a> 或 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/lark-grammar/" data-link-title="Lark Grammar" data-link-desc="Lark parser 使用的 EBNF-like grammar 格式，常被 structured output 工具拿來描述自訂輸出語法">Lark Grammar&lt;/a>；需要應用層自訂語言讀 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/dsl/" data-link-title="DSL（Domain-Specific Language）" data-link-desc="為特定業務或技術領域設計的小語言，在 LLM 應用中常作為可解析、可驗證、可執行的中介輸出">DSL&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Grammar（語法規則）的核心概念是「<strong>用形式化規則描述哪些字串是合法輸出</strong>」。在 LLM structured output 裡，grammar 是 parser / decoder 可以執行的規則集合，用來判斷 JSON、SQL、DSL、表達式或自訂格式是否符合預期形狀——此處的 grammar 指形式語法，而非英文文法。</p>
<h2 id="概念位置">概念位置</h2>
<p>Grammar 位在格式定義層，常被 <a href="/blog/llm/knowledge-cards/constrained-decoding/" data-link-title="Constrained Decoding" data-link-desc="推論時用 grammar 強制 LLM 輸出符合特定格式（JSON / regex / CFG）的 sampling 機制、把不合法 token 的機率歸零">constrained decoding</a> 編譯成 token mask。它跟 schema 的差異在表達方式：schema 常描述資料結構與欄位限制，grammar 描述字串如何從符號規則生成；JSON Schema 適合物件欄位，grammar 適合自訂語言、查詢語法、括號結構與特定文字格式。</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">grammar 規則 → parser / decoder 編譯
</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">每個生成位置算出合法 token
</span></span><span class="line"><span class="ln">4</span><span class="cl">  ↓
</span></span><span class="line"><span class="ln">5</span><span class="cl">不合法 token 被 mask 掉</span></span></code></pre></div><h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>看到 <code>expr: term (&quot;+&quot; term)*</code>、<code>start: object</code>、<code>&lt;json&gt; ::= ...</code> 這類規則就是 grammar。例子是讓模型只輸出簡化查詢語言：欄位只能是 <code>status</code> / <code>owner</code>，運算子只能是 <code>=</code> / <code>in</code>，字串必須加引號；grammar 可以把非法查詢擋在生成階段。</p>
<p>Grammar 的邊界是語意與外部狀態。它可以限制語法合法，卻不能知道 <code>owner = &quot;alice&quot;</code> 是否真有這個使用者，也不能判斷查詢是否符合權限；這些仍要交給 validator、authorization 與業務規則。</p>
<h2 id="設計責任">設計責任</h2>
<p>需要自訂輸出格式時，先判斷格式是資料結構還是小語言：物件欄位優先用 JSON Schema，小語言或查詢語法才用 grammar。下一步路由是：需要語法表示法讀 <a href="/blog/llm/knowledge-cards/bnf/" data-link-title="BNF（Backus-Naur Form）" data-link-desc="用遞迴產生式描述語法的經典記法，是 CFG、parser 與 grammar-constrained sampling 常見的基礎表示">BNF</a> 或 <a href="/blog/llm/knowledge-cards/lark-grammar/" data-link-title="Lark Grammar" data-link-desc="Lark parser 使用的 EBNF-like grammar 格式，常被 structured output 工具拿來描述自訂輸出語法">Lark Grammar</a>；需要應用層自訂語言讀 <a href="/blog/llm/knowledge-cards/dsl/" data-link-title="DSL（Domain-Specific Language）" data-link-desc="為特定業務或技術領域設計的小語言，在 LLM 應用中常作為可解析、可驗證、可執行的中介輸出">DSL</a>。</p>
]]></content:encoded></item><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>Guardrail</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/guardrail/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/guardrail/</guid><description>&lt;p>Guardrail 的核心概念是「&lt;strong>在 LLM 的 fuzzy 行為外層加上可驗證的控制邊界&lt;/strong>」。LLM 本身會生成機率性輸出，guardrail 用 deterministic 檢查、policy、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">structured output&lt;/a>、權限與人工審查，把錯誤後果限制在可承擔範圍內。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Guardrail 是一組控制層。常見形式包含 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">structured output&lt;/a>、validator、allowlist、rate limit、sandbox、human approval、eval、monitoring 與 rollback。它通常包在模型輸出與下游副作用之間。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>客服分類可以用 enum schema 限制類別；tool use 可以用 allowlist 限制可呼叫工具；production 操作可以要求 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/human-in-the-loop/" data-link-title="Human-in-the-loop（HITL）" data-link-desc="人類介入 LLM 工作流的設計：三種觸發時機（pre-act / mid-stream / post-hoc）、避免橡皮圖章化的四條件">human-in-the-loop&lt;/a> approval；外部內容進 context 前可以標記為 untrusted，降低 prompt injection 後果。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>設計 guardrail 時先判斷失敗代價，再選控制強度。低風險任務用 schema 與 retry 即可；高副作用任務要加 permission boundary、sandbox、審查與 audit log。相關基礎見 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/deterministic-vs-fuzzy/" data-link-title="Deterministic vs Fuzzy engineering" data-link-desc="LLM 軟體 vs 傳統軟體在資料 / 邏輯 / 行為一致性 / 實驗成本四維度的典範差異、決定哪段該包 guardrail">Deterministic vs Fuzzy engineering&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Guardrail 的核心概念是「<strong>在 LLM 的 fuzzy 行為外層加上可驗證的控制邊界</strong>」。LLM 本身會生成機率性輸出，guardrail 用 deterministic 檢查、policy、<a href="/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">structured output</a>、權限與人工審查，把錯誤後果限制在可承擔範圍內。</p>
<h2 id="概念位置">概念位置</h2>
<p>Guardrail 是一組控制層。常見形式包含 <a href="/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">structured output</a>、validator、allowlist、rate limit、sandbox、human approval、eval、monitoring 與 rollback。它通常包在模型輸出與下游副作用之間。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>客服分類可以用 enum schema 限制類別；tool use 可以用 allowlist 限制可呼叫工具；production 操作可以要求 <a href="/blog/llm/knowledge-cards/human-in-the-loop/" data-link-title="Human-in-the-loop（HITL）" data-link-desc="人類介入 LLM 工作流的設計：三種觸發時機（pre-act / mid-stream / post-hoc）、避免橡皮圖章化的四條件">human-in-the-loop</a> approval；外部內容進 context 前可以標記為 untrusted，降低 prompt injection 後果。</p>
<h2 id="設計責任">設計責任</h2>
<p>設計 guardrail 時先判斷失敗代價，再選控制強度。低風險任務用 schema 與 retry 即可；高副作用任務要加 permission boundary、sandbox、審查與 audit log。相關基礎見 <a href="/blog/llm/knowledge-cards/deterministic-vs-fuzzy/" data-link-title="Deterministic vs Fuzzy engineering" data-link-desc="LLM 軟體 vs 傳統軟體在資料 / 邏輯 / 行為一致性 / 實驗成本四維度的典範差異、決定哪段該包 guardrail">Deterministic vs Fuzzy engineering</a>。</p>
]]></content:encoded></item><item><title>Human-in-the-loop（HITL）</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/human-in-the-loop/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/human-in-the-loop/</guid><description>&lt;p>Human-in-the-loop（HITL）的核心概念是「&lt;strong>人類在 LLM 工作流中介入的設計&lt;/strong>」、用來在 fuzzy AI 行為的關鍵節點插入 deterministic 人類判斷。HITL 不是「有 vs 沒有」的二元、是 spectrum：位置由 risk（副作用範圍 + 失敗代價）跟自動 validator 能力決定。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>HITL 三種觸發時機：&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>Pre-act&lt;/td>
 &lt;td>Action 執行前確認&lt;/td>
 &lt;td>不可逆 / 高代價（DB write、deploy）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Mid-stream&lt;/td>
 &lt;td>Agent 過程中遇不確定主動問&lt;/td>
 &lt;td>路徑分歧、需要 domain judgment&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Post-hoc&lt;/td>
 &lt;td>結果交付後 user 申訴 / 校正&lt;/td>
 &lt;td>評分類、低代價、user 數量大&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>跟其他相關概念對照：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>概念&lt;/th>
 &lt;th>跟 HITL 的關係&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Agent 自主度分層&lt;/td>
 &lt;td>Full auto / checkpoint / step-by-step / plan-first → 對應 HITL 時機&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Tool 副作用範圍&lt;/td>
 &lt;td>等級 1-2 不需 HITL、等級 4-5 強制 HITL&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Guardrail&lt;/td>
 &lt;td>Schema / validator / monitoring 是自動 guardrail、HITL 是人類 guardrail&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 AI 應用設計或 agent paper 看到「HITL」「human-in-the-loop」「approval flow」「appeal」就是這個機制。實作判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>位置由 risk 跟 validator 能力決定&lt;/strong>：risk 高 + validator 弱、HITL 頻率高；risk 低 + validator 強、HITL 頻率低。&lt;/li>
&lt;li>&lt;strong>三時機可組合&lt;/strong>：pre-act 擋高代價、mid-stream 處理 agent 不確定性、post-hoc 收回饋。三者各擋不同 risk class、不互斥。&lt;/li>
&lt;li>&lt;strong>避免橡皮圖章化的四條件&lt;/strong>：分級不同 risk 走不同 gate、approval UI 強制 show diff、reject 有明確 fallback、approval 訊號回饋進系統。任一不滿足、HITL 退化成形式。&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/jagged-frontier/" data-link-title="Jagged frontier" data-link-desc="AI 能力分佈不規則的 framing：某些看似簡單的任務 AI 容易壞、某些看似複雜的任務 AI 反而做得好">jagged frontier&lt;/a> 的關係&lt;/strong>：frontier 外的任務該強制 HITL、不交給 user 自由心證。&lt;/li>
&lt;li>&lt;strong>跟 fuzzy engineering 典範的關係&lt;/strong>：HITL 是 fuzzy 行為的 deterministic guardrail 一種、不是預設要有、看 risk 跟自動 validator 能力決定。&lt;/li>
&lt;/ol>
&lt;p>完整 HITL 拓樸設計見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/human-ai-collaboration/" data-link-title="4.5 人機協作拓樸：何時人介入、怎麼介入" data-link-desc="Centaur vs Cyborg 工作模式、jagged frontier、HITL 三種觸發時機（pre-act / mid-stream / post-hoc）、確認流程的設計避免橡皮圖章化">4.5 人機協作拓樸&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Human-in-the-loop（HITL）的核心概念是「<strong>人類在 LLM 工作流中介入的設計</strong>」、用來在 fuzzy AI 行為的關鍵節點插入 deterministic 人類判斷。HITL 不是「有 vs 沒有」的二元、是 spectrum：位置由 risk（副作用範圍 + 失敗代價）跟自動 validator 能力決定。</p>
<h2 id="概念位置">概念位置</h2>
<p>HITL 三種觸發時機：</p>
<table>
  <thead>
      <tr>
          <th>時機</th>
          <th>介入點</th>
          <th>適合任務</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Pre-act</td>
          <td>Action 執行前確認</td>
          <td>不可逆 / 高代價（DB write、deploy）</td>
      </tr>
      <tr>
          <td>Mid-stream</td>
          <td>Agent 過程中遇不確定主動問</td>
          <td>路徑分歧、需要 domain judgment</td>
      </tr>
      <tr>
          <td>Post-hoc</td>
          <td>結果交付後 user 申訴 / 校正</td>
          <td>評分類、低代價、user 數量大</td>
      </tr>
  </tbody>
</table>
<p>跟其他相關概念對照：</p>
<table>
  <thead>
      <tr>
          <th>概念</th>
          <th>跟 HITL 的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Agent 自主度分層</td>
          <td>Full auto / checkpoint / step-by-step / plan-first → 對應 HITL 時機</td>
      </tr>
      <tr>
          <td>Tool 副作用範圍</td>
          <td>等級 1-2 不需 HITL、等級 4-5 強制 HITL</td>
      </tr>
      <tr>
          <td>Guardrail</td>
          <td>Schema / validator / monitoring 是自動 guardrail、HITL 是人類 guardrail</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 AI 應用設計或 agent paper 看到「HITL」「human-in-the-loop」「approval flow」「appeal」就是這個機制。實作判讀：</p>
<ol>
<li><strong>位置由 risk 跟 validator 能力決定</strong>：risk 高 + validator 弱、HITL 頻率高；risk 低 + validator 強、HITL 頻率低。</li>
<li><strong>三時機可組合</strong>：pre-act 擋高代價、mid-stream 處理 agent 不確定性、post-hoc 收回饋。三者各擋不同 risk class、不互斥。</li>
<li><strong>避免橡皮圖章化的四條件</strong>：分級不同 risk 走不同 gate、approval UI 強制 show diff、reject 有明確 fallback、approval 訊號回饋進系統。任一不滿足、HITL 退化成形式。</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/jagged-frontier/" data-link-title="Jagged frontier" data-link-desc="AI 能力分佈不規則的 framing：某些看似簡單的任務 AI 容易壞、某些看似複雜的任務 AI 反而做得好">jagged frontier</a> 的關係</strong>：frontier 外的任務該強制 HITL、不交給 user 自由心證。</li>
<li><strong>跟 fuzzy engineering 典範的關係</strong>：HITL 是 fuzzy 行為的 deterministic guardrail 一種、不是預設要有、看 risk 跟自動 validator 能力決定。</li>
</ol>
<p>完整 HITL 拓樸設計見 <a href="/blog/llm/04-applications/human-ai-collaboration/" data-link-title="4.5 人機協作拓樸：何時人介入、怎麼介入" data-link-desc="Centaur vs Cyborg 工作模式、jagged frontier、HITL 三種觸發時機（pre-act / mid-stream / post-hoc）、確認流程的設計避免橡皮圖章化">4.5 人機協作拓樸</a>。</p>
]]></content:encoded></item><item><title>HyDE（Hypothetical Document Embeddings）</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/hyde/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/hyde/</guid><description>&lt;p>HyDE（Hypothetical Document Embeddings、Gao et al. 2022）是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> retrieval 階段的 query 端增強技術。核心觀察：&lt;strong>query 跟 document 在 embedding 空間的距離往往比 document 跟 document 之間更遠&lt;/strong>——這是典型 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap&lt;/a>。HyDE 的做法是先用 LLM 對 query 生成「假設的答案文件」、對假文件做 embedding 拿去 retrieve、而不是直接 embed 原 query。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>HyDE 三步：&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">User query
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">[Step 1] LLM 生成 hypothetical document
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> (可能 hallucinate、事實正確性不重要)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">[Step 2] Embed 假文件
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">[Step 3] 用假文件 embedding 去 vector DB retrieve 真文件
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">真實 top-k chunks → 主 LLM 回答&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>為什麼比直接 embed query 好：假文件的 phrasing、長度、結構都更接近真文件的分佈、embedding 距離更可靠。重點是&lt;strong>假文件當 embedding 的代理&lt;/strong>、不是當答案——hallucinate 出錯誤事實 OK、但語意 / 領域要落對。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 RAG paper 或工具看到「HyDE」「hypothetical document」「query-side augmentation」就是這個機制。實作判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>適用 phrasing 落差顯著的場景&lt;/strong>：問句 vs 陳述、口語 vs 正式、抽象 vs 技術詞彙。HyDE 原論文跨多領域都有提升、不限技術 / 學術。&lt;/li>
&lt;li>&lt;strong>失效在假文件偏離主題&lt;/strong>：LLM hallucinate 到別領域、retrieve 拿到完全不相關的東西。緩解：生成多個假文件取平均 embedding、或用 query + 假文件兩個 embedding 合併 retrieve。&lt;/li>
&lt;li>&lt;strong>Cost&lt;/strong>：每 query 多一個 LLM call（生假文件）、latency 加 500ms-1s，屬於明顯的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost&lt;/a>。對 latency 敏感場景考慮 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-rewriting/" data-link-title="Query Rewriting" data-link-desc="在 RAG 檢索前改寫使用者查詢，讓 query 更接近文件語言與索引分佈">query rewriting&lt;/a> 等較輕量的替代。&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/hybrid-search/" data-link-title="Hybrid Search" data-link-desc="把字面 retrieval（BM25）跟語意 retrieval（embedding）的結果用 RRF 等方法合併、補單一路線的盲點">hybrid search&lt;/a> 互補&lt;/strong>：HyDE 解語意 phrasing 落差、hybrid 解語意 / 字面互補、可以同時用。&lt;/li>
&lt;/ol>
&lt;p>完整 RAG 檢索增強技術 landscape 見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/rag-retrieval-enhancements/" data-link-title="4.2 RAG 檢索增強：query rewriting / HyDE / multi-step / context packing" data-link-desc="Query 端增強（rewriting / expansion / HyDE）、multi-step iterative retrieval、retrieve 後的 context packing（dedup / ordering / summarization）、adaptive retrieval：vanilla RAG 不夠時的下一層工具箱">4.2 RAG 檢索增強&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>HyDE（Hypothetical Document Embeddings、Gao et al. 2022）是 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> retrieval 階段的 query 端增強技術。核心觀察：<strong>query 跟 document 在 embedding 空間的距離往往比 document 跟 document 之間更遠</strong>——這是典型 <a href="/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap</a>。HyDE 的做法是先用 LLM 對 query 生成「假設的答案文件」、對假文件做 embedding 拿去 retrieve、而不是直接 embed 原 query。</p>
<h2 id="概念位置">概念位置</h2>
<p>HyDE 三步：</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">User query
</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">[Step 1] LLM 生成 hypothetical document
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">         (可能 hallucinate、事實正確性不重要)
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">[Step 2] Embed 假文件
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">[Step 3] 用假文件 embedding 去 vector DB retrieve 真文件
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln">10</span><span class="cl">真實 top-k chunks → 主 LLM 回答</span></span></code></pre></div><p>為什麼比直接 embed query 好：假文件的 phrasing、長度、結構都更接近真文件的分佈、embedding 距離更可靠。重點是<strong>假文件當 embedding 的代理</strong>、不是當答案——hallucinate 出錯誤事實 OK、但語意 / 領域要落對。</p>
<h2 id="設計責任">設計責任</h2>
<p>讀 RAG paper 或工具看到「HyDE」「hypothetical document」「query-side augmentation」就是這個機制。實作判讀：</p>
<ol>
<li><strong>適用 phrasing 落差顯著的場景</strong>：問句 vs 陳述、口語 vs 正式、抽象 vs 技術詞彙。HyDE 原論文跨多領域都有提升、不限技術 / 學術。</li>
<li><strong>失效在假文件偏離主題</strong>：LLM hallucinate 到別領域、retrieve 拿到完全不相關的東西。緩解：生成多個假文件取平均 embedding、或用 query + 假文件兩個 embedding 合併 retrieve。</li>
<li><strong>Cost</strong>：每 query 多一個 LLM call（生假文件）、latency 加 500ms-1s，屬於明顯的 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a>。對 latency 敏感場景考慮 <a href="/blog/llm/knowledge-cards/query-rewriting/" data-link-title="Query Rewriting" data-link-desc="在 RAG 檢索前改寫使用者查詢，讓 query 更接近文件語言與索引分佈">query rewriting</a> 等較輕量的替代。</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/hybrid-search/" data-link-title="Hybrid Search" data-link-desc="把字面 retrieval（BM25）跟語意 retrieval（embedding）的結果用 RRF 等方法合併、補單一路線的盲點">hybrid search</a> 互補</strong>：HyDE 解語意 phrasing 落差、hybrid 解語意 / 字面互補、可以同時用。</li>
</ol>
<p>完整 RAG 檢索增強技術 landscape 見 <a href="/blog/llm/04-applications/rag-retrieval-enhancements/" data-link-title="4.2 RAG 檢索增強：query rewriting / HyDE / multi-step / context packing" data-link-desc="Query 端增強（rewriting / expansion / HyDE）、multi-step iterative retrieval、retrieve 後的 context packing（dedup / ordering / summarization）、adaptive retrieval：vanilla RAG 不夠時的下一層工具箱">4.2 RAG 檢索增強</a>。</p>
]]></content:encoded></item><item><title>In-Context Learning</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/in-context-learning/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/in-context-learning/</guid><description>&lt;p>In-context learning（ICL）的核心概念是「&lt;strong>模型在不更新權重的情況下，從 &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> 內資訊臨時學會任務格式與判準&lt;/strong>」。它是 LLM 跟傳統模型最不同的能力之一：任務規則可以放在 context 裡，而不是一定要 fine-tune 進權重。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>ICL 是推論時行為，不是訓練流程。&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/few-shot-prompting/" data-link-title="Few-shot prompting" data-link-desc="在 prompt 內塞 input-output 範例對齊任務、不動模型權重的 in-context learning 技術">Few-shot prompting&lt;/a> 是 ICL 最常見的操作方式；SFT、LoRA、QLoRA 則是修改權重的訓練或微調方式。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>給模型三個分類範例後，第四個樣本就按同一標準分類，這是 ICL。把專案命名規則、輸出格式、review rubric 放進 prompt，模型在當次回合遵守，也屬於 ICL。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>ICL 適合快速迭代與少量範例；當範例多到吃滿 &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>、每天重複使用且標準穩定時，再考慮 fine-tune。需要穩定輸出格式時，ICL 應搭配 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">structured output&lt;/a> 或 validator。&lt;/p></description><content:encoded><![CDATA[<p>In-context learning（ICL）的核心概念是「<strong>模型在不更新權重的情況下，從 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a> 內資訊臨時學會任務格式與判準</strong>」。它是 LLM 跟傳統模型最不同的能力之一：任務規則可以放在 context 裡，而不是一定要 fine-tune 進權重。</p>
<h2 id="概念位置">概念位置</h2>
<p>ICL 是推論時行為，不是訓練流程。<a href="/blog/llm/knowledge-cards/few-shot-prompting/" data-link-title="Few-shot prompting" data-link-desc="在 prompt 內塞 input-output 範例對齊任務、不動模型權重的 in-context learning 技術">Few-shot prompting</a> 是 ICL 最常見的操作方式；SFT、LoRA、QLoRA 則是修改權重的訓練或微調方式。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>給模型三個分類範例後，第四個樣本就按同一標準分類，這是 ICL。把專案命名規則、輸出格式、review rubric 放進 prompt，模型在當次回合遵守，也屬於 ICL。</p>
<h2 id="設計責任">設計責任</h2>
<p>ICL 適合快速迭代與少量範例；當範例多到吃滿 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a>、每天重複使用且標準穩定時，再考慮 fine-tune。需要穩定輸出格式時，ICL 應搭配 <a href="/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">structured output</a> 或 validator。</p>
]]></content:encoded></item><item><title>Instruction Following</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/instruction-following/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/instruction-following/</guid><description>&lt;p>Instruction following 的核心概念是「&lt;strong>模型能否遵守使用者或系統給定的任務約束&lt;/strong>」。它關注模型是否照格式輸出、是否留在任務範圍、是否遵守長度與禁止事項，跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/instruction-tuned/" data-link-title="Instruction-Tuned Model" data-link-desc="經過指令微調的模型：會跟著 prompt 走、回答使用者問題">instruction-tuned model&lt;/a> 這種訓練後模型類型相關，但不是同一件事。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/instruction-tuned/" data-link-title="Instruction-Tuned Model" data-link-desc="經過指令微調的模型：會跟著 prompt 走、回答使用者問題">Instruction-tuned model&lt;/a> 是訓練狀態，instruction following 是行為表現。模型可能經過 SFT，仍在細格式、邊界條件或多約束任務上失敗；也可能在簡單指令上表現穩定，但遇到衝突指令或長 prompt 漏掉限制。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>測試訊號包含：是否輸出指定 JSON、是否只回答要求的欄位、是否避免多餘解釋、是否在資料不足時說不知道、是否遵守「不要呼叫工具」或「只讀不寫」。本地小模型常在簡單問答可用，但在多條格式限制同時存在時掉分。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>評估 instruction following 時要做 coverage 測試：格式、長度、拒答、資料不足、衝突指令、跨語言指令都要看。失敗時優先用更清楚的 prompt、few-shot、structured output 或 validator 兜底；長期穩定需求才考慮 fine-tune。&lt;/p></description><content:encoded><![CDATA[<p>Instruction following 的核心概念是「<strong>模型能否遵守使用者或系統給定的任務約束</strong>」。它關注模型是否照格式輸出、是否留在任務範圍、是否遵守長度與禁止事項，跟 <a href="/blog/llm/knowledge-cards/instruction-tuned/" data-link-title="Instruction-Tuned Model" data-link-desc="經過指令微調的模型：會跟著 prompt 走、回答使用者問題">instruction-tuned model</a> 這種訓練後模型類型相關，但不是同一件事。</p>
<h2 id="概念位置">概念位置</h2>
<p><a href="/blog/llm/knowledge-cards/instruction-tuned/" data-link-title="Instruction-Tuned Model" data-link-desc="經過指令微調的模型：會跟著 prompt 走、回答使用者問題">Instruction-tuned model</a> 是訓練狀態，instruction following 是行為表現。模型可能經過 SFT，仍在細格式、邊界條件或多約束任務上失敗；也可能在簡單指令上表現穩定，但遇到衝突指令或長 prompt 漏掉限制。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>測試訊號包含：是否輸出指定 JSON、是否只回答要求的欄位、是否避免多餘解釋、是否在資料不足時說不知道、是否遵守「不要呼叫工具」或「只讀不寫」。本地小模型常在簡單問答可用，但在多條格式限制同時存在時掉分。</p>
<h2 id="設計責任">設計責任</h2>
<p>評估 instruction following 時要做 coverage 測試：格式、長度、拒答、資料不足、衝突指令、跨語言指令都要看。失敗時優先用更清楚的 prompt、few-shot、structured output 或 validator 兜底；長期穩定需求才考慮 fine-tune。</p>
]]></content:encoded></item><item><title>Jagged frontier</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/jagged-frontier/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/jagged-frontier/</guid><description>&lt;p>Jagged frontier（鋸齒狀邊界、HBS / UPenn / Wharton BCG 顧問研究、2023）是 AI 能力分佈的 framing：&lt;strong>「AI 能做的任務」呈鋸齒狀分佈，而非按人類直覺的難易連續排列&lt;/strong>——某些看起來簡單的任務 AI 容易壞、某些看起來複雜的任務 AI 反而做得好。原因是能力分佈跟訓練資料 / tokenizer / 推論機制相關、不跟人類直覺的「難易」對齊。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>典型對照（2024-2025 觀察、會隨模型升級漂移）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>看起來簡單但 AI 容易壞&lt;/th>
 &lt;th>看起來複雜但 AI 做得好&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>精確算術&lt;/td>
 &lt;td>寫風格指定的程式碼&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>計數&lt;/td>
 &lt;td>翻譯複雜技術文章&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>嚴格遵守冷僻格式&lt;/td>
 &lt;td>從文字抽取關鍵 entity&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>引用真實 URL&lt;/td>
 &lt;td>解釋複雜概念&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>各失敗的機制各不相同：算術靠符號操作 + tokenizer 把數字切碎、計數跟 attention 機制不對盤、冷僻格式不在訓練分佈中、URL &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/hallucination/" data-link-title="Hallucination" data-link-desc="LLM 生成內容看起來合理但事實錯誤、引用不存在的來源、虛構不存在的 entity 的現象">hallucination&lt;/a> 是模型分辨不了「真實 vs 看起來合理」。Reasoning model + tool use 普及後 frontier 會移動、表的價值在 framing「不規則」、不是具體 4 個 case 當定論。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 AI 應用設計文章看到「jagged frontier」「AI capability boundary」「falling asleep at the wheel」就是這個 framing。設計判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>不要用人類直覺難易推測 AI 能力&lt;/strong>：試跑、看結果、不要預判。&lt;/li>
&lt;li>&lt;strong>「全自動」是 over-trust 假設&lt;/strong>：frontier 鋸齒、總有些子任務落 frontier 外、需要人介入或 tool 補。設計時假設「有部分子任務 AI 會失敗」、不是「都會成功」。&lt;/li>
&lt;li>&lt;strong>失敗在 frontier 外加 prompt iteration 通常無效&lt;/strong>：那是模型能力邊界問題、不是 prompt 問題。對應 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/prompt-techniques-landscape/" data-link-title="4.0 Prompt 技術光譜：手法分類、取捨、組合模式" data-link-desc="Zero-shot / few-shot、chain-of-thought、role / template、reflection 等 prompt 技術的分類與取捨、何時 stack 何時不要 stack、跟 fine-tune / RAG / chaining 的邊界">prompt 技術光譜&lt;/a> 的 systematic vs random error 診斷。&lt;/li>
&lt;li>&lt;strong>Falling asleep at the wheel&lt;/strong>：BCG 研究觀察到的人類行為——傾向不分辨任務是否在 frontier 內、對 AI 結果一律低度審查。緩解：對團隊 / user 明確標 frontier、frontier 外任務強制人類審查（HITL）、抽樣審查偵測 frontier 漂移。&lt;/li>
&lt;/ol>
&lt;p>完整人機協作 framing 見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/human-ai-collaboration/" data-link-title="4.5 人機協作拓樸：何時人介入、怎麼介入" data-link-desc="Centaur vs Cyborg 工作模式、jagged frontier、HITL 三種觸發時機（pre-act / mid-stream / post-hoc）、確認流程的設計避免橡皮圖章化">4.5 人機協作拓樸&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Jagged frontier（鋸齒狀邊界、HBS / UPenn / Wharton BCG 顧問研究、2023）是 AI 能力分佈的 framing：<strong>「AI 能做的任務」呈鋸齒狀分佈，而非按人類直覺的難易連續排列</strong>——某些看起來簡單的任務 AI 容易壞、某些看起來複雜的任務 AI 反而做得好。原因是能力分佈跟訓練資料 / tokenizer / 推論機制相關、不跟人類直覺的「難易」對齊。</p>
<h2 id="概念位置">概念位置</h2>
<p>典型對照（2024-2025 觀察、會隨模型升級漂移）：</p>
<table>
  <thead>
      <tr>
          <th>看起來簡單但 AI 容易壞</th>
          <th>看起來複雜但 AI 做得好</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>精確算術</td>
          <td>寫風格指定的程式碼</td>
      </tr>
      <tr>
          <td>計數</td>
          <td>翻譯複雜技術文章</td>
      </tr>
      <tr>
          <td>嚴格遵守冷僻格式</td>
          <td>從文字抽取關鍵 entity</td>
      </tr>
      <tr>
          <td>引用真實 URL</td>
          <td>解釋複雜概念</td>
      </tr>
  </tbody>
</table>
<p>各失敗的機制各不相同：算術靠符號操作 + tokenizer 把數字切碎、計數跟 attention 機制不對盤、冷僻格式不在訓練分佈中、URL <a href="/blog/llm/knowledge-cards/hallucination/" data-link-title="Hallucination" data-link-desc="LLM 生成內容看起來合理但事實錯誤、引用不存在的來源、虛構不存在的 entity 的現象">hallucination</a> 是模型分辨不了「真實 vs 看起來合理」。Reasoning model + tool use 普及後 frontier 會移動、表的價值在 framing「不規則」、不是具體 4 個 case 當定論。</p>
<h2 id="設計責任">設計責任</h2>
<p>讀 AI 應用設計文章看到「jagged frontier」「AI capability boundary」「falling asleep at the wheel」就是這個 framing。設計判讀：</p>
<ol>
<li><strong>不要用人類直覺難易推測 AI 能力</strong>：試跑、看結果、不要預判。</li>
<li><strong>「全自動」是 over-trust 假設</strong>：frontier 鋸齒、總有些子任務落 frontier 外、需要人介入或 tool 補。設計時假設「有部分子任務 AI 會失敗」、不是「都會成功」。</li>
<li><strong>失敗在 frontier 外加 prompt iteration 通常無效</strong>：那是模型能力邊界問題、不是 prompt 問題。對應 <a href="/blog/llm/04-applications/prompt-techniques-landscape/" data-link-title="4.0 Prompt 技術光譜：手法分類、取捨、組合模式" data-link-desc="Zero-shot / few-shot、chain-of-thought、role / template、reflection 等 prompt 技術的分類與取捨、何時 stack 何時不要 stack、跟 fine-tune / RAG / chaining 的邊界">prompt 技術光譜</a> 的 systematic vs random error 診斷。</li>
<li><strong>Falling asleep at the wheel</strong>：BCG 研究觀察到的人類行為——傾向不分辨任務是否在 frontier 內、對 AI 結果一律低度審查。緩解：對團隊 / user 明確標 frontier、frontier 外任務強制人類審查（HITL）、抽樣審查偵測 frontier 漂移。</li>
</ol>
<p>完整人機協作 framing 見 <a href="/blog/llm/04-applications/human-ai-collaboration/" data-link-title="4.5 人機協作拓樸：何時人介入、怎麼介入" data-link-desc="Centaur vs Cyborg 工作模式、jagged frontier、HITL 三種觸發時機（pre-act / mid-stream / post-hoc）、確認流程的設計避免橡皮圖章化">4.5 人機協作拓樸</a>。</p>
]]></content:encoded></item><item><title>Lark Grammar</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/lark-grammar/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/lark-grammar/</guid><description>&lt;p>Lark grammar 的核心概念是「&lt;strong>Lark parser 使用的一種 EBNF-like 語法描述格式&lt;/strong>」。在 LLM structured output 文件中看到 lark grammar，通常是在說某個工具用 Lark 風格規則描述合法輸出，再把規則交給 parser 或 constrained decoding engine。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Lark 是 Python 生態的 parsing toolkit，Lark grammar 是它的規則語言。它比傳統 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/bnf/" data-link-title="BNF（Backus-Naur Form）" data-link-desc="用遞迴產生式描述語法的經典記法，是 CFG、parser 與 grammar-constrained sampling 常見的基礎表示">BNF&lt;/a> 更接近實作格式，常見元素包含 rule、terminal、literal、repeat、optional、ignore whitespace 與 start rule。&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">start: query
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">query: FIELD OP VALUE
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">FIELD: &amp;#34;status&amp;#34; | &amp;#34;owner&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">OP: &amp;#34;=&amp;#34; | &amp;#34;!=&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">VALUE: ESCAPED_STRING
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">%import common.ESCAPED_STRING
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">%ignore &amp;#34; &amp;#34;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>這段規則描述一個很小的查詢語言，只允許固定欄位、固定運算子與 quoted string。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>看到 &lt;code>start:&lt;/code>、大寫 terminal、&lt;code>%import common.*&lt;/code>、&lt;code>%ignore&lt;/code>，通常就是 Lark grammar 或受它影響的格式。LLM 場景常用它描述 JSON 子集、SQL-like query、指令 DSL、分類輸出或固定格式報告。&lt;/p>
&lt;p>Lark grammar 的風險是把 parser 格式誤當跨引擎標準。某些 constrained decoding 工具支援 Lark-like 語法，某些只支援 JSON Schema、regex、GBNF 或自家格式；搬規則前要確認目標 server 能不能解析同一套語法。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Lark grammar 適合需要清楚描述自訂格式、且工具鏈支援 Lark dialect 的場景。設計時先把合法範圍縮到應用真的需要的語法，再補 validator 處理外部狀態與權限。下一步路由是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">Grammar&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/dsl/" data-link-title="DSL（Domain-Specific Language）" data-link-desc="為特定業務或技術領域設計的小語言，在 LLM 應用中常作為可解析、可驗證、可執行的中介輸出">DSL&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Lark grammar 的核心概念是「<strong>Lark parser 使用的一種 EBNF-like 語法描述格式</strong>」。在 LLM structured output 文件中看到 lark grammar，通常是在說某個工具用 Lark 風格規則描述合法輸出，再把規則交給 parser 或 constrained decoding engine。</p>
<h2 id="概念位置">概念位置</h2>
<p>Lark 是 Python 生態的 parsing toolkit，Lark grammar 是它的規則語言。它比傳統 <a href="/blog/llm/knowledge-cards/bnf/" data-link-title="BNF（Backus-Naur Form）" data-link-desc="用遞迴產生式描述語法的經典記法，是 CFG、parser 與 grammar-constrained sampling 常見的基礎表示">BNF</a> 更接近實作格式，常見元素包含 rule、terminal、literal、repeat、optional、ignore whitespace 與 start rule。</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">start: query
</span></span><span class="line"><span class="ln">2</span><span class="cl">query: FIELD OP VALUE
</span></span><span class="line"><span class="ln">3</span><span class="cl">FIELD: &#34;status&#34; | &#34;owner&#34;
</span></span><span class="line"><span class="ln">4</span><span class="cl">OP: &#34;=&#34; | &#34;!=&#34;
</span></span><span class="line"><span class="ln">5</span><span class="cl">VALUE: ESCAPED_STRING
</span></span><span class="line"><span class="ln">6</span><span class="cl">%import common.ESCAPED_STRING
</span></span><span class="line"><span class="ln">7</span><span class="cl">%ignore &#34; &#34;</span></span></code></pre></div><p>這段規則描述一個很小的查詢語言，只允許固定欄位、固定運算子與 quoted string。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>看到 <code>start:</code>、大寫 terminal、<code>%import common.*</code>、<code>%ignore</code>，通常就是 Lark grammar 或受它影響的格式。LLM 場景常用它描述 JSON 子集、SQL-like query、指令 DSL、分類輸出或固定格式報告。</p>
<p>Lark grammar 的風險是把 parser 格式誤當跨引擎標準。某些 constrained decoding 工具支援 Lark-like 語法，某些只支援 JSON Schema、regex、GBNF 或自家格式；搬規則前要確認目標 server 能不能解析同一套語法。</p>
<h2 id="設計責任">設計責任</h2>
<p>Lark grammar 適合需要清楚描述自訂格式、且工具鏈支援 Lark dialect 的場景。設計時先把合法範圍縮到應用真的需要的語法，再補 validator 處理外部狀態與權限。下一步路由是 <a href="/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">Grammar</a> 與 <a href="/blog/llm/knowledge-cards/dsl/" data-link-title="DSL（Domain-Specific Language）" data-link-desc="為特定業務或技術領域設計的小語言，在 LLM 應用中常作為可解析、可驗證、可執行的中介輸出">DSL</a>。</p>
]]></content:encoded></item><item><title>llama.cpp Tensor Split</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/llama-cpp-tensor-split/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/llama-cpp-tensor-split/</guid><description>&lt;p>llama.cpp tensor split 的核心概念是「&lt;strong>在多 GPU 推論時，把模型張量按比例分配到不同 GPU&lt;/strong>」。它解的是單張卡 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/vram/" data-link-title="VRAM" data-link-desc="顯卡上的記憶體、跟系統 RAM 是兩塊獨立預算、決定能載入多大模型權重跟 KV cache">VRAM&lt;/a> 不足或多卡容量不均時的模型權重擺放問題。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Tensor split 位在 inference server / GPU serving 層，跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/nvlink/" data-link-title="NVLink" data-link-desc="NVIDIA 多 GPU 之間的高速互連介面、提供比 PCIe 更高的卡間頻寬、消費級 RTX 系列普遍不支援">NVLink&lt;/a> 或 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/pcie/" data-link-title="PCIe" data-link-desc="PC 上連接 GPU 跟主機板的高速序列匯流排、影響模型載入速度跟 MoE 卸載時的推論吞吐">PCIe&lt;/a> 是不同責任：互連決定卡間傳輸成本，tensor split 決定權重怎麼分布。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>在 llama.cpp 看到 &lt;code>--tensor-split&lt;/code> 或 &lt;code>-ts&lt;/code>，通常是在手動指定多卡分配比例。兩張 VRAM 不同的卡可以用不同比例，避免小卡先 OOM。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>只有多 GPU 且需要手動控制分配時才需要它。單卡消費級 PC 通常不用；多卡沒有高速互連時，分割模型可能降低速度，需用實際 benchmark 校準。&lt;/p></description><content:encoded><![CDATA[<p>llama.cpp tensor split 的核心概念是「<strong>在多 GPU 推論時，把模型張量按比例分配到不同 GPU</strong>」。它解的是單張卡 <a href="/blog/llm/knowledge-cards/vram/" data-link-title="VRAM" data-link-desc="顯卡上的記憶體、跟系統 RAM 是兩塊獨立預算、決定能載入多大模型權重跟 KV cache">VRAM</a> 不足或多卡容量不均時的模型權重擺放問題。</p>
<h2 id="概念位置">概念位置</h2>
<p>Tensor split 位在 inference server / GPU serving 層，跟 <a href="/blog/llm/knowledge-cards/nvlink/" data-link-title="NVLink" data-link-desc="NVIDIA 多 GPU 之間的高速互連介面、提供比 PCIe 更高的卡間頻寬、消費級 RTX 系列普遍不支援">NVLink</a> 或 <a href="/blog/llm/knowledge-cards/pcie/" data-link-title="PCIe" data-link-desc="PC 上連接 GPU 跟主機板的高速序列匯流排、影響模型載入速度跟 MoE 卸載時的推論吞吐">PCIe</a> 是不同責任：互連決定卡間傳輸成本，tensor split 決定權重怎麼分布。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>在 llama.cpp 看到 <code>--tensor-split</code> 或 <code>-ts</code>，通常是在手動指定多卡分配比例。兩張 VRAM 不同的卡可以用不同比例，避免小卡先 OOM。</p>
<h2 id="設計責任">設計責任</h2>
<p>只有多 GPU 且需要手動控制分配時才需要它。單卡消費級 PC 通常不用；多卡沒有高速互連時，分割模型可能降低速度，需用實際 benchmark 校準。</p>
]]></content:encoded></item><item><title>Local vs Cloud LLM</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/local-vs-cloud/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/local-vs-cloud/</guid><description>&lt;p>Local vs cloud LLM 的核心概念是「&lt;strong>把模型執行位置視為工程取捨，而不是信仰選擇&lt;/strong>」。本地 LLM 把資料、權重與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/inference-server/" data-link-title="Inference Server" data-link-desc="載入模型權重、處理 prompt、產生 token 的常駐 process">推論伺服器&lt;/a> 放在自己的機器上；雲端 LLM 把 serving 與模型能力交給 provider，換取更強模型與更低維運負擔。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>這個決策跨越 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/three-layer-architecture/" data-link-title="Three-Layer Architecture" data-link-desc="把本地 LLM 工具拆成介面層、推論伺服器層、模型權重層的基礎心智模型">three-layer architecture&lt;/a> 的所有層：介面可以相同，伺服器與模型位置不同。常見組合是同一個 IDE 介面同時接本地 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/openai-compatible-api/" data-link-title="OpenAI 相容 API" data-link-desc="本地推論伺服器跟雲端 OpenAI 共用的 API 形狀標準">OpenAI 相容 API&lt;/a> 與雲端 API，依任務切換。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>本地適合私有資料、離線、可控成本、低資料外流風險；雲端適合高難度 reasoning、大型 agent、多模態、需要最新旗艦能力的任務。混合策略常見於 coding：本地做補完、摘要、低風險查詢，雲端處理複雜修復與大型 agent loop。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>判斷時看五個訊號：資料敏感度、模型能力需求、延遲體感、每月成本、維運能力。當任務失敗代價高且能力要求高，雲端未必可替代人工審查；當資料敏感且任務簡單，本地模型通常更划算。完整框架見 &lt;a href="https://tarrragon.github.io/blog/llm/00-foundations/local-vs-cloud/" data-link-title="0.0 本地 vs 雲端 LLM" data-link-desc="從隱私、成本、速度、能力四個維度建立本地與雲端 LLM 的基本對照">0.6 本地 vs 雲端&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Local vs cloud LLM 的核心概念是「<strong>把模型執行位置視為工程取捨，而不是信仰選擇</strong>」。本地 LLM 把資料、權重與 <a href="/blog/llm/knowledge-cards/inference-server/" data-link-title="Inference Server" data-link-desc="載入模型權重、處理 prompt、產生 token 的常駐 process">推論伺服器</a> 放在自己的機器上；雲端 LLM 把 serving 與模型能力交給 provider，換取更強模型與更低維運負擔。</p>
<h2 id="概念位置">概念位置</h2>
<p>這個決策跨越 <a href="/blog/llm/knowledge-cards/three-layer-architecture/" data-link-title="Three-Layer Architecture" data-link-desc="把本地 LLM 工具拆成介面層、推論伺服器層、模型權重層的基礎心智模型">three-layer architecture</a> 的所有層：介面可以相同，伺服器與模型位置不同。常見組合是同一個 IDE 介面同時接本地 <a href="/blog/llm/knowledge-cards/openai-compatible-api/" data-link-title="OpenAI 相容 API" data-link-desc="本地推論伺服器跟雲端 OpenAI 共用的 API 形狀標準">OpenAI 相容 API</a> 與雲端 API，依任務切換。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>本地適合私有資料、離線、可控成本、低資料外流風險；雲端適合高難度 reasoning、大型 agent、多模態、需要最新旗艦能力的任務。混合策略常見於 coding：本地做補完、摘要、低風險查詢，雲端處理複雜修復與大型 agent loop。</p>
<h2 id="設計責任">設計責任</h2>
<p>判斷時看五個訊號：資料敏感度、模型能力需求、延遲體感、每月成本、維運能力。當任務失敗代價高且能力要求高，雲端未必可替代人工審查；當資料敏感且任務簡單，本地模型通常更划算。完整框架見 <a href="/blog/llm/00-foundations/local-vs-cloud/" data-link-title="0.0 本地 vs 雲端 LLM" data-link-desc="從隱私、成本、速度、能力四個維度建立本地與雲端 LLM 的基本對照">0.6 本地 vs 雲端</a>。</p>
]]></content:encoded></item><item><title>Model Supply-Chain Trust</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/model-supply-chain-trust/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/model-supply-chain-trust/</guid><description>&lt;p>Model supply-chain trust 的核心概念是「&lt;strong>把模型權重來源、量化者、registry 與本機檔案都視為信任邊界&lt;/strong>」。本地 LLM 下載的是可影響模型行為的 &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> 或其他權重檔，來源與完整性會直接影響安全與可靠性。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>它位在模型層與安全治理交界，跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/model-card/" data-link-title="Model Card" data-link-desc="Hugging Face 等平台上模型的 metadata 文件、列出模型來源、訓練資料、能力、限制、授權">model card&lt;/a> 不同：model card 提供 metadata，supply-chain trust 判斷來源、hash、量化流程、namespace 與散發路徑是否可信。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>官方 organization、知名量化者、verified registry、可比對 hash、清楚 license 與 model card 都提升信任；個人上傳、來源不明、檔案被替換、缺 metadata 都降低信任。GGUF、Safetensors、Ollama registry、Hugging Face Hub 都在這條鏈上。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>下載模型前確認來源；下載後記錄 SHA-256、檔案大小與版本；第三方量化要看量化者信譽與社群採用。MCP server 與 plugin 是另一條可執行程式碼供應鏈，要用更高權限標準判讀。&lt;/p></description><content:encoded><![CDATA[<p>Model supply-chain trust 的核心概念是「<strong>把模型權重來源、量化者、registry 與本機檔案都視為信任邊界</strong>」。本地 LLM 下載的是可影響模型行為的 <a href="/blog/llm/knowledge-cards/gguf/" data-link-title="GGUF" data-link-desc="llama.cpp 生態定義的模型權重格式：把權重、tokenizer、metadata 打包成單一檔案">GGUF</a> 或其他權重檔，來源與完整性會直接影響安全與可靠性。</p>
<h2 id="概念位置">概念位置</h2>
<p>它位在模型層與安全治理交界，跟 <a href="/blog/llm/knowledge-cards/model-card/" data-link-title="Model Card" data-link-desc="Hugging Face 等平台上模型的 metadata 文件、列出模型來源、訓練資料、能力、限制、授權">model card</a> 不同：model card 提供 metadata，supply-chain trust 判斷來源、hash、量化流程、namespace 與散發路徑是否可信。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>官方 organization、知名量化者、verified registry、可比對 hash、清楚 license 與 model card 都提升信任；個人上傳、來源不明、檔案被替換、缺 metadata 都降低信任。GGUF、Safetensors、Ollama registry、Hugging Face Hub 都在這條鏈上。</p>
<h2 id="設計責任">設計責任</h2>
<p>下載模型前確認來源；下載後記錄 SHA-256、檔案大小與版本；第三方量化要看量化者信譽與社群採用。MCP server 與 plugin 是另一條可執行程式碼供應鏈，要用更高權限標準判讀。</p>
]]></content:encoded></item><item><title>Multi-agent system</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/multi-agent-system/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/multi-agent-system/</guid><description>&lt;p>Multi-agent system 的核心概念是「&lt;strong>多個 LLM &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/agent/" data-link-title="LLM Agent" data-link-desc="把控制流交給 LLM 的應用模式：自主決策、跨多步呼叫工具、人類角色從主導變監督">agent&lt;/a> 協作完成任務&lt;/strong>」。跟 multi-call workflow 的差異&lt;strong>不在 agent 數量多寡、在控制流跟責任邊界&lt;/strong>——multi-call 是主程式編排每 step、multi-agent 是 agent 自決下一步並可呼叫其他 agent。屬於 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/agent/" data-link-title="LLM Agent" data-link-desc="把控制流交給 LLM 的應用模式：自主決策、跨多步呼叫工具、人類角色從主導變監督">agent&lt;/a> 概念的進一步擴展。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>跟 multi-call 對照：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>Multi-call workflow&lt;/th>
 &lt;th>Multi-agent system&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>控制流&lt;/td>
 &lt;td>主程式編排&lt;/td>
 &lt;td>Agent 自決&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>角色&lt;/td>
 &lt;td>Step 是函數、無「身份」&lt;/td>
 &lt;td>每個 agent 有 role / 工具集&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Context&lt;/td>
 &lt;td>主程式傳 context&lt;/td>
 &lt;td>Agent 自帶 memory&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>重用&lt;/td>
 &lt;td>Step 是函數、容易 import&lt;/td>
 &lt;td>Agent 跨系統重用透過協議&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>失敗歸屬&lt;/td>
 &lt;td>Step 失敗、主程式接&lt;/td>
 &lt;td>Agent 失敗可能 cascading&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>三種主流拓樸：&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>Flat&lt;/td>
 &lt;td>All-to-all、無 orchestrator&lt;/td>
 &lt;td>2-4 個 agent、動態協商&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Hierarchical&lt;/td>
 &lt;td>Orchestrator + specialists&lt;/td>
 &lt;td>多專業 agent、單一對外介面&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Agent-as-tool&lt;/td>
 &lt;td>Agent 互通像 tool call（如 MCP）&lt;/td>
 &lt;td>跨組織重用、標準協議&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 agent framework / paper 看到「multi-agent」「orchestrator」「agent-as-tool」就是這層設計。實作判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>「先 multi-call、不夠再 multi-agent」&lt;/strong>：multi-agent 是「特定問題的解法」、不是「更高級的設計」。判讀訊號：role 顯著差異 / 跨產品重用 / 真正平行 / 動態協作 / 團隊熟悉度——四條件全滿足才走 multi-agent。&lt;/li>
&lt;li>&lt;strong>Specialization gain vs orchestration overhead&lt;/strong>：拆細帶來單一責任、獨立優化、重用、平行；代價是 context 重複傳遞、latency 累積、debug 困難、責任歸屬模糊。&lt;/li>
&lt;li>&lt;strong>特有失敗模式&lt;/strong>：循環依賴、責任歸屬模糊、context 重複傳遞、orchestrator 單點瓶頸、agent 互相 hallucinate。每類有對應 guardrail（call stack 監測、trace 全紀錄、shared context、deterministic dispatch rule、schema validation）。&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mcp/" data-link-title="MCP（Model Context Protocol）" data-link-desc="LLM application ↔ 外部 tool server 之間的標準化協議、複用 OpenAI 相容 API 的成功模式">MCP&lt;/a> 的關係&lt;/strong>：MCP 的 tool primitive 視角下、agent-as-tool 可包成 MCP server 暴露、跨組織重用走這條路。&lt;/li>
&lt;/ol>
&lt;p>完整 multi-agent 拓樸設計見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/multi-agent-topology/" data-link-title="4.8 Multi-Agent 拓樸：flat / hierarchical / agent-as-tool" data-link-desc="從 multi-call workflow 走到 multi-agent system 的判讀、flat vs hierarchical 拓樸、agent-as-tool 的 MCP 視角、specialization 跟 orchestration overhead 的取捨">4.8 Multi-Agent 拓樸&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Multi-agent system 的核心概念是「<strong>多個 LLM <a href="/blog/llm/knowledge-cards/agent/" data-link-title="LLM Agent" data-link-desc="把控制流交給 LLM 的應用模式：自主決策、跨多步呼叫工具、人類角色從主導變監督">agent</a> 協作完成任務</strong>」。跟 multi-call workflow 的差異<strong>不在 agent 數量多寡、在控制流跟責任邊界</strong>——multi-call 是主程式編排每 step、multi-agent 是 agent 自決下一步並可呼叫其他 agent。屬於 <a href="/blog/llm/knowledge-cards/agent/" data-link-title="LLM Agent" data-link-desc="把控制流交給 LLM 的應用模式：自主決策、跨多步呼叫工具、人類角色從主導變監督">agent</a> 概念的進一步擴展。</p>
<h2 id="概念位置">概念位置</h2>
<p>跟 multi-call 對照：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>Multi-call workflow</th>
          <th>Multi-agent system</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>控制流</td>
          <td>主程式編排</td>
          <td>Agent 自決</td>
      </tr>
      <tr>
          <td>角色</td>
          <td>Step 是函數、無「身份」</td>
          <td>每個 agent 有 role / 工具集</td>
      </tr>
      <tr>
          <td>Context</td>
          <td>主程式傳 context</td>
          <td>Agent 自帶 memory</td>
      </tr>
      <tr>
          <td>重用</td>
          <td>Step 是函數、容易 import</td>
          <td>Agent 跨系統重用透過協議</td>
      </tr>
      <tr>
          <td>失敗歸屬</td>
          <td>Step 失敗、主程式接</td>
          <td>Agent 失敗可能 cascading</td>
      </tr>
  </tbody>
</table>
<p>三種主流拓樸：</p>
<table>
  <thead>
      <tr>
          <th>拓樸</th>
          <th>結構</th>
          <th>適用</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Flat</td>
          <td>All-to-all、無 orchestrator</td>
          <td>2-4 個 agent、動態協商</td>
      </tr>
      <tr>
          <td>Hierarchical</td>
          <td>Orchestrator + specialists</td>
          <td>多專業 agent、單一對外介面</td>
      </tr>
      <tr>
          <td>Agent-as-tool</td>
          <td>Agent 互通像 tool call（如 MCP）</td>
          <td>跨組織重用、標準協議</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 agent framework / paper 看到「multi-agent」「orchestrator」「agent-as-tool」就是這層設計。實作判讀：</p>
<ol>
<li><strong>「先 multi-call、不夠再 multi-agent」</strong>：multi-agent 是「特定問題的解法」、不是「更高級的設計」。判讀訊號：role 顯著差異 / 跨產品重用 / 真正平行 / 動態協作 / 團隊熟悉度——四條件全滿足才走 multi-agent。</li>
<li><strong>Specialization gain vs orchestration overhead</strong>：拆細帶來單一責任、獨立優化、重用、平行；代價是 context 重複傳遞、latency 累積、debug 困難、責任歸屬模糊。</li>
<li><strong>特有失敗模式</strong>：循環依賴、責任歸屬模糊、context 重複傳遞、orchestrator 單點瓶頸、agent 互相 hallucinate。每類有對應 guardrail（call stack 監測、trace 全紀錄、shared context、deterministic dispatch rule、schema validation）。</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/mcp/" data-link-title="MCP（Model Context Protocol）" data-link-desc="LLM application ↔ 外部 tool server 之間的標準化協議、複用 OpenAI 相容 API 的成功模式">MCP</a> 的關係</strong>：MCP 的 tool primitive 視角下、agent-as-tool 可包成 MCP server 暴露、跨組織重用走這條路。</li>
</ol>
<p>完整 multi-agent 拓樸設計見 <a href="/blog/llm/04-applications/multi-agent-topology/" data-link-title="4.8 Multi-Agent 拓樸：flat / hierarchical / agent-as-tool" data-link-desc="從 multi-call workflow 走到 multi-agent system 的判讀、flat vs hierarchical 拓樸、agent-as-tool 的 MCP 視角、specialization 跟 orchestration overhead 的取捨">4.8 Multi-Agent 拓樸</a>。</p>
]]></content:encoded></item><item><title>Multi-Step Retrieval</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/multi-step-retrieval/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/multi-step-retrieval/</guid><description>&lt;p>Multi-step retrieval 的核心概念是「&lt;strong>讓 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> retrieval 變成多輪控制流，而不是一次性取 top-k&lt;/strong>」。模型先讀第一輪檢索結果，判斷資訊是否足夠，再決定下一個 sub-query。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>它是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop&lt;/a> 的交界：控制流比 vanilla RAG 複雜，但目標仍是補齊回答所需 context，而不是任意行動。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>多 hop 問題常需要 multi-step retrieval：先查 A 的屬性，再用該屬性查 B，最後比較。單次 retrieve 可能只抓到其中一邊，導致回答缺關鍵證據。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Multi-step retrieval 只有在問題確實需要多 hop、latency budget 允許、且有停止條件時才划算。沒有 stop condition 時容易無限 retrieve；沒有資訊足夠性判斷時容易提高 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost&lt;/a> 卻沒提升。&lt;/p></description><content:encoded><![CDATA[<p>Multi-step retrieval 的核心概念是「<strong>讓 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> retrieval 變成多輪控制流，而不是一次性取 top-k</strong>」。模型先讀第一輪檢索結果，判斷資訊是否足夠，再決定下一個 sub-query。</p>
<h2 id="概念位置">概念位置</h2>
<p>它是 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 與 <a href="/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop</a> 的交界：控制流比 vanilla RAG 複雜，但目標仍是補齊回答所需 context，而不是任意行動。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>多 hop 問題常需要 multi-step retrieval：先查 A 的屬性，再用該屬性查 B，最後比較。單次 retrieve 可能只抓到其中一邊，導致回答缺關鍵證據。</p>
<h2 id="設計責任">設計責任</h2>
<p>Multi-step retrieval 只有在問題確實需要多 hop、latency budget 允許、且有停止條件時才划算。沒有 stop condition 時容易無限 retrieve；沒有資訊足夠性判斷時容易提高 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a> 卻沒提升。</p>
]]></content:encoded></item><item><title>oMLX</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/omlx/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/omlx/</guid><description>&lt;p>oMLX 的核心概念是「&lt;strong>以 MLX 為基礎、針對 Apple Silicon 長 context 場景優化的推論伺服器路線&lt;/strong>」。它不是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mlx/" data-link-title="MLX" data-link-desc="Apple 釋出的 Apple Silicon 數值運算 framework：類似 PyTorch / JAX 的 Mac 對應物">MLX&lt;/a> 這個運算框架本身，也不是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mtp/" data-link-title="Multi-Token Prediction (MTP)" data-link-desc="Google 為 Gemma 系列釋出的 speculative decoding 工程化實作">MTP&lt;/a> 這類解碼技巧，而是把 MLX serving、長 context 與 KV cache 管理組合成服務層能力。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>oMLX 位在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/three-layer-architecture/" data-link-title="Three-Layer Architecture" data-link-desc="把本地 LLM 工具拆成介面層、推論伺服器層、模型權重層的基礎心智模型">three-layer architecture&lt;/a> 的伺服器層。它的差異化重點通常是 Apple Silicon 最佳化、長 context prefill 成本、SSD-backed KV cache 或相關 cache 策略；它對上仍可提供 API，對下仍載入模型權重。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>看到文章把 oMLX 跟 Ollama、LM Studio、llama.cpp server 放在同一組比較時，討論的是 serving 路線。看到它跟 MLX / MTP 並列時，判讀重點是「框架、解碼技巧、伺服器」三者層級不同。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>評估 oMLX 時，重點是工作流是否真的受長 context 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT&lt;/a> 影響；短 prompt 對話通常未必需要特化 serving。下一步路由是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mlx/" data-link-title="MLX" data-link-desc="Apple 釋出的 Apple Silicon 數值運算 framework：類似 PyTorch / JAX 的 Mac 對應物">MLX&lt;/a>、&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> 與 &lt;a href="https://tarrragon.github.io/blog/llm/00-foundations/mlx-mtp-omlx/" data-link-title="0.4 MLX / MTP / oMLX 的區別" data-link-desc="三個常被混為一談的術語：framework、加速技巧、特化 server，疊加而非互斥">0.4 MLX / MTP / oMLX&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>oMLX 的核心概念是「<strong>以 MLX 為基礎、針對 Apple Silicon 長 context 場景優化的推論伺服器路線</strong>」。它不是 <a href="/blog/llm/knowledge-cards/mlx/" data-link-title="MLX" data-link-desc="Apple 釋出的 Apple Silicon 數值運算 framework：類似 PyTorch / JAX 的 Mac 對應物">MLX</a> 這個運算框架本身，也不是 <a href="/blog/llm/knowledge-cards/mtp/" data-link-title="Multi-Token Prediction (MTP)" data-link-desc="Google 為 Gemma 系列釋出的 speculative decoding 工程化實作">MTP</a> 這類解碼技巧，而是把 MLX serving、長 context 與 KV cache 管理組合成服務層能力。</p>
<h2 id="概念位置">概念位置</h2>
<p>oMLX 位在 <a href="/blog/llm/knowledge-cards/three-layer-architecture/" data-link-title="Three-Layer Architecture" data-link-desc="把本地 LLM 工具拆成介面層、推論伺服器層、模型權重層的基礎心智模型">three-layer architecture</a> 的伺服器層。它的差異化重點通常是 Apple Silicon 最佳化、長 context prefill 成本、SSD-backed KV cache 或相關 cache 策略；它對上仍可提供 API，對下仍載入模型權重。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>看到文章把 oMLX 跟 Ollama、LM Studio、llama.cpp server 放在同一組比較時，討論的是 serving 路線。看到它跟 MLX / MTP 並列時，判讀重點是「框架、解碼技巧、伺服器」三者層級不同。</p>
<h2 id="設計責任">設計責任</h2>
<p>評估 oMLX 時，重點是工作流是否真的受長 context 與 <a href="/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT</a> 影響；短 prompt 對話通常未必需要特化 serving。下一步路由是 <a href="/blog/llm/knowledge-cards/mlx/" data-link-title="MLX" data-link-desc="Apple 釋出的 Apple Silicon 數值運算 framework：類似 PyTorch / JAX 的 Mac 對應物">MLX</a>、<a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV Cache</a> 與 <a href="/blog/llm/00-foundations/mlx-mtp-omlx/" data-link-title="0.4 MLX / MTP / oMLX 的區別" data-link-desc="三個常被混為一談的術語：framework、加速技巧、特化 server，疊加而非互斥">0.4 MLX / MTP / oMLX</a>。</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>Query Decomposition</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/query-decomposition/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/query-decomposition/</guid><description>&lt;p>Query decomposition 的核心概念是「&lt;strong>把一個複合問題拆成多個可獨立 retrieve 的子問題&lt;/strong>」。它處理的是單一 query 同時要求比較、列舉、跨 entity 查證或多維度分析時，單次 retrieval 容易只命中其中一部分的問題。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Query decomposition 位在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 的 query 端，跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/multi-step-retrieval/" data-link-title="Multi-Step Retrieval" data-link-desc="RAG 中多輪 retrieve → 判斷 → 再 retrieve 的控制流，用來處理 multi-hop 問題">multi-step retrieval&lt;/a> 相鄰但不相同。Decomposition 是先拆好 N 個子 query 平行 retrieve；multi-step retrieval 是 retrieve 後讀結果，再決定下一步要查什麼。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>「比較 A 與 B 在安全性和成本上的差異」可以拆成「A 的安全性」「B 的安全性」「A 的成本」「B 的成本」。每個子 query 都能獨立命中文件，最後再合成比較表。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Query decomposition 適合子問題彼此獨立的複合問題。若後一個子 query 需要前一輪結果才能產生，改用 multi-step retrieval；若拆解後子 query 過多，要回到 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost&lt;/a> 與 latency budget 評估。&lt;/p></description><content:encoded><![CDATA[<p>Query decomposition 的核心概念是「<strong>把一個複合問題拆成多個可獨立 retrieve 的子問題</strong>」。它處理的是單一 query 同時要求比較、列舉、跨 entity 查證或多維度分析時，單次 retrieval 容易只命中其中一部分的問題。</p>
<h2 id="概念位置">概念位置</h2>
<p>Query decomposition 位在 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 的 query 端，跟 <a href="/blog/llm/knowledge-cards/multi-step-retrieval/" data-link-title="Multi-Step Retrieval" data-link-desc="RAG 中多輪 retrieve → 判斷 → 再 retrieve 的控制流，用來處理 multi-hop 問題">multi-step retrieval</a> 相鄰但不相同。Decomposition 是先拆好 N 個子 query 平行 retrieve；multi-step retrieval 是 retrieve 後讀結果，再決定下一步要查什麼。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>「比較 A 與 B 在安全性和成本上的差異」可以拆成「A 的安全性」「B 的安全性」「A 的成本」「B 的成本」。每個子 query 都能獨立命中文件，最後再合成比較表。</p>
<h2 id="設計責任">設計責任</h2>
<p>Query decomposition 適合子問題彼此獨立的複合問題。若後一個子 query 需要前一輪結果才能產生，改用 multi-step retrieval；若拆解後子 query 過多，要回到 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a> 與 latency budget 評估。</p>
]]></content:encoded></item><item><title>Query Expansion</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/query-expansion/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/query-expansion/</guid><description>&lt;p>Query expansion 的核心概念是「&lt;strong>把一個使用者 query 擴成多個檢索變體，再把多路 retrieval 結果合併&lt;/strong>」。它處理的是 query 太短、有歧義、或只覆蓋單一表述角度時的 recall 問題，跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-rewriting/" data-link-title="Query Rewriting" data-link-desc="在 RAG 檢索前改寫使用者查詢，讓 query 更接近文件語言與索引分佈">query rewriting&lt;/a> 的單一路徑改寫不同。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Query expansion 位在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 的 query 端增強層。它會提高 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost&lt;/a>，因為每個變體都要 retrieve；它也常跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/hybrid-search/" data-link-title="Hybrid Search" data-link-desc="把字面 retrieval（BM25）跟語意 retrieval（embedding）的結果用 RRF 等方法合併、補單一路線的盲點">hybrid search&lt;/a> 的 RRF 合併思路相鄰，用排名融合降低單一 query 變體失誤。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>使用者問「python deploy」時，系統可能擴成「Python application deployment」「Docker deploy Python service」「CI/CD for Python backend」。這能增加 coverage，但也可能把不同意圖混在一起。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Query expansion 適合短 query、歧義 query、或同一問題有多種常見說法的場景。設計時要限制變體數量，保留 original query，並用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-recall/" data-link-title="Retrieval Recall" data-link-desc="衡量 RAG 檢索是否把應該命中的文件或 chunk 放進 top-k 結果，是 component-level eval 的核心指標">retrieval recall&lt;/a> 驗證是否真的提高命中率；變體太發散時應改用澄清問題或 query rewriting。&lt;/p></description><content:encoded><![CDATA[<p>Query expansion 的核心概念是「<strong>把一個使用者 query 擴成多個檢索變體，再把多路 retrieval 結果合併</strong>」。它處理的是 query 太短、有歧義、或只覆蓋單一表述角度時的 recall 問題，跟 <a href="/blog/llm/knowledge-cards/query-rewriting/" data-link-title="Query Rewriting" data-link-desc="在 RAG 檢索前改寫使用者查詢，讓 query 更接近文件語言與索引分佈">query rewriting</a> 的單一路徑改寫不同。</p>
<h2 id="概念位置">概念位置</h2>
<p>Query expansion 位在 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 的 query 端增強層。它會提高 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a>，因為每個變體都要 retrieve；它也常跟 <a href="/blog/llm/knowledge-cards/hybrid-search/" data-link-title="Hybrid Search" data-link-desc="把字面 retrieval（BM25）跟語意 retrieval（embedding）的結果用 RRF 等方法合併、補單一路線的盲點">hybrid search</a> 的 RRF 合併思路相鄰，用排名融合降低單一 query 變體失誤。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>使用者問「python deploy」時，系統可能擴成「Python application deployment」「Docker deploy Python service」「CI/CD for Python backend」。這能增加 coverage，但也可能把不同意圖混在一起。</p>
<h2 id="設計責任">設計責任</h2>
<p>Query expansion 適合短 query、歧義 query、或同一問題有多種常見說法的場景。設計時要限制變體數量，保留 original query，並用 <a href="/blog/llm/knowledge-cards/retrieval-recall/" data-link-title="Retrieval Recall" data-link-desc="衡量 RAG 檢索是否把應該命中的文件或 chunk 放進 top-k 結果，是 component-level eval 的核心指標">retrieval recall</a> 驗證是否真的提高命中率；變體太發散時應改用澄清問題或 query rewriting。</p>
]]></content:encoded></item><item><title>Query Rewriting</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/query-rewriting/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/query-rewriting/</guid><description>&lt;p>Query rewriting 的核心概念是「&lt;strong>在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> retrieval 前把使用者 query 改寫成更適合搜尋的形狀&lt;/strong>」。使用者常用口語、模糊或情境化說法，文件則使用正式術語；改寫能縮小 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap&lt;/a>。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Query rewriting 位在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> pipeline 的 query 端，早於 embedding、hybrid search、reranker 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/context-packing/" data-link-title="Context Packing" data-link-desc="RAG retrieve 後把 chunks 去重、排序、壓縮、標來源，再塞進 prompt 的組裝決策">context packing&lt;/a>。它跟 HyDE 不同：rewriting 產生更好的查詢句，HyDE 產生假設文件再拿去 embed。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>使用者問「API 為什麼很慢」，rewriting 可能改成「API latency bottleneck, tail latency, database query optimization」。這能讓 retrieval 更容易命中正式文件中的用詞，但會增加 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost&lt;/a>。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>改寫要保留原始意圖，避免把「診斷原因」改成「優化方案」這類偏移。實務上要保存 original query，retrieve 後再用原始 query 檢查結果是否對題。&lt;/p></description><content:encoded><![CDATA[<p>Query rewriting 的核心概念是「<strong>在 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> retrieval 前把使用者 query 改寫成更適合搜尋的形狀</strong>」。使用者常用口語、模糊或情境化說法，文件則使用正式術語；改寫能縮小 <a href="/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap</a>。</p>
<h2 id="概念位置">概念位置</h2>
<p>Query rewriting 位在 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> pipeline 的 query 端，早於 embedding、hybrid search、reranker 與 <a href="/blog/llm/knowledge-cards/context-packing/" data-link-title="Context Packing" data-link-desc="RAG retrieve 後把 chunks 去重、排序、壓縮、標來源，再塞進 prompt 的組裝決策">context packing</a>。它跟 HyDE 不同：rewriting 產生更好的查詢句，HyDE 產生假設文件再拿去 embed。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>使用者問「API 為什麼很慢」，rewriting 可能改成「API latency bottleneck, tail latency, database query optimization」。這能讓 retrieval 更容易命中正式文件中的用詞，但會增加 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a>。</p>
<h2 id="設計責任">設計責任</h2>
<p>改寫要保留原始意圖，避免把「診斷原因」改成「優化方案」這類偏移。實務上要保存 original query，retrieve 後再用原始 query 檢查結果是否對題。</p>
]]></content:encoded></item><item><title>Query-Document Gap</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/query-document-gap/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/query-document-gap/</guid><description>&lt;p>Query-document gap 的核心概念是「&lt;strong>使用者 query 的語言形狀跟被檢索文件的語言形狀不一致&lt;/strong>」。它是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> retrieval miss 的常見原因：query 可能是口語問句，document 可能是正式陳述、專業術語、程式碼符號或另一種抽象層級。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Query-document gap 位在 query 端與 embedding / search 端之間。它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/hybrid-search/" data-link-title="Hybrid Search" data-link-desc="把字面 retrieval（BM25）跟語意 retrieval（embedding）的結果用 RRF 等方法合併、補單一路線的盲點">hybrid search&lt;/a> 的字面 vs 語意互補相關，也跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-rewriting/" data-link-title="Query Rewriting" data-link-desc="在 RAG 檢索前改寫使用者查詢，讓 query 更接近文件語言與索引分佈">query rewriting&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/hyde/" data-link-title="HyDE（Hypothetical Document Embeddings）" data-link-desc="用 LLM 生成假設文件、對假文件做 embedding 去 retrieve、繞過 query-document gap 的 RAG 增強技術">HyDE&lt;/a> 直接相鄰：前者改寫 query，後者生成假設文件來靠近 document 分佈。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>使用者問「API 為什麼很慢」，文件寫的是「tail latency、database query plan、connection pool saturation」。兩者意思相關，但 phrasing、抽象層級與術語不同，embedding 可能命中弱，BM25 可能完全漏掉。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>處理 query-document gap 時先判斷落差類型：同義詞、口語 vs 正式、問句 vs 陳述、跨語言、domain jargon 或識別碼。輕量修法是 query rewriting；形態落差明顯時可用 HyDE；精確 keyword 與語意都重要時用 hybrid search；仍然 top-k 不準時再加 reranker。&lt;/p></description><content:encoded><![CDATA[<p>Query-document gap 的核心概念是「<strong>使用者 query 的語言形狀跟被檢索文件的語言形狀不一致</strong>」。它是 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> retrieval miss 的常見原因：query 可能是口語問句，document 可能是正式陳述、專業術語、程式碼符號或另一種抽象層級。</p>
<h2 id="概念位置">概念位置</h2>
<p>Query-document gap 位在 query 端與 embedding / search 端之間。它跟 <a href="/blog/llm/knowledge-cards/hybrid-search/" data-link-title="Hybrid Search" data-link-desc="把字面 retrieval（BM25）跟語意 retrieval（embedding）的結果用 RRF 等方法合併、補單一路線的盲點">hybrid search</a> 的字面 vs 語意互補相關，也跟 <a href="/blog/llm/knowledge-cards/query-rewriting/" data-link-title="Query Rewriting" data-link-desc="在 RAG 檢索前改寫使用者查詢，讓 query 更接近文件語言與索引分佈">query rewriting</a> 與 <a href="/blog/llm/knowledge-cards/hyde/" data-link-title="HyDE（Hypothetical Document Embeddings）" data-link-desc="用 LLM 生成假設文件、對假文件做 embedding 去 retrieve、繞過 query-document gap 的 RAG 增強技術">HyDE</a> 直接相鄰：前者改寫 query，後者生成假設文件來靠近 document 分佈。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>使用者問「API 為什麼很慢」，文件寫的是「tail latency、database query plan、connection pool saturation」。兩者意思相關，但 phrasing、抽象層級與術語不同，embedding 可能命中弱，BM25 可能完全漏掉。</p>
<h2 id="設計責任">設計責任</h2>
<p>處理 query-document gap 時先判斷落差類型：同義詞、口語 vs 正式、問句 vs 陳述、跨語言、domain jargon 或識別碼。輕量修法是 query rewriting；形態落差明顯時可用 HyDE；精確 keyword 與語意都重要時用 hybrid search；仍然 top-k 不準時再加 reranker。</p>
]]></content:encoded></item><item><title>Reflection / Self-critique</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/reflection/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/reflection/</guid><description>&lt;p>Reflection（self-critique）的核心概念是「&lt;strong>模型先生成一個草版、再對自己的草版 critique、再修改&lt;/strong>」。屬於推理引導類的 prompting 技術、也是 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/workflow-patterns/" data-link-title="4.7 Workflow 編排模式" data-link-desc="Pipeline / router / parallel / reflection：多 LLM call 組合的四種基本模式與退化條件">workflow pattern&lt;/a> 的基本模式之一。跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/chain-of-thought/" data-link-title="Chain-of-Thought（CoT）" data-link-desc="讓 LLM 先輸出推理步驟再給最終答案的 prompting / 訓練方式、reasoning model 的基礎機制">chain-of-thought&lt;/a> 不同：CoT 是「過程要 explicit」、reflection 是「先寫一版再批評再改」、有明確的兩階段。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Reflection 三步：&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">[Generate] 模型生成 v1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">[Critique] 模型（或 critic LLM）對 v1 給回饋
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">[Refine] 模型按回饋生成 v2
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">(可選 loop)&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>跟其他模式對照：&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>CoT&lt;/td>
 &lt;td>Think step by step、單次生成&lt;/td>
 &lt;td>隱式推理變 explicit&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Reflection&lt;/td>
 &lt;td>Generate → critique → refine&lt;/td>
 &lt;td>一次生成不夠好、需要二次審視&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Multi-step&lt;/td>
 &lt;td>Retrieve / decide / retrieve again&lt;/td>
 &lt;td>資訊不足、要動態補資料&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 prompt engineering / agent paper 看到「reflection」「self-critique」「self-refine」「critic」就是這個機制。實作判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>適用模型有能力辨識「自己寫的不夠好」&lt;/strong>、critique 跟 generator 不會共用同樣 blind spot。&lt;/li>
&lt;li>&lt;strong>失敗在 systematic error&lt;/strong>：critique 跟 generator 是同個模型、訓練分佈中的盲點不會因為「再想一次」消失。判讀訊號：critique 每次給很像的建議、或修完還是同一類錯——換 critic 用不同 base model、或加外部驗證（test、lint、schema）取代 LLM critique。&lt;/li>
&lt;li>&lt;strong>失敗在低能力模型&lt;/strong>：critic 能力不足、產不出有用建議、徒增 cost / latency。&lt;/li>
&lt;li>&lt;strong>失敗在無限循環&lt;/strong>：沒有客觀停止訊號、reflection 一直跑、cost 爆掉。緩解：step cap + 外部 metric（test pass、schema valid）。&lt;/li>
&lt;li>&lt;strong>失敗在過度修正&lt;/strong>：每次 reflection 都改一點、累積結果變糟（過度 fitting critic 意見）。緩解：保留 baseline、reflection 結果要跟 baseline 比、不一定採用。&lt;/li>
&lt;/ol>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">Agent loop&lt;/a> 是 reflection 的延伸特例、進階失敗模式見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/agent-architecture/" data-link-title="4.4 Agent 架構原理" data-link-desc="Agent loop 結構、失敗模式、什麼任務適合 vs 不適合、跟人類審查的協作模型">4.4 Agent 架構&lt;/a>。完整 workflow pattern 比較見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/workflow-patterns/" data-link-title="4.7 Workflow 編排模式" data-link-desc="Pipeline / router / parallel / reflection：多 LLM call 組合的四種基本模式與退化條件">4.7 Workflow patterns&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Reflection（self-critique）的核心概念是「<strong>模型先生成一個草版、再對自己的草版 critique、再修改</strong>」。屬於推理引導類的 prompting 技術、也是 <a href="/blog/llm/04-applications/workflow-patterns/" data-link-title="4.7 Workflow 編排模式" data-link-desc="Pipeline / router / parallel / reflection：多 LLM call 組合的四種基本模式與退化條件">workflow pattern</a> 的基本模式之一。跟 <a href="/blog/llm/knowledge-cards/chain-of-thought/" data-link-title="Chain-of-Thought（CoT）" data-link-desc="讓 LLM 先輸出推理步驟再給最終答案的 prompting / 訓練方式、reasoning model 的基礎機制">chain-of-thought</a> 不同：CoT 是「過程要 explicit」、reflection 是「先寫一版再批評再改」、有明確的兩階段。</p>
<h2 id="概念位置">概念位置</h2>
<p>Reflection 三步：</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">[Generate]    模型生成 v1
</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">[Critique]    模型（或 critic LLM）對 v1 給回饋
</span></span><span class="line"><span class="ln">4</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln">5</span><span class="cl">[Refine]      模型按回饋生成 v2
</span></span><span class="line"><span class="ln">6</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln">7</span><span class="cl">(可選 loop)</span></span></code></pre></div><p>跟其他模式對照：</p>
<table>
  <thead>
      <tr>
          <th>模式</th>
          <th>結構</th>
          <th>主要解的問題</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>CoT</td>
          <td>Think step by step、單次生成</td>
          <td>隱式推理變 explicit</td>
      </tr>
      <tr>
          <td>Reflection</td>
          <td>Generate → critique → refine</td>
          <td>一次生成不夠好、需要二次審視</td>
      </tr>
      <tr>
          <td>Multi-step</td>
          <td>Retrieve / decide / retrieve again</td>
          <td>資訊不足、要動態補資料</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 prompt engineering / agent paper 看到「reflection」「self-critique」「self-refine」「critic」就是這個機制。實作判讀：</p>
<ol>
<li><strong>適用模型有能力辨識「自己寫的不夠好」</strong>、critique 跟 generator 不會共用同樣 blind spot。</li>
<li><strong>失敗在 systematic error</strong>：critique 跟 generator 是同個模型、訓練分佈中的盲點不會因為「再想一次」消失。判讀訊號：critique 每次給很像的建議、或修完還是同一類錯——換 critic 用不同 base model、或加外部驗證（test、lint、schema）取代 LLM critique。</li>
<li><strong>失敗在低能力模型</strong>：critic 能力不足、產不出有用建議、徒增 cost / latency。</li>
<li><strong>失敗在無限循環</strong>：沒有客觀停止訊號、reflection 一直跑、cost 爆掉。緩解：step cap + 外部 metric（test pass、schema valid）。</li>
<li><strong>失敗在過度修正</strong>：每次 reflection 都改一點、累積結果變糟（過度 fitting critic 意見）。緩解：保留 baseline、reflection 結果要跟 baseline 比、不一定採用。</li>
</ol>
<p><a href="/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">Agent loop</a> 是 reflection 的延伸特例、進階失敗模式見 <a href="/blog/llm/04-applications/agent-architecture/" data-link-title="4.4 Agent 架構原理" data-link-desc="Agent loop 結構、失敗模式、什麼任務適合 vs 不適合、跟人類審查的協作模型">4.4 Agent 架構</a>。完整 workflow pattern 比較見 <a href="/blog/llm/04-applications/workflow-patterns/" data-link-title="4.7 Workflow 編排模式" data-link-desc="Pipeline / router / parallel / reflection：多 LLM call 組合的四種基本模式與退化條件">4.7 Workflow patterns</a>。</p>
]]></content:encoded></item><item><title>Residual Stream</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/residual-stream/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/residual-stream/</guid><description>&lt;p>Residual stream 的核心概念是「&lt;strong>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/transformer/" data-link-title="Transformer" data-link-desc="寫 code 用的 LLM 神經網路架構：基於 attention 機制、自回歸生成 token">Transformer&lt;/a> block 之間持續傳遞、被各層逐步修改的 hidden state 通道&lt;/strong>」。它是整個模型中資訊流動的主幹，涵蓋範圍超過單一殘差連接。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/residual-connection/" data-link-title="Residual Connection" data-link-desc="把 layer 的輸入直接加到輸出上的「跳接」、讓深層網路的梯度能穩定回流">Residual connection&lt;/a> 是局部結構：把 layer input 加回 output。Residual stream 是整體視角：token representation 在每層 attention、FFN、normalization 作用後沿著主通道前進。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>讀 Transformer 架構或 mechanistic interpretability 文章看到「write to residual stream」「read from residual stream」「logit lens」時，討論的是各層如何在同一條 hidden state 通道上累積特徵。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>一般使用者不用調 residual stream，但理解它能幫助區分 layer、block、hidden state 與 residual connection。進一步閱讀可回到 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/transformer/" data-link-title="Transformer" data-link-desc="寫 code 用的 LLM 神經網路架構：基於 attention 機制、自回歸生成 token">Transformer&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/residual-connection/" data-link-title="Residual Connection" data-link-desc="把 layer 的輸入直接加到輸出上的「跳接」、讓深層網路的梯度能穩定回流">Residual Connection&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Residual stream 的核心概念是「<strong><a href="/blog/llm/knowledge-cards/transformer/" data-link-title="Transformer" data-link-desc="寫 code 用的 LLM 神經網路架構：基於 attention 機制、自回歸生成 token">Transformer</a> block 之間持續傳遞、被各層逐步修改的 hidden state 通道</strong>」。它是整個模型中資訊流動的主幹，涵蓋範圍超過單一殘差連接。</p>
<h2 id="概念位置">概念位置</h2>
<p><a href="/blog/llm/knowledge-cards/residual-connection/" data-link-title="Residual Connection" data-link-desc="把 layer 的輸入直接加到輸出上的「跳接」、讓深層網路的梯度能穩定回流">Residual connection</a> 是局部結構：把 layer input 加回 output。Residual stream 是整體視角：token representation 在每層 attention、FFN、normalization 作用後沿著主通道前進。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>讀 Transformer 架構或 mechanistic interpretability 文章看到「write to residual stream」「read from residual stream」「logit lens」時，討論的是各層如何在同一條 hidden state 通道上累積特徵。</p>
<h2 id="設計責任">設計責任</h2>
<p>一般使用者不用調 residual stream，但理解它能幫助區分 layer、block、hidden state 與 residual connection。進一步閱讀可回到 <a href="/blog/llm/knowledge-cards/transformer/" data-link-title="Transformer" data-link-desc="寫 code 用的 LLM 神經網路架構：基於 attention 機制、自回歸生成 token">Transformer</a> 與 <a href="/blog/llm/knowledge-cards/residual-connection/" data-link-title="Residual Connection" data-link-desc="把 layer 的輸入直接加到輸出上的「跳接」、讓深層網路的梯度能穩定回流">Residual Connection</a>。</p>
]]></content:encoded></item><item><title>Retrieval Cost</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/</guid><description>&lt;p>Retrieval cost 的核心概念是「&lt;strong>每一次 retrieve 與其周邊增強會消耗多少 latency、token、compute 與維護成本&lt;/strong>」。它讓 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 設計從「能不能找更多資料」轉成「多找這些資料是否值得」。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Retrieval cost 橫跨 query 端、retrieval 端、context 組裝端與控制流端。它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT&lt;/a> 有關，但不只是一個延遲數字：query rewriting 多一次 LLM call，query expansion 多次 retrieve，reranker 多一段 cross-encoder 計算，retrieved chunks 進 prompt 會增加 token cost。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>常見訊號是「accuracy 有提升，但 p95 latency 變差」「每個 query 都 retrieve，聊天問題也燒 embedding / vector DB」「multi-step retrieval 連跑三輪，答案只比 single-step 好一點」。這時問題在於收益是否大於成本，而非技術能不能做。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>判斷 retrieval cost 要把 accuracy、latency、token budget、服務費用與維運複雜度一起看。低風險聊天可用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/adaptive-retrieval/" data-link-title="Adaptive Retrieval" data-link-desc="RAG 控制流中先判斷是否需要檢索，只在外部知識有價值時才 retrieve">adaptive retrieval&lt;/a> 降低不必要檢索；高價值問答可接受 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/reranker/" data-link-title="Reranker" data-link-desc="對 retrieval top-K 結果用 cross-encoder 重新排序的 RAG 第二階段、品質提升顯著但 latency / cost 增加">reranker&lt;/a> 或 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/multi-step-retrieval/" data-link-title="Multi-Step Retrieval" data-link-desc="RAG 中多輪 retrieve → 判斷 → 再 retrieve 的控制流，用來處理 multi-hop 問題">multi-step retrieval&lt;/a> 的額外成本；即時補完則通常偏向 single-step、cache 或較小 top-k。&lt;/p></description><content:encoded><![CDATA[<p>Retrieval cost 的核心概念是「<strong>每一次 retrieve 與其周邊增強會消耗多少 latency、token、compute 與維護成本</strong>」。它讓 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 設計從「能不能找更多資料」轉成「多找這些資料是否值得」。</p>
<h2 id="概念位置">概念位置</h2>
<p>Retrieval cost 橫跨 query 端、retrieval 端、context 組裝端與控制流端。它跟 <a href="/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT</a> 有關，但不只是一個延遲數字：query rewriting 多一次 LLM call，query expansion 多次 retrieve，reranker 多一段 cross-encoder 計算，retrieved chunks 進 prompt 會增加 token cost。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>常見訊號是「accuracy 有提升，但 p95 latency 變差」「每個 query 都 retrieve，聊天問題也燒 embedding / vector DB」「multi-step retrieval 連跑三輪，答案只比 single-step 好一點」。這時問題在於收益是否大於成本，而非技術能不能做。</p>
<h2 id="設計責任">設計責任</h2>
<p>判斷 retrieval cost 要把 accuracy、latency、token budget、服務費用與維運複雜度一起看。低風險聊天可用 <a href="/blog/llm/knowledge-cards/adaptive-retrieval/" data-link-title="Adaptive Retrieval" data-link-desc="RAG 控制流中先判斷是否需要檢索，只在外部知識有價值時才 retrieve">adaptive retrieval</a> 降低不必要檢索；高價值問答可接受 <a href="/blog/llm/knowledge-cards/reranker/" data-link-title="Reranker" data-link-desc="對 retrieval top-K 結果用 cross-encoder 重新排序的 RAG 第二階段、品質提升顯著但 latency / cost 增加">reranker</a> 或 <a href="/blog/llm/knowledge-cards/multi-step-retrieval/" data-link-title="Multi-Step Retrieval" data-link-desc="RAG 中多輪 retrieve → 判斷 → 再 retrieve 的控制流，用來處理 multi-hop 問題">multi-step retrieval</a> 的額外成本；即時補完則通常偏向 single-step、cache 或較小 top-k。</p>
]]></content:encoded></item><item><title>Retrieval Recall</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-recall/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-recall/</guid><description>&lt;p>Retrieval recall 的核心概念是「&lt;strong>正確文件或 chunk 是否出現在 retrieval top-k 結果中&lt;/strong>」。它把 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 的 retrieval 階段從主觀感覺改成 component-level eval，讓 generation 失敗與 retrieval miss 能分開判讀。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Retrieval recall 位在 retrieval component eval 層。它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/reranker/" data-link-title="Reranker" data-link-desc="對 retrieval top-K 結果用 cross-encoder 重新排序的 RAG 第二階段、品質提升顯著但 latency / cost 增加">reranker&lt;/a> 相鄰，因為 reranker 常用來提升 top-k 的排序品質；也跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap&lt;/a> 相鄰，因為 gap 太大會讓 expected doc 不進 top-k。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>一組 eval query 事先標出 expected chunk。若 expected chunk 出現在 top-5，記為 hit@5；一百題中 82 題命中，hit_rate@5 是 82%。若 retrieval recall 高但答案錯，問題多半在 generation 或 context packing；若 retrieval recall 低，先修 chunking、embedding、hybrid search 或 query 端增強。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>設計 retrieval recall eval 時要保存 query、expected source、top-k 結果、score 與失敗分類。不要只看 end-to-end answer correctness；否則 retrieval miss 會被 LLM hallucination、judge 偏差或 prompt 問題掩蓋。&lt;/p></description><content:encoded><![CDATA[<p>Retrieval recall 的核心概念是「<strong>正確文件或 chunk 是否出現在 retrieval top-k 結果中</strong>」。它把 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 的 retrieval 階段從主觀感覺改成 component-level eval，讓 generation 失敗與 retrieval miss 能分開判讀。</p>
<h2 id="概念位置">概念位置</h2>
<p>Retrieval recall 位在 retrieval component eval 層。它跟 <a href="/blog/llm/knowledge-cards/reranker/" data-link-title="Reranker" data-link-desc="對 retrieval top-K 結果用 cross-encoder 重新排序的 RAG 第二階段、品質提升顯著但 latency / cost 增加">reranker</a> 相鄰，因為 reranker 常用來提升 top-k 的排序品質；也跟 <a href="/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap</a> 相鄰，因為 gap 太大會讓 expected doc 不進 top-k。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>一組 eval query 事先標出 expected chunk。若 expected chunk 出現在 top-5，記為 hit@5；一百題中 82 題命中，hit_rate@5 是 82%。若 retrieval recall 高但答案錯，問題多半在 generation 或 context packing；若 retrieval recall 低，先修 chunking、embedding、hybrid search 或 query 端增強。</p>
<h2 id="設計責任">設計責任</h2>
<p>設計 retrieval recall eval 時要保存 query、expected source、top-k 結果、score 與失敗分類。不要只看 end-to-end answer correctness；否則 retrieval miss 會被 LLM hallucination、judge 偏差或 prompt 問題掩蓋。</p>
]]></content:encoded></item><item><title>Retrieval Source</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-source/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-source/</guid><description>&lt;p>Retrieval source 的核心概念是「&lt;strong>RAG 或 agent 在 retrieve 時實際查詢的資料來源&lt;/strong>」。它是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> pipeline 中可被檢索、可被引用、也可能被污染或過期的 corpus、index、database、file system、tool response 或第三方服務——比泛稱的 source 更具體。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Retrieval source 位在 ingestion、index 與 runtime retrieval 的交界。它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/chunking/" data-link-title="Chunking" data-link-desc="把長文件切成可檢索片段的設計決策：resolution vs context loss 的本質取捨">chunking&lt;/a> 不同：chunking 決定來源如何切片，retrieval source 決定來源本身是否可信、是否新鮮、是否有權限被查、是否能被引用。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>看到「從 codebase retrieve」「從歷史客服案例庫取相似案例」「從 vector DB 查 policy」「把 filesystem search 結果塞進 prompt」就是 retrieval source 問題。不同 source 的責任不同：官方 policy 文件可引用，使用者上傳文件要標記租戶與權限，網頁內容要防 prompt injection，過期 index 要能重建。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>設計 retrieval source 時要同時回答四件事：資料來源是否可信、資料是否新鮮、查詢者是否有權限、LLM 回答是否能追溯。高風險來源要保留 source metadata、ingestion timestamp、tenant boundary 與引用標籤；否則 retrieval 命中正確內容，也可能把不該看的資料送進 prompt。&lt;/p></description><content:encoded><![CDATA[<p>Retrieval source 的核心概念是「<strong>RAG 或 agent 在 retrieve 時實際查詢的資料來源</strong>」。它是 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> pipeline 中可被檢索、可被引用、也可能被污染或過期的 corpus、index、database、file system、tool response 或第三方服務——比泛稱的 source 更具體。</p>
<h2 id="概念位置">概念位置</h2>
<p>Retrieval source 位在 ingestion、index 與 runtime retrieval 的交界。它跟 <a href="/blog/llm/knowledge-cards/chunking/" data-link-title="Chunking" data-link-desc="把長文件切成可檢索片段的設計決策：resolution vs context loss 的本質取捨">chunking</a> 不同：chunking 決定來源如何切片，retrieval source 決定來源本身是否可信、是否新鮮、是否有權限被查、是否能被引用。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>看到「從 codebase retrieve」「從歷史客服案例庫取相似案例」「從 vector DB 查 policy」「把 filesystem search 結果塞進 prompt」就是 retrieval source 問題。不同 source 的責任不同：官方 policy 文件可引用，使用者上傳文件要標記租戶與權限，網頁內容要防 prompt injection，過期 index 要能重建。</p>
<h2 id="設計責任">設計責任</h2>
<p>設計 retrieval source 時要同時回答四件事：資料來源是否可信、資料是否新鮮、查詢者是否有權限、LLM 回答是否能追溯。高風險來源要保留 source metadata、ingestion timestamp、tenant boundary 與引用標籤；否則 retrieval 命中正確內容，也可能把不該看的資料送進 prompt。</p>
]]></content:encoded></item><item><title>Sampling Constraint</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/sampling-constraint/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/sampling-constraint/</guid><description>&lt;p>Sampling constraint（sampling 約束）的核心概念是「&lt;strong>在模型選下一個 token 時，限制哪些 token 可以被選到&lt;/strong>」。模型 forward pass 產生每個 token 的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/logit/" data-link-title="Logit" data-link-desc="softmax 之前的原始實數分數、每個 vocab token 一個值、可正可負">logit&lt;/a>，sampling 約束在取樣前調整候選集合或機率，讓輸出符合格式、選項或安全邊界。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Sampling 約束屬於推論階段，不修改模型權重，也不等於模型真的理解規則。常見控制手段有 temperature、top-p / top-k、logit bias、grammar mask、JSON mode 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/constrained-decoding/" data-link-title="Constrained Decoding" data-link-desc="推論時用 grammar 強制 LLM 輸出符合特定格式（JSON / regex / CFG）的 sampling 機制、把不合法 token 的機率歸零">constrained decoding&lt;/a>；其中 grammar mask 是 structured output 最關鍵的一類。&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">prompt → model forward pass → logits
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">sampling constraint：調整候選 token / logit / 機率
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">sample next token → append → 下一輪&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>看到「低 temperature 讓答案更穩」「top-p 過濾長尾 token」「logit bias 禁止某個 token」「grammar mask 只允許合法 JSON token」就是 sampling 約束。例子是 enum 分類：如果合法答案只有 &lt;code>billing&lt;/code>、&lt;code>technical&lt;/code>、&lt;code>other&lt;/code>，推論伺服器可以在輸出欄位值的位置只允許這幾組 token 的路徑。&lt;/p>
&lt;p>Sampling 約束的風險是把模型逼到錯誤但合法的輸出。當 grammar 太窄、enum 缺少 &lt;code>unknown&lt;/code>、schema 沒有容納例外狀態時，模型可能輸出看似可解析但語意不可信的值；這時要加 fallback、confidence 或人工覆核路由。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Sampling 約束適合處理格式合法性與候選空間控制，不適合單獨承擔事實正確性。設計時先問三件事：合法 token 集合能否完整表示業務狀態、約束失敗時要 retry 還是回退、下游 validator 如何分辨「格式合法但語意可疑」。下一步路由是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">Structured Output&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/top-p-sampling/" data-link-title="Top-K / Top-P / Min-P Sampling" data-link-desc="從機率分佈取樣前先過濾低機率 token 的三種策略、現代 LLM 推論主流">Top-K / Top-P / Min-P Sampling&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Sampling constraint（sampling 約束）的核心概念是「<strong>在模型選下一個 token 時，限制哪些 token 可以被選到</strong>」。模型 forward pass 產生每個 token 的 <a href="/blog/llm/knowledge-cards/logit/" data-link-title="Logit" data-link-desc="softmax 之前的原始實數分數、每個 vocab token 一個值、可正可負">logit</a>，sampling 約束在取樣前調整候選集合或機率，讓輸出符合格式、選項或安全邊界。</p>
<h2 id="概念位置">概念位置</h2>
<p>Sampling 約束屬於推論階段，不修改模型權重，也不等於模型真的理解規則。常見控制手段有 temperature、top-p / top-k、logit bias、grammar mask、JSON mode 與 <a href="/blog/llm/knowledge-cards/constrained-decoding/" data-link-title="Constrained Decoding" data-link-desc="推論時用 grammar 強制 LLM 輸出符合特定格式（JSON / regex / CFG）的 sampling 機制、把不合法 token 的機率歸零">constrained decoding</a>；其中 grammar mask 是 structured output 最關鍵的一類。</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">prompt → model forward pass → logits
</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">sampling constraint：調整候選 token / logit / 機率
</span></span><span class="line"><span class="ln">4</span><span class="cl">  ↓
</span></span><span class="line"><span class="ln">5</span><span class="cl">sample next token → append → 下一輪</span></span></code></pre></div><h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>看到「低 temperature 讓答案更穩」「top-p 過濾長尾 token」「logit bias 禁止某個 token」「grammar mask 只允許合法 JSON token」就是 sampling 約束。例子是 enum 分類：如果合法答案只有 <code>billing</code>、<code>technical</code>、<code>other</code>，推論伺服器可以在輸出欄位值的位置只允許這幾組 token 的路徑。</p>
<p>Sampling 約束的風險是把模型逼到錯誤但合法的輸出。當 grammar 太窄、enum 缺少 <code>unknown</code>、schema 沒有容納例外狀態時，模型可能輸出看似可解析但語意不可信的值；這時要加 fallback、confidence 或人工覆核路由。</p>
<h2 id="設計責任">設計責任</h2>
<p>Sampling 約束適合處理格式合法性與候選空間控制，不適合單獨承擔事實正確性。設計時先問三件事：合法 token 集合能否完整表示業務狀態、約束失敗時要 retry 還是回退、下游 validator 如何分辨「格式合法但語意可疑」。下一步路由是 <a href="/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">Structured Output</a> 與 <a href="/blog/llm/knowledge-cards/top-p-sampling/" data-link-title="Top-K / Top-P / Min-P Sampling" data-link-desc="從機率分佈取樣前先過濾低機率 token 的三種策略、現代 LLM 推論主流">Top-K / Top-P / Min-P Sampling</a>。</p>
]]></content:encoded></item><item><title>Structured Output</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/structured-output/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/structured-output/</guid><description>&lt;p>Structured output 的核心概念是「&lt;strong>讓 LLM 輸出符合可機器解析的固定形狀&lt;/strong>」。它解的是應用層 parser 能不能穩定消費模型輸出的問題：輸出要能被 JSON parser、schema validator、dispatcher、workflow engine 確定性處理，而不是靠人類讀自然語言再猜意圖。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Structured output 位在推論與應用交界，常見實作包含 JSON mode、JSON Schema、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">grammar&lt;/a> 約束、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/constrained-decoding/" data-link-title="Constrained Decoding" data-link-desc="推論時用 grammar 強制 LLM 輸出符合特定格式（JSON / regex / CFG）的 sampling 機制、把不合法 token 的機率歸零">constrained decoding&lt;/a> 與 logit mask。它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/function-calling/" data-link-title="Function Calling" data-link-desc="模型訓練階段建立的「呼叫工具」能力：知道何時該呼叫、傳什麼參數">function calling&lt;/a> 的差異在責任層：function calling 是模型訓練出的工具呼叫能力，structured output 是推論時讓輸出形狀穩定的約束。&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">模型能力：知道是否該呼叫工具、該填什麼參數
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">推論約束：輸出必須符合 JSON / schema / grammar
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">應用消費：parser 解析、validator 檢查、dispatcher 執行&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>看到「固定輸出 JSON」「把結果分類成 enum」「回傳符合 schema 的物件」「讓 parser 不再處理自由文字」就是 structured output 場景。例子是客服工單分類：模型輸出 &lt;code>{&amp;quot;category&amp;quot;:&amp;quot;billing&amp;quot;,&amp;quot;priority&amp;quot;:&amp;quot;high&amp;quot;}&lt;/code>，後端可以直接依欄位路由，而不是從一段自然語言裡抽關鍵字。&lt;/p>
&lt;p>Structured output 的成功訊號是合法率、schema 對位率與下游解析失敗率。JSON 合法率只代表文字可被 parser 讀，schema 對位率才代表欄位、型別、enum、required 都符合應用契約；兩者分開看，才能分辨是語法錯、schema 錯，還是模型語意判斷錯。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Structured output 適合「下游要自動執行」的輸出：tool 參數、分類、抽取、workflow 狀態、查詢條件。它的邊界是語意品質：grammar 可以保證格式合法，但不能保證模型填的值正確。下一步路由是：需要理解 token mask 機制讀 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/constrained-decoding/" data-link-title="Constrained Decoding" data-link-desc="推論時用 grammar 強制 LLM 輸出符合特定格式（JSON / regex / CFG）的 sampling 機制、把不合法 token 的機率歸零">Constrained Decoding&lt;/a>；需要判斷它跟工具呼叫的分工讀 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/function-calling/" data-link-title="Function Calling" data-link-desc="模型訓練階段建立的「呼叫工具」能力：知道何時該呼叫、傳什麼參數">Function Calling&lt;/a>；需要完整應用層組合讀 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/application-protocols/" data-link-title="4.6 應用層協議：function calling / structured output / MCP" data-link-desc="三個常被混為一談的概念：模型能力、sampling 約束、server 協議，三者的層級差異與組合方式">4.6 應用層協議&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Structured output 的核心概念是「<strong>讓 LLM 輸出符合可機器解析的固定形狀</strong>」。它解的是應用層 parser 能不能穩定消費模型輸出的問題：輸出要能被 JSON parser、schema validator、dispatcher、workflow engine 確定性處理，而不是靠人類讀自然語言再猜意圖。</p>
<h2 id="概念位置">概念位置</h2>
<p>Structured output 位在推論與應用交界，常見實作包含 JSON mode、JSON Schema、<a href="/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">grammar</a> 約束、<a href="/blog/llm/knowledge-cards/constrained-decoding/" data-link-title="Constrained Decoding" data-link-desc="推論時用 grammar 強制 LLM 輸出符合特定格式（JSON / regex / CFG）的 sampling 機制、把不合法 token 的機率歸零">constrained decoding</a> 與 logit mask。它跟 <a href="/blog/llm/knowledge-cards/function-calling/" data-link-title="Function Calling" data-link-desc="模型訓練階段建立的「呼叫工具」能力：知道何時該呼叫、傳什麼參數">function calling</a> 的差異在責任層：function calling 是模型訓練出的工具呼叫能力，structured output 是推論時讓輸出形狀穩定的約束。</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">模型能力：知道是否該呼叫工具、該填什麼參數
</span></span><span class="line"><span class="ln">2</span><span class="cl">推論約束：輸出必須符合 JSON / schema / grammar
</span></span><span class="line"><span class="ln">3</span><span class="cl">應用消費：parser 解析、validator 檢查、dispatcher 執行</span></span></code></pre></div><h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>看到「固定輸出 JSON」「把結果分類成 enum」「回傳符合 schema 的物件」「讓 parser 不再處理自由文字」就是 structured output 場景。例子是客服工單分類：模型輸出 <code>{&quot;category&quot;:&quot;billing&quot;,&quot;priority&quot;:&quot;high&quot;}</code>，後端可以直接依欄位路由，而不是從一段自然語言裡抽關鍵字。</p>
<p>Structured output 的成功訊號是合法率、schema 對位率與下游解析失敗率。JSON 合法率只代表文字可被 parser 讀，schema 對位率才代表欄位、型別、enum、required 都符合應用契約；兩者分開看，才能分辨是語法錯、schema 錯，還是模型語意判斷錯。</p>
<h2 id="設計責任">設計責任</h2>
<p>Structured output 適合「下游要自動執行」的輸出：tool 參數、分類、抽取、workflow 狀態、查詢條件。它的邊界是語意品質：grammar 可以保證格式合法，但不能保證模型填的值正確。下一步路由是：需要理解 token mask 機制讀 <a href="/blog/llm/knowledge-cards/constrained-decoding/" data-link-title="Constrained Decoding" data-link-desc="推論時用 grammar 強制 LLM 輸出符合特定格式（JSON / regex / CFG）的 sampling 機制、把不合法 token 的機率歸零">Constrained Decoding</a>；需要判斷它跟工具呼叫的分工讀 <a href="/blog/llm/knowledge-cards/function-calling/" data-link-title="Function Calling" data-link-desc="模型訓練階段建立的「呼叫工具」能力：知道何時該呼叫、傳什麼參數">Function Calling</a>；需要完整應用層組合讀 <a href="/blog/llm/04-applications/application-protocols/" data-link-title="4.6 應用層協議：function calling / structured output / MCP" data-link-desc="三個常被混為一談的概念：模型能力、sampling 約束、server 協議，三者的層級差異與組合方式">4.6 應用層協議</a>。</p>
]]></content:encoded></item><item><title>Three-Layer Architecture</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/three-layer-architecture/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/three-layer-architecture/</guid><description>&lt;p>Three-layer architecture（三層架構）的核心概念是「&lt;strong>把本地 LLM 系統拆成介面層、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/inference-server/" data-link-title="Inference Server" data-link-desc="載入模型權重、處理 prompt、產生 token 的常駐 process">inference server&lt;/a> 層、模型層&lt;/strong>」。這個分層讓讀者能判斷一個工具是在處理使用者互動、模型 serving，還是權重本身。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>三層責任分工如下：&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">介面層：CLI / IDE plugin / Web UI，負責接收任務與顯示結果
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">伺服器層：inference server，負責載入模型、提供 API、跑推論
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">模型層：權重檔與 tokenizer，負責提供可被執行的神經網路參數&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/openai-compatible-api/" data-link-title="OpenAI 相容 API" data-link-desc="本地推論伺服器跟雲端 OpenAI 共用的 API 形狀標準">OpenAI 相容 API&lt;/a> 的關係是：API 是介面層跟伺服器層之間的標準接縫；跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/inference-server/" data-link-title="Inference Server" data-link-desc="載入模型權重、處理 prompt、產生 token 的常駐 process">inference server&lt;/a> 的關係是：伺服器層是三層中的中介。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>看到 Continue.dev、Open WebUI、aider，通常是在介面層；看到 Ollama、LM Studio server、llama.cpp server、vLLM，通常是在伺服器層；看到 GGUF、Safetensors、MLX 權重，通常是在模型層。LM Studio 這類 all-in-one 工具會跨層，但仍可拆成 UI 與 server 兩種責任。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>排錯或換工具時，先問「問題出在哪一層」。連不上 &lt;code>localhost&lt;/code> 是伺服器或網路問題；回答品質差多半是模型或 prompt 問題；IDE 操作不順是介面層問題。完整推導見 &lt;a href="https://tarrragon.github.io/blog/llm/00-foundations/three-layer-architecture/" data-link-title="0.2 介面 / 伺服器 / 模型三層架構" data-link-desc="把任何本地 LLM 工具放回正確的層級，用三層心智模型看懂工具關係">0.2 三層架構&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Three-layer architecture（三層架構）的核心概念是「<strong>把本地 LLM 系統拆成介面層、<a href="/blog/llm/knowledge-cards/inference-server/" data-link-title="Inference Server" data-link-desc="載入模型權重、處理 prompt、產生 token 的常駐 process">inference server</a> 層、模型層</strong>」。這個分層讓讀者能判斷一個工具是在處理使用者互動、模型 serving，還是權重本身。</p>
<h2 id="概念位置">概念位置</h2>
<p>三層責任分工如下：</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">介面層：CLI / IDE plugin / Web UI，負責接收任務與顯示結果
</span></span><span class="line"><span class="ln">2</span><span class="cl">伺服器層：inference server，負責載入模型、提供 API、跑推論
</span></span><span class="line"><span class="ln">3</span><span class="cl">模型層：權重檔與 tokenizer，負責提供可被執行的神經網路參數</span></span></code></pre></div><p>它跟 <a href="/blog/llm/knowledge-cards/openai-compatible-api/" data-link-title="OpenAI 相容 API" data-link-desc="本地推論伺服器跟雲端 OpenAI 共用的 API 形狀標準">OpenAI 相容 API</a> 的關係是：API 是介面層跟伺服器層之間的標準接縫；跟 <a href="/blog/llm/knowledge-cards/inference-server/" data-link-title="Inference Server" data-link-desc="載入模型權重、處理 prompt、產生 token 的常駐 process">inference server</a> 的關係是：伺服器層是三層中的中介。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>看到 Continue.dev、Open WebUI、aider，通常是在介面層；看到 Ollama、LM Studio server、llama.cpp server、vLLM，通常是在伺服器層；看到 GGUF、Safetensors、MLX 權重，通常是在模型層。LM Studio 這類 all-in-one 工具會跨層，但仍可拆成 UI 與 server 兩種責任。</p>
<h2 id="設計責任">設計責任</h2>
<p>排錯或換工具時，先問「問題出在哪一層」。連不上 <code>localhost</code> 是伺服器或網路問題；回答品質差多半是模型或 prompt 問題；IDE 操作不順是介面層問題。完整推導見 <a href="/blog/llm/00-foundations/three-layer-architecture/" data-link-title="0.2 介面 / 伺服器 / 模型三層架構" data-link-desc="把任何本地 LLM 工具放回正確的層級，用三層心智模型看懂工具關係">0.2 三層架構</a>。</p>
]]></content:encoded></item><item><title>Tool Result Misread</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/tool-result-misread/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/tool-result-misread/</guid><description>&lt;p>Tool result misread（工具結果誤判）的核心概念是「&lt;strong>agent 把工具輸出的錯誤或不完整狀態解讀成成功&lt;/strong>」。LLM 只看文字與結構化回傳，若工具結果設計不清楚，模型容易忽略 error、warning、空集合或 partial failure。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>它是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">tool use&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop&lt;/a> 交界的失敗模式。模型可能選對工具、也成功呼叫工具，但在 observe 階段錯讀結果。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>&lt;code>git push&lt;/code> 失敗，agent 卻開始寫 PR description；查詢回空集合，agent 卻假設資料存在；測試命令非零退出，agent 只讀到最後幾行 log 就當成功。這些都是工具結果誤判。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>工具回傳要結構化表示 status、exit code、error type、stdout/stderr 與可重試性。Agent loop 要在 error signal 出現時強制 re-read 或 retry，必要時呼叫狀態確認工具，而不是依賴模型記憶。&lt;/p></description><content:encoded><![CDATA[<p>Tool result misread（工具結果誤判）的核心概念是「<strong>agent 把工具輸出的錯誤或不完整狀態解讀成成功</strong>」。LLM 只看文字與結構化回傳，若工具結果設計不清楚，模型容易忽略 error、warning、空集合或 partial failure。</p>
<h2 id="概念位置">概念位置</h2>
<p>它是 <a href="/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">tool use</a> 與 <a href="/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop</a> 交界的失敗模式。模型可能選對工具、也成功呼叫工具，但在 observe 階段錯讀結果。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p><code>git push</code> 失敗，agent 卻開始寫 PR description；查詢回空集合，agent 卻假設資料存在；測試命令非零退出，agent 只讀到最後幾行 log 就當成功。這些都是工具結果誤判。</p>
<h2 id="設計責任">設計責任</h2>
<p>工具回傳要結構化表示 status、exit code、error type、stdout/stderr 與可重試性。Agent loop 要在 error signal 出現時強制 re-read 或 retry，必要時呼叫狀態確認工具，而不是依賴模型記憶。</p>
]]></content:encoded></item><item><title>Tool-Use Permission Model</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/tool-use-permission-model/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/tool-use-permission-model/</guid><description>&lt;p>Tool-use permission model 的核心概念是「&lt;strong>按工具副作用範圍設計 LLM 可以做什麼、何時需要人類批准&lt;/strong>」。模型只生成 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">tool use&lt;/a> call，真正副作用由 client、MCP server、shell 或外部 API 執行，因此權限邊界必須放在工具層與執行環境。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>它建立在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">tool use&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mcp/" data-link-title="MCP（Model Context Protocol）" data-link-desc="LLM application ↔ 外部 tool server 之間的標準化協議、複用 OpenAI 相容 API 的成功模式">MCP&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/sandbox/" data-link-title="Sandbox" data-link-desc="把程式跑在受限制環境的隔離技術、限制檔案 / 網路 / 系統呼叫權限、是 tool use 跟 MCP server 副作用控制的基礎">sandbox&lt;/a> 之上。核心不是模型是否「想」執行，而是執行該 tool 的 process 是否有權限、是否有 allowlist、是否需要 approval。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>Read-only file search 可以自動；修改檔案要 checkpoint；刪除資料、push、部署、發送外部訊息通常要 step-by-step approval。第三方 MCP server 如果能讀整個 home directory，風險高於只讀 workspace 的 server。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>先把工具分成 read、local write、external side effect、irreversible operation，再配置 sandbox、allowlist、confirmation、audit log 與 rollback。高風險工具的預設應是人類批准，而不是 prompt 裡要求模型小心。&lt;/p></description><content:encoded><![CDATA[<p>Tool-use permission model 的核心概念是「<strong>按工具副作用範圍設計 LLM 可以做什麼、何時需要人類批准</strong>」。模型只生成 <a href="/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">tool use</a> call，真正副作用由 client、MCP server、shell 或外部 API 執行，因此權限邊界必須放在工具層與執行環境。</p>
<h2 id="概念位置">概念位置</h2>
<p>它建立在 <a href="/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">tool use</a>、<a href="/blog/llm/knowledge-cards/mcp/" data-link-title="MCP（Model Context Protocol）" data-link-desc="LLM application ↔ 外部 tool server 之間的標準化協議、複用 OpenAI 相容 API 的成功模式">MCP</a> 與 <a href="/blog/llm/knowledge-cards/sandbox/" data-link-title="Sandbox" data-link-desc="把程式跑在受限制環境的隔離技術、限制檔案 / 網路 / 系統呼叫權限、是 tool use 跟 MCP server 副作用控制的基礎">sandbox</a> 之上。核心不是模型是否「想」執行，而是執行該 tool 的 process 是否有權限、是否有 allowlist、是否需要 approval。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>Read-only file search 可以自動；修改檔案要 checkpoint；刪除資料、push、部署、發送外部訊息通常要 step-by-step approval。第三方 MCP server 如果能讀整個 home directory，風險高於只讀 workspace 的 server。</p>
<h2 id="設計責任">設計責任</h2>
<p>先把工具分成 read、local write、external side effect、irreversible operation，再配置 sandbox、allowlist、confirmation、audit log 與 rollback。高風險工具的預設應是人類批准，而不是 prompt 裡要求模型小心。</p>
]]></content:encoded></item><item><title>Training Example Coverage</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/training-example-coverage/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/training-example-coverage/</guid><description>&lt;p>Training example coverage（訓練範例覆蓋度）的核心概念是「&lt;strong>模型在訓練時看過的任務情境是否足以支撐部署時遇到的變化&lt;/strong>」。LLM 的能力宣稱常寫成支援某功能，但實際穩定性取決於範例是否覆蓋工具數量、參數形狀、語言變體、錯誤情境與 edge cases。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Coverage 是訓練資料分佈的問題，常在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/sft/" data-link-title="SFT（Supervised Fine-Tuning）" data-link-desc="在 base model 上用「指令-回答」對資料微調、讓模型會跟著指令走">SFT&lt;/a>、偏好資料、tool-use data、domain fine-tune 裡出現。它跟 prompt 範例不同：few-shot 範例只存在於當次 context，training examples 會透過訓練更新模型權重，影響模型「自然」傾向怎麼回答。&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">訓練資料有覆蓋 → 模型自然輸出穩定
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">訓練資料缺口大 → 靠 prompt / structured output / validator 兜底&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>Function calling 的 coverage 可從四個面向判讀：該呼叫時是否呼叫、工具選擇是否正確、參數型別是否正確、巢狀 schema 與多工具情境是否穩定。小模型常在單一工具 + 平坦 schema 表現可用，但一進到多工具、optional field、nested object、跨語言 query 就明顯掉分，這通常是 coverage 不足而不是單純 parser 問題。&lt;/p>
&lt;p>Coverage 的陷阱是只看 happy path。訓練範例如果只有成功呼叫工具，模型會傾向每次都呼叫；如果缺少「資訊不足時先追問」「使用者要求超出權限時拒絕」「工具錯誤時重試或回退」這類範例，部署後會在安全與可靠性邊界失敗。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>評估模型能力時，把支援功能改問成覆蓋範圍：支援哪些 tool schema 複雜度、哪些語言、哪些錯誤路徑、哪些反例。下一步路由是用 eval set 補齊代表性情境；如果 coverage 無法補在模型訓練層，就用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">structured output&lt;/a>、validator、retry 與 fallback 降低失敗成本。&lt;/p></description><content:encoded><![CDATA[<p>Training example coverage（訓練範例覆蓋度）的核心概念是「<strong>模型在訓練時看過的任務情境是否足以支撐部署時遇到的變化</strong>」。LLM 的能力宣稱常寫成支援某功能，但實際穩定性取決於範例是否覆蓋工具數量、參數形狀、語言變體、錯誤情境與 edge cases。</p>
<h2 id="概念位置">概念位置</h2>
<p>Coverage 是訓練資料分佈的問題，常在 <a href="/blog/llm/knowledge-cards/sft/" data-link-title="SFT（Supervised Fine-Tuning）" data-link-desc="在 base model 上用「指令-回答」對資料微調、讓模型會跟著指令走">SFT</a>、偏好資料、tool-use data、domain fine-tune 裡出現。它跟 prompt 範例不同：few-shot 範例只存在於當次 context，training examples 會透過訓練更新模型權重，影響模型「自然」傾向怎麼回答。</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">訓練資料有覆蓋 → 模型自然輸出穩定
</span></span><span class="line"><span class="ln">2</span><span class="cl">訓練資料缺口大 → 靠 prompt / structured output / validator 兜底</span></span></code></pre></div><h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>Function calling 的 coverage 可從四個面向判讀：該呼叫時是否呼叫、工具選擇是否正確、參數型別是否正確、巢狀 schema 與多工具情境是否穩定。小模型常在單一工具 + 平坦 schema 表現可用，但一進到多工具、optional field、nested object、跨語言 query 就明顯掉分，這通常是 coverage 不足而不是單純 parser 問題。</p>
<p>Coverage 的陷阱是只看 happy path。訓練範例如果只有成功呼叫工具，模型會傾向每次都呼叫；如果缺少「資訊不足時先追問」「使用者要求超出權限時拒絕」「工具錯誤時重試或回退」這類範例，部署後會在安全與可靠性邊界失敗。</p>
<h2 id="設計責任">設計責任</h2>
<p>評估模型能力時，把支援功能改問成覆蓋範圍：支援哪些 tool schema 複雜度、哪些語言、哪些錯誤路徑、哪些反例。下一步路由是用 eval set 補齊代表性情境；如果 coverage 無法補在模型訓練層，就用 <a href="/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">structured output</a>、validator、retry 與 fallback 降低失敗成本。</p>
]]></content:encoded></item><item><title>Unigram Tokenizer</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/unigram-tokenizer/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/unigram-tokenizer/</guid><description>&lt;p>Unigram tokenizer 的核心概念是「&lt;strong>把 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a> 切分視為從候選子詞集合中選最可能切分的機率問題&lt;/strong>」。它先有一組候選 subword，再用機率模型找出最合理的切分，有別於逐步合併字元對的做法。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Unigram 是 subword tokenizer 家族的一員，常由 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/sentencepiece/" data-link-title="SentencePiece" data-link-desc="Google 開源的多語言 tokenization 框架、支援 BPE 跟 unigram 演算法、處理空白統一">SentencePiece&lt;/a> 支援。它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/bpe/" data-link-title="BPE（Byte-Pair Encoding）" data-link-desc="用「最常一起出現的字元對」合併建詞彙表的 tokenization 演算法、GPT / Llama 等主流">BPE&lt;/a> 的差異在訓練與切分策略：BPE 是貪婪合併，unigram 是機率選擇與剪枝候選。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>讀 tokenizer 文件看到「unigram language model」「subword regularization」「SentencePiece unigram」就是這個概念。它可在訓練時對同一句話採不同合理切分，增加 tokenizer 層的資料多樣性。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>一般應用不會手動選 unigram tokenizer，但理解它能幫助比較模型的多語言支援與 token 效率。判讀時搭配 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/vocabulary-size/" data-link-title="Vocabulary Size" data-link-desc="tokenizer 詞彙表的 token 總數、影響 embedding 大小、tokenization 粒度、多語言友善度">Vocabulary Size&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">Token&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Unigram tokenizer 的核心概念是「<strong>把 <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a> 切分視為從候選子詞集合中選最可能切分的機率問題</strong>」。它先有一組候選 subword，再用機率模型找出最合理的切分，有別於逐步合併字元對的做法。</p>
<h2 id="概念位置">概念位置</h2>
<p>Unigram 是 subword tokenizer 家族的一員，常由 <a href="/blog/llm/knowledge-cards/sentencepiece/" data-link-title="SentencePiece" data-link-desc="Google 開源的多語言 tokenization 框架、支援 BPE 跟 unigram 演算法、處理空白統一">SentencePiece</a> 支援。它跟 <a href="/blog/llm/knowledge-cards/bpe/" data-link-title="BPE（Byte-Pair Encoding）" data-link-desc="用「最常一起出現的字元對」合併建詞彙表的 tokenization 演算法、GPT / Llama 等主流">BPE</a> 的差異在訓練與切分策略：BPE 是貪婪合併，unigram 是機率選擇與剪枝候選。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>讀 tokenizer 文件看到「unigram language model」「subword regularization」「SentencePiece unigram」就是這個概念。它可在訓練時對同一句話採不同合理切分，增加 tokenizer 層的資料多樣性。</p>
<h2 id="設計責任">設計責任</h2>
<p>一般應用不會手動選 unigram tokenizer，但理解它能幫助比較模型的多語言支援與 token 效率。判讀時搭配 <a href="/blog/llm/knowledge-cards/vocabulary-size/" data-link-title="Vocabulary Size" data-link-desc="tokenizer 詞彙表的 token 總數、影響 embedding 大小、tokenization 粒度、多語言友善度">Vocabulary Size</a> 與 <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">Token</a>。</p>
]]></content:encoded></item><item><title>Word2Vec</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/word2vec/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/word2vec/</guid><description>&lt;p>Word2Vec 的核心概念是「&lt;strong>用上下文預測任務學出靜態詞向量&lt;/strong>」。它讓語意相近的詞在向量空間中靠近，是理解 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model&lt;/a> 與 embedding space 的經典起點。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Word2Vec 屬於 LLM 前一代的 static embedding 方法，常見訓練方式是 skip-gram 與 CBOW。它跟現代 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model&lt;/a> 的差異是：Word2Vec 對同一個詞給固定向量，現代 Transformer 會依上下文產生 contextual representation。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>經典例子是 &lt;code>king - man + woman ≈ queen&lt;/code> 這類向量類比。它展示 embedding space 可以承載語意方向，但也暴露靜態詞向量對多義詞與上下文的限制。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 embedding 章節看到 Word2Vec 時，把它當成「embedding 概念的歷史基線」。實務 RAG 選型通常看現代 embedding model 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mteb-benchmark/" data-link-title="MTEB" data-link-desc="Massive Text Embedding Benchmark：8 大類 56 任務、評估 embedding model 跨任務通用能力的標準">MTEB&lt;/a>，不是直接使用 Word2Vec。&lt;/p></description><content:encoded><![CDATA[<p>Word2Vec 的核心概念是「<strong>用上下文預測任務學出靜態詞向量</strong>」。它讓語意相近的詞在向量空間中靠近，是理解 <a href="/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model</a> 與 embedding space 的經典起點。</p>
<h2 id="概念位置">概念位置</h2>
<p>Word2Vec 屬於 LLM 前一代的 static embedding 方法，常見訓練方式是 skip-gram 與 CBOW。它跟現代 <a href="/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model</a> 的差異是：Word2Vec 對同一個詞給固定向量，現代 Transformer 會依上下文產生 contextual representation。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>經典例子是 <code>king - man + woman ≈ queen</code> 這類向量類比。它展示 embedding space 可以承載語意方向，但也暴露靜態詞向量對多義詞與上下文的限制。</p>
<h2 id="設計責任">設計責任</h2>
<p>讀 embedding 章節看到 Word2Vec 時，把它當成「embedding 概念的歷史基線」。實務 RAG 選型通常看現代 embedding model 與 <a href="/blog/llm/knowledge-cards/mteb-benchmark/" data-link-title="MTEB" data-link-desc="Massive Text Embedding Benchmark：8 大類 56 任務、評估 embedding model 跨任務通用能力的標準">MTEB</a>，不是直接使用 Word2Vec。</p>
]]></content:encoded></item><item><title>WordPiece</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/wordpiece/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/wordpiece/</guid><description>&lt;p>WordPiece 的核心概念是「&lt;strong>用語料 likelihood 改善量選擇子詞合併的 tokenization 演算法&lt;/strong>」。它跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/bpe/" data-link-title="BPE（Byte-Pair Encoding）" data-link-desc="用「最常一起出現的字元對」合併建詞彙表的 tokenization 演算法、GPT / Llama 等主流">BPE&lt;/a> 一樣把文字拆成 subword，但選擇 merge 的準則不同。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>WordPiece 屬於 subword tokenizer 家族，BERT 系列是代表。BPE 偏向合併高頻相鄰片段；WordPiece 偏向選擇能最大化語言模型 likelihood 的片段；&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/sentencepiece/" data-link-title="SentencePiece" data-link-desc="Google 開源的多語言 tokenization 框架、支援 BPE 跟 unigram 演算法、處理空白統一">SentencePiece&lt;/a> 則是 tokenizer framework，可支援 BPE 或 unigram。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>看到 &lt;code>##ing&lt;/code>、&lt;code>##ed&lt;/code> 這類 continuation marker，通常是 WordPiece 風格 vocabulary。它讓模型能處理未見過的詞，因為陌生詞仍可拆成已知 subword。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>比較 tokenizer 時，WordPiece 主要作為 BERT/encoder 系統的背景知識。寫 LLM 推論與本地 serving 時更常遇到 BPE、SentencePiece、vocab size 與 special tokens。&lt;/p></description><content:encoded><![CDATA[<p>WordPiece 的核心概念是「<strong>用語料 likelihood 改善量選擇子詞合併的 tokenization 演算法</strong>」。它跟 <a href="/blog/llm/knowledge-cards/bpe/" data-link-title="BPE（Byte-Pair Encoding）" data-link-desc="用「最常一起出現的字元對」合併建詞彙表的 tokenization 演算法、GPT / Llama 等主流">BPE</a> 一樣把文字拆成 subword，但選擇 merge 的準則不同。</p>
<h2 id="概念位置">概念位置</h2>
<p>WordPiece 屬於 subword tokenizer 家族，BERT 系列是代表。BPE 偏向合併高頻相鄰片段；WordPiece 偏向選擇能最大化語言模型 likelihood 的片段；<a href="/blog/llm/knowledge-cards/sentencepiece/" data-link-title="SentencePiece" data-link-desc="Google 開源的多語言 tokenization 框架、支援 BPE 跟 unigram 演算法、處理空白統一">SentencePiece</a> 則是 tokenizer framework，可支援 BPE 或 unigram。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>看到 <code>##ing</code>、<code>##ed</code> 這類 continuation marker，通常是 WordPiece 風格 vocabulary。它讓模型能處理未見過的詞，因為陌生詞仍可拆成已知 subword。</p>
<h2 id="設計責任">設計責任</h2>
<p>比較 tokenizer 時，WordPiece 主要作為 BERT/encoder 系統的背景知識。寫 LLM 推論與本地 serving 時更常遇到 BPE、SentencePiece、vocab size 與 special tokens。</p>
]]></content:encoded></item><item><title>Acceptance Rate</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/acceptance-rate/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/acceptance-rate/</guid><description>&lt;p>Acceptance rate（接受率）的核心概念是「&lt;strong>在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">speculative decoding&lt;/a> 中、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/drafter-model/" data-link-title="Drafter Model" data-link-desc="speculative decoding 中用來快速猜未來 token 的小模型">drafter&lt;/a> 提出的 token 序列被 target model 驗證後接受的比例&lt;/strong>」。Acceptance rate 直接決定 speculative decoding 的實際加速倍率：高 acceptance rate（如 0.8）能拉出接近理論上限的加速；低 acceptance rate（如 0.3）可能反而比純 target model 慢。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Speculative decoding 一個 step 的流程：&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">1. Drafter 一次生 K 個候選 token（如 K=5）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">2. Target model 對「prefix + 這 K 個 token」並行驗證
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">3. 從前往後：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> - drafter token i 跟 target 第 i 個位置 sampling 一致 → 接受
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> - 第一個不一致 → 接受到此為止、用 target 的 token 取代第一個不一致
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">4. 若全 K 個都接受、target 再 sample 一個 bonus token&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Acceptance rate 影響：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>場景&lt;/th>
 &lt;th>Acceptance rate&lt;/th>
 &lt;th>實際加速&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Drafter 跟 target 高度同分佈&lt;/td>
 &lt;td>0.8 ~ 0.95&lt;/td>
 &lt;td>接近 K 倍上限&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Drafter / target 一般搭配&lt;/td>
 &lt;td>0.5 ~ 0.7&lt;/td>
 &lt;td>約 1.5 ~ 2× 加速&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Drafter 訓練分佈差很多&lt;/td>
 &lt;td>0.2 ~ 0.4&lt;/td>
 &lt;td>接近 1×（甚至更慢）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Drafter / target tokenizer 不一致&lt;/td>
 &lt;td>不能用&lt;/td>
 &lt;td>概念不成立&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="影響-acceptance-rate-的因素">影響 acceptance rate 的因素&lt;/h2>
&lt;ol>
&lt;li>&lt;strong>Drafter / target 同 family&lt;/strong>：同訓練分佈、acceptance rate 高（如 Gemma 4 31B + Gemma 4 E4B）&lt;/li>
&lt;li>&lt;strong>任務難度&lt;/strong>：簡單任務（boilerplate、常見 pattern）drafter 容易猜對；困難任務（reasoning、罕見領域）acceptance rate 降&lt;/li>
&lt;li>&lt;strong>Sampling temperature&lt;/strong>：高 temperature 兩邊 sample 分佈都拉平、隨機性增加、acceptance rate 降；T=0（greedy）acceptance rate 最高&lt;/li>
&lt;li>&lt;strong>K 設太大&lt;/strong>：drafter 越往後預測、累積誤差越大、後半段 token acceptance rate 急降；K 通常設 3-5 為甜蜜點&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 speculative decoding 設定 / model card 看到「draft acceptance」「acceptance length」就是這指標。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>挑 drafter 看 family + 大小&lt;/strong>：drafter 跟 target 同 family（如 Gemma 4 31B + Gemma 4 E4B、Qwen3-30B + Qwen3-1.5B）是 acceptance rate 最高的組合&lt;/li>
&lt;li>&lt;strong>&lt;code>llama-bench&lt;/code> 量實際加速比理論 K 倍重要&lt;/strong>：理論加速 = K × acceptance rate、實測才知道 drafter 在自己工作流的真實表現&lt;/li>
&lt;li>&lt;strong>太低的 acceptance rate 是訊號&lt;/strong>：&amp;lt; 0.3 通常表示 drafter / target 不匹配、值得換 drafter；&amp;lt; 0.5 表示甜蜜點以下、可調 K 或 sampling 設定&lt;/li>
&lt;li>&lt;strong>MTP（Multi-Token Prediction）&lt;/strong>：把 drafter 改成 target 內建多預測 head、acceptance rate 通常更高（因為 head 跟 target 完全同分佈）&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Acceptance rate（接受率）的核心概念是「<strong>在 <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/drafter-model/" data-link-title="Drafter Model" data-link-desc="speculative decoding 中用來快速猜未來 token 的小模型">drafter</a> 提出的 token 序列被 target model 驗證後接受的比例</strong>」。Acceptance rate 直接決定 speculative decoding 的實際加速倍率：高 acceptance rate（如 0.8）能拉出接近理論上限的加速；低 acceptance rate（如 0.3）可能反而比純 target model 慢。</p>
<h2 id="概念位置">概念位置</h2>
<p>Speculative decoding 一個 step 的流程：</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">1. Drafter 一次生 K 個候選 token（如 K=5）
</span></span><span class="line"><span class="ln">2</span><span class="cl">2. Target model 對「prefix + 這 K 個 token」並行驗證
</span></span><span class="line"><span class="ln">3</span><span class="cl">3. 從前往後：
</span></span><span class="line"><span class="ln">4</span><span class="cl">   - drafter token i 跟 target 第 i 個位置 sampling 一致 → 接受
</span></span><span class="line"><span class="ln">5</span><span class="cl">   - 第一個不一致 → 接受到此為止、用 target 的 token 取代第一個不一致
</span></span><span class="line"><span class="ln">6</span><span class="cl">4. 若全 K 個都接受、target 再 sample 一個 bonus token</span></span></code></pre></div><p>Acceptance rate 影響：</p>
<table>
  <thead>
      <tr>
          <th>場景</th>
          <th>Acceptance rate</th>
          <th>實際加速</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Drafter 跟 target 高度同分佈</td>
          <td>0.8 ~ 0.95</td>
          <td>接近 K 倍上限</td>
      </tr>
      <tr>
          <td>Drafter / target 一般搭配</td>
          <td>0.5 ~ 0.7</td>
          <td>約 1.5 ~ 2× 加速</td>
      </tr>
      <tr>
          <td>Drafter 訓練分佈差很多</td>
          <td>0.2 ~ 0.4</td>
          <td>接近 1×（甚至更慢）</td>
      </tr>
      <tr>
          <td>Drafter / target tokenizer 不一致</td>
          <td>不能用</td>
          <td>概念不成立</td>
      </tr>
  </tbody>
</table>
<h2 id="影響-acceptance-rate-的因素">影響 acceptance rate 的因素</h2>
<ol>
<li><strong>Drafter / target 同 family</strong>：同訓練分佈、acceptance rate 高（如 Gemma 4 31B + Gemma 4 E4B）</li>
<li><strong>任務難度</strong>：簡單任務（boilerplate、常見 pattern）drafter 容易猜對；困難任務（reasoning、罕見領域）acceptance rate 降</li>
<li><strong>Sampling temperature</strong>：高 temperature 兩邊 sample 分佈都拉平、隨機性增加、acceptance rate 降；T=0（greedy）acceptance rate 最高</li>
<li><strong>K 設太大</strong>：drafter 越往後預測、累積誤差越大、後半段 token acceptance rate 急降；K 通常設 3-5 為甜蜜點</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 speculative decoding 設定 / model card 看到「draft acceptance」「acceptance length」就是這指標。寫 code 場景的判讀：</p>
<ol>
<li><strong>挑 drafter 看 family + 大小</strong>：drafter 跟 target 同 family（如 Gemma 4 31B + Gemma 4 E4B、Qwen3-30B + Qwen3-1.5B）是 acceptance rate 最高的組合</li>
<li><strong><code>llama-bench</code> 量實際加速比理論 K 倍重要</strong>：理論加速 = K × acceptance rate、實測才知道 drafter 在自己工作流的真實表現</li>
<li><strong>太低的 acceptance rate 是訊號</strong>：&lt; 0.3 通常表示 drafter / target 不匹配、值得換 drafter；&lt; 0.5 表示甜蜜點以下、可調 K 或 sampling 設定</li>
<li><strong>MTP（Multi-Token Prediction）</strong>：把 drafter 改成 target 內建多預測 head、acceptance rate 通常更高（因為 head 跟 target 完全同分佈）</li>
</ol>
]]></content:encoded></item><item><title>Activation Function</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/activation-function/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/activation-function/</guid><description>&lt;p>Activation function（激活函數）的核心概念是「在 linear layer（矩陣乘法）之間插入的非線性函數」。沒有 activation function、整個多層神經網路會塌縮成單一個線性變換、表達能力跟單層 linear 一樣弱。activation function 讓深度網路真的「深」起來。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>LLM 中 activation function 主要出現在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/ffn/" data-link-title="FFN（Feed-Forward Network）" data-link-desc="Transformer block 內部的兩層 linear &amp;#43; activation、佔模型參數量的多數">FFN&lt;/a> 內、夾在兩個矩陣乘法之間：&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">FFN: input → W_up (linear) → activation → W_down (linear) → output
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↑
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> 這裡是 activation function&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>主流 LLM 用的 activation function 演化：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Activation&lt;/th>
 &lt;th>公式（簡化）&lt;/th>
 &lt;th>出現在&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>ReLU&lt;/td>
 &lt;td>&lt;code>max(0, x)&lt;/code>&lt;/td>
 &lt;td>早期 Transformer（如 BERT）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>GELU&lt;/td>
 &lt;td>&lt;code>x · Φ(x)&lt;/code>（Φ 是 Gaussian CDF）&lt;/td>
 &lt;td>GPT-2 / 3、BERT 後期&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>SwiGLU&lt;/td>
 &lt;td>&lt;code>Swish(xW) ⊙ (xV)&lt;/code>&lt;/td>
 &lt;td>Llama、Gemma、Qwen 等主流&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>GeGLU&lt;/td>
 &lt;td>&lt;code>GELU(xW) ⊙ (xV)&lt;/code>&lt;/td>
 &lt;td>部分 Google 系列模型&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>SwiGLU / GeGLU 是「gated」變體、用兩條線性投影相乘、表達能力比單一 activation 強、是現代 LLM 主流。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 paper / model card 看到 SwiGLU、ReLU、GELU 等詞、知道它們是 FFN 內部的選擇、影響模型表達能力跟訓練穩定性、不影響「模型怎麼用 / 怎麼 inference」這類使用者面議題。寫 code 場景的判讀：模型用什麼 activation 由模型作者決定、使用者通常不用調；但若要 fine-tune 或自己訓模型、activation 選擇是設計決策之一。&lt;/p></description><content:encoded><![CDATA[<p>Activation function（激活函數）的核心概念是「在 linear layer（矩陣乘法）之間插入的非線性函數」。沒有 activation function、整個多層神經網路會塌縮成單一個線性變換、表達能力跟單層 linear 一樣弱。activation function 讓深度網路真的「深」起來。</p>
<h2 id="概念位置">概念位置</h2>
<p>LLM 中 activation function 主要出現在 <a href="/blog/llm/knowledge-cards/ffn/" data-link-title="FFN（Feed-Forward Network）" data-link-desc="Transformer block 內部的兩層 linear &#43; activation、佔模型參數量的多數">FFN</a> 內、夾在兩個矩陣乘法之間：</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">FFN: input → W_up (linear) → activation → W_down (linear) → output
</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">                       這裡是 activation function</span></span></code></pre></div><p>主流 LLM 用的 activation function 演化：</p>
<table>
  <thead>
      <tr>
          <th>Activation</th>
          <th>公式（簡化）</th>
          <th>出現在</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>ReLU</td>
          <td><code>max(0, x)</code></td>
          <td>早期 Transformer（如 BERT）</td>
      </tr>
      <tr>
          <td>GELU</td>
          <td><code>x · Φ(x)</code>（Φ 是 Gaussian CDF）</td>
          <td>GPT-2 / 3、BERT 後期</td>
      </tr>
      <tr>
          <td>SwiGLU</td>
          <td><code>Swish(xW) ⊙ (xV)</code></td>
          <td>Llama、Gemma、Qwen 等主流</td>
      </tr>
      <tr>
          <td>GeGLU</td>
          <td><code>GELU(xW) ⊙ (xV)</code></td>
          <td>部分 Google 系列模型</td>
      </tr>
  </tbody>
</table>
<p>SwiGLU / GeGLU 是「gated」變體、用兩條線性投影相乘、表達能力比單一 activation 強、是現代 LLM 主流。</p>
<h2 id="設計責任">設計責任</h2>
<p>讀 paper / model card 看到 SwiGLU、ReLU、GELU 等詞、知道它們是 FFN 內部的選擇、影響模型表達能力跟訓練穩定性、不影響「模型怎麼用 / 怎麼 inference」這類使用者面議題。寫 code 場景的判讀：模型用什麼 activation 由模型作者決定、使用者通常不用調；但若要 fine-tune 或自己訓模型、activation 選擇是設計決策之一。</p>
]]></content:encoded></item><item><title>Active Parameter</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/active-parameter/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/active-parameter/</guid><description>&lt;p>Active parameter 的核心概念是「&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/moe/" data-link-title="Mixture of Experts (MoE)" data-link-desc="把 transformer 的 FFN 層拆成多個專家、每 token 只啟用少數、總參數大但每 token 計算量小的架構">MoE&lt;/a> 模型每生成一個 token 實際參與 forward pass 的參數量」。跟模型總參數量是兩個獨立指標：&lt;strong>總參數&lt;/strong>影響記憶體需求（要全部載入）、&lt;strong>active parameter&lt;/strong> 影響推論速度上限（每 token 走的計算量）。Dense 模型的 active parameter 等於總參數；MoE 模型的 active parameter 通常只有總參數的 10% ~ 20%。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>模型命名中的 active parameter 線索：&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>&lt;code>Qwen3-30B-A3B&lt;/code>&lt;/td>
 &lt;td>30B 總參數、A3B 表示 active 約 3B&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>Mixtral-8x7B&lt;/code>&lt;/td>
 &lt;td>8 個 7B expert、每 token top-2 啟用 ≈ 14B active（含 shared）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>Llama-3.3-70B&lt;/code>&lt;/td>
 &lt;td>Dense、active = total = 70B&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>DeepSeek-V3&lt;/code>&lt;/td>
 &lt;td>671B 總參數、active 約 37B（依官方文件）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>模型在不同維度的影響：&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>記憶體需求&lt;/td>
 &lt;td>總參數 × 每權重 bytes&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>生字速度上限&lt;/td>
 &lt;td>active parameter × 每 token 讀取量 / &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>模型能力（社群常見回報）&lt;/td>
 &lt;td>較強相關於總參數、但 active parameter 是底線&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：active parameter 跟模型能力的關係是社群常見回報、不是嚴格定理；具體模型在 coding / reasoning / 對話等任務的表現依訓練資料、RLHF、prompt 風格變化、需以 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/swe-bench/" data-link-title="SWE-bench" data-link-desc="用真實 GitHub issue 量化 LLM coding 能力的 benchmark">SWE-bench&lt;/a> 等公開 benchmark 跟自己工作流校準。&lt;/p>&lt;/blockquote>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 active parameter 後可以解釋兩個現象：為什麼 30B MoE 跟 30B Dense 在同硬體下生字速度差很多（前者每 token 只走 3B active）、為什麼 MoE 模型能力對應的「等價 Dense 大小」不是簡單線性（社群常見回報接近總參數的 60% ~ 80% 等價 Dense 能力、但 case-by-case）。&lt;/p>
&lt;p>選 MoE 模型時、active parameter 是速度判讀軸、總參數是記憶體判讀軸、能力判讀靠自己工作流的 benchmark；不要直接拿「30B」跟 Dense 30B 作能力對等。&lt;/p></description><content:encoded><![CDATA[<p>Active parameter 的核心概念是「<a href="/blog/llm/knowledge-cards/moe/" data-link-title="Mixture of Experts (MoE)" data-link-desc="把 transformer 的 FFN 層拆成多個專家、每 token 只啟用少數、總參數大但每 token 計算量小的架構">MoE</a> 模型每生成一個 token 實際參與 forward pass 的參數量」。跟模型總參數量是兩個獨立指標：<strong>總參數</strong>影響記憶體需求（要全部載入）、<strong>active parameter</strong> 影響推論速度上限（每 token 走的計算量）。Dense 模型的 active parameter 等於總參數；MoE 模型的 active parameter 通常只有總參數的 10% ~ 20%。</p>
<h2 id="概念位置">概念位置</h2>
<p>模型命名中的 active parameter 線索：</p>
<table>
  <thead>
      <tr>
          <th>命名範例</th>
          <th>解讀</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>Qwen3-30B-A3B</code></td>
          <td>30B 總參數、A3B 表示 active 約 3B</td>
      </tr>
      <tr>
          <td><code>Mixtral-8x7B</code></td>
          <td>8 個 7B expert、每 token top-2 啟用 ≈ 14B active（含 shared）</td>
      </tr>
      <tr>
          <td><code>Llama-3.3-70B</code></td>
          <td>Dense、active = total = 70B</td>
      </tr>
      <tr>
          <td><code>DeepSeek-V3</code></td>
          <td>671B 總參數、active 約 37B（依官方文件）</td>
      </tr>
  </tbody>
</table>
<p>模型在不同維度的影響：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>受影響因素</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>記憶體需求</td>
          <td>總參數 × 每權重 bytes</td>
      </tr>
      <tr>
          <td>生字速度上限</td>
          <td>active parameter × 每 token 讀取量 / <a href="/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth</a></td>
      </tr>
      <tr>
          <td>模型能力（社群常見回報）</td>
          <td>較強相關於總參數、但 active parameter 是底線</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p><strong>事實查核註</strong>：active parameter 跟模型能力的關係是社群常見回報、不是嚴格定理；具體模型在 coding / reasoning / 對話等任務的表現依訓練資料、RLHF、prompt 風格變化、需以 <a href="/blog/llm/knowledge-cards/swe-bench/" data-link-title="SWE-bench" data-link-desc="用真實 GitHub issue 量化 LLM coding 能力的 benchmark">SWE-bench</a> 等公開 benchmark 跟自己工作流校準。</p></blockquote>
<h2 id="設計責任">設計責任</h2>
<p>理解 active parameter 後可以解釋兩個現象：為什麼 30B MoE 跟 30B Dense 在同硬體下生字速度差很多（前者每 token 只走 3B active）、為什麼 MoE 模型能力對應的「等價 Dense 大小」不是簡單線性（社群常見回報接近總參數的 60% ~ 80% 等價 Dense 能力、但 case-by-case）。</p>
<p>選 MoE 模型時、active parameter 是速度判讀軸、總參數是記憶體判讀軸、能力判讀靠自己工作流的 benchmark；不要直接拿「30B」跟 Dense 30B 作能力對等。</p>
]]></content:encoded></item><item><title>Adam / AdamW</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/adam-adamw/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/adam-adamw/</guid><description>&lt;p>Adam（Adaptive Moment Estimation、Kingma &amp;amp; Ba, 2014）的核心概念是「&lt;strong>對每個參數維護兩個 EMA&lt;/strong>（gradient 的一階矩 = 平均、二階矩 = 變異）、用這兩個值自適應地縮放每個參數的更新步長」。AdamW（Loshchilov &amp;amp; Hutter, 2017）是 Adam 加上「decoupled weight decay」的修正版、是現代 LLM 訓練的標準 optimizer。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Adam 更新規則（簡化）：&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">m_t = β₁ × m_{t-1} + (1 - β₁) × g_t ← gradient 的 EMA（一階矩、方向）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">v_t = β₂ × v_{t-1} + (1 - β₂) × g_t² ← gradient² 的 EMA（二階矩、變動率）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">W -= lr × m_t / (sqrt(v_t) + ε)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> └──────┬──────┘
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> 每個參數獨立縮放
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> 經常變動的方向減小步長、穩定方向加大&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>跟其他 optimizer 對比：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>對比&lt;/th>
 &lt;th>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/sgd/" data-link-title="SGD" data-link-desc="Stochastic Gradient Descent：每次用 mini-batch 算 gradient 更新權重的基礎 optimizer">SGD&lt;/a>&lt;/th>
 &lt;th>SGD + Momentum&lt;/th>
 &lt;th>Adam&lt;/th>
 &lt;th>AdamW&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>每參數自適應&lt;/td>
 &lt;td>否&lt;/td>
 &lt;td>否&lt;/td>
 &lt;td>是&lt;/td>
 &lt;td>是&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>記憶體開銷&lt;/td>
 &lt;td>1× W（就 gradient）&lt;/td>
 &lt;td>2× W&lt;/td>
 &lt;td>3× W&lt;/td>
 &lt;td>3× W&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Hyperparameter&lt;/td>
 &lt;td>lr&lt;/td>
 &lt;td>lr + μ&lt;/td>
 &lt;td>lr + β₁、β₂&lt;/td>
 &lt;td>lr + β₁、β₂ + weight_decay&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM 訓練主流&lt;/td>
 &lt;td>否&lt;/td>
 &lt;td>否&lt;/td>
 &lt;td>早期&lt;/td>
 &lt;td>現在主流&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵：AdamW 對 weight decay 跟 lr 解耦、修正了 Adam 在「lr × weight_decay」交互上的 bug、是 GPT、Llama、Gemma 等系列訓練的標配。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 LLM training paper / config 看到 &lt;code>optimizer: AdamW&lt;/code>、&lt;code>betas: [0.9, 0.95]&lt;/code>、&lt;code>weight_decay: 0.1&lt;/code> 等就是這個 optimizer 的標準設定。記憶體佔用 = 模型權重 × 3（model + m + v）、加上 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/backpropagation/" data-link-title="Backpropagation" data-link-desc="從 output loss 反向遞推、用 chain rule 算出每個權重的 gradient 的演算法">backpropagation&lt;/a> 的 activation、是訓練 vs 推論記憶體差距的主要來源。&lt;/p></description><content:encoded><![CDATA[<p>Adam（Adaptive Moment Estimation、Kingma &amp; Ba, 2014）的核心概念是「<strong>對每個參數維護兩個 EMA</strong>（gradient 的一階矩 = 平均、二階矩 = 變異）、用這兩個值自適應地縮放每個參數的更新步長」。AdamW（Loshchilov &amp; Hutter, 2017）是 Adam 加上「decoupled weight decay」的修正版、是現代 LLM 訓練的標準 optimizer。</p>
<h2 id="概念位置">概念位置</h2>
<p>Adam 更新規則（簡化）：</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">m_t = β₁ × m_{t-1} + (1 - β₁) × g_t      ← gradient 的 EMA（一階矩、方向）
</span></span><span class="line"><span class="ln">2</span><span class="cl">v_t = β₂ × v_{t-1} + (1 - β₂) × g_t²     ← gradient² 的 EMA（二階矩、變動率）
</span></span><span class="line"><span class="ln">3</span><span class="cl">W -= lr × m_t / (sqrt(v_t) + ε)
</span></span><span class="line"><span class="ln">4</span><span class="cl">            └──────┬──────┘
</span></span><span class="line"><span class="ln">5</span><span class="cl">        每個參數獨立縮放
</span></span><span class="line"><span class="ln">6</span><span class="cl">        經常變動的方向減小步長、穩定方向加大</span></span></code></pre></div><p>跟其他 optimizer 對比：</p>
<table>
  <thead>
      <tr>
          <th>對比</th>
          <th><a href="/blog/llm/knowledge-cards/sgd/" data-link-title="SGD" data-link-desc="Stochastic Gradient Descent：每次用 mini-batch 算 gradient 更新權重的基礎 optimizer">SGD</a></th>
          <th>SGD + Momentum</th>
          <th>Adam</th>
          <th>AdamW</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>每參數自適應</td>
          <td>否</td>
          <td>否</td>
          <td>是</td>
          <td>是</td>
      </tr>
      <tr>
          <td>記憶體開銷</td>
          <td>1× W（就 gradient）</td>
          <td>2× W</td>
          <td>3× W</td>
          <td>3× W</td>
      </tr>
      <tr>
          <td>Hyperparameter</td>
          <td>lr</td>
          <td>lr + μ</td>
          <td>lr + β₁、β₂</td>
          <td>lr + β₁、β₂ + weight_decay</td>
      </tr>
      <tr>
          <td>LLM 訓練主流</td>
          <td>否</td>
          <td>否</td>
          <td>早期</td>
          <td>現在主流</td>
      </tr>
  </tbody>
</table>
<p>關鍵：AdamW 對 weight decay 跟 lr 解耦、修正了 Adam 在「lr × weight_decay」交互上的 bug、是 GPT、Llama、Gemma 等系列訓練的標配。</p>
<h2 id="設計責任">設計責任</h2>
<p>讀 LLM training paper / config 看到 <code>optimizer: AdamW</code>、<code>betas: [0.9, 0.95]</code>、<code>weight_decay: 0.1</code> 等就是這個 optimizer 的標準設定。記憶體佔用 = 模型權重 × 3（model + m + v）、加上 <a href="/blog/llm/knowledge-cards/backpropagation/" data-link-title="Backpropagation" data-link-desc="從 output loss 反向遞推、用 chain rule 算出每個權重的 gradient 的演算法">backpropagation</a> 的 activation、是訓練 vs 推論記憶體差距的主要來源。</p>
]]></content:encoded></item><item><title>Agent Loop</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/agent-loop/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/agent-loop/</guid><description>&lt;p>Agent loop 的核心概念是「LLM 在 plan → act → observe → plan 的循環中推進任務、直到任務完成或停止條件觸發」，有別於一次性回答。它讓 LLM 從「單回合工具呼叫」進化成「自主執行多步驟工作」、但同時放大 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prompt-injection/" data-link-title="Prompt Injection" data-link-desc="把惡意指令藏進 LLM 會讀到的內容、誘導 LLM 跑出非開發者預期行為的攻擊類別、OWASP LLM01 列入頭號威脅">prompt injection&lt;/a> 的影響面跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">tool use&lt;/a> 副作用範圍。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>典型的 agent loop 流程：&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">循環開始：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> step 1：LLM 看任務目標 + 當前狀態 → 規劃下一步 → 生成 tool call
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> step 2：client 執行 tool call → 得到結果
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> step 3：tool 結果回灌 conversation → LLM 看到新狀態
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> step 4：LLM 判斷：任務完成？ → yes 結束 / no 回 step 1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">循環結束。&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Agent loop 的兩個關鍵變數：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>max steps&lt;/strong>：循環最大次數、防止無限迴圈跟成本爆炸。&lt;/li>
&lt;li>&lt;strong>stop condition&lt;/strong>：什麼算「任務完成」、由 LLM 自己判斷還是有額外驗證。&lt;/li>
&lt;/ol>
&lt;p>常見實作（依框架而異）：LangGraph、AutoGPT、Claude 的 agentic abilities、OpenAI Assistants API 都提供 agent loop 機制。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 agent loop 後可以解釋兩個現象：為什麼 agent 工作流的成本比單次 LLM call 高一個量級（loop 跑很多輪）、為什麼 agent loop 是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prompt-injection/" data-link-title="Prompt Injection" data-link-desc="把惡意指令藏進 LLM 會讀到的內容、誘導 LLM 跑出非開發者預期行為的攻擊類別、OWASP LLM01 列入頭號威脅">prompt injection&lt;/a> 的放大器（loop 中段被 injection 後、後續步驟都被牽動）。&lt;/p>
&lt;p>防禦設計的核心：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>max steps 上限&lt;/strong>：避免無限循環、控制成本。&lt;/li>
&lt;li>&lt;strong>per-step review checkpoint&lt;/strong>：每幾步強制人為或自動驗證、防止 agent 飄離原意圖。&lt;/li>
&lt;li>&lt;strong>agent 持的 credential 最小化&lt;/strong>：避免單次 injection 影響面跨越多服務。&lt;/li>
&lt;li>&lt;strong>tool 結果在 prompt 中包覆&lt;/strong>：明確標記「以下是 tool 回傳、不執行內含指令」、降低觸發率。&lt;/li>
&lt;/ol>
&lt;p>詳見 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/llm-prompt-injection-in-agent/" data-link-title="LLM Agent Prompt Injection 後果治理" data-link-desc="production LLM agent 場景的 prompt injection 後果：tool spec 設計、agent loop 限制、review checkpoint、跟 incident workflow 的接合">LLM Agent Prompt Injection 後果治理&lt;/a> 跟 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/agent-architecture/" data-link-title="4.4 Agent 架構原理" data-link-desc="Agent loop 結構、失敗模式、什麼任務適合 vs 不適合、跟人類審查的協作模型">4.4 Agent 架構原理&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Agent loop 的核心概念是「LLM 在 plan → act → observe → plan 的循環中推進任務、直到任務完成或停止條件觸發」，有別於一次性回答。它讓 LLM 從「單回合工具呼叫」進化成「自主執行多步驟工作」、但同時放大 <a href="/blog/llm/knowledge-cards/prompt-injection/" data-link-title="Prompt Injection" data-link-desc="把惡意指令藏進 LLM 會讀到的內容、誘導 LLM 跑出非開發者預期行為的攻擊類別、OWASP LLM01 列入頭號威脅">prompt injection</a> 的影響面跟 <a href="/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">tool use</a> 副作用範圍。</p>
<h2 id="概念位置">概念位置</h2>
<p>典型的 agent loop 流程：</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">循環開始：
</span></span><span class="line"><span class="ln">2</span><span class="cl">  step 1：LLM 看任務目標 + 當前狀態 → 規劃下一步 → 生成 tool call
</span></span><span class="line"><span class="ln">3</span><span class="cl">  step 2：client 執行 tool call → 得到結果
</span></span><span class="line"><span class="ln">4</span><span class="cl">  step 3：tool 結果回灌 conversation → LLM 看到新狀態
</span></span><span class="line"><span class="ln">5</span><span class="cl">  step 4：LLM 判斷：任務完成？ → yes 結束 / no 回 step 1
</span></span><span class="line"><span class="ln">6</span><span class="cl">循環結束。</span></span></code></pre></div><p>Agent loop 的兩個關鍵變數：</p>
<ol>
<li><strong>max steps</strong>：循環最大次數、防止無限迴圈跟成本爆炸。</li>
<li><strong>stop condition</strong>：什麼算「任務完成」、由 LLM 自己判斷還是有額外驗證。</li>
</ol>
<p>常見實作（依框架而異）：LangGraph、AutoGPT、Claude 的 agentic abilities、OpenAI Assistants API 都提供 agent loop 機制。</p>
<h2 id="設計責任">設計責任</h2>
<p>理解 agent loop 後可以解釋兩個現象：為什麼 agent 工作流的成本比單次 LLM call 高一個量級（loop 跑很多輪）、為什麼 agent loop 是 <a href="/blog/llm/knowledge-cards/prompt-injection/" data-link-title="Prompt Injection" data-link-desc="把惡意指令藏進 LLM 會讀到的內容、誘導 LLM 跑出非開發者預期行為的攻擊類別、OWASP LLM01 列入頭號威脅">prompt injection</a> 的放大器（loop 中段被 injection 後、後續步驟都被牽動）。</p>
<p>防禦設計的核心：</p>
<ol>
<li><strong>max steps 上限</strong>：避免無限循環、控制成本。</li>
<li><strong>per-step review checkpoint</strong>：每幾步強制人為或自動驗證、防止 agent 飄離原意圖。</li>
<li><strong>agent 持的 credential 最小化</strong>：避免單次 injection 影響面跨越多服務。</li>
<li><strong>tool 結果在 prompt 中包覆</strong>：明確標記「以下是 tool 回傳、不執行內含指令」、降低觸發率。</li>
</ol>
<p>詳見 <a href="/blog/backend/07-security-data-protection/llm-prompt-injection-in-agent/" data-link-title="LLM Agent Prompt Injection 後果治理" data-link-desc="production LLM agent 場景的 prompt injection 後果：tool spec 設計、agent loop 限制、review checkpoint、跟 incident workflow 的接合">LLM Agent Prompt Injection 後果治理</a> 跟 <a href="/blog/llm/04-applications/agent-architecture/" data-link-title="4.4 Agent 架構原理" data-link-desc="Agent loop 結構、失敗模式、什麼任務適合 vs 不適合、跟人類審查的協作模型">4.4 Agent 架構原理</a>。</p>
]]></content:encoded></item><item><title>Agent Memory</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/agent-memory/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/agent-memory/</guid><description>&lt;p>Agent memory 的核心概念是「&lt;strong>agent 在 &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> 之外管理長期狀態的設計&lt;/strong>」、把使用者偏好、過去任務、知識、操作流程等持久化、跨 session 重用。借鑒人類認知科學的五個層次：working memory（context 本身）、short-term（session scratchpad）、long-term episodic（過去事件）、long-term semantic（事實 / 知識）、long-term procedural（流程 / 技能）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>五個層次的對比：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &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>Working memory&lt;/td>
 &lt;td>當前 query / forward pass&lt;/td>
 &lt;td>&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> 本身&lt;/td>
 &lt;td>當下對話、tool result、reasoning trace&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Short-term / session memory&lt;/td>
 &lt;td>單一 session（小時級）&lt;/td>
 &lt;td>Scratchpad 物件 / &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prompt-cache/" data-link-title="Prompt Cache" data-link-desc="重複出現的 prompt prefix 在推論伺服器或 LLM 服務端被 cache、後續 query 跳過 prefill、大幅降 cost 跟 TTFT">prompt cache&lt;/a>&lt;/td>
 &lt;td>Session 內累積的中間結果、用過的策略&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Long-term episodic memory&lt;/td>
 &lt;td>跨 session（永久）&lt;/td>
 &lt;td>DB / vector store / file system&lt;/td>
 &lt;td>「上週 alice 問過 X」「上個 sprint 解過 Y bug」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Long-term semantic memory&lt;/td>
 &lt;td>跨 session（永久）&lt;/td>
 &lt;td>DB / vector store / KG&lt;/td>
 &lt;td>「user 偏好 markdown 輸出」「專案用 React 18」「Python 3.11」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Long-term procedural memory&lt;/td>
 &lt;td>跨 session（永久）&lt;/td>
 &lt;td>Skill registry / playbook&lt;/td>
 &lt;td>「跑測試前先 npm install」「commit 前要 lint」&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>跟其他相關概念的關係：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>概念&lt;/th>
 &lt;th>跟 agent memory 的關係&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a>&lt;/td>
 &lt;td>Long-term semantic memory 的常見實作（vector store retrieval）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&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>&lt;/td>
 &lt;td>Working memory 的物理上限&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/system-prompt/" data-link-title="System Prompt" data-link-desc="LLM application 中由開發者預設、不直接顯示給使用者的指令層、定義模型的角色、行為規範、輸出格式">System prompt&lt;/a>&lt;/td>
 &lt;td>把 semantic / procedural memory 編碼進 scaffold 的方式&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/subagent/" data-link-title="Subagent" data-link-desc="Coding agent 中把特定責任拆給專門子 agent 的設計模式、各 subagent 有獨立 context、由 main agent 透過 handoff 調度">Subagent&lt;/a>&lt;/td>
 &lt;td>用 subagent 分隔不同 specialty 的 memory&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 agent paper / 設計 / framework docs 看到「agent memory」「memory store」「mem0 / Letta」「episodic / semantic memory」就是這 framing。寫 code 場景的判讀：&lt;/p></description><content:encoded><![CDATA[<p>Agent memory 的核心概念是「<strong>agent 在 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a> 之外管理長期狀態的設計</strong>」、把使用者偏好、過去任務、知識、操作流程等持久化、跨 session 重用。借鑒人類認知科學的五個層次：working memory（context 本身）、short-term（session scratchpad）、long-term episodic（過去事件）、long-term semantic（事實 / 知識）、long-term procedural（流程 / 技能）。</p>
<h2 id="概念位置">概念位置</h2>
<p>五個層次的對比：</p>
<table>
  <thead>
      <tr>
          <th>層</th>
          <th>範圍</th>
          <th>存放位置</th>
          <th>典型內容</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Working memory</td>
          <td>當前 query / forward pass</td>
          <td><a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">Context window</a> 本身</td>
          <td>當下對話、tool result、reasoning trace</td>
      </tr>
      <tr>
          <td>Short-term / session memory</td>
          <td>單一 session（小時級）</td>
          <td>Scratchpad 物件 / <a href="/blog/llm/knowledge-cards/prompt-cache/" data-link-title="Prompt Cache" data-link-desc="重複出現的 prompt prefix 在推論伺服器或 LLM 服務端被 cache、後續 query 跳過 prefill、大幅降 cost 跟 TTFT">prompt cache</a></td>
          <td>Session 內累積的中間結果、用過的策略</td>
      </tr>
      <tr>
          <td>Long-term episodic memory</td>
          <td>跨 session（永久）</td>
          <td>DB / vector store / file system</td>
          <td>「上週 alice 問過 X」「上個 sprint 解過 Y bug」</td>
      </tr>
      <tr>
          <td>Long-term semantic memory</td>
          <td>跨 session（永久）</td>
          <td>DB / vector store / KG</td>
          <td>「user 偏好 markdown 輸出」「專案用 React 18」「Python 3.11」</td>
      </tr>
      <tr>
          <td>Long-term procedural memory</td>
          <td>跨 session（永久）</td>
          <td>Skill registry / playbook</td>
          <td>「跑測試前先 npm install」「commit 前要 lint」</td>
      </tr>
  </tbody>
</table>
<p>跟其他相關概念的關係：</p>
<table>
  <thead>
      <tr>
          <th>概念</th>
          <th>跟 agent memory 的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a></td>
          <td>Long-term semantic memory 的常見實作（vector store retrieval）</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">Context window</a></td>
          <td>Working memory 的物理上限</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/system-prompt/" data-link-title="System Prompt" data-link-desc="LLM application 中由開發者預設、不直接顯示給使用者的指令層、定義模型的角色、行為規範、輸出格式">System prompt</a></td>
          <td>把 semantic / procedural memory 編碼進 scaffold 的方式</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/subagent/" data-link-title="Subagent" data-link-desc="Coding agent 中把特定責任拆給專門子 agent 的設計模式、各 subagent 有獨立 context、由 main agent 透過 handoff 調度">Subagent</a></td>
          <td>用 subagent 分隔不同 specialty 的 memory</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 agent paper / 設計 / framework docs 看到「agent memory」「memory store」「mem0 / Letta」「episodic / semantic memory」就是這 framing。寫 code 場景的判讀：</p>
<ol>
<li><strong>不是每個 agent 都需要五個層次都用</strong>：autocomplete 只要 working memory；對話 IDE assistant 多用 working + session；長期 coding agent 才需要 long-term</li>
<li><strong>Long-term memory 的兩條實作路線</strong>：(a) retrieval-on-demand（vector store + similarity search、見 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a>）、(b) injection-on-startup（把關鍵 memory 編進 system prompt、適合小量穩定的 procedural）</li>
<li><strong>失敗模式</strong>：memory drift（舊 memory 過時但仍被 retrieve）、PII 寫入（user 不知情下被存）、context 污染（不相關 memory 被 inject 進 working）、跟 <a href="/blog/llm/knowledge-cards/hallucination/" data-link-title="Hallucination" data-link-desc="LLM 生成內容看起來合理但事實錯誤、引用不存在的來源、虛構不存在的 entity 的現象">hallucination</a> 互相 boost</li>
<li><strong>跟 <a href="/blog/llm/04-applications/agent-memory-architecture/" data-link-title="4.19 Agent memory 分層架構" data-link-desc="Agent 在 context window 之外管理長期狀態的設計：working / short-term / long-term episodic / semantic / procedural 五個層次、寫入時機、retrieval 設計、失敗模式">4.19 agent memory 章節</a> 的關係</strong>：本卡是分類定義、章節是工程實務（寫入時機、retrieval 設計、失敗模式緩解）</li>
</ol>
]]></content:encoded></item><item><title>Attention</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/attention/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/attention/</guid><description>&lt;p>Attention 的核心概念是「Transformer 中讓每個 token 對其他 token 加權平均、產生 context-aware 表示」的計算機制。具體運作是用 Query（Q）、Key（K）、Value（V）三組向量算 attention score、再用 softmax 把 score 變成權重、最後加權平均 V。這個機制是 &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> 概念的源頭、也是 &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> 上限的計算瓶頸。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Attention 在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/transformer/" data-link-title="Transformer" data-link-desc="寫 code 用的 LLM 神經網路架構：基於 attention 機制、自回歸生成 token">Transformer&lt;/a> block 中的位置：&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">Transformer block：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ├── Layer Norm
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> ├── Attention（本卡聚焦）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> │ ├── Q · K^T → attention score
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> │ ├── softmax → weight
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> │ └── weight · V → output
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> ├── Layer Norm
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl"> └── FFN 層（或 MoE）&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>簡化的計算公式：&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(Q, K, V) = softmax(Q · K^T / √d) · V&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Attention 的常見變體（影響 KV cache 體積跟推論性能）：&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>MHA（Multi-Head Attention）&lt;/td>
 &lt;td>原始 Transformer 設計、每 head 獨立 Q / K / V&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>GQA（Grouped-Query Attention）&lt;/td>
 &lt;td>head group 共用 K / V、KV cache 體積減小、推論較快&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>MLA（Multi-head Latent Attention）&lt;/td>
 &lt;td>DeepSeek 提出、KV cache 壓縮更激進&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Flash Attention&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/flash-attention/" data-link-title="Flash Attention" data-link-desc="Attention 計算的記憶體友善實作、減少 GPU memory 讀寫、提升長 context 推論吞吐">演算法層的優化實作&lt;/a>、跟變體獨立&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 attention 後可以解釋三個現象：為什麼 LLM 推論的記憶體用量隨 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context&lt;/a> 長度線性增加（KV cache 是 attention 暫存）、為什麼 &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> 對品質影響有不對稱性（K 用於 score 比較、V 用於加權平均、誤差累積方式不同）、為什麼不同 attention 變體在同等模型大小下推論速度差異明顯（KV cache 體積跟卡間頻寬需求不同）。&lt;/p>
&lt;p>工程實務上、Attention 是 LLM 推論性能跟記憶體需求的最大來源、量化策略、context 上限、併發數設計都圍繞 attention 跟 KV cache 展開。&lt;/p></description><content:encoded><![CDATA[<p>Attention 的核心概念是「Transformer 中讓每個 token 對其他 token 加權平均、產生 context-aware 表示」的計算機制。具體運作是用 Query（Q）、Key（K）、Value（V）三組向量算 attention score、再用 softmax 把 score 變成權重、最後加權平均 V。這個機制是 <a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 概念的源頭、也是 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a> 上限的計算瓶頸。</p>
<h2 id="概念位置">概念位置</h2>
<p>Attention 在 <a href="/blog/llm/knowledge-cards/transformer/" data-link-title="Transformer" data-link-desc="寫 code 用的 LLM 神經網路架構：基於 attention 機制、自回歸生成 token">Transformer</a> block 中的位置：</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">Transformer block：
</span></span><span class="line"><span class="ln">2</span><span class="cl">  ├── Layer Norm
</span></span><span class="line"><span class="ln">3</span><span class="cl">  ├── Attention（本卡聚焦）
</span></span><span class="line"><span class="ln">4</span><span class="cl">  │     ├── Q · K^T → attention score
</span></span><span class="line"><span class="ln">5</span><span class="cl">  │     ├── softmax → weight
</span></span><span class="line"><span class="ln">6</span><span class="cl">  │     └── weight · V → output
</span></span><span class="line"><span class="ln">7</span><span class="cl">  ├── Layer Norm
</span></span><span class="line"><span class="ln">8</span><span class="cl">  └── FFN 層（或 MoE）</span></span></code></pre></div><p>簡化的計算公式：</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 / √d) · V</span></span></code></pre></div><p>Attention 的常見變體（影響 KV cache 體積跟推論性能）：</p>
<table>
  <thead>
      <tr>
          <th>變體</th>
          <th>描述</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>MHA（Multi-Head Attention）</td>
          <td>原始 Transformer 設計、每 head 獨立 Q / K / V</td>
      </tr>
      <tr>
          <td>GQA（Grouped-Query Attention）</td>
          <td>head group 共用 K / V、KV cache 體積減小、推論較快</td>
      </tr>
      <tr>
          <td>MLA（Multi-head Latent Attention）</td>
          <td>DeepSeek 提出、KV cache 壓縮更激進</td>
      </tr>
      <tr>
          <td>Flash Attention</td>
          <td><a href="/blog/llm/knowledge-cards/flash-attention/" data-link-title="Flash Attention" data-link-desc="Attention 計算的記憶體友善實作、減少 GPU memory 讀寫、提升長 context 推論吞吐">演算法層的優化實作</a>、跟變體獨立</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>理解 attention 後可以解釋三個現象：為什麼 LLM 推論的記憶體用量隨 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context</a> 長度線性增加（KV cache 是 attention 暫存）、為什麼 <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 用於 score 比較、V 用於加權平均、誤差累積方式不同）、為什麼不同 attention 變體在同等模型大小下推論速度差異明顯（KV cache 體積跟卡間頻寬需求不同）。</p>
<p>工程實務上、Attention 是 LLM 推論性能跟記憶體需求的最大來源、量化策略、context 上限、併發數設計都圍繞 attention 跟 KV cache 展開。</p>
]]></content:encoded></item><item><title>Backpropagation</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/backpropagation/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/backpropagation/</guid><description>&lt;p>Backpropagation（反向傳播）的核心概念是「從輸出端的 loss 開始、用 chain rule 一層層往輸入端遞推、算出每個權重的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/gradient/" data-link-title="Gradient" data-link-desc="loss function 對權重的偏微分向量、指出「該往哪個方向調權重才能讓 loss 下降最快」">gradient&lt;/a>」。它是訓練神經網路的核心演算法、沒有它就無法在合理時間內訓練深度模型。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Backpropagation 是訓練 loop 的中段、夾在 forward pass 跟權重更新之間：&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">[forward pass]：input → layer1 → layer2 → ... → output → loss
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">[backpropagation]：把 loss 對最後一層權重的偏微分算出來
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ←─ chain rule ─ 再往前傳播一層、算前一層的 gradient
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> ←─ chain rule ─ ...一路傳回輸入層
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">[optimizer step]：每個權重 w 用對應的 gradient 更新&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>關鍵特性：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>計算成本 ≈ forward pass 的 2~3 倍&lt;/strong>：每個 layer 都要存 forward 階段的中間值（activation）、反向時拿來算 gradient。所以訓練比推論貴一個量級。&lt;/li>
&lt;li>&lt;strong>記憶體佔用 = forward 階段 activation 的累計&lt;/strong>：這是訓練比推論吃 VRAM 的主因、不是「權重變大」、是「activation 要存著」。&lt;/li>
&lt;li>&lt;strong>數值穩定性敏感&lt;/strong>：long chain 的 chain rule 容易導致 gradient 爆炸或消失、見 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/gradient/" data-link-title="Gradient" data-link-desc="loss function 對權重的偏微分向量、指出「該往哪個方向調權重才能讓 loss 下降最快」">gradient&lt;/a> 卡。&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>推論階段完全不用 backpropagation。理解這點能解釋幾個現象：為什麼同樣模型訓練要 8 卡 H100 一週、推論單卡就跑得動（差幾十倍的計算與記憶體需求）；為什麼 LoRA / QLoRA 等 parameter-efficient fine-tuning 能大幅降低訓練成本（凍住大部分權重、只對少數 LoRA 矩陣做 backpropagation）；為什麼 inference framework（llama.cpp、vLLM）跟 training framework（PyTorch、JAX）的設計重點完全不同。&lt;/p></description><content:encoded><![CDATA[<p>Backpropagation（反向傳播）的核心概念是「從輸出端的 loss 開始、用 chain rule 一層層往輸入端遞推、算出每個權重的 <a href="/blog/llm/knowledge-cards/gradient/" data-link-title="Gradient" data-link-desc="loss function 對權重的偏微分向量、指出「該往哪個方向調權重才能讓 loss 下降最快」">gradient</a>」。它是訓練神經網路的核心演算法、沒有它就無法在合理時間內訓練深度模型。</p>
<h2 id="概念位置">概念位置</h2>
<p>Backpropagation 是訓練 loop 的中段、夾在 forward pass 跟權重更新之間：</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">[forward pass]：input → layer1 → layer2 → ... → output → loss
</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">[backpropagation]：把 loss 對最後一層權重的偏微分算出來
</span></span><span class="line"><span class="ln">4</span><span class="cl">                  ←─ chain rule ─ 再往前傳播一層、算前一層的 gradient
</span></span><span class="line"><span class="ln">5</span><span class="cl">                  ←─ chain rule ─ ...一路傳回輸入層
</span></span><span class="line"><span class="ln">6</span><span class="cl">                                                          ↓
</span></span><span class="line"><span class="ln">7</span><span class="cl">[optimizer step]：每個權重 w 用對應的 gradient 更新</span></span></code></pre></div><p>關鍵特性：</p>
<ol>
<li><strong>計算成本 ≈ forward pass 的 2~3 倍</strong>：每個 layer 都要存 forward 階段的中間值（activation）、反向時拿來算 gradient。所以訓練比推論貴一個量級。</li>
<li><strong>記憶體佔用 = forward 階段 activation 的累計</strong>：這是訓練比推論吃 VRAM 的主因、不是「權重變大」、是「activation 要存著」。</li>
<li><strong>數值穩定性敏感</strong>：long chain 的 chain rule 容易導致 gradient 爆炸或消失、見 <a href="/blog/llm/knowledge-cards/gradient/" data-link-title="Gradient" data-link-desc="loss function 對權重的偏微分向量、指出「該往哪個方向調權重才能讓 loss 下降最快」">gradient</a> 卡。</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>推論階段完全不用 backpropagation。理解這點能解釋幾個現象：為什麼同樣模型訓練要 8 卡 H100 一週、推論單卡就跑得動（差幾十倍的計算與記憶體需求）；為什麼 LoRA / QLoRA 等 parameter-efficient fine-tuning 能大幅降低訓練成本（凍住大部分權重、只對少數 LoRA 矩陣做 backpropagation）；為什麼 inference framework（llama.cpp、vLLM）跟 training framework（PyTorch、JAX）的設計重點完全不同。</p>
]]></content:encoded></item><item><title>Batching</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/batching/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/batching/</guid><description>&lt;p>Batching 的核心概念是「&lt;strong>多個 request 在同一個 forward pass 內一起跑、攤平 model weights 從記憶體讀到處理器的成本&lt;/strong>」。是 production LLM inference 的核心優化——跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth&lt;/a> 瓶頸對接：讀一次 model weights、能 process N 個 request、單 request 的 effective throughput 上升 N 倍。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Batching 介於 inference engine 內部、跟 &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> 一起決定一個 GPU / Apple Silicon 能服務多少並發 user。但 batching 不是 free——靜態 batching 要等湊滿才跑、延遲首字延遲；連續 batching 平衡 throughput + latency 但實作複雜。Single-user 場景常無 batching（local Mac 跑 Ollama 即此情境）、production multi-tenant 必有 batching。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&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>No batching&lt;/td>
 &lt;td>每 request 獨立 forward pass&lt;/td>
 &lt;td>Single-user、極低 latency 要求&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Static batching&lt;/td>
 &lt;td>等湊滿 N 個 request 才跑&lt;/td>
 &lt;td>高 throughput 批次處理（embedding pipeline、文件 ingest）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Continuous batching&lt;/td>
 &lt;td>新 request 動態加入正在跑的 batch&lt;/td>
 &lt;td>vLLM / TGI / SGLang 等 production inference 主流&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>In-flight batching&lt;/td>
 &lt;td>不同 sequence 在不同 step 同時推&lt;/td>
 &lt;td>NVIDIA Triton + TensorRT-LLM 等深度優化&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>實務觀察：production LLM 服務 throughput 在 batch size 4-32 之間有明顯提升、超過 GPU memory 上限後反而下降（KV cache 跟 model weight 競爭記憶體）。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>選 batching 策略看兩維度：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>應用 latency tolerance&lt;/strong>：
&lt;ul>
&lt;li>互動式 UI（chatbot、IDE 補完）→ continuous batching、低 latency 優先&lt;/li>
&lt;li>批次處理（夜間 summarization）→ static batching、throughput 優先&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>硬體 KV cache 上限&lt;/strong>：
&lt;ul>
&lt;li>GPU memory - model weights = batchable 容量&lt;/li>
&lt;li>預估 max batch size = available_memory / per_user_kv_cache&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>Embedding 服務通常 batch 16-128 都 OK（embedding 是純 forward pass、無 KV cache 累積）；chat / generation 服務 batch size 受 KV cache 嚴格限制。&lt;/p></description><content:encoded><![CDATA[<p>Batching 的核心概念是「<strong>多個 request 在同一個 forward pass 內一起跑、攤平 model weights 從記憶體讀到處理器的成本</strong>」。是 production LLM inference 的核心優化——跟 <a href="/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth</a> 瓶頸對接：讀一次 model weights、能 process N 個 request、單 request 的 effective throughput 上升 N 倍。</p>
<h2 id="概念位置">概念位置</h2>
<p>Batching 介於 inference engine 內部、跟 <a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 一起決定一個 GPU / Apple Silicon 能服務多少並發 user。但 batching 不是 free——靜態 batching 要等湊滿才跑、延遲首字延遲；連續 batching 平衡 throughput + latency 但實作複雜。Single-user 場景常無 batching（local Mac 跑 Ollama 即此情境）、production multi-tenant 必有 batching。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<table>
  <thead>
      <tr>
          <th>策略</th>
          <th>機制</th>
          <th>適合場景</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>No batching</td>
          <td>每 request 獨立 forward pass</td>
          <td>Single-user、極低 latency 要求</td>
      </tr>
      <tr>
          <td>Static batching</td>
          <td>等湊滿 N 個 request 才跑</td>
          <td>高 throughput 批次處理（embedding pipeline、文件 ingest）</td>
      </tr>
      <tr>
          <td>Continuous batching</td>
          <td>新 request 動態加入正在跑的 batch</td>
          <td>vLLM / TGI / SGLang 等 production inference 主流</td>
      </tr>
      <tr>
          <td>In-flight batching</td>
          <td>不同 sequence 在不同 step 同時推</td>
          <td>NVIDIA Triton + TensorRT-LLM 等深度優化</td>
      </tr>
  </tbody>
</table>
<p>實務觀察：production LLM 服務 throughput 在 batch size 4-32 之間有明顯提升、超過 GPU memory 上限後反而下降（KV cache 跟 model weight 競爭記憶體）。</p>
<h2 id="設計責任">設計責任</h2>
<p>選 batching 策略看兩維度：</p>
<ol>
<li><strong>應用 latency tolerance</strong>：
<ul>
<li>互動式 UI（chatbot、IDE 補完）→ continuous batching、低 latency 優先</li>
<li>批次處理（夜間 summarization）→ static batching、throughput 優先</li>
</ul>
</li>
<li><strong>硬體 KV cache 上限</strong>：
<ul>
<li>GPU memory - model weights = batchable 容量</li>
<li>預估 max batch size = available_memory / per_user_kv_cache</li>
</ul>
</li>
</ol>
<p>Embedding 服務通常 batch 16-128 都 OK（embedding 是純 forward pass、無 KV cache 累積）；chat / generation 服務 batch size 受 KV cache 嚴格限制。</p>
<p>詳細跟 production 部署 capacity planning 的對接見 <a href="/blog/llm/04-applications/production-resource-planning/" data-link-title="4.9 Production 部署的資源評估原理" data-link-desc="從本地單 user 到 production multi-tenant：concurrent users、cost model、observability、SLA、capacity planning 的設計取捨">4.9 Production 資源評估</a>；跟 <a href="/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">autoregressive</a> 推論的單 token 瓶頸對應的優化討論見 <a href="/blog/llm/03-theoretical-foundations/attention-mechanism/" data-link-title="3.2 Attention 機制" data-link-desc="Query / Key / Value、scaled dot-product attention、multi-head attention：Transformer 的核心運算">3.2 attention 機制</a>。</p>
]]></content:encoded></item><item><title>Beam Search</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/beam-search/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/beam-search/</guid><description>&lt;p>Beam search 的核心概念是「&lt;strong>每步同時保留 K 條最有機率的候選 sequence（beam width = K）、最終挑一條總機率最高的當輸出&lt;/strong>」。相比 greedy decoding 只保一條、beam search 能探索更多可能、避免「貪心一時、累積失誤」；但對話 / coding 場景常出現副作用、是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/top-p-sampling/" data-link-title="Top-K / Top-P / Min-P Sampling" data-link-desc="從機率分佈取樣前先過濾低機率 token 的三種策略、現代 LLM 推論主流">top-p sampling&lt;/a> 取代它的原因。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Beam search 跟其他 decoding 策略的對比：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>策略&lt;/th>
 &lt;th>機制&lt;/th>
 &lt;th>適合場景&lt;/th>
 &lt;th>LLM 常見性&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Greedy&lt;/td>
 &lt;td>每步選機率最大的 token&lt;/td>
 &lt;td>確定性任務、debugging&lt;/td>
 &lt;td>高&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Beam search (K)&lt;/strong>&lt;/td>
 &lt;td>維護 K 條候選、最後挑總機率最高的&lt;/td>
 &lt;td>機器翻譯、summarization、有「正確答案」的任務&lt;/td>
 &lt;td>中（傳統 NLP 主流）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Top-k / top-p / min-p&lt;/td>
 &lt;td>從機率分佈隨機取樣（限制候選範圍）&lt;/td>
 &lt;td>對話、寫作、coding、創意輸出&lt;/td>
 &lt;td>高（LLM 主流）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Beam search 的算法直覺：&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">beam_width = 3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">Step 1：從機率分佈挑前 3 個 token、得到 3 條 partial sequence
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">Step 2：每條 partial 各自展開所有可能下個 token、組合機率排序、保留前 3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">Step 3：重複 Step 2、直到所有 beam 都遇到 EOS 或達到 max_length
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">Final：選總 log-probability 最高的 beam 當輸出&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Beam search 在 LLM chat / coding 場景的副作用：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>輸出偏 boilerplate&lt;/strong>：K 個 beam 容易收斂到同樣的高頻開頭（「Sure!」「That&amp;rsquo;s a great question」）、各 beam 平均化掉原本該有的多樣性。&lt;/li>
&lt;li>&lt;strong>缺乏隨機性&lt;/strong>：給同 prompt 永遠生同輸出、缺乏寫作 / 創意任務需要的變化。&lt;/li>
&lt;li>&lt;strong>計算貴&lt;/strong>：K 倍記憶體 + K 倍 forward pass。&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 inference framework 看到 &lt;code>num_beams: 1&lt;/code> 預設值就是用 greedy/sampling、&lt;code>num_beams: 5&lt;/code> 才會開 beam search。寫 code 場景的判讀：日常用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/top-p-sampling/" data-link-title="Top-K / Top-P / Min-P Sampling" data-link-desc="從機率分佈取樣前先過濾低機率 token 的三種策略、現代 LLM 推論主流">top-p sampling&lt;/a> 為主、需要確定性測試用 greedy、需要「在多個候選中挑最好的」用 best-of-N（每個獨立 sample、再選 reward 最高）而非 beam search。Beam search 在現代 LLM chat 場景已經少用、但在 translation / structured output 等「有正確答案」場景仍見。&lt;/p></description><content:encoded><![CDATA[<p>Beam search 的核心概念是「<strong>每步同時保留 K 條最有機率的候選 sequence（beam width = K）、最終挑一條總機率最高的當輸出</strong>」。相比 greedy decoding 只保一條、beam search 能探索更多可能、避免「貪心一時、累積失誤」；但對話 / coding 場景常出現副作用、是 <a href="/blog/llm/knowledge-cards/top-p-sampling/" data-link-title="Top-K / Top-P / Min-P Sampling" data-link-desc="從機率分佈取樣前先過濾低機率 token 的三種策略、現代 LLM 推論主流">top-p sampling</a> 取代它的原因。</p>
<h2 id="概念位置">概念位置</h2>
<p>Beam search 跟其他 decoding 策略的對比：</p>
<table>
  <thead>
      <tr>
          <th>策略</th>
          <th>機制</th>
          <th>適合場景</th>
          <th>LLM 常見性</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Greedy</td>
          <td>每步選機率最大的 token</td>
          <td>確定性任務、debugging</td>
          <td>高</td>
      </tr>
      <tr>
          <td><strong>Beam search (K)</strong></td>
          <td>維護 K 條候選、最後挑總機率最高的</td>
          <td>機器翻譯、summarization、有「正確答案」的任務</td>
          <td>中（傳統 NLP 主流）</td>
      </tr>
      <tr>
          <td>Top-k / top-p / min-p</td>
          <td>從機率分佈隨機取樣（限制候選範圍）</td>
          <td>對話、寫作、coding、創意輸出</td>
          <td>高（LLM 主流）</td>
      </tr>
  </tbody>
</table>
<p>Beam search 的算法直覺：</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">beam_width = 3
</span></span><span class="line"><span class="ln">2</span><span class="cl">Step 1：從機率分佈挑前 3 個 token、得到 3 條 partial sequence
</span></span><span class="line"><span class="ln">3</span><span class="cl">Step 2：每條 partial 各自展開所有可能下個 token、組合機率排序、保留前 3
</span></span><span class="line"><span class="ln">4</span><span class="cl">Step 3：重複 Step 2、直到所有 beam 都遇到 EOS 或達到 max_length
</span></span><span class="line"><span class="ln">5</span><span class="cl">Final：選總 log-probability 最高的 beam 當輸出</span></span></code></pre></div><p>Beam search 在 LLM chat / coding 場景的副作用：</p>
<ol>
<li><strong>輸出偏 boilerplate</strong>：K 個 beam 容易收斂到同樣的高頻開頭（「Sure!」「That&rsquo;s a great question」）、各 beam 平均化掉原本該有的多樣性。</li>
<li><strong>缺乏隨機性</strong>：給同 prompt 永遠生同輸出、缺乏寫作 / 創意任務需要的變化。</li>
<li><strong>計算貴</strong>：K 倍記憶體 + K 倍 forward pass。</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 inference framework 看到 <code>num_beams: 1</code> 預設值就是用 greedy/sampling、<code>num_beams: 5</code> 才會開 beam search。寫 code 場景的判讀：日常用 <a href="/blog/llm/knowledge-cards/top-p-sampling/" data-link-title="Top-K / Top-P / Min-P Sampling" data-link-desc="從機率分佈取樣前先過濾低機率 token 的三種策略、現代 LLM 推論主流">top-p sampling</a> 為主、需要確定性測試用 greedy、需要「在多個候選中挑最好的」用 best-of-N（每個獨立 sample、再選 reward 最高）而非 beam search。Beam search 在現代 LLM chat 場景已經少用、但在 translation / structured output 等「有正確答案」場景仍見。</p>
]]></content:encoded></item><item><title>Bind Address</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/bind-address/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/bind-address/</guid><description>&lt;p>Bind address 的核心概念是「伺服器啟動時決定『監聽哪個網路介面上的請求』」。同一個 port 在不同 bind address 下、能接受的請求來源完全不同；對本地 LLM 推論伺服器（Ollama / llama-server / LM Studio）來說、bind address 是決定誰能連到模型的最直接設定。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>三層典型 bind address 的暴露範圍：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>bind address&lt;/th>
 &lt;th>接受來源&lt;/th>
 &lt;th>個人 dev 場景的常見用途&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;code>127.0.0.1&lt;/code> / &lt;code>localhost&lt;/code>&lt;/td>
 &lt;td>只本機 process&lt;/td>
 &lt;td>VS Code 連本機 server、最安全預設&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>具體 LAN IP（如 &lt;code>192.168.x.x&lt;/code>）&lt;/td>
 &lt;td>同網段設備&lt;/td>
 &lt;td>想分享給家裡桌機 / 筆電&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>0.0.0.0&lt;/code>&lt;/td>
 &lt;td>所有網路介面&lt;/td>
 &lt;td>容器化 / 想接受 LAN + WAN（風險高）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵差異：&lt;/p>
&lt;ol>
&lt;li>&lt;code>127.0.0.1&lt;/code> 只接 loopback、無論其他網路介面狀態都不接外部請求。&lt;/li>
&lt;li>&lt;code>0.0.0.0&lt;/code> 在所有介面上監聽、若機器有 public IP 或在公開 Wi-Fi、就會被網路上其他人連到。&lt;/li>
&lt;li>具體 LAN IP 是中間地帶、限定來源到該介面的網段。&lt;/li>
&lt;/ol>
&lt;p>檢查當前 bind 狀態的指令：&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">&lt;span class="c1"># macOS / Linux&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">lsof -i -P -n &lt;span class="p">|&lt;/span> grep LISTEN &lt;span class="p">|&lt;/span> grep &amp;lt;port&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="c1"># Linux&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">ss -lntp &lt;span class="p">|&lt;/span> grep &amp;lt;port&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">&lt;span class="c1"># 或&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl">netstat -an &lt;span class="p">|&lt;/span> grep LISTEN &lt;span class="p">|&lt;/span> grep &amp;lt;port&amp;gt;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>看到 &lt;code>127.0.0.1:&amp;lt;port&amp;gt;&lt;/code> 是 loopback、&lt;code>*:&amp;lt;port&amp;gt;&lt;/code> 或 &lt;code>0.0.0.0:&amp;lt;port&amp;gt;&lt;/code> 是所有介面。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 bind address 後可以解釋兩個現象：為什麼預設安全的伺服器都 bind 到 &lt;code>127.0.0.1&lt;/code>（避免不小心暴露）、為什麼 Docker &lt;code>-p 8080:8080&lt;/code> 預設 bind 到 &lt;code>0.0.0.0&lt;/code>（容器化的便利性、但對個人 dev 是潛在暴露點）。&lt;/p>
&lt;p>設計本地推論伺服器時、預設 loopback、想分享 LAN 時 bind 到具體 LAN IP（不要直接 &lt;code>0.0.0.0&lt;/code>）、要對外時加 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/api-gateway/" data-link-title="API Gateway" data-link-desc="說明外部流量如何先收斂到一層可集中控制的入口">reverse proxy&lt;/a> + auth + TLS。詳見 &lt;a href="https://tarrragon.github.io/blog/llm/06-security/inference-server-binding/" data-link-title="6.1 推論伺服器的綁定與暴露範圍" data-link-desc="個人 dev 場景下 llama-server / Ollama / LM Studio 的 bind address 判讀：127.0.0.1 vs LAN vs 反代、預設安全、誤開放給內網的後果">6.1 推論伺服器的綁定與暴露範圍&lt;/a> 跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/entrypoint-and-server-protection/" data-link-title="7.3 入口治理與伺服器防護" data-link-desc="以問題驅動方式整理對外入口、管理平面與伺服器邊界">7.3 入口治理與伺服器防護&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Bind address 的核心概念是「伺服器啟動時決定『監聽哪個網路介面上的請求』」。同一個 port 在不同 bind address 下、能接受的請求來源完全不同；對本地 LLM 推論伺服器（Ollama / llama-server / LM Studio）來說、bind address 是決定誰能連到模型的最直接設定。</p>
<h2 id="概念位置">概念位置</h2>
<p>三層典型 bind address 的暴露範圍：</p>
<table>
  <thead>
      <tr>
          <th>bind address</th>
          <th>接受來源</th>
          <th>個人 dev 場景的常見用途</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>127.0.0.1</code> / <code>localhost</code></td>
          <td>只本機 process</td>
          <td>VS Code 連本機 server、最安全預設</td>
      </tr>
      <tr>
          <td>具體 LAN IP（如 <code>192.168.x.x</code>）</td>
          <td>同網段設備</td>
          <td>想分享給家裡桌機 / 筆電</td>
      </tr>
      <tr>
          <td><code>0.0.0.0</code></td>
          <td>所有網路介面</td>
          <td>容器化 / 想接受 LAN + WAN（風險高）</td>
      </tr>
  </tbody>
</table>
<p>關鍵差異：</p>
<ol>
<li><code>127.0.0.1</code> 只接 loopback、無論其他網路介面狀態都不接外部請求。</li>
<li><code>0.0.0.0</code> 在所有介面上監聽、若機器有 public IP 或在公開 Wi-Fi、就會被網路上其他人連到。</li>
<li>具體 LAN IP 是中間地帶、限定來源到該介面的網段。</li>
</ol>
<p>檢查當前 bind 狀態的指令：</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"><span class="c1"># macOS / Linux</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">lsof -i -P -n <span class="p">|</span> grep LISTEN <span class="p">|</span> grep &lt;port&gt;
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># Linux</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">ss -lntp <span class="p">|</span> grep &lt;port&gt;
</span></span><span class="line"><span class="ln">6</span><span class="cl">
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="c1"># 或</span>
</span></span><span class="line"><span class="ln">8</span><span class="cl">netstat -an <span class="p">|</span> grep LISTEN <span class="p">|</span> grep &lt;port&gt;</span></span></code></pre></div><p>看到 <code>127.0.0.1:&lt;port&gt;</code> 是 loopback、<code>*:&lt;port&gt;</code> 或 <code>0.0.0.0:&lt;port&gt;</code> 是所有介面。</p>
<h2 id="設計責任">設計責任</h2>
<p>理解 bind address 後可以解釋兩個現象：為什麼預設安全的伺服器都 bind 到 <code>127.0.0.1</code>（避免不小心暴露）、為什麼 Docker <code>-p 8080:8080</code> 預設 bind 到 <code>0.0.0.0</code>（容器化的便利性、但對個人 dev 是潛在暴露點）。</p>
<p>設計本地推論伺服器時、預設 loopback、想分享 LAN 時 bind 到具體 LAN IP（不要直接 <code>0.0.0.0</code>）、要對外時加 <a href="/blog/backend/knowledge-cards/api-gateway/" data-link-title="API Gateway" data-link-desc="說明外部流量如何先收斂到一層可集中控制的入口">reverse proxy</a> + auth + TLS。詳見 <a href="/blog/llm/06-security/inference-server-binding/" data-link-title="6.1 推論伺服器的綁定與暴露範圍" data-link-desc="個人 dev 場景下 llama-server / Ollama / LM Studio 的 bind address 判讀：127.0.0.1 vs LAN vs 反代、預設安全、誤開放給內網的後果">6.1 推論伺服器的綁定與暴露範圍</a> 跟 <a href="/blog/backend/07-security-data-protection/entrypoint-and-server-protection/" data-link-title="7.3 入口治理與伺服器防護" data-link-desc="以問題驅動方式整理對外入口、管理平面與伺服器邊界">7.3 入口治理與伺服器防護</a>。</p>
]]></content:encoded></item><item><title>BPE（Byte-Pair Encoding）</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/bpe/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/bpe/</guid><description>&lt;p>BPE（Byte-Pair Encoding、Sennrich et al., 2015 引入 NLP）的核心概念是「&lt;strong>從字元開始、反覆找『出現頻率最高的字元對』把它合併成新 token、直到達到目標詞彙表大小&lt;/strong>」。是 GPT、Llama、Mistral 等主流 LLM 的 tokenization 演算法、能在「字元」跟「整詞」之間找平衡。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>BPE 訓練 tokenizer 的流程（簡化）：&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">Step 0：vocab = 所有單一字元（256 個 byte / Unicode 字符）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">迭代：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> Step 1：掃描 corpus、統計所有相鄰 token 對的出現頻率
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> Step 2：找出現最多的字元對（如 &amp;#34;l&amp;#34; + &amp;#34;o&amp;#34; 一起出現 1M 次）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> Step 3：把它當新 token 加進 vocab、把 corpus 裡所有這個對換成新 token
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> Step 4：回到 Step 1、直到 vocab 達到目標大小（如 50K、128K、256K）&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>實際 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a> 化的結果：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>文字&lt;/th>
 &lt;th>BPE token 化結果&lt;/th>
 &lt;th>理由&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;code>Hello&lt;/code>&lt;/td>
 &lt;td>&lt;code>[&amp;quot;Hello&amp;quot;]&lt;/code>&lt;/td>
 &lt;td>高頻單字、整詞當一個 token&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>Hellobot&lt;/code>&lt;/td>
 &lt;td>&lt;code>[&amp;quot;Hello&amp;quot;, &amp;quot;bot&amp;quot;]&lt;/code>&lt;/td>
 &lt;td>罕見組合、拆成已知 token&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>Antidisestab...&lt;/code>&lt;/td>
 &lt;td>&lt;code>[&amp;quot;Anti&amp;quot;, &amp;quot;dis&amp;quot;, &amp;quot;establish&amp;quot;, ...]&lt;/code>&lt;/td>
 &lt;td>罕見長詞、拆成 sub-word&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>你好&lt;/code>&lt;/td>
 &lt;td>&lt;code>[&amp;quot;你&amp;quot;, &amp;quot;好&amp;quot;]&lt;/code> 或 &lt;code>[&amp;quot;你好&amp;quot;]&lt;/code>&lt;/td>
 &lt;td>視 tokenizer 訓練 corpus 的中文比例&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>BPE 的變體：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Byte-level BPE&lt;/strong>：把每個 byte 當基底（256 個）、所以任何 Unicode / 二進制都能 tokenize、不會有 unknown token。GPT-2 開始的標準。&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/sentencepiece/" data-link-title="SentencePiece" data-link-desc="Google 開源的多語言 tokenization 框架、支援 BPE 跟 unigram 演算法、處理空白統一">SentencePiece&lt;/a> BPE&lt;/strong>：跟 SentencePiece 框架結合、處理多語言更靈活。&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 model card 看到 &lt;code>tokenizer: BPE&lt;/code> 就是這個演算法。BPE 對英文友好（高頻單詞整個一 token）、中文 / 日韓較不友好（單字符常被當獨立 token）；這就是為什麼同一段中文翻譯成英文後、英文 token 數常常更少、雲端 LLM 用中文 API 比英文貴。但越新的模型（Gemma 4、Qwen3 等）vocab 越大（256K+）、對中文友善度提升中。&lt;/p></description><content:encoded><![CDATA[<p>BPE（Byte-Pair Encoding、Sennrich et al., 2015 引入 NLP）的核心概念是「<strong>從字元開始、反覆找『出現頻率最高的字元對』把它合併成新 token、直到達到目標詞彙表大小</strong>」。是 GPT、Llama、Mistral 等主流 LLM 的 tokenization 演算法、能在「字元」跟「整詞」之間找平衡。</p>
<h2 id="概念位置">概念位置</h2>
<p>BPE 訓練 tokenizer 的流程（簡化）：</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">Step 0：vocab = 所有單一字元（256 個 byte / Unicode 字符）
</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">迭代：
</span></span><span class="line"><span class="ln">4</span><span class="cl">  Step 1：掃描 corpus、統計所有相鄰 token 對的出現頻率
</span></span><span class="line"><span class="ln">5</span><span class="cl">  Step 2：找出現最多的字元對（如 &#34;l&#34; + &#34;o&#34; 一起出現 1M 次）
</span></span><span class="line"><span class="ln">6</span><span class="cl">  Step 3：把它當新 token 加進 vocab、把 corpus 裡所有這個對換成新 token
</span></span><span class="line"><span class="ln">7</span><span class="cl">  Step 4：回到 Step 1、直到 vocab 達到目標大小（如 50K、128K、256K）</span></span></code></pre></div><p>實際 <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a> 化的結果：</p>
<table>
  <thead>
      <tr>
          <th>文字</th>
          <th>BPE token 化結果</th>
          <th>理由</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>Hello</code></td>
          <td><code>[&quot;Hello&quot;]</code></td>
          <td>高頻單字、整詞當一個 token</td>
      </tr>
      <tr>
          <td><code>Hellobot</code></td>
          <td><code>[&quot;Hello&quot;, &quot;bot&quot;]</code></td>
          <td>罕見組合、拆成已知 token</td>
      </tr>
      <tr>
          <td><code>Antidisestab...</code></td>
          <td><code>[&quot;Anti&quot;, &quot;dis&quot;, &quot;establish&quot;, ...]</code></td>
          <td>罕見長詞、拆成 sub-word</td>
      </tr>
      <tr>
          <td><code>你好</code></td>
          <td><code>[&quot;你&quot;, &quot;好&quot;]</code> 或 <code>[&quot;你好&quot;]</code></td>
          <td>視 tokenizer 訓練 corpus 的中文比例</td>
      </tr>
  </tbody>
</table>
<p>BPE 的變體：</p>
<ol>
<li><strong>Byte-level BPE</strong>：把每個 byte 當基底（256 個）、所以任何 Unicode / 二進制都能 tokenize、不會有 unknown token。GPT-2 開始的標準。</li>
<li><strong><a href="/blog/llm/knowledge-cards/sentencepiece/" data-link-title="SentencePiece" data-link-desc="Google 開源的多語言 tokenization 框架、支援 BPE 跟 unigram 演算法、處理空白統一">SentencePiece</a> BPE</strong>：跟 SentencePiece 框架結合、處理多語言更靈活。</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 model card 看到 <code>tokenizer: BPE</code> 就是這個演算法。BPE 對英文友好（高頻單詞整個一 token）、中文 / 日韓較不友好（單字符常被當獨立 token）；這就是為什麼同一段中文翻譯成英文後、英文 token 數常常更少、雲端 LLM 用中文 API 比英文貴。但越新的模型（Gemma 4、Qwen3 等）vocab 越大（256K+）、對中文友善度提升中。</p>
]]></content:encoded></item><item><title>Catastrophic Forgetting</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/catastrophic-forgetting/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/catastrophic-forgetting/</guid><description>&lt;p>Catastrophic forgetting（災難遺忘）的核心概念是「&lt;strong>Fine-tune 模型時、新訓練資料的 gradient 更新破壞了模型原本學到的能力&lt;/strong>」。在 LLM fine-tuning 場景特別常見：在自己 domain 資料上 fine-tune、結果模型在原 benchmark / 通用任務上分數大幅下降。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Catastrophic forgetting 在 LLM fine-tuning 的典型表現：&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">Before fine-tune（base instruct model）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> HumanEval: 75
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> MMLU: 70
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> 自己 domain 任務 hit rate: 40%
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">After fine-tune（在自己 domain 資料上跑 SFT、3 epochs）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> HumanEval: 55 ← 下降 20 點
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> MMLU: 50 ← 下降 20 點
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> 自己 domain 任務 hit rate: 70% ← 提升 30 點
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">→ 自己 domain 強了、但通用能力崩了&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>成因：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Gradient 在新資料上對 base 權重做大更新&lt;/strong>：原本 base 的權重對通用任務有用、被覆蓋掉&lt;/li>
&lt;li>&lt;strong>資料分佈差距大&lt;/strong>：自己 domain 跟 pretrain corpus 分佈差距大、學新的 = 忘舊的&lt;/li>
&lt;li>&lt;strong>訓練 epoch 太多&lt;/strong>：模型 over-fit 到新資料、舊能力衰退更嚴重&lt;/li>
&lt;li>&lt;strong>Learning rate 太高&lt;/strong>：每步更新幅度大、舊權重變化快&lt;/li>
&lt;/ol>
&lt;h2 id="緩解策略">緩解策略&lt;/h2>
&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>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/lora/" data-link-title="LoRA" data-link-desc="Low-Rank Adaptation：凍住原模型權重、只訓兩個小矩陣的 parameter-efficient fine-tuning">LoRA&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/qlora/" data-link-title="QLoRA" data-link-desc="把 base model 量化到 4-bit &amp;#43; LoRA fine-tune 的組合、消費級 GPU 也能 fine-tune 大模型">QLoRA&lt;/a>&lt;/td>
 &lt;td>凍住 base 權重、只訓 adapter、舊能力完全保留&lt;/td>
 &lt;td>多數 fine-tune 場景的 default&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>資料 mixing&lt;/td>
 &lt;td>訓練 batch 內 mix 通用資料 + domain 資料、避免分佈完全偏移&lt;/td>
 &lt;td>跟 LoRA 結合使用&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Lower learning rate&lt;/td>
 &lt;td>用較小 lr（如 5e-6 vs 1e-5）、減慢更新&lt;/td>
 &lt;td>全參數 fine-tune 必選&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Fewer epochs&lt;/td>
 &lt;td>訓 1-2 epoch 就停、不過度擬合&lt;/td>
 &lt;td>同上&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Regularization（KL constraint）&lt;/td>
 &lt;td>Loss 加「不能偏離 base 太遠」的約束&lt;/td>
 &lt;td>RLHF / DPO 已內建&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>EWC（Elastic Weight Consolidation）&lt;/td>
 &lt;td>對重要權重加更強懲罰、防止它們被改&lt;/td>
 &lt;td>研究用、實務罕見&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>主流 fine-tuning 配置（避免 catastrophic forgetting）：&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">方法：QLoRA fine-tune
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">參數：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> - rank: 16-64（看資料量）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> - alpha: 32（typical）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> - lr: 1e-4 ~ 5e-4（LoRA 適合較大 lr）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> - epochs: 1-3（不過度訓）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> - 資料：80% in-domain + 20% 通用 instruction data（保留通用能力）&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 fine-tune paper / 報告看到「forgetting」「retention」「regression」就是這現象。寫 code 場景的判讀：&lt;/p></description><content:encoded><![CDATA[<p>Catastrophic forgetting（災難遺忘）的核心概念是「<strong>Fine-tune 模型時、新訓練資料的 gradient 更新破壞了模型原本學到的能力</strong>」。在 LLM fine-tuning 場景特別常見：在自己 domain 資料上 fine-tune、結果模型在原 benchmark / 通用任務上分數大幅下降。</p>
<h2 id="概念位置">概念位置</h2>
<p>Catastrophic forgetting 在 LLM fine-tuning 的典型表現：</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">Before fine-tune（base instruct model）：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  HumanEval: 75
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">  MMLU: 70
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  自己 domain 任務 hit rate: 40%
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">After fine-tune（在自己 domain 資料上跑 SFT、3 epochs）：
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  HumanEval: 55  ← 下降 20 點
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  MMLU: 50       ← 下降 20 點
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">  自己 domain 任務 hit rate: 70%  ← 提升 30 點
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">→ 自己 domain 強了、但通用能力崩了</span></span></code></pre></div><p>成因：</p>
<ol>
<li><strong>Gradient 在新資料上對 base 權重做大更新</strong>：原本 base 的權重對通用任務有用、被覆蓋掉</li>
<li><strong>資料分佈差距大</strong>：自己 domain 跟 pretrain corpus 分佈差距大、學新的 = 忘舊的</li>
<li><strong>訓練 epoch 太多</strong>：模型 over-fit 到新資料、舊能力衰退更嚴重</li>
<li><strong>Learning rate 太高</strong>：每步更新幅度大、舊權重變化快</li>
</ol>
<h2 id="緩解策略">緩解策略</h2>
<table>
  <thead>
      <tr>
          <th>策略</th>
          <th>機制</th>
          <th>適用情境</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/lora/" data-link-title="LoRA" data-link-desc="Low-Rank Adaptation：凍住原模型權重、只訓兩個小矩陣的 parameter-efficient fine-tuning">LoRA</a> / <a href="/blog/llm/knowledge-cards/qlora/" data-link-title="QLoRA" data-link-desc="把 base model 量化到 4-bit &#43; LoRA fine-tune 的組合、消費級 GPU 也能 fine-tune 大模型">QLoRA</a></td>
          <td>凍住 base 權重、只訓 adapter、舊能力完全保留</td>
          <td>多數 fine-tune 場景的 default</td>
      </tr>
      <tr>
          <td>資料 mixing</td>
          <td>訓練 batch 內 mix 通用資料 + domain 資料、避免分佈完全偏移</td>
          <td>跟 LoRA 結合使用</td>
      </tr>
      <tr>
          <td>Lower learning rate</td>
          <td>用較小 lr（如 5e-6 vs 1e-5）、減慢更新</td>
          <td>全參數 fine-tune 必選</td>
      </tr>
      <tr>
          <td>Fewer epochs</td>
          <td>訓 1-2 epoch 就停、不過度擬合</td>
          <td>同上</td>
      </tr>
      <tr>
          <td>Regularization（KL constraint）</td>
          <td>Loss 加「不能偏離 base 太遠」的約束</td>
          <td>RLHF / DPO 已內建</td>
      </tr>
      <tr>
          <td>EWC（Elastic Weight Consolidation）</td>
          <td>對重要權重加更強懲罰、防止它們被改</td>
          <td>研究用、實務罕見</td>
      </tr>
  </tbody>
</table>
<p>主流 fine-tuning 配置（避免 catastrophic forgetting）：</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">方法：QLoRA fine-tune
</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">  - rank: 16-64（看資料量）
</span></span><span class="line"><span class="ln">4</span><span class="cl">  - alpha: 32（typical）
</span></span><span class="line"><span class="ln">5</span><span class="cl">  - lr: 1e-4 ~ 5e-4（LoRA 適合較大 lr）
</span></span><span class="line"><span class="ln">6</span><span class="cl">  - epochs: 1-3（不過度訓）
</span></span><span class="line"><span class="ln">7</span><span class="cl">  - 資料：80% in-domain + 20% 通用 instruction data（保留通用能力）</span></span></code></pre></div><h2 id="設計責任">設計責任</h2>
<p>讀 fine-tune paper / 報告看到「forgetting」「retention」「regression」就是這現象。寫 code 場景的判讀：</p>
<ol>
<li><strong>Fine-tune 前先建 baseline benchmark</strong>：把 base model 在通用 benchmark + 自己 domain 都跑一遍、fine-tune 後對比看 regression</li>
<li><strong>用 LoRA / QLoRA 是 default</strong>：除非有特殊理由要 full fine-tune、不然優先 LoRA</li>
<li><strong>不要把通用 chat 能力 fine-tune 掉</strong>：如果 fine-tune 後模型不會聊天、只會答自己 domain 問題、就是 forgetting 過頭</li>
<li><strong>Iterative fine-tune 風險疊加</strong>：在 fine-tuned 模型上再 fine-tune（如 SFT → DPO）、forgetting 風險加倍、要小心評估</li>
<li><strong>Reasoning 能力特別容易 forget</strong>：reasoning 是後期訓練的、fine-tune 一輪 SFT 容易破壞、reasoning model 不建議再 fine-tune</li>
</ol>
]]></content:encoded></item><item><title>Causal Mask</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/causal-mask/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/causal-mask/</guid><description>&lt;p>Causal mask（因果遮罩）的核心概念是「在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/self-attention/" data-link-title="Self-Attention" data-link-desc="Q / K / V 都從同一個 sequence 投影出來的 attention、Transformer 的標誌性設計">self-attention&lt;/a> 計算時、把 token i 看 token j (j &amp;gt; i) 的 attention 分數設成 -∞、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/softmax/" data-link-title="Softmax" data-link-desc="把任意實數向量正規化成「總和為 1、每個分量 ∈ [0,1]」的機率分佈">softmax&lt;/a> 後機率為 0」。直覺：LLM 是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">autoregressive&lt;/a> 的、生成 token N 時不能看到 N+1 以後（後面還沒生）、causal mask 強制這個約束、是 decoder-only Transformer 的標誌。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Causal mask 在 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">score = Q @ K^T / sqrt(d) ← shape (seq_len, seq_len)、每對 token 一個分數
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">score = score + causal_mask ← 加上 mask
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">attention = softmax(score) @ V
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">causal_mask 長這樣（lower triangular、上三角全是 -∞）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> K_0 K_1 K_2 K_3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">Q_0 [ 0 -∞ -∞ -∞ ] ← token 0 只能看自己
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">Q_1 [ 0 0 -∞ -∞ ] ← token 1 能看 0~1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">Q_2 [ 0 0 0 -∞ ]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">Q_3 [ 0 0 0 0 ]&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>關鍵特性：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>訓練時並行有效&lt;/strong>：所有 token 同時跑 forward pass、causal mask 確保每個 token 只看到該看的範圍。沒 mask 就會「偷看未來」、訓出 cheating 模型。&lt;/li>
&lt;li>&lt;strong>推論時自動成立&lt;/strong>：自回歸生成本來就是一個一個生、後面不存在、mask 是隱式的。&lt;/li>
&lt;li>&lt;strong>跟 &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> 結合&lt;/strong>：推論時 cache 只存「過去」的 K/V、causal mask 自然滿足。&lt;/li>
&lt;/ol>
&lt;p>跟其他 attention 變體的關係：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>架構&lt;/th>
 &lt;th>是否用 causal mask&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Decoder-only LLM（GPT / Llama / Gemma）&lt;/td>
 &lt;td>用、是標配&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Encoder-only（BERT）&lt;/td>
 &lt;td>不用、可以看雙向 context&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Encoder-decoder（T5）&lt;/td>
 &lt;td>Decoder 部分用、Encoder 部分不用&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 paper / model card 看到「causal」「decoder-only」「auto-regressive」這幾組詞、就是這個機制。實務上、寫 code 場景的所有主流 LLM 都用 causal mask、所以這個概念是隱式 default、不會主動暴露給使用者；但理解它能解釋為什麼 LLM 是「接龍」、為什麼 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">bidirectional context&lt;/a> 在 LLM 裡不存在（要 bidirectional 要用 encoder 架構）。&lt;/p></description><content:encoded><![CDATA[<p>Causal mask（因果遮罩）的核心概念是「在 <a href="/blog/llm/knowledge-cards/self-attention/" data-link-title="Self-Attention" data-link-desc="Q / K / V 都從同一個 sequence 投影出來的 attention、Transformer 的標誌性設計">self-attention</a> 計算時、把 token i 看 token j (j &gt; i) 的 attention 分數設成 -∞、<a href="/blog/llm/knowledge-cards/softmax/" data-link-title="Softmax" data-link-desc="把任意實數向量正規化成「總和為 1、每個分量 ∈ [0,1]」的機率分佈">softmax</a> 後機率為 0」。直覺：LLM 是 <a href="/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">autoregressive</a> 的、生成 token N 時不能看到 N+1 以後（後面還沒生）、causal mask 強制這個約束、是 decoder-only Transformer 的標誌。</p>
<h2 id="概念位置">概念位置</h2>
<p>Causal mask 在 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">score = Q @ K^T / sqrt(d)     ← shape (seq_len, seq_len)、每對 token 一個分數
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">score = score + causal_mask   ← 加上 mask
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">attention = softmax(score) @ V
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">causal_mask 長這樣（lower triangular、上三角全是 -∞）：
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">        K_0    K_1    K_2    K_3
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">Q_0   [  0    -∞     -∞     -∞ ]   ← token 0 只能看自己
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">Q_1   [  0     0     -∞     -∞ ]   ← token 1 能看 0~1
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">Q_2   [  0     0      0     -∞ ]
</span></span><span class="line"><span class="ln">10</span><span class="cl">Q_3   [  0     0      0      0 ]</span></span></code></pre></div><p>關鍵特性：</p>
<ol>
<li><strong>訓練時並行有效</strong>：所有 token 同時跑 forward pass、causal mask 確保每個 token 只看到該看的範圍。沒 mask 就會「偷看未來」、訓出 cheating 模型。</li>
<li><strong>推論時自動成立</strong>：自回歸生成本來就是一個一個生、後面不存在、mask 是隱式的。</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 結合</strong>：推論時 cache 只存「過去」的 K/V、causal mask 自然滿足。</li>
</ol>
<p>跟其他 attention 變體的關係：</p>
<table>
  <thead>
      <tr>
          <th>架構</th>
          <th>是否用 causal mask</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Decoder-only LLM（GPT / Llama / Gemma）</td>
          <td>用、是標配</td>
      </tr>
      <tr>
          <td>Encoder-only（BERT）</td>
          <td>不用、可以看雙向 context</td>
      </tr>
      <tr>
          <td>Encoder-decoder（T5）</td>
          <td>Decoder 部分用、Encoder 部分不用</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 paper / model card 看到「causal」「decoder-only」「auto-regressive」這幾組詞、就是這個機制。實務上、寫 code 場景的所有主流 LLM 都用 causal mask、所以這個概念是隱式 default、不會主動暴露給使用者；但理解它能解釋為什麼 LLM 是「接龍」、為什麼 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">bidirectional context</a> 在 LLM 裡不存在（要 bidirectional 要用 encoder 架構）。</p>
]]></content:encoded></item><item><title>Chain-of-Thought（CoT）</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/chain-of-thought/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/chain-of-thought/</guid><description>&lt;p>Chain-of-Thought（CoT、思維鏈、Wei et al., 2022）的核心概念是「&lt;strong>讓 LLM 先輸出一連串中間推理步驟、再給最終答案&lt;/strong>」、不是直接從問題跳到結論。CoT 是 reasoning model 的基礎機制；prompting 形式（few-shot 提示）跟訓練形式（reasoning RLHF / RL）兩條路都圍繞它演化。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>CoT 的兩種觸發方式：&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">直接回答：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> Q: 23 × 47 = ?
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> A: 1081
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">Chain-of-Thought：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> Q: 23 × 47 = ?
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> A: 先算 20 × 47 = 940、再算 3 × 47 = 141、加起來 940 + 141 = 1081。
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl"> 答案：1081&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>CoT 在 LLM 演化中的兩個階段：&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>Prompting CoT&lt;/td>
 &lt;td>Few-shot 提示「請逐步思考」或「let&amp;rsquo;s think step by step」&lt;/td>
 &lt;td>GPT-3、PaLM、早期 instruct 模型&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Training CoT&lt;/td>
 &lt;td>訓練資料含大量 reasoning trace、模型學會「自然」用 CoT&lt;/td>
 &lt;td>GPT-4、Claude 3.5、Gemini Pro&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Reasoning RL&lt;/td>
 &lt;td>RL 階段獎勵「正確答案的長 reasoning trace」、模型學會用更長 CoT&lt;/td>
 &lt;td>DeepSeek-R1、o1 / o3、Qwen-QwQ、Claude 3.7 Sonnet thinking&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>第三階段的特性：模型自己決定「該想多久」（&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/test-time-compute/" data-link-title="Test-Time Compute" data-link-desc="推論時動態增加計算量換取答案品質的 paradigm、reasoning model 跟 best-of-N 的共同基底">test-time compute&lt;/a> 動態擴展）、推理 trace 可達數千 token、最終答案才是少數 token。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 prompt engineering / paper 看到「CoT」「step by step」「reasoning trace」「thinking」等就是這個機制。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>複雜推理任務開 CoT 通常有幫助&lt;/strong>（math、debug、algorithm design）— 即使是 instruct model 也能透過 prompting 觸發&lt;/li>
&lt;li>&lt;strong>簡單任務 CoT 浪費 token&lt;/strong>（autocomplete、單行查詢、純查表）&lt;/li>
&lt;li>&lt;strong>Reasoning model 的 CoT 是內建行為&lt;/strong>、不需要用 prompt 觸發、但 reasoning trace 會消耗大量 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a>（推論時間、context、API 成本都翻倍）&lt;/li>
&lt;li>&lt;strong>本地跑 reasoning model&lt;/strong>：DeepSeek-R1 distill 系列、Qwen-QwQ 等可本地跑、但需要較大 &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> 容納 reasoning trace&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Chain-of-Thought（CoT、思維鏈、Wei et al., 2022）的核心概念是「<strong>讓 LLM 先輸出一連串中間推理步驟、再給最終答案</strong>」、不是直接從問題跳到結論。CoT 是 reasoning model 的基礎機制；prompting 形式（few-shot 提示）跟訓練形式（reasoning RLHF / RL）兩條路都圍繞它演化。</p>
<h2 id="概念位置">概念位置</h2>
<p>CoT 的兩種觸發方式：</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">直接回答：
</span></span><span class="line"><span class="ln">2</span><span class="cl">  Q: 23 × 47 = ?
</span></span><span class="line"><span class="ln">3</span><span class="cl">  A: 1081
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl">Chain-of-Thought：
</span></span><span class="line"><span class="ln">6</span><span class="cl">  Q: 23 × 47 = ?
</span></span><span class="line"><span class="ln">7</span><span class="cl">  A: 先算 20 × 47 = 940、再算 3 × 47 = 141、加起來 940 + 141 = 1081。
</span></span><span class="line"><span class="ln">8</span><span class="cl">     答案：1081</span></span></code></pre></div><p>CoT 在 LLM 演化中的兩個階段：</p>
<table>
  <thead>
      <tr>
          <th>階段</th>
          <th>觸發方式</th>
          <th>代表模型 / 技術</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Prompting CoT</td>
          <td>Few-shot 提示「請逐步思考」或「let&rsquo;s think step by step」</td>
          <td>GPT-3、PaLM、早期 instruct 模型</td>
      </tr>
      <tr>
          <td>Training CoT</td>
          <td>訓練資料含大量 reasoning trace、模型學會「自然」用 CoT</td>
          <td>GPT-4、Claude 3.5、Gemini Pro</td>
      </tr>
      <tr>
          <td>Reasoning RL</td>
          <td>RL 階段獎勵「正確答案的長 reasoning trace」、模型學會用更長 CoT</td>
          <td>DeepSeek-R1、o1 / o3、Qwen-QwQ、Claude 3.7 Sonnet thinking</td>
      </tr>
  </tbody>
</table>
<p>第三階段的特性：模型自己決定「該想多久」（<a href="/blog/llm/knowledge-cards/test-time-compute/" data-link-title="Test-Time Compute" data-link-desc="推論時動態增加計算量換取答案品質的 paradigm、reasoning model 跟 best-of-N 的共同基底">test-time compute</a> 動態擴展）、推理 trace 可達數千 token、最終答案才是少數 token。</p>
<h2 id="設計責任">設計責任</h2>
<p>讀 prompt engineering / paper 看到「CoT」「step by step」「reasoning trace」「thinking」等就是這個機制。寫 code 場景的判讀：</p>
<ol>
<li><strong>複雜推理任務開 CoT 通常有幫助</strong>（math、debug、algorithm design）— 即使是 instruct model 也能透過 prompting 觸發</li>
<li><strong>簡單任務 CoT 浪費 token</strong>（autocomplete、單行查詢、純查表）</li>
<li><strong>Reasoning model 的 CoT 是內建行為</strong>、不需要用 prompt 觸發、但 reasoning trace 會消耗大量 <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a>（推論時間、context、API 成本都翻倍）</li>
<li><strong>本地跑 reasoning model</strong>：DeepSeek-R1 distill 系列、Qwen-QwQ 等可本地跑、但需要較大 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a> 容納 reasoning trace</li>
</ol>
]]></content:encoded></item><item><title>Chunking</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/chunking/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/chunking/</guid><description>&lt;p>Chunking 的核心概念是「把長文件切成可被 retrieval 系統獨立檢索的片段」。是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 系統的關鍵設計決策——chunk 太小、retrieval 拿到的 fragment 缺脈絡；太大、retrieval 精確度低且浪費 &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>。「resolution vs context loss」是無法兩全的設計取捨。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Chunking 介於 corpus 跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model&lt;/a> 之間、決定 embedding 的單位。同一份 corpus 不同 chunking 策略產出不同 index、retrieval 行為完全不同。Chunk 邊界也決定 retrieval 命中後給 LLM 的 context 邊界——chunk 邊界穿過語意單位、會把連貫資訊切散。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Chunk 大小&lt;/th>
 &lt;th>典型 token 數&lt;/th>
 &lt;th>適合場景&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>細粒度&lt;/td>
 &lt;td>100-300&lt;/td>
 &lt;td>精確問答（單句答案）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>中粒度&lt;/td>
 &lt;td>400-800&lt;/td>
 &lt;td>一般 RAG 主流&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>粗粒度&lt;/td>
 &lt;td>1500-3000&lt;/td>
 &lt;td>摘要任務、需要長段脈絡&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>切法策略：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>固定 token 數&lt;/strong>：簡單但易切過句子 / 段落中間。&lt;/li>
&lt;li>&lt;strong>段落感知&lt;/strong>：用空白行切、保留段落完整。&lt;/li>
&lt;li>&lt;strong>語意 chunking&lt;/strong>：用 LLM / embedding 找語意邊界。&lt;/li>
&lt;li>&lt;strong>結構化文件&lt;/strong>：按 heading / section 切（markdown、code）。&lt;/li>
&lt;/ul>
&lt;p>跨 chunk 重複（overlap）：相鄰 chunk 留 10-20% 重疊、避免邊界訊號丟失。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Chunking 之前要回答四個問題：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>任務類型&lt;/strong>：問答 / 摘要 / 探索性搜尋？決定 chunk 大小 baseline。&lt;/li>
&lt;li>&lt;strong>文件結構&lt;/strong>：純文字 / markdown / code？決定切割 strategy。&lt;/li>
&lt;li>&lt;strong>語言混合&lt;/strong>：中文跟英文 token 比例不同、char-based heuristic 可能不準。&lt;/li>
&lt;li>&lt;strong>Embedding model 能力&lt;/strong>：太短 / 太長 chunk 都會降低 embedding 品質。&lt;/li>
&lt;/ol>
&lt;p>寫 code 場景的實作範例見 &lt;a href="https://tarrragon.github.io/blog/llm/01-local-llm-services/hands-on/rag-demo/" data-link-title="Hands-on：用 blog content 當 corpus 跑 RAG" data-link-desc="200 行 Python：embedding &amp;#43; cosine retrieval &amp;#43; Ollama chat、validating 4.0 RAG 原理">RAG demo hands-on&lt;/a> 的 &lt;code>slice_markdown&lt;/code> function、設計取捨展開見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &amp;#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG 原理&lt;/a> 的「Chunking 的本質取捨」段。&lt;/p></description><content:encoded><![CDATA[<p>Chunking 的核心概念是「把長文件切成可被 retrieval 系統獨立檢索的片段」。是 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 系統的關鍵設計決策——chunk 太小、retrieval 拿到的 fragment 缺脈絡；太大、retrieval 精確度低且浪費 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a>。「resolution vs context loss」是無法兩全的設計取捨。</p>
<h2 id="概念位置">概念位置</h2>
<p>Chunking 介於 corpus 跟 <a href="/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model</a> 之間、決定 embedding 的單位。同一份 corpus 不同 chunking 策略產出不同 index、retrieval 行為完全不同。Chunk 邊界也決定 retrieval 命中後給 LLM 的 context 邊界——chunk 邊界穿過語意單位、會把連貫資訊切散。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<table>
  <thead>
      <tr>
          <th>Chunk 大小</th>
          <th>典型 token 數</th>
          <th>適合場景</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>細粒度</td>
          <td>100-300</td>
          <td>精確問答（單句答案）</td>
      </tr>
      <tr>
          <td>中粒度</td>
          <td>400-800</td>
          <td>一般 RAG 主流</td>
      </tr>
      <tr>
          <td>粗粒度</td>
          <td>1500-3000</td>
          <td>摘要任務、需要長段脈絡</td>
      </tr>
  </tbody>
</table>
<p>切法策略：</p>
<ul>
<li><strong>固定 token 數</strong>：簡單但易切過句子 / 段落中間。</li>
<li><strong>段落感知</strong>：用空白行切、保留段落完整。</li>
<li><strong>語意 chunking</strong>：用 LLM / embedding 找語意邊界。</li>
<li><strong>結構化文件</strong>：按 heading / section 切（markdown、code）。</li>
</ul>
<p>跨 chunk 重複（overlap）：相鄰 chunk 留 10-20% 重疊、避免邊界訊號丟失。</p>
<h2 id="設計責任">設計責任</h2>
<p>Chunking 之前要回答四個問題：</p>
<ol>
<li><strong>任務類型</strong>：問答 / 摘要 / 探索性搜尋？決定 chunk 大小 baseline。</li>
<li><strong>文件結構</strong>：純文字 / markdown / code？決定切割 strategy。</li>
<li><strong>語言混合</strong>：中文跟英文 token 比例不同、char-based heuristic 可能不準。</li>
<li><strong>Embedding model 能力</strong>：太短 / 太長 chunk 都會降低 embedding 品質。</li>
</ol>
<p>寫 code 場景的實作範例見 <a href="/blog/llm/01-local-llm-services/hands-on/rag-demo/" data-link-title="Hands-on：用 blog content 當 corpus 跑 RAG" data-link-desc="200 行 Python：embedding &#43; cosine retrieval &#43; Ollama chat、validating 4.0 RAG 原理">RAG demo hands-on</a> 的 <code>slice_markdown</code> function、設計取捨展開見 <a href="/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG 原理</a> 的「Chunking 的本質取捨」段。</p>
]]></content:encoded></item><item><title>Client-Side LLM / Embedding</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/client-side-llm/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/client-side-llm/</guid><description>&lt;p>Client-side LLM / embedding 的核心概念是「&lt;strong>模型權重下載到使用者瀏覽器、用 WebGPU 或 WebAssembly 直接在 browser 內推論、不經過任何 server&lt;/strong>」。代表 runtime：WebLLM（MLC AI、用 WebGPU）、wllama（llama.cpp 的 WebAssembly port）、&lt;code>@xenova/transformers&lt;/code>（瀏覽器版 transformers）。是「靜態網站做 RAG」、「離線可用 LLM 應用」這類場景的關鍵基底。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>跟其他 LLM deployment 形態的對比：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &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>雲端 LLM API&lt;/td>
 &lt;td>雲端伺服器&lt;/td>
 &lt;td>雲端&lt;/td>
 &lt;td>視 vendor 政策&lt;/td>
 &lt;td>高品質、production&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>本地 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/inference-server/" data-link-title="Inference Server" data-link-desc="載入模型權重、處理 prompt、產生 token 的常駐 process">推論伺服器&lt;/a>&lt;/td>
 &lt;td>本機磁碟&lt;/td>
 &lt;td>本機 process&lt;/td>
 &lt;td>完全本地&lt;/td>
 &lt;td>寫 code、個人 dev&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Client-side LLM&lt;/strong>&lt;/td>
 &lt;td>使用者 browser cache&lt;/td>
 &lt;td>使用者 browser&lt;/td>
 &lt;td>完全本地（不經 server）&lt;/td>
 &lt;td>靜態網站、demo、離線&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>主流 client-side runtime（2026/5）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Runtime&lt;/th>
 &lt;th>機制&lt;/th>
 &lt;th>模型支援&lt;/th>
 &lt;th>典型體積&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;code>@xenova/transformers&lt;/code>&lt;/td>
 &lt;td>WASM、ONNX 格式&lt;/td>
 &lt;td>sentence-transformers、小型 LLM、CLIP、embedding&lt;/td>
 &lt;td>&amp;lt; 100 MB / 模型&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>WebLLM（MLC）&lt;/td>
 &lt;td>WebGPU、自家 MLC compiled&lt;/td>
 &lt;td>Llama / Qwen / Gemma / Phi 等 1-13B&lt;/td>
 &lt;td>1-8 GB / 模型&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>wllama&lt;/td>
 &lt;td>WASM、llama.cpp 編譯版&lt;/td>
 &lt;td>GGUF Q4 等量化模型、&amp;lt; 4B 為主&lt;/td>
 &lt;td>0.5-4 GB / 模型&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>transformers.js&lt;/code>&lt;/td>
 &lt;td>WASM、跟 &lt;code>@xenova/transformers&lt;/code> 同源&lt;/td>
 &lt;td>同上&lt;/td>
 &lt;td>同上&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀靜態網站 / 前端 RAG / 離線 LLM 教學看到「WebGPU LLM」「browser-side embedding」「offline LLM」就是這 paradigm。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>首訪載入慢&lt;/strong>：browser 第一次要下載模型權重（embedding 模型 ~50MB、LLM 1-5GB）、首訪體驗差；後續訪問 cache 起來、變快&lt;/li>
&lt;li>&lt;strong>WebGPU 支援度&lt;/strong>：2026/5 仍非所有 browser / 裝置都穩定支援、Safari iOS 較弱；fallback 到 WASM 但速度降一個量級&lt;/li>
&lt;li>&lt;strong>模型完整性沒簽章&lt;/strong>：使用者下載到的模型權重沒類似 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/model-card/" data-link-title="Model Card" data-link-desc="Hugging Face 等平台上模型的 metadata 文件、列出模型來源、訓練資料、能力、限制、授權">GGUF model card&lt;/a> 的官方驗證、要靠 CDN + HTTPS 信任、不像本地 Ollama 有 hash 比對&lt;/li>
&lt;li>&lt;strong>適合「embedding + 小 LLM」、不適合「30B reasoning」&lt;/strong>：browser 記憶體跟 WebGPU 算力都遠不如本地 Ollama、選 &amp;lt; 4B 模型較實際&lt;/li>
&lt;li>&lt;strong>跟資安的關係&lt;/strong>：client-side 不需要 server API key、隱私強；但模型分發鏈（CDN → browser）成為新的供應鏈面、見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/static-and-serverless-rag-deployment/" data-link-title="4.16 靜態 / serverless RAG deployment：架構選擇與資安取捨" data-link-desc="沒 backend 的場景怎麼做 RAG：四種 deployment 方案、API key 暴露問題、CORS / abuse / 第三方信任、跟模組六的 routing">4.16 靜態 RAG deployment&lt;/a> 的資安段&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Client-side LLM / embedding 的核心概念是「<strong>模型權重下載到使用者瀏覽器、用 WebGPU 或 WebAssembly 直接在 browser 內推論、不經過任何 server</strong>」。代表 runtime：WebLLM（MLC AI、用 WebGPU）、wllama（llama.cpp 的 WebAssembly port）、<code>@xenova/transformers</code>（瀏覽器版 transformers）。是「靜態網站做 RAG」、「離線可用 LLM 應用」這類場景的關鍵基底。</p>
<h2 id="概念位置">概念位置</h2>
<p>跟其他 LLM deployment 形態的對比：</p>
<table>
  <thead>
      <tr>
          <th>形態</th>
          <th>模型權重位置</th>
          <th>推論執行位置</th>
          <th>隱私</th>
          <th>適合</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>雲端 LLM API</td>
          <td>雲端伺服器</td>
          <td>雲端</td>
          <td>視 vendor 政策</td>
          <td>高品質、production</td>
      </tr>
      <tr>
          <td>本地 <a href="/blog/llm/knowledge-cards/inference-server/" data-link-title="Inference Server" data-link-desc="載入模型權重、處理 prompt、產生 token 的常駐 process">推論伺服器</a></td>
          <td>本機磁碟</td>
          <td>本機 process</td>
          <td>完全本地</td>
          <td>寫 code、個人 dev</td>
      </tr>
      <tr>
          <td><strong>Client-side LLM</strong></td>
          <td>使用者 browser cache</td>
          <td>使用者 browser</td>
          <td>完全本地（不經 server）</td>
          <td>靜態網站、demo、離線</td>
      </tr>
  </tbody>
</table>
<p>主流 client-side runtime（2026/5）：</p>
<table>
  <thead>
      <tr>
          <th>Runtime</th>
          <th>機制</th>
          <th>模型支援</th>
          <th>典型體積</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>@xenova/transformers</code></td>
          <td>WASM、ONNX 格式</td>
          <td>sentence-transformers、小型 LLM、CLIP、embedding</td>
          <td>&lt; 100 MB / 模型</td>
      </tr>
      <tr>
          <td>WebLLM（MLC）</td>
          <td>WebGPU、自家 MLC compiled</td>
          <td>Llama / Qwen / Gemma / Phi 等 1-13B</td>
          <td>1-8 GB / 模型</td>
      </tr>
      <tr>
          <td>wllama</td>
          <td>WASM、llama.cpp 編譯版</td>
          <td>GGUF Q4 等量化模型、&lt; 4B 為主</td>
          <td>0.5-4 GB / 模型</td>
      </tr>
      <tr>
          <td><code>transformers.js</code></td>
          <td>WASM、跟 <code>@xenova/transformers</code> 同源</td>
          <td>同上</td>
          <td>同上</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀靜態網站 / 前端 RAG / 離線 LLM 教學看到「WebGPU LLM」「browser-side embedding」「offline LLM」就是這 paradigm。寫 code 場景的判讀：</p>
<ol>
<li><strong>首訪載入慢</strong>：browser 第一次要下載模型權重（embedding 模型 ~50MB、LLM 1-5GB）、首訪體驗差；後續訪問 cache 起來、變快</li>
<li><strong>WebGPU 支援度</strong>：2026/5 仍非所有 browser / 裝置都穩定支援、Safari iOS 較弱；fallback 到 WASM 但速度降一個量級</li>
<li><strong>模型完整性沒簽章</strong>：使用者下載到的模型權重沒類似 <a href="/blog/llm/knowledge-cards/model-card/" data-link-title="Model Card" data-link-desc="Hugging Face 等平台上模型的 metadata 文件、列出模型來源、訓練資料、能力、限制、授權">GGUF model card</a> 的官方驗證、要靠 CDN + HTTPS 信任、不像本地 Ollama 有 hash 比對</li>
<li><strong>適合「embedding + 小 LLM」、不適合「30B reasoning」</strong>：browser 記憶體跟 WebGPU 算力都遠不如本地 Ollama、選 &lt; 4B 模型較實際</li>
<li><strong>跟資安的關係</strong>：client-side 不需要 server API key、隱私強；但模型分發鏈（CDN → browser）成為新的供應鏈面、見 <a href="/blog/llm/04-applications/static-and-serverless-rag-deployment/" data-link-title="4.16 靜態 / serverless RAG deployment：架構選擇與資安取捨" data-link-desc="沒 backend 的場景怎麼做 RAG：四種 deployment 方案、API key 暴露問題、CORS / abuse / 第三方信任、跟模組六的 routing">4.16 靜態 RAG deployment</a> 的資安段</li>
</ol>
]]></content:encoded></item><item><title>CLIP</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/clip/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/clip/</guid><description>&lt;p>CLIP（Contrastive Language-Image Pre-training、Radford et al., 2021）的核心概念是「&lt;strong>用 4 億組 (image, caption) 對、訓 image encoder 跟 text encoder、讓對應圖文的 embedding 在共享空間靠近&lt;/strong>」。CLIP 本身不是 VLM、但它的 image encoder 成為現代幾乎所有 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/vlm/" data-link-title="VLM（Vision-Language Model）" data-link-desc="同時吃圖片 &amp;#43; 文字輸入、產生文字輸出的 LLM 變體、coding 工作流中處理截圖 / 設計稿 / UI debug 的基底">VLM&lt;/a> 的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/vision-encoder/" data-link-title="Vision Encoder" data-link-desc="VLM 內部負責把圖片轉成可進 Transformer 的向量序列的模組、ViT / CLIP encoder 為主流">vision encoder&lt;/a> 起點。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>CLIP 的訓練架構（簡化）：&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">4 億組 (image, caption) 從網路爬：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> (photo of cat, &amp;#34;a fluffy orange cat sitting&amp;#34;)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> (screenshot of code, &amp;#34;Python error: NameError x undefined&amp;#34;)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> ...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">訓練：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> image → Image encoder（ViT-L/14）→ image_embedding
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> caption → Text encoder（Transformer）→ text_embedding
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> 正向對（matching image-caption）：embedding 應該相似
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> 負向對（同 batch 內其他不匹配）：embedding 應該遠
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl"> [Contrastive learning](/llm/knowledge-cards/contrastive-learning/) loss&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>訓完後得到：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>共享 embedding 空間&lt;/strong>：圖跟文字 embedding 都在 768/1024 維空間、相似度比較有意義&lt;/li>
&lt;li>&lt;strong>Zero-shot classification 能力&lt;/strong>：給一張圖、給 100 個文字標籤、看哪個 embedding 最接近 → 不用 fine-tune 就能分類&lt;/li>
&lt;li>&lt;strong>Image search / 多模態 retrieval&lt;/strong>：text 跟 image 互查、是 multimodal RAG 基底&lt;/li>
&lt;/ol>
&lt;p>對 VLM 的影響：&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">CLIP 訓出來後：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> image encoder 已經學會「把圖片變成有意義的 embedding」
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">VLM 訓練時：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> - 直接拿 CLIP 的 image encoder 當 vision encoder（凍住或一起 fine-tune）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> - 接上 LLM、用 image-text 任務資料訓 alignment
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> - 不用從頭訓 vision encoder、省下大量 compute&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>跟 SigLIP 的關係：SigLIP（Zhai et al., 2023）是 Google 提出的 CLIP 變體、用 sigmoid loss 取代原本 InfoNCE、訓練更穩、品質略佳；Gemma 3 / Idefics 等用 SigLIP 而非原 CLIP。&lt;/p></description><content:encoded><![CDATA[<p>CLIP（Contrastive Language-Image Pre-training、Radford et al., 2021）的核心概念是「<strong>用 4 億組 (image, caption) 對、訓 image encoder 跟 text encoder、讓對應圖文的 embedding 在共享空間靠近</strong>」。CLIP 本身不是 VLM、但它的 image encoder 成為現代幾乎所有 <a href="/blog/llm/knowledge-cards/vlm/" data-link-title="VLM（Vision-Language Model）" data-link-desc="同時吃圖片 &#43; 文字輸入、產生文字輸出的 LLM 變體、coding 工作流中處理截圖 / 設計稿 / UI debug 的基底">VLM</a> 的 <a href="/blog/llm/knowledge-cards/vision-encoder/" data-link-title="Vision Encoder" data-link-desc="VLM 內部負責把圖片轉成可進 Transformer 的向量序列的模組、ViT / CLIP encoder 為主流">vision encoder</a> 起點。</p>
<h2 id="概念位置">概念位置</h2>
<p>CLIP 的訓練架構（簡化）：</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">4 億組 (image, caption) 從網路爬：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  (photo of cat, &#34;a fluffy orange cat sitting&#34;)
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">  (screenshot of code, &#34;Python error: NameError x undefined&#34;)
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  ...
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">訓練：
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  image → Image encoder（ViT-L/14）→ image_embedding
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  caption → Text encoder（Transformer）→ text_embedding
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">  正向對（matching image-caption）：embedding 應該相似
</span></span><span class="line"><span class="ln">11</span><span class="cl">  負向對（同 batch 內其他不匹配）：embedding 應該遠
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl">  [Contrastive learning](/llm/knowledge-cards/contrastive-learning/) loss</span></span></code></pre></div><p>訓完後得到：</p>
<ol>
<li><strong>共享 embedding 空間</strong>：圖跟文字 embedding 都在 768/1024 維空間、相似度比較有意義</li>
<li><strong>Zero-shot classification 能力</strong>：給一張圖、給 100 個文字標籤、看哪個 embedding 最接近 → 不用 fine-tune 就能分類</li>
<li><strong>Image search / 多模態 retrieval</strong>：text 跟 image 互查、是 multimodal RAG 基底</li>
</ol>
<p>對 VLM 的影響：</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">CLIP 訓出來後：
</span></span><span class="line"><span class="ln">2</span><span class="cl">  image encoder 已經學會「把圖片變成有意義的 embedding」
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">VLM 訓練時：
</span></span><span class="line"><span class="ln">5</span><span class="cl">  - 直接拿 CLIP 的 image encoder 當 vision encoder（凍住或一起 fine-tune）
</span></span><span class="line"><span class="ln">6</span><span class="cl">  - 接上 LLM、用 image-text 任務資料訓 alignment
</span></span><span class="line"><span class="ln">7</span><span class="cl">  - 不用從頭訓 vision encoder、省下大量 compute</span></span></code></pre></div><p>跟 SigLIP 的關係：SigLIP（Zhai et al., 2023）是 Google 提出的 CLIP 變體、用 sigmoid loss 取代原本 InfoNCE、訓練更穩、品質略佳；Gemma 3 / Idefics 等用 SigLIP 而非原 CLIP。</p>
<h2 id="設計責任">設計責任</h2>
<p>讀 VLM paper / model card 看到「CLIP backbone」「SigLIP encoder」「OpenCLIP weights」就是這 family。寫 code 場景的判讀：</p>
<ol>
<li><strong>CLIP 本身不是 VLM</strong>：CLIP 只有 image-text 相似度、不能生文字回答；VLM 是「CLIP 的 image encoder + LLM + alignment training」</li>
<li><strong>不同 CLIP 變體影響 VLM 能力</strong>：CLIP ViT-L/14 是經典、SigLIP / DFN（Apple）等變體在某些任務更強</li>
<li><strong>Multimodal RAG 直接用 CLIP</strong>：純 image-text retrieval（如「找跟這張圖相似的 doc」）不需要完整 VLM、CLIP-like 模型就夠</li>
<li><strong>CLIP 用於 zero-shot 分類仍實用</strong>：給定固定的 class label set（如「截圖 / 設計稿 / 程式碼 / 文件」）、CLIP 能直接 zero-shot 分類、不需要訓 specific classifier</li>
</ol>
]]></content:encoded></item><item><title>Constrained Decoding</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/constrained-decoding/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/constrained-decoding/</guid><description>&lt;p>Constrained decoding（受限解碼）的核心概念是「&lt;strong>推論時用 grammar 動態算出每個位置的合法 token mask、把不合法 token 的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/logit/" data-link-title="Logit" data-link-desc="softmax 之前的原始實數分數、每個 vocab token 一個值、可正可負">logit&lt;/a> 設成 -∞、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/softmax/" data-link-title="Softmax" data-link-desc="把任意實數向量正規化成「總和為 1、每個分量 ∈ [0,1]」的機率分佈">softmax&lt;/a> 後機率為 0&lt;/strong>」。是 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/application-protocols/" data-link-title="4.6 應用層協議：function calling / structured output / MCP" data-link-desc="三個常被混為一談的概念：模型能力、sampling 約束、server 協議，三者的層級差異與組合方式">structured output&lt;/a>（JSON mode / function calling 的合法性保證）背後的 sampling 機制。代表實作：XGrammar、outlines、lm-format-enforcer、guidance、SGLang。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>跟既有 sampling 概念的層次：&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">模型 forward pass → logits（每個 vocab token 一個分數）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓ apply temperature
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> ↓ apply grammar mask（constrained decoding） ← 本卡聚焦
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> - 算出當下位置的合法 token 集合
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> - 不合法 token 的 logit 設 -∞
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> ↓ softmax → 機率分佈
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> ↓ sampling（greedy / top-p / top-k）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl"> ↓ next token&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>主要 grammar 類型：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Grammar 類型&lt;/th>
 &lt;th>描述&lt;/th>
 &lt;th>用例&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>JSON Schema&lt;/td>
 &lt;td>標準 JSON schema 定義合法 JSON 結構&lt;/td>
 &lt;td>Function calling、structured output&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Regex&lt;/td>
 &lt;td>Regular expression&lt;/td>
 &lt;td>受限文字格式（如 phone number、email）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>CFG（Context-Free Grammar）&lt;/td>
 &lt;td>BNF 等 grammar 描述合法語法&lt;/td>
 &lt;td>Code generation、DSL、SQL&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Choice list&lt;/td>
 &lt;td>一組固定字串選項&lt;/td>
 &lt;td>Classification、enum 輸出&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>主流實作對比：&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>&lt;strong>XGrammar&lt;/strong>&lt;/td>
 &lt;td>Pre-compile grammar → token mask cache、極快&lt;/td>
 &lt;td>vLLM / SGLang / TensorRT-LLM 預設&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>outlines&lt;/td>
 &lt;td>Python lib、JSON schema / regex / CFG&lt;/td>
 &lt;td>用 Transformers / vLLM&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>lm-format-enforcer&lt;/td>
 &lt;td>Lazy compile、適合動態 grammar&lt;/td>
 &lt;td>Hugging Face Transformers&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>guidance&lt;/td>
 &lt;td>Microsoft 系、API 較高階&lt;/td>
 &lt;td>自家 server&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>llama.cpp grammar&lt;/td>
 &lt;td>Built-in GBNF（GGML BNF）&lt;/td>
 &lt;td>llama.cpp 內建&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 sampling / structured output / function calling 進階文件看到「constrained decoding」「grammar mask」「JSON schema enforcement」就是這 framing。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>何時值得用&lt;/strong>：需要 100% 合法 JSON / 特定格式、function calling spec 嚴格、structured output 不可有解析錯誤&lt;/li>
&lt;li>&lt;strong>不該用的情況&lt;/strong>：自由 / 創意輸出（會限制模型表達）、grammar 太嚴讓模型「該說的話說不出來」（如 enum 不含「unknown」、模型強制選錯）&lt;/li>
&lt;li>&lt;strong>跟 function calling 的關係&lt;/strong>：function calling 是「模型訓練 + structured output」、constrained decoding 是 sampling 層的工程實作、可獨立組合&lt;/li>
&lt;li>&lt;strong>加速 vs 拖慢&lt;/strong>：常見誤解是 grammar 拖慢 — 實測 XGrammar 等 pre-compiled 實作反而&lt;strong>加速&lt;/strong>生成（跳過 boilerplate token 直接生關鍵 token、節省 forward pass）&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/03-theoretical-foundations/constrained-decoding-internals/" data-link-title="3.10 Constrained decoding 內部：grammar mask 跟性能取捨" data-link-desc="Constrained decoding 的內部運作：token mask 計算、JSON schema / regex / CFG 三種 grammar、XGrammar pre-compile 機制、性能反而加速">3.10 constrained decoding 章節&lt;/a> 的關係&lt;/strong>：本卡是定義、章節是內部機制（token mask 計算、CFG 編譯、性能取捨）&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Constrained decoding（受限解碼）的核心概念是「<strong>推論時用 grammar 動態算出每個位置的合法 token mask、把不合法 token 的 <a href="/blog/llm/knowledge-cards/logit/" data-link-title="Logit" data-link-desc="softmax 之前的原始實數分數、每個 vocab token 一個值、可正可負">logit</a> 設成 -∞、<a href="/blog/llm/knowledge-cards/softmax/" data-link-title="Softmax" data-link-desc="把任意實數向量正規化成「總和為 1、每個分量 ∈ [0,1]」的機率分佈">softmax</a> 後機率為 0</strong>」。是 <a href="/blog/llm/04-applications/application-protocols/" data-link-title="4.6 應用層協議：function calling / structured output / MCP" data-link-desc="三個常被混為一談的概念：模型能力、sampling 約束、server 協議，三者的層級差異與組合方式">structured output</a>（JSON mode / function calling 的合法性保證）背後的 sampling 機制。代表實作：XGrammar、outlines、lm-format-enforcer、guidance、SGLang。</p>
<h2 id="概念位置">概念位置</h2>
<p>跟既有 sampling 概念的層次：</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">模型 forward pass → logits（每個 vocab token 一個分數）
</span></span><span class="line"><span class="ln">2</span><span class="cl">   ↓ apply temperature
</span></span><span class="line"><span class="ln">3</span><span class="cl">   ↓ apply grammar mask（constrained decoding）  ← 本卡聚焦
</span></span><span class="line"><span class="ln">4</span><span class="cl">       - 算出當下位置的合法 token 集合
</span></span><span class="line"><span class="ln">5</span><span class="cl">       - 不合法 token 的 logit 設 -∞
</span></span><span class="line"><span class="ln">6</span><span class="cl">   ↓ softmax → 機率分佈
</span></span><span class="line"><span class="ln">7</span><span class="cl">   ↓ sampling（greedy / top-p / top-k）
</span></span><span class="line"><span class="ln">8</span><span class="cl">   ↓ next token</span></span></code></pre></div><p>主要 grammar 類型：</p>
<table>
  <thead>
      <tr>
          <th>Grammar 類型</th>
          <th>描述</th>
          <th>用例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>JSON Schema</td>
          <td>標準 JSON schema 定義合法 JSON 結構</td>
          <td>Function calling、structured output</td>
      </tr>
      <tr>
          <td>Regex</td>
          <td>Regular expression</td>
          <td>受限文字格式（如 phone number、email）</td>
      </tr>
      <tr>
          <td>CFG（Context-Free Grammar）</td>
          <td>BNF 等 grammar 描述合法語法</td>
          <td>Code generation、DSL、SQL</td>
      </tr>
      <tr>
          <td>Choice list</td>
          <td>一組固定字串選項</td>
          <td>Classification、enum 輸出</td>
      </tr>
  </tbody>
</table>
<p>主流實作對比：</p>
<table>
  <thead>
      <tr>
          <th>實作</th>
          <th>機制</th>
          <th>推論伺服器整合</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>XGrammar</strong></td>
          <td>Pre-compile grammar → token mask cache、極快</td>
          <td>vLLM / SGLang / TensorRT-LLM 預設</td>
      </tr>
      <tr>
          <td>outlines</td>
          <td>Python lib、JSON schema / regex / CFG</td>
          <td>用 Transformers / vLLM</td>
      </tr>
      <tr>
          <td>lm-format-enforcer</td>
          <td>Lazy compile、適合動態 grammar</td>
          <td>Hugging Face Transformers</td>
      </tr>
      <tr>
          <td>guidance</td>
          <td>Microsoft 系、API 較高階</td>
          <td>自家 server</td>
      </tr>
      <tr>
          <td>llama.cpp grammar</td>
          <td>Built-in GBNF（GGML BNF）</td>
          <td>llama.cpp 內建</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 sampling / structured output / function calling 進階文件看到「constrained decoding」「grammar mask」「JSON schema enforcement」就是這 framing。寫 code 場景的判讀：</p>
<ol>
<li><strong>何時值得用</strong>：需要 100% 合法 JSON / 特定格式、function calling spec 嚴格、structured output 不可有解析錯誤</li>
<li><strong>不該用的情況</strong>：自由 / 創意輸出（會限制模型表達）、grammar 太嚴讓模型「該說的話說不出來」（如 enum 不含「unknown」、模型強制選錯）</li>
<li><strong>跟 function calling 的關係</strong>：function calling 是「模型訓練 + structured output」、constrained decoding 是 sampling 層的工程實作、可獨立組合</li>
<li><strong>加速 vs 拖慢</strong>：常見誤解是 grammar 拖慢 — 實測 XGrammar 等 pre-compiled 實作反而<strong>加速</strong>生成（跳過 boilerplate token 直接生關鍵 token、節省 forward pass）</li>
<li><strong>跟 <a href="/blog/llm/03-theoretical-foundations/constrained-decoding-internals/" data-link-title="3.10 Constrained decoding 內部：grammar mask 跟性能取捨" data-link-desc="Constrained decoding 的內部運作：token mask 計算、JSON schema / regex / CFG 三種 grammar、XGrammar pre-compile 機制、性能反而加速">3.10 constrained decoding 章節</a> 的關係</strong>：本卡是定義、章節是內部機制（token mask 計算、CFG 編譯、性能取捨）</li>
</ol>
]]></content:encoded></item><item><title>Context Budget</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/context-budget/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/context-budget/</guid><description>&lt;p>Context budget 的核心概念是「&lt;strong>把 &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> 視為有限資源、明確規劃 system prompt / tool schema / history / file content / reasoning trace / tool result 各佔多少&lt;/strong>」。coding agent 的最大失敗模式是「context 用爆 → 模型開始遺忘關鍵指令 → 行為飄」、預算化是 harness 設計的核心責任。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>典型 coding agent 的 context 構成（以 200K 模型為例）：&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">[1. System prompt + tool schema]： 固定 ~10K-30K
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> - agent 角色、輸出規則、tool 列表 + spec、subagent 路由
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> - 經常用 prompt cache 加速、見 [prompt cache 卡]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">[2. 工作歷史 / conversation history]： 動態 0-60K
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> - 過去回合的 user query + assistant answer + tool calls
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> - 越長越貴、harness 要決定何時 summarize / trim
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">[3. 當前任務 file context]： 動態 0-100K
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> - 開啟的檔案、grep 結果、@-mention 帶入的內容
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">[4. Reasoning trace（若 reasoning model）]： 動態 1K-10K / step
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl"> - &amp;lt;think&amp;gt;...&amp;lt;/think&amp;gt; 段、每次推論都會佔 context
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl">[5. Tool result]： 動態 0-50K
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl"> - file read 結果、bash output、test result
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">17&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">18&lt;/span>&lt;span class="cl">[6. Margin / safety buffer]： 保留 20-30K
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">19&lt;/span>&lt;span class="cl"> - 防止 generation 階段碰到 context limit&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>主流 coding agent 的 25% 規則（&lt;a href="https://tarrragon.github.io/blog/llm/04-applications/coding-agent-harness/" data-link-title="4.17 Coding agent harness：scaffold / context engineering / subagent" data-link-desc="Coding agent 的內部設計：scaffold vs harness 分層、context budget 25% 規則、subagent 拓樸、跟 Claude Code / Cursor / Aider 的 mapping">context engineering 慣例&lt;/a>）：&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>Scaffold 部分（1+2） ≤ 25%&lt;/td>
 &lt;td>留 75% 給「當下任務」、避免 lost-in-the-middle 把指令吃掉&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>File content ≤ 50%&lt;/td>
 &lt;td>不全載入大檔、用 grep / chunked read 替代&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Margin ≥ 10%&lt;/td>
 &lt;td>Generation 階段才不會被 context limit 截斷&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Reasoning trace 配長 context&lt;/td>
 &lt;td>Reasoning model 至少配 64K context、見 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/reasoning-model/" data-link-title="Reasoning Model" data-link-desc="訓練成自然輸出長 reasoning trace 的 LLM 變體、o1 / DeepSeek-R1 / Claude thinking 為代表">reasoning-model 卡&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 coding agent 設計 / harness paper 看到「context budget」「context engineering」「token budgeting」就是這 framing。寫 code 場景的判讀：&lt;/p></description><content:encoded><![CDATA[<p>Context budget 的核心概念是「<strong>把 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a> 視為有限資源、明確規劃 system prompt / tool schema / history / file content / reasoning trace / tool result 各佔多少</strong>」。coding agent 的最大失敗模式是「context 用爆 → 模型開始遺忘關鍵指令 → 行為飄」、預算化是 harness 設計的核心責任。</p>
<h2 id="概念位置">概念位置</h2>
<p>典型 coding agent 的 context 構成（以 200K 模型為例）：</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">[1. System prompt + tool schema]：     固定 ~10K-30K
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">   - agent 角色、輸出規則、tool 列表 + spec、subagent 路由
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">   - 經常用 prompt cache 加速、見 [prompt cache 卡]
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">[2. 工作歷史 / conversation history]：  動態 0-60K
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">   - 過去回合的 user query + assistant answer + tool calls
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">   - 越長越貴、harness 要決定何時 summarize / trim
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">[3. 當前任務 file context]：           動態 0-100K
</span></span><span class="line"><span class="ln">10</span><span class="cl">   - 開啟的檔案、grep 結果、@-mention 帶入的內容
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl">[4. Reasoning trace（若 reasoning model）]：  動態 1K-10K / step
</span></span><span class="line"><span class="ln">13</span><span class="cl">   - &lt;think&gt;...&lt;/think&gt; 段、每次推論都會佔 context
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl">[5. Tool result]：                    動態 0-50K
</span></span><span class="line"><span class="ln">16</span><span class="cl">   - file read 結果、bash output、test result
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl">[6. Margin / safety buffer]：         保留 20-30K
</span></span><span class="line"><span class="ln">19</span><span class="cl">   - 防止 generation 階段碰到 context limit</span></span></code></pre></div><p>主流 coding agent 的 25% 規則（<a href="/blog/llm/04-applications/coding-agent-harness/" data-link-title="4.17 Coding agent harness：scaffold / context engineering / subagent" data-link-desc="Coding agent 的內部設計：scaffold vs harness 分層、context budget 25% 規則、subagent 拓樸、跟 Claude Code / Cursor / Aider 的 mapping">context engineering 慣例</a>）：</p>
<table>
  <thead>
      <tr>
          <th>規則</th>
          <th>直覺</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Scaffold 部分（1+2） ≤ 25%</td>
          <td>留 75% 給「當下任務」、避免 lost-in-the-middle 把指令吃掉</td>
      </tr>
      <tr>
          <td>File content ≤ 50%</td>
          <td>不全載入大檔、用 grep / chunked read 替代</td>
      </tr>
      <tr>
          <td>Margin ≥ 10%</td>
          <td>Generation 階段才不會被 context limit 截斷</td>
      </tr>
      <tr>
          <td>Reasoning trace 配長 context</td>
          <td>Reasoning model 至少配 64K context、見 <a href="/blog/llm/knowledge-cards/reasoning-model/" data-link-title="Reasoning Model" data-link-desc="訓練成自然輸出長 reasoning trace 的 LLM 變體、o1 / DeepSeek-R1 / Claude thinking 為代表">reasoning-model 卡</a></td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 coding agent 設計 / harness paper 看到「context budget」「context engineering」「token budgeting」就是這 framing。寫 code 場景的判讀：</p>
<ol>
<li><strong>超出 budget 的訊號</strong>：模型開始忽略 system prompt、回答跟前文重複、tool call 重複過去步驟、reasoning trace 截斷</li>
<li><strong>節省 budget 的策略</strong>：用 <a href="/blog/llm/knowledge-cards/prompt-cache/" data-link-title="Prompt Cache" data-link-desc="重複出現的 prompt prefix 在推論伺服器或 LLM 服務端被 cache、後續 query 跳過 prefill、大幅降 cost 跟 TTFT">prompt cache</a> 把 system + tool schema 攤平、grep 取代全檔讀、tool result 限長度（如 head -100）、定期 summarize history</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/lost-in-the-middle/" data-link-title="Lost in the Middle" data-link-desc="LLM 對 long context 中段內容的 attention / recall 顯著低於開頭與結尾的現象">lost-in-the-middle</a> 的關係</strong>：context 用越多、中段內容 recall 越差、所以「能用 20K 解就別用 100K」、不是「能塞 200K 就塞滿」</li>
<li><strong>不同 task 不同 budget</strong>：autocomplete 任務 budget 小（系統 prompt + 最近 50 行 code 就夠）；refactor 任務 budget 大（多檔案）；agent loop 任務 budget 動態（每步可能 grow）</li>
</ol>
]]></content:encoded></item><item><title>Contrastive Learning</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/contrastive-learning/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/contrastive-learning/</guid><description>&lt;p>Contrastive learning（對比學習）的核心概念是「&lt;strong>訓練模型讓相關樣本的 embedding 在向量空間中靠近、無關樣本遠離&lt;/strong>」。是現代 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model&lt;/a> 的標準訓練 paradigm、跟 LLM pretrain 的 next-token prediction 完全不同的訓練目標。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Contrastive learning 的核心訓練形態：&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">正向對（positive pair）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> (query, relevant_doc) — 應該在 embedding 空間靠近
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> 例：(&amp;#34;Python how to read file&amp;#34;, &amp;#34;Python file reading tutorial...&amp;#34;)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">負向對（negative pair）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> (query, irrelevant_doc) — 應該在 embedding 空間遠離
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> 例：(&amp;#34;Python how to read file&amp;#34;, &amp;#34;CSS flexbox guide...&amp;#34;)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">Loss（簡化的 InfoNCE loss）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> pull positive pair 靠近
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> push negative pair 遠離（多個 negative samples 對比）&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>主流形式：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>形式&lt;/th>
 &lt;th>Loss 設計&lt;/th>
 &lt;th>代表模型&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Triplet loss&lt;/td>
 &lt;td>(anchor, positive, negative)、要求 anchor-positive 距離 &amp;lt; anchor-negative&lt;/td>
 &lt;td>早期 sentence-BERT&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>InfoNCE / NCE&lt;/td>
 &lt;td>Cross-entropy over batch、把 batch 內其他樣本當 hard negative&lt;/td>
 &lt;td>OpenAI ada-002、bge 系列&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>MultipleNegativesRankingLoss&lt;/td>
 &lt;td>上述變體、用 batch 內隨機其他樣本當 negative&lt;/td>
 &lt;td>Sentence-Transformers 主流&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵特性：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>資料量需求大&lt;/strong>：contrastive learning 需要億級的正向對才能訓出好 embedding；資料來源是 query-doc click log、StackExchange QA pair、CC-paraphrase 等&lt;/li>
&lt;li>&lt;strong>Hard negative mining 是品質關鍵&lt;/strong>：隨機選 negative 容易（從 batch 取就行）、找「看似相關但實際無關」的 hard negative 更挑戰、是 embedding quality 提升的關鍵&lt;/li>
&lt;li>&lt;strong>不能直接拿 pretrained LLM 用&lt;/strong>：LLM 的 hidden state 不是「為 retrieval 優化」的、要再 fine-tune 一輪 contrastive learning 才能當 embedding model&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 embedding model paper / 訓練 code 看到「InfoNCE」「triplet」「hard negatives」「mining strategy」就是這 paradigm。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>挑 embedding model 看訓練資料 domain&lt;/strong>：通用 retrieval（如 bge-large、nomic-embed）vs code-specific（如 jina-embeddings-v2-code、CodeT5+）、訓練資料分佈影響大&lt;/li>
&lt;li>&lt;strong>不能拿任意 LLM 抽 hidden state 當 embedding&lt;/strong>：如「Llama 的 last hidden state 當 embedding」這類做法在 retrieval 上通常顯著輸給專門 contrastive-trained embedding model&lt;/li>
&lt;li>&lt;strong>Fine-tune embedding model 通常用 LoRA + contrastive loss&lt;/strong>：在自己 domain 資料上 fine-tune、提升 in-domain retrieval；標準 pipeline 是 sentence-transformers + LoRA&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Contrastive learning（對比學習）的核心概念是「<strong>訓練模型讓相關樣本的 embedding 在向量空間中靠近、無關樣本遠離</strong>」。是現代 <a href="/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model</a> 的標準訓練 paradigm、跟 LLM pretrain 的 next-token prediction 完全不同的訓練目標。</p>
<h2 id="概念位置">概念位置</h2>
<p>Contrastive learning 的核心訓練形態：</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">正向對（positive pair）：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  (query, relevant_doc) — 應該在 embedding 空間靠近
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">  例：(&#34;Python how to read file&#34;, &#34;Python file reading tutorial...&#34;)
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">負向對（negative pair）：
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">  (query, irrelevant_doc) — 應該在 embedding 空間遠離
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  例：(&#34;Python how to read file&#34;, &#34;CSS flexbox guide...&#34;)
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">Loss（簡化的 InfoNCE loss）：
</span></span><span class="line"><span class="ln">10</span><span class="cl">  pull positive pair 靠近
</span></span><span class="line"><span class="ln">11</span><span class="cl">  push negative pair 遠離（多個 negative samples 對比）</span></span></code></pre></div><p>主流形式：</p>
<table>
  <thead>
      <tr>
          <th>形式</th>
          <th>Loss 設計</th>
          <th>代表模型</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Triplet loss</td>
          <td>(anchor, positive, negative)、要求 anchor-positive 距離 &lt; anchor-negative</td>
          <td>早期 sentence-BERT</td>
      </tr>
      <tr>
          <td>InfoNCE / NCE</td>
          <td>Cross-entropy over batch、把 batch 內其他樣本當 hard negative</td>
          <td>OpenAI ada-002、bge 系列</td>
      </tr>
      <tr>
          <td>MultipleNegativesRankingLoss</td>
          <td>上述變體、用 batch 內隨機其他樣本當 negative</td>
          <td>Sentence-Transformers 主流</td>
      </tr>
  </tbody>
</table>
<p>關鍵特性：</p>
<ol>
<li><strong>資料量需求大</strong>：contrastive learning 需要億級的正向對才能訓出好 embedding；資料來源是 query-doc click log、StackExchange QA pair、CC-paraphrase 等</li>
<li><strong>Hard negative mining 是品質關鍵</strong>：隨機選 negative 容易（從 batch 取就行）、找「看似相關但實際無關」的 hard negative 更挑戰、是 embedding quality 提升的關鍵</li>
<li><strong>不能直接拿 pretrained LLM 用</strong>：LLM 的 hidden state 不是「為 retrieval 優化」的、要再 fine-tune 一輪 contrastive learning 才能當 embedding model</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 embedding model paper / 訓練 code 看到「InfoNCE」「triplet」「hard negatives」「mining strategy」就是這 paradigm。寫 code 場景的判讀：</p>
<ol>
<li><strong>挑 embedding model 看訓練資料 domain</strong>：通用 retrieval（如 bge-large、nomic-embed）vs code-specific（如 jina-embeddings-v2-code、CodeT5+）、訓練資料分佈影響大</li>
<li><strong>不能拿任意 LLM 抽 hidden state 當 embedding</strong>：如「Llama 的 last hidden state 當 embedding」這類做法在 retrieval 上通常顯著輸給專門 contrastive-trained embedding model</li>
<li><strong>Fine-tune embedding model 通常用 LoRA + contrastive loss</strong>：在自己 domain 資料上 fine-tune、提升 in-domain retrieval；標準 pipeline 是 sentence-transformers + LoRA</li>
</ol>
]]></content:encoded></item><item><title>Cross-Entropy</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/cross-entropy/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/cross-entropy/</guid><description>&lt;p>Cross-entropy（交叉熵）的核心概念是「衡量兩個機率分佈的距離」。LLM 預訓練的標準 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/loss-function/" data-link-title="Loss Function" data-link-desc="把「模型預測」跟「正確答案」的差距量化成一個純量、訓練的最佳化目標">loss function&lt;/a> 是 cross-entropy：對每個 token、把模型預測的 vocab 機率分佈跟「真實答案是 one-hot 分佈」做 cross-entropy、加總。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Cross-entropy 在 next-token prediction 訓練裡的具體計算：&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">模型預測：p = softmax(logits) ← shape: (vocab_size,)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">真實答案：y = one-hot(true_token) ← shape: (vocab_size,)、只有真實 token 那位是 1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">cross-entropy = -sum(y_i × log(p_i))
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> = -log(p_true_token) ← 因為 y 是 one-hot、只剩這項&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>所以實作上 cross-entropy 就退化成「真實 token 預測機率的負對數」、機率越接近 1、loss 越接近 0；機率越接近 0、loss 越接近 ∞。&lt;/p>
&lt;p>跟相關概念的關係：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>概念&lt;/th>
 &lt;th>跟 cross-entropy 的關係&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/perplexity/" data-link-title="Perplexity" data-link-desc="cross-entropy 的指數形式、直覺意義為「模型平均覺得下個 token 有多少種可能」">Perplexity&lt;/a>&lt;/td>
 &lt;td>&lt;code>perplexity = exp(cross-entropy)&lt;/code>、cross-entropy 的指數形式、人類直覺較好讀&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/kl-divergence/" data-link-title="KL Divergence" data-link-desc="衡量「兩個機率分佈差距」的非對稱指標、RLHF / DPO 等 alignment 訓練的關鍵約束">KL divergence&lt;/a>&lt;/td>
 &lt;td>Cross-entropy = entropy(真實) + KL(真實 ‖ 預測)、訓練時 entropy 是常數、所以 minimize cross-entropy 等於 minimize KL&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/softmax/" data-link-title="Softmax" data-link-desc="把任意實數向量正規化成「總和為 1、每個分量 ∈ [0,1]」的機率分佈">Softmax&lt;/a>&lt;/td>
 &lt;td>Cross-entropy 通常吃 softmax 的輸出當「預測機率」&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 LLM 訓練 / paper 時看到「training loss」幾乎都是 cross-entropy。實務判讀：cross-entropy 直接代表「模型對真實 token 的預測機率有多差」、loss = 2 大致對應「真實 token 被預測機率 ≈ 0.135」（exp(-2)）。模型在 pretrain 階段 cross-entropy 從約 11（純隨機）降到約 2-3（成熟模型）、SFT 階段再略降。&lt;/p></description><content:encoded><![CDATA[<p>Cross-entropy（交叉熵）的核心概念是「衡量兩個機率分佈的距離」。LLM 預訓練的標準 <a href="/blog/llm/knowledge-cards/loss-function/" data-link-title="Loss Function" data-link-desc="把「模型預測」跟「正確答案」的差距量化成一個純量、訓練的最佳化目標">loss function</a> 是 cross-entropy：對每個 token、把模型預測的 vocab 機率分佈跟「真實答案是 one-hot 分佈」做 cross-entropy、加總。</p>
<h2 id="概念位置">概念位置</h2>
<p>Cross-entropy 在 next-token prediction 訓練裡的具體計算：</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">模型預測：p = softmax(logits)  ← shape: (vocab_size,)
</span></span><span class="line"><span class="ln">2</span><span class="cl">真實答案：y = one-hot(true_token)  ← shape: (vocab_size,)、只有真實 token 那位是 1
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">cross-entropy = -sum(y_i × log(p_i))
</span></span><span class="line"><span class="ln">5</span><span class="cl">              = -log(p_true_token)  ← 因為 y 是 one-hot、只剩這項</span></span></code></pre></div><p>所以實作上 cross-entropy 就退化成「真實 token 預測機率的負對數」、機率越接近 1、loss 越接近 0；機率越接近 0、loss 越接近 ∞。</p>
<p>跟相關概念的關係：</p>
<table>
  <thead>
      <tr>
          <th>概念</th>
          <th>跟 cross-entropy 的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/perplexity/" data-link-title="Perplexity" data-link-desc="cross-entropy 的指數形式、直覺意義為「模型平均覺得下個 token 有多少種可能」">Perplexity</a></td>
          <td><code>perplexity = exp(cross-entropy)</code>、cross-entropy 的指數形式、人類直覺較好讀</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/kl-divergence/" data-link-title="KL Divergence" data-link-desc="衡量「兩個機率分佈差距」的非對稱指標、RLHF / DPO 等 alignment 訓練的關鍵約束">KL divergence</a></td>
          <td>Cross-entropy = entropy(真實) + KL(真實 ‖ 預測)、訓練時 entropy 是常數、所以 minimize cross-entropy 等於 minimize KL</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/softmax/" data-link-title="Softmax" data-link-desc="把任意實數向量正規化成「總和為 1、每個分量 ∈ [0,1]」的機率分佈">Softmax</a></td>
          <td>Cross-entropy 通常吃 softmax 的輸出當「預測機率」</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 LLM 訓練 / paper 時看到「training loss」幾乎都是 cross-entropy。實務判讀：cross-entropy 直接代表「模型對真實 token 的預測機率有多差」、loss = 2 大致對應「真實 token 被預測機率 ≈ 0.135」（exp(-2)）。模型在 pretrain 階段 cross-entropy 從約 11（純隨機）降到約 2-3（成熟模型）、SFT 階段再略降。</p>
]]></content:encoded></item><item><title>Dot Product</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/dot-product/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/dot-product/</guid><description>&lt;p>Dot product（內積、inner product）的核心概念是「&lt;strong>兩個向量對應位置相乘再加總&lt;/strong>」：&lt;code>a · b = a₁b₁ + a₂b₂ + ... + aₙbₙ&lt;/code>。幾何意義是「a 在 b 方向上的投影長度 × b 的長度」。Dot product 是 LLM 中&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 的計算基礎">attention&lt;/a> 的核心是 dot product、cosine similarity 的本體也是 dot product。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Dot product 在 LLM 中的核心應用：&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>Attention score&lt;/td>
 &lt;td>&lt;code>Q · K^T&lt;/code>&lt;/td>
 &lt;td>算「該 token 跟其他 token 的相關性」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Cosine similarity&lt;/td>
 &lt;td>&lt;code>dot(a, b) / (norm(a) × norm(b))&lt;/code>&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> / semantic search&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>L2-normalized similarity&lt;/td>
 &lt;td>normalize 後直接用 &lt;code>a · b&lt;/code>&lt;/td>
 &lt;td>Vector database 高效檢索&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Logits → token 機率&lt;/td>
 &lt;td>output_projection 本質是「最後 hidden state · token embedding」&lt;/td>
 &lt;td>算每個 vocab token 的「匹配度」&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>幾何直覺：&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">兩個向量方向接近時：dot product 大（正值大）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">兩個向量垂直時： dot product = 0
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">兩個向量方向相反時：dot product 大負值
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">a · b = |a| × |b| × cos(θ)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> ↑
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> θ 是兩向量夾角&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>LLM 推論性能上、dot product 是「&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/matrix-multiplication/" data-link-title="Matrix Multiplication" data-link-desc="LLM 推論最頻繁的單一運算、forward pass 每層的核心、memory bandwidth 瓶頸的根源">matrix multiplication&lt;/a> 的基本單元」、整個 forward pass 可以看成大量 dot product 的批次運算；這是為什麼 GPU / Apple Silicon Neural Engine 都針對 dot product 做硬體優化。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 attention / RAG 相關內容看到「inner product」「dot product」「QK^T」就是這個運算。寫 code 場景的判讀：用 vector database 時、選 distance metric 看：cosine 適合未 normalized 的 embedding、dot product 適合 L2-normalized 的 embedding（兩者結果同、後者較快）；attention 的 KV cache 量化（K=Q8 / V=Q4）對品質的不對稱影響、根本原因是 K 用於 dot product（誤差累積快）、V 用於加權平均（誤差被平均化）。&lt;/p></description><content:encoded><![CDATA[<p>Dot product（內積、inner product）的核心概念是「<strong>兩個向量對應位置相乘再加總</strong>」：<code>a · b = a₁b₁ + a₂b₂ + ... + aₙbₙ</code>。幾何意義是「a 在 b 方向上的投影長度 × b 的長度」。Dot product 是 LLM 中<strong>最頻繁出現的運算之一</strong>：<a href="/blog/llm/knowledge-cards/attention/" data-link-title="Attention" data-link-desc="Transformer 內部讓每個 token 對其他 token 加權平均的核心機制、形成 KV cache 跟 context window 的計算基礎">attention</a> 的核心是 dot product、cosine similarity 的本體也是 dot product。</p>
<h2 id="概念位置">概念位置</h2>
<p>Dot product 在 LLM 中的核心應用：</p>
<table>
  <thead>
      <tr>
          <th>應用</th>
          <th>公式 / 機制</th>
          <th>角色</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Attention score</td>
          <td><code>Q · K^T</code></td>
          <td>算「該 token 跟其他 token 的相關性」</td>
      </tr>
      <tr>
          <td>Cosine similarity</td>
          <td><code>dot(a, b) / (norm(a) × norm(b))</code></td>
          <td><a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> / semantic search</td>
      </tr>
      <tr>
          <td>L2-normalized similarity</td>
          <td>normalize 後直接用 <code>a · b</code></td>
          <td>Vector database 高效檢索</td>
      </tr>
      <tr>
          <td>Logits → token 機率</td>
          <td>output_projection 本質是「最後 hidden state · token embedding」</td>
          <td>算每個 vocab token 的「匹配度」</td>
      </tr>
  </tbody>
</table>
<p>幾何直覺：</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">兩個向量方向接近時：dot product 大（正值大）
</span></span><span class="line"><span class="ln">2</span><span class="cl">兩個向量垂直時：    dot product = 0
</span></span><span class="line"><span class="ln">3</span><span class="cl">兩個向量方向相反時：dot product 大負值
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl">a · b = |a| × |b| × cos(θ)
</span></span><span class="line"><span class="ln">6</span><span class="cl">                          ↑
</span></span><span class="line"><span class="ln">7</span><span class="cl">                  θ 是兩向量夾角</span></span></code></pre></div><p>LLM 推論性能上、dot product 是「<a href="/blog/llm/knowledge-cards/matrix-multiplication/" data-link-title="Matrix Multiplication" data-link-desc="LLM 推論最頻繁的單一運算、forward pass 每層的核心、memory bandwidth 瓶頸的根源">matrix multiplication</a> 的基本單元」、整個 forward pass 可以看成大量 dot product 的批次運算；這是為什麼 GPU / Apple Silicon Neural Engine 都針對 dot product 做硬體優化。</p>
<h2 id="設計責任">設計責任</h2>
<p>讀 attention / RAG 相關內容看到「inner product」「dot product」「QK^T」就是這個運算。寫 code 場景的判讀：用 vector database 時、選 distance metric 看：cosine 適合未 normalized 的 embedding、dot product 適合 L2-normalized 的 embedding（兩者結果同、後者較快）；attention 的 KV cache 量化（K=Q8 / V=Q4）對品質的不對稱影響、根本原因是 K 用於 dot product（誤差累積快）、V 用於加權平均（誤差被平均化）。</p>
]]></content:encoded></item><item><title>DPO（Direct Preference Optimization）</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/dpo/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/dpo/</guid><description>&lt;p>DPO（Direct Preference Optimization、直接偏好最佳化）的核心概念是「&lt;strong>用人類偏好資料直接 fine-tune LLM、不訓 reward model、不用 RL&lt;/strong>」。Rafailov et al. (2023) 提出、用數學變形把 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rlhf/" data-link-title="RLHF" data-link-desc="Reinforcement Learning from Human Feedback：用人類偏好訓練的 reward model 透過 RL 對齊 LLM">RLHF&lt;/a> 的「reward model + PPO」兩階段合併成單一個 supervised loss、訓練流程大幅簡化。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>DPO vs RLHF 的對比：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>RLHF&lt;/th>
 &lt;th>DPO&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>需要 reward model&lt;/td>
 &lt;td>是&lt;/td>
 &lt;td>否&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>訓練步驟&lt;/td>
 &lt;td>收偏好 → 訓 RM → PPO&lt;/td>
 &lt;td>收偏好 → 直接 DPO loss fine-tune&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>訓練穩定性&lt;/td>
 &lt;td>PPO 對 hyperparameter 敏感、容易不穩&lt;/td>
 &lt;td>像 supervised learning、相對穩&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>記憶體&lt;/td>
 &lt;td>三個模型同時運作（policy / RM / reference）&lt;/td>
 &lt;td>兩個（policy / reference frozen）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>KL 約束&lt;/td>
 &lt;td>顯式加 β × KL term&lt;/td>
 &lt;td>內嵌在 loss 公式裡、不用顯式&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>流行度（2026）&lt;/td>
 &lt;td>商業大廠（OpenAI / Anthropic）&lt;/td>
 &lt;td>開源社群（Llama / Qwen / Gemma 系列許多用 DPO）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>DPO 的 loss 形式（簡化）：&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">loss = -log σ( β · (log π(y_w|x)/π_ref(y_w|x) - log π(y_l|x)/π_ref(y_l|x)) )
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> └─ 偏好 response 在 policy 跟 ref 的 ratio ─┘
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> └─ 拒絕 response 的同樣 ratio ─┘&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>直覺：讓 policy 對偏好 response 的機率增加（相對 ref）、對拒絕 response 的機率降低（相對 ref）。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀開源 LLM 的 paper / model card 看到「DPO-tuned」「preference fine-tuning」就是這個流程。實務上 DPO 訓練成本只是 RLHF 的一小部分、許多 fine-tune 平台（如 Hugging Face TRL）內建支援。後續還有 IPO、KTO、ORPO 等變體、都是「直接用偏好 fine-tune、不訓 reward」這條路線的進一步演化。&lt;/p></description><content:encoded><![CDATA[<p>DPO（Direct Preference Optimization、直接偏好最佳化）的核心概念是「<strong>用人類偏好資料直接 fine-tune LLM、不訓 reward model、不用 RL</strong>」。Rafailov et al. (2023) 提出、用數學變形把 <a href="/blog/llm/knowledge-cards/rlhf/" data-link-title="RLHF" data-link-desc="Reinforcement Learning from Human Feedback：用人類偏好訓練的 reward model 透過 RL 對齊 LLM">RLHF</a> 的「reward model + PPO」兩階段合併成單一個 supervised loss、訓練流程大幅簡化。</p>
<h2 id="概念位置">概念位置</h2>
<p>DPO vs RLHF 的對比：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>RLHF</th>
          <th>DPO</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>需要 reward model</td>
          <td>是</td>
          <td>否</td>
      </tr>
      <tr>
          <td>訓練步驟</td>
          <td>收偏好 → 訓 RM → PPO</td>
          <td>收偏好 → 直接 DPO loss fine-tune</td>
      </tr>
      <tr>
          <td>訓練穩定性</td>
          <td>PPO 對 hyperparameter 敏感、容易不穩</td>
          <td>像 supervised learning、相對穩</td>
      </tr>
      <tr>
          <td>記憶體</td>
          <td>三個模型同時運作（policy / RM / reference）</td>
          <td>兩個（policy / reference frozen）</td>
      </tr>
      <tr>
          <td>KL 約束</td>
          <td>顯式加 β × KL term</td>
          <td>內嵌在 loss 公式裡、不用顯式</td>
      </tr>
      <tr>
          <td>流行度（2026）</td>
          <td>商業大廠（OpenAI / Anthropic）</td>
          <td>開源社群（Llama / Qwen / Gemma 系列許多用 DPO）</td>
      </tr>
  </tbody>
</table>
<p>DPO 的 loss 形式（簡化）：</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">loss = -log σ( β · (log π(y_w|x)/π_ref(y_w|x) - log π(y_l|x)/π_ref(y_l|x)) )
</span></span><span class="line"><span class="ln">2</span><span class="cl">                └─ 偏好 response 在 policy 跟 ref 的 ratio ─┘
</span></span><span class="line"><span class="ln">3</span><span class="cl">                                                            └─ 拒絕 response 的同樣 ratio ─┘</span></span></code></pre></div><p>直覺：讓 policy 對偏好 response 的機率增加（相對 ref）、對拒絕 response 的機率降低（相對 ref）。</p>
<h2 id="設計責任">設計責任</h2>
<p>讀開源 LLM 的 paper / model card 看到「DPO-tuned」「preference fine-tuning」就是這個流程。實務上 DPO 訓練成本只是 RLHF 的一小部分、許多 fine-tune 平台（如 Hugging Face TRL）內建支援。後續還有 IPO、KTO、ORPO 等變體、都是「直接用偏好 fine-tune、不訓 reward」這條路線的進一步演化。</p>
]]></content:encoded></item><item><title>Embedding Layer</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-layer/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-layer/</guid><description>&lt;p>Embedding layer（嵌入層）的核心概念是「Transformer 第一層的查表結構：把整數 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a> ID 對應到一個可訓練向量（embedding）」。本質上是 &lt;code>vocab_size × hidden_dim&lt;/code> 的權重矩陣、每個 token ID 取對應 row 當該 token 的向量表示。後續所有 Transformer block 都對這些向量做運算。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Embedding layer 在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/forward-pass/" data-link-title="Forward Pass" data-link-desc="input 經過所有 layer 的計算、得到 output 的單向流程；推論跟訓練都會跑、訓練多一個反向階段">forward pass&lt;/a> 的位置：&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">input：&amp;#34;Hello world&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓ tokenizer
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">token IDs: [9906, 1917] ← 整數序列
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ↓ embedding layer（vocab × hidden 查表）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">embeddings: [[0.1, -0.3, ...], [0.5, 0.2, ...]] ← 向量序列、(seq_len, hidden_dim)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> ↓ Transformer block × N
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> ↓ output projection
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl">logits&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model&lt;/a> 的差別：&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>Embedding layer（本卡）&lt;/td>
 &lt;td>LLM 內部第一層、把 token ID 轉向量&lt;/td>
 &lt;td>否、是 LLM 的一部分&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">Embedding model&lt;/a>&lt;/td>
 &lt;td>獨立模型、把整段文字轉向量、用於 RAG / 相似度&lt;/td>
 &lt;td>是、獨立模型&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>兩者「都產出向量」、但層級跟用途完全不同：embedding layer 是 LLM 內部結構（per-token、給模型 forward pass 用）、embedding model 是外部工具（per-text、給檢索系統用）。&lt;/p>
&lt;p>Embedding layer 的大小：&lt;/p>
&lt;ul>
&lt;li>Gemma 4 31B：vocab=256K、hidden=5120、embedding matrix ≈ 256K × 5120 = 1.3B 參數&lt;/li>
&lt;li>Llama 3 8B：vocab=128K、hidden=4096、embedding matrix ≈ 0.5B 參數&lt;/li>
&lt;/ul>
&lt;p>通常跟 output projection（hidden → vocab）相同大小、有些模型 tied（共用權重）、有些 untied。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀模型架構圖看到「token embedding」「embed_tokens」就是這一層。實務意涵：模型大小有非小比例來自 embedding（vocab 越大、embedding 越大）；換 tokenizer 等於整個 embedding 重訓、是 fine-tune 時通常不動的部分。&lt;/p></description><content:encoded><![CDATA[<p>Embedding layer（嵌入層）的核心概念是「Transformer 第一層的查表結構：把整數 <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a> ID 對應到一個可訓練向量（embedding）」。本質上是 <code>vocab_size × hidden_dim</code> 的權重矩陣、每個 token ID 取對應 row 當該 token 的向量表示。後續所有 Transformer block 都對這些向量做運算。</p>
<h2 id="概念位置">概念位置</h2>
<p>Embedding layer 在 <a href="/blog/llm/knowledge-cards/forward-pass/" data-link-title="Forward Pass" data-link-desc="input 經過所有 layer 的計算、得到 output 的單向流程；推論跟訓練都會跑、訓練多一個反向階段">forward pass</a> 的位置：</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">input：&#34;Hello world&#34;
</span></span><span class="line"><span class="ln">2</span><span class="cl">   ↓ tokenizer
</span></span><span class="line"><span class="ln">3</span><span class="cl">token IDs: [9906, 1917]            ← 整數序列
</span></span><span class="line"><span class="ln">4</span><span class="cl">   ↓ embedding layer（vocab × hidden 查表）
</span></span><span class="line"><span class="ln">5</span><span class="cl">embeddings: [[0.1, -0.3, ...], [0.5, 0.2, ...]]   ← 向量序列、(seq_len, hidden_dim)
</span></span><span class="line"><span class="ln">6</span><span class="cl">   ↓ Transformer block × N
</span></span><span class="line"><span class="ln">7</span><span class="cl">   ↓ output projection
</span></span><span class="line"><span class="ln">8</span><span class="cl">logits</span></span></code></pre></div><p>跟 <a href="/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model</a> 的差別：</p>
<table>
  <thead>
      <tr>
          <th>概念</th>
          <th>用途</th>
          <th>是否獨立訓練 / 部署</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Embedding layer（本卡）</td>
          <td>LLM 內部第一層、把 token ID 轉向量</td>
          <td>否、是 LLM 的一部分</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">Embedding model</a></td>
          <td>獨立模型、把整段文字轉向量、用於 RAG / 相似度</td>
          <td>是、獨立模型</td>
      </tr>
  </tbody>
</table>
<p>兩者「都產出向量」、但層級跟用途完全不同：embedding layer 是 LLM 內部結構（per-token、給模型 forward pass 用）、embedding model 是外部工具（per-text、給檢索系統用）。</p>
<p>Embedding layer 的大小：</p>
<ul>
<li>Gemma 4 31B：vocab=256K、hidden=5120、embedding matrix ≈ 256K × 5120 = 1.3B 參數</li>
<li>Llama 3 8B：vocab=128K、hidden=4096、embedding matrix ≈ 0.5B 參數</li>
</ul>
<p>通常跟 output projection（hidden → vocab）相同大小、有些模型 tied（共用權重）、有些 untied。</p>
<h2 id="設計責任">設計責任</h2>
<p>讀模型架構圖看到「token embedding」「embed_tokens」就是這一層。實務意涵：模型大小有非小比例來自 embedding（vocab 越大、embedding 越大）；換 tokenizer 等於整個 embedding 重訓、是 fine-tune 時通常不動的部分。</p>
]]></content:encoded></item><item><title>Entropy</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/entropy/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/entropy/</guid><description>&lt;p>Entropy（熵）的核心概念是「衡量一個機率分佈的不確定性」。Shannon entropy 公式：&lt;code>H(P) = -sum(P(x) × log P(x))&lt;/code>。直覺：分佈越「平」、entropy 越大（任何結果都可能）；分佈越「尖」、entropy 越小（結果很確定）。Entropy 是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/cross-entropy/" data-link-title="Cross-Entropy" data-link-desc="衡量「預測機率分佈」跟「真實分佈」距離的指標、LLM 預訓練的主要 loss">cross-entropy&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/kl-divergence/" data-link-title="KL Divergence" data-link-desc="衡量「兩個機率分佈差距」的非對稱指標、RLHF / DPO 等 alignment 訓練的關鍵約束">KL divergence&lt;/a>、資訊壓縮等概念的基底。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Entropy 跟 LLM 相關概念的關係：&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">Entropy(P) = -sum P log P ← 一個分佈自身的不確定性
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">Cross-entropy(P, Q) = -sum P log Q ← 用分佈 Q 編碼 P 的成本
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">KL(P ‖ Q) = Cross-entropy(P, Q) - Entropy(P) ← 兩個分佈的差距&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Entropy 在 LLM 中的具體意義：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>場景&lt;/th>
 &lt;th>Entropy 大&lt;/th>
 &lt;th>Entropy 小&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>模型 next-token 預測分佈&lt;/td>
 &lt;td>「不確定下個字、可能 N 種選項」&lt;/td>
 &lt;td>「強烈傾向某幾個 token」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Sampling temperature 高&lt;/td>
 &lt;td>Entropy 高、輸出多樣&lt;/td>
 &lt;td>Entropy 低、輸出確定&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>訓練未收斂&lt;/td>
 &lt;td>分佈接近 uniform、entropy 接近 log(vocab)&lt;/td>
 &lt;td>分佈集中、entropy 降低&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>範例：vocab = 128K、uniform 分佈的 entropy = log(128K) ≈ 11.76（接近 12）；成熟模型在文本上的平均 entropy 約 2-3。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Entropy 本身在 LLM 訓練 / 推論很少直接出現、但理解它能解釋一些現象：&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/perplexity/" data-link-title="Perplexity" data-link-desc="cross-entropy 的指數形式、直覺意義為「模型平均覺得下個 token 有多少種可能」">perplexity&lt;/a> = exp(cross-entropy) 是模型平均不確定性的指數形式；temperature 控制 sampling entropy（高 T → 高 entropy → 多樣輸出）；某些評估方法（如 entropy-based uncertainty estimation）會看模型輸出分佈的 entropy 來判讀「模型有多確定」。&lt;/p></description><content:encoded><![CDATA[<p>Entropy（熵）的核心概念是「衡量一個機率分佈的不確定性」。Shannon entropy 公式：<code>H(P) = -sum(P(x) × log P(x))</code>。直覺：分佈越「平」、entropy 越大（任何結果都可能）；分佈越「尖」、entropy 越小（結果很確定）。Entropy 是 <a href="/blog/llm/knowledge-cards/cross-entropy/" data-link-title="Cross-Entropy" data-link-desc="衡量「預測機率分佈」跟「真實分佈」距離的指標、LLM 預訓練的主要 loss">cross-entropy</a>、<a href="/blog/llm/knowledge-cards/kl-divergence/" data-link-title="KL Divergence" data-link-desc="衡量「兩個機率分佈差距」的非對稱指標、RLHF / DPO 等 alignment 訓練的關鍵約束">KL divergence</a>、資訊壓縮等概念的基底。</p>
<h2 id="概念位置">概念位置</h2>
<p>Entropy 跟 LLM 相關概念的關係：</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">Entropy(P) = -sum P log P                  ← 一個分佈自身的不確定性
</span></span><span class="line"><span class="ln">2</span><span class="cl">Cross-entropy(P, Q) = -sum P log Q         ← 用分佈 Q 編碼 P 的成本
</span></span><span class="line"><span class="ln">3</span><span class="cl">KL(P ‖ Q) = Cross-entropy(P, Q) - Entropy(P) ← 兩個分佈的差距</span></span></code></pre></div><p>Entropy 在 LLM 中的具體意義：</p>
<table>
  <thead>
      <tr>
          <th>場景</th>
          <th>Entropy 大</th>
          <th>Entropy 小</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>模型 next-token 預測分佈</td>
          <td>「不確定下個字、可能 N 種選項」</td>
          <td>「強烈傾向某幾個 token」</td>
      </tr>
      <tr>
          <td>Sampling temperature 高</td>
          <td>Entropy 高、輸出多樣</td>
          <td>Entropy 低、輸出確定</td>
      </tr>
      <tr>
          <td>訓練未收斂</td>
          <td>分佈接近 uniform、entropy 接近 log(vocab)</td>
          <td>分佈集中、entropy 降低</td>
      </tr>
  </tbody>
</table>
<p>範例：vocab = 128K、uniform 分佈的 entropy = log(128K) ≈ 11.76（接近 12）；成熟模型在文本上的平均 entropy 約 2-3。</p>
<h2 id="設計責任">設計責任</h2>
<p>Entropy 本身在 LLM 訓練 / 推論很少直接出現、但理解它能解釋一些現象：<a href="/blog/llm/knowledge-cards/perplexity/" data-link-title="Perplexity" data-link-desc="cross-entropy 的指數形式、直覺意義為「模型平均覺得下個 token 有多少種可能」">perplexity</a> = exp(cross-entropy) 是模型平均不確定性的指數形式；temperature 控制 sampling entropy（高 T → 高 entropy → 多樣輸出）；某些評估方法（如 entropy-based uncertainty estimation）會看模型輸出分佈的 entropy 來判讀「模型有多確定」。</p>
]]></content:encoded></item><item><title>FFN（Feed-Forward Network）</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/ffn/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/ffn/</guid><description>&lt;p>FFN（Feed-Forward Network、前饋網路）的核心概念是「Transformer block 中 attention 後面的兩層 linear + &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/activation-function/" data-link-title="Activation Function" data-link-desc="在 linear layer 之間插入的非線性函數、讓神經網路能表達非線性關係">activation function&lt;/a> 結構」。FFN 是 LLM 中&lt;strong>參數量最大&lt;/strong>的元件、典型 Transformer block 裡 FFN 約佔 2/3 參數、attention 約佔 1/3。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>標準 FFN 的計算：&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">input（hidden_dim）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓ W_up（linear、hidden_dim → intermediate_dim、通常放大 4x）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">intermediate vector
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ↓ activation function（ReLU / GELU / SwiGLU）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> ↓ W_down（linear、intermediate_dim → hidden_dim）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">output（hidden_dim）&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Intermediate dim 通常是 hidden dim 的 4 倍（例如 hidden=4096、intermediate=16384）、所以 FFN 的參數量是 &lt;code>hidden × intermediate × 2 ≈ 8 × hidden²&lt;/code>、遠大於 attention 的 &lt;code>4 × hidden²&lt;/code>（Q/K/V/O 四個 hidden × hidden 矩陣）。&lt;/p>
&lt;p>FFN 變體：&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>標準 FFN&lt;/td>
 &lt;td>兩個 linear + 一個 activation&lt;/td>
 &lt;td>早期 Transformer、BERT、GPT-2&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>SwiGLU FFN&lt;/td>
 &lt;td>三個 linear（gate + up + down）+ Swish&lt;/td>
 &lt;td>Llama、Gemma、Qwen 主流&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>MoE FFN&lt;/td>
 &lt;td>多個「expert」FFN、每個 token 只啟用幾個&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/moe/" data-link-title="Mixture of Experts (MoE)" data-link-desc="把 transformer 的 FFN 層拆成多個專家、每 token 只啟用少數、總參數大但每 token 計算量小的架構">MoE&lt;/a> 模型&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 FFN 是參數大頭、能解釋幾件事：&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/moe/" data-link-title="Mixture of Experts (MoE)" data-link-desc="把 transformer 的 FFN 層拆成多個專家、每 token 只啟用少數、總參數大但每 token 計算量小的架構">MoE&lt;/a> 為什麼是「把 FFN 換成多個專家、只啟用部分」（因為 FFN 是最值得稀疏化的部分）、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/moe-cpu-offload/" data-link-title="MoE CPU 卸載" data-link-desc="把 Mixture-of-Experts 模型不活躍的專家層權重放在系統 RAM、用到再走 PCIe 拉回 GPU、讓有限 VRAM 跑得了更大模型">MoE CPU offload&lt;/a> 為什麼是「把 expert FFN 卸到 RAM」（FFN 大、卸下來省 VRAM）、為什麼模型大小用「參數量」算（FFN 主導）。LoRA fine-tuning 時、通常選擇對 attention 的 Q/V 投影做 LoRA、不對 FFN 動、因為 FFN 太大、LoRA 收益相對小。&lt;/p></description><content:encoded><![CDATA[<p>FFN（Feed-Forward Network、前饋網路）的核心概念是「Transformer block 中 attention 後面的兩層 linear + <a href="/blog/llm/knowledge-cards/activation-function/" data-link-title="Activation Function" data-link-desc="在 linear layer 之間插入的非線性函數、讓神經網路能表達非線性關係">activation function</a> 結構」。FFN 是 LLM 中<strong>參數量最大</strong>的元件、典型 Transformer block 裡 FFN 約佔 2/3 參數、attention 約佔 1/3。</p>
<h2 id="概念位置">概念位置</h2>
<p>標準 FFN 的計算：</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">input（hidden_dim）
</span></span><span class="line"><span class="ln">2</span><span class="cl">  ↓ W_up（linear、hidden_dim → intermediate_dim、通常放大 4x）
</span></span><span class="line"><span class="ln">3</span><span class="cl">intermediate vector
</span></span><span class="line"><span class="ln">4</span><span class="cl">  ↓ activation function（ReLU / GELU / SwiGLU）
</span></span><span class="line"><span class="ln">5</span><span class="cl">  ↓ W_down（linear、intermediate_dim → hidden_dim）
</span></span><span class="line"><span class="ln">6</span><span class="cl">output（hidden_dim）</span></span></code></pre></div><p>Intermediate dim 通常是 hidden dim 的 4 倍（例如 hidden=4096、intermediate=16384）、所以 FFN 的參數量是 <code>hidden × intermediate × 2 ≈ 8 × hidden²</code>、遠大於 attention 的 <code>4 × hidden²</code>（Q/K/V/O 四個 hidden × hidden 矩陣）。</p>
<p>FFN 變體：</p>
<table>
  <thead>
      <tr>
          <th>變體</th>
          <th>結構特性</th>
          <th>出現在</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>標準 FFN</td>
          <td>兩個 linear + 一個 activation</td>
          <td>早期 Transformer、BERT、GPT-2</td>
      </tr>
      <tr>
          <td>SwiGLU FFN</td>
          <td>三個 linear（gate + up + down）+ Swish</td>
          <td>Llama、Gemma、Qwen 主流</td>
      </tr>
      <tr>
          <td>MoE FFN</td>
          <td>多個「expert」FFN、每個 token 只啟用幾個</td>
          <td><a href="/blog/llm/knowledge-cards/moe/" data-link-title="Mixture of Experts (MoE)" data-link-desc="把 transformer 的 FFN 層拆成多個專家、每 token 只啟用少數、總參數大但每 token 計算量小的架構">MoE</a> 模型</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>理解 FFN 是參數大頭、能解釋幾件事：<a href="/blog/llm/knowledge-cards/moe/" data-link-title="Mixture of Experts (MoE)" data-link-desc="把 transformer 的 FFN 層拆成多個專家、每 token 只啟用少數、總參數大但每 token 計算量小的架構">MoE</a> 為什麼是「把 FFN 換成多個專家、只啟用部分」（因為 FFN 是最值得稀疏化的部分）、<a href="/blog/llm/knowledge-cards/moe-cpu-offload/" data-link-title="MoE CPU 卸載" data-link-desc="把 Mixture-of-Experts 模型不活躍的專家層權重放在系統 RAM、用到再走 PCIe 拉回 GPU、讓有限 VRAM 跑得了更大模型">MoE CPU offload</a> 為什麼是「把 expert FFN 卸到 RAM」（FFN 大、卸下來省 VRAM）、為什麼模型大小用「參數量」算（FFN 主導）。LoRA fine-tuning 時、通常選擇對 attention 的 Q/V 投影做 LoRA、不對 FFN 動、因為 FFN 太大、LoRA 收益相對小。</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>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>Forward Pass</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/forward-pass/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/forward-pass/</guid><description>&lt;p>Forward pass（前向傳播）的核心概念是「input 從第一層算到最後一層、得到 output 的單向計算流程」。LLM 推論時生成一個 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a>、就是跑一次 forward pass；訓練時、每個 batch 也都先跑 forward pass 算出 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/loss-function/" data-link-title="Loss Function" data-link-desc="把「模型預測」跟「正確答案」的差距量化成一個純量、訓練的最佳化目標">loss&lt;/a>、再跑 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/backpropagation/" data-link-title="Backpropagation" data-link-desc="從 output loss 反向遞推、用 chain rule 算出每個權重的 gradient 的演算法">backpropagation&lt;/a> 算 gradient。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>LLM 一次 forward pass 的大略流程：&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">input token IDs
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> ↓ embedding layer：整數 → 向量
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">sequence of vectors
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> ↓ Transformer block 1（attention + FFN）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> ↓ Transformer block 2
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> ↓ ...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> ↓ Transformer block N
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">final hidden state
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> ↓ output projection（hidden → vocab）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">logits（每個 vocab token 一個分數）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> ↓ softmax（推論時）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">probability distribution → 挑下一個 token&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>跟相關概念的對比：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>概念&lt;/th>
 &lt;th>跟 forward pass 的關係&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prefill/" data-link-title="Prefill" data-link-desc="Prompt 首次處理時的計算階段：把整段輸入跑過模型、產生 KV cache">Prefill&lt;/a>&lt;/td>
 &lt;td>Prompt 階段的「一次性 forward pass」、所有 prompt token 並行&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Decode 階段&lt;/td>
 &lt;td>每生一個 token 跑一次 forward pass、序列化、慢&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">Speculative decoding&lt;/a>&lt;/td>
 &lt;td>一次 forward pass 同時驗證多個猜測 token&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/backpropagation/" data-link-title="Backpropagation" data-link-desc="從 output loss 反向遞推、用 chain rule 算出每個權重的 gradient 的演算法">Backpropagation&lt;/a>&lt;/td>
 &lt;td>訓練時 forward pass 的反向延伸、推論不需要&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 forward pass 後可以判讀 LLM 的記憶體與速度：每次 forward pass 都要把整份模型權重從記憶體讀到處理器一次、所以 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth&lt;/a> 是推論瓶頸；&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> 的存在是為了避免每次 forward pass 重算前面 token 的 K/V；MTP / speculative decoding 都是「一次 forward pass 攤平多個 token 成本」的優化路徑。&lt;/p></description><content:encoded><![CDATA[<p>Forward pass（前向傳播）的核心概念是「input 從第一層算到最後一層、得到 output 的單向計算流程」。LLM 推論時生成一個 <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a>、就是跑一次 forward pass；訓練時、每個 batch 也都先跑 forward pass 算出 <a href="/blog/llm/knowledge-cards/loss-function/" data-link-title="Loss Function" data-link-desc="把「模型預測」跟「正確答案」的差距量化成一個純量、訓練的最佳化目標">loss</a>、再跑 <a href="/blog/llm/knowledge-cards/backpropagation/" data-link-title="Backpropagation" data-link-desc="從 output loss 反向遞推、用 chain rule 算出每個權重的 gradient 的演算法">backpropagation</a> 算 gradient。</p>
<h2 id="概念位置">概念位置</h2>
<p>LLM 一次 forward pass 的大略流程：</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">input token IDs
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  ↓ embedding layer：整數 → 向量
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">sequence of vectors
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  ↓ Transformer block 1（attention + FFN）
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">  ↓ Transformer block 2
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">  ↓ ...
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  ↓ Transformer block N
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">final hidden state
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">  ↓ output projection（hidden → vocab）
</span></span><span class="line"><span class="ln">10</span><span class="cl">logits（每個 vocab token 一個分數）
</span></span><span class="line"><span class="ln">11</span><span class="cl">  ↓ softmax（推論時）
</span></span><span class="line"><span class="ln">12</span><span class="cl">probability distribution → 挑下一個 token</span></span></code></pre></div><p>跟相關概念的對比：</p>
<table>
  <thead>
      <tr>
          <th>概念</th>
          <th>跟 forward pass 的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/prefill/" data-link-title="Prefill" data-link-desc="Prompt 首次處理時的計算階段：把整段輸入跑過模型、產生 KV cache">Prefill</a></td>
          <td>Prompt 階段的「一次性 forward pass」、所有 prompt token 並行</td>
      </tr>
      <tr>
          <td>Decode 階段</td>
          <td>每生一個 token 跑一次 forward pass、序列化、慢</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">Speculative decoding</a></td>
          <td>一次 forward pass 同時驗證多個猜測 token</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/backpropagation/" data-link-title="Backpropagation" data-link-desc="從 output loss 反向遞推、用 chain rule 算出每個權重的 gradient 的演算法">Backpropagation</a></td>
          <td>訓練時 forward pass 的反向延伸、推論不需要</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>理解 forward pass 後可以判讀 LLM 的記憶體與速度：每次 forward pass 都要把整份模型權重從記憶體讀到處理器一次、所以 <a href="/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth</a> 是推論瓶頸；<a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 的存在是為了避免每次 forward pass 重算前面 token 的 K/V；MTP / speculative decoding 都是「一次 forward pass 攤平多個 token 成本」的優化路徑。</p>
]]></content:encoded></item><item><title>GPU Compute Backend</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/gpu-compute-backend/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/gpu-compute-backend/</guid><description>&lt;p>GPU compute backend 的核心概念是「推論軟體（如 llama.cpp、PyTorch）跟 GPU 之間的計算 API 抽象層」。不同廠商 GPU 對應不同 backend、同一推論軟體通常要為每個 backend 編譯獨立 build。選對 backend 直接影響 GPU 算力能否被有效利用。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>各家 GPU 對應的常見 backend（2026 年 5 月狀態、依社群實踐變化）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Backend&lt;/th>
 &lt;th>主要 GPU 廠商&lt;/th>
 &lt;th>平台支援&lt;/th>
 &lt;th>llama.cpp 生態成熟度&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>CUDA&lt;/td>
 &lt;td>NVIDIA&lt;/td>
 &lt;td>Windows / Linux&lt;/td>
 &lt;td>最成熟、社群預設&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>ROCm&lt;/td>
 &lt;td>AMD&lt;/td>
 &lt;td>Linux 主、Windows 演進中&lt;/td>
 &lt;td>中、依 GPU 型號變化&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Vulkan&lt;/td>
 &lt;td>跨廠商通用&lt;/td>
 &lt;td>Windows / Linux&lt;/td>
 &lt;td>中、通用 fallback&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Metal&lt;/td>
 &lt;td>Apple Silicon&lt;/td>
 &lt;td>macOS&lt;/td>
 &lt;td>成熟（屬模組一範圍）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>SYCL&lt;/td>
 &lt;td>Intel ARC&lt;/td>
 &lt;td>Windows / Linux&lt;/td>
 &lt;td>相對年輕&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DirectML&lt;/td>
 &lt;td>多廠商（DirectX）&lt;/td>
 &lt;td>Windows&lt;/td>
 &lt;td>較少用於 LLM&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>OpenVINO&lt;/td>
 &lt;td>Intel&lt;/td>
 &lt;td>多平台&lt;/td>
 &lt;td>偏 Intel 生態&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>選 backend 的判讀依硬體跟平台：NVIDIA GPU 用 CUDA、AMD on Linux 優先 ROCm、AMD on Windows 多用 Vulkan、Intel ARC 用 Vulkan 或 SYCL、Apple Silicon 用 Metal。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：上表的「llama.cpp 生態成熟度」是社群常見回報、不是經本卡系統實測的 benchmark；各 backend 的支援度跟 throughput 依推論軟體版本快速演進、引用前以對應 backend 的官方文件跟 &lt;a href="https://github.com/ggml-org/llama.cpp/releases">llama.cpp release notes&lt;/a> 為準。&lt;/p>&lt;/blockquote>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 GPU compute backend 後可以解釋三個現象：為什麼下載 llama.cpp release 要選 CUDA / ROCm / Vulkan 版本（每個 build 對應一種 backend）、為什麼同樣硬體 throughput 差很多（backend 不對或 fallback 到 CPU）、為什麼非 NVIDIA GPU 跑 LLM 經驗較少（CUDA 生態太成熟、其他 backend 仍在演進）。&lt;/p>
&lt;p>選 PC GPU 跑本地 LLM 時、backend 成熟度是「工具鏈支援度」軸、跟硬體規格軸獨立、選卡時兩軸都要考慮。詳見 &lt;a href="https://tarrragon.github.io/blog/llm/05-discrete-gpu/gpu-vendor-differences/" data-link-title="5.6 GPU 廠商差異" data-link-desc="NVIDIA CUDA、AMD ROCm、Intel ARC 在 llama.cpp 生態的相對位置、選卡時的判讀軸">5.6 GPU 廠商差異&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>GPU compute backend 的核心概念是「推論軟體（如 llama.cpp、PyTorch）跟 GPU 之間的計算 API 抽象層」。不同廠商 GPU 對應不同 backend、同一推論軟體通常要為每個 backend 編譯獨立 build。選對 backend 直接影響 GPU 算力能否被有效利用。</p>
<h2 id="概念位置">概念位置</h2>
<p>各家 GPU 對應的常見 backend（2026 年 5 月狀態、依社群實踐變化）：</p>
<table>
  <thead>
      <tr>
          <th>Backend</th>
          <th>主要 GPU 廠商</th>
          <th>平台支援</th>
          <th>llama.cpp 生態成熟度</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>CUDA</td>
          <td>NVIDIA</td>
          <td>Windows / Linux</td>
          <td>最成熟、社群預設</td>
      </tr>
      <tr>
          <td>ROCm</td>
          <td>AMD</td>
          <td>Linux 主、Windows 演進中</td>
          <td>中、依 GPU 型號變化</td>
      </tr>
      <tr>
          <td>Vulkan</td>
          <td>跨廠商通用</td>
          <td>Windows / Linux</td>
          <td>中、通用 fallback</td>
      </tr>
      <tr>
          <td>Metal</td>
          <td>Apple Silicon</td>
          <td>macOS</td>
          <td>成熟（屬模組一範圍）</td>
      </tr>
      <tr>
          <td>SYCL</td>
          <td>Intel ARC</td>
          <td>Windows / Linux</td>
          <td>相對年輕</td>
      </tr>
      <tr>
          <td>DirectML</td>
          <td>多廠商（DirectX）</td>
          <td>Windows</td>
          <td>較少用於 LLM</td>
      </tr>
      <tr>
          <td>OpenVINO</td>
          <td>Intel</td>
          <td>多平台</td>
          <td>偏 Intel 生態</td>
      </tr>
  </tbody>
</table>
<p>選 backend 的判讀依硬體跟平台：NVIDIA GPU 用 CUDA、AMD on Linux 優先 ROCm、AMD on Windows 多用 Vulkan、Intel ARC 用 Vulkan 或 SYCL、Apple Silicon 用 Metal。</p>
<blockquote>
<p><strong>事實查核註</strong>：上表的「llama.cpp 生態成熟度」是社群常見回報、不是經本卡系統實測的 benchmark；各 backend 的支援度跟 throughput 依推論軟體版本快速演進、引用前以對應 backend 的官方文件跟 <a href="https://github.com/ggml-org/llama.cpp/releases">llama.cpp release notes</a> 為準。</p></blockquote>
<h2 id="設計責任">設計責任</h2>
<p>理解 GPU compute backend 後可以解釋三個現象：為什麼下載 llama.cpp release 要選 CUDA / ROCm / Vulkan 版本（每個 build 對應一種 backend）、為什麼同樣硬體 throughput 差很多（backend 不對或 fallback 到 CPU）、為什麼非 NVIDIA GPU 跑 LLM 經驗較少（CUDA 生態太成熟、其他 backend 仍在演進）。</p>
<p>選 PC GPU 跑本地 LLM 時、backend 成熟度是「工具鏈支援度」軸、跟硬體規格軸獨立、選卡時兩軸都要考慮。詳見 <a href="/blog/llm/05-discrete-gpu/gpu-vendor-differences/" data-link-title="5.6 GPU 廠商差異" data-link-desc="NVIDIA CUDA、AMD ROCm、Intel ARC 在 llama.cpp 生態的相對位置、選卡時的判讀軸">5.6 GPU 廠商差異</a>。</p>
]]></content:encoded></item><item><title>Gradient</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/gradient/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/gradient/</guid><description>&lt;p>Gradient（梯度）的核心概念是「&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/loss-function/" data-link-title="Loss Function" data-link-desc="把「模型預測」跟「正確答案」的差距量化成一個純量、訓練的最佳化目標">loss function&lt;/a> 對每個權重的偏微分組成的向量」。每個分量回答「這個權重往正方向動一單位、loss 會變多少」、整個 gradient 向量指向「loss 上升最快的方向」、所以訓練時往&lt;strong>反方向&lt;/strong>走、就是讓 loss 下降最快的方向。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Gradient 連接「loss」跟「該怎麼更新權重」兩件事、是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/backpropagation/" data-link-title="Backpropagation" data-link-desc="從 output loss 反向遞推、用 chain rule 算出每個權重的 gradient 的演算法">backpropagation&lt;/a> 算出來的東西、也是 SGD / Adam 等 optimizer 消費的輸入：&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">[forward pass] → 算出 loss
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">[backpropagation] → 算出 gradient（每個權重一個值）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">[optimizer] → 用 gradient 更新權重：w_new = w_old - lr × gradient&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Gradient 在 LLM 訓練中的兩個常見問題：&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>Gradient 爆炸&lt;/td>
 &lt;td>loss 突然變 NaN、梯度 norm &amp;gt; 1000&lt;/td>
 &lt;td>Gradient clipping（截斷 norm 上限）、降 learning rate&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Gradient 消失&lt;/td>
 &lt;td>深層權重幾乎不更新、loss 停在某 plateau&lt;/td>
 &lt;td>Residual connection、Layer normalization、改 activation function&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>推論階段（拿訓練好的模型生 token）&lt;strong>不需要算 gradient&lt;/strong>、只有 forward pass；gradient 只在訓練 / fine-tuning 階段出現。所以本地跑 LLM 寫 code 的場景不會碰到 gradient、但讀懂訓練流程、理解「為什麼 SFT / RLHF 需要 GPU、推論不一定要」這類判讀就要先理解 gradient 的角色。&lt;/p></description><content:encoded><![CDATA[<p>Gradient（梯度）的核心概念是「<a href="/blog/llm/knowledge-cards/loss-function/" data-link-title="Loss Function" data-link-desc="把「模型預測」跟「正確答案」的差距量化成一個純量、訓練的最佳化目標">loss function</a> 對每個權重的偏微分組成的向量」。每個分量回答「這個權重往正方向動一單位、loss 會變多少」、整個 gradient 向量指向「loss 上升最快的方向」、所以訓練時往<strong>反方向</strong>走、就是讓 loss 下降最快的方向。</p>
<h2 id="概念位置">概念位置</h2>
<p>Gradient 連接「loss」跟「該怎麼更新權重」兩件事、是 <a href="/blog/llm/knowledge-cards/backpropagation/" data-link-title="Backpropagation" data-link-desc="從 output loss 反向遞推、用 chain rule 算出每個權重的 gradient 的演算法">backpropagation</a> 算出來的東西、也是 SGD / Adam 等 optimizer 消費的輸入：</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">[forward pass] → 算出 loss
</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">[backpropagation] → 算出 gradient（每個權重一個值）
</span></span><span class="line"><span class="ln">4</span><span class="cl">                    ↓
</span></span><span class="line"><span class="ln">5</span><span class="cl">[optimizer] → 用 gradient 更新權重：w_new = w_old - lr × gradient</span></span></code></pre></div><p>Gradient 在 LLM 訓練中的兩個常見問題：</p>
<table>
  <thead>
      <tr>
          <th>問題</th>
          <th>訊號</th>
          <th>處理</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Gradient 爆炸</td>
          <td>loss 突然變 NaN、梯度 norm &gt; 1000</td>
          <td>Gradient clipping（截斷 norm 上限）、降 learning rate</td>
      </tr>
      <tr>
          <td>Gradient 消失</td>
          <td>深層權重幾乎不更新、loss 停在某 plateau</td>
          <td>Residual connection、Layer normalization、改 activation function</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>推論階段（拿訓練好的模型生 token）<strong>不需要算 gradient</strong>、只有 forward pass；gradient 只在訓練 / fine-tuning 階段出現。所以本地跑 LLM 寫 code 的場景不會碰到 gradient、但讀懂訓練流程、理解「為什麼 SFT / RLHF 需要 GPU、推論不一定要」這類判讀就要先理解 gradient 的角色。</p>
]]></content:encoded></item><item><title>Gradient Explosion / Vanishing</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/gradient-explosion-vanishing/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/gradient-explosion-vanishing/</guid><description>&lt;p>Gradient explosion（爆炸）跟 gradient vanishing（消失）的核心概念是「深層網路的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/backpropagation/" data-link-title="Backpropagation" data-link-desc="從 output loss 反向遞推、用 chain rule 算出每個權重的 gradient 的演算法">backpropagation&lt;/a> 透過 chain rule 一層層相乘、若每層 gradient &amp;gt; 1、累乘到輸入層會指數爆炸；若每層 gradient &amp;lt; 1、累乘到輸入層會衰減到接近 0」。兩者是深層網路訓不起來的典型病因、現代 Transformer 用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/residual-connection/" data-link-title="Residual Connection" data-link-desc="把 layer 的輸入直接加到輸出上的「跳接」、讓深層網路的梯度能穩定回流">residual connection&lt;/a> + &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/layer-normalization/" data-link-title="Layer Normalization" data-link-desc="在每個 token 的 hidden state 上做正規化（減 mean、除 std）、穩定深層網路訓練">layer normalization&lt;/a> 解決。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>兩種失敗模式的訊號跟處理：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &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>Gradient explosion&lt;/td>
 &lt;td>loss 突然變 NaN、gradient norm &amp;gt; 1000+&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/learning-rate/" data-link-title="Learning Rate" data-link-desc="gradient descent 每步更新權重的幅度、訓練中最敏感的 hyperparameter">Learning rate&lt;/a> 太大、初始化不當、loss 函數有奇點&lt;/td>
 &lt;td>Gradient clipping（截斷 norm 上限、如 1.0）、降低 lr、檢查資料 outliers&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Gradient vanishing&lt;/td>
 &lt;td>深層權重幾乎不更新、loss 卡 plateau&lt;/td>
 &lt;td>層數深、activation 飽和區（sigmoid、tanh）、缺 skip connection&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/residual-connection/" data-link-title="Residual Connection" data-link-desc="把 layer 的輸入直接加到輸出上的「跳接」、讓深層網路的梯度能穩定回流">Residual connection&lt;/a> + &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/layer-normalization/" data-link-title="Layer Normalization" data-link-desc="在每個 token 的 hidden state 上做正規化（減 mean、除 std）、穩定深層網路訓練">layer norm&lt;/a> + 換 activation（ReLU / GELU / SwiGLU）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>數學直覺（簡化）：&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">深 N 層的 chain rule：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">∂loss/∂W_input = ∂loss/∂out × ∂out/∂h_N × ∂h_N/∂h_{N-1} × ... × ∂h_1/∂W_input
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> └──────────── N 個 factor 連乘 ──────────────┘
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">若每個 factor ≈ 0.5、N=100：累乘 ≈ 0.5^100 ≈ 0 → vanishing
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">若每個 factor ≈ 1.5、N=100：累乘 ≈ 1.5^100 ≈ 4e17 → explosion&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/residual-connection/" data-link-title="Residual Connection" data-link-desc="把 layer 的輸入直接加到輸出上的「跳接」、讓深層網路的梯度能穩定回流">Residual connection&lt;/a> 讓 gradient 有「捷徑」可走、不全靠 chain rule 一層層乘、是深層 Transformer 訓得起來的核心結構之一。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀訓練 log 看到 &lt;code>loss: nan&lt;/code>、&lt;code>grad_norm: inf&lt;/code> 就是 explosion；看到 loss 平穩、幾個 epoch 都不降就是可能的 vanishing。寫 code 場景幾乎不會碰到（推論不算 gradient）、但自己 fine-tune 時要會判讀。LLM 用的 SwiGLU / GELU 都是 saturation 較不嚴重的 activation、加上 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/residual-connection/" data-link-title="Residual Connection" data-link-desc="把 layer 的輸入直接加到輸出上的「跳接」、讓深層網路的梯度能穩定回流">residual&lt;/a> + &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/layer-normalization/" data-link-title="Layer Normalization" data-link-desc="在每個 token 的 hidden state 上做正規化（減 mean、除 std）、穩定深層網路訓練">pre-norm&lt;/a>、現代 Transformer 訓 100+ 層相對穩定。&lt;/p></description><content:encoded><![CDATA[<p>Gradient explosion（爆炸）跟 gradient vanishing（消失）的核心概念是「深層網路的 <a href="/blog/llm/knowledge-cards/backpropagation/" data-link-title="Backpropagation" data-link-desc="從 output loss 反向遞推、用 chain rule 算出每個權重的 gradient 的演算法">backpropagation</a> 透過 chain rule 一層層相乘、若每層 gradient &gt; 1、累乘到輸入層會指數爆炸；若每層 gradient &lt; 1、累乘到輸入層會衰減到接近 0」。兩者是深層網路訓不起來的典型病因、現代 Transformer 用 <a href="/blog/llm/knowledge-cards/residual-connection/" data-link-title="Residual Connection" data-link-desc="把 layer 的輸入直接加到輸出上的「跳接」、讓深層網路的梯度能穩定回流">residual connection</a> + <a href="/blog/llm/knowledge-cards/layer-normalization/" data-link-title="Layer Normalization" data-link-desc="在每個 token 的 hidden state 上做正規化（減 mean、除 std）、穩定深層網路訓練">layer normalization</a> 解決。</p>
<h2 id="概念位置">概念位置</h2>
<p>兩種失敗模式的訊號跟處理：</p>
<table>
  <thead>
      <tr>
          <th>模式</th>
          <th>訊號</th>
          <th>主要成因</th>
          <th>處理</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Gradient explosion</td>
          <td>loss 突然變 NaN、gradient norm &gt; 1000+</td>
          <td><a href="/blog/llm/knowledge-cards/learning-rate/" data-link-title="Learning Rate" data-link-desc="gradient descent 每步更新權重的幅度、訓練中最敏感的 hyperparameter">Learning rate</a> 太大、初始化不當、loss 函數有奇點</td>
          <td>Gradient clipping（截斷 norm 上限、如 1.0）、降低 lr、檢查資料 outliers</td>
      </tr>
      <tr>
          <td>Gradient vanishing</td>
          <td>深層權重幾乎不更新、loss 卡 plateau</td>
          <td>層數深、activation 飽和區（sigmoid、tanh）、缺 skip connection</td>
          <td><a href="/blog/llm/knowledge-cards/residual-connection/" data-link-title="Residual Connection" data-link-desc="把 layer 的輸入直接加到輸出上的「跳接」、讓深層網路的梯度能穩定回流">Residual connection</a> + <a href="/blog/llm/knowledge-cards/layer-normalization/" data-link-title="Layer Normalization" data-link-desc="在每個 token 的 hidden state 上做正規化（減 mean、除 std）、穩定深層網路訓練">layer norm</a> + 換 activation（ReLU / GELU / SwiGLU）</td>
      </tr>
  </tbody>
</table>
<p>數學直覺（簡化）：</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">深 N 層的 chain rule：
</span></span><span class="line"><span class="ln">2</span><span class="cl">∂loss/∂W_input = ∂loss/∂out × ∂out/∂h_N × ∂h_N/∂h_{N-1} × ... × ∂h_1/∂W_input
</span></span><span class="line"><span class="ln">3</span><span class="cl">                                └──────────── N 個 factor 連乘 ──────────────┘
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl">若每個 factor ≈ 0.5、N=100：累乘 ≈ 0.5^100 ≈ 0       → vanishing
</span></span><span class="line"><span class="ln">6</span><span class="cl">若每個 factor ≈ 1.5、N=100：累乘 ≈ 1.5^100 ≈ 4e17    → explosion</span></span></code></pre></div><p><a href="/blog/llm/knowledge-cards/residual-connection/" data-link-title="Residual Connection" data-link-desc="把 layer 的輸入直接加到輸出上的「跳接」、讓深層網路的梯度能穩定回流">Residual connection</a> 讓 gradient 有「捷徑」可走、不全靠 chain rule 一層層乘、是深層 Transformer 訓得起來的核心結構之一。</p>
<h2 id="設計責任">設計責任</h2>
<p>讀訓練 log 看到 <code>loss: nan</code>、<code>grad_norm: inf</code> 就是 explosion；看到 loss 平穩、幾個 epoch 都不降就是可能的 vanishing。寫 code 場景幾乎不會碰到（推論不算 gradient）、但自己 fine-tune 時要會判讀。LLM 用的 SwiGLU / GELU 都是 saturation 較不嚴重的 activation、加上 <a href="/blog/llm/knowledge-cards/residual-connection/" data-link-title="Residual Connection" data-link-desc="把 layer 的輸入直接加到輸出上的「跳接」、讓深層網路的梯度能穩定回流">residual</a> + <a href="/blog/llm/knowledge-cards/layer-normalization/" data-link-title="Layer Normalization" data-link-desc="在每個 token 的 hidden state 上做正規化（減 mean、除 std）、穩定深層網路訓練">pre-norm</a>、現代 Transformer 訓 100+ 層相對穩定。</p>
]]></content:encoded></item><item><title>Hallucination</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/hallucination/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/hallucination/</guid><description>&lt;p>Hallucination 的核心概念是「LLM 生成的內容語法、語氣、結構看起來合理、但內容上是事實錯誤、引用不存在的來源、虛構不存在的 entity」。這是 LLM 基於統計分布生成的固有特性；以目前的研究跟工程實踐、靠「更大模型」或「更好對齊」很難徹底消除、可控的做法是用工程手段降低觸發率跟下游偵測。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Hallucination 的常見形態：&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>虛構引用&lt;/td>
 &lt;td>引用不存在的論文 / API / 函式名稱&lt;/td>
 &lt;td>使用者照抄、出錯&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>虛構 entity&lt;/td>
 &lt;td>虛構不存在的公司 / 人名 / 地址&lt;/td>
 &lt;td>寫入文件、產生誤導&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>數值幻覺&lt;/td>
 &lt;td>給看似精確但實際錯誤的數字&lt;/td>
 &lt;td>商業 / 工程決策被誤導&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>因果幻覺&lt;/td>
 &lt;td>編造看似合理但不存在的因果關係&lt;/td>
 &lt;td>推理鏈不可信&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>法律 / 醫療幻覺&lt;/td>
 &lt;td>虛構不存在的法條 / 治療方案&lt;/td>
 &lt;td>高風險領域、可能造成實際傷害&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>降低 / 偵測 hallucination 的常見手段（依場景變化）：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a>&lt;/strong>：把真實內容檢索後注入 prompt、模型基於真實內容生成。&lt;/li>
&lt;li>&lt;strong>temperature 降低&lt;/strong>：採樣較保守、減少創造性但也減少幻覺。&lt;/li>
&lt;li>&lt;strong>citation 要求&lt;/strong>：prompt 要求列出引用、後續可驗證。&lt;/li>
&lt;li>&lt;strong>下游驗證&lt;/strong>：對輸出做事實檢查（如 code 跑 compiler、引用查實際資料庫）。&lt;/li>
&lt;li>&lt;strong>明確的「不知道就說不知道」instruction&lt;/strong>：降低過度自信、但不能消除。&lt;/li>
&lt;/ol>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：Hallucination 的研究跟降低技術仍在快速演進、不同模型、不同任務類型的 hallucination rate 變化大、引用前以最新研究跟具體 model card 為準。Stanford &lt;a href="https://arxiv.org/abs/2109.07958">TruthfulQA&lt;/a> 等 benchmark 是常見參考。&lt;/p>&lt;/blockquote>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 hallucination 後可以解釋兩個現象：為什麼 LLM 給的「具體事實」（人名 / 數字 / 引用）特別要驗證（生成機制本身就會虛構）、為什麼 LLM 寫的 code 看似合理但 import 不存在的 package（hallucinate 出 library API）。&lt;/p>
&lt;p>production 場景下、hallucination 影響合規（生成包含真人 PII 的虛構內容仍是 PII 處理）、UX（使用者照抄誤導內容）、安全（生成假 URL 引發釣魚）；應對策略不是「擋住 hallucination」、是「降低觸發率 + 下游驗證 + 適當的 disclaimer」。詳見 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/llm-log-and-pii-governance/" data-link-title="LLM Log 與 PII 治理" data-link-desc="production LLM 服務的 prompt log 累積、PII 偵測與過濾、保留期限與合規對齊">LLM Log 與 PII 治理&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Hallucination 的核心概念是「LLM 生成的內容語法、語氣、結構看起來合理、但內容上是事實錯誤、引用不存在的來源、虛構不存在的 entity」。這是 LLM 基於統計分布生成的固有特性；以目前的研究跟工程實踐、靠「更大模型」或「更好對齊」很難徹底消除、可控的做法是用工程手段降低觸發率跟下游偵測。</p>
<h2 id="概念位置">概念位置</h2>
<p>Hallucination 的常見形態：</p>
<table>
  <thead>
      <tr>
          <th>形態</th>
          <th>例子</th>
          <th>風險</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>虛構引用</td>
          <td>引用不存在的論文 / API / 函式名稱</td>
          <td>使用者照抄、出錯</td>
      </tr>
      <tr>
          <td>虛構 entity</td>
          <td>虛構不存在的公司 / 人名 / 地址</td>
          <td>寫入文件、產生誤導</td>
      </tr>
      <tr>
          <td>數值幻覺</td>
          <td>給看似精確但實際錯誤的數字</td>
          <td>商業 / 工程決策被誤導</td>
      </tr>
      <tr>
          <td>因果幻覺</td>
          <td>編造看似合理但不存在的因果關係</td>
          <td>推理鏈不可信</td>
      </tr>
      <tr>
          <td>法律 / 醫療幻覺</td>
          <td>虛構不存在的法條 / 治療方案</td>
          <td>高風險領域、可能造成實際傷害</td>
      </tr>
  </tbody>
</table>
<p>降低 / 偵測 hallucination 的常見手段（依場景變化）：</p>
<ol>
<li><strong><a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a></strong>：把真實內容檢索後注入 prompt、模型基於真實內容生成。</li>
<li><strong>temperature 降低</strong>：採樣較保守、減少創造性但也減少幻覺。</li>
<li><strong>citation 要求</strong>：prompt 要求列出引用、後續可驗證。</li>
<li><strong>下游驗證</strong>：對輸出做事實檢查（如 code 跑 compiler、引用查實際資料庫）。</li>
<li><strong>明確的「不知道就說不知道」instruction</strong>：降低過度自信、但不能消除。</li>
</ol>
<blockquote>
<p><strong>事實查核註</strong>：Hallucination 的研究跟降低技術仍在快速演進、不同模型、不同任務類型的 hallucination rate 變化大、引用前以最新研究跟具體 model card 為準。Stanford <a href="https://arxiv.org/abs/2109.07958">TruthfulQA</a> 等 benchmark 是常見參考。</p></blockquote>
<h2 id="設計責任">設計責任</h2>
<p>理解 hallucination 後可以解釋兩個現象：為什麼 LLM 給的「具體事實」（人名 / 數字 / 引用）特別要驗證（生成機制本身就會虛構）、為什麼 LLM 寫的 code 看似合理但 import 不存在的 package（hallucinate 出 library API）。</p>
<p>production 場景下、hallucination 影響合規（生成包含真人 PII 的虛構內容仍是 PII 處理）、UX（使用者照抄誤導內容）、安全（生成假 URL 引發釣魚）；應對策略不是「擋住 hallucination」、是「降低觸發率 + 下游驗證 + 適當的 disclaimer」。詳見 <a href="/blog/backend/07-security-data-protection/llm-log-and-pii-governance/" data-link-title="LLM Log 與 PII 治理" data-link-desc="production LLM 服務的 prompt log 累積、PII 偵測與過濾、保留期限與合規對齊">LLM Log 與 PII 治理</a>。</p>
]]></content:encoded></item><item><title>Homebrew</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/homebrew/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/homebrew/</guid><description>&lt;p>Homebrew 的核心概念是「macOS 的社群套件管理器、用 &lt;code>brew install&lt;/code> 一行裝完 CLI 工具或 GUI 程式」。對本地 LLM 場景的角色是「Ollama、llama.cpp 等命令列工具的標準安裝入口」、把編譯、依賴管理、PATH 設定、二進位放置位置都自動化。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Homebrew 在 macOS 跟使用者要安裝的工具之間、扮演「公開 registry + 本地套件管理」的角色。它維護一份名為「formula」的 Ruby 腳本清單、每個 formula 描述某個工具怎麼下載、編譯、安裝。執行 &lt;code>brew install ollama&lt;/code> 時、Homebrew 找到 ollama formula、下載對應 bottle（預編譯二進位）、放到 &lt;code>/opt/homebrew/&lt;/code>（Apple Silicon）或 &lt;code>/usr/local/&lt;/code>（Intel Mac）、再把可執行檔 symlink 到 &lt;code>/opt/homebrew/bin/&lt;/code>。新機從零的完整安裝順序（含第一次裝 Homebrew、PATH 設定與晶片前綴差異）見 &lt;a href="https://tarrragon.github.io/blog/other/macos-%E6%96%B0%E6%A9%9F%E5%9F%BA%E7%A4%8E%E5%BB%BA%E8%A8%AD%E5%A5%97%E4%BB%B6%E7%AE%A1%E7%90%86%E8%88%87%E5%80%8B%E4%BA%BA-bin-%E7%9A%84%E8%A8%AD%E5%AE%9A%E9%A0%86%E5%BA%8F/" data-link-title="macOS 新機基礎建設：套件管理與個人 bin 的設定順序" data-link-desc="重灌或換機後底層基礎建設的依賴順序，免得後面工具裝不起來或路徑互相找不到。">macOS 新機基礎建設&lt;/a>。&lt;/p>
&lt;p>&lt;code>brew services&lt;/code> 是 Homebrew 附帶的服務管理子命令、把指令封裝成 macOS 原生的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/launchd-service/" data-link-title="launchd Service" data-link-desc="macOS 原生的服務管理機制、把 process 註冊成自動啟動的 daemon 或 agent">launchd service&lt;/a>、處理「開機自動啟動 / 停止 / 重啟」需求。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>日常會碰到的 brew 指令：&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>&lt;code>brew install &amp;lt;pkg&amp;gt;&lt;/code>&lt;/td>
 &lt;td>安裝套件&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>brew upgrade &amp;lt;pkg&amp;gt;&lt;/code>&lt;/td>
 &lt;td>升級單一套件&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>brew services start&lt;/code>&lt;/td>
 &lt;td>把套件註冊成 launchd service、立刻啟動&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>brew services list&lt;/code>&lt;/td>
 &lt;td>列出目前由 brew 管理的常駐服務&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>which &amp;lt;bin&amp;gt;&lt;/code>&lt;/td>
 &lt;td>確認可執行檔在 PATH 上的實際路徑&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>brew --prefix&lt;/code>&lt;/td>
 &lt;td>查 Homebrew 的安裝根目錄&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Apple Silicon Mac 上的關鍵路徑是 &lt;code>/opt/homebrew/&lt;/code>、子資料夾各有角色：&lt;code>bin/&lt;/code>（可執行檔）、&lt;code>var/log/&lt;/code>（服務 log）、&lt;code>Cellar/&lt;/code>（套件實際內容）、&lt;code>opt/&lt;/code>（版本無關的 symlink）。看到「&lt;code>/opt/homebrew/var/log/ollama.log&lt;/code>」時、就是 brew 管理的 Ollama 服務 log 位置。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>用 brew 安裝 vs 用官方 .dmg / .pkg 的取捨：CLI 工具（ollama、llama.cpp、git 等）走 brew、好處是統一升級路徑；GUI 應用（LM Studio、Docker Desktop 等）多半改下載官方安裝包、因為 brew cask 不一定即時跟上版本。第一次裝 Homebrew 自己用官方 install script（在 &lt;a href="https://brew.sh">brew.sh&lt;/a>）、之後其他工具都從 brew 走。&lt;/p></description><content:encoded><![CDATA[<p>Homebrew 的核心概念是「macOS 的社群套件管理器、用 <code>brew install</code> 一行裝完 CLI 工具或 GUI 程式」。對本地 LLM 場景的角色是「Ollama、llama.cpp 等命令列工具的標準安裝入口」、把編譯、依賴管理、PATH 設定、二進位放置位置都自動化。</p>
<h2 id="概念位置">概念位置</h2>
<p>Homebrew 在 macOS 跟使用者要安裝的工具之間、扮演「公開 registry + 本地套件管理」的角色。它維護一份名為「formula」的 Ruby 腳本清單、每個 formula 描述某個工具怎麼下載、編譯、安裝。執行 <code>brew install ollama</code> 時、Homebrew 找到 ollama formula、下載對應 bottle（預編譯二進位）、放到 <code>/opt/homebrew/</code>（Apple Silicon）或 <code>/usr/local/</code>（Intel Mac）、再把可執行檔 symlink 到 <code>/opt/homebrew/bin/</code>。新機從零的完整安裝順序（含第一次裝 Homebrew、PATH 設定與晶片前綴差異）見 <a href="/blog/other/macos-%E6%96%B0%E6%A9%9F%E5%9F%BA%E7%A4%8E%E5%BB%BA%E8%A8%AD%E5%A5%97%E4%BB%B6%E7%AE%A1%E7%90%86%E8%88%87%E5%80%8B%E4%BA%BA-bin-%E7%9A%84%E8%A8%AD%E5%AE%9A%E9%A0%86%E5%BA%8F/" data-link-title="macOS 新機基礎建設：套件管理與個人 bin 的設定順序" data-link-desc="重灌或換機後底層基礎建設的依賴順序，免得後面工具裝不起來或路徑互相找不到。">macOS 新機基礎建設</a>。</p>
<p><code>brew services</code> 是 Homebrew 附帶的服務管理子命令、把指令封裝成 macOS 原生的 <a href="/blog/llm/knowledge-cards/launchd-service/" data-link-title="launchd Service" data-link-desc="macOS 原生的服務管理機制、把 process 註冊成自動啟動的 daemon 或 agent">launchd service</a>、處理「開機自動啟動 / 停止 / 重啟」需求。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>日常會碰到的 brew 指令：</p>
<table>
  <thead>
      <tr>
          <th>指令</th>
          <th>用途</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>brew install &lt;pkg&gt;</code></td>
          <td>安裝套件</td>
      </tr>
      <tr>
          <td><code>brew upgrade &lt;pkg&gt;</code></td>
          <td>升級單一套件</td>
      </tr>
      <tr>
          <td><code>brew services start</code></td>
          <td>把套件註冊成 launchd service、立刻啟動</td>
      </tr>
      <tr>
          <td><code>brew services list</code></td>
          <td>列出目前由 brew 管理的常駐服務</td>
      </tr>
      <tr>
          <td><code>which &lt;bin&gt;</code></td>
          <td>確認可執行檔在 PATH 上的實際路徑</td>
      </tr>
      <tr>
          <td><code>brew --prefix</code></td>
          <td>查 Homebrew 的安裝根目錄</td>
      </tr>
  </tbody>
</table>
<p>Apple Silicon Mac 上的關鍵路徑是 <code>/opt/homebrew/</code>、子資料夾各有角色：<code>bin/</code>（可執行檔）、<code>var/log/</code>（服務 log）、<code>Cellar/</code>（套件實際內容）、<code>opt/</code>（版本無關的 symlink）。看到「<code>/opt/homebrew/var/log/ollama.log</code>」時、就是 brew 管理的 Ollama 服務 log 位置。</p>
<h2 id="設計責任">設計責任</h2>
<p>用 brew 安裝 vs 用官方 .dmg / .pkg 的取捨：CLI 工具（ollama、llama.cpp、git 等）走 brew、好處是統一升級路徑；GUI 應用（LM Studio、Docker Desktop 等）多半改下載官方安裝包、因為 brew cask 不一定即時跟上版本。第一次裝 Homebrew 自己用官方 install script（在 <a href="https://brew.sh">brew.sh</a>）、之後其他工具都從 brew 走。</p>
]]></content:encoded></item><item><title>Hybrid Search</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/hybrid-search/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/hybrid-search/</guid><description>&lt;p>Hybrid search 的核心概念是「&lt;strong>同時跑字面 retrieval（BM25 / tf-idf）跟語意 retrieval（embedding similarity）、用 Reciprocal Rank Fusion 等方法合併結果&lt;/strong>」。補單一路線的盲點：BM25 抓不到語意相似（同義詞 / 不同表述）、embedding 抓不到精確 keyword（術語 / 識別碼 / 罕見 entity）。是 production RAG 的標配。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>兩條 retrieval 路線的盲點：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>場景&lt;/th>
 &lt;th>BM25（字面）&lt;/th>
 &lt;th>Embedding（語意）&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Query / doc 共用 keyword&lt;/td>
 &lt;td>強&lt;/td>
 &lt;td>強&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Query 用同義詞、doc 用另一字&lt;/td>
 &lt;td>找不到&lt;/td>
 &lt;td>命中&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Query 用通俗、doc 用 jargon&lt;/td>
 &lt;td>找不到&lt;/td>
 &lt;td>命中&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>精確 keyword（如 product code、UUID、API 名）&lt;/td>
 &lt;td>命中&lt;/td>
 &lt;td>可能漂掉&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>罕見 entity（人名 / 地名）&lt;/td>
 &lt;td>命中&lt;/td>
 &lt;td>弱（embedding model 不熟）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Embedding model 不熟的 domain&lt;/td>
 &lt;td>命中&lt;/td>
 &lt;td>表現崩&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>主流合併方法：&lt;/p>
&lt;h3 id="reciprocal-rank-fusionrrf">Reciprocal Rank Fusion（RRF）&lt;/h3>
&lt;p>最常用、簡單：&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">對每個 doc：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> score = sum_over_retrievers(1 / (k + rank_i))
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">k 是常數（典型 60）、rank 是該 retriever 給 doc 的排名
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">example：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> doc X 在 BM25 排名 3、在 embedding 排名 1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> RRF score = 1/(60+3) + 1/(60+1) = 0.0159 + 0.0164 = 0.0323
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">按 RRF score 排序、取 top-K&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>優點：不需要 normalize 不同 retriever 的分數、簡單可靠
缺點：不能 fine-tune 兩條路線的權重&lt;/p>
&lt;h3 id="weighted-score-fusion">Weighted score fusion&lt;/h3>
&lt;p>對每條路線的 score 加權平均：&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">score = α × BM25_score_normalized + (1-α) × embedding_score_normalized&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>優點：可以調 α 偏 BM25 或 embedding
缺點：要 normalize 兩個 score scale、調 α 是 hyper-parameter&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 RAG production / retrieval framework 看到「hybrid search」「BM25 + dense」「RRF」就是這 framing。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>何時值得加 hybrid&lt;/strong>：embedding-only retrieval 漏精確 keyword / 識別碼、BM25-only 漏語意相似、混合補完&lt;/li>
&lt;li>&lt;strong>何時不需要&lt;/strong>：純語意任務（embedding 已準）、純 keyword 任務（BM25 已準）、極小語料&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/reranker/" data-link-title="Reranker" data-link-desc="對 retrieval top-K 結果用 cross-encoder 重新排序的 RAG 第二階段、品質提升顯著但 latency / cost 增加">reranker&lt;/a> 的組合&lt;/strong>：hybrid retrieve top-50（BM25 top-25 + embedding top-25、RRF 合併）→ reranker rerank → LLM top-5&lt;/li>
&lt;li>&lt;strong>主流實作&lt;/strong>：Elasticsearch / OpenSearch 內建、Weaviate / Qdrant / Pinecone 都支援、Postgres 用 pg_search + pgvector&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &amp;#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG 章節&lt;/a> 的關係&lt;/strong>：本卡是定義、章節是 retrieval pipeline 設計含 hybrid 段&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Hybrid search 的核心概念是「<strong>同時跑字面 retrieval（BM25 / tf-idf）跟語意 retrieval（embedding similarity）、用 Reciprocal Rank Fusion 等方法合併結果</strong>」。補單一路線的盲點：BM25 抓不到語意相似（同義詞 / 不同表述）、embedding 抓不到精確 keyword（術語 / 識別碼 / 罕見 entity）。是 production RAG 的標配。</p>
<h2 id="概念位置">概念位置</h2>
<p>兩條 retrieval 路線的盲點：</p>
<table>
  <thead>
      <tr>
          <th>場景</th>
          <th>BM25（字面）</th>
          <th>Embedding（語意）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Query / doc 共用 keyword</td>
          <td>強</td>
          <td>強</td>
      </tr>
      <tr>
          <td>Query 用同義詞、doc 用另一字</td>
          <td>找不到</td>
          <td>命中</td>
      </tr>
      <tr>
          <td>Query 用通俗、doc 用 jargon</td>
          <td>找不到</td>
          <td>命中</td>
      </tr>
      <tr>
          <td>精確 keyword（如 product code、UUID、API 名）</td>
          <td>命中</td>
          <td>可能漂掉</td>
      </tr>
      <tr>
          <td>罕見 entity（人名 / 地名）</td>
          <td>命中</td>
          <td>弱（embedding model 不熟）</td>
      </tr>
      <tr>
          <td>Embedding model 不熟的 domain</td>
          <td>命中</td>
          <td>表現崩</td>
      </tr>
  </tbody>
</table>
<p>主流合併方法：</p>
<h3 id="reciprocal-rank-fusionrrf">Reciprocal Rank Fusion（RRF）</h3>
<p>最常用、簡單：</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">對每個 doc：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  score = sum_over_retrievers(1 / (k + rank_i))
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">k 是常數（典型 60）、rank 是該 retriever 給 doc 的排名
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">example：
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  doc X 在 BM25 排名 3、在 embedding 排名 1
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  RRF score = 1/(60+3) + 1/(60+1) = 0.0159 + 0.0164 = 0.0323
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">按 RRF score 排序、取 top-K</span></span></code></pre></div><p>優點：不需要 normalize 不同 retriever 的分數、簡單可靠
缺點：不能 fine-tune 兩條路線的權重</p>
<h3 id="weighted-score-fusion">Weighted score fusion</h3>
<p>對每條路線的 score 加權平均：</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">score = α × BM25_score_normalized + (1-α) × embedding_score_normalized</span></span></code></pre></div><p>優點：可以調 α 偏 BM25 或 embedding
缺點：要 normalize 兩個 score scale、調 α 是 hyper-parameter</p>
<h2 id="設計責任">設計責任</h2>
<p>讀 RAG production / retrieval framework 看到「hybrid search」「BM25 + dense」「RRF」就是這 framing。寫 code 場景的判讀：</p>
<ol>
<li><strong>何時值得加 hybrid</strong>：embedding-only retrieval 漏精確 keyword / 識別碼、BM25-only 漏語意相似、混合補完</li>
<li><strong>何時不需要</strong>：純語意任務（embedding 已準）、純 keyword 任務（BM25 已準）、極小語料</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/reranker/" data-link-title="Reranker" data-link-desc="對 retrieval top-K 結果用 cross-encoder 重新排序的 RAG 第二階段、品質提升顯著但 latency / cost 增加">reranker</a> 的組合</strong>：hybrid retrieve top-50（BM25 top-25 + embedding top-25、RRF 合併）→ reranker rerank → LLM top-5</li>
<li><strong>主流實作</strong>：Elasticsearch / OpenSearch 內建、Weaviate / Qdrant / Pinecone 都支援、Postgres 用 pg_search + pgvector</li>
<li><strong>跟 <a href="/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG 章節</a> 的關係</strong>：本卡是定義、章節是 retrieval pipeline 設計含 hybrid 段</li>
</ol>
]]></content:encoded></item><item><title>Image Token</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/image-token/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/image-token/</guid><description>&lt;p>Image token（圖片 token）的核心概念是「&lt;strong>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/vlm/" data-link-title="VLM（Vision-Language Model）" data-link-desc="同時吃圖片 &amp;#43; 文字輸入、產生文字輸出的 LLM 變體、coding 工作流中處理截圖 / 設計稿 / UI debug 的基底">VLM&lt;/a> 把圖片過 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/vision-encoder/" data-link-title="Vision Encoder" data-link-desc="VLM 內部負責把圖片轉成可進 Transformer 的向量序列的模組、ViT / CLIP encoder 為主流">vision encoder&lt;/a> 後、產出的向量序列、在 Transformer 內跟 text &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a> 同質處理&lt;/strong>」。理解這個概念能解釋為什麼「一張圖 = 幾百到幾千 token」、為什麼塞圖會吃掉 context budget、為什麼 VLM 推論比純文字 LLM 慢。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>從圖到 image token 的轉換：&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">Input image: 1024×1024 RGB
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓ Patchify（切 14×14 patch、得 ~5000 個 patch）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> ↓ Vision encoder（ViT 處理每個 patch、產 768/1024 維向量）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ↓ Optional: 2D position embedding
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> ↓ Optional: pooling / merging（減少 token 數）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">Image tokens: ~500-2500 個（依模型設計）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> ↓ Projection（vision_dim → LLM hidden_dim、配合 LLM 內部維度）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl"> ↓ 跟 text token 串成單一 sequence
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">9&lt;/span>&lt;span class="cl"> ↓ Transformer 跟一般 token 一樣處理&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>主流 VLM 的單張圖 token 用量（粗略、依模型 / 解析度而變）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>模型&lt;/th>
 &lt;th>預設輸入解析度&lt;/th>
 &lt;th>單張圖約用 token&lt;/th>
 &lt;th>Context 影響&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>GPT-4o vision&lt;/td>
 &lt;td>動態（最高 2048×768）&lt;/td>
 &lt;td>~85 - 1000+&lt;/td>
 &lt;td>高解析度模式消耗大&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Claude 3 vision&lt;/td>
 &lt;td>動態&lt;/td>
 &lt;td>~1000-1600&lt;/td>
 &lt;td>一張圖 ≈ 1.5K text token&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Qwen2.5-VL&lt;/td>
 &lt;td>動態、可調 min/max&lt;/td>
 &lt;td>~500 - 4000&lt;/td>
 &lt;td>設定 &lt;code>min_pixels&lt;/code> 控制下限&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Llama 3.2 Vision&lt;/td>
 &lt;td>固定（560×560）&lt;/td>
 &lt;td>~1600&lt;/td>
 &lt;td>多張圖直接乘&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Gemma 3 Vision&lt;/td>
 &lt;td>動態&lt;/td>
 &lt;td>~256 - 2000&lt;/td>
 &lt;td>多語 / 多解析度&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：上述 token 數量級依模型版本、推論配置（如「low / high detail」模式）變化、引用前以對應 model card 跟 API 文件為準。&lt;/p>&lt;/blockquote>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 VLM API / 推論 log 看到「image tokens used: 1247」「visual tokens: 580」就是這指標。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>多張截圖 = context 吃緊&lt;/strong>：一張 1500 token、丟 10 張就 15K、加上 prompt 跟回答、long context 模型才能 handle&lt;/li>
&lt;li>&lt;strong>同張圖、解析度模式影響成本&lt;/strong>：許多 API 提供 low / auto / high detail 模式、low detail 約 1/10 token；OCR 需要高解析、不細節辨識可選 low&lt;/li>
&lt;li>&lt;strong>本地 VLM 推論 prefill 慢&lt;/strong>：image token 多、prefill 階段（&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT&lt;/a>）對應變長、第一個字出來要等較久&lt;/li>
&lt;li>&lt;strong>API 計費通常 image token 跟 text token 同價&lt;/strong>：算成本看實際用了多少 image token、不要假設「一張圖 = 一個 token」&lt;/li>
&lt;li>&lt;strong>Image token 是消耗品、不是參數&lt;/strong>：跟模型內部權重不同、純粹是「這次 forward pass 的 input」&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Image token（圖片 token）的核心概念是「<strong><a href="/blog/llm/knowledge-cards/vlm/" data-link-title="VLM（Vision-Language Model）" data-link-desc="同時吃圖片 &#43; 文字輸入、產生文字輸出的 LLM 變體、coding 工作流中處理截圖 / 設計稿 / UI debug 的基底">VLM</a> 把圖片過 <a href="/blog/llm/knowledge-cards/vision-encoder/" data-link-title="Vision Encoder" data-link-desc="VLM 內部負責把圖片轉成可進 Transformer 的向量序列的模組、ViT / CLIP encoder 為主流">vision encoder</a> 後、產出的向量序列、在 Transformer 內跟 text <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a> 同質處理</strong>」。理解這個概念能解釋為什麼「一張圖 = 幾百到幾千 token」、為什麼塞圖會吃掉 context budget、為什麼 VLM 推論比純文字 LLM 慢。</p>
<h2 id="概念位置">概念位置</h2>
<p>從圖到 image token 的轉換：</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">Input image: 1024×1024 RGB
</span></span><span class="line"><span class="ln">2</span><span class="cl">   ↓ Patchify（切 14×14 patch、得 ~5000 個 patch）
</span></span><span class="line"><span class="ln">3</span><span class="cl">   ↓ Vision encoder（ViT 處理每個 patch、產 768/1024 維向量）
</span></span><span class="line"><span class="ln">4</span><span class="cl">   ↓ Optional: 2D position embedding
</span></span><span class="line"><span class="ln">5</span><span class="cl">   ↓ Optional: pooling / merging（減少 token 數）
</span></span><span class="line"><span class="ln">6</span><span class="cl">Image tokens: ~500-2500 個（依模型設計）
</span></span><span class="line"><span class="ln">7</span><span class="cl">   ↓ Projection（vision_dim → LLM hidden_dim、配合 LLM 內部維度）
</span></span><span class="line"><span class="ln">8</span><span class="cl">   ↓ 跟 text token 串成單一 sequence
</span></span><span class="line"><span class="ln">9</span><span class="cl">   ↓ Transformer 跟一般 token 一樣處理</span></span></code></pre></div><p>主流 VLM 的單張圖 token 用量（粗略、依模型 / 解析度而變）：</p>
<table>
  <thead>
      <tr>
          <th>模型</th>
          <th>預設輸入解析度</th>
          <th>單張圖約用 token</th>
          <th>Context 影響</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>GPT-4o vision</td>
          <td>動態（最高 2048×768）</td>
          <td>~85 - 1000+</td>
          <td>高解析度模式消耗大</td>
      </tr>
      <tr>
          <td>Claude 3 vision</td>
          <td>動態</td>
          <td>~1000-1600</td>
          <td>一張圖 ≈ 1.5K text token</td>
      </tr>
      <tr>
          <td>Qwen2.5-VL</td>
          <td>動態、可調 min/max</td>
          <td>~500 - 4000</td>
          <td>設定 <code>min_pixels</code> 控制下限</td>
      </tr>
      <tr>
          <td>Llama 3.2 Vision</td>
          <td>固定（560×560）</td>
          <td>~1600</td>
          <td>多張圖直接乘</td>
      </tr>
      <tr>
          <td>Gemma 3 Vision</td>
          <td>動態</td>
          <td>~256 - 2000</td>
          <td>多語 / 多解析度</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p><strong>事實查核註</strong>：上述 token 數量級依模型版本、推論配置（如「low / high detail」模式）變化、引用前以對應 model card 跟 API 文件為準。</p></blockquote>
<h2 id="設計責任">設計責任</h2>
<p>讀 VLM API / 推論 log 看到「image tokens used: 1247」「visual tokens: 580」就是這指標。寫 code 場景的判讀：</p>
<ol>
<li><strong>多張截圖 = context 吃緊</strong>：一張 1500 token、丟 10 張就 15K、加上 prompt 跟回答、long context 模型才能 handle</li>
<li><strong>同張圖、解析度模式影響成本</strong>：許多 API 提供 low / auto / high detail 模式、low detail 約 1/10 token；OCR 需要高解析、不細節辨識可選 low</li>
<li><strong>本地 VLM 推論 prefill 慢</strong>：image token 多、prefill 階段（<a href="/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT</a>）對應變長、第一個字出來要等較久</li>
<li><strong>API 計費通常 image token 跟 text token 同價</strong>：算成本看實際用了多少 image token、不要假設「一張圖 = 一個 token」</li>
<li><strong>Image token 是消耗品、不是參數</strong>：跟模型內部權重不同、純粹是「這次 forward pass 的 input」</li>
</ol>
]]></content:encoded></item><item><title>KL Divergence</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/kl-divergence/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/kl-divergence/</guid><description>&lt;p>KL divergence（Kullback-Leibler divergence、KL 散度）的核心概念是「衡量兩個機率分佈 P 跟 Q 的差距」：&lt;code>KL(P ‖ Q) = sum(P(x) × log(P(x) / Q(x)))&lt;/code>。它&lt;strong>不對稱&lt;/strong>（&lt;code>KL(P ‖ Q) ≠ KL(Q ‖ P)&lt;/code>）、所以不算「距離」、是「散度」。在 LLM 訓練中是 alignment 階段防止模型「為了 reward 偏離太遠」的關鍵約束。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>KL divergence 在 LLM 中的兩個主要角色：&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/cross-entropy/" data-link-title="Cross-Entropy" data-link-desc="衡量「預測機率分佈」跟「真實分佈」距離的指標、LLM 預訓練的主要 loss">cross-entropy&lt;/a> 的關係&lt;/strong>：&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">cross-entropy(P, Q) = entropy(P) + KL(P ‖ Q)&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>訓練時 P（真實分佈）固定、entropy(P) 是常數、所以「minimize cross-entropy」等於「minimize KL」。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>RLHF / DPO 的「KL 約束」&lt;/strong>：&lt;/p>
&lt;p>alignment 階段不能只 maximize reward、否則模型會「為了 reward 把語言能力毀掉」。所以加 KL 約束：&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">objective = E[reward] - β × KL(π_new ‖ π_ref)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> └─ 不讓新模型偏離 ref（通常是 SFT 後的 base）太遠 ─┘&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>β 控制「reward 追求」vs「不偏離原始模型」的平衡。&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>跟相關概念的對比：&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>Cross-entropy&lt;/td>
 &lt;td>否&lt;/td>
 &lt;td>訓練 loss、衡量預測機率分佈跟真實分佈&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>KL divergence&lt;/td>
 &lt;td>否&lt;/td>
 &lt;td>Alignment 訓練的偏離約束&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>JS divergence&lt;/td>
 &lt;td>是&lt;/td>
 &lt;td>兩個分佈的對稱差距、研究比較多&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 alignment paper 看到 β、KL penalty、KL coefficient 等詞、知道這些是控制「模型在追 reward 時偏離 base 多遠的容忍度」。β 太小、模型容易 reward hacking（找 reward 高但實質爛的輸出）；β 太大、模型動不了、reward 升不上去。DPO 把 KL 約束內嵌進 loss、不像 RLHF 需要顯式 KL term、是 DPO 比 RLHF 簡單的原因之一。&lt;/p></description><content:encoded><![CDATA[<p>KL divergence（Kullback-Leibler divergence、KL 散度）的核心概念是「衡量兩個機率分佈 P 跟 Q 的差距」：<code>KL(P ‖ Q) = sum(P(x) × log(P(x) / Q(x)))</code>。它<strong>不對稱</strong>（<code>KL(P ‖ Q) ≠ KL(Q ‖ P)</code>）、所以不算「距離」、是「散度」。在 LLM 訓練中是 alignment 階段防止模型「為了 reward 偏離太遠」的關鍵約束。</p>
<h2 id="概念位置">概念位置</h2>
<p>KL divergence 在 LLM 中的兩個主要角色：</p>
<ol>
<li>
<p><strong>跟 <a href="/blog/llm/knowledge-cards/cross-entropy/" data-link-title="Cross-Entropy" data-link-desc="衡量「預測機率分佈」跟「真實分佈」距離的指標、LLM 預訓練的主要 loss">cross-entropy</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">cross-entropy(P, Q) = entropy(P) + KL(P ‖ Q)</span></span></code></pre></div><p>訓練時 P（真實分佈）固定、entropy(P) 是常數、所以「minimize cross-entropy」等於「minimize KL」。</p>
</li>
<li>
<p><strong>RLHF / DPO 的「KL 約束」</strong>：</p>
<p>alignment 階段不能只 maximize reward、否則模型會「為了 reward 把語言能力毀掉」。所以加 KL 約束：</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">objective = E[reward] - β × KL(π_new ‖ π_ref)
</span></span><span class="line"><span class="ln">2</span><span class="cl">                         └─ 不讓新模型偏離 ref（通常是 SFT 後的 base）太遠 ─┘</span></span></code></pre></div><p>β 控制「reward 追求」vs「不偏離原始模型」的平衡。</p>
</li>
</ol>
<p>跟相關概念的對比：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>對稱？</th>
          <th>主要用途</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Cross-entropy</td>
          <td>否</td>
          <td>訓練 loss、衡量預測機率分佈跟真實分佈</td>
      </tr>
      <tr>
          <td>KL divergence</td>
          <td>否</td>
          <td>Alignment 訓練的偏離約束</td>
      </tr>
      <tr>
          <td>JS divergence</td>
          <td>是</td>
          <td>兩個分佈的對稱差距、研究比較多</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 alignment paper 看到 β、KL penalty、KL coefficient 等詞、知道這些是控制「模型在追 reward 時偏離 base 多遠的容忍度」。β 太小、模型容易 reward hacking（找 reward 高但實質爛的輸出）；β 太大、模型動不了、reward 升不上去。DPO 把 KL 約束內嵌進 loss、不像 RLHF 需要顯式 KL term、是 DPO 比 RLHF 簡單的原因之一。</p>
]]></content:encoded></item><item><title>launchd Service</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/launchd-service/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/launchd-service/</guid><description>&lt;p>launchd Service 的核心概念是「macOS 用來管理常駐 process 生命週期的原生機制」。launchd 本身是 macOS 啟動後的第一個 process（PID 1）、由它負責拉起其他系統服務跟使用者註冊的背景任務。本地 LLM 場景中、Ollama 等推論伺服器透過 launchd 設定成「開機自動啟動、登入時自動拉起」、就不需要每次重開機都手動跑 &lt;code>ollama serve&lt;/code>。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>launchd service 用一份 plist（property list、XML 格式設定檔）描述「要跑哪個程式、何時啟動、出問題時要不要重啟、log 寫到哪裡」。plist 放在三個位置之一、決定服務的觸發範圍：&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>&lt;code>~/Library/LaunchAgents/&lt;/code>&lt;/td>
 &lt;td>使用者 agent&lt;/td>
 &lt;td>該使用者登入時&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>/Library/LaunchAgents/&lt;/code>&lt;/td>
 &lt;td>全機所有使用者 agent&lt;/td>
 &lt;td>任何使用者登入時&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>/Library/LaunchDaemons/&lt;/code>&lt;/td>
 &lt;td>系統 daemon、需 root&lt;/td>
 &lt;td>macOS 開機時、不需登入&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/homebrew/" data-link-title="Homebrew" data-link-desc="macOS 上社群維護的套件管理器、用一行指令安裝 CLI 工具與背景服務">Homebrew&lt;/a> 的 &lt;code>brew services&lt;/code> 子命令是 launchd 的 wrapper、產生 plist 並放進 &lt;code>~/Library/LaunchAgents/&lt;/code>、避免使用者直接手寫 XML。Apple Silicon Mac 上產生的檔名形式是 &lt;code>homebrew.mxcl.&amp;lt;service&amp;gt;.plist&lt;/code>。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>執行 &lt;code>brew services start ollama&lt;/code> 後可以驗證實際發生的事：&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">&lt;span class="c1"># 看 plist 內容&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">cat ~/Library/LaunchAgents/homebrew.mxcl.ollama.plist
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="c1"># 用 launchctl 看服務狀態&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">launchctl list &lt;span class="p">|&lt;/span> grep ollama
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">&lt;span class="c1"># 看服務 log（Apple Silicon）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl">tail -f /opt/homebrew/var/log/ollama.log&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>plist 內常見的鍵：&lt;code>ProgramArguments&lt;/code>（要跑哪個指令）、&lt;code>RunAtLoad&lt;/code>（開機就啟動）、&lt;code>KeepAlive&lt;/code>（crash 後自動拉回）、&lt;code>StandardOutPath&lt;/code> / &lt;code>StandardErrorPath&lt;/code>（log 路徑）。出問題時先看 log 路徑指向的檔案、能直接看到 service 的 stdout / stderr。&lt;/p>
&lt;p>服務管理常用指令：&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">brew services list &lt;span class="c1"># 列出所有由 brew 管理的服務&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">brew services start ollama &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">brew services stop ollama &lt;span class="c1"># 停掉服務、保留 plist&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">brew services restart ollama &lt;span class="c1"># 升級套件後重啟&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>直接用系統的 &lt;code>launchctl&lt;/code> 也行、但語意較底層、實務上有 brew 包裝就用 brew。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>選擇「launchd service」vs「前景手動跑 &lt;code>ollama serve&lt;/code>」的判讀：日常用機建議用 launchd service、好處是重開機自動拉起、出問題的 log 有固定位置可看；只在偶爾用本地 LLM 的場景、保持手動跑反而省記憶體（沒在用就停掉）。升級套件後記得 &lt;code>brew services restart&lt;/code>、否則跑的還是舊版二進位。&lt;/p></description><content:encoded><![CDATA[<p>launchd Service 的核心概念是「macOS 用來管理常駐 process 生命週期的原生機制」。launchd 本身是 macOS 啟動後的第一個 process（PID 1）、由它負責拉起其他系統服務跟使用者註冊的背景任務。本地 LLM 場景中、Ollama 等推論伺服器透過 launchd 設定成「開機自動啟動、登入時自動拉起」、就不需要每次重開機都手動跑 <code>ollama serve</code>。</p>
<h2 id="概念位置">概念位置</h2>
<p>launchd service 用一份 plist（property list、XML 格式設定檔）描述「要跑哪個程式、何時啟動、出問題時要不要重啟、log 寫到哪裡」。plist 放在三個位置之一、決定服務的觸發範圍：</p>
<table>
  <thead>
      <tr>
          <th>路徑</th>
          <th>角色</th>
          <th>何時觸發</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>~/Library/LaunchAgents/</code></td>
          <td>使用者 agent</td>
          <td>該使用者登入時</td>
      </tr>
      <tr>
          <td><code>/Library/LaunchAgents/</code></td>
          <td>全機所有使用者 agent</td>
          <td>任何使用者登入時</td>
      </tr>
      <tr>
          <td><code>/Library/LaunchDaemons/</code></td>
          <td>系統 daemon、需 root</td>
          <td>macOS 開機時、不需登入</td>
      </tr>
  </tbody>
</table>
<p><a href="/blog/llm/knowledge-cards/homebrew/" data-link-title="Homebrew" data-link-desc="macOS 上社群維護的套件管理器、用一行指令安裝 CLI 工具與背景服務">Homebrew</a> 的 <code>brew services</code> 子命令是 launchd 的 wrapper、產生 plist 並放進 <code>~/Library/LaunchAgents/</code>、避免使用者直接手寫 XML。Apple Silicon Mac 上產生的檔名形式是 <code>homebrew.mxcl.&lt;service&gt;.plist</code>。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>執行 <code>brew services start ollama</code> 後可以驗證實際發生的事：</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"><span class="c1"># 看 plist 內容</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">cat ~/Library/LaunchAgents/homebrew.mxcl.ollama.plist
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 用 launchctl 看服務狀態</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">launchctl list <span class="p">|</span> grep ollama
</span></span><span class="line"><span class="ln">6</span><span class="cl">
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="c1"># 看服務 log（Apple Silicon）</span>
</span></span><span class="line"><span class="ln">8</span><span class="cl">tail -f /opt/homebrew/var/log/ollama.log</span></span></code></pre></div><p>plist 內常見的鍵：<code>ProgramArguments</code>（要跑哪個指令）、<code>RunAtLoad</code>（開機就啟動）、<code>KeepAlive</code>（crash 後自動拉回）、<code>StandardOutPath</code> / <code>StandardErrorPath</code>（log 路徑）。出問題時先看 log 路徑指向的檔案、能直接看到 service 的 stdout / stderr。</p>
<p>服務管理常用指令：</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">brew services list             <span class="c1"># 列出所有由 brew 管理的服務</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">brew services start ollama     <span class="c1"># 啟動 + 註冊自動啟動</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">brew services stop ollama      <span class="c1"># 停掉服務、保留 plist</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">brew services restart ollama   <span class="c1"># 升級套件後重啟</span></span></span></code></pre></div><p>直接用系統的 <code>launchctl</code> 也行、但語意較底層、實務上有 brew 包裝就用 brew。</p>
<h2 id="設計責任">設計責任</h2>
<p>選擇「launchd service」vs「前景手動跑 <code>ollama serve</code>」的判讀：日常用機建議用 launchd service、好處是重開機自動拉起、出問題的 log 有固定位置可看；只在偶爾用本地 LLM 的場景、保持手動跑反而省記憶體（沒在用就停掉）。升級套件後記得 <code>brew services restart</code>、否則跑的還是舊版二進位。</p>
]]></content:encoded></item><item><title>Layer Normalization</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/layer-normalization/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/layer-normalization/</guid><description>&lt;p>Layer normalization（LayerNorm）的核心概念是「對單一 token 的 hidden state 向量做正規化」——把該向量的 mean 移到 0、std 縮到 1、再用兩個可學參數做仿射變換。它是 Transformer 穩定深層訓練的關鍵元件、跟 batch normalization 的差別是「正規化軸不同」、LayerNorm 對單個 sample 內部做、不依賴 batch 統計。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>LayerNorm 在 Transformer block 內的位置（現代主流是 pre-norm）：&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">Transformer block（pre-norm 配置）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> x
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> ↓ LayerNorm
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ↓ Self-Attention
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> ↓ + 跟 x 做 residual connection
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> ↓ LayerNorm
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> ↓ FFN
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl"> ↓ + 跟前一步輸出做 residual connection&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>主流變體比較：&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>LayerNorm&lt;/td>
 &lt;td>&lt;code>(x - mean) / std × γ + β&lt;/code>&lt;/td>
 &lt;td>早期 Transformer（GPT-2、BERT）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>RMSNorm&lt;/td>
 &lt;td>&lt;code>x / rms(x) × γ&lt;/code>（不減 mean、不加 β）&lt;/td>
 &lt;td>Llama、Gemma、Qwen 等主流&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>RMSNorm 比 LayerNorm 簡單、實測訓練穩定性接近、推論更快（少算 mean 跟加 β）、所以現代 LLM 多用 RMSNorm。讀 paper 看到「RMSNorm」就是 LayerNorm 的這個簡化變體。&lt;/p>
&lt;p>Pre-norm vs post-norm：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Pre-norm&lt;/strong>（LayerNorm 在 attention / FFN 之前）：深度模型訓練較穩、現代主流。&lt;/li>
&lt;li>&lt;strong>Post-norm&lt;/strong>（LayerNorm 在 residual add 之後）：原始 Transformer paper 的設計、深層訓練不穩定。&lt;/li>
&lt;/ul>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 LayerNorm 後可以判讀「深層 LLM 為什麼訓得起來」的部分答案：&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/residual-connection/" data-link-title="Residual Connection" data-link-desc="把 layer 的輸入直接加到輸出上的「跳接」、讓深層網路的梯度能穩定回流">residual connection&lt;/a> + LayerNorm 是讓梯度能穩定流過幾十層 Transformer 的兩根支柱。讀 model card 看到「RMSNorm」「pre-norm」等詞、知道對應的設計選擇跟訓練穩定性意涵。&lt;/p></description><content:encoded><![CDATA[<p>Layer normalization（LayerNorm）的核心概念是「對單一 token 的 hidden state 向量做正規化」——把該向量的 mean 移到 0、std 縮到 1、再用兩個可學參數做仿射變換。它是 Transformer 穩定深層訓練的關鍵元件、跟 batch normalization 的差別是「正規化軸不同」、LayerNorm 對單個 sample 內部做、不依賴 batch 統計。</p>
<h2 id="概念位置">概念位置</h2>
<p>LayerNorm 在 Transformer block 內的位置（現代主流是 pre-norm）：</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">Transformer block（pre-norm 配置）：
</span></span><span class="line"><span class="ln">2</span><span class="cl">  x
</span></span><span class="line"><span class="ln">3</span><span class="cl">  ↓ LayerNorm
</span></span><span class="line"><span class="ln">4</span><span class="cl">  ↓ Self-Attention
</span></span><span class="line"><span class="ln">5</span><span class="cl">  ↓ + 跟 x 做 residual connection
</span></span><span class="line"><span class="ln">6</span><span class="cl">  ↓ LayerNorm
</span></span><span class="line"><span class="ln">7</span><span class="cl">  ↓ FFN
</span></span><span class="line"><span class="ln">8</span><span class="cl">  ↓ + 跟前一步輸出做 residual connection</span></span></code></pre></div><p>主流變體比較：</p>
<table>
  <thead>
      <tr>
          <th>變體</th>
          <th>計算</th>
          <th>出現在</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>LayerNorm</td>
          <td><code>(x - mean) / std × γ + β</code></td>
          <td>早期 Transformer（GPT-2、BERT）</td>
      </tr>
      <tr>
          <td>RMSNorm</td>
          <td><code>x / rms(x) × γ</code>（不減 mean、不加 β）</td>
          <td>Llama、Gemma、Qwen 等主流</td>
      </tr>
  </tbody>
</table>
<p>RMSNorm 比 LayerNorm 簡單、實測訓練穩定性接近、推論更快（少算 mean 跟加 β）、所以現代 LLM 多用 RMSNorm。讀 paper 看到「RMSNorm」就是 LayerNorm 的這個簡化變體。</p>
<p>Pre-norm vs post-norm：</p>
<ul>
<li><strong>Pre-norm</strong>（LayerNorm 在 attention / FFN 之前）：深度模型訓練較穩、現代主流。</li>
<li><strong>Post-norm</strong>（LayerNorm 在 residual add 之後）：原始 Transformer paper 的設計、深層訓練不穩定。</li>
</ul>
<h2 id="設計責任">設計責任</h2>
<p>理解 LayerNorm 後可以判讀「深層 LLM 為什麼訓得起來」的部分答案：<a href="/blog/llm/knowledge-cards/residual-connection/" data-link-title="Residual Connection" data-link-desc="把 layer 的輸入直接加到輸出上的「跳接」、讓深層網路的梯度能穩定回流">residual connection</a> + LayerNorm 是讓梯度能穩定流過幾十層 Transformer 的兩根支柱。讀 model card 看到「RMSNorm」「pre-norm」等詞、知道對應的設計選擇跟訓練穩定性意涵。</p>
]]></content:encoded></item><item><title>Learning Rate</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/learning-rate/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/learning-rate/</guid><description>&lt;p>Learning rate（學習率、lr、α、η）的核心概念是「&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/gradient/" data-link-title="Gradient" data-link-desc="loss function 對權重的偏微分向量、指出「該往哪個方向調權重才能讓 loss 下降最快」">gradient&lt;/a> 每步更新權重時、被乘上的純量縮放因子」。更新公式 &lt;code>W_new = W_old - lr × gradient&lt;/code> 裡的 lr 就是它。是訓練最敏感的單一 hyperparameter — 太大會 diverge（loss 飛走）、太小會訓得超慢或卡 local minimum。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>LLM 訓練 learning rate 的常見模式：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>階段&lt;/th>
 &lt;th>典型 lr&lt;/th>
 &lt;th>理由&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/pre-training/" data-link-title="Pre-training" data-link-desc="LLM 訓練的第一階段：用 trillion-token 級網路文字做 next-token prediction、得到 base model">Pre-training&lt;/a>&lt;/td>
 &lt;td>1e-4 ~ 3e-4&lt;/td>
 &lt;td>訓 trillion token、需要溫和的 lr 避免 diverge&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/sft/" data-link-title="SFT（Supervised Fine-Tuning）" data-link-desc="在 base model 上用「指令-回答」對資料微調、讓模型會跟著指令走">SFT&lt;/a>&lt;/td>
 &lt;td>1e-5 ~ 5e-5&lt;/td>
 &lt;td>base model 已收斂、用小 lr 微調避免 overshoot&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rlhf/" data-link-title="RLHF" data-link-desc="Reinforcement Learning from Human Feedback：用人類偏好訓練的 reward model 透過 RL 對齊 LLM">RLHF&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/dpo/" data-link-title="DPO（Direct Preference Optimization）" data-link-desc="RLHF 的簡化替代：跳過 reward model、直接從人類偏好資料 fine-tune LLM">DPO&lt;/a>&lt;/td>
 &lt;td>1e-7 ~ 1e-6&lt;/td>
 &lt;td>又比 SFT 更小、避免破壞 SFT 學到的對話能力&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/lora/" data-link-title="LoRA" data-link-desc="Low-Rank Adaptation：凍住原模型權重、只訓兩個小矩陣的 parameter-efficient fine-tuning">LoRA&lt;/a> fine-tune&lt;/td>
 &lt;td>1e-4 ~ 5e-4&lt;/td>
 &lt;td>只訓小 adapter、可用較大 lr&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Learning rate schedule（lr 隨訓練步數調整）的主流模式：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Warmup&lt;/strong>：訓練最初幾百 ~ 幾千 step、lr 從 0 線性升到目標值。避免初期 gradient 大、模型瞬間 diverge。&lt;/li>
&lt;li>&lt;strong>Cosine decay&lt;/strong>：warmup 後、lr 用 cosine 函數從目標值降到接近 0。訓練後期細調。&lt;/li>
&lt;li>&lt;strong>WSD（Warmup-Stable-Decay）&lt;/strong>：近期變體、中間維持高 lr 更久。&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 training config 看到 &lt;code>learning_rate&lt;/code>、&lt;code>lr_scheduler_type: cosine&lt;/code>、&lt;code>warmup_steps: 1000&lt;/code> 等就是這組設定。Fine-tune 時 lr 設太大、模型會「忘記」pre-training 學到的能力（catastrophic forgetting）；太小則訓不進新資料、loss 不降。實務除錯：fine-tune 時 loss 第一個 epoch 就 NaN、十之八九是 lr 太大；loss 完全不降、十之八九是 lr 太小或 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/gradient/" data-link-title="Gradient" data-link-desc="loss function 對權重的偏微分向量、指出「該往哪個方向調權重才能讓 loss 下降最快」">gradient&lt;/a> 沒流到要訓的權重。&lt;/p></description><content:encoded><![CDATA[<p>Learning rate（學習率、lr、α、η）的核心概念是「<a href="/blog/llm/knowledge-cards/gradient/" data-link-title="Gradient" data-link-desc="loss function 對權重的偏微分向量、指出「該往哪個方向調權重才能讓 loss 下降最快」">gradient</a> 每步更新權重時、被乘上的純量縮放因子」。更新公式 <code>W_new = W_old - lr × gradient</code> 裡的 lr 就是它。是訓練最敏感的單一 hyperparameter — 太大會 diverge（loss 飛走）、太小會訓得超慢或卡 local minimum。</p>
<h2 id="概念位置">概念位置</h2>
<p>LLM 訓練 learning rate 的常見模式：</p>
<table>
  <thead>
      <tr>
          <th>階段</th>
          <th>典型 lr</th>
          <th>理由</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/pre-training/" data-link-title="Pre-training" data-link-desc="LLM 訓練的第一階段：用 trillion-token 級網路文字做 next-token prediction、得到 base model">Pre-training</a></td>
          <td>1e-4 ~ 3e-4</td>
          <td>訓 trillion token、需要溫和的 lr 避免 diverge</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/sft/" data-link-title="SFT（Supervised Fine-Tuning）" data-link-desc="在 base model 上用「指令-回答」對資料微調、讓模型會跟著指令走">SFT</a></td>
          <td>1e-5 ~ 5e-5</td>
          <td>base model 已收斂、用小 lr 微調避免 overshoot</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/rlhf/" data-link-title="RLHF" data-link-desc="Reinforcement Learning from Human Feedback：用人類偏好訓練的 reward model 透過 RL 對齊 LLM">RLHF</a> / <a href="/blog/llm/knowledge-cards/dpo/" data-link-title="DPO（Direct Preference Optimization）" data-link-desc="RLHF 的簡化替代：跳過 reward model、直接從人類偏好資料 fine-tune LLM">DPO</a></td>
          <td>1e-7 ~ 1e-6</td>
          <td>又比 SFT 更小、避免破壞 SFT 學到的對話能力</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/lora/" data-link-title="LoRA" data-link-desc="Low-Rank Adaptation：凍住原模型權重、只訓兩個小矩陣的 parameter-efficient fine-tuning">LoRA</a> fine-tune</td>
          <td>1e-4 ~ 5e-4</td>
          <td>只訓小 adapter、可用較大 lr</td>
      </tr>
  </tbody>
</table>
<p>Learning rate schedule（lr 隨訓練步數調整）的主流模式：</p>
<ol>
<li><strong>Warmup</strong>：訓練最初幾百 ~ 幾千 step、lr 從 0 線性升到目標值。避免初期 gradient 大、模型瞬間 diverge。</li>
<li><strong>Cosine decay</strong>：warmup 後、lr 用 cosine 函數從目標值降到接近 0。訓練後期細調。</li>
<li><strong>WSD（Warmup-Stable-Decay）</strong>：近期變體、中間維持高 lr 更久。</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 training config 看到 <code>learning_rate</code>、<code>lr_scheduler_type: cosine</code>、<code>warmup_steps: 1000</code> 等就是這組設定。Fine-tune 時 lr 設太大、模型會「忘記」pre-training 學到的能力（catastrophic forgetting）；太小則訓不進新資料、loss 不降。實務除錯：fine-tune 時 loss 第一個 epoch 就 NaN、十之八九是 lr 太大；loss 完全不降、十之八九是 lr 太小或 <a href="/blog/llm/knowledge-cards/gradient/" data-link-title="Gradient" data-link-desc="loss function 對權重的偏微分向量、指出「該往哪個方向調權重才能讓 loss 下降最快」">gradient</a> 沒流到要訓的權重。</p>
]]></content:encoded></item><item><title>LLM Benchmarks（MMLU / HumanEval / SWE-bench 等）</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/llm-benchmarks/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/llm-benchmarks/</guid><description>&lt;p>LLM benchmarks 的核心概念是「&lt;strong>用標準化任務集合衡量 LLM 各維度能力的評估工具&lt;/strong>」。不同 benchmark 衡量不同維度（知識、reasoning、code、對話、math 等）、選錯 benchmark 看模型會誤判。本卡列主流 benchmark 跟它們的覆蓋面、失效情境。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>主流 LLM benchmark 一覽：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Benchmark&lt;/th>
 &lt;th>衡量維度&lt;/th>
 &lt;th>任務形式&lt;/th>
 &lt;th>失效情境&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>MMLU&lt;/strong>&lt;/td>
 &lt;td>通用知識（57 學科多選題）&lt;/td>
 &lt;td>4 選 1 選擇題&lt;/td>
 &lt;td>訓練資料污染（題目可能在 pretrain corpus）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>GSM8K&lt;/strong>&lt;/td>
 &lt;td>小學數學 word problem&lt;/td>
 &lt;td>文字 + 數字、需 reasoning&lt;/td>
 &lt;td>飽和（前沿模型 95%+）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>MATH&lt;/strong>&lt;/td>
 &lt;td>高中 / 競賽數學&lt;/td>
 &lt;td>自由作答&lt;/td>
 &lt;td>訓練污染、reasoning model 表現遠超 instruct&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>HumanEval&lt;/strong>&lt;/td>
 &lt;td>Python function 補完&lt;/td>
 &lt;td>寫一個 function 通過 unit test&lt;/td>
 &lt;td>飽和、僅覆蓋初級 coding&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>MBPP&lt;/strong>&lt;/td>
 &lt;td>Python coding 任務&lt;/td>
 &lt;td>同上、規模較大&lt;/td>
 &lt;td>同 HumanEval&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/swe-bench/" data-link-title="SWE-bench" data-link-desc="用真實 GitHub issue 量化 LLM coding 能力的 benchmark">&lt;strong>SWE-bench&lt;/strong>&lt;/a>&lt;/td>
 &lt;td>真實 GitHub issue 修復&lt;/td>
 &lt;td>給 repo + issue、生 patch、跑 test&lt;/td>
 &lt;td>仍是 LLM 主要 coding 差距、不易飽和&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>MT-Bench&lt;/strong>&lt;/td>
 &lt;td>多輪對話品質&lt;/td>
 &lt;td>80 題 prompt、LLM-as-judge 評分&lt;/td>
 &lt;td>LLM-as-judge bias、judge 模型本身能力影響評分&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Chatbot Arena&lt;/strong>&lt;/td>
 &lt;td>開放對話偏好（眾人投票）&lt;/td>
 &lt;td>A/B 對戰、Elo 排名&lt;/td>
 &lt;td>文化偏好、prompt 設計影響&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>HELM&lt;/strong>&lt;/td>
 &lt;td>多 dimension comprehensive&lt;/td>
 &lt;td>22 scenarios × 多 metrics&lt;/td>
 &lt;td>計算昂貴、不易追蹤每代新模型&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>AlpacaEval&lt;/strong>&lt;/td>
 &lt;td>指令跟隨能力&lt;/td>
 &lt;td>LLM-as-judge 對比 GPT-4&lt;/td>
 &lt;td>Judge bias、易被「verbose」攻擊&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>RULER&lt;/strong>&lt;/td>
 &lt;td>Long context 真實任務&lt;/td>
 &lt;td>Multi-needle、aggregation、reasoning&lt;/td>
 &lt;td>較新、覆蓋仍在演化&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：各 benchmark 的飽和狀態、前沿模型 score 持續變動、上述為 2026/5 主流觀察。引用前以 &lt;a href="https://paperswithcode.com/">Papers with Code&lt;/a> 或 &lt;a href="https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard">HuggingFace Open LLM Leaderboard&lt;/a> 當前狀態為準。&lt;/p>&lt;/blockquote>
&lt;h2 id="benchmark-的常見陷阱">Benchmark 的常見陷阱&lt;/h2>
&lt;ol>
&lt;li>&lt;strong>訓練資料污染（Contamination）&lt;/strong>：benchmark 題目本身在 pretrain corpus 出現過、模型「記得」答案、看似強實際是 memorization&lt;/li>
&lt;li>&lt;strong>飽和（Saturation）&lt;/strong>：前沿模型 score 接近上限、無法區分模型品質差距（HumanEval 80%→95% 看似進步、實際 5% 多半是 lucky 而非實質提升）&lt;/li>
&lt;li>&lt;strong>LLM-as-judge bias&lt;/strong>：用 LLM（如 GPT-4）評其他 LLM、judge 的偏好（如「冗長 = 好」）會 bias 評分&lt;/li>
&lt;li>&lt;strong>Single-task overfitting&lt;/strong>：模型廠商針對 benchmark 特別 fine-tune、benchmark 高分但通用能力沒提升&lt;/li>
&lt;li>&lt;strong>Prompt sensitivity&lt;/strong>：同個 benchmark 用不同 prompt format、score 差幾個百分點&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 model card / paper 看到 benchmark 數字、判讀框架：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>看 multiple benchmarks、不只一個&lt;/strong>：如挑 coding 模型、看 HumanEval + MBPP + SWE-bench、不只看 HumanEval&lt;/li>
&lt;li>&lt;strong>跟自己任務對齊的 benchmark 才重要&lt;/strong>：你做 RAG 應用、看 retrieval benchmark；你做 chat、看 MT-Bench / Arena&lt;/li>
&lt;li>&lt;strong>看「相對」、不只看「絕對」&lt;/strong>：「Model A 在 MMLU 比 Model B 高 2%」可能 noise；「A 比 B 高 10%」更可信&lt;/li>
&lt;li>&lt;strong>In-house benchmark 是最後檢驗&lt;/strong>：自己的真實工作流案例 &amp;gt; 任何公開 benchmark&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>LLM benchmarks 的核心概念是「<strong>用標準化任務集合衡量 LLM 各維度能力的評估工具</strong>」。不同 benchmark 衡量不同維度（知識、reasoning、code、對話、math 等）、選錯 benchmark 看模型會誤判。本卡列主流 benchmark 跟它們的覆蓋面、失效情境。</p>
<h2 id="概念位置">概念位置</h2>
<p>主流 LLM benchmark 一覽：</p>
<table>
  <thead>
      <tr>
          <th>Benchmark</th>
          <th>衡量維度</th>
          <th>任務形式</th>
          <th>失效情境</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>MMLU</strong></td>
          <td>通用知識（57 學科多選題）</td>
          <td>4 選 1 選擇題</td>
          <td>訓練資料污染（題目可能在 pretrain corpus）</td>
      </tr>
      <tr>
          <td><strong>GSM8K</strong></td>
          <td>小學數學 word problem</td>
          <td>文字 + 數字、需 reasoning</td>
          <td>飽和（前沿模型 95%+）</td>
      </tr>
      <tr>
          <td><strong>MATH</strong></td>
          <td>高中 / 競賽數學</td>
          <td>自由作答</td>
          <td>訓練污染、reasoning model 表現遠超 instruct</td>
      </tr>
      <tr>
          <td><strong>HumanEval</strong></td>
          <td>Python function 補完</td>
          <td>寫一個 function 通過 unit test</td>
          <td>飽和、僅覆蓋初級 coding</td>
      </tr>
      <tr>
          <td><strong>MBPP</strong></td>
          <td>Python coding 任務</td>
          <td>同上、規模較大</td>
          <td>同 HumanEval</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/swe-bench/" data-link-title="SWE-bench" data-link-desc="用真實 GitHub issue 量化 LLM coding 能力的 benchmark"><strong>SWE-bench</strong></a></td>
          <td>真實 GitHub issue 修復</td>
          <td>給 repo + issue、生 patch、跑 test</td>
          <td>仍是 LLM 主要 coding 差距、不易飽和</td>
      </tr>
      <tr>
          <td><strong>MT-Bench</strong></td>
          <td>多輪對話品質</td>
          <td>80 題 prompt、LLM-as-judge 評分</td>
          <td>LLM-as-judge bias、judge 模型本身能力影響評分</td>
      </tr>
      <tr>
          <td><strong>Chatbot Arena</strong></td>
          <td>開放對話偏好（眾人投票）</td>
          <td>A/B 對戰、Elo 排名</td>
          <td>文化偏好、prompt 設計影響</td>
      </tr>
      <tr>
          <td><strong>HELM</strong></td>
          <td>多 dimension comprehensive</td>
          <td>22 scenarios × 多 metrics</td>
          <td>計算昂貴、不易追蹤每代新模型</td>
      </tr>
      <tr>
          <td><strong>AlpacaEval</strong></td>
          <td>指令跟隨能力</td>
          <td>LLM-as-judge 對比 GPT-4</td>
          <td>Judge bias、易被「verbose」攻擊</td>
      </tr>
      <tr>
          <td><strong>RULER</strong></td>
          <td>Long context 真實任務</td>
          <td>Multi-needle、aggregation、reasoning</td>
          <td>較新、覆蓋仍在演化</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p><strong>事實查核註</strong>：各 benchmark 的飽和狀態、前沿模型 score 持續變動、上述為 2026/5 主流觀察。引用前以 <a href="https://paperswithcode.com/">Papers with Code</a> 或 <a href="https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard">HuggingFace Open LLM Leaderboard</a> 當前狀態為準。</p></blockquote>
<h2 id="benchmark-的常見陷阱">Benchmark 的常見陷阱</h2>
<ol>
<li><strong>訓練資料污染（Contamination）</strong>：benchmark 題目本身在 pretrain corpus 出現過、模型「記得」答案、看似強實際是 memorization</li>
<li><strong>飽和（Saturation）</strong>：前沿模型 score 接近上限、無法區分模型品質差距（HumanEval 80%→95% 看似進步、實際 5% 多半是 lucky 而非實質提升）</li>
<li><strong>LLM-as-judge bias</strong>：用 LLM（如 GPT-4）評其他 LLM、judge 的偏好（如「冗長 = 好」）會 bias 評分</li>
<li><strong>Single-task overfitting</strong>：模型廠商針對 benchmark 特別 fine-tune、benchmark 高分但通用能力沒提升</li>
<li><strong>Prompt sensitivity</strong>：同個 benchmark 用不同 prompt format、score 差幾個百分點</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 model card / paper 看到 benchmark 數字、判讀框架：</p>
<ol>
<li><strong>看 multiple benchmarks、不只一個</strong>：如挑 coding 模型、看 HumanEval + MBPP + SWE-bench、不只看 HumanEval</li>
<li><strong>跟自己任務對齊的 benchmark 才重要</strong>：你做 RAG 應用、看 retrieval benchmark；你做 chat、看 MT-Bench / Arena</li>
<li><strong>看「相對」、不只看「絕對」</strong>：「Model A 在 MMLU 比 Model B 高 2%」可能 noise；「A 比 B 高 10%」更可信</li>
<li><strong>In-house benchmark 是最後檢驗</strong>：自己的真實工作流案例 &gt; 任何公開 benchmark</li>
</ol>
]]></content:encoded></item><item><title>LLM Tracing</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/llm-tracing/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/llm-tracing/</guid><description>&lt;p>LLM tracing 的核心概念是「&lt;strong>把 LLM 應用的每次 LLM call / tool call / memory op / handoff 編成結構化 span、串成 trace、可在 observability 平台查詢&lt;/strong>」。對應的標準是 OpenTelemetry GenAI semantic conventions（2025 stabilizing 中）。代表平台：LangSmith、Phoenix、Braintrust、Langfuse、Datadog APM、Logfire。是 production LLM 應用 debug / cost / latency 監控的事實標準、補 traditional logging 抓不到的「為什麼 agent 跑這條路」。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>跟 traditional logging 的對比：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>Traditional logging&lt;/th>
 &lt;th>LLM tracing&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>結構&lt;/td>
 &lt;td>字串 line、靠 grep&lt;/td>
 &lt;td>結構化 span、parent-child 樹&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>關聯性&lt;/td>
 &lt;td>弱（要靠 request-id 串）&lt;/td>
 &lt;td>強（trace-id + span 父子關係內建）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>屬性&lt;/td>
 &lt;td>自由 key-value&lt;/td>
 &lt;td>標準化（OTel GenAI semconv）：model / temperature / token usage / cost&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>查詢&lt;/td>
 &lt;td>grep / log aggregator&lt;/td>
 &lt;td>Trace explorer + filter + 視覺化&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM 特有 attr&lt;/td>
 &lt;td>沒有&lt;/td>
 &lt;td>system prompt / tool calls / token / reasoning&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>主流 OTel GenAI span 類型：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Span 類型&lt;/th>
 &lt;th>內容&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;code>gen_ai.client.operation&lt;/code>&lt;/td>
 &lt;td>一次完整 LLM API call&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>gen_ai.tool.execution&lt;/code>&lt;/td>
 &lt;td>一次 tool 執行&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>gen_ai.agent&lt;/code>&lt;/td>
 &lt;td>Agent loop 一個 iteration&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>gen_ai.embeddings&lt;/code>&lt;/td>
 &lt;td>Embedding call&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>gen_ai.memory.read/write&lt;/code>&lt;/td>
 &lt;td>Memory 操作&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>每個 span 標準屬性：&lt;code>gen_ai.system&lt;/code>（vendor）、&lt;code>gen_ai.request.model&lt;/code>、&lt;code>gen_ai.usage.input_tokens&lt;/code> / &lt;code>output_tokens&lt;/code>、&lt;code>gen_ai.request.temperature&lt;/code> 等。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 LLM observability docs / OTel spec 看到「span」「trace」「OTel GenAI semconv」就是這 framing。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>何時值得加 tracing&lt;/strong>：超過個人 demo、有實際使用者 / production 流量、開始遇到「為什麼 agent 跑這條路」debug 問題&lt;/li>
&lt;li>&lt;strong>不該自己寫 logging&lt;/strong>：用 OTel GenAI semconv 標準化、未來可換 backend（LangSmith → Phoenix → 自架）&lt;/li>
&lt;li>&lt;strong>Trace 不只 debug、也是 eval 來源&lt;/strong>：production trace 餵回 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/llm-as-judge/" data-link-title="LLM-as-Judge" data-link-desc="用 LLM 評估另一個 LLM 的輸出品質、production eval 的主流方法、500-5000× 成本降但有 bias 要處理">LLM-as-judge&lt;/a> 做品質評估&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/llm-tracing-and-observability/" data-link-title="4.20 LLM tracing 與 observability" data-link-desc="OpenTelemetry GenAI semantic conventions、結構化 span 設計、cost / latency 監控、failure debug 流程、跟 LLM-as-judge eval 的串接">4.20 LLM tracing 章節&lt;/a> 的關係&lt;/strong>：本卡是定義、章節是工程實務（attribute 設計、cost monitoring、failure debug 流程）&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>LLM tracing 的核心概念是「<strong>把 LLM 應用的每次 LLM call / tool call / memory op / handoff 編成結構化 span、串成 trace、可在 observability 平台查詢</strong>」。對應的標準是 OpenTelemetry GenAI semantic conventions（2025 stabilizing 中）。代表平台：LangSmith、Phoenix、Braintrust、Langfuse、Datadog APM、Logfire。是 production LLM 應用 debug / cost / latency 監控的事實標準、補 traditional logging 抓不到的「為什麼 agent 跑這條路」。</p>
<h2 id="概念位置">概念位置</h2>
<p>跟 traditional logging 的對比：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>Traditional logging</th>
          <th>LLM tracing</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>結構</td>
          <td>字串 line、靠 grep</td>
          <td>結構化 span、parent-child 樹</td>
      </tr>
      <tr>
          <td>關聯性</td>
          <td>弱（要靠 request-id 串）</td>
          <td>強（trace-id + span 父子關係內建）</td>
      </tr>
      <tr>
          <td>屬性</td>
          <td>自由 key-value</td>
          <td>標準化（OTel GenAI semconv）：model / temperature / token usage / cost</td>
      </tr>
      <tr>
          <td>查詢</td>
          <td>grep / log aggregator</td>
          <td>Trace explorer + filter + 視覺化</td>
      </tr>
      <tr>
          <td>LLM 特有 attr</td>
          <td>沒有</td>
          <td>system prompt / tool calls / token / reasoning</td>
      </tr>
  </tbody>
</table>
<p>主流 OTel GenAI span 類型：</p>
<table>
  <thead>
      <tr>
          <th>Span 類型</th>
          <th>內容</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>gen_ai.client.operation</code></td>
          <td>一次完整 LLM API call</td>
      </tr>
      <tr>
          <td><code>gen_ai.tool.execution</code></td>
          <td>一次 tool 執行</td>
      </tr>
      <tr>
          <td><code>gen_ai.agent</code></td>
          <td>Agent loop 一個 iteration</td>
      </tr>
      <tr>
          <td><code>gen_ai.embeddings</code></td>
          <td>Embedding call</td>
      </tr>
      <tr>
          <td><code>gen_ai.memory.read/write</code></td>
          <td>Memory 操作</td>
      </tr>
  </tbody>
</table>
<p>每個 span 標準屬性：<code>gen_ai.system</code>（vendor）、<code>gen_ai.request.model</code>、<code>gen_ai.usage.input_tokens</code> / <code>output_tokens</code>、<code>gen_ai.request.temperature</code> 等。</p>
<h2 id="設計責任">設計責任</h2>
<p>讀 LLM observability docs / OTel spec 看到「span」「trace」「OTel GenAI semconv」就是這 framing。寫 code 場景的判讀：</p>
<ol>
<li><strong>何時值得加 tracing</strong>：超過個人 demo、有實際使用者 / production 流量、開始遇到「為什麼 agent 跑這條路」debug 問題</li>
<li><strong>不該自己寫 logging</strong>：用 OTel GenAI semconv 標準化、未來可換 backend（LangSmith → Phoenix → 自架）</li>
<li><strong>Trace 不只 debug、也是 eval 來源</strong>：production trace 餵回 <a href="/blog/llm/knowledge-cards/llm-as-judge/" data-link-title="LLM-as-Judge" data-link-desc="用 LLM 評估另一個 LLM 的輸出品質、production eval 的主流方法、500-5000× 成本降但有 bias 要處理">LLM-as-judge</a> 做品質評估</li>
<li><strong>跟 <a href="/blog/llm/04-applications/llm-tracing-and-observability/" data-link-title="4.20 LLM tracing 與 observability" data-link-desc="OpenTelemetry GenAI semantic conventions、結構化 span 設計、cost / latency 監控、failure debug 流程、跟 LLM-as-judge eval 的串接">4.20 LLM tracing 章節</a> 的關係</strong>：本卡是定義、章節是工程實務（attribute 設計、cost monitoring、failure debug 流程）</li>
</ol>
]]></content:encoded></item><item><title>LLM-as-Judge</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/llm-as-judge/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/llm-as-judge/</guid><description>&lt;p>LLM-as-Judge 的核心概念是「&lt;strong>用一個 LLM（judge）對另一個 LLM（test subject）的輸出做品質評估&lt;/strong>」。給 judge 一個 rubric（評分標準）跟 (input, output) pair、judge 輸出分數或 pairwise 偏好。是 production LLM eval 的主流方法（500-5000× 比 human eval 便宜、80%+ 跟人類同意度）、但有 bias 要處理（position / verbosity / self-preference）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>跟其他 eval 路徑的對比：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Eval 路徑&lt;/th>
 &lt;th>成本&lt;/th>
 &lt;th>速度&lt;/th>
 &lt;th>適合&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Standard &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/llm-benchmarks/" data-link-title="LLM Benchmarks（MMLU / HumanEval / SWE-bench 等）" data-link-desc="LLM 能力評估的標準 benchmark 集合：MMLU / HumanEval / MBPP / SWE-bench / MT-Bench 等的覆蓋範圍與失效情境">benchmark&lt;/a>（MMLU / SWE-bench 等）&lt;/td>
 &lt;td>中&lt;/td>
 &lt;td>慢（一次 run 數小時）&lt;/td>
 &lt;td>通用能力比較&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Human eval&lt;/td>
 &lt;td>極高（每筆 $1-10）&lt;/td>
 &lt;td>慢&lt;/td>
 &lt;td>黃金標準、final QA&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>LLM-as-Judge（本卡）&lt;/strong>&lt;/td>
 &lt;td>低（每筆 $0.001-0.01）&lt;/td>
 &lt;td>快&lt;/td>
 &lt;td>Production loop eval、自己應用 in-house&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Rule-based / regex&lt;/td>
 &lt;td>極低&lt;/td>
 &lt;td>即時&lt;/td>
 &lt;td>明確 binary（如格式對不對）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>主要 use case：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>In-house benchmark&lt;/strong>：自己工作流的真實案例、自寫 rubric、judge 評&lt;/li>
&lt;li>&lt;strong>Production trace eval&lt;/strong>：用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/llm-tracing/" data-link-title="LLM Tracing" data-link-desc="把 LLM 應用的每次 LLM call / tool call / memory op 編成結構化 span、用 OpenTelemetry GenAI semantic conventions 標準化">LLM tracing&lt;/a> 蒐集的 production trace、定期 judge 跑、抓品質回歸&lt;/li>
&lt;li>&lt;strong>A/B test&lt;/strong>：兩個 prompt / model 變體、judge 做 pairwise 比較&lt;/li>
&lt;li>&lt;strong>Synthetic data quality&lt;/strong>：用大模型生 fine-tune 資料、judge 過濾低品質&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 eval framework / production AI app 看到「LLM as judge」「pairwise eval」「LLM evaluator」就是這 framing。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Judge 模型選擇&lt;/strong>：強模型當 judge（GPT-5 / Claude 4 / Gemini 旗艦）、reasoning model 更穩；judge 跟被測同家可能有 self-preference bias&lt;/li>
&lt;li>&lt;strong>三大 bias 緩解&lt;/strong>：
&lt;ul>
&lt;li>&lt;strong>Position bias&lt;/strong>：A/B pairwise 換位置跑 2 次取一致 vote&lt;/li>
&lt;li>&lt;strong>Verbosity bias&lt;/strong>：rubric 加「冗長不加分」明確指示、或長度 normalize&lt;/li>
&lt;li>&lt;strong>Self-preference bias&lt;/strong>：用 3 個不同 judge model 取多數&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21 LLM-as-judge 章節&lt;/a> 的關係&lt;/strong>：本卡是定義、章節是工程實務（rubric design、bias 緩解、calibration、trace 串接）&lt;/li>
&lt;li>&lt;strong>不是萬靈丹&lt;/strong>：高 stake 任務（醫療、法律、安全）仍需 human eval；judge 的天花板 = judge 模型本身的能力&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>LLM-as-Judge 的核心概念是「<strong>用一個 LLM（judge）對另一個 LLM（test subject）的輸出做品質評估</strong>」。給 judge 一個 rubric（評分標準）跟 (input, output) pair、judge 輸出分數或 pairwise 偏好。是 production LLM eval 的主流方法（500-5000× 比 human eval 便宜、80%+ 跟人類同意度）、但有 bias 要處理（position / verbosity / self-preference）。</p>
<h2 id="概念位置">概念位置</h2>
<p>跟其他 eval 路徑的對比：</p>
<table>
  <thead>
      <tr>
          <th>Eval 路徑</th>
          <th>成本</th>
          <th>速度</th>
          <th>適合</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Standard <a href="/blog/llm/knowledge-cards/llm-benchmarks/" data-link-title="LLM Benchmarks（MMLU / HumanEval / SWE-bench 等）" data-link-desc="LLM 能力評估的標準 benchmark 集合：MMLU / HumanEval / MBPP / SWE-bench / MT-Bench 等的覆蓋範圍與失效情境">benchmark</a>（MMLU / SWE-bench 等）</td>
          <td>中</td>
          <td>慢（一次 run 數小時）</td>
          <td>通用能力比較</td>
      </tr>
      <tr>
          <td>Human eval</td>
          <td>極高（每筆 $1-10）</td>
          <td>慢</td>
          <td>黃金標準、final QA</td>
      </tr>
      <tr>
          <td><strong>LLM-as-Judge（本卡）</strong></td>
          <td>低（每筆 $0.001-0.01）</td>
          <td>快</td>
          <td>Production loop eval、自己應用 in-house</td>
      </tr>
      <tr>
          <td>Rule-based / regex</td>
          <td>極低</td>
          <td>即時</td>
          <td>明確 binary（如格式對不對）</td>
      </tr>
  </tbody>
</table>
<p>主要 use case：</p>
<ol>
<li><strong>In-house benchmark</strong>：自己工作流的真實案例、自寫 rubric、judge 評</li>
<li><strong>Production trace eval</strong>：用 <a href="/blog/llm/knowledge-cards/llm-tracing/" data-link-title="LLM Tracing" data-link-desc="把 LLM 應用的每次 LLM call / tool call / memory op 編成結構化 span、用 OpenTelemetry GenAI semantic conventions 標準化">LLM tracing</a> 蒐集的 production trace、定期 judge 跑、抓品質回歸</li>
<li><strong>A/B test</strong>：兩個 prompt / model 變體、judge 做 pairwise 比較</li>
<li><strong>Synthetic data quality</strong>：用大模型生 fine-tune 資料、judge 過濾低品質</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 eval framework / production AI app 看到「LLM as judge」「pairwise eval」「LLM evaluator」就是這 framing。寫 code 場景的判讀：</p>
<ol>
<li><strong>Judge 模型選擇</strong>：強模型當 judge（GPT-5 / Claude 4 / Gemini 旗艦）、reasoning model 更穩；judge 跟被測同家可能有 self-preference bias</li>
<li><strong>三大 bias 緩解</strong>：
<ul>
<li><strong>Position bias</strong>：A/B pairwise 換位置跑 2 次取一致 vote</li>
<li><strong>Verbosity bias</strong>：rubric 加「冗長不加分」明確指示、或長度 normalize</li>
<li><strong>Self-preference bias</strong>：用 3 個不同 judge model 取多數</li>
</ul>
</li>
<li><strong>跟 <a href="/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21 LLM-as-judge 章節</a> 的關係</strong>：本卡是定義、章節是工程實務（rubric design、bias 緩解、calibration、trace 串接）</li>
<li><strong>不是萬靈丹</strong>：高 stake 任務（醫療、法律、安全）仍需 human eval；judge 的天花板 = judge 模型本身的能力</li>
</ol>
]]></content:encoded></item><item><title>Logit</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/logit/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/logit/</guid><description>&lt;p>Logit 的核心概念是「&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/softmax/" data-link-title="Softmax" data-link-desc="把任意實數向量正規化成「總和為 1、每個分量 ∈ [0,1]」的機率分佈">softmax&lt;/a> 之前的原始分數」。LLM 每次 forward pass 的最後一步、會輸出長度為 vocab size 的實數向量（例如 vocab size = 128K、輸出就是 128K 個浮點數）、這個向量就是 logits。Logit 可正可負、無上下界、要經過 softmax 才變成機率分佈。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Logit 在 LLM 輸出 pipeline 的位置：&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">最後一層 Transformer 輸出 hidden state
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓ output projection（linear layer）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">logits（shape: vocab_size、實數、可正可負）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ↓ logit warping / masking（可選、用於控制輸出）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> ↓ /temperature
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> ↓ softmax
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">probability distribution
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl"> ↓ sampling（greedy / top-k / top-p）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">9&lt;/span>&lt;span class="cl">next token&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>操作 logit 的常見技巧：&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>Temperature&lt;/td>
 &lt;td>logit / T&lt;/td>
 &lt;td>控制輸出隨機度、T 越大越平&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Logit bias&lt;/td>
 &lt;td>對特定 token 的 logit 加 / 減 offset&lt;/td>
 &lt;td>強制 / 抑制特定 token（如禁用特定詞）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Grammar masking&lt;/td>
 &lt;td>把不合法 token 的 logit 設成 -∞&lt;/td>
 &lt;td>Structured output、確保輸出符合 grammar&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Repetition penalty&lt;/td>
 &lt;td>對最近出現過的 token logit 扣分&lt;/td>
 &lt;td>避免重複、改善生成多樣性&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 logit 後可以判讀 sampling 階段的控制粒度：所有「不重訓模型、影響輸出」的技巧（temperature、structured output、constrained generation、logit bias）本質上都是「在 softmax 前後動 logit」、不是動模型權重。這也是為什麼同一個模型用不同 sampling 設定能產生差很多的輸出。&lt;/p></description><content:encoded><![CDATA[<p>Logit 的核心概念是「<a href="/blog/llm/knowledge-cards/softmax/" data-link-title="Softmax" data-link-desc="把任意實數向量正規化成「總和為 1、每個分量 ∈ [0,1]」的機率分佈">softmax</a> 之前的原始分數」。LLM 每次 forward pass 的最後一步、會輸出長度為 vocab size 的實數向量（例如 vocab size = 128K、輸出就是 128K 個浮點數）、這個向量就是 logits。Logit 可正可負、無上下界、要經過 softmax 才變成機率分佈。</p>
<h2 id="概念位置">概念位置</h2>
<p>Logit 在 LLM 輸出 pipeline 的位置：</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">最後一層 Transformer 輸出 hidden state
</span></span><span class="line"><span class="ln">2</span><span class="cl">   ↓ output projection（linear layer）
</span></span><span class="line"><span class="ln">3</span><span class="cl">logits（shape: vocab_size、實數、可正可負）
</span></span><span class="line"><span class="ln">4</span><span class="cl">   ↓ logit warping / masking（可選、用於控制輸出）
</span></span><span class="line"><span class="ln">5</span><span class="cl">   ↓ /temperature
</span></span><span class="line"><span class="ln">6</span><span class="cl">   ↓ softmax
</span></span><span class="line"><span class="ln">7</span><span class="cl">probability distribution
</span></span><span class="line"><span class="ln">8</span><span class="cl">   ↓ sampling（greedy / top-k / top-p）
</span></span><span class="line"><span class="ln">9</span><span class="cl">next token</span></span></code></pre></div><p>操作 logit 的常見技巧：</p>
<table>
  <thead>
      <tr>
          <th>技巧</th>
          <th>做法</th>
          <th>用途</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Temperature</td>
          <td>logit / T</td>
          <td>控制輸出隨機度、T 越大越平</td>
      </tr>
      <tr>
          <td>Logit bias</td>
          <td>對特定 token 的 logit 加 / 減 offset</td>
          <td>強制 / 抑制特定 token（如禁用特定詞）</td>
      </tr>
      <tr>
          <td>Grammar masking</td>
          <td>把不合法 token 的 logit 設成 -∞</td>
          <td>Structured output、確保輸出符合 grammar</td>
      </tr>
      <tr>
          <td>Repetition penalty</td>
          <td>對最近出現過的 token logit 扣分</td>
          <td>避免重複、改善生成多樣性</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>理解 logit 後可以判讀 sampling 階段的控制粒度：所有「不重訓模型、影響輸出」的技巧（temperature、structured output、constrained generation、logit bias）本質上都是「在 softmax 前後動 logit」、不是動模型權重。這也是為什麼同一個模型用不同 sampling 設定能產生差很多的輸出。</p>
]]></content:encoded></item><item><title>LoRA</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/lora/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/lora/</guid><description>&lt;p>LoRA（Low-Rank Adaptation、低秩適配）的核心概念是「&lt;strong>凍住原模型所有權重、在指定 layer 旁邊掛兩個小矩陣 A、B（rank 很低、如 r=8）、只訓 A、B&lt;/strong>」。Hu et al. (2021) 提出、是現在 fine-tuning 的主流選擇、大幅降低訓練成本與記憶體需求。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>LoRA 的數學形式：&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">原 layer 輸出：y = W × x （W 凍住）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">加 LoRA 後： y = W × x + B × A × x
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> └──┬──┘
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> LoRA update（rank r）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> A shape: (r, hidden_dim)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> B shape: (hidden_dim, r)&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>關鍵特性：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>完整 fine-tuning&lt;/th>
 &lt;th>LoRA fine-tuning（r=16）&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>可訓練參數&lt;/td>
 &lt;td>全部（如 7B、70B）&lt;/td>
 &lt;td>~0.1% ~ 1%（只 A、B）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>GPU 記憶體&lt;/td>
 &lt;td>高（要存所有 gradient）&lt;/td>
 &lt;td>大幅降低&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Adapter 檔案大小&lt;/td>
 &lt;td>跟原模型同大&lt;/td>
 &lt;td>幾 MB ~ 幾百 MB&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>訓練成本&lt;/td>
 &lt;td>全模型 backprop&lt;/td>
 &lt;td>只算 A、B 的 gradient&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>部署&lt;/td>
 &lt;td>載入新模型&lt;/td>
 &lt;td>載入原模型 + adapter、推論時合併&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>多任務切換&lt;/td>
 &lt;td>載入不同模型&lt;/td>
 &lt;td>切換 adapter 即可（同個底）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>QLoRA（Dettmers et al., 2023）進一步把原模型量化到 4-bit、LoRA 訓在量化模型上、消費級 GPU 也能 fine-tune 大模型。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 fine-tuning 教學 / Hugging Face PEFT 看到 LoRA、QLoRA 是現在主流。寫 code 場景的判讀：LoRA 適合「在現有模型上加領域知識 / 風格」（如教模型用特定 codebase 慣例）、不適合「教模型新世界知識」（仍要 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/pre-training/" data-link-title="Pre-training" data-link-desc="LLM 訓練的第一階段：用 trillion-token 級網路文字做 next-token prediction、得到 base model">pre-training&lt;/a> 級資料）；adapter 形式讓「多客戶 / 多風格」場景可以共用 base model、只切換 adapter、節省 GPU 記憶體。&lt;/p></description><content:encoded><![CDATA[<p>LoRA（Low-Rank Adaptation、低秩適配）的核心概念是「<strong>凍住原模型所有權重、在指定 layer 旁邊掛兩個小矩陣 A、B（rank 很低、如 r=8）、只訓 A、B</strong>」。Hu et al. (2021) 提出、是現在 fine-tuning 的主流選擇、大幅降低訓練成本與記憶體需求。</p>
<h2 id="概念位置">概念位置</h2>
<p>LoRA 的數學形式：</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">原 layer 輸出：y = W × x       （W 凍住）
</span></span><span class="line"><span class="ln">2</span><span class="cl">加 LoRA 後：  y = W × x + B × A × x
</span></span><span class="line"><span class="ln">3</span><span class="cl">                          └──┬──┘
</span></span><span class="line"><span class="ln">4</span><span class="cl">                       LoRA update（rank r）
</span></span><span class="line"><span class="ln">5</span><span class="cl">                       A shape: (r, hidden_dim)
</span></span><span class="line"><span class="ln">6</span><span class="cl">                       B shape: (hidden_dim, r)</span></span></code></pre></div><p>關鍵特性：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>完整 fine-tuning</th>
          <th>LoRA fine-tuning（r=16）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>可訓練參數</td>
          <td>全部（如 7B、70B）</td>
          <td>~0.1% ~ 1%（只 A、B）</td>
      </tr>
      <tr>
          <td>GPU 記憶體</td>
          <td>高（要存所有 gradient）</td>
          <td>大幅降低</td>
      </tr>
      <tr>
          <td>Adapter 檔案大小</td>
          <td>跟原模型同大</td>
          <td>幾 MB ~ 幾百 MB</td>
      </tr>
      <tr>
          <td>訓練成本</td>
          <td>全模型 backprop</td>
          <td>只算 A、B 的 gradient</td>
      </tr>
      <tr>
          <td>部署</td>
          <td>載入新模型</td>
          <td>載入原模型 + adapter、推論時合併</td>
      </tr>
      <tr>
          <td>多任務切換</td>
          <td>載入不同模型</td>
          <td>切換 adapter 即可（同個底）</td>
      </tr>
  </tbody>
</table>
<p>QLoRA（Dettmers et al., 2023）進一步把原模型量化到 4-bit、LoRA 訓在量化模型上、消費級 GPU 也能 fine-tune 大模型。</p>
<h2 id="設計責任">設計責任</h2>
<p>讀 fine-tuning 教學 / Hugging Face PEFT 看到 LoRA、QLoRA 是現在主流。寫 code 場景的判讀：LoRA 適合「在現有模型上加領域知識 / 風格」（如教模型用特定 codebase 慣例）、不適合「教模型新世界知識」（仍要 <a href="/blog/llm/knowledge-cards/pre-training/" data-link-title="Pre-training" data-link-desc="LLM 訓練的第一階段：用 trillion-token 級網路文字做 next-token prediction、得到 base model">pre-training</a> 級資料）；adapter 形式讓「多客戶 / 多風格」場景可以共用 base model、只切換 adapter、節省 GPU 記憶體。</p>
]]></content:encoded></item><item><title>Loss Function</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/loss-function/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/loss-function/</guid><description>&lt;p>Loss function（損失函數、目的函數）的核心概念是「把模型預測跟正確答案的差距、壓成一個純量數值」。訓練的整個目標就是「最小化這個數值」、所有 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/gradient/" data-link-title="Gradient" data-link-desc="loss function 對權重的偏微分向量、指出「該往哪個方向調權重才能讓 loss 下降最快」">gradient&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/backpropagation/" data-link-title="Backpropagation" data-link-desc="從 output loss 反向遞推、用 chain rule 算出每個權重的 gradient 的演算法">backpropagation&lt;/a> / optimizer step 都在做這件事。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>LLM 各訓練階段用不同的 loss function：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>階段&lt;/th>
 &lt;th>主要 loss&lt;/th>
 &lt;th>衡量的東西&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Pre-training&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/cross-entropy/" data-link-title="Cross-Entropy" data-link-desc="衡量「預測機率分佈」跟「真實分佈」距離的指標、LLM 預訓練的主要 loss">Cross-entropy&lt;/a>（next-token prediction）&lt;/td>
 &lt;td>模型預測的下個 token 機率跟真實答案的距離&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>SFT&lt;/td>
 &lt;td>Cross-entropy（同上、但 only on assistant response）&lt;/td>
 &lt;td>模型回答跟人類示範回答的距離&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Reward model&lt;/td>
 &lt;td>Pairwise ranking loss&lt;/td>
 &lt;td>「人類偏好 A 大於 B」這個訊號的擬合度&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>RLHF / DPO&lt;/td>
 &lt;td>KL-constrained reward loss / DPO loss&lt;/td>
 &lt;td>reward 高 + 不偏離 base 模型太遠&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>評估時用的指標（&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/perplexity/" data-link-title="Perplexity" data-link-desc="cross-entropy 的指數形式、直覺意義為「模型平均覺得下個 token 有多少種可能」">perplexity&lt;/a>、accuracy、BLEU 等）跟訓練 loss 是不同概念：loss 是「訓練要 minimize 的東西」、指標是「給人看模型好不好的數字」、兩者不一定一致（loss 降但指標不一定升、反之亦然）。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>選 loss function 等於選「訓練要把模型推往哪個方向」。Cross-entropy 推「機率分佈接近真實 token」、reward model 推「人類偏好高的回應」、DPO 推「偏好回應 vs 拒絕回應的對比」— 每種 loss 對應的模型行為不同。讀 paper 看到「我們用 X loss」、要回問「這 loss 把模型推往哪個方向」、才能判斷模型訓練出來的特性是否符合預期。&lt;/p></description><content:encoded><![CDATA[<p>Loss function（損失函數、目的函數）的核心概念是「把模型預測跟正確答案的差距、壓成一個純量數值」。訓練的整個目標就是「最小化這個數值」、所有 <a href="/blog/llm/knowledge-cards/gradient/" data-link-title="Gradient" data-link-desc="loss function 對權重的偏微分向量、指出「該往哪個方向調權重才能讓 loss 下降最快」">gradient</a> / <a href="/blog/llm/knowledge-cards/backpropagation/" data-link-title="Backpropagation" data-link-desc="從 output loss 反向遞推、用 chain rule 算出每個權重的 gradient 的演算法">backpropagation</a> / optimizer step 都在做這件事。</p>
<h2 id="概念位置">概念位置</h2>
<p>LLM 各訓練階段用不同的 loss function：</p>
<table>
  <thead>
      <tr>
          <th>階段</th>
          <th>主要 loss</th>
          <th>衡量的東西</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Pre-training</td>
          <td><a href="/blog/llm/knowledge-cards/cross-entropy/" data-link-title="Cross-Entropy" data-link-desc="衡量「預測機率分佈」跟「真實分佈」距離的指標、LLM 預訓練的主要 loss">Cross-entropy</a>（next-token prediction）</td>
          <td>模型預測的下個 token 機率跟真實答案的距離</td>
      </tr>
      <tr>
          <td>SFT</td>
          <td>Cross-entropy（同上、但 only on assistant response）</td>
          <td>模型回答跟人類示範回答的距離</td>
      </tr>
      <tr>
          <td>Reward model</td>
          <td>Pairwise ranking loss</td>
          <td>「人類偏好 A 大於 B」這個訊號的擬合度</td>
      </tr>
      <tr>
          <td>RLHF / DPO</td>
          <td>KL-constrained reward loss / DPO loss</td>
          <td>reward 高 + 不偏離 base 模型太遠</td>
      </tr>
  </tbody>
</table>
<p>評估時用的指標（<a href="/blog/llm/knowledge-cards/perplexity/" data-link-title="Perplexity" data-link-desc="cross-entropy 的指數形式、直覺意義為「模型平均覺得下個 token 有多少種可能」">perplexity</a>、accuracy、BLEU 等）跟訓練 loss 是不同概念：loss 是「訓練要 minimize 的東西」、指標是「給人看模型好不好的數字」、兩者不一定一致（loss 降但指標不一定升、反之亦然）。</p>
<h2 id="設計責任">設計責任</h2>
<p>選 loss function 等於選「訓練要把模型推往哪個方向」。Cross-entropy 推「機率分佈接近真實 token」、reward model 推「人類偏好高的回應」、DPO 推「偏好回應 vs 拒絕回應的對比」— 每種 loss 對應的模型行為不同。讀 paper 看到「我們用 X loss」、要回問「這 loss 把模型推往哪個方向」、才能判斷模型訓練出來的特性是否符合預期。</p>
]]></content:encoded></item><item><title>Lost in the Middle</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/lost-in-the-middle/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/lost-in-the-middle/</guid><description>&lt;p>Lost in the middle（中段遺失、Liu et al., 2023）的核心概念是「&lt;strong>LLM 對 long context 中段內容的 attention / recall 顯著低於開頭與結尾&lt;/strong>」。實測：把答案放在 10K context 的開頭或結尾、模型 recall 準確率 80%+；放在中段 4000-6000 token 位置、recall 掉到 50% 甚至更低。是 long context 使用上最常見的失敗模式。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Long context 的 effective context 跟 claimed context 落差來自三個現象：&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>Lost in the middle&lt;/td>
 &lt;td>中段內容 attention 顯著低、recall 掉&lt;/td>
 &lt;td>普遍、最頻繁&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Context degradation&lt;/td>
 &lt;td>接近 context 上限時、整體品質緩降&lt;/td>
 &lt;td>接近上限才明顯&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Needle in haystack&lt;/td>
 &lt;td>抓單一事實的能力（vs lost-in-the-middle 抓整段邏輯）&lt;/td>
 &lt;td>兩條軸、不完全重疊&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>





&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">Recall accuracy vs 答案位置（典型 10K context）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">100% |█ █
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> |██ ██
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> 80% |███ ███
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> |███ ███
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> 60% |███ ____ ███
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> |███ ___/ \___ ███
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> 40% |███ _/ \_ ███
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> |█████─/ \───── ███
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> 0 2K 4K 6K 8K 10K
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl"> 開頭 結尾&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>成因：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Attention weight 分佈不均勻&lt;/strong>：訓練資料中、句首 / 段首通常含關鍵資訊、模型學會偏重句首；長 context 的中段在訓練資料中相對稀疏、attention 沒學好&lt;/li>
&lt;li>&lt;strong>Positional encoding 設計&lt;/strong>：RoPE / ALiBi 等對長距離 attention 的衰減模式、中段 token 跟 query 距離通常較大、attention 弱&lt;/li>
&lt;li>&lt;strong>訓練 context 長度的影響&lt;/strong>：模型若訓練在 8K context、推論時用 128K（用 RoPE scaling 延伸）、中段表現比訓練範圍內差更多&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 long-context paper / benchmark 看到「lost-in-the-middle」「U-shape recall」就是這現象。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>把關鍵資訊放開頭或結尾&lt;/strong>：system prompt 在開頭、最新指示在結尾（剛好是模型 attention 最強的兩處）&lt;/li>
&lt;li>&lt;strong>長 context 不是「塞越多越好」&lt;/strong>：超過 effective context（典型 8-16K）後、邊際效用急降&lt;/li>
&lt;li>&lt;strong>RAG 比 long context 仍有價值&lt;/strong>：把相關片段 retrieve 出來放 prompt 開頭、比把整份文件塞進 100K context 效果更穩定&lt;/li>
&lt;li>&lt;strong>驗證自己模型的 effective context&lt;/strong>：用 needle-in-haystack 或自製測試、看模型在 8K / 16K / 32K 表現掉到哪&lt;/li>
&lt;li>&lt;strong>Reasoning model 的 thinking trace 不會遇到這事故嗎？&lt;/strong> — 仍會遇到、但 reasoning 過程會主動重新引用前文、部分緩解；不過 thinking trace 本身會擠壓 context budget、可能反而觸發 degradation&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Lost in the middle（中段遺失、Liu et al., 2023）的核心概念是「<strong>LLM 對 long context 中段內容的 attention / recall 顯著低於開頭與結尾</strong>」。實測：把答案放在 10K context 的開頭或結尾、模型 recall 準確率 80%+；放在中段 4000-6000 token 位置、recall 掉到 50% 甚至更低。是 long context 使用上最常見的失敗模式。</p>
<h2 id="概念位置">概念位置</h2>
<p>Long context 的 effective context 跟 claimed context 落差來自三個現象：</p>
<table>
  <thead>
      <tr>
          <th>現象</th>
          <th>描述</th>
          <th>嚴重度</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Lost in the middle</td>
          <td>中段內容 attention 顯著低、recall 掉</td>
          <td>普遍、最頻繁</td>
      </tr>
      <tr>
          <td>Context degradation</td>
          <td>接近 context 上限時、整體品質緩降</td>
          <td>接近上限才明顯</td>
      </tr>
      <tr>
          <td>Needle in haystack</td>
          <td>抓單一事實的能力（vs lost-in-the-middle 抓整段邏輯）</td>
          <td>兩條軸、不完全重疊</td>
      </tr>
  </tbody>
</table>





<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">Recall accuracy vs 答案位置（典型 10K context）：
</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">100% |█                                       █
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">     |██                                     ██
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"> 80% |███                                   ███
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">     |███                                   ███
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"> 60% |███          ____                     ███
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">     |███      ___/    \___                 ███
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"> 40% |███    _/            \_               ███
</span></span><span class="line"><span class="ln">10</span><span class="cl">     |█████─/                \─────         ███
</span></span><span class="line"><span class="ln">11</span><span class="cl">     |
</span></span><span class="line"><span class="ln">12</span><span class="cl">       0      2K     4K     6K     8K    10K
</span></span><span class="line"><span class="ln">13</span><span class="cl">       開頭                              結尾</span></span></code></pre></div><p>成因：</p>
<ol>
<li><strong>Attention weight 分佈不均勻</strong>：訓練資料中、句首 / 段首通常含關鍵資訊、模型學會偏重句首；長 context 的中段在訓練資料中相對稀疏、attention 沒學好</li>
<li><strong>Positional encoding 設計</strong>：RoPE / ALiBi 等對長距離 attention 的衰減模式、中段 token 跟 query 距離通常較大、attention 弱</li>
<li><strong>訓練 context 長度的影響</strong>：模型若訓練在 8K context、推論時用 128K（用 RoPE scaling 延伸）、中段表現比訓練範圍內差更多</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 long-context paper / benchmark 看到「lost-in-the-middle」「U-shape recall」就是這現象。寫 code 場景的判讀：</p>
<ol>
<li><strong>把關鍵資訊放開頭或結尾</strong>：system prompt 在開頭、最新指示在結尾（剛好是模型 attention 最強的兩處）</li>
<li><strong>長 context 不是「塞越多越好」</strong>：超過 effective context（典型 8-16K）後、邊際效用急降</li>
<li><strong>RAG 比 long context 仍有價值</strong>：把相關片段 retrieve 出來放 prompt 開頭、比把整份文件塞進 100K context 效果更穩定</li>
<li><strong>驗證自己模型的 effective context</strong>：用 needle-in-haystack 或自製測試、看模型在 8K / 16K / 32K 表現掉到哪</li>
<li><strong>Reasoning model 的 thinking trace 不會遇到這事故嗎？</strong> — 仍會遇到、但 reasoning 過程會主動重新引用前文、部分緩解；不過 thinking trace 本身會擠壓 context budget、可能反而觸發 degradation</li>
</ol>
]]></content:encoded></item><item><title>Matrix Multiplication</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/matrix-multiplication/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/matrix-multiplication/</guid><description>&lt;p>Matrix multiplication（矩陣乘法、matmul、&lt;code>@&lt;/code>）的核心概念是「&lt;strong>左矩陣的每個 row 跟右矩陣的每個 column 做 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/dot-product/" data-link-title="Dot Product" data-link-desc="兩個向量對應位置相乘再加總、attention score 跟相似度判讀的基礎">dot product&lt;/a>、結果填進新矩陣&lt;/strong>」。對 &lt;code>A (m × k)&lt;/code> 跟 &lt;code>B (k × n)&lt;/code>、結果 &lt;code>C (m × n)&lt;/code>、其中 &lt;code>C[i][j] = A 第 i row · B 第 j column&lt;/code>。Matmul 是 LLM 推論最頻繁的運算、整個 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/forward-pass/" data-link-title="Forward Pass" data-link-desc="input 經過所有 layer 的計算、得到 output 的單向流程；推論跟訓練都會跑、訓練多一個反向階段">forward pass&lt;/a> 可以看成幾百次 matmul 串起來。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>LLM 中 matmul 出現的關鍵位置：&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>Embedding lookup&lt;/td>
 &lt;td>&lt;code>(seq_len, vocab) @ (vocab, hidden)&lt;/code> ≡ 查表&lt;/td>
 &lt;td>Token ID → embedding&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Q/K/V 投影&lt;/td>
 &lt;td>&lt;code>(seq_len, hidden) @ (hidden, hidden)&lt;/code>&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/self-attention/" data-link-title="Self-Attention" data-link-desc="Q / K / V 都從同一個 sequence 投影出來的 attention、Transformer 的標誌性設計">Self-attention&lt;/a> 第一步&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Attention score&lt;/td>
 &lt;td>&lt;code>(seq_len, head_dim) @ (head_dim, seq_len)&lt;/code>&lt;/td>
 &lt;td>Q · K^T、O(n²)、long context 痛點&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Attention output&lt;/td>
 &lt;td>&lt;code>(seq_len, seq_len) @ (seq_len, head_dim)&lt;/code>&lt;/td>
 &lt;td>attention weight · V&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/ffn/" data-link-title="FFN（Feed-Forward Network）" data-link-desc="Transformer block 內部的兩層 linear &amp;#43; activation、佔模型參數量的多數">FFN&lt;/a> up&lt;/td>
 &lt;td>&lt;code>(seq_len, hidden) @ (hidden, 4×hidden)&lt;/code>&lt;/td>
 &lt;td>FFN 升維、參數大頭&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>FFN down&lt;/td>
 &lt;td>&lt;code>(seq_len, 4×hidden) @ (4×hidden, hidden)&lt;/code>&lt;/td>
 &lt;td>FFN 降維&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Output projection&lt;/td>
 &lt;td>&lt;code>(seq_len, hidden) @ (hidden, vocab)&lt;/code>&lt;/td>
 &lt;td>Hidden → logits&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵尺寸規則：&lt;strong>左矩陣 column 數 = 右矩陣 row 數&lt;/strong>、即 &lt;code>(m × k) @ (k × n) = (m × n)&lt;/code>。Dimension mismatch 是訓練 / 推論最常見的 PyTorch 報錯之一。&lt;/p>
&lt;h2 id="為什麼-matmul-是-memory-bandwidth-bound">為什麼 matmul 是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth&lt;/a> bound&lt;/h2>
&lt;p>LLM 推論每生一個 token、要把整份模型權重從記憶體讀到處理器一次（每個權重在當輪 forward pass 的某個 matmul 都用得到）；現代 GPU / Apple Silicon 的算力遠超頻寬、所以「讀權重要多久」變主要瓶頸。這就是為什麼：&lt;/p>
&lt;ul>
&lt;li>31B 模型 Q4_K_M 約 18GB、M4 Max 頻寬 546 GB/s、理論上限 ≈ 30 tok/s&lt;/li>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">量化&lt;/a> 加速主要是「權重變小、每秒能讀過更多次完整模型」&lt;/li>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/batching/" data-link-title="Batching" data-link-desc="多 request 一起跑、攤平 model load 成本：production LLM inference 的核心優化、決定 throughput vs latency 取捨">Batching&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">speculative decoding&lt;/a> 加速主要是「一次讀權重、攤平到多個 token」&lt;/li>
&lt;/ul>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 paper / model card 看到模型參數量、可以反推總 matmul 工作量；看到 inference benchmark 看到 tok/s、可以用「模型大小 / memory bandwidth」算理論上限對照。寫 code 場景無需直接寫 matmul、但理解這個運算的成本結構、能看懂量化 / batching / speculative decoding 等加速技巧為什麼有效。&lt;/p></description><content:encoded><![CDATA[<p>Matrix multiplication（矩陣乘法、matmul、<code>@</code>）的核心概念是「<strong>左矩陣的每個 row 跟右矩陣的每個 column 做 <a href="/blog/llm/knowledge-cards/dot-product/" data-link-title="Dot Product" data-link-desc="兩個向量對應位置相乘再加總、attention score 跟相似度判讀的基礎">dot product</a>、結果填進新矩陣</strong>」。對 <code>A (m × k)</code> 跟 <code>B (k × n)</code>、結果 <code>C (m × n)</code>、其中 <code>C[i][j] = A 第 i row · B 第 j column</code>。Matmul 是 LLM 推論最頻繁的運算、整個 <a href="/blog/llm/knowledge-cards/forward-pass/" data-link-title="Forward Pass" data-link-desc="input 經過所有 layer 的計算、得到 output 的單向流程；推論跟訓練都會跑、訓練多一個反向階段">forward pass</a> 可以看成幾百次 matmul 串起來。</p>
<h2 id="概念位置">概念位置</h2>
<p>LLM 中 matmul 出現的關鍵位置：</p>
<table>
  <thead>
      <tr>
          <th>位置</th>
          <th>形狀（簡化）</th>
          <th>角色</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Embedding lookup</td>
          <td><code>(seq_len, vocab) @ (vocab, hidden)</code> ≡ 查表</td>
          <td>Token ID → embedding</td>
      </tr>
      <tr>
          <td>Q/K/V 投影</td>
          <td><code>(seq_len, hidden) @ (hidden, hidden)</code></td>
          <td><a href="/blog/llm/knowledge-cards/self-attention/" data-link-title="Self-Attention" data-link-desc="Q / K / V 都從同一個 sequence 投影出來的 attention、Transformer 的標誌性設計">Self-attention</a> 第一步</td>
      </tr>
      <tr>
          <td>Attention score</td>
          <td><code>(seq_len, head_dim) @ (head_dim, seq_len)</code></td>
          <td>Q · K^T、O(n²)、long context 痛點</td>
      </tr>
      <tr>
          <td>Attention output</td>
          <td><code>(seq_len, seq_len) @ (seq_len, head_dim)</code></td>
          <td>attention weight · V</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/ffn/" data-link-title="FFN（Feed-Forward Network）" data-link-desc="Transformer block 內部的兩層 linear &#43; activation、佔模型參數量的多數">FFN</a> up</td>
          <td><code>(seq_len, hidden) @ (hidden, 4×hidden)</code></td>
          <td>FFN 升維、參數大頭</td>
      </tr>
      <tr>
          <td>FFN down</td>
          <td><code>(seq_len, 4×hidden) @ (4×hidden, hidden)</code></td>
          <td>FFN 降維</td>
      </tr>
      <tr>
          <td>Output projection</td>
          <td><code>(seq_len, hidden) @ (hidden, vocab)</code></td>
          <td>Hidden → logits</td>
      </tr>
  </tbody>
</table>
<p>關鍵尺寸規則：<strong>左矩陣 column 數 = 右矩陣 row 數</strong>、即 <code>(m × k) @ (k × n) = (m × n)</code>。Dimension mismatch 是訓練 / 推論最常見的 PyTorch 報錯之一。</p>
<h2 id="為什麼-matmul-是-memory-bandwidth-bound">為什麼 matmul 是 <a href="/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth</a> bound</h2>
<p>LLM 推論每生一個 token、要把整份模型權重從記憶體讀到處理器一次（每個權重在當輪 forward pass 的某個 matmul 都用得到）；現代 GPU / Apple Silicon 的算力遠超頻寬、所以「讀權重要多久」變主要瓶頸。這就是為什麼：</p>
<ul>
<li>31B 模型 Q4_K_M 約 18GB、M4 Max 頻寬 546 GB/s、理論上限 ≈ 30 tok/s</li>
<li><a href="/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">量化</a> 加速主要是「權重變小、每秒能讀過更多次完整模型」</li>
<li><a href="/blog/llm/knowledge-cards/batching/" data-link-title="Batching" data-link-desc="多 request 一起跑、攤平 model load 成本：production LLM inference 的核心優化、決定 throughput vs latency 取捨">Batching</a> / <a href="/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">speculative decoding</a> 加速主要是「一次讀權重、攤平到多個 token」</li>
</ul>
<h2 id="設計責任">設計責任</h2>
<p>讀 paper / model card 看到模型參數量、可以反推總 matmul 工作量；看到 inference benchmark 看到 tok/s、可以用「模型大小 / memory bandwidth」算理論上限對照。寫 code 場景無需直接寫 matmul、但理解這個運算的成本結構、能看懂量化 / batching / speculative decoding 等加速技巧為什麼有效。</p>
]]></content:encoded></item><item><title>Mixture of Experts (MoE)</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/moe/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/moe/</guid><description>&lt;p>MoE（Mixture of Experts）的核心概念是「把 transformer block 內的 FFN 層拆成多個專家網路、router 為每個 token 動態挑選少數啟用」。結果是模型總參數可以擴張到很大、但每個 token 實際計算量保持在「&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/active-parameter/" data-link-title="Active Parameter" data-link-desc="MoE 模型每生成一個 token 實際參與計算的參數量、跟模型總參數量不同、影響推論速度上限">active parameter&lt;/a>」這個較小的數目；同硬體下 MoE 模型常比同總參數的 Dense 模型跑得快、且能力強於同 active parameter 的 Dense 模型。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>MoE 在 transformer 架構中的位置：&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">transformer block：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ├── attention 層（所有 token 共用）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> ├── layer norm
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> └── FFN 層
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> ├── Dense 架構：所有 token 走同一組 FFN
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> └── MoE 架構：FFN 拆成多個 expert、router 挑選 top-k 個啟用&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>主流 MoE 模型的設計選擇（依模型而異）：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>expert 數量&lt;/strong>：通常 8 ~ 256 個&lt;/li>
&lt;li>&lt;strong>每 token 啟用 expert 數&lt;/strong>：通常 1 ~ 2 個（top-k routing）&lt;/li>
&lt;li>&lt;strong>shared expert&lt;/strong>：部分模型保留少數所有 token 共用的 expert&lt;/li>
&lt;li>&lt;strong>total / active parameter 比&lt;/strong>：常見 5x ~ 10x（如 Qwen3-30B-A3B：30B total / 3B active）&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：MoE 架構的具體實作（router 演算法、load balancing loss、expert 並行策略等）依模型快速演進、引用前以該模型的技術報告或 paper 為準。&lt;/p>&lt;/blockquote>
&lt;p>代表性 MoE 模型（依公開資訊）：Mixtral 8x7B、DeepSeek V3、Qwen3-30B-A3B、Llama 4 Scout 等。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 MoE 後可以解釋三個現象：為什麼 MoE 模型的「30B 總參數」跟「3B active parameter」是兩個獨立指標（前者影響記憶體需求、後者影響速度）、為什麼 MoE 適合 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/moe-cpu-offload/" data-link-title="MoE CPU 卸載" data-link-desc="把 Mixture-of-Experts 模型不活躍的專家層權重放在系統 RAM、用到再走 PCIe 拉回 GPU、讓有限 VRAM 跑得了更大模型">CPU 卸載&lt;/a>（不活躍的 expert 可以留在系統 RAM）、為什麼 MoE 在多 GPU 場景的並行策略跟 Dense 模型不同（expert 可以分到不同卡）。&lt;/p>
&lt;p>選 MoE 模型 vs Dense 模型、需考慮：MoE 對 RAM 容量要求較高（要放所有 expert 權重）、對 GPU 算力要求較低（每 token 走 active parameter）；Dense 對 VRAM 容量要求較低（可全載中型模型）、對 GPU 算力要求較高。詳見 &lt;a href="https://tarrragon.github.io/blog/llm/05-discrete-gpu/moe-cpu-offload-strategy/" data-link-title="5.1 MoE 模型與 CPU 卸載策略" data-link-desc="PC 場景把 MoE 不活躍專家層留在系統 RAM 的判讀：何時值得卸載、卸幾層、對 prefill 跟生成的影響各自不同">5.1 MoE 模型與 CPU 卸載策略&lt;/a> 跟 &lt;a href="https://tarrragon.github.io/blog/llm/05-discrete-gpu/model-selection-priority-pc/" data-link-title="5.5 PC 場景的模型選型優先順序" data-link-desc="PC 獨立 GPU 場景下、MoE 卸載讓「全載小模型 vs 卸載大 MoE」變成主要的選型軸；對應不同 VRAM 容量的模型推薦">5.5 PC 場景的模型選型優先順序&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>MoE（Mixture of Experts）的核心概念是「把 transformer block 內的 FFN 層拆成多個專家網路、router 為每個 token 動態挑選少數啟用」。結果是模型總參數可以擴張到很大、但每個 token 實際計算量保持在「<a href="/blog/llm/knowledge-cards/active-parameter/" data-link-title="Active Parameter" data-link-desc="MoE 模型每生成一個 token 實際參與計算的參數量、跟模型總參數量不同、影響推論速度上限">active parameter</a>」這個較小的數目；同硬體下 MoE 模型常比同總參數的 Dense 模型跑得快、且能力強於同 active parameter 的 Dense 模型。</p>
<h2 id="概念位置">概念位置</h2>
<p>MoE 在 transformer 架構中的位置：</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">transformer block：
</span></span><span class="line"><span class="ln">2</span><span class="cl">  ├── attention 層（所有 token 共用）
</span></span><span class="line"><span class="ln">3</span><span class="cl">  ├── layer norm
</span></span><span class="line"><span class="ln">4</span><span class="cl">  └── FFN 層
</span></span><span class="line"><span class="ln">5</span><span class="cl">        ├── Dense 架構：所有 token 走同一組 FFN
</span></span><span class="line"><span class="ln">6</span><span class="cl">        └── MoE 架構：FFN 拆成多個 expert、router 挑選 top-k 個啟用</span></span></code></pre></div><p>主流 MoE 模型的設計選擇（依模型而異）：</p>
<ul>
<li><strong>expert 數量</strong>：通常 8 ~ 256 個</li>
<li><strong>每 token 啟用 expert 數</strong>：通常 1 ~ 2 個（top-k routing）</li>
<li><strong>shared expert</strong>：部分模型保留少數所有 token 共用的 expert</li>
<li><strong>total / active parameter 比</strong>：常見 5x ~ 10x（如 Qwen3-30B-A3B：30B total / 3B active）</li>
</ul>
<blockquote>
<p><strong>事實查核註</strong>：MoE 架構的具體實作（router 演算法、load balancing loss、expert 並行策略等）依模型快速演進、引用前以該模型的技術報告或 paper 為準。</p></blockquote>
<p>代表性 MoE 模型（依公開資訊）：Mixtral 8x7B、DeepSeek V3、Qwen3-30B-A3B、Llama 4 Scout 等。</p>
<h2 id="設計責任">設計責任</h2>
<p>理解 MoE 後可以解釋三個現象：為什麼 MoE 模型的「30B 總參數」跟「3B active parameter」是兩個獨立指標（前者影響記憶體需求、後者影響速度）、為什麼 MoE 適合 <a href="/blog/llm/knowledge-cards/moe-cpu-offload/" data-link-title="MoE CPU 卸載" data-link-desc="把 Mixture-of-Experts 模型不活躍的專家層權重放在系統 RAM、用到再走 PCIe 拉回 GPU、讓有限 VRAM 跑得了更大模型">CPU 卸載</a>（不活躍的 expert 可以留在系統 RAM）、為什麼 MoE 在多 GPU 場景的並行策略跟 Dense 模型不同（expert 可以分到不同卡）。</p>
<p>選 MoE 模型 vs Dense 模型、需考慮：MoE 對 RAM 容量要求較高（要放所有 expert 權重）、對 GPU 算力要求較低（每 token 走 active parameter）；Dense 對 VRAM 容量要求較低（可全載中型模型）、對 GPU 算力要求較高。詳見 <a href="/blog/llm/05-discrete-gpu/moe-cpu-offload-strategy/" data-link-title="5.1 MoE 模型與 CPU 卸載策略" data-link-desc="PC 場景把 MoE 不活躍專家層留在系統 RAM 的判讀：何時值得卸載、卸幾層、對 prefill 跟生成的影響各自不同">5.1 MoE 模型與 CPU 卸載策略</a> 跟 <a href="/blog/llm/05-discrete-gpu/model-selection-priority-pc/" data-link-title="5.5 PC 場景的模型選型優先順序" data-link-desc="PC 獨立 GPU 場景下、MoE 卸載讓「全載小模型 vs 卸載大 MoE」變成主要的選型軸；對應不同 VRAM 容量的模型推薦">5.5 PC 場景的模型選型優先順序</a>。</p>
]]></content:encoded></item><item><title>Model Card</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/model-card/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/model-card/</guid><description>&lt;p>Model card 的核心概念是「模型發布時附帶的 metadata 文件、列出模型的來源、訓練資料、預期用途、能力上限、已知限制跟授權條款」。Hugging Face 上每個 model repo 的 &lt;code>README.md&lt;/code> 就是 model card；它是個人 dev 跟 production 場景下判讀「該不該用這個模型」的最主要資訊來源。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>典型的 model card 包含哪些區段（依平台跟模型而異）：&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>基本資訊&lt;/td>
 &lt;td>模型名稱、參數量、架構、發布者&lt;/td>
 &lt;td>確認是哪個 organization 發布&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Training data&lt;/td>
 &lt;td>訓練語料的來源、規模、語言分布&lt;/td>
 &lt;td>評估模型在自己語言 / 任務的適配性&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Intended use&lt;/td>
 &lt;td>預期用途、適合的應用場景&lt;/td>
 &lt;td>判讀模型是否符合自己工作流&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Out-of-scope use&lt;/td>
 &lt;td>不適合的用途、已知不擅長的任務&lt;/td>
 &lt;td>避免誤用&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Bias、ethical considerations&lt;/td>
 &lt;td>已知偏見、敏感議題的回應傾向&lt;/td>
 &lt;td>production 場景的合規評估&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Benchmark&lt;/td>
 &lt;td>在公開 benchmark 上的分數&lt;/td>
 &lt;td>跟其他模型對比&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>License&lt;/td>
 &lt;td>模型權重的使用授權&lt;/td>
 &lt;td>商用前必看&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Quantization 版本&lt;/td>
 &lt;td>該 repo 提供哪些量化版本&lt;/td>
 &lt;td>選對應 &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> 版本&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：Hugging Face 推動 Model Card 規範跟 &lt;a href="https://github.com/huggingface/hub-docs">Model Card Toolkit&lt;/a>、但實際填寫品質依 organization 變化、部分 repo 的 model card 內容很簡略、不能 100% 依賴。引用前以該 repo 當前內容為準。&lt;/p>&lt;/blockquote>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 model card 後可以解釋兩個現象：為什麼選模型不能只看名字（同個 base model 的不同 fine-tune 版本能力差很多）、為什麼商用前要看 license（Llama Community License、Apache 2.0、MIT 等差異大）。&lt;/p>
&lt;p>實務上選模型時、model card 是第一閱讀對象、其他資訊（社群評測、benchmark leaderboard）作為交叉驗證；引用模型時應該明確記下「base model + fine-tune 變體 + 量化版本」三層。詳見 &lt;a href="https://tarrragon.github.io/blog/llm/06-security/model-supply-chain-trust/" data-link-title="6.0 模型供應鏈與信任邊界" data-link-desc="個人 dev 用本地 LLM 時的模型權重來源信任：GGUF 完整性、Hugging Face / Ollama registry 信任、量化版本污染、檔案完整性檢查">6.0 模型供應鏈與信任邊界&lt;/a> 跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/llm-deployment-supply-chain/" data-link-title="LLM Deployment 供應鏈完整性" data-link-desc="把 LLM 模型權重、推論伺服器、第三方 plugin 三條 production 供應鏈納入既有 artifact trust 框架的判讀">LLM Deployment 供應鏈完整性&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Model card 的核心概念是「模型發布時附帶的 metadata 文件、列出模型的來源、訓練資料、預期用途、能力上限、已知限制跟授權條款」。Hugging Face 上每個 model repo 的 <code>README.md</code> 就是 model card；它是個人 dev 跟 production 場景下判讀「該不該用這個模型」的最主要資訊來源。</p>
<h2 id="概念位置">概念位置</h2>
<p>典型的 model card 包含哪些區段（依平台跟模型而異）：</p>
<table>
  <thead>
      <tr>
          <th>區段</th>
          <th>內容</th>
          <th>對應的判讀</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>基本資訊</td>
          <td>模型名稱、參數量、架構、發布者</td>
          <td>確認是哪個 organization 發布</td>
      </tr>
      <tr>
          <td>Training data</td>
          <td>訓練語料的來源、規模、語言分布</td>
          <td>評估模型在自己語言 / 任務的適配性</td>
      </tr>
      <tr>
          <td>Intended use</td>
          <td>預期用途、適合的應用場景</td>
          <td>判讀模型是否符合自己工作流</td>
      </tr>
      <tr>
          <td>Out-of-scope use</td>
          <td>不適合的用途、已知不擅長的任務</td>
          <td>避免誤用</td>
      </tr>
      <tr>
          <td>Bias、ethical considerations</td>
          <td>已知偏見、敏感議題的回應傾向</td>
          <td>production 場景的合規評估</td>
      </tr>
      <tr>
          <td>Benchmark</td>
          <td>在公開 benchmark 上的分數</td>
          <td>跟其他模型對比</td>
      </tr>
      <tr>
          <td>License</td>
          <td>模型權重的使用授權</td>
          <td>商用前必看</td>
      </tr>
      <tr>
          <td>Quantization 版本</td>
          <td>該 repo 提供哪些量化版本</td>
          <td>選對應 <a href="/blog/llm/knowledge-cards/gguf/" data-link-title="GGUF" data-link-desc="llama.cpp 生態定義的模型權重格式：把權重、tokenizer、metadata 打包成單一檔案">GGUF</a> 版本</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p><strong>事實查核註</strong>：Hugging Face 推動 Model Card 規範跟 <a href="https://github.com/huggingface/hub-docs">Model Card Toolkit</a>、但實際填寫品質依 organization 變化、部分 repo 的 model card 內容很簡略、不能 100% 依賴。引用前以該 repo 當前內容為準。</p></blockquote>
<h2 id="設計責任">設計責任</h2>
<p>理解 model card 後可以解釋兩個現象：為什麼選模型不能只看名字（同個 base model 的不同 fine-tune 版本能力差很多）、為什麼商用前要看 license（Llama Community License、Apache 2.0、MIT 等差異大）。</p>
<p>實務上選模型時、model card 是第一閱讀對象、其他資訊（社群評測、benchmark leaderboard）作為交叉驗證；引用模型時應該明確記下「base model + fine-tune 變體 + 量化版本」三層。詳見 <a href="/blog/llm/06-security/model-supply-chain-trust/" data-link-title="6.0 模型供應鏈與信任邊界" data-link-desc="個人 dev 用本地 LLM 時的模型權重來源信任：GGUF 完整性、Hugging Face / Ollama registry 信任、量化版本污染、檔案完整性檢查">6.0 模型供應鏈與信任邊界</a> 跟 <a href="/blog/backend/07-security-data-protection/llm-deployment-supply-chain/" data-link-title="LLM Deployment 供應鏈完整性" data-link-desc="把 LLM 模型權重、推論伺服器、第三方 plugin 三條 production 供應鏈納入既有 artifact trust 框架的判讀">LLM Deployment 供應鏈完整性</a>。</p>
]]></content:encoded></item><item><title>Model Tag</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/model-tag/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/model-tag/</guid><description>&lt;p>Model Tag 的核心概念是「推論伺服器用來定位特定模型版本的字串 key」。同一個模型家族（例如 Gemma 4）會被切出十幾個 tag、每個 tag 對應不同的參數量、訓練變體與&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">量化&lt;/a>等級、使用者用 tag 在 CLI 或 API 中指定要載入哪一份權重。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Model tag 是介面層跟&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/inference-server/" data-link-title="Inference Server" data-link-desc="載入模型權重、處理 prompt、產生 token 的常駐 process">推論伺服器&lt;/a>之間的識別碼、形式由各個伺服器各自定義。Ollama 用 &lt;code>family:size-variant-quantization&lt;/code> 的單行字串、LM Studio 用 Hugging Face 完整檔名、llama.cpp 直接用 &lt;code>.gguf&lt;/code> 檔路徑。同一份模型權重在不同伺服器有不同 tag 字串、但指向的底層&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>權重可以是同一份。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>Ollama 的 tag 結構：&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>&lt;code>gemma4:e4b&lt;/code>&lt;/td>
 &lt;td>Gemma 4、E4B（edge dense）、預設量化&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>gemma4:31b-instruct-q5_K_M&lt;/code>&lt;/td>
 &lt;td>Gemma 4、31B、instruct-tuned、Q5_K_M 量化&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>gemma4:31b-coding-mtp-bf16&lt;/code>&lt;/td>
 &lt;td>Gemma 4、31B、coding 特化、含 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mtp/" data-link-title="Multi-Token Prediction (MTP)" data-link-desc="Google 為 Gemma 系列釋出的 speculative decoding 工程化實作">MTP&lt;/a> drafter&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>qwen3-coder:30b&lt;/code>&lt;/td>
 &lt;td>Qwen3-Coder、30B 參數、預設量化&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>llama3.3:70b-instruct-q4_K_M&lt;/code>&lt;/td>
 &lt;td>Llama 3.3、70B、instruct、Q4_K_M&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>四個欄位裡、&lt;code>size&lt;/code> 直接決定記憶體佔用、&lt;code>variant&lt;/code>（instruct / coding / base）決定模型適合的任務型態、&lt;code>quantization&lt;/code> 影響品質跟記憶體取捨。Tag 中省略某些欄位時、伺服器用該欄位的預設值（通常是「常用組合」）。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>選 tag 時要看三件事：先看 &lt;code>size&lt;/code> 確認模型塞得進記憶體（對照&lt;a href="https://tarrragon.github.io/blog/llm/00-foundations/hardware-memory-budget/" data-link-title="0.5 Apple Silicon 記憶體預算" data-link-desc="記憶體決定能跑什麼，Q4 量化下的可運作模型對照與系統保留">硬體記憶體預算&lt;/a>）、再看 &lt;code>variant&lt;/code> 確認用途匹配（寫 code 要選 &lt;code>instruct&lt;/code> / &lt;code>coding&lt;/code> 變體、避免 base model 的隨機接龍行為）、最後看 &lt;code>quantization&lt;/code> 決定品質 / 記憶體甜蜜點。完整可用 tag 在各伺服器的 model registry（Ollama 在 &lt;a href="https://ollama.com/library">ollama.com/library&lt;/a>、LM Studio 在 Discover 分頁）。&lt;/p></description><content:encoded><![CDATA[<p>Model Tag 的核心概念是「推論伺服器用來定位特定模型版本的字串 key」。同一個模型家族（例如 Gemma 4）會被切出十幾個 tag、每個 tag 對應不同的參數量、訓練變體與<a href="/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">量化</a>等級、使用者用 tag 在 CLI 或 API 中指定要載入哪一份權重。</p>
<h2 id="概念位置">概念位置</h2>
<p>Model tag 是介面層跟<a href="/blog/llm/knowledge-cards/inference-server/" data-link-title="Inference Server" data-link-desc="載入模型權重、處理 prompt、產生 token 的常駐 process">推論伺服器</a>之間的識別碼、形式由各個伺服器各自定義。Ollama 用 <code>family:size-variant-quantization</code> 的單行字串、LM Studio 用 Hugging Face 完整檔名、llama.cpp 直接用 <code>.gguf</code> 檔路徑。同一份模型權重在不同伺服器有不同 tag 字串、但指向的底層<a href="/blog/llm/knowledge-cards/gguf/" data-link-title="GGUF" data-link-desc="llama.cpp 生態定義的模型權重格式：把權重、tokenizer、metadata 打包成單一檔案">GGUF</a>權重可以是同一份。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>Ollama 的 tag 結構：</p>
<table>
  <thead>
      <tr>
          <th>範例</th>
          <th>拆解</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>gemma4:e4b</code></td>
          <td>Gemma 4、E4B（edge dense）、預設量化</td>
      </tr>
      <tr>
          <td><code>gemma4:31b-instruct-q5_K_M</code></td>
          <td>Gemma 4、31B、instruct-tuned、Q5_K_M 量化</td>
      </tr>
      <tr>
          <td><code>gemma4:31b-coding-mtp-bf16</code></td>
          <td>Gemma 4、31B、coding 特化、含 <a href="/blog/llm/knowledge-cards/mtp/" data-link-title="Multi-Token Prediction (MTP)" data-link-desc="Google 為 Gemma 系列釋出的 speculative decoding 工程化實作">MTP</a> drafter</td>
      </tr>
      <tr>
          <td><code>qwen3-coder:30b</code></td>
          <td>Qwen3-Coder、30B 參數、預設量化</td>
      </tr>
      <tr>
          <td><code>llama3.3:70b-instruct-q4_K_M</code></td>
          <td>Llama 3.3、70B、instruct、Q4_K_M</td>
      </tr>
  </tbody>
</table>
<p>四個欄位裡、<code>size</code> 直接決定記憶體佔用、<code>variant</code>（instruct / coding / base）決定模型適合的任務型態、<code>quantization</code> 影響品質跟記憶體取捨。Tag 中省略某些欄位時、伺服器用該欄位的預設值（通常是「常用組合」）。</p>
<h2 id="設計責任">設計責任</h2>
<p>選 tag 時要看三件事：先看 <code>size</code> 確認模型塞得進記憶體（對照<a href="/blog/llm/00-foundations/hardware-memory-budget/" data-link-title="0.5 Apple Silicon 記憶體預算" data-link-desc="記憶體決定能跑什麼，Q4 量化下的可運作模型對照與系統保留">硬體記憶體預算</a>）、再看 <code>variant</code> 確認用途匹配（寫 code 要選 <code>instruct</code> / <code>coding</code> 變體、避免 base model 的隨機接龍行為）、最後看 <code>quantization</code> 決定品質 / 記憶體甜蜜點。完整可用 tag 在各伺服器的 model registry（Ollama 在 <a href="https://ollama.com/library">ollama.com/library</a>、LM Studio 在 Discover 分頁）。</p>
]]></content:encoded></item><item><title>MoE CPU 卸載</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/moe-cpu-offload/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/moe-cpu-offload/</guid><description>&lt;p>MoE CPU 卸載的核心概念是「&lt;a href="https://en.wikipedia.org/wiki/Mixture_of_experts">Mixture-of-Experts&lt;/a> 模型每個 token 只啟用少數專家、把不活躍的專家權重留在系統 RAM、用到再走 PCIe 拉回 GPU」。它讓 16GB VRAM 卡能載入 30B / 70B 等級的 MoE 模型、是 &lt;a href="https://tarrragon.github.io/blog/llm/05-discrete-gpu/" data-link-title="模組五：Windows / Linux &amp;#43; 獨立 GPU" data-link-desc="消費級 PC（Windows / Linux &amp;#43; NVIDIA / AMD 獨立 GPU）跑本地 LLM 的硬體判讀、MoE CPU 卸載、KV cache 量化與 llama.cpp 調參">獨立 GPU 場景&lt;/a> 相對 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/unified-memory/" data-link-title="Unified Memory Architecture" data-link-desc="Apple Silicon 讓 CPU / GPU / NE 共用同一塊記憶體：跑大模型的優勢來源">統一記憶體&lt;/a> 場景多出的工程選項。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>MoE 卸載屬於「推論時的權重位置管理」、跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">量化&lt;/a> 屬於「權重精度壓縮」是兩個獨立維度、可以疊加（如 30B MoE Q4 + 卸載部分層、模型精度跟記憶體位置同時被處理）。它跟 &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> 量化是 PC 場景常一起使用的兩個工具：卸載騰出 VRAM、KV cache 量化讓騰出的 VRAM 拿去開大 &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>。&lt;/p>
&lt;p>在 llama.cpp 中、對應的旗標是 &lt;code>--n-cpu-moe &amp;lt;N&amp;gt;&lt;/code>、把 N 層的 MoE 專家權重保留在 CPU 記憶體。例如 &lt;code>--n-cpu-moe 30&lt;/code> 表示 30 層的專家層留 RAM、其餘走 GPU。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>以 Qwen3-30B-A3B Q4_K_M（模型體積 10 GB 級、active parameter 約 3B 等級）為例、不同卸載策略下記憶體分布與生字速度的相對方向（具體數值依驅動、CUDA backend、模型版本、PCIe 版本變化、本表用於說明趨勢、不是嚴格 benchmark）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>配置&lt;/th>
 &lt;th>卸載策略&lt;/th>
 &lt;th>VRAM 佔用方向&lt;/th>
 &lt;th>RAM 佔用方向&lt;/th>
 &lt;th>生字速度方向（同卡比較）&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>全載 VRAM&lt;/td>
 &lt;td>&lt;code>--n-cpu-moe 0&lt;/code>&lt;/td>
 &lt;td>接近 VRAM 上限&lt;/td>
 &lt;td>系統正常&lt;/td>
 &lt;td>上限取決於 VRAM 頻寬&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>中度卸載&lt;/td>
 &lt;td>&lt;code>--n-cpu-moe ~20&lt;/code>&lt;/td>
 &lt;td>顯著下降&lt;/td>
 &lt;td>上升至 10 GB 級&lt;/td>
 &lt;td>較全載小幅下降&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>重度卸載&lt;/td>
 &lt;td>&lt;code>--n-cpu-moe ~30&lt;/code>&lt;/td>
 &lt;td>大幅下降&lt;/td>
 &lt;td>上升較多&lt;/td>
 &lt;td>較全載明顯下降&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>極限卸載&lt;/td>
 &lt;td>&lt;code>--n-cpu-moe ~40&lt;/code>&lt;/td>
 &lt;td>接近最低&lt;/td>
 &lt;td>上升最多&lt;/td>
 &lt;td>較全載大幅下降&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：上表是趨勢示意、不是經本文系統實測的數值。實際數值依顯卡型號、PCIe 版本、CUDA backend、GGUF 量化版本、&lt;code>-ngl&lt;/code> 設定、context 長度與 batch size 變化、建議用 &lt;code>llama-bench&lt;/code> 或實際工作流校準。&lt;/p>&lt;/blockquote>
&lt;p>社群常見的觀察是：MoE 卸載對生字速度的衰減幅度、相對於「Dense 模型把同樣比例的層卸載到 CPU」較小、原因是 MoE 每 token 只啟用少數專家、PCIe 上的權重傳輸量也較少；具體幅度依模型架構（active parameter 比例、專家數）變化。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 MoE 卸載後、可以解釋三個 PC 場景的現象：16GB VRAM 卡能載入 30B 級 MoE 模型（透過部分卸載而非全載 VRAM）、PC 場景 64GB RAM 相對 32GB 在 MoE 卸載空間上明顯更寬裕（可卸載更多層）、Mac 統一記憶體場景較少需要「卸載」這個概念（VRAM 跟 RAM 共用、不需要在兩個區域之間搬資料）。&lt;/p></description><content:encoded><![CDATA[<p>MoE CPU 卸載的核心概念是「<a href="https://en.wikipedia.org/wiki/Mixture_of_experts">Mixture-of-Experts</a> 模型每個 token 只啟用少數專家、把不活躍的專家權重留在系統 RAM、用到再走 PCIe 拉回 GPU」。它讓 16GB VRAM 卡能載入 30B / 70B 等級的 MoE 模型、是 <a href="/blog/llm/05-discrete-gpu/" data-link-title="模組五：Windows / Linux &#43; 獨立 GPU" data-link-desc="消費級 PC（Windows / Linux &#43; NVIDIA / AMD 獨立 GPU）跑本地 LLM 的硬體判讀、MoE CPU 卸載、KV cache 量化與 llama.cpp 調參">獨立 GPU 場景</a> 相對 <a href="/blog/llm/knowledge-cards/unified-memory/" data-link-title="Unified Memory Architecture" data-link-desc="Apple Silicon 讓 CPU / GPU / NE 共用同一塊記憶體：跑大模型的優勢來源">統一記憶體</a> 場景多出的工程選項。</p>
<h2 id="概念位置">概念位置</h2>
<p>MoE 卸載屬於「推論時的權重位置管理」、跟 <a href="/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">量化</a> 屬於「權重精度壓縮」是兩個獨立維度、可以疊加（如 30B MoE Q4 + 卸載部分層、模型精度跟記憶體位置同時被處理）。它跟 <a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 量化是 PC 場景常一起使用的兩個工具：卸載騰出 VRAM、KV cache 量化讓騰出的 VRAM 拿去開大 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a>。</p>
<p>在 llama.cpp 中、對應的旗標是 <code>--n-cpu-moe &lt;N&gt;</code>、把 N 層的 MoE 專家權重保留在 CPU 記憶體。例如 <code>--n-cpu-moe 30</code> 表示 30 層的專家層留 RAM、其餘走 GPU。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>以 Qwen3-30B-A3B Q4_K_M（模型體積 10 GB 級、active parameter 約 3B 等級）為例、不同卸載策略下記憶體分布與生字速度的相對方向（具體數值依驅動、CUDA backend、模型版本、PCIe 版本變化、本表用於說明趨勢、不是嚴格 benchmark）：</p>
<table>
  <thead>
      <tr>
          <th>配置</th>
          <th>卸載策略</th>
          <th>VRAM 佔用方向</th>
          <th>RAM 佔用方向</th>
          <th>生字速度方向（同卡比較）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>全載 VRAM</td>
          <td><code>--n-cpu-moe 0</code></td>
          <td>接近 VRAM 上限</td>
          <td>系統正常</td>
          <td>上限取決於 VRAM 頻寬</td>
      </tr>
      <tr>
          <td>中度卸載</td>
          <td><code>--n-cpu-moe ~20</code></td>
          <td>顯著下降</td>
          <td>上升至 10 GB 級</td>
          <td>較全載小幅下降</td>
      </tr>
      <tr>
          <td>重度卸載</td>
          <td><code>--n-cpu-moe ~30</code></td>
          <td>大幅下降</td>
          <td>上升較多</td>
          <td>較全載明顯下降</td>
      </tr>
      <tr>
          <td>極限卸載</td>
          <td><code>--n-cpu-moe ~40</code></td>
          <td>接近最低</td>
          <td>上升最多</td>
          <td>較全載大幅下降</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p><strong>事實查核註</strong>：上表是趨勢示意、不是經本文系統實測的數值。實際數值依顯卡型號、PCIe 版本、CUDA backend、GGUF 量化版本、<code>-ngl</code> 設定、context 長度與 batch size 變化、建議用 <code>llama-bench</code> 或實際工作流校準。</p></blockquote>
<p>社群常見的觀察是：MoE 卸載對生字速度的衰減幅度、相對於「Dense 模型把同樣比例的層卸載到 CPU」較小、原因是 MoE 每 token 只啟用少數專家、PCIe 上的權重傳輸量也較少；具體幅度依模型架構（active parameter 比例、專家數）變化。</p>
<h2 id="設計責任">設計責任</h2>
<p>理解 MoE 卸載後、可以解釋三個 PC 場景的現象：16GB VRAM 卡能載入 30B 級 MoE 模型（透過部分卸載而非全載 VRAM）、PC 場景 64GB RAM 相對 32GB 在 MoE 卸載空間上明顯更寬裕（可卸載更多層）、Mac 統一記憶體場景較少需要「卸載」這個概念（VRAM 跟 RAM 共用、不需要在兩個區域之間搬資料）。</p>
<p>設定 PC 推論伺服器時、卸載層數通常跟 KV cache 量化、context 長度、併發數一起調：先估算想開的 context 長度、扣掉 KV cache 體積算出 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>
]]></content:encoded></item><item><title>MTEB</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/mteb-benchmark/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/mteb-benchmark/</guid><description>&lt;p>MTEB（Massive Text Embedding Benchmark、Muennighoff et al., 2022）的核心概念是「&lt;strong>評估 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model&lt;/a> 跨多種任務通用能力的標準 benchmark&lt;/strong>」。覆蓋 8 大類任務（classification、clustering、pair classification、reranking、retrieval、STS、summarization、bitext mining）、56 個 dataset、112 種語言。是現在挑選 embedding model 最常用的 leaderboard。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>MTEB 的 8 大任務類別：&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>Classification&lt;/td>
 &lt;td>用 embedding 做下游分類（如情感分析）&lt;/td>
 &lt;td>分類 accuracy&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Clustering&lt;/td>
 &lt;td>把相似 doc 聚到一起&lt;/td>
 &lt;td>V-measure、NMI&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Pair classification&lt;/td>
 &lt;td>判斷兩段文字「相關 / 不相關」&lt;/td>
 &lt;td>F1、AP&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Reranking&lt;/strong>&lt;/td>
 &lt;td>對 retrieval 結果用 embedding 重新排序&lt;/td>
 &lt;td>mAP、MRR&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Retrieval&lt;/strong>&lt;/td>
 &lt;td>給 query、從大量 corpus 找相關 doc&lt;/td>
 &lt;td>nDCG@10、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-recall/" data-link-title="Retrieval Recall" data-link-desc="衡量 RAG 檢索是否把應該命中的文件或 chunk 放進 top-k 結果，是 component-level eval 的核心指標">Recall@k&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>STS（Semantic Textual Similarity）&lt;/td>
 &lt;td>預測句對相似度（連續分數）&lt;/td>
 &lt;td>Spearman correlation&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Summarization&lt;/td>
 &lt;td>embedding-based summary quality&lt;/td>
 &lt;td>Correlation with human rating&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Bitext mining&lt;/td>
 &lt;td>跨語言找翻譯對&lt;/td>
 &lt;td>F1&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>對寫 code / RAG 場景最相關&lt;/strong>：Retrieval、Reranking 兩類（粗體）。其他類別反映通用能力、但不直接影響 RAG 應用品質。&lt;/p>
&lt;p>主流 embedding model 在 MTEB Retrieval 的代表性能（2026/5 估計、會持續變動）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>模型&lt;/th>
 &lt;th>模型大小&lt;/th>
 &lt;th>MTEB Retrieval avg&lt;/th>
 &lt;th>適合場景&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>BAAI/bge-large-en-v1.5&lt;/td>
 &lt;td>~335M&lt;/td>
 &lt;td>~55&lt;/td>
 &lt;td>開源通用、英文 retrieval 主力&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>nomic-embed-text-v1.5&lt;/td>
 &lt;td>~137M&lt;/td>
 &lt;td>~52&lt;/td>
 &lt;td>開源、小巧、Ollama 內建&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>jina-embeddings-v3&lt;/td>
 &lt;td>~570M&lt;/td>
 &lt;td>~58&lt;/td>
 &lt;td>開源、多語、code 友善&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>mxbai-embed-large-v1&lt;/td>
 &lt;td>~335M&lt;/td>
 &lt;td>~55&lt;/td>
 &lt;td>開源通用&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>OpenAI text-embedding-3-large&lt;/td>
 &lt;td>API only&lt;/td>
 &lt;td>~64&lt;/td>
 &lt;td>雲端旗艦&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>voyage-3&lt;/td>
 &lt;td>API only&lt;/td>
 &lt;td>~62&lt;/td>
 &lt;td>雲端、Anthropic 推薦&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：MTEB 數字依模型版本、評估配置變動、上述為 2026/5 大致排名、引用前以 &lt;a href="https://huggingface.co/spaces/mteb/leaderboard">MTEB Leaderboard&lt;/a> 當前狀態為準。&lt;/p>&lt;/blockquote>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 embedding model 比較看到「MTEB score」就是這 benchmark。寫 code / RAG 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>看 Retrieval 子分數、不是 overall&lt;/strong>：MTEB overall 含 8 類、跟 RAG 場景關係最大的是 Retrieval 子分；通用 retrieval 分數高、reranking 分數高、就值得試&lt;/li>
&lt;li>&lt;strong>跟自己 domain 對齊&lt;/strong>：MTEB 多為通用語料、自己 domain（如 code、medical、legal）可能跟 MTEB 落差大；in-domain benchmark 比 MTEB 更重要&lt;/li>
&lt;li>&lt;strong>大小 / 速度 / 品質 trade-off&lt;/strong>：bge-large（335M）vs nomic-embed（137M）、後者跑得快、適合本地 RAG；前者品質略高、適合雲端或 latency 不敏感場景&lt;/li>
&lt;li>&lt;strong>MTEB 高分不代表「適合你」&lt;/strong>：高分模型可能是 instruction-tuned embedding（query 需要加特定前綴）、用法跟簡單模型不同、要看 model card&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>MTEB（Massive Text Embedding Benchmark、Muennighoff et al., 2022）的核心概念是「<strong>評估 <a href="/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model</a> 跨多種任務通用能力的標準 benchmark</strong>」。覆蓋 8 大類任務（classification、clustering、pair classification、reranking、retrieval、STS、summarization、bitext mining）、56 個 dataset、112 種語言。是現在挑選 embedding model 最常用的 leaderboard。</p>
<h2 id="概念位置">概念位置</h2>
<p>MTEB 的 8 大任務類別：</p>
<table>
  <thead>
      <tr>
          <th>類別</th>
          <th>任務本質</th>
          <th>衡量</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Classification</td>
          <td>用 embedding 做下游分類（如情感分析）</td>
          <td>分類 accuracy</td>
      </tr>
      <tr>
          <td>Clustering</td>
          <td>把相似 doc 聚到一起</td>
          <td>V-measure、NMI</td>
      </tr>
      <tr>
          <td>Pair classification</td>
          <td>判斷兩段文字「相關 / 不相關」</td>
          <td>F1、AP</td>
      </tr>
      <tr>
          <td><strong>Reranking</strong></td>
          <td>對 retrieval 結果用 embedding 重新排序</td>
          <td>mAP、MRR</td>
      </tr>
      <tr>
          <td><strong>Retrieval</strong></td>
          <td>給 query、從大量 corpus 找相關 doc</td>
          <td>nDCG@10、<a href="/blog/llm/knowledge-cards/retrieval-recall/" data-link-title="Retrieval Recall" data-link-desc="衡量 RAG 檢索是否把應該命中的文件或 chunk 放進 top-k 結果，是 component-level eval 的核心指標">Recall@k</a></td>
      </tr>
      <tr>
          <td>STS（Semantic Textual Similarity）</td>
          <td>預測句對相似度（連續分數）</td>
          <td>Spearman correlation</td>
      </tr>
      <tr>
          <td>Summarization</td>
          <td>embedding-based summary quality</td>
          <td>Correlation with human rating</td>
      </tr>
      <tr>
          <td>Bitext mining</td>
          <td>跨語言找翻譯對</td>
          <td>F1</td>
      </tr>
  </tbody>
</table>
<p><strong>對寫 code / RAG 場景最相關</strong>：Retrieval、Reranking 兩類（粗體）。其他類別反映通用能力、但不直接影響 RAG 應用品質。</p>
<p>主流 embedding model 在 MTEB Retrieval 的代表性能（2026/5 估計、會持續變動）：</p>
<table>
  <thead>
      <tr>
          <th>模型</th>
          <th>模型大小</th>
          <th>MTEB Retrieval avg</th>
          <th>適合場景</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>BAAI/bge-large-en-v1.5</td>
          <td>~335M</td>
          <td>~55</td>
          <td>開源通用、英文 retrieval 主力</td>
      </tr>
      <tr>
          <td>nomic-embed-text-v1.5</td>
          <td>~137M</td>
          <td>~52</td>
          <td>開源、小巧、Ollama 內建</td>
      </tr>
      <tr>
          <td>jina-embeddings-v3</td>
          <td>~570M</td>
          <td>~58</td>
          <td>開源、多語、code 友善</td>
      </tr>
      <tr>
          <td>mxbai-embed-large-v1</td>
          <td>~335M</td>
          <td>~55</td>
          <td>開源通用</td>
      </tr>
      <tr>
          <td>OpenAI text-embedding-3-large</td>
          <td>API only</td>
          <td>~64</td>
          <td>雲端旗艦</td>
      </tr>
      <tr>
          <td>voyage-3</td>
          <td>API only</td>
          <td>~62</td>
          <td>雲端、Anthropic 推薦</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p><strong>事實查核註</strong>：MTEB 數字依模型版本、評估配置變動、上述為 2026/5 大致排名、引用前以 <a href="https://huggingface.co/spaces/mteb/leaderboard">MTEB Leaderboard</a> 當前狀態為準。</p></blockquote>
<h2 id="設計責任">設計責任</h2>
<p>讀 embedding model 比較看到「MTEB score」就是這 benchmark。寫 code / RAG 場景的判讀：</p>
<ol>
<li><strong>看 Retrieval 子分數、不是 overall</strong>：MTEB overall 含 8 類、跟 RAG 場景關係最大的是 Retrieval 子分；通用 retrieval 分數高、reranking 分數高、就值得試</li>
<li><strong>跟自己 domain 對齊</strong>：MTEB 多為通用語料、自己 domain（如 code、medical、legal）可能跟 MTEB 落差大；in-domain benchmark 比 MTEB 更重要</li>
<li><strong>大小 / 速度 / 品質 trade-off</strong>：bge-large（335M）vs nomic-embed（137M）、後者跑得快、適合本地 RAG；前者品質略高、適合雲端或 latency 不敏感場景</li>
<li><strong>MTEB 高分不代表「適合你」</strong>：高分模型可能是 instruction-tuned embedding（query 需要加特定前綴）、用法跟簡單模型不同、要看 model card</li>
</ol>
]]></content:encoded></item><item><title>Multi-Head Attention</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/multi-head-attention/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/multi-head-attention/</guid><description>&lt;p>Multi-Head Attention（MHA、多頭注意力）的核心概念是「把 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/self-attention/" data-link-title="Self-Attention" data-link-desc="Q / K / V 都從同一個 sequence 投影出來的 attention、Transformer 的標誌性設計">self-attention&lt;/a> 的 Q/K/V 投影切成多個獨立的 &lt;strong>head&lt;/strong>、各自算 attention、最後再 concat 起來」。直覺：每個 head 可以學會關注不同類型的關係（語法 / 語意 / 位置 / 共指 etc.）、比單一 attention 表達能力強。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>MHA 的計算結構：&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">輸入 hidden state（dim = 4096）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓ 投影成 Q/K/V、每個切成 h 個 head（如 h=32、每個 head 128 維）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">Head 1：Q_1、K_1、V_1 → attention_1（128 維）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">Head 2：Q_2、K_2、V_2 → attention_2
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">Head h：Q_h、K_h、V_h → attention_h
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> ↓ concat 所有 head 輸出（h × 128 = 4096）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl"> ↓ output projection（4096 → 4096）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">9&lt;/span>&lt;span class="cl">最終輸出&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>多頭變體：MHA → GQA → MLA 是 KV cache 體積壓縮的演化方向。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>變體&lt;/th>
 &lt;th>Q head 數&lt;/th>
 &lt;th>K/V head 數&lt;/th>
 &lt;th>KV cache 體積&lt;/th>
 &lt;th>出現在&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>MHA（Multi-Head Attention）&lt;/td>
 &lt;td>h&lt;/td>
 &lt;td>h&lt;/td>
 &lt;td>100%（基準）&lt;/td>
 &lt;td>原始 Transformer、GPT-3、Llama 1&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>MQA（Multi-Query Attention）&lt;/td>
 &lt;td>h&lt;/td>
 &lt;td>1（所有 head 共用）&lt;/td>
 &lt;td>1/h&lt;/td>
 &lt;td>PaLM、Falcon&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>GQA（Grouped-Query Attention）&lt;/td>
 &lt;td>h&lt;/td>
 &lt;td>h/g（每 g 個 Q head 共用一組 K/V）&lt;/td>
 &lt;td>1/g&lt;/td>
 &lt;td>Llama 2 / 3、Mistral、Gemma&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>MLA（Multi-head Latent Attention）&lt;/td>
 &lt;td>h&lt;/td>
 &lt;td>用 latent 壓縮再展開&lt;/td>
 &lt;td>更激進壓縮&lt;/td>
 &lt;td>DeepSeek-V2 / V3&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 model card 看到 &lt;code>num_attention_heads: 32&lt;/code>、&lt;code>num_key_value_heads: 8&lt;/code> 等就是 MHA / GQA 設定（Q=32、K/V=8 表示 GQA、g=4）。寫 code 場景的意涵：GQA / MLA 的 &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 / 高併發場景更友善、是現代 LLM 大量採用的設計。&lt;/p></description><content:encoded><![CDATA[<p>Multi-Head Attention（MHA、多頭注意力）的核心概念是「把 <a href="/blog/llm/knowledge-cards/self-attention/" data-link-title="Self-Attention" data-link-desc="Q / K / V 都從同一個 sequence 投影出來的 attention、Transformer 的標誌性設計">self-attention</a> 的 Q/K/V 投影切成多個獨立的 <strong>head</strong>、各自算 attention、最後再 concat 起來」。直覺：每個 head 可以學會關注不同類型的關係（語法 / 語意 / 位置 / 共指 etc.）、比單一 attention 表達能力強。</p>
<h2 id="概念位置">概念位置</h2>
<p>MHA 的計算結構：</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">輸入 hidden state（dim = 4096）
</span></span><span class="line"><span class="ln">2</span><span class="cl">   ↓ 投影成 Q/K/V、每個切成 h 個 head（如 h=32、每個 head 128 維）
</span></span><span class="line"><span class="ln">3</span><span class="cl">Head 1：Q_1、K_1、V_1 → attention_1（128 維）
</span></span><span class="line"><span class="ln">4</span><span class="cl">Head 2：Q_2、K_2、V_2 → attention_2
</span></span><span class="line"><span class="ln">5</span><span class="cl">...
</span></span><span class="line"><span class="ln">6</span><span class="cl">Head h：Q_h、K_h、V_h → attention_h
</span></span><span class="line"><span class="ln">7</span><span class="cl">   ↓ concat 所有 head 輸出（h × 128 = 4096）
</span></span><span class="line"><span class="ln">8</span><span class="cl">   ↓ output projection（4096 → 4096）
</span></span><span class="line"><span class="ln">9</span><span class="cl">最終輸出</span></span></code></pre></div><p>多頭變體：MHA → GQA → MLA 是 KV cache 體積壓縮的演化方向。</p>
<table>
  <thead>
      <tr>
          <th>變體</th>
          <th>Q head 數</th>
          <th>K/V head 數</th>
          <th>KV cache 體積</th>
          <th>出現在</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>MHA（Multi-Head Attention）</td>
          <td>h</td>
          <td>h</td>
          <td>100%（基準）</td>
          <td>原始 Transformer、GPT-3、Llama 1</td>
      </tr>
      <tr>
          <td>MQA（Multi-Query Attention）</td>
          <td>h</td>
          <td>1（所有 head 共用）</td>
          <td>1/h</td>
          <td>PaLM、Falcon</td>
      </tr>
      <tr>
          <td>GQA（Grouped-Query Attention）</td>
          <td>h</td>
          <td>h/g（每 g 個 Q head 共用一組 K/V）</td>
          <td>1/g</td>
          <td>Llama 2 / 3、Mistral、Gemma</td>
      </tr>
      <tr>
          <td>MLA（Multi-head Latent Attention）</td>
          <td>h</td>
          <td>用 latent 壓縮再展開</td>
          <td>更激進壓縮</td>
          <td>DeepSeek-V2 / V3</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 model card 看到 <code>num_attention_heads: 32</code>、<code>num_key_value_heads: 8</code> 等就是 MHA / GQA 設定（Q=32、K/V=8 表示 GQA、g=4）。寫 code 場景的意涵：GQA / MLA 的 <a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 體積小、長 context / 高併發場景更友善、是現代 LLM 大量採用的設計。</p>
]]></content:encoded></item><item><title>Multimodal Fusion</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/multimodal-fusion/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/multimodal-fusion/</guid><description>&lt;p>Multimodal fusion（多模態融合）的核心概念是「&lt;strong>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/vlm/" data-link-title="VLM（Vision-Language Model）" data-link-desc="同時吃圖片 &amp;#43; 文字輸入、產生文字輸出的 LLM 變體、coding 工作流中處理截圖 / 設計稿 / UI debug 的基底">VLM&lt;/a> 把 vision encoder 產出的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/image-token/" data-link-title="Image Token" data-link-desc="VLM 把圖片轉成「對 Transformer 而言跟 text token 同質」的向量、計入 context window 預算">image token&lt;/a> 跟 text token 結合進 LLM 的設計方式&lt;/strong>」。三條主流路線：early fusion（image token 跟 text token 串成同 sequence）、cross-attention（separate stream、attention 跨流）、native multimodal（單一網路統一處理）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>三種 fusion 方式的對比：&lt;/p>
&lt;h3 id="1-early-fusion最主流">1. Early Fusion（最主流）&lt;/h3>





&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">image → vision encoder → image tokens ─┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ├→ concat 成單一 sequence → 同 LLM Transformer 處理
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">text → tokenizer → text tokens ────────┘&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>&lt;strong>特性&lt;/strong>：image token 跟 text token 在同一個 token sequence、共用 LLM 的 attention / FFN&lt;/li>
&lt;li>&lt;strong>代表&lt;/strong>：LLaVA、Qwen2-VL、Llama 3.2 Vision、Pixtral、GPT-4V 多數變體&lt;/li>
&lt;li>&lt;strong>優點&lt;/strong>：實作簡單、可重用 LLM 的 weight、訓練資料效率高&lt;/li>
&lt;li>&lt;strong>缺點&lt;/strong>：image token 佔 context、長對話 / 多圖時 context budget 吃緊&lt;/li>
&lt;/ul>
&lt;h3 id="2-cross-attentionflamingo-style">2. Cross-Attention（Flamingo-style）&lt;/h3>





&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">image → vision encoder → image features ─┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> │ Cross-attention 層
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">text → tokenizer → tokens → LLM Transformer ──┤ 插在每幾層 Transformer 之間
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> │ Image features 不進 LLM 主流
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">output ←─────────────────────────────────┘&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>&lt;strong>特性&lt;/strong>：image features 不變成 LLM 的 token、透過額外的 cross-attention 層注入&lt;/li>
&lt;li>&lt;strong>代表&lt;/strong>：Flamingo（DeepMind）、Idefics（Hugging Face）、部分 video LLM&lt;/li>
&lt;li>&lt;strong>優點&lt;/strong>：text token sequence 不會被 image 撐大、長文字 + 多圖比較友善&lt;/li>
&lt;li>&lt;strong>缺點&lt;/strong>：架構複雜、訓練難、推論伺服器支援度差&lt;/li>
&lt;/ul>
&lt;h3 id="3-native-multimodalunified-token-space">3. Native Multimodal（unified token space）&lt;/h3>





&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">image → patchify → discrete image tokens（如 VQ-VAE 編碼）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">text → tokenizer → text tokens
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">兩者共用 vocab、同一個 Transformer 從頭訓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">（沒有「分開的 vision encoder」、modality 在 vocab level 統一）&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>&lt;strong>特性&lt;/strong>：架構上「圖跟文字是同一種東西」、共用 vocab&lt;/li>
&lt;li>&lt;strong>代表&lt;/strong>：Chameleon（Meta 研究）、未來 trend&lt;/li>
&lt;li>&lt;strong>優點&lt;/strong>：理論最 clean、跨模態 generation 自然（生圖 + 生文都同個模型）&lt;/li>
&lt;li>&lt;strong>缺點&lt;/strong>：訓練極貴、目前研究階段為主、實用 VLM 仍以 early fusion 為主流&lt;/li>
&lt;/ul>
&lt;h2 id="主流選擇對比">主流選擇對比&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>路線&lt;/th>
 &lt;th>佔比（2026/5）&lt;/th>
 &lt;th>對 coding 場景的影響&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Early fusion&lt;/td>
 &lt;td>~85%&lt;/td>
 &lt;td>Image token 佔 context、要算清楚 context budget&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Cross-attention&lt;/td>
 &lt;td>~10%&lt;/td>
 &lt;td>推論伺服器支援度差、本地跑選項少&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Native multimodal&lt;/td>
 &lt;td>&amp;lt; 5%&lt;/td>
 &lt;td>研究階段、現在不適合 production / 本地工作流&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 VLM paper / blog 看到「early fusion」「LLaVA-style」「Flamingo-style」「cross-attention adapter」就是這分類。寫 code 場景的判讀：&lt;/p></description><content:encoded><![CDATA[<p>Multimodal fusion（多模態融合）的核心概念是「<strong><a href="/blog/llm/knowledge-cards/vlm/" data-link-title="VLM（Vision-Language Model）" data-link-desc="同時吃圖片 &#43; 文字輸入、產生文字輸出的 LLM 變體、coding 工作流中處理截圖 / 設計稿 / UI debug 的基底">VLM</a> 把 vision encoder 產出的 <a href="/blog/llm/knowledge-cards/image-token/" data-link-title="Image Token" data-link-desc="VLM 把圖片轉成「對 Transformer 而言跟 text token 同質」的向量、計入 context window 預算">image token</a> 跟 text token 結合進 LLM 的設計方式</strong>」。三條主流路線：early fusion（image token 跟 text token 串成同 sequence）、cross-attention（separate stream、attention 跨流）、native multimodal（單一網路統一處理）。</p>
<h2 id="概念位置">概念位置</h2>
<p>三種 fusion 方式的對比：</p>
<h3 id="1-early-fusion最主流">1. Early Fusion（最主流）</h3>





<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">image → vision encoder → image tokens ─┐
</span></span><span class="line"><span class="ln">2</span><span class="cl">                                       ├→ concat 成單一 sequence → 同 LLM Transformer 處理
</span></span><span class="line"><span class="ln">3</span><span class="cl">text → tokenizer → text tokens ────────┘</span></span></code></pre></div><ul>
<li><strong>特性</strong>：image token 跟 text token 在同一個 token sequence、共用 LLM 的 attention / FFN</li>
<li><strong>代表</strong>：LLaVA、Qwen2-VL、Llama 3.2 Vision、Pixtral、GPT-4V 多數變體</li>
<li><strong>優點</strong>：實作簡單、可重用 LLM 的 weight、訓練資料效率高</li>
<li><strong>缺點</strong>：image token 佔 context、長對話 / 多圖時 context budget 吃緊</li>
</ul>
<h3 id="2-cross-attentionflamingo-style">2. Cross-Attention（Flamingo-style）</h3>





<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">image → vision encoder → image features ─┐
</span></span><span class="line"><span class="ln">2</span><span class="cl">                                          │ Cross-attention 層
</span></span><span class="line"><span class="ln">3</span><span class="cl">text → tokenizer → tokens → LLM Transformer ──┤  插在每幾層 Transformer 之間
</span></span><span class="line"><span class="ln">4</span><span class="cl">                                          │ Image features 不進 LLM 主流
</span></span><span class="line"><span class="ln">5</span><span class="cl">output ←─────────────────────────────────┘</span></span></code></pre></div><ul>
<li><strong>特性</strong>：image features 不變成 LLM 的 token、透過額外的 cross-attention 層注入</li>
<li><strong>代表</strong>：Flamingo（DeepMind）、Idefics（Hugging Face）、部分 video LLM</li>
<li><strong>優點</strong>：text token sequence 不會被 image 撐大、長文字 + 多圖比較友善</li>
<li><strong>缺點</strong>：架構複雜、訓練難、推論伺服器支援度差</li>
</ul>
<h3 id="3-native-multimodalunified-token-space">3. Native Multimodal（unified token space）</h3>





<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">image → patchify → discrete image tokens（如 VQ-VAE 編碼）
</span></span><span class="line"><span class="ln">2</span><span class="cl">text → tokenizer → text tokens
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">兩者共用 vocab、同一個 Transformer 從頭訓
</span></span><span class="line"><span class="ln">5</span><span class="cl">（沒有「分開的 vision encoder」、modality 在 vocab level 統一）</span></span></code></pre></div><ul>
<li><strong>特性</strong>：架構上「圖跟文字是同一種東西」、共用 vocab</li>
<li><strong>代表</strong>：Chameleon（Meta 研究）、未來 trend</li>
<li><strong>優點</strong>：理論最 clean、跨模態 generation 自然（生圖 + 生文都同個模型）</li>
<li><strong>缺點</strong>：訓練極貴、目前研究階段為主、實用 VLM 仍以 early fusion 為主流</li>
</ul>
<h2 id="主流選擇對比">主流選擇對比</h2>
<table>
  <thead>
      <tr>
          <th>路線</th>
          <th>佔比（2026/5）</th>
          <th>對 coding 場景的影響</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Early fusion</td>
          <td>~85%</td>
          <td>Image token 佔 context、要算清楚 context budget</td>
      </tr>
      <tr>
          <td>Cross-attention</td>
          <td>~10%</td>
          <td>推論伺服器支援度差、本地跑選項少</td>
      </tr>
      <tr>
          <td>Native multimodal</td>
          <td>&lt; 5%</td>
          <td>研究階段、現在不適合 production / 本地工作流</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 VLM paper / blog 看到「early fusion」「LLaVA-style」「Flamingo-style」「cross-attention adapter」就是這分類。寫 code 場景的判讀：</p>
<ol>
<li><strong>本地跑 VLM 多半是 early fusion</strong>：選 Qwen2.5-VL / Llama 3.2 Vision / Gemma 3 Vision 都是這條路線、推論伺服器（llama.cpp、Ollama、LM Studio）都支援</li>
<li><strong>Cross-attention 模型本地跑可能撞牆</strong>：推論伺服器對 Idefics 等 cross-attention 模型支援度差、不一定能跑 GGUF</li>
<li><strong>理解 fusion 影響 token 估算</strong>：early fusion 下「image token = 真的進 context」、cross-attention 下不算進 context window 主流</li>
<li><strong>未來 trend 是 unified</strong>：但現在做 production / 本地工作流不必等、用 early fusion 主流模型即可</li>
</ol>
]]></content:encoded></item><item><title>Needle in a Haystack</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/needle-in-haystack/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/needle-in-haystack/</guid><description>&lt;p>Needle in a Haystack（NIH、大海撈針、Greg Kamradt 2023）的核心概念是「&lt;strong>把一個明確事實（needle）插入長度可變的 context（haystack）的不同位置、測試 LLM 能否在問問題時準確 recall 該事實&lt;/strong>」。是評估 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">long context&lt;/a> 模型實用性的標準 benchmark 之一、跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/lost-in-the-middle/" data-link-title="Lost in the Middle" data-link-desc="LLM 對 long context 中段內容的 attention / recall 顯著低於開頭與結尾的現象">lost-in-the-middle&lt;/a> 對應但側重不同。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>NIH 測試的典型流程：&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">1. 準備 haystack：一份長文（如 Paul Graham essays、技術文件）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">2. 在指定位置（如 50% 處）插入 needle：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> 「The best thing to do in San Francisco is eat a sandwich at Dolores Park.」
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">3. Prompt 模型：「What is the best thing to do in San Francisco?」
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">4. 看模型能否抓出 needle 內容
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">Variables：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">- Context 總長度（1K、4K、16K、64K、128K、1M）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">- Needle 插入位置（0%、10%、25%、50%、75%、90%、100%）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">每個 (length, position) 組合測 N 次、得到 accuracy heatmap&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>跟 lost-in-the-middle 的對比：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>Lost in the middle&lt;/th>
 &lt;th>Needle in haystack&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>衡量的能力&lt;/td>
 &lt;td>對中段內容的整體 attention&lt;/td>
 &lt;td>抓單一事實的 recall&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>任務&lt;/td>
 &lt;td>抓整段邏輯、做推論&lt;/td>
 &lt;td>純 retrieve、不需推論&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>難度&lt;/td>
 &lt;td>高（需理解整段語意）&lt;/td>
 &lt;td>較低（明確 keyword 匹配）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>模型表現&lt;/td>
 &lt;td>中段顯著差&lt;/td>
 &lt;td>通常各位置都接近 100%（強模型）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>判讀意義&lt;/td>
 &lt;td>反映「實用 effective context」&lt;/td>
 &lt;td>反映「lower bound effective context」&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>





&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">典型 NIH heatmap（GPT-4 128K 之類）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">100% |████ ████████████████████████████ ████
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> 80% |████ ████████████████████████████ ████
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> 60% |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> 40% |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> 20% |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> 0 +----+----+----+----+----+----+----+
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> 0% 25% 50% 75% 100%（needle 位置）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> ↑ ↑
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> 開頭強 結尾強
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">NIH heatmap 通常全綠（強模型）、但實用任務（reasoning over long context）就會出現中段塌陷&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 long context 模型 release notes 看到「needle in a haystack: 100%」「pass NIH up to 128K」等聲稱、要區分：&lt;/p></description><content:encoded><![CDATA[<p>Needle in a Haystack（NIH、大海撈針、Greg Kamradt 2023）的核心概念是「<strong>把一個明確事實（needle）插入長度可變的 context（haystack）的不同位置、測試 LLM 能否在問問題時準確 recall 該事實</strong>」。是評估 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">long context</a> 模型實用性的標準 benchmark 之一、跟 <a href="/blog/llm/knowledge-cards/lost-in-the-middle/" data-link-title="Lost in the Middle" data-link-desc="LLM 對 long context 中段內容的 attention / recall 顯著低於開頭與結尾的現象">lost-in-the-middle</a> 對應但側重不同。</p>
<h2 id="概念位置">概念位置</h2>
<p>NIH 測試的典型流程：</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">1. 準備 haystack：一份長文（如 Paul Graham essays、技術文件）
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">2. 在指定位置（如 50% 處）插入 needle：
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">   「The best thing to do in San Francisco is eat a sandwich at Dolores Park.」
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">3. Prompt 模型：「What is the best thing to do in San Francisco?」
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">4. 看模型能否抓出 needle 內容
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">Variables：
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">- Context 總長度（1K、4K、16K、64K、128K、1M）
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">- Needle 插入位置（0%、10%、25%、50%、75%、90%、100%）
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">每個 (length, position) 組合測 N 次、得到 accuracy heatmap</span></span></code></pre></div><p>跟 lost-in-the-middle 的對比：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>Lost in the middle</th>
          <th>Needle in haystack</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>衡量的能力</td>
          <td>對中段內容的整體 attention</td>
          <td>抓單一事實的 recall</td>
      </tr>
      <tr>
          <td>任務</td>
          <td>抓整段邏輯、做推論</td>
          <td>純 retrieve、不需推論</td>
      </tr>
      <tr>
          <td>難度</td>
          <td>高（需理解整段語意）</td>
          <td>較低（明確 keyword 匹配）</td>
      </tr>
      <tr>
          <td>模型表現</td>
          <td>中段顯著差</td>
          <td>通常各位置都接近 100%（強模型）</td>
      </tr>
      <tr>
          <td>判讀意義</td>
          <td>反映「實用 effective context」</td>
          <td>反映「lower bound effective context」</td>
      </tr>
  </tbody>
</table>





<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">典型 NIH heatmap（GPT-4 128K 之類）：
</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">100% |████ ████████████████████████████ ████
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"> 80% |████ ████████████████████████████ ████
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"> 60% |
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"> 40% |
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"> 20% |
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">   0 +----+----+----+----+----+----+----+
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">     0%   25%   50%   75%   100%（needle 位置）
</span></span><span class="line"><span class="ln">10</span><span class="cl">     ↑                                  ↑
</span></span><span class="line"><span class="ln">11</span><span class="cl">     開頭強                             結尾強
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl">NIH heatmap 通常全綠（強模型）、但實用任務（reasoning over long context）就會出現中段塌陷</span></span></code></pre></div><h2 id="設計責任">設計責任</h2>
<p>讀 long context 模型 release notes 看到「needle in a haystack: 100%」「pass NIH up to 128K」等聲稱、要區分：</p>
<ol>
<li><strong>NIH 100% 不代表「能用 128K context」</strong>：NIH 只測單一事實 retrieve、實際 reasoning over long context 仍可能崩</li>
<li><strong>真實任務 benchmark</strong>：<a href="https://github.com/THUDM/LongBench">LongBench</a>、<a href="https://github.com/hsiehjackson/RULER">RULER</a> 等是更貼近實用的 long context evaluation、會暴露 lost-in-the-middle 等問題</li>
<li><strong>本地跑 long context 模型</strong>：先用 NIH 驗證 baseline、再用 RULER / 自己工作流 case 測 effective context</li>
<li><strong>判讀「我的模型實際能用幾 K」</strong>：NIH pass 的長度是上限、實用 effective context 通常是 NIH pass 長度的 1/2 到 1/4</li>
</ol>
]]></content:encoded></item><item><title>NVLink</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/nvlink/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/nvlink/</guid><description>&lt;p>NVLink 的核心概念是「NVIDIA 自家的 GPU 之間高速互連介面、頻寬高於 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/pcie/" data-link-title="PCIe" data-link-desc="PC 上連接 GPU 跟主機板的高速序列匯流排、影響模型載入速度跟 MoE 卸載時的推論吞吐">PCIe&lt;/a>、適合多卡 tensor parallel 場景」。資料中心級 GPU（如 A100 / H100 / H200）普遍支援、消費級 RTX 30 系列部分支援（如 3090）、RTX 40 / 50 系列普遍移除 NVLink、消費級多卡通常只能走 PCIe。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>NVLink 在多卡推論場景的角色：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>tensor parallel&lt;/strong>：把一個 transformer 層的 weight 切到多張卡、每 token 計算時需要卡間同步、卡間頻寬影響直接。&lt;/li>
&lt;li>&lt;strong>pipeline parallel&lt;/strong>：把不同層分到不同卡、卡間需要傳 activation、頻寬要求中等。&lt;/li>
&lt;li>&lt;strong>資料分發&lt;/strong>：把不同 request 分到不同卡（data parallel）、卡間流量低、PCIe 也夠。&lt;/li>
&lt;/ol>
&lt;p>頻寬對照（廠商標稱、依世代變化）：&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>PCIe 4.0 x16&lt;/td>
 &lt;td>約 32 GB/s 單向&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>PCIe 5.0 x16&lt;/td>
 &lt;td>約 64 GB/s 單向&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>NVLink（H100）&lt;/td>
 &lt;td>約 900 GB/s 雙向、依世代&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>NVLink（A100）&lt;/td>
 &lt;td>約 600 GB/s 雙向&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>NVLink 比 PCIe 高一個量級、是資料中心多卡推論的關鍵；消費級 RTX 場景多卡通常只能走 PCIe、縮放效益相對受限。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：NVLink 各世代的頻寬數字依 NVIDIA 官方規格、不同 GPU 跟世代有差異；NVLink 在哪些消費級 / 工作站 / 資料中心 GPU 可用、依時段跟廠商策略變化、引用前以 &lt;a href="https://www.nvidia.com/">NVIDIA 官方產品頁&lt;/a> 跟對應 GPU 的 datasheet 為準。&lt;/p>&lt;/blockquote>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 NVLink 後可以解釋兩個現象：為什麼資料中心多卡 LLM 推論能線性 scale（NVLink 頻寬足以做 tensor parallel）、為什麼消費級雙卡 RTX 推論縮放比通常低於線性（沒 NVLink、走 PCIe x4 / x8、卡間頻寬限制）。&lt;/p>
&lt;p>選消費級 GPU 跑本地 LLM 時、NVLink 不是常見選項；多卡升級的判讀應該基於「能否容忍縮放比低於線性」、而不是預期 NVLink 等級的卡間頻寬。詳見 &lt;a href="https://tarrragon.github.io/blog/llm/05-discrete-gpu/gpu-vendor-differences/" data-link-title="5.6 GPU 廠商差異" data-link-desc="NVIDIA CUDA、AMD ROCm、Intel ARC 在 llama.cpp 生態的相對位置、選卡時的判讀軸">5.6 GPU 廠商差異&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>NVLink 的核心概念是「NVIDIA 自家的 GPU 之間高速互連介面、頻寬高於 <a href="/blog/llm/knowledge-cards/pcie/" data-link-title="PCIe" data-link-desc="PC 上連接 GPU 跟主機板的高速序列匯流排、影響模型載入速度跟 MoE 卸載時的推論吞吐">PCIe</a>、適合多卡 tensor parallel 場景」。資料中心級 GPU（如 A100 / H100 / H200）普遍支援、消費級 RTX 30 系列部分支援（如 3090）、RTX 40 / 50 系列普遍移除 NVLink、消費級多卡通常只能走 PCIe。</p>
<h2 id="概念位置">概念位置</h2>
<p>NVLink 在多卡推論場景的角色：</p>
<ol>
<li><strong>tensor parallel</strong>：把一個 transformer 層的 weight 切到多張卡、每 token 計算時需要卡間同步、卡間頻寬影響直接。</li>
<li><strong>pipeline parallel</strong>：把不同層分到不同卡、卡間需要傳 activation、頻寬要求中等。</li>
<li><strong>資料分發</strong>：把不同 request 分到不同卡（data parallel）、卡間流量低、PCIe 也夠。</li>
</ol>
<p>頻寬對照（廠商標稱、依世代變化）：</p>
<table>
  <thead>
      <tr>
          <th>介面</th>
          <th>卡間頻寬（標稱）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>PCIe 4.0 x16</td>
          <td>約 32 GB/s 單向</td>
      </tr>
      <tr>
          <td>PCIe 5.0 x16</td>
          <td>約 64 GB/s 單向</td>
      </tr>
      <tr>
          <td>NVLink（H100）</td>
          <td>約 900 GB/s 雙向、依世代</td>
      </tr>
      <tr>
          <td>NVLink（A100）</td>
          <td>約 600 GB/s 雙向</td>
      </tr>
  </tbody>
</table>
<p>NVLink 比 PCIe 高一個量級、是資料中心多卡推論的關鍵；消費級 RTX 場景多卡通常只能走 PCIe、縮放效益相對受限。</p>
<blockquote>
<p><strong>事實查核註</strong>：NVLink 各世代的頻寬數字依 NVIDIA 官方規格、不同 GPU 跟世代有差異；NVLink 在哪些消費級 / 工作站 / 資料中心 GPU 可用、依時段跟廠商策略變化、引用前以 <a href="https://www.nvidia.com/">NVIDIA 官方產品頁</a> 跟對應 GPU 的 datasheet 為準。</p></blockquote>
<h2 id="設計責任">設計責任</h2>
<p>理解 NVLink 後可以解釋兩個現象：為什麼資料中心多卡 LLM 推論能線性 scale（NVLink 頻寬足以做 tensor parallel）、為什麼消費級雙卡 RTX 推論縮放比通常低於線性（沒 NVLink、走 PCIe x4 / x8、卡間頻寬限制）。</p>
<p>選消費級 GPU 跑本地 LLM 時、NVLink 不是常見選項；多卡升級的判讀應該基於「能否容忍縮放比低於線性」、而不是預期 NVLink 等級的卡間頻寬。詳見 <a href="/blog/llm/05-discrete-gpu/gpu-vendor-differences/" data-link-title="5.6 GPU 廠商差異" data-link-desc="NVIDIA CUDA、AMD ROCm、Intel ARC 在 llama.cpp 生態的相對位置、選卡時的判讀軸">5.6 GPU 廠商差異</a>。</p>
]]></content:encoded></item><item><title>OWASP LLM Top 10</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/owasp-llm-top10/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/owasp-llm-top10/</guid><description>&lt;p>OWASP LLM Top 10 的核心概念是「&lt;strong>Open Worldwide Application Security Project 發布的 LLM 應用最常見 10 大資安風險清單&lt;/strong>」。2023 首發、2025 更新版是業界跟企業安全溝通的共同詞彙、是 production LLM 應用做 threat modeling 跟合規溝通的標準入口。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>2025 版的 10 項（簡述）：&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>LLM01&lt;/td>
 &lt;td>Prompt Injection&lt;/td>
 &lt;td>把惡意指令藏進 LLM 會讀到的內容、間接影響模型行為&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM02&lt;/td>
 &lt;td>Sensitive Information Disclosure&lt;/td>
 &lt;td>LLM 輸出洩漏訓練資料 / system prompt / PII&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM03&lt;/td>
 &lt;td>Supply Chain&lt;/td>
 &lt;td>模型 / 訓練資料 / 工具 / dependency 供應鏈攻擊&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM04&lt;/td>
 &lt;td>Data and Model Poisoning&lt;/td>
 &lt;td>訓練資料污染、模型行為被植入後門&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM05&lt;/td>
 &lt;td>Improper Output Handling&lt;/td>
 &lt;td>LLM 輸出未驗證直接執行（XSS / SQLi / RCE）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM06&lt;/td>
 &lt;td>Excessive Agency&lt;/td>
 &lt;td>Agent 工具權限過大、副作用不可控&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM07&lt;/td>
 &lt;td>System Prompt Leakage&lt;/td>
 &lt;td>System prompt 被使用者誘導露出&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM08&lt;/td>
 &lt;td>Vector and Embedding Weaknesses&lt;/td>
 &lt;td>Vector DB / embedding pipeline 的攻擊面&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM09&lt;/td>
 &lt;td>Misinformation&lt;/td>
 &lt;td>Hallucination / 過度信任 LLM 輸出&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM10&lt;/td>
 &lt;td>Unbounded Consumption&lt;/td>
 &lt;td>Resource exhaustion / cost runaway（DoS / 燒錢）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="跟模組六的-mapping">跟模組六的 mapping&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>OWASP&lt;/th>
 &lt;th>模組六章節&lt;/th>
 &lt;th>補充&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>LLM01 Prompt Injection&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/06-security/prompt-injection-in-ide/" data-link-title="6.3 IDE 場景的 prompt injection" data-link-desc="個人 dev 場景下 IDE 寫 code 工作流的 prompt injection：codebase 內容、外部文件、剪貼簿作為攻擊面、跟雲端 LLM 場景的差異">6.3 IDE 場景 prompt injection&lt;/a>&lt;/td>
 &lt;td>直接對應&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM02 Sensitive Disclosure&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/06-security/cross-cloud-local-data-boundary/" data-link-title="6.4 跨雲端 / 本地的資料邊界" data-link-desc="個人 dev 場景下混用雲端 LLM 跟本地 LLM 時的 prompt 洩漏點：Continue.dev 多 provider 設定、隱私資料流、按敏感度分流的判讀">6.4 跨雲端資料邊界&lt;/a>&lt;/td>
 &lt;td>加 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/static-and-serverless-rag-deployment/" data-link-title="4.16 靜態 / serverless RAG deployment：架構選擇與資安取捨" data-link-desc="沒 backend 的場景怎麼做 RAG：四種 deployment 方案、API key 暴露問題、CORS / abuse / 第三方信任、跟模組六的 routing">4.16 靜態 RAG 資安&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM03 Supply Chain&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/06-security/model-supply-chain-trust/" data-link-title="6.0 模型供應鏈與信任邊界" data-link-desc="個人 dev 用本地 LLM 時的模型權重來源信任：GGUF 完整性、Hugging Face / Ollama registry 信任、量化版本污染、檔案完整性檢查">6.0 模型供應鏈&lt;/a>&lt;/td>
 &lt;td>直接對應&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM04 Data/Model Poisoning&lt;/td>
 &lt;td>部分（限本地 dev、production 訓練屬 backend/07）&lt;/td>
 &lt;td>M6 cover 模型來源信任、不 cover 訓練毒化&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM05 Improper Output&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/06-security/tool-use-permission-model/" data-link-title="6.2 tool use 與 MCP server 的權限模型" data-link-desc="個人 dev 場景下 tool use / MCP server 的副作用權限：檔案系統 / shell / 網路存取邊界、第三方 MCP 信任、副作用的可逆性">6.2 tool use 權限&lt;/a>&lt;/td>
 &lt;td>直接對應&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM06 Excessive Agency&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/06-security/tool-use-permission-model/" data-link-title="6.2 tool use 與 MCP server 的權限模型" data-link-desc="個人 dev 場景下 tool use / MCP server 的副作用權限：檔案系統 / shell / 網路存取邊界、第三方 MCP 信任、副作用的可逆性">6.2&lt;/a> + &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/agent-architecture/" data-link-title="4.4 Agent 架構原理" data-link-desc="Agent loop 結構、失敗模式、什麼任務適合 vs 不適合、跟人類審查的協作模型">4.4 agent 架構&lt;/a>&lt;/td>
 &lt;td>跨原理 + 安全&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM07 System Prompt Leakage&lt;/td>
 &lt;td>部分（&lt;a href="https://tarrragon.github.io/blog/llm/04-applications/coding-agent-harness/" data-link-title="4.17 Coding agent harness：scaffold / context engineering / subagent" data-link-desc="Coding agent 的內部設計：scaffold vs harness 分層、context budget 25% 規則、subagent 拓樸、跟 Claude Code / Cursor / Aider 的 mapping">4.17 coding agent harness&lt;/a>）&lt;/td>
 &lt;td>M6 沒專章、屬 scaffold 設計&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM08 Vector / Embedding&lt;/td>
 &lt;td>部分（&lt;a href="https://tarrragon.github.io/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &amp;#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG&lt;/a> + &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/static-and-serverless-rag-deployment/" data-link-title="4.16 靜態 / serverless RAG deployment：架構選擇與資安取捨" data-link-desc="沒 backend 的場景怎麼做 RAG：四種 deployment 方案、API key 暴露問題、CORS / abuse / 第三方信任、跟模組六的 routing">4.16 靜態 RAG 資安&lt;/a>）&lt;/td>
 &lt;td>跨原理 + 應用&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM09 Misinformation&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/hallucination/" data-link-title="Hallucination" data-link-desc="LLM 生成內容看起來合理但事實錯誤、引用不存在的來源、虛構不存在的 entity 的現象">hallucination&lt;/a> 卡 + &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21 LLM-as-judge&lt;/a>&lt;/td>
 &lt;td>跨卡 + 應用&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLM10 Unbounded Consumption&lt;/td>
 &lt;td>部分（&lt;a href="https://tarrragon.github.io/blog/llm/04-applications/prompt-caching-engineering/" data-link-title="4.18 Prompt caching 工程實務：cost / latency 最大槓桿" data-link-desc="Prompt cache 怎麼運作、cache_control 設計、coding agent 跟 long-context 的 cache pattern、anti-pattern 跟 cache miss 訊號">4.18 prompt caching&lt;/a> + &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/static-and-serverless-rag-deployment/" data-link-title="4.16 靜態 / serverless RAG deployment：架構選擇與資安取捨" data-link-desc="沒 backend 的場景怎麼做 RAG：四種 deployment 方案、API key 暴露問題、CORS / abuse / 第三方信任、跟模組六的 routing">4.16 靜態 RAG 資安 abuse&lt;/a>）&lt;/td>
 &lt;td>M6 沒專章、屬 abuse 緩解&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀企業 LLM 安全 / 合規文件 / vendor security audit 看到「OWASP LLM Top 10」就是這 framing。寫 code 場景的判讀：&lt;/p></description><content:encoded><![CDATA[<p>OWASP LLM Top 10 的核心概念是「<strong>Open Worldwide Application Security Project 發布的 LLM 應用最常見 10 大資安風險清單</strong>」。2023 首發、2025 更新版是業界跟企業安全溝通的共同詞彙、是 production LLM 應用做 threat modeling 跟合規溝通的標準入口。</p>
<h2 id="概念位置">概念位置</h2>
<p>2025 版的 10 項（簡述）：</p>
<table>
  <thead>
      <tr>
          <th>編號</th>
          <th>名稱</th>
          <th>簡述</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>LLM01</td>
          <td>Prompt Injection</td>
          <td>把惡意指令藏進 LLM 會讀到的內容、間接影響模型行為</td>
      </tr>
      <tr>
          <td>LLM02</td>
          <td>Sensitive Information Disclosure</td>
          <td>LLM 輸出洩漏訓練資料 / system prompt / PII</td>
      </tr>
      <tr>
          <td>LLM03</td>
          <td>Supply Chain</td>
          <td>模型 / 訓練資料 / 工具 / dependency 供應鏈攻擊</td>
      </tr>
      <tr>
          <td>LLM04</td>
          <td>Data and Model Poisoning</td>
          <td>訓練資料污染、模型行為被植入後門</td>
      </tr>
      <tr>
          <td>LLM05</td>
          <td>Improper Output Handling</td>
          <td>LLM 輸出未驗證直接執行（XSS / SQLi / RCE）</td>
      </tr>
      <tr>
          <td>LLM06</td>
          <td>Excessive Agency</td>
          <td>Agent 工具權限過大、副作用不可控</td>
      </tr>
      <tr>
          <td>LLM07</td>
          <td>System Prompt Leakage</td>
          <td>System prompt 被使用者誘導露出</td>
      </tr>
      <tr>
          <td>LLM08</td>
          <td>Vector and Embedding Weaknesses</td>
          <td>Vector DB / embedding pipeline 的攻擊面</td>
      </tr>
      <tr>
          <td>LLM09</td>
          <td>Misinformation</td>
          <td>Hallucination / 過度信任 LLM 輸出</td>
      </tr>
      <tr>
          <td>LLM10</td>
          <td>Unbounded Consumption</td>
          <td>Resource exhaustion / cost runaway（DoS / 燒錢）</td>
      </tr>
  </tbody>
</table>
<h2 id="跟模組六的-mapping">跟模組六的 mapping</h2>
<table>
  <thead>
      <tr>
          <th>OWASP</th>
          <th>模組六章節</th>
          <th>補充</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>LLM01 Prompt Injection</td>
          <td><a href="/blog/llm/06-security/prompt-injection-in-ide/" data-link-title="6.3 IDE 場景的 prompt injection" data-link-desc="個人 dev 場景下 IDE 寫 code 工作流的 prompt injection：codebase 內容、外部文件、剪貼簿作為攻擊面、跟雲端 LLM 場景的差異">6.3 IDE 場景 prompt injection</a></td>
          <td>直接對應</td>
      </tr>
      <tr>
          <td>LLM02 Sensitive Disclosure</td>
          <td><a href="/blog/llm/06-security/cross-cloud-local-data-boundary/" data-link-title="6.4 跨雲端 / 本地的資料邊界" data-link-desc="個人 dev 場景下混用雲端 LLM 跟本地 LLM 時的 prompt 洩漏點：Continue.dev 多 provider 設定、隱私資料流、按敏感度分流的判讀">6.4 跨雲端資料邊界</a></td>
          <td>加 <a href="/blog/llm/04-applications/static-and-serverless-rag-deployment/" data-link-title="4.16 靜態 / serverless RAG deployment：架構選擇與資安取捨" data-link-desc="沒 backend 的場景怎麼做 RAG：四種 deployment 方案、API key 暴露問題、CORS / abuse / 第三方信任、跟模組六的 routing">4.16 靜態 RAG 資安</a></td>
      </tr>
      <tr>
          <td>LLM03 Supply Chain</td>
          <td><a href="/blog/llm/06-security/model-supply-chain-trust/" data-link-title="6.0 模型供應鏈與信任邊界" data-link-desc="個人 dev 用本地 LLM 時的模型權重來源信任：GGUF 完整性、Hugging Face / Ollama registry 信任、量化版本污染、檔案完整性檢查">6.0 模型供應鏈</a></td>
          <td>直接對應</td>
      </tr>
      <tr>
          <td>LLM04 Data/Model Poisoning</td>
          <td>部分（限本地 dev、production 訓練屬 backend/07）</td>
          <td>M6 cover 模型來源信任、不 cover 訓練毒化</td>
      </tr>
      <tr>
          <td>LLM05 Improper Output</td>
          <td><a href="/blog/llm/06-security/tool-use-permission-model/" data-link-title="6.2 tool use 與 MCP server 的權限模型" data-link-desc="個人 dev 場景下 tool use / MCP server 的副作用權限：檔案系統 / shell / 網路存取邊界、第三方 MCP 信任、副作用的可逆性">6.2 tool use 權限</a></td>
          <td>直接對應</td>
      </tr>
      <tr>
          <td>LLM06 Excessive Agency</td>
          <td><a href="/blog/llm/06-security/tool-use-permission-model/" data-link-title="6.2 tool use 與 MCP server 的權限模型" data-link-desc="個人 dev 場景下 tool use / MCP server 的副作用權限：檔案系統 / shell / 網路存取邊界、第三方 MCP 信任、副作用的可逆性">6.2</a> + <a href="/blog/llm/04-applications/agent-architecture/" data-link-title="4.4 Agent 架構原理" data-link-desc="Agent loop 結構、失敗模式、什麼任務適合 vs 不適合、跟人類審查的協作模型">4.4 agent 架構</a></td>
          <td>跨原理 + 安全</td>
      </tr>
      <tr>
          <td>LLM07 System Prompt Leakage</td>
          <td>部分（<a href="/blog/llm/04-applications/coding-agent-harness/" data-link-title="4.17 Coding agent harness：scaffold / context engineering / subagent" data-link-desc="Coding agent 的內部設計：scaffold vs harness 分層、context budget 25% 規則、subagent 拓樸、跟 Claude Code / Cursor / Aider 的 mapping">4.17 coding agent harness</a>）</td>
          <td>M6 沒專章、屬 scaffold 設計</td>
      </tr>
      <tr>
          <td>LLM08 Vector / Embedding</td>
          <td>部分（<a href="/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG</a> + <a href="/blog/llm/04-applications/static-and-serverless-rag-deployment/" data-link-title="4.16 靜態 / serverless RAG deployment：架構選擇與資安取捨" data-link-desc="沒 backend 的場景怎麼做 RAG：四種 deployment 方案、API key 暴露問題、CORS / abuse / 第三方信任、跟模組六的 routing">4.16 靜態 RAG 資安</a>）</td>
          <td>跨原理 + 應用</td>
      </tr>
      <tr>
          <td>LLM09 Misinformation</td>
          <td><a href="/blog/llm/knowledge-cards/hallucination/" data-link-title="Hallucination" data-link-desc="LLM 生成內容看起來合理但事實錯誤、引用不存在的來源、虛構不存在的 entity 的現象">hallucination</a> 卡 + <a href="/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21 LLM-as-judge</a></td>
          <td>跨卡 + 應用</td>
      </tr>
      <tr>
          <td>LLM10 Unbounded Consumption</td>
          <td>部分（<a href="/blog/llm/04-applications/prompt-caching-engineering/" data-link-title="4.18 Prompt caching 工程實務：cost / latency 最大槓桿" data-link-desc="Prompt cache 怎麼運作、cache_control 設計、coding agent 跟 long-context 的 cache pattern、anti-pattern 跟 cache miss 訊號">4.18 prompt caching</a> + <a href="/blog/llm/04-applications/static-and-serverless-rag-deployment/" data-link-title="4.16 靜態 / serverless RAG deployment：架構選擇與資安取捨" data-link-desc="沒 backend 的場景怎麼做 RAG：四種 deployment 方案、API key 暴露問題、CORS / abuse / 第三方信任、跟模組六的 routing">4.16 靜態 RAG 資安 abuse</a>）</td>
          <td>M6 沒專章、屬 abuse 緩解</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀企業 LLM 安全 / 合規文件 / vendor security audit 看到「OWASP LLM Top 10」就是這 framing。寫 code 場景的判讀：</p>
<ol>
<li><strong>跟企業溝通必備</strong>：安全 team / vendor audit 都用 OWASP 編號、能 map 自己應用到 LLM01-LLM10 就能 align 對話</li>
<li><strong>不是 production 才需要看</strong>：個人 dev 也適用大部分（LLM01 prompt injection、LLM03 supply chain、LLM06 excessive agency 對個人都直接相關）</li>
<li><strong>跟 <a href="/blog/llm/06-security/owasp-llm-top10-mapping/" data-link-title="6.6 OWASP LLM Top 10 對照圖" data-link-desc="把模組六的本地 dev 視角安全章節對照到 OWASP LLM Top 10 2025、補出個人 dev 場景跟企業合規溝通的共同詞彙">6.6 OWASP 對照章節</a> 的關係</strong>：本卡是定義 + mapping、章節是詳細 mapping + 個人 dev 場景的對應 control</li>
</ol>
]]></content:encoded></item><item><title>PCIe</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/pcie/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/pcie/</guid><description>&lt;p>PCIe（PCI Express）的核心概念是「PC 上 GPU 跟主機板（CPU + 系統 RAM）之間的高速序列匯流排」。獨立 GPU 場景下、模型權重從 SSD / 系統 RAM 走 PCIe 進 VRAM、之後推論主要在 GPU 內部完成；但 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/moe-cpu-offload/" data-link-title="MoE CPU 卸載" data-link-desc="把 Mixture-of-Experts 模型不活躍的專家層權重放在系統 RAM、用到再走 PCIe 拉回 GPU、讓有限 VRAM 跑得了更大模型">MoE CPU 卸載&lt;/a> 啟用時、每 token 都需要從系統 RAM 走 PCIe 拉部分權重、PCIe 頻寬開始影響推論吞吐。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>PCIe 在本地 LLM 推論的兩個階段角色不同：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>模型載入階段&lt;/strong>：模型權重從 SSD → 系統 RAM → 走 PCIe → &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/vram/" data-link-title="VRAM" data-link-desc="顯卡上的記憶體、跟系統 RAM 是兩塊獨立預算、決定能載入多大模型權重跟 KV cache">VRAM&lt;/a>。PCIe 是常見瓶頸、影響「啟動時間」、不影響推論。&lt;/li>
&lt;li>&lt;strong>推論階段&lt;/strong>：
&lt;ul>
&lt;li>全載 VRAM 場景：權重已在 VRAM、推論時 PCIe 流量很少。&lt;/li>
&lt;li>MoE 卸載場景：每 token 從系統 RAM 拉專家權重經 PCIe、PCIe 頻寬成為次要瓶頸。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>PCIe 版本跟頻寬（廠商標稱、單向）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>版本&lt;/th>
 &lt;th>x16 單向標稱頻寬&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>PCIe 4.0 x16&lt;/td>
 &lt;td>約 32 GB/s&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>PCIe 5.0 x16&lt;/td>
 &lt;td>約 64 GB/s&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>PCIe 6.0 x16&lt;/td>
 &lt;td>約 128 GB/s&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>實際傳輸吞吐受驅動、檔案系統、量化格式影響、通常低於規格上限。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：PCIe 各版本的標稱頻寬數字以 &lt;a href="https://pcisig.com/">PCI-SIG&lt;/a> 官方規格為主、實際可達吞吐依硬體配置變化、引用前以對應版本的官方規格文件為準。&lt;/p>&lt;/blockquote>
&lt;p>消費級主機板的 PCIe lane 分配常見「一條 x16 + 一條 x4」、加第二張 GPU 時、第二張的有效頻寬可能只有 x4、影響多卡縮放效益。詳見 &lt;a href="https://tarrragon.github.io/blog/llm/05-discrete-gpu/llama-cpp-on-pc/" data-link-title="5.3 llama.cpp 在 PC 上" data-link-desc="CUDA / ROCm build 取得、核心旗標地圖、llama-bench 校準、多卡 tensor split 的入門設定">5.3 llama.cpp 在 PC 上&lt;/a> 的多卡 tensor split 段落。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 PCIe 後可以解釋三個現象：為什麼模型載入要等幾秒到十幾秒（PCIe 是橋）、為什麼單卡 + MoE 卸載通常不卡 PCIe（每 token 拉的權重量小於 PCIe 頻寬）、為什麼雙卡縮放比沒有直接翻倍（PCIe lane 跟主機板配置）。&lt;/p>
&lt;p>選 PC 配置時、PCIe 版本影響模型載入體感、但對單人推論的生字速度通常影響小。多卡升級前要看主機板的 PCIe lane 分配。&lt;/p></description><content:encoded><![CDATA[<p>PCIe（PCI Express）的核心概念是「PC 上 GPU 跟主機板（CPU + 系統 RAM）之間的高速序列匯流排」。獨立 GPU 場景下、模型權重從 SSD / 系統 RAM 走 PCIe 進 VRAM、之後推論主要在 GPU 內部完成；但 <a href="/blog/llm/knowledge-cards/moe-cpu-offload/" data-link-title="MoE CPU 卸載" data-link-desc="把 Mixture-of-Experts 模型不活躍的專家層權重放在系統 RAM、用到再走 PCIe 拉回 GPU、讓有限 VRAM 跑得了更大模型">MoE CPU 卸載</a> 啟用時、每 token 都需要從系統 RAM 走 PCIe 拉部分權重、PCIe 頻寬開始影響推論吞吐。</p>
<h2 id="概念位置">概念位置</h2>
<p>PCIe 在本地 LLM 推論的兩個階段角色不同：</p>
<ol>
<li><strong>模型載入階段</strong>：模型權重從 SSD → 系統 RAM → 走 PCIe → <a href="/blog/llm/knowledge-cards/vram/" data-link-title="VRAM" data-link-desc="顯卡上的記憶體、跟系統 RAM 是兩塊獨立預算、決定能載入多大模型權重跟 KV cache">VRAM</a>。PCIe 是常見瓶頸、影響「啟動時間」、不影響推論。</li>
<li><strong>推論階段</strong>：
<ul>
<li>全載 VRAM 場景：權重已在 VRAM、推論時 PCIe 流量很少。</li>
<li>MoE 卸載場景：每 token 從系統 RAM 拉專家權重經 PCIe、PCIe 頻寬成為次要瓶頸。</li>
</ul>
</li>
</ol>
<p>PCIe 版本跟頻寬（廠商標稱、單向）：</p>
<table>
  <thead>
      <tr>
          <th>版本</th>
          <th>x16 單向標稱頻寬</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>PCIe 4.0 x16</td>
          <td>約 32 GB/s</td>
      </tr>
      <tr>
          <td>PCIe 5.0 x16</td>
          <td>約 64 GB/s</td>
      </tr>
      <tr>
          <td>PCIe 6.0 x16</td>
          <td>約 128 GB/s</td>
      </tr>
  </tbody>
</table>
<p>實際傳輸吞吐受驅動、檔案系統、量化格式影響、通常低於規格上限。</p>
<blockquote>
<p><strong>事實查核註</strong>：PCIe 各版本的標稱頻寬數字以 <a href="https://pcisig.com/">PCI-SIG</a> 官方規格為主、實際可達吞吐依硬體配置變化、引用前以對應版本的官方規格文件為準。</p></blockquote>
<p>消費級主機板的 PCIe lane 分配常見「一條 x16 + 一條 x4」、加第二張 GPU 時、第二張的有效頻寬可能只有 x4、影響多卡縮放效益。詳見 <a href="/blog/llm/05-discrete-gpu/llama-cpp-on-pc/" data-link-title="5.3 llama.cpp 在 PC 上" data-link-desc="CUDA / ROCm build 取得、核心旗標地圖、llama-bench 校準、多卡 tensor split 的入門設定">5.3 llama.cpp 在 PC 上</a> 的多卡 tensor split 段落。</p>
<h2 id="設計責任">設計責任</h2>
<p>理解 PCIe 後可以解釋三個現象：為什麼模型載入要等幾秒到十幾秒（PCIe 是橋）、為什麼單卡 + MoE 卸載通常不卡 PCIe（每 token 拉的權重量小於 PCIe 頻寬）、為什麼雙卡縮放比沒有直接翻倍（PCIe lane 跟主機板配置）。</p>
<p>選 PC 配置時、PCIe 版本影響模型載入體感、但對單人推論的生字速度通常影響小。多卡升級前要看主機板的 PCIe lane 分配。</p>
]]></content:encoded></item><item><title>Perplexity</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/perplexity/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/perplexity/</guid><description>&lt;p>Perplexity（困惑度）的核心概念是「&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/cross-entropy/" data-link-title="Cross-Entropy" data-link-desc="衡量「預測機率分佈」跟「真實分佈」距離的指標、LLM 預訓練的主要 loss">cross-entropy&lt;/a> 的指數形式」：&lt;code>perplexity = exp(cross-entropy)&lt;/code>。直覺意義是「模型在每個位置平均覺得下個 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a> 有多少種候選」。perplexity = 1 表示模型完美預測；perplexity = vocab_size 表示模型純猜（vocab 上的 uniform 分佈）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Perplexity 跟 cross-entropy 的關係：&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>Cross-entropy&lt;/td>
 &lt;td>&lt;code>-mean(log p_true)&lt;/code>、底通常是 e&lt;/td>
 &lt;td>loss 數字、訓練拿來最佳化&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Perplexity&lt;/td>
 &lt;td>&lt;code>exp(cross-entropy)&lt;/code>&lt;/td>
 &lt;td>「平均看到幾種候選」、好讀&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>換算範例（base e）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Cross-entropy&lt;/th>
 &lt;th>Perplexity&lt;/th>
 &lt;th>意義（極粗略直覺）&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>11&lt;/td>
 &lt;td>~60K&lt;/td>
 &lt;td>純隨機（vocab ≈ 128K 時）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>5&lt;/td>
 &lt;td>~148&lt;/td>
 &lt;td>早期訓練&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>3&lt;/td>
 &lt;td>~20&lt;/td>
 &lt;td>中等訓練模型&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>2&lt;/td>
 &lt;td>~7.4&lt;/td>
 &lt;td>接近現代成熟 LLM 在文本上的表現&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>0&lt;/td>
 &lt;td>1&lt;/td>
 &lt;td>完美預測（不可能達到）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Perplexity 主要用於：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>預訓練評估&lt;/strong>：在 held-out 語料上算 perplexity、衡量基礎建模能力。&lt;/li>
&lt;li>&lt;strong>量化品質衡量&lt;/strong>：fp16 vs Q4 vs Q3 模型的 perplexity 差異、看量化造成多少品質損失。&lt;/li>
&lt;li>&lt;strong>領域 benchmark&lt;/strong>：在特定領域語料（code、math、医學文獻）上算 perplexity、評估模型對該領域的熟悉度。&lt;/li>
&lt;/ul>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Perplexity 是 base model 評估標準、但對 instruction-tuned / chat 模型用處有限（chat 模型輸出風格已偏離 raw text、perplexity 不一定降）。對寫 code 場景的判讀：看到 paper 報 perplexity 是評估 pretrain 品質的訊號、實際聊天 / coding 能力要看 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/swe-bench/" data-link-title="SWE-bench" data-link-desc="用真實 GitHub issue 量化 LLM coding 能力的 benchmark">SWE-bench&lt;/a>、MMLU、HumanEval 等任務式 benchmark。&lt;/p></description><content:encoded><![CDATA[<p>Perplexity（困惑度）的核心概念是「<a href="/blog/llm/knowledge-cards/cross-entropy/" data-link-title="Cross-Entropy" data-link-desc="衡量「預測機率分佈」跟「真實分佈」距離的指標、LLM 預訓練的主要 loss">cross-entropy</a> 的指數形式」：<code>perplexity = exp(cross-entropy)</code>。直覺意義是「模型在每個位置平均覺得下個 <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a> 有多少種候選」。perplexity = 1 表示模型完美預測；perplexity = vocab_size 表示模型純猜（vocab 上的 uniform 分佈）。</p>
<h2 id="概念位置">概念位置</h2>
<p>Perplexity 跟 cross-entropy 的關係：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>公式 / 定義</th>
          <th>人類直覺</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Cross-entropy</td>
          <td><code>-mean(log p_true)</code>、底通常是 e</td>
          <td>loss 數字、訓練拿來最佳化</td>
      </tr>
      <tr>
          <td>Perplexity</td>
          <td><code>exp(cross-entropy)</code></td>
          <td>「平均看到幾種候選」、好讀</td>
      </tr>
  </tbody>
</table>
<p>換算範例（base e）：</p>
<table>
  <thead>
      <tr>
          <th>Cross-entropy</th>
          <th>Perplexity</th>
          <th>意義（極粗略直覺）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>11</td>
          <td>~60K</td>
          <td>純隨機（vocab ≈ 128K 時）</td>
      </tr>
      <tr>
          <td>5</td>
          <td>~148</td>
          <td>早期訓練</td>
      </tr>
      <tr>
          <td>3</td>
          <td>~20</td>
          <td>中等訓練模型</td>
      </tr>
      <tr>
          <td>2</td>
          <td>~7.4</td>
          <td>接近現代成熟 LLM 在文本上的表現</td>
      </tr>
      <tr>
          <td>0</td>
          <td>1</td>
          <td>完美預測（不可能達到）</td>
      </tr>
  </tbody>
</table>
<p>Perplexity 主要用於：</p>
<ul>
<li><strong>預訓練評估</strong>：在 held-out 語料上算 perplexity、衡量基礎建模能力。</li>
<li><strong>量化品質衡量</strong>：fp16 vs Q4 vs Q3 模型的 perplexity 差異、看量化造成多少品質損失。</li>
<li><strong>領域 benchmark</strong>：在特定領域語料（code、math、医學文獻）上算 perplexity、評估模型對該領域的熟悉度。</li>
</ul>
<h2 id="設計責任">設計責任</h2>
<p>Perplexity 是 base model 評估標準、但對 instruction-tuned / chat 模型用處有限（chat 模型輸出風格已偏離 raw text、perplexity 不一定降）。對寫 code 場景的判讀：看到 paper 報 perplexity 是評估 pretrain 品質的訊號、實際聊天 / coding 能力要看 <a href="/blog/llm/knowledge-cards/swe-bench/" data-link-title="SWE-bench" data-link-desc="用真實 GitHub issue 量化 LLM coding 能力的 benchmark">SWE-bench</a>、MMLU、HumanEval 等任務式 benchmark。</p>
]]></content:encoded></item><item><title>Port 與 Localhost</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/port-and-localhost/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/port-and-localhost/</guid><description>&lt;p>Port 與 Localhost 的核心概念是「網路 server 暴露在哪個地址、聽哪個 port、讓誰能連進來」。本地 LLM 場景中、Ollama 預設聽 &lt;code>127.0.0.1:11434&lt;/code>、Continue.dev 等介面層透過這個地址呼叫 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/openai-compatible-api/" data-link-title="OpenAI 相容 API" data-link-desc="本地推論伺服器跟雲端 OpenAI 共用的 API 形狀標準">OpenAI 相容 API&lt;/a>；理解 listen address 跟 port 的角色、才能判讀「為什麼 port 撞 / 為什麼 LAN 上另一台連不到 / 暴露到 internet 安全嗎」。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>完整的 server 入口由兩個欄位定義：&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>Listen address&lt;/td>
 &lt;td>接受哪些網路介面送進來的封包&lt;/td>
 &lt;td>&lt;code>127.0.0.1&lt;/code> / &lt;code>0.0.0.0&lt;/code> / &lt;code>192.168.x&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Port&lt;/td>
 &lt;td>OS 用來區分「同一台機器上哪個 server」&lt;/td>
 &lt;td>&lt;code>11434&lt;/code> / &lt;code>1234&lt;/code> / &lt;code>8080&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Port 是 16 bit 數字（0 ~ 65535）、其中 0 ~ 1023 是 well-known port（HTTP 80、HTTPS 443 等、需 root 權限才能 bind）、1024 ~ 65535 是 user port、本地 LLM 工具都用這個區間（Ollama 11434、LM Studio 1234、llama.cpp 8080）。同一個 port 在同一個 listen address 上同時只能被一個 process 持有、要兩個 Ollama 並存就要其中一個換 port。&lt;/p>
&lt;p>三個常見 listen address 的語意：&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>&lt;code>127.0.0.1&lt;/code>&lt;/td>
 &lt;td>&lt;code>localhost&lt;/code>&lt;/td>
 &lt;td>只接受本機 process、外部裝置連不到&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>0.0.0.0&lt;/code>&lt;/td>
 &lt;td>所有介面&lt;/td>
 &lt;td>接受任何網路介面送進來的封包、包含 LAN / VPN / public&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>192.168.x&lt;/code>&lt;/td>
 &lt;td>特定 LAN 介面&lt;/td>
 &lt;td>只接受該 LAN 介面送進來的封包&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>驗證 server 真的在聽預期地址：&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">&lt;span class="c1"># macOS 下查誰佔了 11434&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">lsof -i :11434
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="c1"># COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="c1"># ollama 1234 mac 6u IPv4 0xabcd 0t0 TCP localhost:11434 (LISTEN)&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>TCP localhost:11434 (LISTEN)&lt;/code> 表示這個 process 只接 localhost 進來的封包。改 listen address 把 Ollama 暴露到 LAN：&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">&lt;span class="nv">OLLAMA_HOST&lt;/span>&lt;span class="o">=&lt;/span>0.0.0.0:11434 ollama serve
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="c1"># lsof 之後會看到 TCP *:11434 (LISTEN)、星號表示所有介面&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>curl 用不同 host 名稱呼叫同一個 server：&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">curl http://localhost:11434/api/version &lt;span class="c1"># 走 loopback、最快&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">curl http://127.0.0.1:11434/api/version &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">curl http://&amp;lt;本機 LAN IP&amp;gt;:11434/api/version &lt;span class="c1"># 若 listen 在 0.0.0.0、會通；只 listen localhost 會 connection refused&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>「為什麼桌機跑 Ollama、筆電連不到」的最常見原因就是 Ollama 沒改 listen address、預設只接受 loopback。&lt;/p></description><content:encoded><![CDATA[<p>Port 與 Localhost 的核心概念是「網路 server 暴露在哪個地址、聽哪個 port、讓誰能連進來」。本地 LLM 場景中、Ollama 預設聽 <code>127.0.0.1:11434</code>、Continue.dev 等介面層透過這個地址呼叫 <a href="/blog/llm/knowledge-cards/openai-compatible-api/" data-link-title="OpenAI 相容 API" data-link-desc="本地推論伺服器跟雲端 OpenAI 共用的 API 形狀標準">OpenAI 相容 API</a>；理解 listen address 跟 port 的角色、才能判讀「為什麼 port 撞 / 為什麼 LAN 上另一台連不到 / 暴露到 internet 安全嗎」。</p>
<h2 id="概念位置">概念位置</h2>
<p>完整的 server 入口由兩個欄位定義：</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>角色</th>
          <th>範例值</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Listen address</td>
          <td>接受哪些網路介面送進來的封包</td>
          <td><code>127.0.0.1</code> / <code>0.0.0.0</code> / <code>192.168.x</code></td>
      </tr>
      <tr>
          <td>Port</td>
          <td>OS 用來區分「同一台機器上哪個 server」</td>
          <td><code>11434</code> / <code>1234</code> / <code>8080</code></td>
      </tr>
  </tbody>
</table>
<p>Port 是 16 bit 數字（0 ~ 65535）、其中 0 ~ 1023 是 well-known port（HTTP 80、HTTPS 443 等、需 root 權限才能 bind）、1024 ~ 65535 是 user port、本地 LLM 工具都用這個區間（Ollama 11434、LM Studio 1234、llama.cpp 8080）。同一個 port 在同一個 listen address 上同時只能被一個 process 持有、要兩個 Ollama 並存就要其中一個換 port。</p>
<p>三個常見 listen address 的語意：</p>
<table>
  <thead>
      <tr>
          <th>地址</th>
          <th>等同名稱</th>
          <th>接受誰的連線</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>127.0.0.1</code></td>
          <td><code>localhost</code></td>
          <td>只接受本機 process、外部裝置連不到</td>
      </tr>
      <tr>
          <td><code>0.0.0.0</code></td>
          <td>所有介面</td>
          <td>接受任何網路介面送進來的封包、包含 LAN / VPN / public</td>
      </tr>
      <tr>
          <td><code>192.168.x</code></td>
          <td>特定 LAN 介面</td>
          <td>只接受該 LAN 介面送進來的封包</td>
      </tr>
  </tbody>
</table>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>驗證 server 真的在聽預期地址：</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"><span class="c1"># macOS 下查誰佔了 11434</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">lsof -i :11434
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1"># COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># ollama  1234 mac  6u IPv4 0xabcd      0t0 TCP localhost:11434 (LISTEN)</span></span></span></code></pre></div><p><code>TCP localhost:11434 (LISTEN)</code> 表示這個 process 只接 localhost 進來的封包。改 listen address 把 Ollama 暴露到 LAN：</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"><span class="nv">OLLAMA_HOST</span><span class="o">=</span>0.0.0.0:11434 ollama serve
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1"># lsof 之後會看到 TCP *:11434 (LISTEN)、星號表示所有介面</span></span></span></code></pre></div><p>curl 用不同 host 名稱呼叫同一個 server：</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">curl http://localhost:11434/api/version    <span class="c1"># 走 loopback、最快</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">curl http://127.0.0.1:11434/api/version    <span class="c1"># 跟上面等價</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">curl http://&lt;本機 LAN IP&gt;:11434/api/version <span class="c1"># 若 listen 在 0.0.0.0、會通；只 listen localhost 會 connection refused</span></span></span></code></pre></div><p>「為什麼桌機跑 Ollama、筆電連不到」的最常見原因就是 Ollama 沒改 listen address、預設只接受 loopback。</p>
<h2 id="設計責任">設計責任</h2>
<p>選 listen address 是信任邊界決定：</p>
<ul>
<li><strong><code>127.0.0.1</code>（預設）</strong>：機器本身就是信任邊界、外部進不來、最安全</li>
<li><strong><code>0.0.0.0</code> 在家用 / 信任 LAN</strong>：把 server 暴露給同網路裝置、便於多裝置共用、風險可接受</li>
<li><strong><code>0.0.0.0</code> 在公共 Wi-Fi / 對 internet</strong>：等於對所有路過裝置開放、Ollama 沒有內建 auth、需要 SSH tunnel 或 reverse proxy + auth 才安全</li>
</ul>
<p>Port 衝突的處理順序：用 <code>lsof</code> 確認佔用方身分 → 若是舊版自己 kill、若是別的服務改自己的 port → 同步更新 IDE plugin 的 <code>apiBase</code>。完整資料流判讀見 <a href="/blog/llm/00-foundations/privacy-data-flow/" data-link-title="0.7 隱私 / 資安的資料流原理" data-link-desc="從「位置」到「資料流」的思考升級：信任邊界、合約模型、零信任原則套用到 LLM 工作流">0.7 隱私資料流</a>。</p>
]]></content:encoded></item><item><title>Pre-training</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/pre-training/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/pre-training/</guid><description>&lt;p>Pre-training（預訓練）的核心概念是「在大量未標註文字上、用 next-token prediction 當目標訓練一個語言模型」。產出的權重稱為 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/base-model/" data-link-title="Base Model" data-link-desc="未經指令微調的原始模型：擅長文字接龍、適合下游微調用途">base model&lt;/a>、是後續 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/sft/" data-link-title="SFT（Supervised Fine-Tuning）" data-link-desc="在 base model 上用「指令-回答」對資料微調、讓模型會跟著指令走">SFT&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rlhf/" data-link-title="RLHF" data-link-desc="Reinforcement Learning from Human Feedback：用人類偏好訓練的 reward model 透過 RL 對齊 LLM">RLHF&lt;/a> 的起點。Pre-training 是 LLM 三階段訓練流程中&lt;strong>最貴、最耗時、最決定模型上限&lt;/strong>的階段。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Pre-training 在 LLM 訓練 pipeline 的位置：&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">[網路文字 / 書籍 / code / 論文]（trillion token 級）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓ Pre-training（next-token prediction、cross-entropy loss）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">[Base model]：會接龍但不會對話
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ↓ SFT（指令-回答對資料）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">[Instruction-tuned model]：會跟指令走
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> ↓ RLHF / DPO（人類偏好資料）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">[Aligned model]：對話風格 / 安全性對齊&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Pre-training 的特性：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>典型數字（2026 年主流大模型）&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>資料量&lt;/td>
 &lt;td>數兆 token（Common Crawl、RefinedWeb、The Pile、Stack 等）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>GPU 用量&lt;/td>
 &lt;td>數百到數萬張 H100 / B200、並行訓練&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>訓練時間&lt;/td>
 &lt;td>數週到數月&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>成本級別&lt;/td>
 &lt;td>數百萬到數億美元&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Loss&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/cross-entropy/" data-link-title="Cross-Entropy" data-link-desc="衡量「預測機率分佈」跟「真實分佈」距離的指標、LLM 預訓練的主要 loss">Cross-entropy&lt;/a> on next-token&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>結果&lt;/td>
 &lt;td>「會接龍」的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/base-model/" data-link-title="Base Model" data-link-desc="未經指令微調的原始模型：擅長文字接龍、適合下游微調用途">base model&lt;/a>、可用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/perplexity/" data-link-title="Perplexity" data-link-desc="cross-entropy 的指數形式、直覺意義為「模型平均覺得下個 token 有多少種可能」">perplexity&lt;/a> 評估&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 pre-training 後可以判讀幾件事：模型的「世界知識」絕大部分在 pre-training 時就決定了、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/sft/" data-link-title="SFT（Supervised Fine-Tuning）" data-link-desc="在 base model 上用「指令-回答」對資料微調、讓模型會跟著指令走">SFT&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rlhf/" data-link-title="RLHF" data-link-desc="Reinforcement Learning from Human Feedback：用人類偏好訓練的 reward model 透過 RL 對齊 LLM">RLHF&lt;/a> 只是「教模型怎麼用這些知識回答」、不會大幅增加新知識；模型 cutoff date 就是 pre-training 資料的截止；想做新領域知識引入、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 比繼續 fine-tune 划算（pre-training 太貴、且 fine-tune 容易讓既有能力退化）。&lt;/p></description><content:encoded><![CDATA[<p>Pre-training（預訓練）的核心概念是「在大量未標註文字上、用 next-token prediction 當目標訓練一個語言模型」。產出的權重稱為 <a href="/blog/llm/knowledge-cards/base-model/" data-link-title="Base Model" data-link-desc="未經指令微調的原始模型：擅長文字接龍、適合下游微調用途">base model</a>、是後續 <a href="/blog/llm/knowledge-cards/sft/" data-link-title="SFT（Supervised Fine-Tuning）" data-link-desc="在 base model 上用「指令-回答」對資料微調、讓模型會跟著指令走">SFT</a> / <a href="/blog/llm/knowledge-cards/rlhf/" data-link-title="RLHF" data-link-desc="Reinforcement Learning from Human Feedback：用人類偏好訓練的 reward model 透過 RL 對齊 LLM">RLHF</a> 的起點。Pre-training 是 LLM 三階段訓練流程中<strong>最貴、最耗時、最決定模型上限</strong>的階段。</p>
<h2 id="概念位置">概念位置</h2>
<p>Pre-training 在 LLM 訓練 pipeline 的位置：</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">[網路文字 / 書籍 / code / 論文]（trillion token 級）
</span></span><span class="line"><span class="ln">2</span><span class="cl">   ↓ Pre-training（next-token prediction、cross-entropy loss）
</span></span><span class="line"><span class="ln">3</span><span class="cl">[Base model]：會接龍但不會對話
</span></span><span class="line"><span class="ln">4</span><span class="cl">   ↓ SFT（指令-回答對資料）
</span></span><span class="line"><span class="ln">5</span><span class="cl">[Instruction-tuned model]：會跟指令走
</span></span><span class="line"><span class="ln">6</span><span class="cl">   ↓ RLHF / DPO（人類偏好資料）
</span></span><span class="line"><span class="ln">7</span><span class="cl">[Aligned model]：對話風格 / 安全性對齊</span></span></code></pre></div><p>Pre-training 的特性：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>典型數字（2026 年主流大模型）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>資料量</td>
          <td>數兆 token（Common Crawl、RefinedWeb、The Pile、Stack 等）</td>
      </tr>
      <tr>
          <td>GPU 用量</td>
          <td>數百到數萬張 H100 / B200、並行訓練</td>
      </tr>
      <tr>
          <td>訓練時間</td>
          <td>數週到數月</td>
      </tr>
      <tr>
          <td>成本級別</td>
          <td>數百萬到數億美元</td>
      </tr>
      <tr>
          <td>Loss</td>
          <td><a href="/blog/llm/knowledge-cards/cross-entropy/" data-link-title="Cross-Entropy" data-link-desc="衡量「預測機率分佈」跟「真實分佈」距離的指標、LLM 預訓練的主要 loss">Cross-entropy</a> on next-token</td>
      </tr>
      <tr>
          <td>結果</td>
          <td>「會接龍」的 <a href="/blog/llm/knowledge-cards/base-model/" data-link-title="Base Model" data-link-desc="未經指令微調的原始模型：擅長文字接龍、適合下游微調用途">base model</a>、可用 <a href="/blog/llm/knowledge-cards/perplexity/" data-link-title="Perplexity" data-link-desc="cross-entropy 的指數形式、直覺意義為「模型平均覺得下個 token 有多少種可能」">perplexity</a> 評估</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>理解 pre-training 後可以判讀幾件事：模型的「世界知識」絕大部分在 pre-training 時就決定了、<a href="/blog/llm/knowledge-cards/sft/" data-link-title="SFT（Supervised Fine-Tuning）" data-link-desc="在 base model 上用「指令-回答」對資料微調、讓模型會跟著指令走">SFT</a> / <a href="/blog/llm/knowledge-cards/rlhf/" data-link-title="RLHF" data-link-desc="Reinforcement Learning from Human Feedback：用人類偏好訓練的 reward model 透過 RL 對齊 LLM">RLHF</a> 只是「教模型怎麼用這些知識回答」、不會大幅增加新知識；模型 cutoff date 就是 pre-training 資料的截止；想做新領域知識引入、<a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 比繼續 fine-tune 划算（pre-training 太貴、且 fine-tune 容易讓既有能力退化）。</p>
]]></content:encoded></item><item><title>Prefix Cache</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/prefix-cache/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/prefix-cache/</guid><description>&lt;p>Prefix Cache 的核心概念是「當多個請求共用相同的前綴 prompt（如同一 system prompt、同一 few-shot 範例）、把該前綴的 &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> 算一次、後續請求共用、省下重複 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prefill/" data-link-title="Prefill" data-link-desc="Prompt 首次處理時的計算階段：把整段輸入跑過模型、產生 KV cache">prefill&lt;/a> 算力」。是 production LLM 服務的常見優化、能大幅降低 latency 跟成本；但在多租戶場景下、跨租戶共用 prefix cache 是直接的隱私洩漏面。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Prefix Cache 在推論流程中的角色：&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">傳統推論：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> Request A：system prompt + user A → 完整 prefill → 生成
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> Request B：system prompt + user B → 完整 prefill → 生成
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ↑ 重複算 system prompt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">開啟 Prefix Cache：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> Request A：system prompt + user A → prefill 整段、cache 共用 prefix
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl"> Request B：system prompt + user B → 重用 cache 的 system prefix + 只 prefill user B → 生成
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">9&lt;/span>&lt;span class="cl"> ↑ 省下 system prompt 的 prefill 算力&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>效益對應的場景：&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>同 system prompt、不同 user message&lt;/td>
 &lt;td>prefill 算力大幅省&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>同 few-shot 例子、不同 query&lt;/td>
 &lt;td>prefill 算力大幅省&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>長 RAG context 共用、不同問題&lt;/td>
 &lt;td>prefill 算力大幅省&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>完全獨立的請求（無共用前綴）&lt;/td>
 &lt;td>無效益&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>主流推論引擎的支援度（依版本變化）：vLLM、SGLang、llama.cpp 等都有 prefix cache 機制、命名各異。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：prefix cache 的命名、設定方式、tenant 隔離預設行為依推論引擎跟版本差異大、引用前以對應引擎的官方文件為準（如 &lt;a href="https://docs.vllm.ai/">vLLM Automatic Prefix Caching&lt;/a>、SGLang RadixAttention 等）。&lt;/p>&lt;/blockquote>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 prefix cache 後可以解釋兩個現象：為什麼 production LLM 服務的 latency 在啟用 prefix cache 後大幅下降（system prompt 不再每次重算）、為什麼 prefix cache 在多租戶場景是隱私風險（A 租戶的 prefix 可能被 B 看到、見 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/llm-multi-tenant-isolation/" data-link-title="LLM 多租戶推論隔離" data-link-desc="production LLM 服務的多租戶隔離：KV cache 不共享、log / model artifact 隔離、跨用戶 prompt 洩漏面">llm-multi-tenant-isolation&lt;/a>）。&lt;/p>
&lt;p>production 設計時、prefix cache 應該按 tenant 分桶、同 tenant 內可共用、跨 tenant 必須隔離。隔離邊界對齊 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/tenant-boundary/" data-link-title="Tenant Boundary" data-link-desc="說明多租戶系統如何隔離不同客戶或組織的資料與資源">tenant-boundary&lt;/a> 卡片的設計。&lt;/p></description><content:encoded><![CDATA[<p>Prefix Cache 的核心概念是「當多個請求共用相同的前綴 prompt（如同一 system prompt、同一 few-shot 範例）、把該前綴的 <a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 算一次、後續請求共用、省下重複 <a href="/blog/llm/knowledge-cards/prefill/" data-link-title="Prefill" data-link-desc="Prompt 首次處理時的計算階段：把整段輸入跑過模型、產生 KV cache">prefill</a> 算力」。是 production LLM 服務的常見優化、能大幅降低 latency 跟成本；但在多租戶場景下、跨租戶共用 prefix cache 是直接的隱私洩漏面。</p>
<h2 id="概念位置">概念位置</h2>
<p>Prefix Cache 在推論流程中的角色：</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">傳統推論：
</span></span><span class="line"><span class="ln">2</span><span class="cl">  Request A：system prompt + user A → 完整 prefill → 生成
</span></span><span class="line"><span class="ln">3</span><span class="cl">  Request B：system prompt + user B → 完整 prefill → 生成
</span></span><span class="line"><span class="ln">4</span><span class="cl">                                       ↑ 重複算 system prompt
</span></span><span class="line"><span class="ln">5</span><span class="cl">
</span></span><span class="line"><span class="ln">6</span><span class="cl">開啟 Prefix Cache：
</span></span><span class="line"><span class="ln">7</span><span class="cl">  Request A：system prompt + user A → prefill 整段、cache 共用 prefix
</span></span><span class="line"><span class="ln">8</span><span class="cl">  Request B：system prompt + user B → 重用 cache 的 system prefix + 只 prefill user B → 生成
</span></span><span class="line"><span class="ln">9</span><span class="cl">                                       ↑ 省下 system prompt 的 prefill 算力</span></span></code></pre></div><p>效益對應的場景：</p>
<table>
  <thead>
      <tr>
          <th>場景</th>
          <th>效益</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>同 system prompt、不同 user message</td>
          <td>prefill 算力大幅省</td>
      </tr>
      <tr>
          <td>同 few-shot 例子、不同 query</td>
          <td>prefill 算力大幅省</td>
      </tr>
      <tr>
          <td>長 RAG context 共用、不同問題</td>
          <td>prefill 算力大幅省</td>
      </tr>
      <tr>
          <td>完全獨立的請求（無共用前綴）</td>
          <td>無效益</td>
      </tr>
  </tbody>
</table>
<p>主流推論引擎的支援度（依版本變化）：vLLM、SGLang、llama.cpp 等都有 prefix cache 機制、命名各異。</p>
<blockquote>
<p><strong>事實查核註</strong>：prefix cache 的命名、設定方式、tenant 隔離預設行為依推論引擎跟版本差異大、引用前以對應引擎的官方文件為準（如 <a href="https://docs.vllm.ai/">vLLM Automatic Prefix Caching</a>、SGLang RadixAttention 等）。</p></blockquote>
<h2 id="設計責任">設計責任</h2>
<p>理解 prefix cache 後可以解釋兩個現象：為什麼 production LLM 服務的 latency 在啟用 prefix cache 後大幅下降（system prompt 不再每次重算）、為什麼 prefix cache 在多租戶場景是隱私風險（A 租戶的 prefix 可能被 B 看到、見 <a href="/blog/backend/07-security-data-protection/llm-multi-tenant-isolation/" data-link-title="LLM 多租戶推論隔離" data-link-desc="production LLM 服務的多租戶隔離：KV cache 不共享、log / model artifact 隔離、跨用戶 prompt 洩漏面">llm-multi-tenant-isolation</a>）。</p>
<p>production 設計時、prefix cache 應該按 tenant 分桶、同 tenant 內可共用、跨 tenant 必須隔離。隔離邊界對齊 <a href="/blog/backend/knowledge-cards/tenant-boundary/" data-link-title="Tenant Boundary" data-link-desc="說明多租戶系統如何隔離不同客戶或組織的資料與資源">tenant-boundary</a> 卡片的設計。</p>
]]></content:encoded></item><item><title>Prompt Cache</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/prompt-cache/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/prompt-cache/</guid><description>&lt;p>Prompt cache 的核心概念是「&lt;strong>LLM 服務端 / 推論伺服器把重複出現的 prompt prefix（如 system prompt + tool schema）的 &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> 暫存起來、後續 query 跳過該 prefix 的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prefill/" data-link-title="Prefill" data-link-desc="Prompt 首次處理時的計算階段：把整段輸入跑過模型、產生 KV cache">prefill&lt;/a> 階段&lt;/strong>」。Anthropic / OpenAI / Bedrock / Gemini 都提供、最高 90% cost 折扣 + 13-31% &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT&lt;/a> 改善、是 coding agent / long-context 應用的核心 cost / latency 槓桿。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>跟既有 cache 概念的層次：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Cache 層&lt;/th>
 &lt;th>範圍&lt;/th>
 &lt;th>機制&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&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>&lt;/td>
 &lt;td>單一 conversation 的同一次推論&lt;/td>
 &lt;td>過去 token 的 K/V 暫存、autoregressive 才省重算&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prefix-cache/" data-link-title="Prefix Cache" data-link-desc="把多個請求共用的前綴 prompt 的 KV cache 重用、省下重複 prefill 算力的優化、production 多用戶服務的常見設計">Prefix cache&lt;/a>&lt;/td>
 &lt;td>多 request 共用 prefix（同 server 同 model）&lt;/td>
 &lt;td>跨 request 共用 KV cache、production 推論伺服器特性&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Prompt cache（本卡）&lt;/strong>&lt;/td>
 &lt;td>跨 request 跨時間、雲端 LLM API 服務端&lt;/td>
 &lt;td>服務端把 prefix 的 KV cache 持久化、有 TTL&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Prompt cache 的「保留範圍」跟「定價」是商業 LLM 的 product feature：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>服務&lt;/th>
 &lt;th>Cache TTL&lt;/th>
 &lt;th>Write cost&lt;/th>
 &lt;th>Read cost&lt;/th>
 &lt;th>觸發方式&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Anthropic（cache_control）&lt;/td>
 &lt;td>5min 預設、1h ext&lt;/td>
 &lt;td>1.25× 原價&lt;/td>
 &lt;td>0.1× 原價（90% 折扣）&lt;/td>
 &lt;td>明確 cache_control breakpoint&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>OpenAI&lt;/td>
 &lt;td>自動（隱式）&lt;/td>
 &lt;td>同原價&lt;/td>
 &lt;td>0.5× 原價（50% 折扣）&lt;/td>
 &lt;td>自動偵測重複 prefix（&amp;gt; 1024 token）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Bedrock（Anthropic）&lt;/td>
 &lt;td>5min&lt;/td>
 &lt;td>同 Anthropic&lt;/td>
 &lt;td>同上&lt;/td>
 &lt;td>同 Anthropic&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Gemini&lt;/td>
 &lt;td>自動 + explicit&lt;/td>
 &lt;td>視方案&lt;/td>
 &lt;td>視方案&lt;/td>
 &lt;td>implicit + context caching API&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：定價跟 TTL 隨時間更新、引用前以對應 vendor 當前文件為準。&lt;/p>&lt;/blockquote>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 LLM API docs / coding agent 設計 / cost optimization blog 看到「prompt cache」「context caching」「cache_control」就是這機制。寫 code 場景的判讀：&lt;/p></description><content:encoded><![CDATA[<p>Prompt cache 的核心概念是「<strong>LLM 服務端 / 推論伺服器把重複出現的 prompt prefix（如 system prompt + tool schema）的 <a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 暫存起來、後續 query 跳過該 prefix 的 <a href="/blog/llm/knowledge-cards/prefill/" data-link-title="Prefill" data-link-desc="Prompt 首次處理時的計算階段：把整段輸入跑過模型、產生 KV cache">prefill</a> 階段</strong>」。Anthropic / OpenAI / Bedrock / Gemini 都提供、最高 90% cost 折扣 + 13-31% <a href="/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT</a> 改善、是 coding agent / long-context 應用的核心 cost / latency 槓桿。</p>
<h2 id="概念位置">概念位置</h2>
<p>跟既有 cache 概念的層次：</p>
<table>
  <thead>
      <tr>
          <th>Cache 層</th>
          <th>範圍</th>
          <th>機制</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a></td>
          <td>單一 conversation 的同一次推論</td>
          <td>過去 token 的 K/V 暫存、autoregressive 才省重算</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/prefix-cache/" data-link-title="Prefix Cache" data-link-desc="把多個請求共用的前綴 prompt 的 KV cache 重用、省下重複 prefill 算力的優化、production 多用戶服務的常見設計">Prefix cache</a></td>
          <td>多 request 共用 prefix（同 server 同 model）</td>
          <td>跨 request 共用 KV cache、production 推論伺服器特性</td>
      </tr>
      <tr>
          <td><strong>Prompt cache（本卡）</strong></td>
          <td>跨 request 跨時間、雲端 LLM API 服務端</td>
          <td>服務端把 prefix 的 KV cache 持久化、有 TTL</td>
      </tr>
  </tbody>
</table>
<p>Prompt cache 的「保留範圍」跟「定價」是商業 LLM 的 product feature：</p>
<table>
  <thead>
      <tr>
          <th>服務</th>
          <th>Cache TTL</th>
          <th>Write cost</th>
          <th>Read cost</th>
          <th>觸發方式</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Anthropic（cache_control）</td>
          <td>5min 預設、1h ext</td>
          <td>1.25× 原價</td>
          <td>0.1× 原價（90% 折扣）</td>
          <td>明確 cache_control breakpoint</td>
      </tr>
      <tr>
          <td>OpenAI</td>
          <td>自動（隱式）</td>
          <td>同原價</td>
          <td>0.5× 原價（50% 折扣）</td>
          <td>自動偵測重複 prefix（&gt; 1024 token）</td>
      </tr>
      <tr>
          <td>Bedrock（Anthropic）</td>
          <td>5min</td>
          <td>同 Anthropic</td>
          <td>同上</td>
          <td>同 Anthropic</td>
      </tr>
      <tr>
          <td>Gemini</td>
          <td>自動 + explicit</td>
          <td>視方案</td>
          <td>視方案</td>
          <td>implicit + context caching API</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p><strong>事實查核註</strong>：定價跟 TTL 隨時間更新、引用前以對應 vendor 當前文件為準。</p></blockquote>
<h2 id="設計責任">設計責任</h2>
<p>讀 LLM API docs / coding agent 設計 / cost optimization blog 看到「prompt cache」「context caching」「cache_control」就是這機制。寫 code 場景的判讀：</p>
<ol>
<li><strong>誰最值得開</strong>：coding agent（system prompt + tool schema 經常 &gt; 10K token、每 turn 重用）、long-context RAG（檢索 chunks 重用）、long conversation（history 累積）</li>
<li><strong>設計原則</strong>：把不變的內容（system prompt、tool schema、固定文件）放 prefix；變動的（user query、最新 file content）放後面</li>
<li><strong>常見 anti-pattern</strong>：在 prefix 插入 timestamp / user-id / request-id → 每次 prefix 不同 → cache 從不命中、付 1.25× write cost 沒得回本</li>
<li><strong>5 分鐘 TTL 的意涵</strong>：query 之間間隔 &gt; 5 分鐘、cache 已 expire、要 1h ext TTL 才能撐長對話</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/context-budget/" data-link-title="Context Budget" data-link-desc="Coding agent 的 context window 拆分配額：system prompt &#43; tool schema &#43; history &#43; file content &#43; reasoning &#43; tool result 各佔多少、留多少 margin">context budget</a> 的關係</strong>：cache 攤平 scaffold 部分的 cost、所以可以放寬「scaffold ≤ 25%」的成本顧慮、focus 在「不超 context limit」即可</li>
</ol>
]]></content:encoded></item><item><title>Prompt Injection</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/prompt-injection/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/prompt-injection/</guid><description>&lt;p>Prompt injection 的核心概念是「攻擊者把惡意指令藏進 LLM 會讀到的內容（檔案、網頁、issue、tool 回傳）、誘導 LLM 忽略原本的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/system-prompt/" data-link-title="System Prompt" data-link-desc="LLM application 中由開發者預設、不直接顯示給使用者的指令層、定義模型的角色、行為規範、輸出格式">system prompt&lt;/a>、改執行攻擊者意圖的動作」。OWASP &lt;a href="https://owasp.org/www-project-top-10-for-large-language-model-applications/">LLM Top 10&lt;/a> 把它列為 LLM01、是 LLM application 安全的頭號威脅。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Prompt injection 的兩種主要形態：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>形態&lt;/th>
 &lt;th>描述&lt;/th>
 &lt;th>個人 dev 場景的觸發路徑&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Direct injection&lt;/td>
 &lt;td>使用者自己 prompt 內含惡意指令&lt;/td>
 &lt;td>較少發生、主要是測試場景&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Indirect injection&lt;/td>
 &lt;td>LLM 讀到的別人內容含惡意指令&lt;/td>
 &lt;td>主要威脅形態&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Indirect injection 的常見入口：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>檔案內容&lt;/strong>：codebase 中的 README、依賴的 package README、PDF / Word 文件&lt;/li>
&lt;li>&lt;strong>Web 內容&lt;/strong>：tool 抓的網頁、社群留言、PR 描述&lt;/li>
&lt;li>&lt;strong>tool 回傳結果&lt;/strong>：DB 查詢結果、API response、其他 service 回傳&lt;/li>
&lt;li>&lt;strong>使用者貼上內容&lt;/strong>：從外部複製貼上、帶進惡意 prompt&lt;/li>
&lt;li>&lt;strong>agent 自我循環中累積&lt;/strong>：sub-agent 回傳、長 agent loop 中前段 injection 影響後段&lt;/li>
&lt;/ol>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：prompt injection 的攻擊形態跟研究進展快速演進、本卡描述參考 &lt;a href="https://owasp.org/www-project-top-10-for-large-language-model-applications/">OWASP LLM Top 10 LLM01&lt;/a> 跟 Greshake et al. 的「Indirect Prompt Injection」論文、引用前以對應的最新版本為準。&lt;/p>&lt;/blockquote>
&lt;p>實際造成影響的不是 injection 本身、是 LLM 輸出後的下游動作：&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">injection → LLM 輸出 → 下游動作（這裡才是真正攻擊面）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ├── 使用者照建議貼到 shell 跑
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> ├── tool use 自動執行
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ├── 寫進 commit / 文件
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> └── 觸發下一個 agent&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 prompt injection 後可以解釋兩個現象：為什麼「擋住 injection」對 production LLM application 是不切實際的目標（外部內容會持續引入）、為什麼防禦重點應該放在「下游動作的可逆性 + review checkpoint」（injection 不可完全擋住、但後果可以收斂）。&lt;/p>
&lt;p>防禦設計的層次：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>降低觸發率&lt;/strong>：明確標記 untrusted 內容、強化模型對齊（vendor 端責任）。&lt;/li>
&lt;li>&lt;strong>限制能力上限&lt;/strong>：&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">tool use&lt;/a> 白名單、副作用可逆性、agent loop 步數限制。&lt;/li>
&lt;li>&lt;strong>後果可控&lt;/strong>：人為 review checkpoint、自動偵測異常（見 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/llm-as-service-detection-coverage/" data-link-title="LLM Service 偵測訊號覆蓋" data-link-desc="production LLM 服務的 detection 訊號設計：tool call 異常模式、prompt injection 觸發徵兆、abuse 跟濫用模式、跟既有 detection-coverage 框架的接合">LLM Service 偵測訊號覆蓋&lt;/a>）。&lt;/li>
&lt;/ol>
&lt;p>詳見 &lt;a href="https://tarrragon.github.io/blog/llm/06-security/prompt-injection-in-ide/" data-link-title="6.3 IDE 場景的 prompt injection" data-link-desc="個人 dev 場景下 IDE 寫 code 工作流的 prompt injection：codebase 內容、外部文件、剪貼簿作為攻擊面、跟雲端 LLM 場景的差異">6.3 IDE 場景的 prompt injection&lt;/a> 跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/llm-prompt-injection-in-agent/" data-link-title="LLM Agent Prompt Injection 後果治理" data-link-desc="production LLM agent 場景的 prompt injection 後果：tool spec 設計、agent loop 限制、review checkpoint、跟 incident workflow 的接合">LLM Agent Prompt Injection 後果治理&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Prompt injection 的核心概念是「攻擊者把惡意指令藏進 LLM 會讀到的內容（檔案、網頁、issue、tool 回傳）、誘導 LLM 忽略原本的 <a href="/blog/llm/knowledge-cards/system-prompt/" data-link-title="System Prompt" data-link-desc="LLM application 中由開發者預設、不直接顯示給使用者的指令層、定義模型的角色、行為規範、輸出格式">system prompt</a>、改執行攻擊者意圖的動作」。OWASP <a href="https://owasp.org/www-project-top-10-for-large-language-model-applications/">LLM Top 10</a> 把它列為 LLM01、是 LLM application 安全的頭號威脅。</p>
<h2 id="概念位置">概念位置</h2>
<p>Prompt injection 的兩種主要形態：</p>
<table>
  <thead>
      <tr>
          <th>形態</th>
          <th>描述</th>
          <th>個人 dev 場景的觸發路徑</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Direct injection</td>
          <td>使用者自己 prompt 內含惡意指令</td>
          <td>較少發生、主要是測試場景</td>
      </tr>
      <tr>
          <td>Indirect injection</td>
          <td>LLM 讀到的別人內容含惡意指令</td>
          <td>主要威脅形態</td>
      </tr>
  </tbody>
</table>
<p>Indirect injection 的常見入口：</p>
<ol>
<li><strong>檔案內容</strong>：codebase 中的 README、依賴的 package README、PDF / Word 文件</li>
<li><strong>Web 內容</strong>：tool 抓的網頁、社群留言、PR 描述</li>
<li><strong>tool 回傳結果</strong>：DB 查詢結果、API response、其他 service 回傳</li>
<li><strong>使用者貼上內容</strong>：從外部複製貼上、帶進惡意 prompt</li>
<li><strong>agent 自我循環中累積</strong>：sub-agent 回傳、長 agent loop 中前段 injection 影響後段</li>
</ol>
<blockquote>
<p><strong>事實查核註</strong>：prompt injection 的攻擊形態跟研究進展快速演進、本卡描述參考 <a href="https://owasp.org/www-project-top-10-for-large-language-model-applications/">OWASP LLM Top 10 LLM01</a> 跟 Greshake et al. 的「Indirect Prompt Injection」論文、引用前以對應的最新版本為準。</p></blockquote>
<p>實際造成影響的不是 injection 本身、是 LLM 輸出後的下游動作：</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">injection → LLM 輸出 → 下游動作（這裡才是真正攻擊面）
</span></span><span class="line"><span class="ln">2</span><span class="cl">                       ├── 使用者照建議貼到 shell 跑
</span></span><span class="line"><span class="ln">3</span><span class="cl">                       ├── tool use 自動執行
</span></span><span class="line"><span class="ln">4</span><span class="cl">                       ├── 寫進 commit / 文件
</span></span><span class="line"><span class="ln">5</span><span class="cl">                       └── 觸發下一個 agent</span></span></code></pre></div><h2 id="設計責任">設計責任</h2>
<p>理解 prompt injection 後可以解釋兩個現象：為什麼「擋住 injection」對 production LLM application 是不切實際的目標（外部內容會持續引入）、為什麼防禦重點應該放在「下游動作的可逆性 + review checkpoint」（injection 不可完全擋住、但後果可以收斂）。</p>
<p>防禦設計的層次：</p>
<ol>
<li><strong>降低觸發率</strong>：明確標記 untrusted 內容、強化模型對齊（vendor 端責任）。</li>
<li><strong>限制能力上限</strong>：<a href="/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">tool use</a> 白名單、副作用可逆性、agent loop 步數限制。</li>
<li><strong>後果可控</strong>：人為 review checkpoint、自動偵測異常（見 <a href="/blog/backend/07-security-data-protection/llm-as-service-detection-coverage/" data-link-title="LLM Service 偵測訊號覆蓋" data-link-desc="production LLM 服務的 detection 訊號設計：tool call 異常模式、prompt injection 觸發徵兆、abuse 跟濫用模式、跟既有 detection-coverage 框架的接合">LLM Service 偵測訊號覆蓋</a>）。</li>
</ol>
<p>詳見 <a href="/blog/llm/06-security/prompt-injection-in-ide/" data-link-title="6.3 IDE 場景的 prompt injection" data-link-desc="個人 dev 場景下 IDE 寫 code 工作流的 prompt injection：codebase 內容、外部文件、剪貼簿作為攻擊面、跟雲端 LLM 場景的差異">6.3 IDE 場景的 prompt injection</a> 跟 <a href="/blog/backend/07-security-data-protection/llm-prompt-injection-in-agent/" data-link-title="LLM Agent Prompt Injection 後果治理" data-link-desc="production LLM agent 場景的 prompt injection 後果：tool spec 設計、agent loop 限制、review checkpoint、跟 incident workflow 的接合">LLM Agent Prompt Injection 後果治理</a>。</p>
]]></content:encoded></item><item><title>QLoRA</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/qlora/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/qlora/</guid><description>&lt;p>QLoRA（Quantized LoRA、Dettmers et al., 2023）的核心概念是「&lt;strong>把 base model 量化到 4-bit（凍住）+ 用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/lora/" data-link-title="LoRA" data-link-desc="Low-Rank Adaptation：凍住原模型權重、只訓兩個小矩陣的 parameter-efficient fine-tuning">LoRA&lt;/a> 訓兩個小矩陣&lt;/strong>」。讓消費級 GPU（24GB VRAM）就能 fine-tune 30B-70B 模型、是現代 local fine-tuning 主流。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>QLoRA vs full fine-tuning vs LoRA 的記憶體需求對比（70B 模型）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>方法&lt;/th>
 &lt;th>Base model 精度&lt;/th>
 &lt;th>訓練記憶體&lt;/th>
 &lt;th>適合硬體&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Full fine-tuning&lt;/td>
 &lt;td>BF16&lt;/td>
 &lt;td>~280 GB&lt;/td>
 &lt;td>多卡 H100&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LoRA&lt;/td>
 &lt;td>BF16&lt;/td>
 &lt;td>~150 GB&lt;/td>
 &lt;td>多卡 A100 / H100&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>QLoRA&lt;/strong>&lt;/td>
 &lt;td>4-bit (NF4)&lt;/td>
 &lt;td>&lt;strong>~40 GB&lt;/strong>&lt;/td>
 &lt;td>單張 A100 80GB / 雙 24GB GPU&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>QLoRA on 7B&lt;/td>
 &lt;td>4-bit&lt;/td>
 &lt;td>~6-8 GB&lt;/td>
 &lt;td>消費級 16GB+ GPU&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>QLoRA on 30-32B&lt;/td>
 &lt;td>4-bit&lt;/td>
 &lt;td>~20-24 GB&lt;/td>
 &lt;td>消費級 24GB+ GPU（5090）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>QLoRA 的核心創新（簡化）：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>4-bit NormalFloat（NF4）量化&lt;/strong>：base model 用 4-bit 表示、精度損失低於原 INT4&lt;/li>
&lt;li>&lt;strong>Double quantization&lt;/strong>：量化常數本身也量化、再省一點記憶體&lt;/li>
&lt;li>&lt;strong>Paged optimizer&lt;/strong>：optimizer state 跑 CPU offload、避免訓練 spike OOM&lt;/li>
&lt;li>&lt;strong>LoRA on 4-bit base&lt;/strong>：&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/lora/" data-link-title="LoRA" data-link-desc="Low-Rank Adaptation：凍住原模型權重、只訓兩個小矩陣的 parameter-efficient fine-tuning">LoRA&lt;/a> 訓的 A、B 矩陣仍是 BF16、只有 base 是 4-bit、推論時 dequantize → 加 LoRA → forward&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 fine-tuning 教學 / Hugging Face PEFT 文件看到「QLoRA」「bnb-4bit」就是這方法。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>想 fine-tune 大模型在消費級硬體&lt;/strong>：QLoRA 是 default 選擇（不用 QLoRA、就只能訓 &amp;lt; 7B）&lt;/li>
&lt;li>&lt;strong>記憶體預算估算&lt;/strong>：QLoRA 訓 N B 模型約需 &lt;code>0.6 × N GB&lt;/code> VRAM（30B → ~18GB、70B → ~42GB）&lt;/li>
&lt;li>&lt;strong>品質 vs full fine-tune 差距&lt;/strong>：QLoRA 後合併權重的模型、實測跟 full fine-tune 接近（差距 &amp;lt; 2-3%）、對多數場景可接受&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/lora/" data-link-title="LoRA" data-link-desc="Low-Rank Adaptation：凍住原模型權重、只訓兩個小矩陣的 parameter-efficient fine-tuning">LoRA&lt;/a> 卡片區分&lt;/strong>：純 LoRA 是「base 不量化、訓 LoRA」、QLoRA 是「base 量化 4-bit、訓 LoRA」；QLoRA 是 LoRA 的延伸、不是替代&lt;/li>
&lt;li>&lt;strong>推論時的選擇&lt;/strong>：QLoRA fine-tuned 模型可以「base 仍 4-bit + 載入 LoRA adapter」推論、記憶體用量低；也可以 merge 後用 GGUF Q4_K_M、跟 base 原相同&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>QLoRA（Quantized LoRA、Dettmers et al., 2023）的核心概念是「<strong>把 base model 量化到 4-bit（凍住）+ 用 <a href="/blog/llm/knowledge-cards/lora/" data-link-title="LoRA" data-link-desc="Low-Rank Adaptation：凍住原模型權重、只訓兩個小矩陣的 parameter-efficient fine-tuning">LoRA</a> 訓兩個小矩陣</strong>」。讓消費級 GPU（24GB VRAM）就能 fine-tune 30B-70B 模型、是現代 local fine-tuning 主流。</p>
<h2 id="概念位置">概念位置</h2>
<p>QLoRA vs full fine-tuning vs LoRA 的記憶體需求對比（70B 模型）：</p>
<table>
  <thead>
      <tr>
          <th>方法</th>
          <th>Base model 精度</th>
          <th>訓練記憶體</th>
          <th>適合硬體</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Full fine-tuning</td>
          <td>BF16</td>
          <td>~280 GB</td>
          <td>多卡 H100</td>
      </tr>
      <tr>
          <td>LoRA</td>
          <td>BF16</td>
          <td>~150 GB</td>
          <td>多卡 A100 / H100</td>
      </tr>
      <tr>
          <td><strong>QLoRA</strong></td>
          <td>4-bit (NF4)</td>
          <td><strong>~40 GB</strong></td>
          <td>單張 A100 80GB / 雙 24GB GPU</td>
      </tr>
      <tr>
          <td>QLoRA on 7B</td>
          <td>4-bit</td>
          <td>~6-8 GB</td>
          <td>消費級 16GB+ GPU</td>
      </tr>
      <tr>
          <td>QLoRA on 30-32B</td>
          <td>4-bit</td>
          <td>~20-24 GB</td>
          <td>消費級 24GB+ GPU（5090）</td>
      </tr>
  </tbody>
</table>
<p>QLoRA 的核心創新（簡化）：</p>
<ol>
<li><strong>4-bit NormalFloat（NF4）量化</strong>：base model 用 4-bit 表示、精度損失低於原 INT4</li>
<li><strong>Double quantization</strong>：量化常數本身也量化、再省一點記憶體</li>
<li><strong>Paged optimizer</strong>：optimizer state 跑 CPU offload、避免訓練 spike OOM</li>
<li><strong>LoRA on 4-bit base</strong>：<a href="/blog/llm/knowledge-cards/lora/" data-link-title="LoRA" data-link-desc="Low-Rank Adaptation：凍住原模型權重、只訓兩個小矩陣的 parameter-efficient fine-tuning">LoRA</a> 訓的 A、B 矩陣仍是 BF16、只有 base 是 4-bit、推論時 dequantize → 加 LoRA → forward</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 fine-tuning 教學 / Hugging Face PEFT 文件看到「QLoRA」「bnb-4bit」就是這方法。寫 code 場景的判讀：</p>
<ol>
<li><strong>想 fine-tune 大模型在消費級硬體</strong>：QLoRA 是 default 選擇（不用 QLoRA、就只能訓 &lt; 7B）</li>
<li><strong>記憶體預算估算</strong>：QLoRA 訓 N B 模型約需 <code>0.6 × N GB</code> VRAM（30B → ~18GB、70B → ~42GB）</li>
<li><strong>品質 vs full fine-tune 差距</strong>：QLoRA 後合併權重的模型、實測跟 full fine-tune 接近（差距 &lt; 2-3%）、對多數場景可接受</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/lora/" data-link-title="LoRA" data-link-desc="Low-Rank Adaptation：凍住原模型權重、只訓兩個小矩陣的 parameter-efficient fine-tuning">LoRA</a> 卡片區分</strong>：純 LoRA 是「base 不量化、訓 LoRA」、QLoRA 是「base 量化 4-bit、訓 LoRA」；QLoRA 是 LoRA 的延伸、不是替代</li>
<li><strong>推論時的選擇</strong>：QLoRA fine-tuned 模型可以「base 仍 4-bit + 載入 LoRA adapter」推論、記憶體用量低；也可以 merge 後用 GGUF Q4_K_M、跟 base 原相同</li>
</ol>
]]></content:encoded></item><item><title>Reasoning Model</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/reasoning-model/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/reasoning-model/</guid><description>&lt;p>Reasoning model 的核心概念是「&lt;strong>透過後訓練（多半是 RL）讓模型自然在回答前產出長 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/chain-of-thought/" data-link-title="Chain-of-Thought（CoT）" data-link-desc="讓 LLM 先輸出推理步驟再給最終答案的 prompting / 訓練方式、reasoning model 的基礎機制">chain-of-thought&lt;/a> reasoning trace 的 LLM 變體&lt;/strong>」。代表是 OpenAI o1 / o3、DeepSeek-R1、Qwen-QwQ、Claude 3.7 Sonnet thinking 等。Reasoning model 是 2024-2026 LLM 的最大 paradigm shift、把 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/test-time-compute/" data-link-title="Test-Time Compute" data-link-desc="推論時動態增加計算量換取答案品質的 paradigm、reasoning model 跟 best-of-N 的共同基底">test-time compute&lt;/a> 變成可訓練、可 scale 的維度。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Reasoning model 跟一般 instruction-tuned model 的差異：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>Instruction-tuned model（如 Gemma 4 instruct）&lt;/th>
 &lt;th>Reasoning model（如 DeepSeek-R1）&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>訓練後階段&lt;/td>
 &lt;td>SFT + RLHF / DPO&lt;/td>
 &lt;td>SFT + RLHF + &lt;strong>reasoning RL&lt;/strong>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>推論行為&lt;/td>
 &lt;td>直接答（或短 CoT）&lt;/td>
 &lt;td>先生 reasoning trace（數百到數千 token）再答&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>適合任務&lt;/td>
 &lt;td>對話、寫作、簡單 coding、查詢&lt;/td>
 &lt;td>math、debug、algorithm、複雜 reasoning&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Token 消耗&lt;/td>
 &lt;td>直接生答案 token&lt;/td>
 &lt;td>reasoning trace 通常 5-50× 於最終答案&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>推論成本&lt;/td>
 &lt;td>1×&lt;/td>
 &lt;td>5-20×（依任務難度）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Context 需求&lt;/td>
 &lt;td>一般&lt;/td>
 &lt;td>較大（要容納 reasoning trace）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>主流 reasoning model 比較（2026/5）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>模型&lt;/th>
 &lt;th>開源 / 商業&lt;/th>
 &lt;th>推理 trace 格式&lt;/th>
 &lt;th>本地跑可行性&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>OpenAI o1 / o3&lt;/td>
 &lt;td>商業 API&lt;/td>
 &lt;td>對使用者隱藏&lt;/td>
 &lt;td>不可&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DeepSeek-R1（full）&lt;/td>
 &lt;td>開源&lt;/td>
 &lt;td>&lt;code>&amp;lt;think&amp;gt;...&amp;lt;/think&amp;gt;&lt;/code> 標記&lt;/td>
 &lt;td>671B 太大、本地不實際&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DeepSeek-R1 distill&lt;/td>
 &lt;td>開源&lt;/td>
 &lt;td>同上&lt;/td>
 &lt;td>7B / 14B / 32B distill 可在 24-48GB Mac 跑&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Qwen-QwQ&lt;/td>
 &lt;td>開源&lt;/td>
 &lt;td>純文字 reasoning（無特殊 token）&lt;/td>
 &lt;td>32B 可在 64GB+ Mac 跑&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Claude 3.7 Sonnet thinking&lt;/td>
 &lt;td>商業 API&lt;/td>
 &lt;td>extended thinking field&lt;/td>
 &lt;td>不可&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Gemini 2.5 Flash thinking&lt;/td>
 &lt;td>商業 API&lt;/td>
 &lt;td>thinking field&lt;/td>
 &lt;td>不可&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 model card / paper 看到「reasoning」「thinking」「test-time compute」「R1-style」就是這個 family。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>本地用 distill 版本是合理起點&lt;/strong>：DeepSeek-R1-Distill-Qwen-32B、QwQ-32B 等是「正常 32B 模型 + reasoning 後訓練」的產物、跑得起來&lt;/li>
&lt;li>&lt;strong>適合的任務&lt;/strong>：debug 複雜 bug、算 algorithm complexity、設計 multi-step refactor、解 leetcode hard&lt;/li>
&lt;li>&lt;strong>不適合的任務&lt;/strong>：autocomplete（reasoning trace 拉長 TTFT、體感變慢）、簡單 docstring 補完、純文字翻譯&lt;/li>
&lt;li>&lt;strong>混用策略&lt;/strong>：日常用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/instruction-tuned/" data-link-title="Instruction-Tuned Model" data-link-desc="經過指令微調的模型：會跟著 prompt 走、回答使用者問題">instruction-tuned model&lt;/a>（如 Gemma 4 31B、Qwen3-Coder）+ 複雜任務切到本地 reasoning model（如 QwQ-32B）+ 真正困難任務切雲端 o1 / R1 full&lt;/li>
&lt;li>&lt;strong>記憶體預算&lt;/strong>：reasoning model 本身大小跟對應 instruct model 相當、但要預留更大 &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> 給長 reasoning trace（context 通常開 32K+）&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Reasoning model 的核心概念是「<strong>透過後訓練（多半是 RL）讓模型自然在回答前產出長 <a href="/blog/llm/knowledge-cards/chain-of-thought/" data-link-title="Chain-of-Thought（CoT）" data-link-desc="讓 LLM 先輸出推理步驟再給最終答案的 prompting / 訓練方式、reasoning model 的基礎機制">chain-of-thought</a> reasoning trace 的 LLM 變體</strong>」。代表是 OpenAI o1 / o3、DeepSeek-R1、Qwen-QwQ、Claude 3.7 Sonnet thinking 等。Reasoning model 是 2024-2026 LLM 的最大 paradigm shift、把 <a href="/blog/llm/knowledge-cards/test-time-compute/" data-link-title="Test-Time Compute" data-link-desc="推論時動態增加計算量換取答案品質的 paradigm、reasoning model 跟 best-of-N 的共同基底">test-time compute</a> 變成可訓練、可 scale 的維度。</p>
<h2 id="概念位置">概念位置</h2>
<p>Reasoning model 跟一般 instruction-tuned model 的差異：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>Instruction-tuned model（如 Gemma 4 instruct）</th>
          <th>Reasoning model（如 DeepSeek-R1）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>訓練後階段</td>
          <td>SFT + RLHF / DPO</td>
          <td>SFT + RLHF + <strong>reasoning RL</strong></td>
      </tr>
      <tr>
          <td>推論行為</td>
          <td>直接答（或短 CoT）</td>
          <td>先生 reasoning trace（數百到數千 token）再答</td>
      </tr>
      <tr>
          <td>適合任務</td>
          <td>對話、寫作、簡單 coding、查詢</td>
          <td>math、debug、algorithm、複雜 reasoning</td>
      </tr>
      <tr>
          <td>Token 消耗</td>
          <td>直接生答案 token</td>
          <td>reasoning trace 通常 5-50× 於最終答案</td>
      </tr>
      <tr>
          <td>推論成本</td>
          <td>1×</td>
          <td>5-20×（依任務難度）</td>
      </tr>
      <tr>
          <td>Context 需求</td>
          <td>一般</td>
          <td>較大（要容納 reasoning trace）</td>
      </tr>
  </tbody>
</table>
<p>主流 reasoning model 比較（2026/5）：</p>
<table>
  <thead>
      <tr>
          <th>模型</th>
          <th>開源 / 商業</th>
          <th>推理 trace 格式</th>
          <th>本地跑可行性</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>OpenAI o1 / o3</td>
          <td>商業 API</td>
          <td>對使用者隱藏</td>
          <td>不可</td>
      </tr>
      <tr>
          <td>DeepSeek-R1（full）</td>
          <td>開源</td>
          <td><code>&lt;think&gt;...&lt;/think&gt;</code> 標記</td>
          <td>671B 太大、本地不實際</td>
      </tr>
      <tr>
          <td>DeepSeek-R1 distill</td>
          <td>開源</td>
          <td>同上</td>
          <td>7B / 14B / 32B distill 可在 24-48GB Mac 跑</td>
      </tr>
      <tr>
          <td>Qwen-QwQ</td>
          <td>開源</td>
          <td>純文字 reasoning（無特殊 token）</td>
          <td>32B 可在 64GB+ Mac 跑</td>
      </tr>
      <tr>
          <td>Claude 3.7 Sonnet thinking</td>
          <td>商業 API</td>
          <td>extended thinking field</td>
          <td>不可</td>
      </tr>
      <tr>
          <td>Gemini 2.5 Flash thinking</td>
          <td>商業 API</td>
          <td>thinking field</td>
          <td>不可</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 model card / paper 看到「reasoning」「thinking」「test-time compute」「R1-style」就是這個 family。寫 code 場景的判讀：</p>
<ol>
<li><strong>本地用 distill 版本是合理起點</strong>：DeepSeek-R1-Distill-Qwen-32B、QwQ-32B 等是「正常 32B 模型 + reasoning 後訓練」的產物、跑得起來</li>
<li><strong>適合的任務</strong>：debug 複雜 bug、算 algorithm complexity、設計 multi-step refactor、解 leetcode hard</li>
<li><strong>不適合的任務</strong>：autocomplete（reasoning trace 拉長 TTFT、體感變慢）、簡單 docstring 補完、純文字翻譯</li>
<li><strong>混用策略</strong>：日常用 <a href="/blog/llm/knowledge-cards/instruction-tuned/" data-link-title="Instruction-Tuned Model" data-link-desc="經過指令微調的模型：會跟著 prompt 走、回答使用者問題">instruction-tuned model</a>（如 Gemma 4 31B、Qwen3-Coder）+ 複雜任務切到本地 reasoning model（如 QwQ-32B）+ 真正困難任務切雲端 o1 / R1 full</li>
<li><strong>記憶體預算</strong>：reasoning model 本身大小跟對應 instruct model 相當、但要預留更大 <a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 給長 reasoning trace（context 通常開 32K+）</li>
</ol>
]]></content:encoded></item><item><title>Refusal Rate</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/refusal-rate/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/refusal-rate/</guid><description>&lt;p>Refusal rate 的核心概念是「LLM 拒絕回答 prompt 的比例」。LLM 在訓練階段（特別是 RLHF）會學到「對特定類型的請求說『我不能幫忙這個』」、production 服務通常會監控這個比例作為對齊強度跟異常行為偵測的訊號之一。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Refusal 行為的典型形態：&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>安全相關拒絕&lt;/td>
 &lt;td>&amp;ldquo;Sorry, I can&amp;rsquo;t help with that request.&amp;rdquo;&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>政策相關拒絕&lt;/td>
 &lt;td>&amp;ldquo;I&amp;rsquo;m not able to discuss specific medical advice.&amp;rdquo;&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>能力相關拒絕&lt;/td>
 &lt;td>&amp;ldquo;I don&amp;rsquo;t have real-time data access.&amp;rdquo;&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>模糊拒絕（soft refusal）&lt;/td>
 &lt;td>&amp;ldquo;That&amp;rsquo;s an interesting question, but&amp;hellip;&amp;rdquo;&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Refusal rate 作為偵測訊號的兩個方向：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>率突然下降&lt;/strong>：可能是對齊被繞過、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prompt-injection/" data-link-title="Prompt Injection" data-link-desc="把惡意指令藏進 LLM 會讀到的內容、誘導 LLM 跑出非開發者預期行為的攻擊類別、OWASP LLM01 列入頭號威脅">prompt injection&lt;/a> 攻擊在進行、或新版本模型對齊變弱。&lt;/li>
&lt;li>&lt;strong>率突然上升&lt;/strong>：可能是訓練資料或對齊政策變嚴、影響使用者體驗、或 vendor 端政策調整。&lt;/li>
&lt;/ol>
&lt;p>實作上、偵測 refusal 通常用簡單 pattern matching（看是否含 &amp;ldquo;I can&amp;rsquo;t&amp;rdquo; / &amp;ldquo;I&amp;rsquo;m not able&amp;rdquo; / &amp;ldquo;Sorry&amp;rdquo; 等）或更精確的 classifier；具體實作依 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/detection-coverage-and-signal-governance/" data-link-title="7.13 偵測覆蓋率與訊號治理" data-link-desc="定義偵測覆蓋、訊號品質與誤報成本的治理問題">偵測平台&lt;/a> 設計。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：refusal rate 的標準化測量方式、跟「對齊強度」的對應關係仍在研究演進、不同 vendor 跟 model 的 baseline 差異大、引用前以對應模型的 model card 跟最新研究為準。&lt;/p>&lt;/blockquote>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 refusal rate 後可以解釋兩個現象：為什麼 production LLM 服務監控 refusal rate（變化是異常訊號）、為什麼開源模型的 refusal rate 通常低於商業旗艦（前者 safety RLHF 投入較少）。&lt;/p>
&lt;p>production 設計時、refusal rate 是 content 層偵測訊號之一、需配合 tool call 序列、token usage、prompt pattern 等其他訊號才能形成完整偵測覆蓋。詳見 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/llm-as-service-detection-coverage/" data-link-title="LLM Service 偵測訊號覆蓋" data-link-desc="production LLM 服務的 detection 訊號設計：tool call 異常模式、prompt injection 觸發徵兆、abuse 跟濫用模式、跟既有 detection-coverage 框架的接合">LLM Service 偵測訊號覆蓋&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Refusal rate 的核心概念是「LLM 拒絕回答 prompt 的比例」。LLM 在訓練階段（特別是 RLHF）會學到「對特定類型的請求說『我不能幫忙這個』」、production 服務通常會監控這個比例作為對齊強度跟異常行為偵測的訊號之一。</p>
<h2 id="概念位置">概念位置</h2>
<p>Refusal 行為的典型形態：</p>
<table>
  <thead>
      <tr>
          <th>形態</th>
          <th>例子</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>安全相關拒絕</td>
          <td>&ldquo;Sorry, I can&rsquo;t help with that request.&rdquo;</td>
      </tr>
      <tr>
          <td>政策相關拒絕</td>
          <td>&ldquo;I&rsquo;m not able to discuss specific medical advice.&rdquo;</td>
      </tr>
      <tr>
          <td>能力相關拒絕</td>
          <td>&ldquo;I don&rsquo;t have real-time data access.&rdquo;</td>
      </tr>
      <tr>
          <td>模糊拒絕（soft refusal）</td>
          <td>&ldquo;That&rsquo;s an interesting question, but&hellip;&rdquo;</td>
      </tr>
  </tbody>
</table>
<p>Refusal rate 作為偵測訊號的兩個方向：</p>
<ol>
<li><strong>率突然下降</strong>：可能是對齊被繞過、<a href="/blog/llm/knowledge-cards/prompt-injection/" data-link-title="Prompt Injection" data-link-desc="把惡意指令藏進 LLM 會讀到的內容、誘導 LLM 跑出非開發者預期行為的攻擊類別、OWASP LLM01 列入頭號威脅">prompt injection</a> 攻擊在進行、或新版本模型對齊變弱。</li>
<li><strong>率突然上升</strong>：可能是訓練資料或對齊政策變嚴、影響使用者體驗、或 vendor 端政策調整。</li>
</ol>
<p>實作上、偵測 refusal 通常用簡單 pattern matching（看是否含 &ldquo;I can&rsquo;t&rdquo; / &ldquo;I&rsquo;m not able&rdquo; / &ldquo;Sorry&rdquo; 等）或更精確的 classifier；具體實作依 <a href="/blog/backend/07-security-data-protection/detection-coverage-and-signal-governance/" data-link-title="7.13 偵測覆蓋率與訊號治理" data-link-desc="定義偵測覆蓋、訊號品質與誤報成本的治理問題">偵測平台</a> 設計。</p>
<blockquote>
<p><strong>事實查核註</strong>：refusal rate 的標準化測量方式、跟「對齊強度」的對應關係仍在研究演進、不同 vendor 跟 model 的 baseline 差異大、引用前以對應模型的 model card 跟最新研究為準。</p></blockquote>
<h2 id="設計責任">設計責任</h2>
<p>理解 refusal rate 後可以解釋兩個現象：為什麼 production LLM 服務監控 refusal rate（變化是異常訊號）、為什麼開源模型的 refusal rate 通常低於商業旗艦（前者 safety RLHF 投入較少）。</p>
<p>production 設計時、refusal rate 是 content 層偵測訊號之一、需配合 tool call 序列、token usage、prompt pattern 等其他訊號才能形成完整偵測覆蓋。詳見 <a href="/blog/backend/07-security-data-protection/llm-as-service-detection-coverage/" data-link-title="LLM Service 偵測訊號覆蓋" data-link-desc="production LLM 服務的 detection 訊號設計：tool call 異常模式、prompt injection 觸發徵兆、abuse 跟濫用模式、跟既有 detection-coverage 框架的接合">LLM Service 偵測訊號覆蓋</a>。</p>
]]></content:encoded></item><item><title>Reranker</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/reranker/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/reranker/</guid><description>&lt;p>Reranker 的核心概念是「&lt;strong>對 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">retrieval&lt;/a> 第一階段拿到的 top-K（如 50）結果、用 cross-encoder 模型重新評分、排出 top-N（如 5）給 LLM&lt;/strong>」。是 RAG 第二階段、補 bi-encoder（&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model&lt;/a>）對 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap&lt;/a> 的細粒度匹配不足、品質提升明顯（recall@5 通常 +10-30%）但成本 / latency 增加。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Bi-encoder vs cross-encoder 的差別：&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">Bi-encoder（embedding model、retrieval 第一階段）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> query → embedding A
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> document → embedding B（pre-compute、存 vector DB）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> score = cosine(A, B)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> → 快、可 pre-compute、適合海量 retrieval
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">Cross-encoder（reranker、retrieval 第二階段）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl"> (query, document) 一起進模型 → 直接輸出 relevance score
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">9&lt;/span>&lt;span class="cl"> → 慢（每對都要 forward pass）、不可 pre-compute、適合 top-K rerank&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>主流 reranker：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Reranker&lt;/th>
 &lt;th>類型&lt;/th>
 &lt;th>適合場景&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Cohere Rerank 3&lt;/td>
 &lt;td>SaaS API&lt;/td>
 &lt;td>Production 高品質、多語&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Jina Reranker v2&lt;/td>
 &lt;td>開源&lt;/td>
 &lt;td>開源、多語&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>BGE Reranker（bge-reranker-v2-m3）&lt;/td>
 &lt;td>開源&lt;/td>
 &lt;td>開源中文友善&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Voyage rerank-2&lt;/td>
 &lt;td>SaaS API&lt;/td>
 &lt;td>跟 voyage embedding 配對&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>ColBERT v2&lt;/td>
 &lt;td>Late interaction&lt;/td>
 &lt;td>介於 bi 跟 cross encoder&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 RAG / production retrieval docs 看到「reranker」「cross-encoder」「rerank stage」就是這 framing。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>何時值得加 reranker&lt;/strong>：retrieval 結果有「相關但不精確」問題、top-K hit rate 高但 top-5 hit rate 低、有 latency / cost budget&lt;/li>
&lt;li>&lt;strong>何時不需要&lt;/strong>：小語料（&amp;lt; 1000 docs、retrieval 已準）、明確 keyword 任務（BM25 已準）、latency 敏感（&amp;lt; 100ms TTFT）&lt;/li>
&lt;li>&lt;strong>Pipeline 設計&lt;/strong>：bi-encoder retrieve top-50 → reranker rerank → 給 LLM top-5；50/5 是常見起點、看實測調&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/hybrid-search/" data-link-title="Hybrid Search" data-link-desc="把字面 retrieval（BM25）跟語意 retrieval（embedding）的結果用 RRF 等方法合併、補單一路線的盲點">hybrid search&lt;/a> 結合&lt;/strong>：BM25 + embedding hybrid retrieve top-50 → reranker rerank → LLM、是 production RAG 標配&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &amp;#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG 章節&lt;/a> 的關係&lt;/strong>：本卡是定義、章節是 retrieval pipeline 設計（含 reranker / hybrid 段）&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Reranker 的核心概念是「<strong>對 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">retrieval</a> 第一階段拿到的 top-K（如 50）結果、用 cross-encoder 模型重新評分、排出 top-N（如 5）給 LLM</strong>」。是 RAG 第二階段、補 bi-encoder（<a href="/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model</a>）對 <a href="/blog/llm/knowledge-cards/query-document-gap/" data-link-title="Query-Document Gap" data-link-desc="使用者 query 與文件語言在詞彙、形態、抽象層級或領域分佈上的落差，是 RAG retrieval miss 的常見原因">query-document gap</a> 的細粒度匹配不足、品質提升明顯（recall@5 通常 +10-30%）但成本 / latency 增加。</p>
<h2 id="概念位置">概念位置</h2>
<p>Bi-encoder vs cross-encoder 的差別：</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">Bi-encoder（embedding model、retrieval 第一階段）：
</span></span><span class="line"><span class="ln">2</span><span class="cl">  query → embedding A
</span></span><span class="line"><span class="ln">3</span><span class="cl">  document → embedding B（pre-compute、存 vector DB）
</span></span><span class="line"><span class="ln">4</span><span class="cl">  score = cosine(A, B)
</span></span><span class="line"><span class="ln">5</span><span class="cl">  → 快、可 pre-compute、適合海量 retrieval
</span></span><span class="line"><span class="ln">6</span><span class="cl">
</span></span><span class="line"><span class="ln">7</span><span class="cl">Cross-encoder（reranker、retrieval 第二階段）：
</span></span><span class="line"><span class="ln">8</span><span class="cl">  (query, document) 一起進模型 → 直接輸出 relevance score
</span></span><span class="line"><span class="ln">9</span><span class="cl">  → 慢（每對都要 forward pass）、不可 pre-compute、適合 top-K rerank</span></span></code></pre></div><p>主流 reranker：</p>
<table>
  <thead>
      <tr>
          <th>Reranker</th>
          <th>類型</th>
          <th>適合場景</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Cohere Rerank 3</td>
          <td>SaaS API</td>
          <td>Production 高品質、多語</td>
      </tr>
      <tr>
          <td>Jina Reranker v2</td>
          <td>開源</td>
          <td>開源、多語</td>
      </tr>
      <tr>
          <td>BGE Reranker（bge-reranker-v2-m3）</td>
          <td>開源</td>
          <td>開源中文友善</td>
      </tr>
      <tr>
          <td>Voyage rerank-2</td>
          <td>SaaS API</td>
          <td>跟 voyage embedding 配對</td>
      </tr>
      <tr>
          <td>ColBERT v2</td>
          <td>Late interaction</td>
          <td>介於 bi 跟 cross encoder</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 RAG / production retrieval docs 看到「reranker」「cross-encoder」「rerank stage」就是這 framing。寫 code 場景的判讀：</p>
<ol>
<li><strong>何時值得加 reranker</strong>：retrieval 結果有「相關但不精確」問題、top-K hit rate 高但 top-5 hit rate 低、有 latency / cost budget</li>
<li><strong>何時不需要</strong>：小語料（&lt; 1000 docs、retrieval 已準）、明確 keyword 任務（BM25 已準）、latency 敏感（&lt; 100ms TTFT）</li>
<li><strong>Pipeline 設計</strong>：bi-encoder retrieve top-50 → reranker rerank → 給 LLM top-5；50/5 是常見起點、看實測調</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/hybrid-search/" data-link-title="Hybrid Search" data-link-desc="把字面 retrieval（BM25）跟語意 retrieval（embedding）的結果用 RRF 等方法合併、補單一路線的盲點">hybrid search</a> 結合</strong>：BM25 + embedding hybrid retrieve top-50 → reranker rerank → LLM、是 production RAG 標配</li>
<li><strong>跟 <a href="/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG 章節</a> 的關係</strong>：本卡是定義、章節是 retrieval pipeline 設計（含 reranker / hybrid 段）</li>
</ol>
]]></content:encoded></item><item><title>Residual Connection</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/residual-connection/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/residual-connection/</guid><description>&lt;p>Residual connection（殘差連接、skip connection）的核心概念是「把 layer 的輸入直接加到輸出上」、形式是 &lt;code>output = layer(x) + x&lt;/code>。這個簡單加法解決了深層網路的訓練退化問題：沒有 residual、模型加深會反而變差（不是過擬合、是 gradient 在反向傳播中衰減太多）；有 residual、訓練幾十甚至上百層都穩。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Residual connection 在 Transformer block 中出現兩次：&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">Transformer block：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> x
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> ├──────────────┐ ← skip connection（保留原始 x）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> ↓ │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> LayerNorm │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> ↓ │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> Self-Attention │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> ↓ │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> +←─────────────┘ ← residual add：attention output + x
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> ├──────────────┐ ← skip connection（保留 attention 後的值）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> ↓ │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl"> LayerNorm │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl"> ↓ │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl"> FFN │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl"> ↓ │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">17&lt;/span>&lt;span class="cl"> +←─────────────┘ ← residual add：FFN output + previous
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">18&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">19&lt;/span>&lt;span class="cl"> 進入下一個 block&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>關鍵性質：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Gradient 可以走捷徑&lt;/strong>：&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/backpropagation/" data-link-title="Backpropagation" data-link-desc="從 output loss 反向遞推、用 chain rule 算出每個權重的 gradient 的演算法">Backpropagation&lt;/a> 時、gradient 能透過 skip connection 直接傳回淺層、避免 chain rule 累積衰減。&lt;/li>
&lt;li>&lt;strong>Layer 學「殘差」而不是「完整轉換」&lt;/strong>：每層學「該怎麼微調輸入」、不用學「從零生成輸出」、優化更容易。&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/layer-normalization/" data-link-title="Layer Normalization" data-link-desc="在每個 token 的 hidden state 上做正規化（減 mean、除 std）、穩定深層網路訓練">LayerNorm&lt;/a> 配對&lt;/strong>：兩者一起是深層 Transformer 訓得起來的基礎。&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 residual connection 後可以判讀 Transformer 能堆幾十層的根本原因（不是因為 attention、是因為 residual + LayerNorm 讓深層仍可訓練）；也能看懂 ResNet、ViT 等其他用 residual 架構的設計。LLM 推論時 residual 不算 bottleneck、但在訓練 / fine-tune 時、residual 是 gradient flow 健康度的關鍵。&lt;/p></description><content:encoded><![CDATA[<p>Residual connection（殘差連接、skip connection）的核心概念是「把 layer 的輸入直接加到輸出上」、形式是 <code>output = layer(x) + x</code>。這個簡單加法解決了深層網路的訓練退化問題：沒有 residual、模型加深會反而變差（不是過擬合、是 gradient 在反向傳播中衰減太多）；有 residual、訓練幾十甚至上百層都穩。</p>
<h2 id="概念位置">概念位置</h2>
<p>Residual connection 在 Transformer block 中出現兩次：</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">Transformer block：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  x
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">  ├──────────────┐  ← skip connection（保留原始 x）
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  ↓              │
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">  LayerNorm      │
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">  ↓              │
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  Self-Attention │
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  ↓              │
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">  +←─────────────┘  ← residual add：attention output + x
</span></span><span class="line"><span class="ln">10</span><span class="cl">  │
</span></span><span class="line"><span class="ln">11</span><span class="cl">  ├──────────────┐  ← skip connection（保留 attention 後的值）
</span></span><span class="line"><span class="ln">12</span><span class="cl">  ↓              │
</span></span><span class="line"><span class="ln">13</span><span class="cl">  LayerNorm      │
</span></span><span class="line"><span class="ln">14</span><span class="cl">  ↓              │
</span></span><span class="line"><span class="ln">15</span><span class="cl">  FFN            │
</span></span><span class="line"><span class="ln">16</span><span class="cl">  ↓              │
</span></span><span class="line"><span class="ln">17</span><span class="cl">  +←─────────────┘  ← residual add：FFN output + previous
</span></span><span class="line"><span class="ln">18</span><span class="cl">  ↓
</span></span><span class="line"><span class="ln">19</span><span class="cl">  進入下一個 block</span></span></code></pre></div><p>關鍵性質：</p>
<ol>
<li><strong>Gradient 可以走捷徑</strong>：<a href="/blog/llm/knowledge-cards/backpropagation/" data-link-title="Backpropagation" data-link-desc="從 output loss 反向遞推、用 chain rule 算出每個權重的 gradient 的演算法">Backpropagation</a> 時、gradient 能透過 skip connection 直接傳回淺層、避免 chain rule 累積衰減。</li>
<li><strong>Layer 學「殘差」而不是「完整轉換」</strong>：每層學「該怎麼微調輸入」、不用學「從零生成輸出」、優化更容易。</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/layer-normalization/" data-link-title="Layer Normalization" data-link-desc="在每個 token 的 hidden state 上做正規化（減 mean、除 std）、穩定深層網路訓練">LayerNorm</a> 配對</strong>：兩者一起是深層 Transformer 訓得起來的基礎。</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>理解 residual connection 後可以判讀 Transformer 能堆幾十層的根本原因（不是因為 attention、是因為 residual + LayerNorm 讓深層仍可訓練）；也能看懂 ResNet、ViT 等其他用 residual 架構的設計。LLM 推論時 residual 不算 bottleneck、但在訓練 / fine-tune 時、residual 是 gradient flow 健康度的關鍵。</p>
]]></content:encoded></item><item><title>RLHF</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/rlhf/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/rlhf/</guid><description>&lt;p>RLHF（Reinforcement Learning from Human Feedback、人類反饋強化學習）的核心概念是「&lt;strong>讓人類比較兩個模型回答的好壞、訓一個 reward model 學會這個偏好、再用 RL 把 LLM 推往 reward model 給高分的方向&lt;/strong>」。RLHF 是 LLM 對話品質飛躍的關鍵（從 GPT-3 base 到 ChatGPT 的差別主要是 RLHF）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>RLHF 在訓練流程的位置與步驟：&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">[SFT 後的模型]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">Step 1：收集人類偏好
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> 對同個 prompt 讓模型生 A、B 兩個 response、人類標「我較喜歡 A」
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">Step 2：訓 reward model
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> 輸入 (prompt, response)、輸出一個分數
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> 目標：人類偏好的 response 分數高
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">Step 3：用 PPO 等 RL 演算法 fine-tune LLM
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> 讓模型輸出讓 reward model 給高分的 response
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> 加 [KL constraint](/llm/knowledge-cards/kl-divergence/)：不能偏離 SFT model 太遠
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">[Aligned model]：回答更貼近人類偏好&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>關鍵特性與挑戰：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>三個模型同時運作&lt;/strong>：policy（LLM）、reward model、reference model（SFT 後 frozen 那份）、訓練時記憶體吃緊。&lt;/li>
&lt;li>&lt;strong>Reward hacking&lt;/strong>：模型可能找到 reward model 的弱點、生成「reward 高但實質爛」的輸出（如冗長 boilerplate）。&lt;/li>
&lt;li>&lt;strong>訓練不穩&lt;/strong>：PPO 對 hyperparameter 敏感、需要小心調 β（KL 約束強度）、learning rate 等。&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>RLHF 是 ChatGPT / Claude / Gemini 等商業 LLM 對話品質的核心。讀 model card 看到「RLHF-tuned」「helpfulness fine-tuning」就是這個階段。&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/dpo/" data-link-title="DPO（Direct Preference Optimization）" data-link-desc="RLHF 的簡化替代：跳過 reward model、直接從人類偏好資料 fine-tune LLM">DPO&lt;/a> 是 2023 年後出現的簡化替代方案、跳過 reward model、直接用偏好資料 fine-tune、訓練流程簡單很多、是現代許多開源模型的主流選擇。&lt;/p></description><content:encoded><![CDATA[<p>RLHF（Reinforcement Learning from Human Feedback、人類反饋強化學習）的核心概念是「<strong>讓人類比較兩個模型回答的好壞、訓一個 reward model 學會這個偏好、再用 RL 把 LLM 推往 reward model 給高分的方向</strong>」。RLHF 是 LLM 對話品質飛躍的關鍵（從 GPT-3 base 到 ChatGPT 的差別主要是 RLHF）。</p>
<h2 id="概念位置">概念位置</h2>
<p>RLHF 在訓練流程的位置與步驟：</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">[SFT 後的模型]
</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">Step 1：收集人類偏好
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  對同個 prompt 讓模型生 A、B 兩個 response、人類標「我較喜歡 A」
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">Step 2：訓 reward model
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  輸入 (prompt, response)、輸出一個分數
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  目標：人類偏好的 response 分數高
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln">10</span><span class="cl">Step 3：用 PPO 等 RL 演算法 fine-tune LLM
</span></span><span class="line"><span class="ln">11</span><span class="cl">  讓模型輸出讓 reward model 給高分的 response
</span></span><span class="line"><span class="ln">12</span><span class="cl">  加 [KL constraint](/llm/knowledge-cards/kl-divergence/)：不能偏離 SFT model 太遠
</span></span><span class="line"><span class="ln">13</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln">14</span><span class="cl">[Aligned model]：回答更貼近人類偏好</span></span></code></pre></div><p>關鍵特性與挑戰：</p>
<ol>
<li><strong>三個模型同時運作</strong>：policy（LLM）、reward model、reference model（SFT 後 frozen 那份）、訓練時記憶體吃緊。</li>
<li><strong>Reward hacking</strong>：模型可能找到 reward model 的弱點、生成「reward 高但實質爛」的輸出（如冗長 boilerplate）。</li>
<li><strong>訓練不穩</strong>：PPO 對 hyperparameter 敏感、需要小心調 β（KL 約束強度）、learning rate 等。</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>RLHF 是 ChatGPT / Claude / Gemini 等商業 LLM 對話品質的核心。讀 model card 看到「RLHF-tuned」「helpfulness fine-tuning」就是這個階段。<a href="/blog/llm/knowledge-cards/dpo/" data-link-title="DPO（Direct Preference Optimization）" data-link-desc="RLHF 的簡化替代：跳過 reward model、直接從人類偏好資料 fine-tune LLM">DPO</a> 是 2023 年後出現的簡化替代方案、跳過 reward model、直接用偏好資料 fine-tune、訓練流程簡單很多、是現代許多開源模型的主流選擇。</p>
]]></content:encoded></item><item><title>RoPE（Rotary Position Embedding）</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/rope/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/rope/</guid><description>&lt;p>RoPE（Rotary Position Embedding、旋轉位置編碼、Su et al., 2021）的核心概念是「&lt;strong>把 token 在序列中的位置資訊用旋轉矩陣直接旋轉進 Q 跟 K 向量裡&lt;/strong>、不是用加法疊加另一個 embedding」。RoPE 是 Llama、Gemma、Qwen、Mistral 等現代 LLM 的標配、相對早期的 absolute / learned positional embedding 有更好的長 context 推廣性。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>位置編碼的演化路線：&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>Absolute（原 Transformer）&lt;/td>
 &lt;td>用 sin/cos 函數產生固定 position embedding、加到 token embedding&lt;/td>
 &lt;td>訓練長度外推性差&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Learned absolute（GPT-2）&lt;/td>
 &lt;td>每個位置學一個可訓練向量、加到 token embedding&lt;/td>
 &lt;td>超過訓練長度完全沒對應 embedding&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Relative&lt;/td>
 &lt;td>attention 算分數時加上「相對位置」的 bias&lt;/td>
 &lt;td>實作複雜、跟 &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> 兼容性差&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>RoPE&lt;/strong>&lt;/td>
 &lt;td>用旋轉矩陣把位置旋轉進 Q/K（不動 V）&lt;/td>
 &lt;td>主流、長 context 推廣性好（配 scaling）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>RoPE 的核心數學（簡化）：&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">傳統：token at position m 的 Q 是 Q_m = x_m @ W_Q
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">RoPE：Q_m = R(m) × (x_m @ W_Q) ← R(m) 是依位置 m 決定的旋轉矩陣
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">attention score = Q_m @ K_n^T
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> = R(m) × q × (R(n) × k)^T
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> = q × R(m - n) × k^T ← 只依賴相對位置 (m-n)！&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>關鍵性質：RoPE 算出的 attention score 只依賴&lt;strong>相對位置&lt;/strong>、所以推廣到比訓練長度更長的 context 時有自然的數學基礎、配合 RoPE scaling（YaRN、NTK-aware、Position Interpolation）就能把 8K 訓練的模型擴展到 128K / 1M context。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 model card 看到 &lt;code>rope_theta: 10000&lt;/code>、&lt;code>rope_scaling: {type: yarn, factor: 8}&lt;/code> 等就是 RoPE 配置。寫 code 場景的意涵：long context 模型（如 Llama 3 128K）的推廣能力主要靠 RoPE + scaling、不是直接訓練 128K 全長；但聲稱 context 跟「實用 context」仍有差距、長 context 上模型表現會逐步衰減。&lt;/p></description><content:encoded><![CDATA[<p>RoPE（Rotary Position Embedding、旋轉位置編碼、Su et al., 2021）的核心概念是「<strong>把 token 在序列中的位置資訊用旋轉矩陣直接旋轉進 Q 跟 K 向量裡</strong>、不是用加法疊加另一個 embedding」。RoPE 是 Llama、Gemma、Qwen、Mistral 等現代 LLM 的標配、相對早期的 absolute / learned positional embedding 有更好的長 context 推廣性。</p>
<h2 id="概念位置">概念位置</h2>
<p>位置編碼的演化路線：</p>
<table>
  <thead>
      <tr>
          <th>方法</th>
          <th>機制</th>
          <th>主要問題</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Absolute（原 Transformer）</td>
          <td>用 sin/cos 函數產生固定 position embedding、加到 token embedding</td>
          <td>訓練長度外推性差</td>
      </tr>
      <tr>
          <td>Learned absolute（GPT-2）</td>
          <td>每個位置學一個可訓練向量、加到 token embedding</td>
          <td>超過訓練長度完全沒對應 embedding</td>
      </tr>
      <tr>
          <td>Relative</td>
          <td>attention 算分數時加上「相對位置」的 bias</td>
          <td>實作複雜、跟 <a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 兼容性差</td>
      </tr>
      <tr>
          <td><strong>RoPE</strong></td>
          <td>用旋轉矩陣把位置旋轉進 Q/K（不動 V）</td>
          <td>主流、長 context 推廣性好（配 scaling）</td>
      </tr>
  </tbody>
</table>
<p>RoPE 的核心數學（簡化）：</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">傳統：token at position m 的 Q 是 Q_m = x_m @ W_Q
</span></span><span class="line"><span class="ln">2</span><span class="cl">RoPE：Q_m = R(m) × (x_m @ W_Q)  ← R(m) 是依位置 m 決定的旋轉矩陣
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">attention score = Q_m @ K_n^T
</span></span><span class="line"><span class="ln">5</span><span class="cl">               = R(m) × q × (R(n) × k)^T
</span></span><span class="line"><span class="ln">6</span><span class="cl">               = q × R(m - n) × k^T  ← 只依賴相對位置 (m-n)！</span></span></code></pre></div><p>關鍵性質：RoPE 算出的 attention score 只依賴<strong>相對位置</strong>、所以推廣到比訓練長度更長的 context 時有自然的數學基礎、配合 RoPE scaling（YaRN、NTK-aware、Position Interpolation）就能把 8K 訓練的模型擴展到 128K / 1M context。</p>
<h2 id="設計責任">設計責任</h2>
<p>讀 model card 看到 <code>rope_theta: 10000</code>、<code>rope_scaling: {type: yarn, factor: 8}</code> 等就是 RoPE 配置。寫 code 場景的意涵：long context 模型（如 Llama 3 128K）的推廣能力主要靠 RoPE + scaling、不是直接訓練 128K 全長；但聲稱 context 跟「實用 context」仍有差距、長 context 上模型表現會逐步衰減。</p>
]]></content:encoded></item><item><title>Sandbox</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/sandbox/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/sandbox/</guid><description>&lt;p>Sandbox 的核心概念是「把程式跑在權限受限的隔離環境、限制檔案存取、網路連線、系統呼叫的範圍」。在 LLM 場景下、sandbox 用來控制 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">tool use&lt;/a> 跟 MCP server 的副作用範圍：即使 LLM 被 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prompt-injection/" data-link-title="Prompt Injection" data-link-desc="把惡意指令藏進 LLM 會讀到的內容、誘導 LLM 跑出非開發者預期行為的攻擊類別、OWASP LLM01 列入頭號威脅">prompt injection&lt;/a> 誘導跑惡意 tool、sandbox 能限制最壞情況的影響面。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>常見的 sandbox 技術光譜（依隔離強度跟工程成本）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>技術&lt;/th>
 &lt;th>隔離強度&lt;/th>
 &lt;th>工程成本&lt;/th>
 &lt;th>LLM 場景的典型用途&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>不同 OS user&lt;/td>
 &lt;td>中（檔案權限）&lt;/td>
 &lt;td>低&lt;/td>
 &lt;td>個人 dev 跑 MCP server&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Docker container&lt;/td>
 &lt;td>中高&lt;/td>
 &lt;td>中&lt;/td>
 &lt;td>跑第三方 MCP server、隔離 LLM agent&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>VM / Firecracker / gVisor&lt;/td>
 &lt;td>高&lt;/td>
 &lt;td>中高&lt;/td>
 &lt;td>production 多租戶 LLM agent&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>chroot / namespace&lt;/td>
 &lt;td>中&lt;/td>
 &lt;td>中&lt;/td>
 &lt;td>限定 filesystem 視角&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>seccomp / AppArmor / SELinux&lt;/td>
 &lt;td>高（syscall 層）&lt;/td>
 &lt;td>高&lt;/td>
 &lt;td>細粒度限制 syscall&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Web Worker / V8 isolate&lt;/td>
 &lt;td>中（JavaScript 層）&lt;/td>
 &lt;td>中&lt;/td>
 &lt;td>LLM 跑 user-provided JavaScript&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Sandbox 在 LLM 場景的常見配置：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>個人 dev&lt;/strong>：用獨立 OS user 跑 MCP server、限制檔案存取到 workspace；或用 Docker。&lt;/li>
&lt;li>&lt;strong>production agent&lt;/strong>：每個 user / session 一個 ephemeral container、跑完就 destroy。&lt;/li>
&lt;li>&lt;strong>code execution tool&lt;/strong>：把 LLM 生成的 code 丟進 sandbox 跑（如 OpenAI Code Interpreter、Anthropic Claude Code Tool）。&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 sandbox 後可以解釋兩個現象：為什麼跑第三方 MCP server 前 sandbox 是基本配置（MCP 是可執行程式碼、權限上限是「跑該 server 的 user 的權限」）、為什麼 production 場景的 code execution tool 必定在 ephemeral sandbox 內跑（避免長期 state 跟跨 user 殘留）。&lt;/p>
&lt;p>設計 LLM application 時、sandbox 跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">tool use&lt;/a> 的白名單是兩個獨立的防護層、建議都做：白名單擋已知範圍、sandbox 擋未預期的副作用。詳見 &lt;a href="https://tarrragon.github.io/blog/llm/06-security/tool-use-permission-model/" data-link-title="6.2 tool use 與 MCP server 的權限模型" data-link-desc="個人 dev 場景下 tool use / MCP server 的副作用權限：檔案系統 / shell / 網路存取邊界、第三方 MCP 信任、副作用的可逆性">6.2 tool use 與 MCP server 的權限模型&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Sandbox 的核心概念是「把程式跑在權限受限的隔離環境、限制檔案存取、網路連線、系統呼叫的範圍」。在 LLM 場景下、sandbox 用來控制 <a href="/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">tool use</a> 跟 MCP server 的副作用範圍：即使 LLM 被 <a href="/blog/llm/knowledge-cards/prompt-injection/" data-link-title="Prompt Injection" data-link-desc="把惡意指令藏進 LLM 會讀到的內容、誘導 LLM 跑出非開發者預期行為的攻擊類別、OWASP LLM01 列入頭號威脅">prompt injection</a> 誘導跑惡意 tool、sandbox 能限制最壞情況的影響面。</p>
<h2 id="概念位置">概念位置</h2>
<p>常見的 sandbox 技術光譜（依隔離強度跟工程成本）：</p>
<table>
  <thead>
      <tr>
          <th>技術</th>
          <th>隔離強度</th>
          <th>工程成本</th>
          <th>LLM 場景的典型用途</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>不同 OS user</td>
          <td>中（檔案權限）</td>
          <td>低</td>
          <td>個人 dev 跑 MCP server</td>
      </tr>
      <tr>
          <td>Docker container</td>
          <td>中高</td>
          <td>中</td>
          <td>跑第三方 MCP server、隔離 LLM agent</td>
      </tr>
      <tr>
          <td>VM / Firecracker / gVisor</td>
          <td>高</td>
          <td>中高</td>
          <td>production 多租戶 LLM agent</td>
      </tr>
      <tr>
          <td>chroot / namespace</td>
          <td>中</td>
          <td>中</td>
          <td>限定 filesystem 視角</td>
      </tr>
      <tr>
          <td>seccomp / AppArmor / SELinux</td>
          <td>高（syscall 層）</td>
          <td>高</td>
          <td>細粒度限制 syscall</td>
      </tr>
      <tr>
          <td>Web Worker / V8 isolate</td>
          <td>中（JavaScript 層）</td>
          <td>中</td>
          <td>LLM 跑 user-provided JavaScript</td>
      </tr>
  </tbody>
</table>
<p>Sandbox 在 LLM 場景的常見配置：</p>
<ol>
<li><strong>個人 dev</strong>：用獨立 OS user 跑 MCP server、限制檔案存取到 workspace；或用 Docker。</li>
<li><strong>production agent</strong>：每個 user / session 一個 ephemeral container、跑完就 destroy。</li>
<li><strong>code execution tool</strong>：把 LLM 生成的 code 丟進 sandbox 跑（如 OpenAI Code Interpreter、Anthropic Claude Code Tool）。</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>理解 sandbox 後可以解釋兩個現象：為什麼跑第三方 MCP server 前 sandbox 是基本配置（MCP 是可執行程式碼、權限上限是「跑該 server 的 user 的權限」）、為什麼 production 場景的 code execution tool 必定在 ephemeral sandbox 內跑（避免長期 state 跟跨 user 殘留）。</p>
<p>設計 LLM application 時、sandbox 跟 <a href="/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">tool use</a> 的白名單是兩個獨立的防護層、建議都做：白名單擋已知範圍、sandbox 擋未預期的副作用。詳見 <a href="/blog/llm/06-security/tool-use-permission-model/" data-link-title="6.2 tool use 與 MCP server 的權限模型" data-link-desc="個人 dev 場景下 tool use / MCP server 的副作用權限：檔案系統 / shell / 網路存取邊界、第三方 MCP 信任、副作用的可逆性">6.2 tool use 與 MCP server 的權限模型</a>。</p>
]]></content:encoded></item><item><title>Scaffold vs Harness</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/scaffold-vs-harness/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/scaffold-vs-harness/</guid><description>&lt;p>Scaffold 跟 harness 的核心概念是「&lt;strong>把 coding agent 拆成『建構時靜態結構』跟『runtime 動態邏輯』兩層&lt;/strong>」。Scaffold 是建構時就決定的：system prompt 模板、tool schema 註冊、subagent 拓樸；harness 是 runtime 動態運作：tool dispatch、context budget 管理、safety / 中斷、handoff。Claude Code、Cursor、Aider、Codex 這類 coding agent 的內部設計都遵循這個分層。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>兩層的職責劃分：&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">Scaffold（建構時、static）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> ├── System prompt 模板（角色、約束、輸出格式）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> ├── Tool schema 註冊（read_file / write_file / run_bash 等的 spec）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> ├── Subagent 拓樸（main agent + 子 agent 的調用關係）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> ├── Skill / playbook 註冊
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> └── 安全 policy（什麼可寫、什麼要 confirm）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> ↓ 編譯 / 載入
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">Harness（runtime、dynamic）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> ├── Tool dispatch（接 LLM tool call、執行、回 result）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> ├── Context budget 管理（剪裁歷史、塞新內容、不超 25% 規則）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl"> ├── Safety / 中斷（confirm UI、permission boundary、可逆性檢查）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl"> ├── Error recovery（tool failed → retry / fallback / escalate）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl"> └── Telemetry（trace / metrics / cost）&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>跟既有概念的關係：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>概念&lt;/th>
 &lt;th>跟 scaffold / harness 的關係&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/system-prompt/" data-link-title="System Prompt" data-link-desc="LLM application 中由開發者預設、不直接顯示給使用者的指令層、定義模型的角色、行為規範、輸出格式">System prompt&lt;/a>&lt;/td>
 &lt;td>Scaffold 的核心元件、定義 agent 角色&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">Tool use&lt;/a>&lt;/td>
 &lt;td>Scaffold 註冊 tool spec、Harness 在 runtime dispatch&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">Agent loop&lt;/a>&lt;/td>
 &lt;td>Harness 的核心 loop（perceive / reason / act / observe / terminate）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/function-calling/" data-link-title="Function Calling" data-link-desc="模型訓練階段建立的「呼叫工具」能力：知道何時該呼叫、傳什麼參數">Function calling&lt;/a>&lt;/td>
 &lt;td>Tool spec 的具體 protocol&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 coding agent paper / blog 看到「scaffold」「harness」「context engineering」就是這 framing。寫 code 場景的判讀：&lt;/p></description><content:encoded><![CDATA[<p>Scaffold 跟 harness 的核心概念是「<strong>把 coding agent 拆成『建構時靜態結構』跟『runtime 動態邏輯』兩層</strong>」。Scaffold 是建構時就決定的：system prompt 模板、tool schema 註冊、subagent 拓樸；harness 是 runtime 動態運作：tool dispatch、context budget 管理、safety / 中斷、handoff。Claude Code、Cursor、Aider、Codex 這類 coding agent 的內部設計都遵循這個分層。</p>
<h2 id="概念位置">概念位置</h2>
<p>兩層的職責劃分：</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">Scaffold（建構時、static）：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  ├── System prompt 模板（角色、約束、輸出格式）
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">  ├── Tool schema 註冊（read_file / write_file / run_bash 等的 spec）
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  ├── Subagent 拓樸（main agent + 子 agent 的調用關係）
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">  ├── Skill / playbook 註冊
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">  └── 安全 policy（什麼可寫、什麼要 confirm）
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">   ↓ 編譯 / 載入
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">Harness（runtime、dynamic）：
</span></span><span class="line"><span class="ln">11</span><span class="cl">  ├── Tool dispatch（接 LLM tool call、執行、回 result）
</span></span><span class="line"><span class="ln">12</span><span class="cl">  ├── Context budget 管理（剪裁歷史、塞新內容、不超 25% 規則）
</span></span><span class="line"><span class="ln">13</span><span class="cl">  ├── Safety / 中斷（confirm UI、permission boundary、可逆性檢查）
</span></span><span class="line"><span class="ln">14</span><span class="cl">  ├── Error recovery（tool failed → retry / fallback / escalate）
</span></span><span class="line"><span class="ln">15</span><span class="cl">  └── Telemetry（trace / metrics / cost）</span></span></code></pre></div><p>跟既有概念的關係：</p>
<table>
  <thead>
      <tr>
          <th>概念</th>
          <th>跟 scaffold / harness 的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/system-prompt/" data-link-title="System Prompt" data-link-desc="LLM application 中由開發者預設、不直接顯示給使用者的指令層、定義模型的角色、行為規範、輸出格式">System prompt</a></td>
          <td>Scaffold 的核心元件、定義 agent 角色</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">Tool use</a></td>
          <td>Scaffold 註冊 tool spec、Harness 在 runtime dispatch</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">Agent loop</a></td>
          <td>Harness 的核心 loop（perceive / reason / act / observe / terminate）</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/function-calling/" data-link-title="Function Calling" data-link-desc="模型訓練階段建立的「呼叫工具」能力：知道何時該呼叫、傳什麼參數">Function calling</a></td>
          <td>Tool spec 的具體 protocol</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 coding agent paper / blog 看到「scaffold」「harness」「context engineering」就是這 framing。寫 code 場景的判讀：</p>
<ol>
<li><strong>看新 coding agent 時、分兩層拆解</strong>：scaffold（system prompt、tool list、subagent 結構）是「設計做了什麼」、harness（context 怎麼裁、tool 怎麼 dispatch、安全怎麼擋）是「runtime 怎麼跑」</li>
<li><strong>修改 / 客製 agent 時、看你動的是哪層</strong>：改 system prompt = 動 scaffold；改 tool 執行邏輯 = 動 harness</li>
<li><strong>跟 <a href="/blog/llm/04-applications/coding-agent-harness/" data-link-title="4.17 Coding agent harness：scaffold / context engineering / subagent" data-link-desc="Coding agent 的內部設計：scaffold vs harness 分層、context budget 25% 規則、subagent 拓樸、跟 Claude Code / Cursor / Aider 的 mapping">4.17 coding-agent harness</a> 的關係</strong>：本卡是定義、4.12 是 coding 場景的工程實務（context budget、scaffold 模式、harness pattern）</li>
</ol>
]]></content:encoded></item><item><title>Self-Attention</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/self-attention/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/self-attention/</guid><description>&lt;p>Self-attention 的核心概念是「Query / Key / Value 三組向量都從&lt;strong>同一個&lt;/strong> sequence 投影出來的 &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>」。對比下、cross-attention 的 Q 來自一個 sequence、K/V 來自另一個 sequence（如 encoder-decoder 的 decoder 看 encoder）。LLM（decoder-only）每層都是 self-attention、self-attention 是 Transformer 「讓每個 token 看到序列其他 token」的機制本身。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Self-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">輸入 sequence: x_1, x_2, ..., x_n（每個是向量）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">對每個 token i：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> Q_i = x_i × W_Q ← Query：「我要找什麼樣的資訊」
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> K_i = x_i × W_K ← Key：「我提供什麼樣的資訊」
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> V_i = x_i × W_V ← Value：「我的實際內容」
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">attention(Q_i, K, V) = softmax(Q_i · K^T / √d) · V
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> └─ Q 跟所有 K 算分數、決定權重 ─┘
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> └─ 加權平均所有 V ─┘&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>關鍵特性：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Q / K / V 來源相同&lt;/strong>：跟 cross-attention 區分；都從同一個輸入 sequence 投影。&lt;/li>
&lt;li>&lt;strong>每個 token 都跟所有 token 算一次&lt;/strong>：複雜度 O(n²)、是 long context 痛點根源。&lt;/li>
&lt;li>&lt;strong>Causal mask 在 self-attention 內生效&lt;/strong>：LLM 的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/transformer/" data-link-title="Transformer" data-link-desc="寫 code 用的 LLM 神經網路架構：基於 attention 機制、自回歸生成 token">decoder-only&lt;/a> self-attention 加 causal mask、token i 只能看 1~i、不能看 i+1 以後（不能偷看未來）。&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 self-attention 後可以判讀幾件 LLM 設計事：&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> 為什麼有效（自回歸生成時、過去 token 的 K/V 不變、存下來下次直接用）；MHA / GQA / MLA 等變體在動什麼（共享 / 壓縮 K/V 投影、不動 Q）；為什麼長 context 推論慢（self-attention 的 O(n²) 計算）。&lt;/p></description><content:encoded><![CDATA[<p>Self-attention 的核心概念是「Query / Key / Value 三組向量都從<strong>同一個</strong> sequence 投影出來的 <a href="/blog/llm/knowledge-cards/attention/" data-link-title="Attention" data-link-desc="Transformer 內部讓每個 token 對其他 token 加權平均的核心機制、形成 KV cache 跟 context window 的計算基礎">attention</a>」。對比下、cross-attention 的 Q 來自一個 sequence、K/V 來自另一個 sequence（如 encoder-decoder 的 decoder 看 encoder）。LLM（decoder-only）每層都是 self-attention、self-attention 是 Transformer 「讓每個 token 看到序列其他 token」的機制本身。</p>
<h2 id="概念位置">概念位置</h2>
<p>Self-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">輸入 sequence: x_1, x_2, ..., x_n（每個是向量）
</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">對每個 token i：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  Q_i = x_i × W_Q   ← Query：「我要找什麼樣的資訊」
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">  K_i = x_i × W_K   ← Key：「我提供什麼樣的資訊」
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">  V_i = x_i × W_V   ← Value：「我的實際內容」
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">attention(Q_i, K, V) = softmax(Q_i · K^T / √d) · V
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">                       └─ Q 跟所有 K 算分數、決定權重 ─┘
</span></span><span class="line"><span class="ln">10</span><span class="cl">                                                       └─ 加權平均所有 V ─┘</span></span></code></pre></div><p>關鍵特性：</p>
<ol>
<li><strong>Q / K / V 來源相同</strong>：跟 cross-attention 區分；都從同一個輸入 sequence 投影。</li>
<li><strong>每個 token 都跟所有 token 算一次</strong>：複雜度 O(n²)、是 long context 痛點根源。</li>
<li><strong>Causal mask 在 self-attention 內生效</strong>：LLM 的 <a href="/blog/llm/knowledge-cards/transformer/" data-link-title="Transformer" data-link-desc="寫 code 用的 LLM 神經網路架構：基於 attention 機制、自回歸生成 token">decoder-only</a> self-attention 加 causal mask、token i 只能看 1~i、不能看 i+1 以後（不能偷看未來）。</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>理解 self-attention 後可以判讀幾件 LLM 設計事：<a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 為什麼有效（自回歸生成時、過去 token 的 K/V 不變、存下來下次直接用）；MHA / GQA / MLA 等變體在動什麼（共享 / 壓縮 K/V 投影、不動 Q）；為什麼長 context 推論慢（self-attention 的 O(n²) 計算）。</p>
]]></content:encoded></item><item><title>SentencePiece</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/sentencepiece/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/sentencepiece/</guid><description>&lt;p>SentencePiece（Kudo &amp;amp; Richardson, 2018）的核心概念是「&lt;strong>Google 開源的 tokenization 框架、把『空白也當一個字元』處理、原生支援 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/bpe/" data-link-title="BPE（Byte-Pair Encoding）" data-link-desc="用「最常一起出現的字元對」合併建詞彙表的 tokenization 演算法、GPT / Llama 等主流">BPE&lt;/a> 跟 unigram 兩種演算法&lt;/strong>」。Llama、Gemma、Mistral、T5 等模型用 SentencePiece 作為 tokenizer 實作；它的 multilingual 友善度跟「不依賴語言預處理」是被選擇的主因。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>SentencePiece 跟其他 tokenization 路線的對比：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &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>WordPiece&lt;/td>
 &lt;td>類似 BPE、Google 早期方案&lt;/td>
 &lt;td>需語言預處理（如英文 lowercase）&lt;/td>
 &lt;td>BERT、DistilBERT&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>SentencePiece BPE&lt;/strong>&lt;/td>
 &lt;td>BPE 演算法、空白當特殊字符 &lt;code>▁&lt;/code> 處理&lt;/td>
 &lt;td>統一處理、不需語言預設&lt;/td>
 &lt;td>Llama、Gemma、Mistral&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>SentencePiece Unigram&lt;/strong>&lt;/td>
 &lt;td>機率模型、選一組讓 corpus likelihood 最大的子詞&lt;/td>
 &lt;td>同上、機率視角&lt;/td>
 &lt;td>T5、XLNet、ALBERT&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>tiktoken（OpenAI）&lt;/td>
 &lt;td>Byte-level BPE&lt;/td>
 &lt;td>統一處理&lt;/td>
 &lt;td>GPT-3.5、GPT-4、GPT-5&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵特性：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>&lt;code>▁&lt;/code> 表示空白&lt;/strong>：SentencePiece 把空白編碼成 &lt;code>▁&lt;/code>（Unicode U+2581）、所以「Hello world」會被 tokenize 成 &lt;code>[&amp;quot;Hello&amp;quot;, &amp;quot;▁world&amp;quot;]&lt;/code>、保留空白資訊在 token 內。&lt;/li>
&lt;li>&lt;strong>不依賴語言預處理&lt;/strong>：傳統 NLP 要先做 lowercasing、word segmentation；SentencePiece 直接從 raw bytes 開始學、跨語言通用。&lt;/li>
&lt;li>&lt;strong>原生 multilingual&lt;/strong>：訓練 corpus 包含多語言時、tokenizer 自動學會跨語言的子詞單元、不需要為每種語言設定不同 tokenizer。&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 model card / repo 看到 &lt;code>tokenizer.model&lt;/code> 檔案（不是 &lt;code>tokenizer.json&lt;/code> 或 &lt;code>vocab.txt&lt;/code>）就是 SentencePiece 用的 protobuf 格式。寫 code 場景的意涵：SentencePiece tokenizer 在中文 / 多語言任務上比 WordPiece 友好；換 tokenizer 等於整個 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-layer/" data-link-title="Embedding Layer" data-link-desc="Transformer 第一層的查表結構、把整數 token ID 轉成可運算的向量">embedding layer&lt;/a> 失效、所以 fine-tune 時不會動 tokenizer。&lt;/p></description><content:encoded><![CDATA[<p>SentencePiece（Kudo &amp; Richardson, 2018）的核心概念是「<strong>Google 開源的 tokenization 框架、把『空白也當一個字元』處理、原生支援 <a href="/blog/llm/knowledge-cards/bpe/" data-link-title="BPE（Byte-Pair Encoding）" data-link-desc="用「最常一起出現的字元對」合併建詞彙表的 tokenization 演算法、GPT / Llama 等主流">BPE</a> 跟 unigram 兩種演算法</strong>」。Llama、Gemma、Mistral、T5 等模型用 SentencePiece 作為 tokenizer 實作；它的 multilingual 友善度跟「不依賴語言預處理」是被選擇的主因。</p>
<h2 id="概念位置">概念位置</h2>
<p>SentencePiece 跟其他 tokenization 路線的對比：</p>
<table>
  <thead>
      <tr>
          <th>框架 / 路線</th>
          <th>機制</th>
          <th>處理多語言 / 空白</th>
          <th>出現在</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>WordPiece</td>
          <td>類似 BPE、Google 早期方案</td>
          <td>需語言預處理（如英文 lowercase）</td>
          <td>BERT、DistilBERT</td>
      </tr>
      <tr>
          <td><strong>SentencePiece BPE</strong></td>
          <td>BPE 演算法、空白當特殊字符 <code>▁</code> 處理</td>
          <td>統一處理、不需語言預設</td>
          <td>Llama、Gemma、Mistral</td>
      </tr>
      <tr>
          <td><strong>SentencePiece Unigram</strong></td>
          <td>機率模型、選一組讓 corpus likelihood 最大的子詞</td>
          <td>同上、機率視角</td>
          <td>T5、XLNet、ALBERT</td>
      </tr>
      <tr>
          <td>tiktoken（OpenAI）</td>
          <td>Byte-level BPE</td>
          <td>統一處理</td>
          <td>GPT-3.5、GPT-4、GPT-5</td>
      </tr>
  </tbody>
</table>
<p>關鍵特性：</p>
<ol>
<li><strong><code>▁</code> 表示空白</strong>：SentencePiece 把空白編碼成 <code>▁</code>（Unicode U+2581）、所以「Hello world」會被 tokenize 成 <code>[&quot;Hello&quot;, &quot;▁world&quot;]</code>、保留空白資訊在 token 內。</li>
<li><strong>不依賴語言預處理</strong>：傳統 NLP 要先做 lowercasing、word segmentation；SentencePiece 直接從 raw bytes 開始學、跨語言通用。</li>
<li><strong>原生 multilingual</strong>：訓練 corpus 包含多語言時、tokenizer 自動學會跨語言的子詞單元、不需要為每種語言設定不同 tokenizer。</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 model card / repo 看到 <code>tokenizer.model</code> 檔案（不是 <code>tokenizer.json</code> 或 <code>vocab.txt</code>）就是 SentencePiece 用的 protobuf 格式。寫 code 場景的意涵：SentencePiece tokenizer 在中文 / 多語言任務上比 WordPiece 友好；換 tokenizer 等於整個 <a href="/blog/llm/knowledge-cards/embedding-layer/" data-link-title="Embedding Layer" data-link-desc="Transformer 第一層的查表結構、把整數 token ID 轉成可運算的向量">embedding layer</a> 失效、所以 fine-tune 時不會動 tokenizer。</p>
]]></content:encoded></item><item><title>SFT（Supervised Fine-Tuning）</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/sft/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/sft/</guid><description>&lt;p>SFT（Supervised Fine-Tuning、指令微調）的核心概念是「在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/base-model/" data-link-title="Base Model" data-link-desc="未經指令微調的原始模型：擅長文字接龍、適合下游微調用途">base model&lt;/a> 上、用人類示範的『指令-回答』成對資料做監督式 fine-tune、讓模型從『接龍』變成『跟指令走』」。SFT 是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/pre-training/" data-link-title="Pre-training" data-link-desc="LLM 訓練的第一階段：用 trillion-token 級網路文字做 next-token prediction、得到 base model">pre-training&lt;/a> 跟 alignment（&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rlhf/" data-link-title="RLHF" data-link-desc="Reinforcement Learning from Human Feedback：用人類偏好訓練的 reward model 透過 RL 對齊 LLM">RLHF&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/dpo/" data-link-title="DPO（Direct Preference Optimization）" data-link-desc="RLHF 的簡化替代：跳過 reward model、直接從人類偏好資料 fine-tune LLM">DPO&lt;/a>）之間的橋。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>SFT 在訓練 pipeline 的位置與資料形態：&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">資料格式（典型）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> {&amp;#34;instruction&amp;#34;: &amp;#34;寫一個 Python fibonacci&amp;#34;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> &amp;#34;response&amp;#34;: &amp;#34;def fib(n): ...&amp;#34;}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">訓練：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> 把 instruction + response 連起來、跑跟 pre-training 一樣的 next-token prediction
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> 但 loss 只算 response token 上的 cross-entropy（instruction 部分不算）&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>SFT 後同一個模型行為大改：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>問同樣問題「寫一個 Python fibonacci」&lt;/th>
 &lt;th>Base model（pre-training 後）&lt;/th>
 &lt;th>Instruction-tuned model（SFT 後）&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>行為&lt;/td>
 &lt;td>純文字接龍：「寫一個 Python fibonacci。寫一個 JavaScript fibonacci。寫一個 Rust&amp;hellip;」&lt;/td>
 &lt;td>直接給出 fibonacci 函式實作&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵特性：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>資料量遠小於 pre-training&lt;/strong>：幾萬到幾百萬筆指令-回答對、相對 pre-training 的兆級 token 是小數字。&lt;/li>
&lt;li>&lt;strong>訓練成本相對低&lt;/strong>：通常幾百到幾千 GPU-hour、可在單機完成。&lt;/li>
&lt;li>&lt;strong>容易過擬合 / 災難遺忘&lt;/strong>：SFT 資料太少 / 太特化時、模型可能丟掉 pre-training 學到的能力、見 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/lora/" data-link-title="LoRA" data-link-desc="Low-Rank Adaptation：凍住原模型權重、只訓兩個小矩陣的 parameter-efficient fine-tuning">LoRA&lt;/a> 的設計動機。&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 model card 看到「instruct」「chat」「-it」「sft」等 suffix、就是經過 SFT 的版本。寫 code 場景用的模型幾乎都是 SFT 後的（base model 對話能力差、實用度低）。Coding-tuned 模型（如 Qwen3-Coder）是 SFT 階段大量加入 code 對話資料的特化版本、跟通用 instruct 模型在 code 任務上有可觀差距。&lt;/p></description><content:encoded><![CDATA[<p>SFT（Supervised Fine-Tuning、指令微調）的核心概念是「在 <a href="/blog/llm/knowledge-cards/base-model/" data-link-title="Base Model" data-link-desc="未經指令微調的原始模型：擅長文字接龍、適合下游微調用途">base model</a> 上、用人類示範的『指令-回答』成對資料做監督式 fine-tune、讓模型從『接龍』變成『跟指令走』」。SFT 是 <a href="/blog/llm/knowledge-cards/pre-training/" data-link-title="Pre-training" data-link-desc="LLM 訓練的第一階段：用 trillion-token 級網路文字做 next-token prediction、得到 base model">pre-training</a> 跟 alignment（<a href="/blog/llm/knowledge-cards/rlhf/" data-link-title="RLHF" data-link-desc="Reinforcement Learning from Human Feedback：用人類偏好訓練的 reward model 透過 RL 對齊 LLM">RLHF</a> / <a href="/blog/llm/knowledge-cards/dpo/" data-link-title="DPO（Direct Preference Optimization）" data-link-desc="RLHF 的簡化替代：跳過 reward model、直接從人類偏好資料 fine-tune LLM">DPO</a>）之間的橋。</p>
<h2 id="概念位置">概念位置</h2>
<p>SFT 在訓練 pipeline 的位置與資料形態：</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">資料格式（典型）：
</span></span><span class="line"><span class="ln">2</span><span class="cl">  {&#34;instruction&#34;: &#34;寫一個 Python fibonacci&#34;,
</span></span><span class="line"><span class="ln">3</span><span class="cl">   &#34;response&#34;:    &#34;def fib(n): ...&#34;}
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl">訓練：
</span></span><span class="line"><span class="ln">6</span><span class="cl">  把 instruction + response 連起來、跑跟 pre-training 一樣的 next-token prediction
</span></span><span class="line"><span class="ln">7</span><span class="cl">  但 loss 只算 response token 上的 cross-entropy（instruction 部分不算）</span></span></code></pre></div><p>SFT 後同一個模型行為大改：</p>
<table>
  <thead>
      <tr>
          <th>問同樣問題「寫一個 Python fibonacci」</th>
          <th>Base model（pre-training 後）</th>
          <th>Instruction-tuned model（SFT 後）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>行為</td>
          <td>純文字接龍：「寫一個 Python fibonacci。寫一個 JavaScript fibonacci。寫一個 Rust&hellip;」</td>
          <td>直接給出 fibonacci 函式實作</td>
      </tr>
  </tbody>
</table>
<p>關鍵特性：</p>
<ol>
<li><strong>資料量遠小於 pre-training</strong>：幾萬到幾百萬筆指令-回答對、相對 pre-training 的兆級 token 是小數字。</li>
<li><strong>訓練成本相對低</strong>：通常幾百到幾千 GPU-hour、可在單機完成。</li>
<li><strong>容易過擬合 / 災難遺忘</strong>：SFT 資料太少 / 太特化時、模型可能丟掉 pre-training 學到的能力、見 <a href="/blog/llm/knowledge-cards/lora/" data-link-title="LoRA" data-link-desc="Low-Rank Adaptation：凍住原模型權重、只訓兩個小矩陣的 parameter-efficient fine-tuning">LoRA</a> 的設計動機。</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 model card 看到「instruct」「chat」「-it」「sft」等 suffix、就是經過 SFT 的版本。寫 code 場景用的模型幾乎都是 SFT 後的（base model 對話能力差、實用度低）。Coding-tuned 模型（如 Qwen3-Coder）是 SFT 階段大量加入 code 對話資料的特化版本、跟通用 instruct 模型在 code 任務上有可觀差距。</p>
]]></content:encoded></item><item><title>SGD</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/sgd/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/sgd/</guid><description>&lt;p>SGD（Stochastic Gradient Descent、隨機梯度下降）的核心概念是「每次只用一小批資料（mini-batch）算 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/gradient/" data-link-title="Gradient" data-link-desc="loss function 對權重的偏微分向量、指出「該往哪個方向調權重才能讓 loss 下降最快」">gradient&lt;/a>、更新權重」。對比的是 vanilla gradient descent（用全部資料算一次 gradient）：full-batch 在 trillion-token 級資料下完全不可行、SGD 用 mini-batch 把記憶體跟計算成本拉到可行範圍。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>SGD 的更新公式：&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">W_new = W_old - learning_rate × gradient_of_loss_on_minibatch&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>跟其他 optimizer 的對比：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Optimizer&lt;/th>
 &lt;th>更新規則&lt;/th>
 &lt;th>特性&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>SGD&lt;/td>
 &lt;td>&lt;code>W -= lr × g&lt;/code>&lt;/td>
 &lt;td>簡單、慢、容易卡 local minimum&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>SGD + Momentum&lt;/td>
 &lt;td>加速度項：&lt;code>v = μv + g; W -= lr × v&lt;/code>&lt;/td>
 &lt;td>衝過 saddle point、收斂較穩&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/adam-adamw/" data-link-title="Adam / AdamW" data-link-desc="對每個參數自適應 learning rate 的 optimizer、LLM 訓練主流選擇">Adam / AdamW&lt;/a>&lt;/td>
 &lt;td>對每個參數自適應 lr、用 gradient 的 EMA 跟二階矩&lt;/td>
 &lt;td>對 lr 較不敏感、LLM 訓練主流&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>LLM 訓練幾乎都用 Adam / AdamW、不是純 SGD。但 SGD 仍出現在：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>小模型 / 簡單任務&lt;/strong>：fine-tune 小 vision 模型、SGD + momentum 仍是合理選擇。&lt;/li>
&lt;li>&lt;strong>理論分析 / 教學&lt;/strong>：SGD 是最簡單的 optimizer、用來解釋 gradient descent 概念。&lt;/li>
&lt;li>&lt;strong>某些 fine-tuning 場景&lt;/strong>：&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/lora/" data-link-title="LoRA" data-link-desc="Low-Rank Adaptation：凍住原模型權重、只訓兩個小矩陣的 parameter-efficient fine-tuning">LoRA&lt;/a> 或 SFT 偶爾用 SGD（避免 Adam 改變 base model 太多）。&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 paper / training script 看到 optimizer 選擇、SGD 是基線、其他 optimizer 通常是「對 SGD 的改進」。寫 code 場景的判讀：訓練自己的小模型可以從 SGD + momentum 開始；fine-tune 大 LLM 沒理由不用 AdamW。&lt;/p></description><content:encoded><![CDATA[<p>SGD（Stochastic Gradient Descent、隨機梯度下降）的核心概念是「每次只用一小批資料（mini-batch）算 <a href="/blog/llm/knowledge-cards/gradient/" data-link-title="Gradient" data-link-desc="loss function 對權重的偏微分向量、指出「該往哪個方向調權重才能讓 loss 下降最快」">gradient</a>、更新權重」。對比的是 vanilla gradient descent（用全部資料算一次 gradient）：full-batch 在 trillion-token 級資料下完全不可行、SGD 用 mini-batch 把記憶體跟計算成本拉到可行範圍。</p>
<h2 id="概念位置">概念位置</h2>
<p>SGD 的更新公式：</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_new = W_old - learning_rate × gradient_of_loss_on_minibatch</span></span></code></pre></div><p>跟其他 optimizer 的對比：</p>
<table>
  <thead>
      <tr>
          <th>Optimizer</th>
          <th>更新規則</th>
          <th>特性</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>SGD</td>
          <td><code>W -= lr × g</code></td>
          <td>簡單、慢、容易卡 local minimum</td>
      </tr>
      <tr>
          <td>SGD + Momentum</td>
          <td>加速度項：<code>v = μv + g; W -= lr × v</code></td>
          <td>衝過 saddle point、收斂較穩</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/adam-adamw/" data-link-title="Adam / AdamW" data-link-desc="對每個參數自適應 learning rate 的 optimizer、LLM 訓練主流選擇">Adam / AdamW</a></td>
          <td>對每個參數自適應 lr、用 gradient 的 EMA 跟二階矩</td>
          <td>對 lr 較不敏感、LLM 訓練主流</td>
      </tr>
  </tbody>
</table>
<p>LLM 訓練幾乎都用 Adam / AdamW、不是純 SGD。但 SGD 仍出現在：</p>
<ol>
<li><strong>小模型 / 簡單任務</strong>：fine-tune 小 vision 模型、SGD + momentum 仍是合理選擇。</li>
<li><strong>理論分析 / 教學</strong>：SGD 是最簡單的 optimizer、用來解釋 gradient descent 概念。</li>
<li><strong>某些 fine-tuning 場景</strong>：<a href="/blog/llm/knowledge-cards/lora/" data-link-title="LoRA" data-link-desc="Low-Rank Adaptation：凍住原模型權重、只訓兩個小矩陣的 parameter-efficient fine-tuning">LoRA</a> 或 SFT 偶爾用 SGD（避免 Adam 改變 base model 太多）。</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 paper / training script 看到 optimizer 選擇、SGD 是基線、其他 optimizer 通常是「對 SGD 的改進」。寫 code 場景的判讀：訓練自己的小模型可以從 SGD + momentum 開始；fine-tune 大 LLM 沒理由不用 AdamW。</p>
]]></content:encoded></item><item><title>Shell 背景 Process</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/shell-background-process/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/shell-background-process/</guid><description>&lt;p>Shell 背景 Process 的核心概念是「terminal 啟動的程式何時跟 shell 綁定、何時可以脫離、被 shell 用什麼方式管理」。本地 LLM 場景中、&lt;code>ollama serve&lt;/code> 這類常駐 server 需要持續跑、放前景會把 terminal 卡住、放背景才能繼續打其他指令、或關掉 terminal 後讓服務改交給 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/launchd-service/" data-link-title="launchd Service" data-link-desc="macOS 原生的服務管理機制、把 process 註冊成自動啟動的 daemon 或 agent">launchd service&lt;/a> 接手。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Shell（zsh / bash）執行一個程式時、預設讓程式佔住 terminal、stdin / stdout / stderr 直接連到使用者眼前的視窗、稱為&lt;strong>前景 process&lt;/strong>。指令尾巴加 &lt;code>&amp;amp;&lt;/code> 改成&lt;strong>背景 process&lt;/strong>、shell 立刻拿回 prompt 控制權、程式繼續跑但不佔住 terminal。背景 process 仍綁在當前 shell session、關掉 terminal 視窗時通常會被 SIGHUP 終止；要完全脫離 shell 生命週期、得改用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/launchd-service/" data-link-title="launchd Service" data-link-desc="macOS 原生的服務管理機制、把 process 註冊成自動啟動的 daemon 或 agent">launchd service&lt;/a> 或 &lt;code>nohup&lt;/code> / &lt;code>disown&lt;/code> 等機制。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>shell 控制 process 的關鍵操作：&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>前景跑&lt;/td>
 &lt;td>&lt;code>ollama serve&lt;/code>&lt;/td>
 &lt;td>terminal 被卡住、看到 process stdout&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>背景跑&lt;/td>
 &lt;td>&lt;code>ollama serve &amp;amp;&lt;/code>&lt;/td>
 &lt;td>拿回 prompt、程式仍在跑&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>中止前景 process&lt;/td>
 &lt;td>&lt;code>Ctrl+C&lt;/code>&lt;/td>
 &lt;td>送 SIGINT、多數程式收到後優雅退出&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>暫停前景 process&lt;/td>
 &lt;td>&lt;code>Ctrl+Z&lt;/code>&lt;/td>
 &lt;td>送 SIGTSTP、process 進 stopped 狀態&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>列出當前 shell jobs&lt;/td>
 &lt;td>&lt;code>jobs&lt;/code>&lt;/td>
 &lt;td>看 shell 管理的背景 / 暫停 job&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>把 job 拉回前景&lt;/td>
 &lt;td>&lt;code>fg %1&lt;/code>&lt;/td>
 &lt;td>1 號 job 變前景&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>把暫停 job 改背景&lt;/td>
 &lt;td>&lt;code>bg %1&lt;/code>&lt;/td>
 &lt;td>1 號 job 改背景繼續跑&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>排錯常用的兩個工具（兩者跟 shell job 不直接相關、是 macOS 系統工具）：&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>&lt;code>lsof -i :11434&lt;/code>&lt;/td>
 &lt;td>找出哪個 process 在聽 11434 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/port-and-localhost/" data-link-title="Port 與 Localhost" data-link-desc="TCP port 與 listen address 如何決定 API server 的對外暴露範圍">port&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>pkill -f &amp;quot;ollama serve&amp;quot;&lt;/code>&lt;/td>
 &lt;td>用 pattern 匹配 process 命令列、送 SIGTERM 終止&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>ps aux | grep ollama&lt;/code>&lt;/td>
 &lt;td>列出所有跟 ollama 有關的 process&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>對 macOS 新手最常遇到的兩個事故：一個是「前景跑 server 後不知道怎麼脫身」、解法是 &lt;code>Ctrl+Z&lt;/code> 暫停 + &lt;code>bg&lt;/code> 改背景、或下次改用 &lt;code>&amp;amp;&lt;/code> 啟動；另一個是「pkill 沒指定夠精確的 pattern、誤殺其他 process」、解法是先用 &lt;code>ps aux&lt;/code> 加 &lt;code>grep&lt;/code> 確認 PID 再 kill。&lt;/p></description><content:encoded><![CDATA[<p>Shell 背景 Process 的核心概念是「terminal 啟動的程式何時跟 shell 綁定、何時可以脫離、被 shell 用什麼方式管理」。本地 LLM 場景中、<code>ollama serve</code> 這類常駐 server 需要持續跑、放前景會把 terminal 卡住、放背景才能繼續打其他指令、或關掉 terminal 後讓服務改交給 <a href="/blog/llm/knowledge-cards/launchd-service/" data-link-title="launchd Service" data-link-desc="macOS 原生的服務管理機制、把 process 註冊成自動啟動的 daemon 或 agent">launchd service</a> 接手。</p>
<h2 id="概念位置">概念位置</h2>
<p>Shell（zsh / bash）執行一個程式時、預設讓程式佔住 terminal、stdin / stdout / stderr 直接連到使用者眼前的視窗、稱為<strong>前景 process</strong>。指令尾巴加 <code>&amp;</code> 改成<strong>背景 process</strong>、shell 立刻拿回 prompt 控制權、程式繼續跑但不佔住 terminal。背景 process 仍綁在當前 shell session、關掉 terminal 視窗時通常會被 SIGHUP 終止；要完全脫離 shell 生命週期、得改用 <a href="/blog/llm/knowledge-cards/launchd-service/" data-link-title="launchd Service" data-link-desc="macOS 原生的服務管理機制、把 process 註冊成自動啟動的 daemon 或 agent">launchd service</a> 或 <code>nohup</code> / <code>disown</code> 等機制。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>shell 控制 process 的關鍵操作：</p>
<table>
  <thead>
      <tr>
          <th>動作</th>
          <th>指令 / 按鍵</th>
          <th>效果</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>前景跑</td>
          <td><code>ollama serve</code></td>
          <td>terminal 被卡住、看到 process stdout</td>
      </tr>
      <tr>
          <td>背景跑</td>
          <td><code>ollama serve &amp;</code></td>
          <td>拿回 prompt、程式仍在跑</td>
      </tr>
      <tr>
          <td>中止前景 process</td>
          <td><code>Ctrl+C</code></td>
          <td>送 SIGINT、多數程式收到後優雅退出</td>
      </tr>
      <tr>
          <td>暫停前景 process</td>
          <td><code>Ctrl+Z</code></td>
          <td>送 SIGTSTP、process 進 stopped 狀態</td>
      </tr>
      <tr>
          <td>列出當前 shell jobs</td>
          <td><code>jobs</code></td>
          <td>看 shell 管理的背景 / 暫停 job</td>
      </tr>
      <tr>
          <td>把 job 拉回前景</td>
          <td><code>fg %1</code></td>
          <td>1 號 job 變前景</td>
      </tr>
      <tr>
          <td>把暫停 job 改背景</td>
          <td><code>bg %1</code></td>
          <td>1 號 job 改背景繼續跑</td>
      </tr>
  </tbody>
</table>
<p>排錯常用的兩個工具（兩者跟 shell job 不直接相關、是 macOS 系統工具）：</p>
<table>
  <thead>
      <tr>
          <th>指令</th>
          <th>用途</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>lsof -i :11434</code></td>
          <td>找出哪個 process 在聽 11434 <a href="/blog/llm/knowledge-cards/port-and-localhost/" data-link-title="Port 與 Localhost" data-link-desc="TCP port 與 listen address 如何決定 API server 的對外暴露範圍">port</a></td>
      </tr>
      <tr>
          <td><code>pkill -f &quot;ollama serve&quot;</code></td>
          <td>用 pattern 匹配 process 命令列、送 SIGTERM 終止</td>
      </tr>
      <tr>
          <td><code>ps aux | grep ollama</code></td>
          <td>列出所有跟 ollama 有關的 process</td>
      </tr>
  </tbody>
</table>
<p>對 macOS 新手最常遇到的兩個事故：一個是「前景跑 server 後不知道怎麼脫身」、解法是 <code>Ctrl+Z</code> 暫停 + <code>bg</code> 改背景、或下次改用 <code>&amp;</code> 啟動；另一個是「pkill 沒指定夠精確的 pattern、誤殺其他 process」、解法是先用 <code>ps aux</code> 加 <code>grep</code> 確認 PID 再 kill。</p>
<h2 id="設計責任">設計責任</h2>
<p>選前景 vs 背景的判讀：debug 場景前景跑、能直接看到 log；日常使用改 <a href="/blog/llm/knowledge-cards/launchd-service/" data-link-title="launchd Service" data-link-desc="macOS 原生的服務管理機制、把 process 註冊成自動啟動的 daemon 或 agent">launchd service</a> 跑、跟 shell session 完全脫鉤。<code>&amp;</code> 適合「terminal 開著就讓它跑、關掉也沒關係」的臨時場景、不適合需要長期穩定的服務。排錯時養成「先 <code>lsof</code> 找誰佔資源、再 <code>ps</code> 確認身分、最後才 kill」的順序、避免誤殺。</p>
]]></content:encoded></item><item><title>Softmax</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/softmax/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/softmax/</guid><description>&lt;p>Softmax 的核心概念是「把一串實數轉成機率分佈」。公式是 &lt;code>softmax(x_i) = exp(x_i) / sum(exp(x_j))&lt;/code>、輸出總和為 1、每個值 ∈ [0, 1]。它是 LLM 兩個關鍵環節的常駐元件：&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> 的權重計算、跟 sampling 階段把 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/logit/" data-link-title="Logit" data-link-desc="softmax 之前的原始實數分數、每個 vocab token 一個值、可正可負">logit&lt;/a> 轉成「下個 token 的機率分佈」。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>LLM 中 softmax 出現的兩個位置：&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">位置 1：Attention 內部
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> Q · K^T → 一堆 score
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> softmax(scores) → attention weight（總和 1）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> weight · V → output
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">位置 2：每次 token 生成的最後一步
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> 最後一層 hidden → logit（每個 vocab token 一個實數分數）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl"> softmax(logits / temperature) → 機率分佈
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">9&lt;/span>&lt;span class="cl"> 從這個分佈 sample 出下一個 token&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>兩個位置的關鍵差異：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>位置&lt;/th>
 &lt;th>softmax 的作用&lt;/th>
 &lt;th>影響&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Attention&lt;/td>
 &lt;td>把 attention score 正規化成「該關注多少」&lt;/td>
 &lt;td>影響模型怎麼整合 context 資訊&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Sampling 端&lt;/td>
 &lt;td>把 logit 變機率、配合 temperature 調分佈陡度&lt;/td>
 &lt;td>影響輸出的多樣性 / 確定性&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Temperature 在 sampling 端跟 softmax 結合：&lt;code>softmax(logits / T)&lt;/code>、T 越小分佈越尖（接近 greedy）、T 越大分佈越平（接近隨機）。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 softmax 後可以判讀幾件事：temperature 為什麼影響輸出多樣性（改的是 softmax 前的縮放）、為什麼 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/logit/" data-link-title="Logit" data-link-desc="softmax 之前的原始實數分數、每個 vocab token 一個值、可正可負">logit&lt;/a> bias / logit warping 等技巧能控制輸出（直接動 softmax 的輸入）、為什麼 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/tool-use-principles/" data-link-title="4.3 Tool use 原理：LLM 跟外部世界互動" data-link-desc="Structured output 是 LLM 跨入工程系統的橋、function calling 取捨、為什麼本地小模型 tool use 表現崩潰">structured output&lt;/a> 的 grammar-constrained sampling 是「把不合法 token 的機率歸零」（在 softmax 後或前做 masking）。&lt;/p></description><content:encoded><![CDATA[<p>Softmax 的核心概念是「把一串實數轉成機率分佈」。公式是 <code>softmax(x_i) = exp(x_i) / sum(exp(x_j))</code>、輸出總和為 1、每個值 ∈ [0, 1]。它是 LLM 兩個關鍵環節的常駐元件：<a href="/blog/llm/knowledge-cards/attention/" data-link-title="Attention" data-link-desc="Transformer 內部讓每個 token 對其他 token 加權平均的核心機制、形成 KV cache 跟 context window 的計算基礎">attention</a> 的權重計算、跟 sampling 階段把 <a href="/blog/llm/knowledge-cards/logit/" data-link-title="Logit" data-link-desc="softmax 之前的原始實數分數、每個 vocab token 一個值、可正可負">logit</a> 轉成「下個 token 的機率分佈」。</p>
<h2 id="概念位置">概念位置</h2>
<p>LLM 中 softmax 出現的兩個位置：</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">位置 1：Attention 內部
</span></span><span class="line"><span class="ln">2</span><span class="cl">  Q · K^T → 一堆 score
</span></span><span class="line"><span class="ln">3</span><span class="cl">  softmax(scores) → attention weight（總和 1）
</span></span><span class="line"><span class="ln">4</span><span class="cl">  weight · V → output
</span></span><span class="line"><span class="ln">5</span><span class="cl">
</span></span><span class="line"><span class="ln">6</span><span class="cl">位置 2：每次 token 生成的最後一步
</span></span><span class="line"><span class="ln">7</span><span class="cl">  最後一層 hidden → logit（每個 vocab token 一個實數分數）
</span></span><span class="line"><span class="ln">8</span><span class="cl">  softmax(logits / temperature) → 機率分佈
</span></span><span class="line"><span class="ln">9</span><span class="cl">  從這個分佈 sample 出下一個 token</span></span></code></pre></div><p>兩個位置的關鍵差異：</p>
<table>
  <thead>
      <tr>
          <th>位置</th>
          <th>softmax 的作用</th>
          <th>影響</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Attention</td>
          <td>把 attention score 正規化成「該關注多少」</td>
          <td>影響模型怎麼整合 context 資訊</td>
      </tr>
      <tr>
          <td>Sampling 端</td>
          <td>把 logit 變機率、配合 temperature 調分佈陡度</td>
          <td>影響輸出的多樣性 / 確定性</td>
      </tr>
  </tbody>
</table>
<p>Temperature 在 sampling 端跟 softmax 結合：<code>softmax(logits / T)</code>、T 越小分佈越尖（接近 greedy）、T 越大分佈越平（接近隨機）。</p>
<h2 id="設計責任">設計責任</h2>
<p>理解 softmax 後可以判讀幾件事：temperature 為什麼影響輸出多樣性（改的是 softmax 前的縮放）、為什麼 <a href="/blog/llm/knowledge-cards/logit/" data-link-title="Logit" data-link-desc="softmax 之前的原始實數分數、每個 vocab token 一個值、可正可負">logit</a> bias / logit warping 等技巧能控制輸出（直接動 softmax 的輸入）、為什麼 <a href="/blog/llm/04-applications/tool-use-principles/" data-link-title="4.3 Tool use 原理：LLM 跟外部世界互動" data-link-desc="Structured output 是 LLM 跨入工程系統的橋、function calling 取捨、為什麼本地小模型 tool use 表現崩潰">structured output</a> 的 grammar-constrained sampling 是「把不合法 token 的機率歸零」（在 softmax 後或前做 masking）。</p>
]]></content:encoded></item><item><title>Special Tokens</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/special-tokens/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/special-tokens/</guid><description>&lt;p>Special tokens（特殊 token）的核心概念是「&lt;strong>在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/vocabulary-size/" data-link-title="Vocabulary Size" data-link-desc="tokenizer 詞彙表的 token 總數、影響 embedding 大小、tokenization 粒度、多語言友善度">vocab&lt;/a> 中保留給控制 / 邊界 / 結構用途的 token&lt;/strong>」、不是正常字面意義的詞。常見如 &lt;code>&amp;lt;bos&amp;gt;&lt;/code>（begin of sequence）、&lt;code>&amp;lt;eos&amp;gt;&lt;/code>（end of sequence）、&lt;code>&amp;lt;pad&amp;gt;&lt;/code>（padding）、&lt;code>&amp;lt;|user|&amp;gt;&lt;/code>、&lt;code>&amp;lt;|assistant|&amp;gt;&lt;/code>、&lt;code>&amp;lt;|tool_call|&amp;gt;&lt;/code> 等。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>LLM 中 special tokens 的常見類型：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Token&lt;/th>
 &lt;th>用途&lt;/th>
 &lt;th>範例&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;code>&amp;lt;bos&amp;gt;&lt;/code> / &lt;code>&amp;lt;s&amp;gt;&lt;/code>&lt;/td>
 &lt;td>序列開頭&lt;/td>
 &lt;td>Llama、Mistral&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>&amp;lt;eos&amp;gt;&lt;/code> / &lt;code>&amp;lt;/s&amp;gt;&lt;/code>&lt;/td>
 &lt;td>序列結尾、模型輸出這個就停&lt;/td>
 &lt;td>所有 LLM&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>&amp;lt;pad&amp;gt;&lt;/code>&lt;/td>
 &lt;td>把 batch 內不同長度 sequence 填齊&lt;/td>
 &lt;td>訓練 / batched 推論時用&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>&amp;lt;unk&amp;gt;&lt;/code>&lt;/td>
 &lt;td>遇到 vocab 外的 token（byte-level BPE 已不需要）&lt;/td>
 &lt;td>早期 tokenizer&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>&amp;lt;|user|&amp;gt;&lt;/code> / &lt;code>&amp;lt;|assistant|&amp;gt;&lt;/code>&lt;/td>
 &lt;td>Chat template 角色標記&lt;/td>
 &lt;td>Llama 3 chat、Qwen chat&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>&amp;lt;|im_start|&amp;gt;&lt;/code> / &lt;code>&amp;lt;|im_end|&amp;gt;&lt;/code>&lt;/td>
 &lt;td>ChatML 格式的對話邊界&lt;/td>
 &lt;td>OpenAI、Qwen 系列&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>&amp;lt;|tool_call|&amp;gt;&lt;/code> / &lt;code>&amp;lt;|tool_response|&amp;gt;&lt;/code>&lt;/td>
 &lt;td>Tool use / function calling 訊號&lt;/td>
 &lt;td>Llama 3.1+ 等支援 tool use 的模型&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>&amp;lt;think&amp;gt;&lt;/code> / &lt;code>&amp;lt;/think&amp;gt;&lt;/code>&lt;/td>
 &lt;td>Chain-of-thought 標記&lt;/td>
 &lt;td>DeepSeek-R1、O1 風格模型&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵特性：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>訓練時用特殊 token ID 標記&lt;/strong>：模型透過大量範例學會「看到 &lt;code>&amp;lt;\|user\|&amp;gt;&lt;/code> 後面是使用者輸入、看到 &lt;code>&amp;lt;\|assistant\|&amp;gt;&lt;/code> 後面要生成回答」。&lt;/li>
&lt;li>&lt;strong>Chat template 把這些組合起來&lt;/strong>：把使用者輸入 + 系統 prompt + 對話歷史依特定格式插入這些 token、組成模型訓練時看過的格式。&lt;/li>
&lt;li>&lt;strong>&lt;code>&amp;lt;eos&amp;gt;&lt;/code> 的 sampling 行為&lt;/strong>：模型輸出 &lt;code>&amp;lt;eos&amp;gt;&lt;/code> 後、推論伺服器停止生成、所以「為什麼回答突然停了」很多時候就是模型決定發 EOS。&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 tokenizer config（&lt;code>tokenizer_config.json&lt;/code>）看到 &lt;code>bos_token&lt;/code>、&lt;code>eos_token&lt;/code>、&lt;code>chat_template&lt;/code> 等就是這組設定。寫 code 場景的判讀：用 Continue.dev / Ollama 時、伺服器會自動套用模型的 chat template、把使用者輸入轉成正確的 special tokens 格式；自己寫 inference code 時、要呼叫 &lt;code>tokenizer.apply_chat_template()&lt;/code> 避免格式錯亂導致模型輸出爛。&lt;/p></description><content:encoded><![CDATA[<p>Special tokens（特殊 token）的核心概念是「<strong>在 <a href="/blog/llm/knowledge-cards/vocabulary-size/" data-link-title="Vocabulary Size" data-link-desc="tokenizer 詞彙表的 token 總數、影響 embedding 大小、tokenization 粒度、多語言友善度">vocab</a> 中保留給控制 / 邊界 / 結構用途的 token</strong>」、不是正常字面意義的詞。常見如 <code>&lt;bos&gt;</code>（begin of sequence）、<code>&lt;eos&gt;</code>（end of sequence）、<code>&lt;pad&gt;</code>（padding）、<code>&lt;|user|&gt;</code>、<code>&lt;|assistant|&gt;</code>、<code>&lt;|tool_call|&gt;</code> 等。</p>
<h2 id="概念位置">概念位置</h2>
<p>LLM 中 special tokens 的常見類型：</p>
<table>
  <thead>
      <tr>
          <th>Token</th>
          <th>用途</th>
          <th>範例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>&lt;bos&gt;</code> / <code>&lt;s&gt;</code></td>
          <td>序列開頭</td>
          <td>Llama、Mistral</td>
      </tr>
      <tr>
          <td><code>&lt;eos&gt;</code> / <code>&lt;/s&gt;</code></td>
          <td>序列結尾、模型輸出這個就停</td>
          <td>所有 LLM</td>
      </tr>
      <tr>
          <td><code>&lt;pad&gt;</code></td>
          <td>把 batch 內不同長度 sequence 填齊</td>
          <td>訓練 / batched 推論時用</td>
      </tr>
      <tr>
          <td><code>&lt;unk&gt;</code></td>
          <td>遇到 vocab 外的 token（byte-level BPE 已不需要）</td>
          <td>早期 tokenizer</td>
      </tr>
      <tr>
          <td><code>&lt;|user|&gt;</code> / <code>&lt;|assistant|&gt;</code></td>
          <td>Chat template 角色標記</td>
          <td>Llama 3 chat、Qwen chat</td>
      </tr>
      <tr>
          <td><code>&lt;|im_start|&gt;</code> / <code>&lt;|im_end|&gt;</code></td>
          <td>ChatML 格式的對話邊界</td>
          <td>OpenAI、Qwen 系列</td>
      </tr>
      <tr>
          <td><code>&lt;|tool_call|&gt;</code> / <code>&lt;|tool_response|&gt;</code></td>
          <td>Tool use / function calling 訊號</td>
          <td>Llama 3.1+ 等支援 tool use 的模型</td>
      </tr>
      <tr>
          <td><code>&lt;think&gt;</code> / <code>&lt;/think&gt;</code></td>
          <td>Chain-of-thought 標記</td>
          <td>DeepSeek-R1、O1 風格模型</td>
      </tr>
  </tbody>
</table>
<p>關鍵特性：</p>
<ol>
<li><strong>訓練時用特殊 token ID 標記</strong>：模型透過大量範例學會「看到 <code>&lt;\|user\|&gt;</code> 後面是使用者輸入、看到 <code>&lt;\|assistant\|&gt;</code> 後面要生成回答」。</li>
<li><strong>Chat template 把這些組合起來</strong>：把使用者輸入 + 系統 prompt + 對話歷史依特定格式插入這些 token、組成模型訓練時看過的格式。</li>
<li><strong><code>&lt;eos&gt;</code> 的 sampling 行為</strong>：模型輸出 <code>&lt;eos&gt;</code> 後、推論伺服器停止生成、所以「為什麼回答突然停了」很多時候就是模型決定發 EOS。</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 tokenizer config（<code>tokenizer_config.json</code>）看到 <code>bos_token</code>、<code>eos_token</code>、<code>chat_template</code> 等就是這組設定。寫 code 場景的判讀：用 Continue.dev / Ollama 時、伺服器會自動套用模型的 chat template、把使用者輸入轉成正確的 special tokens 格式；自己寫 inference code 時、要呼叫 <code>tokenizer.apply_chat_template()</code> 避免格式錯亂導致模型輸出爛。</p>
]]></content:encoded></item><item><title>Subagent</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/subagent/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/subagent/</guid><description>&lt;p>Subagent 的核心概念是「&lt;strong>把 coding agent 切成多個專責子 agent、每個有獨立 &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> 跟 system prompt、由 main agent 透過 handoff 機制調度&lt;/strong>」。代表設計：Claude Code 的 Task agent、OpenAI Agents SDK 的 handoff、Anthropic multi-agent research。是「context budget 不夠 + 任務跨多個 specialty」場景的工程選擇。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Single agent vs subagent 架構的對比：&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">Single agent（無 subagent）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> Main agent context：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> [system prompt + tool schema + 跨所有 specialty 的 history + 所有 file content]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> ↓ 容易爆 context、specialty 互相干擾
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">Subagent 架構：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> Main agent context（路由 + 高階決策）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> [main system prompt + handoff tool spec + 高階任務歷史]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> ↓ 路由到 subagent
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> Subagent A context（如「跑測試」專家）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> [test-runner system prompt + 測試 tool + 測試相關 file]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl"> Subagent B context（如「寫 docs」專家）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl"> [docs system prompt + 寫 docs tool + 相關 docs 檔案]&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>主要好處：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Context budget 隔離&lt;/strong>：每個 subagent 只看自己 specialty 相關 context、不被別的 specialty 污染&lt;/li>
&lt;li>&lt;strong>System prompt 專門化&lt;/strong>：寫 docs 的 system prompt 跟跑測試的 system prompt 不同、各自最佳化&lt;/li>
&lt;li>&lt;strong>Specialty 路由&lt;/strong>：main agent 只決定「這個任務該交給哪個 subagent」、不直接做 specialty 工作&lt;/li>
&lt;/ol>
&lt;p>主要挑戰：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Handoff 設計&lt;/strong>：main agent 要怎麼選 subagent、怎麼傳 context、怎麼接 result&lt;/li>
&lt;li>&lt;strong>跨 subagent 共享狀態&lt;/strong>：codebase 知識、history、要避免重複 work&lt;/li>
&lt;li>&lt;strong>失敗模式&lt;/strong>：subagent 之間互相 deadlock、main agent 失去 high-level view、subagent 邊界劃錯&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 multi-agent / subagent paper / coding agent docs 看到「subagent」「handoff」「Task tool」「specialist agent」就是這 framing。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>何時用 subagent&lt;/strong>：單一 agent context 不夠用、specialty 邊界清楚（如 search / coding / testing / documentation）、main agent 的 system prompt 已太長&lt;/li>
&lt;li>&lt;strong>何時不用&lt;/strong>：任務簡單、specialty 邊界模糊（強行拆會增加 handoff overhead）、本地小模型（handoff 機制對小模型不穩）&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop&lt;/a> 的關係&lt;/strong>：每個 subagent 內部仍是 agent loop（perceive / reason / act / observe / terminate）、只是 loop 範圍縮窄&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/scaffold-vs-harness/" data-link-title="Scaffold vs Harness" data-link-desc="Coding agent 的兩個工程層次：scaffold 是建構時靜態結構、harness 是 runtime 的 tool dispatch &amp;#43; context management &amp;#43; safety">scaffold vs harness&lt;/a> 的關係&lt;/strong>：subagent 註冊在 scaffold（建構時）、handoff 在 harness（runtime）執行&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Subagent 的核心概念是「<strong>把 coding agent 切成多個專責子 agent、每個有獨立 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a> 跟 system prompt、由 main agent 透過 handoff 機制調度</strong>」。代表設計：Claude Code 的 Task agent、OpenAI Agents SDK 的 handoff、Anthropic multi-agent research。是「context budget 不夠 + 任務跨多個 specialty」場景的工程選擇。</p>
<h2 id="概念位置">概念位置</h2>
<p>Single agent vs subagent 架構的對比：</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">Single agent（無 subagent）：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  Main agent context：
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    [system prompt + tool schema + 跨所有 specialty 的 history + 所有 file content]
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    ↓ 容易爆 context、specialty 互相干擾
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">Subagent 架構：
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  Main agent context（路由 + 高階決策）：
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    [main system prompt + handoff tool spec + 高階任務歷史]
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">       ↓ 路由到 subagent
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">  Subagent A context（如「跑測試」專家）：
</span></span><span class="line"><span class="ln">12</span><span class="cl">    [test-runner system prompt + 測試 tool + 測試相關 file]
</span></span><span class="line"><span class="ln">13</span><span class="cl">
</span></span><span class="line"><span class="ln">14</span><span class="cl">  Subagent B context（如「寫 docs」專家）：
</span></span><span class="line"><span class="ln">15</span><span class="cl">    [docs system prompt + 寫 docs tool + 相關 docs 檔案]</span></span></code></pre></div><p>主要好處：</p>
<ol>
<li><strong>Context budget 隔離</strong>：每個 subagent 只看自己 specialty 相關 context、不被別的 specialty 污染</li>
<li><strong>System prompt 專門化</strong>：寫 docs 的 system prompt 跟跑測試的 system prompt 不同、各自最佳化</li>
<li><strong>Specialty 路由</strong>：main agent 只決定「這個任務該交給哪個 subagent」、不直接做 specialty 工作</li>
</ol>
<p>主要挑戰：</p>
<ol>
<li><strong>Handoff 設計</strong>：main agent 要怎麼選 subagent、怎麼傳 context、怎麼接 result</li>
<li><strong>跨 subagent 共享狀態</strong>：codebase 知識、history、要避免重複 work</li>
<li><strong>失敗模式</strong>：subagent 之間互相 deadlock、main agent 失去 high-level view、subagent 邊界劃錯</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 multi-agent / subagent paper / coding agent docs 看到「subagent」「handoff」「Task tool」「specialist agent」就是這 framing。寫 code 場景的判讀：</p>
<ol>
<li><strong>何時用 subagent</strong>：單一 agent context 不夠用、specialty 邊界清楚（如 search / coding / testing / documentation）、main agent 的 system prompt 已太長</li>
<li><strong>何時不用</strong>：任務簡單、specialty 邊界模糊（強行拆會增加 handoff overhead）、本地小模型（handoff 機制對小模型不穩）</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop</a> 的關係</strong>：每個 subagent 內部仍是 agent loop（perceive / reason / act / observe / terminate）、只是 loop 範圍縮窄</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/scaffold-vs-harness/" data-link-title="Scaffold vs Harness" data-link-desc="Coding agent 的兩個工程層次：scaffold 是建構時靜態結構、harness 是 runtime 的 tool dispatch &#43; context management &#43; safety">scaffold vs harness</a> 的關係</strong>：subagent 註冊在 scaffold（建構時）、handoff 在 harness（runtime）執行</li>
</ol>
]]></content:encoded></item><item><title>System Prompt</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/system-prompt/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/system-prompt/</guid><description>&lt;p>System prompt 的核心概念是「LLM application 中、由開發者預設、放在每次 conversation 最前面、不直接顯示給使用者的指令層」。常見用途包括設定模型角色（如「你是 senior Python engineer」）、規範輸出格式（如「always return JSON」）、加入 safety guideline。Chat-based LLM API（OpenAI、Anthropic 等）通常有專門的 &lt;code>role: &amp;quot;system&amp;quot;&lt;/code> message type。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>LLM API call 的訊息結構：&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">messages = [
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> {role: &amp;#34;system&amp;#34;, content: &amp;#34;你是專業 code reviewer...&amp;#34;}, ← system prompt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> {role: &amp;#34;user&amp;#34;, content: &amp;#34;請 review 這段 code: ...&amp;#34;},
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> {role: &amp;#34;assistant&amp;#34;, content: &amp;#34;...&amp;#34;}, ← 模型回答
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> {role: &amp;#34;user&amp;#34;, content: &amp;#34;...&amp;#34;}, ← 後續對話
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> ...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">]&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>System prompt 在 application 設計中的角色：&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>角色定義&lt;/td>
 &lt;td>&amp;ldquo;你是 senior Python engineer、專長 async / typing&amp;rdquo;&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>輸出格式約束&lt;/td>
 &lt;td>&amp;ldquo;always return JSON with keys: title, body, tags&amp;rdquo;&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>行為規範&lt;/td>
 &lt;td>&amp;ldquo;若不確定、明確說『我不知道』、不要編造&amp;rdquo;&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>工具使用指引&lt;/td>
 &lt;td>&amp;ldquo;When user asks about weather, call get_weather tool&amp;rdquo;&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>安全約束&lt;/td>
 &lt;td>&amp;ldquo;Do not generate executable shell commands&amp;rdquo;&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>上下文注入&lt;/td>
 &lt;td>&amp;ldquo;Current date: 2026-05-12; User language: zh-TW&amp;rdquo;&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：不同 LLM vendor 對 system prompt 的處理機制不同（如部分模型把 system 跟 user 視為相同優先級、部分模型有特殊訓練讓 system 較高優先）、具體行為以該模型的&lt;a href="https://platform.openai.com/docs/api-reference/chat">官方文件&lt;/a>為準。&lt;/p>&lt;/blockquote>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 system prompt 後可以解釋兩個現象：為什麼同一個模型在不同 LLM 應用中的「個性」差很多（system prompt 不同）、為什麼 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prompt-injection/" data-link-title="Prompt Injection" data-link-desc="把惡意指令藏進 LLM 會讀到的內容、誘導 LLM 跑出非開發者預期行為的攻擊類別、OWASP LLM01 列入頭號威脅">prompt injection&lt;/a> 的主要目標是繞過 system prompt 的約束（攻擊者想讓模型不照原本指令走）。&lt;/p>
&lt;p>實務上、設計 LLM application 時、system prompt 是行為約束的第一層、但不是唯一防線（容易被 injection 繞過）；critical 行為應該在 application 層（如 tool call 的權限白名單、輸出驗證）加第二層防護。詳見 &lt;a href="https://tarrragon.github.io/blog/llm/06-security/prompt-injection-in-ide/" data-link-title="6.3 IDE 場景的 prompt injection" data-link-desc="個人 dev 場景下 IDE 寫 code 工作流的 prompt injection：codebase 內容、外部文件、剪貼簿作為攻擊面、跟雲端 LLM 場景的差異">6.3 IDE 場景的 prompt injection&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>System prompt 的核心概念是「LLM application 中、由開發者預設、放在每次 conversation 最前面、不直接顯示給使用者的指令層」。常見用途包括設定模型角色（如「你是 senior Python engineer」）、規範輸出格式（如「always return JSON」）、加入 safety guideline。Chat-based LLM API（OpenAI、Anthropic 等）通常有專門的 <code>role: &quot;system&quot;</code> message type。</p>
<h2 id="概念位置">概念位置</h2>
<p>LLM API call 的訊息結構：</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">messages = [
</span></span><span class="line"><span class="ln">2</span><span class="cl">  {role: &#34;system&#34;, content: &#34;你是專業 code reviewer...&#34;},  ← system prompt
</span></span><span class="line"><span class="ln">3</span><span class="cl">  {role: &#34;user&#34;,   content: &#34;請 review 這段 code: ...&#34;},
</span></span><span class="line"><span class="ln">4</span><span class="cl">  {role: &#34;assistant&#34;, content: &#34;...&#34;},  ← 模型回答
</span></span><span class="line"><span class="ln">5</span><span class="cl">  {role: &#34;user&#34;,   content: &#34;...&#34;},     ← 後續對話
</span></span><span class="line"><span class="ln">6</span><span class="cl">  ...
</span></span><span class="line"><span class="ln">7</span><span class="cl">]</span></span></code></pre></div><p>System prompt 在 application 設計中的角色：</p>
<table>
  <thead>
      <tr>
          <th>用途</th>
          <th>例子</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>角色定義</td>
          <td>&ldquo;你是 senior Python engineer、專長 async / typing&rdquo;</td>
      </tr>
      <tr>
          <td>輸出格式約束</td>
          <td>&ldquo;always return JSON with keys: title, body, tags&rdquo;</td>
      </tr>
      <tr>
          <td>行為規範</td>
          <td>&ldquo;若不確定、明確說『我不知道』、不要編造&rdquo;</td>
      </tr>
      <tr>
          <td>工具使用指引</td>
          <td>&ldquo;When user asks about weather, call get_weather tool&rdquo;</td>
      </tr>
      <tr>
          <td>安全約束</td>
          <td>&ldquo;Do not generate executable shell commands&rdquo;</td>
      </tr>
      <tr>
          <td>上下文注入</td>
          <td>&ldquo;Current date: 2026-05-12; User language: zh-TW&rdquo;</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p><strong>事實查核註</strong>：不同 LLM vendor 對 system prompt 的處理機制不同（如部分模型把 system 跟 user 視為相同優先級、部分模型有特殊訓練讓 system 較高優先）、具體行為以該模型的<a href="https://platform.openai.com/docs/api-reference/chat">官方文件</a>為準。</p></blockquote>
<h2 id="設計責任">設計責任</h2>
<p>理解 system prompt 後可以解釋兩個現象：為什麼同一個模型在不同 LLM 應用中的「個性」差很多（system prompt 不同）、為什麼 <a href="/blog/llm/knowledge-cards/prompt-injection/" data-link-title="Prompt Injection" data-link-desc="把惡意指令藏進 LLM 會讀到的內容、誘導 LLM 跑出非開發者預期行為的攻擊類別、OWASP LLM01 列入頭號威脅">prompt injection</a> 的主要目標是繞過 system prompt 的約束（攻擊者想讓模型不照原本指令走）。</p>
<p>實務上、設計 LLM application 時、system prompt 是行為約束的第一層、但不是唯一防線（容易被 injection 繞過）；critical 行為應該在 application 層（如 tool call 的權限白名單、輸出驗證）加第二層防護。詳見 <a href="/blog/llm/06-security/prompt-injection-in-ide/" data-link-title="6.3 IDE 場景的 prompt injection" data-link-desc="個人 dev 場景下 IDE 寫 code 工作流的 prompt injection：codebase 內容、外部文件、剪貼簿作為攻擊面、跟雲端 LLM 場景的差異">6.3 IDE 場景的 prompt injection</a>。</p>
]]></content:encoded></item><item><title>Tensor</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/tensor/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/tensor/</guid><description>&lt;p>Tensor（張量）的核心概念是「&lt;strong>N 維陣列&lt;/strong>」。Scalar 是 0D tensor、vector 是 1D、matrix 是 2D、再往上加維度就是 3D、4D。PyTorch、MLX、JAX、TensorFlow 等所有深度學習 framework 的核心型別都叫 Tensor、所有 LLM 內部運算（&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/matrix-multiplication/" data-link-title="Matrix Multiplication" data-link-desc="LLM 推論最頻繁的單一運算、forward pass 每層的核心、memory bandwidth 瓶頸的根源">matrix multiplication&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/softmax/" data-link-title="Softmax" data-link-desc="把任意實數向量正規化成「總和為 1、每個分量 ∈ [0,1]」的機率分佈">softmax&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/layer-normalization/" data-link-title="Layer Normalization" data-link-desc="在每個 token 的 hidden state 上做正規化（減 mean、除 std）、穩定深層網路訓練">layer norm&lt;/a> 等）都對 tensor 做。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>LLM 中常見的 tensor 維度：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>shape&lt;/th>
 &lt;th>意義&lt;/th>
 &lt;th>出現在&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>1D&lt;/td>
 &lt;td>&lt;code>(vocab_size,)&lt;/code>&lt;/td>
 &lt;td>一個 token 位置的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/logit/" data-link-title="Logit" data-link-desc="softmax 之前的原始實數分數、每個 vocab token 一個值、可正可負">logit&lt;/a> 向量&lt;/td>
 &lt;td>Output layer 輸出&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>2D&lt;/td>
 &lt;td>&lt;code>(seq_len, hidden_dim)&lt;/code>&lt;/td>
 &lt;td>一個 sequence 的 hidden state&lt;/td>
 &lt;td>每個 Transformer block 內部&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>3D&lt;/td>
 &lt;td>&lt;code>(batch_size, seq_len, hidden_dim)&lt;/code>&lt;/td>
 &lt;td>一個 batch 的多個 sequence&lt;/td>
 &lt;td>Batched 推論 / 訓練&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>4D&lt;/td>
 &lt;td>&lt;code>(batch_size, num_heads, seq_len, head_dim)&lt;/code>&lt;/td>
 &lt;td>Multi-head attention 的並行結構&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/self-attention/" data-link-title="Self-Attention" data-link-desc="Q / K / V 都從同一個 sequence 投影出來的 attention、Transformer 的標誌性設計">Self-attention&lt;/a> 內部&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>5D+&lt;/td>
 &lt;td>&lt;code>(batch, heads, seq, head_dim, ...)&lt;/code>&lt;/td>
 &lt;td>罕見、特殊架構&lt;/td>
 &lt;td>MoE expert dispatch、特殊 attention&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵運算：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Reshape&lt;/strong>：改 shape 但不變資料總量、如 &lt;code>(batch, seq, hidden) → (batch * seq, hidden)&lt;/code>。&lt;/li>
&lt;li>&lt;strong>Transpose / permute&lt;/strong>：交換維度順序、attention 計算前後常用。&lt;/li>
&lt;li>&lt;strong>Broadcasting&lt;/strong>：不同 shape 的 tensor 自動擴展配對、如 &lt;code>(seq, hidden) + (hidden,)&lt;/code>。&lt;/li>
&lt;li>&lt;strong>Indexing / slicing&lt;/strong>：抽出子 tensor、如 &lt;code>tensor[:, -1, :]&lt;/code> 取最後一個 token 的 hidden。&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 PyTorch / MLX 推論 / 訓練 code 看到 &lt;code>torch.Tensor&lt;/code>、&lt;code>mx.array&lt;/code>、&lt;code>tf.Tensor&lt;/code> 等就是這個型別、所有 LLM 運算都建在它上面。寫 code 場景的判讀：報錯訊息看到 &lt;code>shape mismatch&lt;/code> / &lt;code>size of dimension X&lt;/code> 通常是 tensor 維度配錯；&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> 內部存的就是 4D tensor &lt;code>(num_layers, 2, batch, num_kv_heads, seq, head_dim)&lt;/code> 之類的結構、量化 KV cache 就是改這個 tensor 的 dtype。&lt;/p></description><content:encoded><![CDATA[<p>Tensor（張量）的核心概念是「<strong>N 維陣列</strong>」。Scalar 是 0D tensor、vector 是 1D、matrix 是 2D、再往上加維度就是 3D、4D。PyTorch、MLX、JAX、TensorFlow 等所有深度學習 framework 的核心型別都叫 Tensor、所有 LLM 內部運算（<a href="/blog/llm/knowledge-cards/matrix-multiplication/" data-link-title="Matrix Multiplication" data-link-desc="LLM 推論最頻繁的單一運算、forward pass 每層的核心、memory bandwidth 瓶頸的根源">matrix multiplication</a>、<a href="/blog/llm/knowledge-cards/softmax/" data-link-title="Softmax" data-link-desc="把任意實數向量正規化成「總和為 1、每個分量 ∈ [0,1]」的機率分佈">softmax</a>、<a href="/blog/llm/knowledge-cards/layer-normalization/" data-link-title="Layer Normalization" data-link-desc="在每個 token 的 hidden state 上做正規化（減 mean、除 std）、穩定深層網路訓練">layer norm</a> 等）都對 tensor 做。</p>
<h2 id="概念位置">概念位置</h2>
<p>LLM 中常見的 tensor 維度：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>shape</th>
          <th>意義</th>
          <th>出現在</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1D</td>
          <td><code>(vocab_size,)</code></td>
          <td>一個 token 位置的 <a href="/blog/llm/knowledge-cards/logit/" data-link-title="Logit" data-link-desc="softmax 之前的原始實數分數、每個 vocab token 一個值、可正可負">logit</a> 向量</td>
          <td>Output layer 輸出</td>
      </tr>
      <tr>
          <td>2D</td>
          <td><code>(seq_len, hidden_dim)</code></td>
          <td>一個 sequence 的 hidden state</td>
          <td>每個 Transformer block 內部</td>
      </tr>
      <tr>
          <td>3D</td>
          <td><code>(batch_size, seq_len, hidden_dim)</code></td>
          <td>一個 batch 的多個 sequence</td>
          <td>Batched 推論 / 訓練</td>
      </tr>
      <tr>
          <td>4D</td>
          <td><code>(batch_size, num_heads, seq_len, head_dim)</code></td>
          <td>Multi-head attention 的並行結構</td>
          <td><a href="/blog/llm/knowledge-cards/self-attention/" data-link-title="Self-Attention" data-link-desc="Q / K / V 都從同一個 sequence 投影出來的 attention、Transformer 的標誌性設計">Self-attention</a> 內部</td>
      </tr>
      <tr>
          <td>5D+</td>
          <td><code>(batch, heads, seq, head_dim, ...)</code></td>
          <td>罕見、特殊架構</td>
          <td>MoE expert dispatch、特殊 attention</td>
      </tr>
  </tbody>
</table>
<p>關鍵運算：</p>
<ol>
<li><strong>Reshape</strong>：改 shape 但不變資料總量、如 <code>(batch, seq, hidden) → (batch * seq, hidden)</code>。</li>
<li><strong>Transpose / permute</strong>：交換維度順序、attention 計算前後常用。</li>
<li><strong>Broadcasting</strong>：不同 shape 的 tensor 自動擴展配對、如 <code>(seq, hidden) + (hidden,)</code>。</li>
<li><strong>Indexing / slicing</strong>：抽出子 tensor、如 <code>tensor[:, -1, :]</code> 取最後一個 token 的 hidden。</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 PyTorch / MLX 推論 / 訓練 code 看到 <code>torch.Tensor</code>、<code>mx.array</code>、<code>tf.Tensor</code> 等就是這個型別、所有 LLM 運算都建在它上面。寫 code 場景的判讀：報錯訊息看到 <code>shape mismatch</code> / <code>size of dimension X</code> 通常是 tensor 維度配錯；<a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 內部存的就是 4D tensor <code>(num_layers, 2, batch, num_kv_heads, seq, head_dim)</code> 之類的結構、量化 KV cache 就是改這個 tensor 的 dtype。</p>
]]></content:encoded></item><item><title>Test-Time Compute</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/test-time-compute/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/test-time-compute/</guid><description>&lt;p>Test-time compute（推論時計算）的核心概念是「&lt;strong>在推論階段花更多計算量、換取更高品質的答案&lt;/strong>」、不是只在訓練時投入算力。是 2024-2026 LLM 的 paradigm shift：GPT-3 → GPT-4 主要靠「更大模型 + 更多訓練資料」；o1 / DeepSeek-R1 → 主要靠「同模型、推論時想更久」。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>LLM 算力分配的兩條軸：&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">Training compute（訓練算力）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> pre-training 大量 GPU-hour → 模型參數
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> 一次性投入、後續推論不變
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> → GPT-3 → 4 的主要 paradigm
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">Test-time compute（推論算力）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> 每次推論時、視任務難度動態增加算力
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> 難題想 30 秒（生 5000 token reasoning trace）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> 簡單問題 1 秒結束（直接答）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> → o1 / R1 / Claude thinking 的新 paradigm&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Test-time compute 的常見實作形式：&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>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/chain-of-thought/" data-link-title="Chain-of-Thought（CoT）" data-link-desc="讓 LLM 先輸出推理步驟再給最終答案的 prompting / 訓練方式、reasoning model 的基礎機制">Chain-of-thought&lt;/a> 內建&lt;/td>
 &lt;td>模型訓練成「自然」用長 reasoning trace、直接生 thinking + answer&lt;/td>
 &lt;td>o1、DeepSeek-R1、Qwen-QwQ、Claude thinking&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Best-of-N sampling&lt;/td>
 &lt;td>同 prompt 跑 N 次、reward model 選最好的&lt;/td>
 &lt;td>OpenAI early experiments、verifier-based&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Tree search&lt;/td>
 &lt;td>結構化探索多條 reasoning path&lt;/td>
 &lt;td>AlphaCode、tree of thoughts&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Self-consistency&lt;/td>
 &lt;td>多次 sample reasoning、投票選最常見答案&lt;/td>
 &lt;td>早期 CoT prompting 技巧&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Tool use + verification&lt;/td>
 &lt;td>模型呼叫 calculator / interpreter 驗證自己&lt;/td>
 &lt;td>Coding agent、math 解題 agent&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>DeepSeek-R1 paper 顯示「reasoning trace 長度跟 benchmark 表現正相關、可透過 RL 拉長」— 把 test-time compute 變成可訓練、可 scale 的維度。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 paper / benchmark 看到「pass@1 vs pass@10」「budget tokens」「thinking time」等就跟 test-time compute 相關。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Reasoning model 算成本翻倍&lt;/strong>：同一個 prompt、reasoning model 生 5000 token thinking + 500 token answer、傳統 model 直接生 500 token answer、推論成本差 ~10 倍&lt;/li>
&lt;li>&lt;strong>本地跑 reasoning model 的痛點&lt;/strong>：需要長 &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> 容納 thinking trace、生成時間長&lt;/li>
&lt;li>&lt;strong>適用任務挑選&lt;/strong>：複雜 reasoning（math、debug、long horizon planning）值得花 test-time compute；簡單任務（autocomplete、查詢）不值得&lt;/li>
&lt;li>&lt;strong>混用策略&lt;/strong>：日常用 instruct model、困難任務切到 reasoning model、是個人 dev 常見模式&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Test-time compute（推論時計算）的核心概念是「<strong>在推論階段花更多計算量、換取更高品質的答案</strong>」、不是只在訓練時投入算力。是 2024-2026 LLM 的 paradigm shift：GPT-3 → GPT-4 主要靠「更大模型 + 更多訓練資料」；o1 / DeepSeek-R1 → 主要靠「同模型、推論時想更久」。</p>
<h2 id="概念位置">概念位置</h2>
<p>LLM 算力分配的兩條軸：</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">Training compute（訓練算力）：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  pre-training 大量 GPU-hour → 模型參數
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">  一次性投入、後續推論不變
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  → GPT-3 → 4 的主要 paradigm
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">Test-time compute（推論算力）：
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  每次推論時、視任務難度動態增加算力
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  難題想 30 秒（生 5000 token reasoning trace）
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">  簡單問題 1 秒結束（直接答）
</span></span><span class="line"><span class="ln">10</span><span class="cl">  → o1 / R1 / Claude thinking 的新 paradigm</span></span></code></pre></div><p>Test-time compute 的常見實作形式：</p>
<table>
  <thead>
      <tr>
          <th>形式</th>
          <th>機制</th>
          <th>代表</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/chain-of-thought/" data-link-title="Chain-of-Thought（CoT）" data-link-desc="讓 LLM 先輸出推理步驟再給最終答案的 prompting / 訓練方式、reasoning model 的基礎機制">Chain-of-thought</a> 內建</td>
          <td>模型訓練成「自然」用長 reasoning trace、直接生 thinking + answer</td>
          <td>o1、DeepSeek-R1、Qwen-QwQ、Claude thinking</td>
      </tr>
      <tr>
          <td>Best-of-N sampling</td>
          <td>同 prompt 跑 N 次、reward model 選最好的</td>
          <td>OpenAI early experiments、verifier-based</td>
      </tr>
      <tr>
          <td>Tree search</td>
          <td>結構化探索多條 reasoning path</td>
          <td>AlphaCode、tree of thoughts</td>
      </tr>
      <tr>
          <td>Self-consistency</td>
          <td>多次 sample reasoning、投票選最常見答案</td>
          <td>早期 CoT prompting 技巧</td>
      </tr>
      <tr>
          <td>Tool use + verification</td>
          <td>模型呼叫 calculator / interpreter 驗證自己</td>
          <td>Coding agent、math 解題 agent</td>
      </tr>
  </tbody>
</table>
<p>DeepSeek-R1 paper 顯示「reasoning trace 長度跟 benchmark 表現正相關、可透過 RL 拉長」— 把 test-time compute 變成可訓練、可 scale 的維度。</p>
<h2 id="設計責任">設計責任</h2>
<p>讀 paper / benchmark 看到「pass@1 vs pass@10」「budget tokens」「thinking time」等就跟 test-time compute 相關。寫 code 場景的判讀：</p>
<ol>
<li><strong>Reasoning model 算成本翻倍</strong>：同一個 prompt、reasoning model 生 5000 token thinking + 500 token answer、傳統 model 直接生 500 token answer、推論成本差 ~10 倍</li>
<li><strong>本地跑 reasoning model 的痛點</strong>：需要長 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a> 容納 thinking trace、生成時間長</li>
<li><strong>適用任務挑選</strong>：複雜 reasoning（math、debug、long horizon planning）值得花 test-time compute；簡單任務（autocomplete、查詢）不值得</li>
<li><strong>混用策略</strong>：日常用 instruct model、困難任務切到 reasoning model、是個人 dev 常見模式</li>
</ol>
]]></content:encoded></item><item><title>Tool Use</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/tool-use/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/tool-use/</guid><description>&lt;p>Tool use 的核心概念是「LLM 不只生成文字、還能透過結構化呼叫外部工具來執行讀檔、查資料庫、發 API request、跑程式等動作」。它擴展 LLM 從「對話模型」變成「能影響真實世界的 agent」。實作上常見透過 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/function-calling/" data-link-title="Function Calling" data-link-desc="模型訓練階段建立的「呼叫工具」能力：知道何時該呼叫、傳什麼參數">function calling&lt;/a> 或 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mcp/" data-link-title="MCP（Model Context Protocol）" data-link-desc="LLM application ↔ 外部 tool server 之間的標準化協議、複用 OpenAI 相容 API 的成功模式">MCP&lt;/a> 協定。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Tool use 的典型流程：&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">1. 開發者定義 tools（每個 tool 含 name、description、parameters schema）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">2. LLM 收到 user message 跟 tools 清單
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">3. LLM 決定要呼叫哪個 tool、生成結構化 tool call（JSON）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">4. LLM client（不是模型本身）執行 tool call、得到結果
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">5. tool 結果回灌進 conversation、模型基於結果繼續生成或再呼叫&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>關鍵特性：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>模型本身不執行 tool&lt;/strong>：模型只生成 tool call JSON、實際執行由 client 或 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mcp/" data-link-title="MCP（Model Context Protocol）" data-link-desc="LLM application ↔ 外部 tool server 之間的標準化協議、複用 OpenAI 相容 API 的成功模式">MCP server&lt;/a> 完成。&lt;/li>
&lt;li>&lt;strong>權限由 OS / user / sandbox 決定&lt;/strong>：模型再「同意」執行 &lt;code>rm -rf /&lt;/code>、實際能不能跑取決於跑 tool 的 process 權限。&lt;/li>
&lt;li>&lt;strong>副作用範圍跟 tool 設計強相關&lt;/strong>：tool 寫得越通用（如 &lt;code>run_shell&lt;/code>）、攻擊面越大；tool 寫得越窄（如 &lt;code>read_workspace_file&lt;/code>）、攻擊面越小。&lt;/li>
&lt;/ol>
&lt;p>Tool use 跟 function calling、MCP 的關係：&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>Tool use（概念）&lt;/td>
 &lt;td>廣義概念、LLM 能呼叫工具&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Function calling&lt;/td>
 &lt;td>OpenAI 提出的 API 規範、用 JSON schema 定義 function&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mcp/" data-link-title="MCP（Model Context Protocol）" data-link-desc="LLM application ↔ 外部 tool server 之間的標準化協議、複用 OpenAI 相容 API 的成功模式">MCP&lt;/a>&lt;/td>
 &lt;td>Anthropic 推動的開放協議、定義 LLM client 跟 tool server 之間的通訊格式&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 tool use 後可以解釋三個現象：為什麼 LLM 「能跑 shell」其實是 client 跑、不是模型跑（職責切分）、為什麼 tool spec 設計直接影響攻擊面（spec 越鬆、injection 後果越大）、為什麼 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop&lt;/a> 比單次 tool call 危險（多步 tool use 中 injection 累積）。&lt;/p>
&lt;p>設計 tool 跟 MCP server 時、權限白名單 + 副作用可逆性 + confirm 機制是基本配置；production 場景見 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/llm-prompt-injection-in-agent/" data-link-title="LLM Agent Prompt Injection 後果治理" data-link-desc="production LLM agent 場景的 prompt injection 後果：tool spec 設計、agent loop 限制、review checkpoint、跟 incident workflow 的接合">LLM Agent Prompt Injection 後果治理&lt;/a> 跟 &lt;a href="https://tarrragon.github.io/blog/llm/06-security/tool-use-permission-model/" data-link-title="6.2 tool use 與 MCP server 的權限模型" data-link-desc="個人 dev 場景下 tool use / MCP server 的副作用權限：檔案系統 / shell / 網路存取邊界、第三方 MCP 信任、副作用的可逆性">6.2 tool use 與 MCP server 的權限模型&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Tool use 的核心概念是「LLM 不只生成文字、還能透過結構化呼叫外部工具來執行讀檔、查資料庫、發 API request、跑程式等動作」。它擴展 LLM 從「對話模型」變成「能影響真實世界的 agent」。實作上常見透過 <a href="/blog/llm/knowledge-cards/function-calling/" data-link-title="Function Calling" data-link-desc="模型訓練階段建立的「呼叫工具」能力：知道何時該呼叫、傳什麼參數">function calling</a> 或 <a href="/blog/llm/knowledge-cards/mcp/" data-link-title="MCP（Model Context Protocol）" data-link-desc="LLM application ↔ 外部 tool server 之間的標準化協議、複用 OpenAI 相容 API 的成功模式">MCP</a> 協定。</p>
<h2 id="概念位置">概念位置</h2>
<p>Tool use 的典型流程：</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">1. 開發者定義 tools（每個 tool 含 name、description、parameters schema）
</span></span><span class="line"><span class="ln">2</span><span class="cl">2. LLM 收到 user message 跟 tools 清單
</span></span><span class="line"><span class="ln">3</span><span class="cl">3. LLM 決定要呼叫哪個 tool、生成結構化 tool call（JSON）
</span></span><span class="line"><span class="ln">4</span><span class="cl">4. LLM client（不是模型本身）執行 tool call、得到結果
</span></span><span class="line"><span class="ln">5</span><span class="cl">5. tool 結果回灌進 conversation、模型基於結果繼續生成或再呼叫</span></span></code></pre></div><p>關鍵特性：</p>
<ol>
<li><strong>模型本身不執行 tool</strong>：模型只生成 tool call JSON、實際執行由 client 或 <a href="/blog/llm/knowledge-cards/mcp/" data-link-title="MCP（Model Context Protocol）" data-link-desc="LLM application ↔ 外部 tool server 之間的標準化協議、複用 OpenAI 相容 API 的成功模式">MCP server</a> 完成。</li>
<li><strong>權限由 OS / user / sandbox 決定</strong>：模型再「同意」執行 <code>rm -rf /</code>、實際能不能跑取決於跑 tool 的 process 權限。</li>
<li><strong>副作用範圍跟 tool 設計強相關</strong>：tool 寫得越通用（如 <code>run_shell</code>）、攻擊面越大；tool 寫得越窄（如 <code>read_workspace_file</code>）、攻擊面越小。</li>
</ol>
<p>Tool use 跟 function calling、MCP 的關係：</p>
<table>
  <thead>
      <tr>
          <th>層次</th>
          <th>角色</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Tool use（概念）</td>
          <td>廣義概念、LLM 能呼叫工具</td>
      </tr>
      <tr>
          <td>Function calling</td>
          <td>OpenAI 提出的 API 規範、用 JSON schema 定義 function</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/mcp/" data-link-title="MCP（Model Context Protocol）" data-link-desc="LLM application ↔ 外部 tool server 之間的標準化協議、複用 OpenAI 相容 API 的成功模式">MCP</a></td>
          <td>Anthropic 推動的開放協議、定義 LLM client 跟 tool server 之間的通訊格式</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>理解 tool use 後可以解釋三個現象：為什麼 LLM 「能跑 shell」其實是 client 跑、不是模型跑（職責切分）、為什麼 tool spec 設計直接影響攻擊面（spec 越鬆、injection 後果越大）、為什麼 <a href="/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop</a> 比單次 tool call 危險（多步 tool use 中 injection 累積）。</p>
<p>設計 tool 跟 MCP server 時、權限白名單 + 副作用可逆性 + confirm 機制是基本配置；production 場景見 <a href="/blog/backend/07-security-data-protection/llm-prompt-injection-in-agent/" data-link-title="LLM Agent Prompt Injection 後果治理" data-link-desc="production LLM agent 場景的 prompt injection 後果：tool spec 設計、agent loop 限制、review checkpoint、跟 incident workflow 的接合">LLM Agent Prompt Injection 後果治理</a> 跟 <a href="/blog/llm/06-security/tool-use-permission-model/" data-link-title="6.2 tool use 與 MCP server 的權限模型" data-link-desc="個人 dev 場景下 tool use / MCP server 的副作用權限：檔案系統 / shell / 網路存取邊界、第三方 MCP 信任、副作用的可逆性">6.2 tool use 與 MCP server 的權限模型</a>。</p>
]]></content:encoded></item><item><title>Top-K / Top-P / Min-P Sampling</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/top-p-sampling/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/top-p-sampling/</guid><description>&lt;p>Top-K、Top-P（nucleus sampling）、Min-P 的核心概念是「&lt;strong>從 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/softmax/" data-link-title="Softmax" data-link-desc="把任意實數向量正規化成「總和為 1、每個分量 ∈ [0,1]」的機率分佈">softmax&lt;/a> 出來的機率分佈中、先過濾掉低機率 token、再從剩餘候選隨機取樣&lt;/strong>」。三者是 LLM 對話 / 寫 code 場景的主流 sampling 策略、跟 greedy 對比保留隨機多樣性、跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/beam-search/" data-link-title="Beam Search" data-link-desc="同時保留 K 條候選 sequence 的 decoding 策略、機器翻譯主流、chat / coding 場景慎用">beam search&lt;/a> 對比計算成本低。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>三種策略的篩選方式：&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>&lt;strong>Top-K&lt;/strong>&lt;/td>
 &lt;td>只保留機率前 K 個 token、其餘設 0&lt;/td>
 &lt;td>固定候選數量、簡單&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Top-P&lt;/strong>&lt;/td>
 &lt;td>把 token 依機率排序、保留「累積機率達到 P」的最小集合&lt;/td>
 &lt;td>動態候選數量、適應分佈尖銳度&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Min-P&lt;/strong>&lt;/td>
 &lt;td>只保留機率 ≥ (P × max_probability) 的 token&lt;/td>
 &lt;td>相對閾值、避免低品質 token&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>範例（vocab 前 10 個 token 的機率）：&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">token: A B C D E F G H I J
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">prob: 0.45 0.30 0.12 0.05 0.03 0.02 0.01 0.01 0.005 0.005
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">Top-K=3：保留 A、B、C（前 3 個）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">Top-P=0.9：累積機率達 0.9、保留 A、B、C、D（0.45+0.30+0.12+0.05 = 0.92）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">Min-P=0.1：max=0.45、閾值=0.045、保留 A、B、C、D（≥ 0.045）&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>三者實務上常組合使用（如 &lt;code>top_k=40, top_p=0.9, temperature=0.7&lt;/code>）、各自處理不同形狀的分佈。&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>分佈非常尖（模型很確定）&lt;/td>
 &lt;td>Top-P / Min-P 動態縮小、Top-K 可能太大&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>分佈平（模型不確定）&lt;/td>
 &lt;td>Top-K 限制最大候選、避免取到極低品質 token&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>寫 code / 嚴謹任務&lt;/td>
 &lt;td>低 temperature (0.2 ~ 0.5) + 較緊的 Top-P (0.8 ~ 0.9)&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>創意 / 多樣寫作&lt;/td>
 &lt;td>高 temperature (0.7 ~ 1.0) + 寬鬆的 Top-P (0.95+)&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 inference config / Continue.dev 設定看到 &lt;code>top_k&lt;/code>、&lt;code>top_p&lt;/code>、&lt;code>min_p&lt;/code>、&lt;code>temperature&lt;/code> 就是這組參數。寫 code 場景的判讀：嚴謹任務（code generation、structured output）用低 temperature + 緊 Top-P 取「最可能對的少數 token」；創意 / 對話用高 temperature + 寬 Top-P 取多樣性。Min-P 是 2023 後流行的新策略、實務上比 Top-P 更穩、避免「分佈很尖時 Top-P 仍納入長尾低品質 token」的問題。&lt;/p></description><content:encoded><![CDATA[<p>Top-K、Top-P（nucleus sampling）、Min-P 的核心概念是「<strong>從 <a href="/blog/llm/knowledge-cards/softmax/" data-link-title="Softmax" data-link-desc="把任意實數向量正規化成「總和為 1、每個分量 ∈ [0,1]」的機率分佈">softmax</a> 出來的機率分佈中、先過濾掉低機率 token、再從剩餘候選隨機取樣</strong>」。三者是 LLM 對話 / 寫 code 場景的主流 sampling 策略、跟 greedy 對比保留隨機多樣性、跟 <a href="/blog/llm/knowledge-cards/beam-search/" data-link-title="Beam Search" data-link-desc="同時保留 K 條候選 sequence 的 decoding 策略、機器翻譯主流、chat / coding 場景慎用">beam search</a> 對比計算成本低。</p>
<h2 id="概念位置">概念位置</h2>
<p>三種策略的篩選方式：</p>
<table>
  <thead>
      <tr>
          <th>策略</th>
          <th>機制</th>
          <th>直覺</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Top-K</strong></td>
          <td>只保留機率前 K 個 token、其餘設 0</td>
          <td>固定候選數量、簡單</td>
      </tr>
      <tr>
          <td><strong>Top-P</strong></td>
          <td>把 token 依機率排序、保留「累積機率達到 P」的最小集合</td>
          <td>動態候選數量、適應分佈尖銳度</td>
      </tr>
      <tr>
          <td><strong>Min-P</strong></td>
          <td>只保留機率 ≥ (P × max_probability) 的 token</td>
          <td>相對閾值、避免低品質 token</td>
      </tr>
  </tbody>
</table>
<p>範例（vocab 前 10 個 token 的機率）：</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">token:     A     B     C     D     E     F     G     H     I     J
</span></span><span class="line"><span class="ln">2</span><span class="cl">prob:    0.45  0.30  0.12  0.05  0.03  0.02  0.01  0.01  0.005 0.005
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">Top-K=3：保留 A、B、C（前 3 個）
</span></span><span class="line"><span class="ln">5</span><span class="cl">Top-P=0.9：累積機率達 0.9、保留 A、B、C、D（0.45+0.30+0.12+0.05 = 0.92）
</span></span><span class="line"><span class="ln">6</span><span class="cl">Min-P=0.1：max=0.45、閾值=0.045、保留 A、B、C、D（≥ 0.045）</span></span></code></pre></div><p>三者實務上常組合使用（如 <code>top_k=40, top_p=0.9, temperature=0.7</code>）、各自處理不同形狀的分佈。</p>
<table>
  <thead>
      <tr>
          <th>參數情境</th>
          <th>適合策略</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>分佈非常尖（模型很確定）</td>
          <td>Top-P / Min-P 動態縮小、Top-K 可能太大</td>
      </tr>
      <tr>
          <td>分佈平（模型不確定）</td>
          <td>Top-K 限制最大候選、避免取到極低品質 token</td>
      </tr>
      <tr>
          <td>寫 code / 嚴謹任務</td>
          <td>低 temperature (0.2 ~ 0.5) + 較緊的 Top-P (0.8 ~ 0.9)</td>
      </tr>
      <tr>
          <td>創意 / 多樣寫作</td>
          <td>高 temperature (0.7 ~ 1.0) + 寬鬆的 Top-P (0.95+)</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 inference config / Continue.dev 設定看到 <code>top_k</code>、<code>top_p</code>、<code>min_p</code>、<code>temperature</code> 就是這組參數。寫 code 場景的判讀：嚴謹任務（code generation、structured output）用低 temperature + 緊 Top-P 取「最可能對的少數 token」；創意 / 對話用高 temperature + 寬 Top-P 取多樣性。Min-P 是 2023 後流行的新策略、實務上比 Top-P 更穩、避免「分佈很尖時 Top-P 仍納入長尾低品質 token」的問題。</p>
]]></content:encoded></item><item><title>Vector Database</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/vector-database/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/vector-database/</guid><description>&lt;p>Vector Database 的核心概念是「&lt;strong>為高維向量設計的儲存系統 + 近似最近鄰 (Approximate Nearest Neighbor, ANN) 檢索引擎&lt;/strong>」。是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> 系統從 prototype 跨到 production 的關鍵元件——當 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding&lt;/a> index 大到記憶體裝不下、或並發 query 量超過單機處理能力、就要從 pickle / in-memory 升級到 vector DB。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Vector DB 跟傳統 SQL / NoSQL database 並列、但專精「向量相似度搜尋」這個操作。它不取代傳統 DB——通常 LLM 應用是兩者並用：傳統 DB 存結構化資料（user / metadata）、vector DB 存 embedding + chunk text。實作上、近期主流是「向量加進去現有 DB」（如 Postgres 的 pgvector extension）或「專用服務」（如 Pinecone、Weaviate、Qdrant）。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>主流選擇分類：&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>Hosted SaaS&lt;/td>
 &lt;td>Pinecone、Weaviate Cloud、Qdrant Cloud&lt;/td>
 &lt;td>不想 maintain、流量大&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Self-host service&lt;/td>
 &lt;td>Weaviate、Qdrant、Milvus&lt;/td>
 &lt;td>內部部署、控制 cost&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Embedded library&lt;/td>
 &lt;td>FAISS、HNSWLib、Annoy&lt;/td>
 &lt;td>嵌進應用、單機規模&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DB extension&lt;/td>
 &lt;td>pgvector、SQLite + vec&lt;/td>
 &lt;td>已有 SQL DB、加 vector 能力&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵 ANN 演算法：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>HNSW&lt;/strong>（Hierarchical Navigable Small World）：主流、sublinear 查詢、犧牲少許精度&lt;/li>
&lt;li>&lt;strong>IVF&lt;/strong>（Inverted File Index）：分組索引、適合超大規模&lt;/li>
&lt;li>&lt;strong>Flat&lt;/strong>（exhaustive search）：精確但 O(n)、小資料集 OK&lt;/li>
&lt;/ul>
&lt;p>scale 對照（基於 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/production-resource-planning/" data-link-title="4.9 Production 部署的資源評估原理" data-link-desc="從本地單 user 到 production multi-tenant：concurrent users、cost model、observability、SLA、capacity planning 的設計取捨">4.9 production&lt;/a> 跟 &lt;a href="https://tarrragon.github.io/blog/llm/01-local-llm-services/hands-on/rag-mcp-resources/" data-link-title="Hands-on：RAG / MCP 的資源 footprint" data-link-desc="RAG ingest / query / MCP server 三階段的 RAM / 磁碟 / process 實測、多模型並存的 RAM 衝突、本地 LLM 跑 RAG 跟單純 chat 的差異">RAG/MCP resources&lt;/a> 章節）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Corpus 規模&lt;/th>
 &lt;th>適合&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&amp;lt; 10K chunks&lt;/td>
 &lt;td>Python pickle / in-memory list（&lt;a href="https://tarrragon.github.io/blog/llm/01-local-llm-services/hands-on/rag-demo/" data-link-title="Hands-on：用 blog content 當 corpus 跑 RAG" data-link-desc="200 行 Python：embedding &amp;#43; cosine retrieval &amp;#43; Ollama chat、validating 4.0 RAG 原理">本 blog demo&lt;/a>）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>10K-100K&lt;/td>
 &lt;td>FAISS / embedded library&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>100K-10M&lt;/td>
 &lt;td>Self-host vector DB&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&amp;gt; 10M&lt;/td>
 &lt;td>Hosted SaaS 或分散式 cluster&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>選 vector DB 之前回答四個問題：&lt;/p></description><content:encoded><![CDATA[<p>Vector Database 的核心概念是「<strong>為高維向量設計的儲存系統 + 近似最近鄰 (Approximate Nearest Neighbor, ANN) 檢索引擎</strong>」。是 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> 系統從 prototype 跨到 production 的關鍵元件——當 <a href="/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding</a> index 大到記憶體裝不下、或並發 query 量超過單機處理能力、就要從 pickle / in-memory 升級到 vector DB。</p>
<h2 id="概念位置">概念位置</h2>
<p>Vector DB 跟傳統 SQL / NoSQL database 並列、但專精「向量相似度搜尋」這個操作。它不取代傳統 DB——通常 LLM 應用是兩者並用：傳統 DB 存結構化資料（user / metadata）、vector DB 存 embedding + chunk text。實作上、近期主流是「向量加進去現有 DB」（如 Postgres 的 pgvector extension）或「專用服務」（如 Pinecone、Weaviate、Qdrant）。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>主流選擇分類：</p>
<table>
  <thead>
      <tr>
          <th>類別</th>
          <th>例子</th>
          <th>適合</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Hosted SaaS</td>
          <td>Pinecone、Weaviate Cloud、Qdrant Cloud</td>
          <td>不想 maintain、流量大</td>
      </tr>
      <tr>
          <td>Self-host service</td>
          <td>Weaviate、Qdrant、Milvus</td>
          <td>內部部署、控制 cost</td>
      </tr>
      <tr>
          <td>Embedded library</td>
          <td>FAISS、HNSWLib、Annoy</td>
          <td>嵌進應用、單機規模</td>
      </tr>
      <tr>
          <td>DB extension</td>
          <td>pgvector、SQLite + vec</td>
          <td>已有 SQL DB、加 vector 能力</td>
      </tr>
  </tbody>
</table>
<p>關鍵 ANN 演算法：</p>
<ul>
<li><strong>HNSW</strong>（Hierarchical Navigable Small World）：主流、sublinear 查詢、犧牲少許精度</li>
<li><strong>IVF</strong>（Inverted File Index）：分組索引、適合超大規模</li>
<li><strong>Flat</strong>（exhaustive search）：精確但 O(n)、小資料集 OK</li>
</ul>
<p>scale 對照（基於 <a href="/blog/llm/04-applications/production-resource-planning/" data-link-title="4.9 Production 部署的資源評估原理" data-link-desc="從本地單 user 到 production multi-tenant：concurrent users、cost model、observability、SLA、capacity planning 的設計取捨">4.9 production</a> 跟 <a href="/blog/llm/01-local-llm-services/hands-on/rag-mcp-resources/" data-link-title="Hands-on：RAG / MCP 的資源 footprint" data-link-desc="RAG ingest / query / MCP server 三階段的 RAM / 磁碟 / process 實測、多模型並存的 RAM 衝突、本地 LLM 跑 RAG 跟單純 chat 的差異">RAG/MCP resources</a> 章節）：</p>
<table>
  <thead>
      <tr>
          <th>Corpus 規模</th>
          <th>適合</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>&lt; 10K chunks</td>
          <td>Python pickle / in-memory list（<a href="/blog/llm/01-local-llm-services/hands-on/rag-demo/" data-link-title="Hands-on：用 blog content 當 corpus 跑 RAG" data-link-desc="200 行 Python：embedding &#43; cosine retrieval &#43; Ollama chat、validating 4.0 RAG 原理">本 blog demo</a>）</td>
      </tr>
      <tr>
          <td>10K-100K</td>
          <td>FAISS / embedded library</td>
      </tr>
      <tr>
          <td>100K-10M</td>
          <td>Self-host vector DB</td>
      </tr>
      <tr>
          <td>&gt; 10M</td>
          <td>Hosted SaaS 或分散式 cluster</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>選 vector DB 之前回答四個問題：</p>
<ol>
<li><strong>Corpus 規模</strong>：決定 hosted vs self-host 取捨。</li>
<li><strong>Update 頻率</strong>：每天一次（適合 batch rebuild）vs 即時（要 incremental update 支援）。</li>
<li><strong>Latency 目標</strong>：&lt; 50ms 要 in-memory HNSW、可接受 200ms 用 disk-based。</li>
<li><strong>Hybrid search 需求</strong>：純向量 vs 向量 + filter（如「embedding 相似 + tag = code」），影響 schema 設計。</li>
</ol>
<p>衍生產物管理上、vector DB 屬於 <a href="/blog/llm/04-applications/artifact-management/" data-link-title="4.10 衍生產物管理原理：什麼進 git、什麼不該" data-link-desc="LLM 應用的 source / derived / external 三類產物對應 git / build cache / registry、與 production 部署的 reproducibility / cost / share 取捨">external 類別</a>——index content 不進 git、用 manifest（如 schema definition + ingest script + version tag）描述。Build pipeline 從 source corpus 自動 rebuild。</p>
<p>不適合 vector DB 的情境：knowledge 高度結構化（直接 SQL）、corpus 小（pickle 就好）、單次 retrieval（off-line 跑、不開 server）。</p>
<p>Storage 升級判讀（什麼規模該從 in-memory 升級到 vector DB）、index 生命週期、dependency 約束的工程分析見 <a href="/blog/llm/04-applications/vector-storage-engineering/" data-link-title="4.22 RAG storage 工程：從 pickle 到 vector database 的選型判讀" data-link-desc="RAG storage backend 選型：規模到哪個階段該從 in-memory 升級到 vector DB、dependency chain 如何收窄選項">4.22 RAG storage 工程</a>。</p>
]]></content:encoded></item><item><title>Vector Norm</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/vector-norm/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/vector-norm/</guid><description>&lt;p>Vector norm（向量範數）的核心概念是「&lt;strong>衡量向量「大小」的純量值&lt;/strong>」。最常用的 L2 norm（歐式長度）= 把每個分量平方加總再開根號；但 L1、L∞ 等其他 norm 也在不同場景出現。Norm 在 LLM 中支撐 cosine similarity、layer normalization、gradient clipping 等核心機制。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>主流 norm 的定義與用途：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Norm&lt;/th>
 &lt;th>定義&lt;/th>
 &lt;th>LLM 中的用途&lt;/th>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>L1（Manhattan）&lt;/td>
 &lt;td>`sum(&lt;/td>
 &lt;td>v_i&lt;/td>
 &lt;td>)`&lt;/td>
 &lt;td>L1 regularization、稀疏化&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>L2（Euclidean）&lt;/strong>&lt;/td>
 &lt;td>&lt;code>sqrt(sum(v_i²))&lt;/code>&lt;/td>
 &lt;td>預設「向量長度」、cosine similarity 的分母&lt;/td>
 &lt;td>&lt;/td>
 &lt;td>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>L∞（max）&lt;/td>
 &lt;td>`max(&lt;/td>
 &lt;td>v_i&lt;/td>
 &lt;td>)`&lt;/td>
 &lt;td>Gradient clipping by max value、某些 attention scaling&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>L2 norm 在 LLM 中的關鍵應用：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Cosine similarity&lt;/strong>：&lt;code>cos(a, b) = (a · b) / (||a||₂ × ||b||₂)&lt;/code>、衡量兩個向量的方向相似度、是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG&lt;/a> / semantic search 的核心指標。&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">Embedding model&lt;/a> 正規化&lt;/strong>：通常把 embedding 正規化到 L2 norm = 1、之後 cosine similarity 退化成單純內積（&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/dot-product/" data-link-title="Dot Product" data-link-desc="兩個向量對應位置相乘再加總、attention score 跟相似度判讀的基礎">dot product&lt;/a>）、計算更快。&lt;/li>
&lt;li>&lt;strong>Gradient clipping&lt;/strong>：訓練時若 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/gradient/" data-link-title="Gradient" data-link-desc="loss function 對權重的偏微分向量、指出「該往哪個方向調權重才能讓 loss 下降最快」">gradient&lt;/a> 的 L2 norm 超過閾值（如 1.0）、整體縮放回去、避免 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/gradient-explosion-vanishing/" data-link-title="Gradient Explosion / Vanishing" data-link-desc="深層網路訓練中 gradient 透過 chain rule 累乘、容易爆炸或衰減到 0 的兩種失敗模式">explosion&lt;/a>。&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/layer-normalization/" data-link-title="Layer Normalization" data-link-desc="在每個 token 的 hidden state 上做正規化（減 mean、除 std）、穩定深層網路訓練">Layer normalization&lt;/a>&lt;/strong>：RMSNorm 用 L2 norm（root mean square）做正規化。&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 RAG / embedding 教學看到「normalize embeddings」「cosine similarity」就是 L2 相關運算。寫 code 場景的判讀：用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/vector-database/" data-link-title="Vector Database" data-link-desc="為高維向量 (embedding) 設計的儲存 &amp;#43; 近似最近鄰 (ANN) 檢索系統：RAG 從 prototype 跨到 production 的關鍵元件">vector database&lt;/a> 時、若 embedding 已 L2-normalized、距離指標選 dot product 比 cosine 快（結果相同）；訓練 / fine-tune 自己 model 時、&lt;code>gradient_clip: 1.0&lt;/code> 是常見預設、防止 gradient 偶發爆炸。&lt;/p></description><content:encoded><![CDATA[<p>Vector norm（向量範數）的核心概念是「<strong>衡量向量「大小」的純量值</strong>」。最常用的 L2 norm（歐式長度）= 把每個分量平方加總再開根號；但 L1、L∞ 等其他 norm 也在不同場景出現。Norm 在 LLM 中支撐 cosine similarity、layer normalization、gradient clipping 等核心機制。</p>
<h2 id="概念位置">概念位置</h2>
<p>主流 norm 的定義與用途：</p>
<table>
  <thead>
      <tr>
          <th>Norm</th>
          <th>定義</th>
          <th>LLM 中的用途</th>
          <th></th>
          <th></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>L1（Manhattan）</td>
          <td>`sum(</td>
          <td>v_i</td>
          <td>)`</td>
          <td>L1 regularization、稀疏化</td>
      </tr>
      <tr>
          <td><strong>L2（Euclidean）</strong></td>
          <td><code>sqrt(sum(v_i²))</code></td>
          <td>預設「向量長度」、cosine similarity 的分母</td>
          <td></td>
          <td></td>
      </tr>
      <tr>
          <td>L∞（max）</td>
          <td>`max(</td>
          <td>v_i</td>
          <td>)`</td>
          <td>Gradient clipping by max value、某些 attention scaling</td>
      </tr>
  </tbody>
</table>
<p>L2 norm 在 LLM 中的關鍵應用：</p>
<ol>
<li><strong>Cosine similarity</strong>：<code>cos(a, b) = (a · b) / (||a||₂ × ||b||₂)</code>、衡量兩個向量的方向相似度、是 <a href="/blog/llm/knowledge-cards/rag/" data-link-title="RAG" data-link-desc="Retrieval-Augmented Generation：動態外掛知識給 LLM、繞開模型參數記憶的靜態限制">RAG</a> / semantic search 的核心指標。</li>
<li><strong><a href="/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">Embedding model</a> 正規化</strong>：通常把 embedding 正規化到 L2 norm = 1、之後 cosine similarity 退化成單純內積（<a href="/blog/llm/knowledge-cards/dot-product/" data-link-title="Dot Product" data-link-desc="兩個向量對應位置相乘再加總、attention score 跟相似度判讀的基礎">dot product</a>）、計算更快。</li>
<li><strong>Gradient clipping</strong>：訓練時若 <a href="/blog/llm/knowledge-cards/gradient/" data-link-title="Gradient" data-link-desc="loss function 對權重的偏微分向量、指出「該往哪個方向調權重才能讓 loss 下降最快」">gradient</a> 的 L2 norm 超過閾值（如 1.0）、整體縮放回去、避免 <a href="/blog/llm/knowledge-cards/gradient-explosion-vanishing/" data-link-title="Gradient Explosion / Vanishing" data-link-desc="深層網路訓練中 gradient 透過 chain rule 累乘、容易爆炸或衰減到 0 的兩種失敗模式">explosion</a>。</li>
<li><strong><a href="/blog/llm/knowledge-cards/layer-normalization/" data-link-title="Layer Normalization" data-link-desc="在每個 token 的 hidden state 上做正規化（減 mean、除 std）、穩定深層網路訓練">Layer normalization</a></strong>：RMSNorm 用 L2 norm（root mean square）做正規化。</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 RAG / embedding 教學看到「normalize embeddings」「cosine similarity」就是 L2 相關運算。寫 code 場景的判讀：用 <a href="/blog/llm/knowledge-cards/vector-database/" data-link-title="Vector Database" data-link-desc="為高維向量 (embedding) 設計的儲存 &#43; 近似最近鄰 (ANN) 檢索系統：RAG 從 prototype 跨到 production 的關鍵元件">vector database</a> 時、若 embedding 已 L2-normalized、距離指標選 dot product 比 cosine 快（結果相同）；訓練 / fine-tune 自己 model 時、<code>gradient_clip: 1.0</code> 是常見預設、防止 gradient 偶發爆炸。</p>
]]></content:encoded></item><item><title>Vision Encoder</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/vision-encoder/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/vision-encoder/</guid><description>&lt;p>Vision encoder（視覺編碼器）的核心概念是「&lt;strong>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/vlm/" data-link-title="VLM（Vision-Language Model）" data-link-desc="同時吃圖片 &amp;#43; 文字輸入、產生文字輸出的 LLM 變體、coding 工作流中處理截圖 / 設計稿 / UI debug 的基底">VLM&lt;/a> 內部把圖片轉成向量序列的模組&lt;/strong>」。主流做法是「把圖片切成 patch、每個 patch 過 ViT（Vision Transformer）變一個向量」、再進入 LLM 的 Transformer 層。Vision encoder 通常用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/clip/" data-link-title="CLIP" data-link-desc="OpenAI 2021 提出的 contrastive image-text pretraining、現代 VLM 的 vision encoder 大多衍生自它">CLIP&lt;/a> 預訓練的權重起始、再跟 LLM 一起 fine-tune。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Vision encoder 在 VLM 中的位置：&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">Input image（如 1024×1024 RGB）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓ 切 patch（如 14×14 patch、每張圖 ~5000 個 patch）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> ↓ Vision encoder（ViT 或 CLIP image encoder）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">Image feature vectors（每個 patch 對應一個 768/1024 維向量）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> ↓ Projection layer（vision dim → LLM hidden dim）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">[Image tokens](/llm/knowledge-cards/image-token/)（變成 LLM 可吃的「視覺 token」）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl">跟 text token 混合 → Transformer → output token&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>主流 vision encoder 設計：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>設計&lt;/th>
 &lt;th>機制&lt;/th>
 &lt;th>代表 VLM&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>CLIP ViT-L/14（或變體）&lt;/td>
 &lt;td>OpenAI CLIP 的 image encoder 直接用&lt;/td>
 &lt;td>LLaVA-1.5、Qwen2-VL、Pixtral&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>SigLIP&lt;/td>
 &lt;td>Google 的 sigmoid-loss CLIP 變體、訓得更穩&lt;/td>
 &lt;td>Gemma 3 Vision、Idefics2&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>自訓 / 多解析度 ViT&lt;/td>
 &lt;td>從頭訓、支援動態解析度（不固定 224×224）&lt;/td>
 &lt;td>Qwen2.5-VL、GPT-4V&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Native multimodal（單一網路）&lt;/td>
 &lt;td>圖跟文字共用 Transformer、不分開 encoder&lt;/td>
 &lt;td>Chameleon（Meta 研究）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Vision encoder 的關鍵設計取捨：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>解析度&lt;/strong>：固定（224×224 / 336×336）vs 動態（依輸入圖大小）&lt;/li>
&lt;li>&lt;strong>參數量&lt;/strong>：vision encoder 0.3B-1B 是主流；太小辨識能力差、太大拖累整體推論速度&lt;/li>
&lt;li>&lt;strong>Pretrain 來源&lt;/strong>：用 CLIP / SigLIP 預訓練的權重起始、加上 multimodal fine-tune；少數從頭訓&lt;/li>
&lt;li>&lt;strong>跟 LLM 結合方式&lt;/strong>：見 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/multimodal-fusion/" data-link-title="Multimodal Fusion" data-link-desc="VLM 把 vision encoder 跟 LLM 結合的方式：early fusion / cross-attention / native multimodal 三條路線">multimodal fusion&lt;/a> 卡&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 VLM model card 看到「vision tower」「ViT backbone」「image encoder」就是這部分。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>解析度影響細節辨識&lt;/strong>：低解析度（224）對「截圖中的小字 / 細邊框」可能模糊、看不清；高解析度（1024+）能看清楚但 token 用量大&lt;/li>
&lt;li>&lt;strong>Token 用量估算&lt;/strong>：一張 1024×1024 圖經過 vision encoder 後、產出 ~500-2500 image tokens（依設計）、相當於一段中等長度的文字 prompt&lt;/li>
&lt;li>&lt;strong>動態解析度模型更實用&lt;/strong>：Qwen2.5-VL / GPT-4V 等支援動態解析度、不會把高清截圖縮成 224 失去細節&lt;/li>
&lt;li>&lt;strong>Vision encoder 不能單獨 fine-tune&lt;/strong>：通常跟 LLM 一起訓、單獨換 vision encoder 會破壞 alignment&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Vision encoder（視覺編碼器）的核心概念是「<strong><a href="/blog/llm/knowledge-cards/vlm/" data-link-title="VLM（Vision-Language Model）" data-link-desc="同時吃圖片 &#43; 文字輸入、產生文字輸出的 LLM 變體、coding 工作流中處理截圖 / 設計稿 / UI debug 的基底">VLM</a> 內部把圖片轉成向量序列的模組</strong>」。主流做法是「把圖片切成 patch、每個 patch 過 ViT（Vision Transformer）變一個向量」、再進入 LLM 的 Transformer 層。Vision encoder 通常用 <a href="/blog/llm/knowledge-cards/clip/" data-link-title="CLIP" data-link-desc="OpenAI 2021 提出的 contrastive image-text pretraining、現代 VLM 的 vision encoder 大多衍生自它">CLIP</a> 預訓練的權重起始、再跟 LLM 一起 fine-tune。</p>
<h2 id="概念位置">概念位置</h2>
<p>Vision encoder 在 VLM 中的位置：</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">Input image（如 1024×1024 RGB）
</span></span><span class="line"><span class="ln">2</span><span class="cl">   ↓ 切 patch（如 14×14 patch、每張圖 ~5000 個 patch）
</span></span><span class="line"><span class="ln">3</span><span class="cl">   ↓ Vision encoder（ViT 或 CLIP image encoder）
</span></span><span class="line"><span class="ln">4</span><span class="cl">Image feature vectors（每個 patch 對應一個 768/1024 維向量）
</span></span><span class="line"><span class="ln">5</span><span class="cl">   ↓ Projection layer（vision dim → LLM hidden dim）
</span></span><span class="line"><span class="ln">6</span><span class="cl">[Image tokens](/llm/knowledge-cards/image-token/)（變成 LLM 可吃的「視覺 token」）
</span></span><span class="line"><span class="ln">7</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln">8</span><span class="cl">跟 text token 混合 → Transformer → output token</span></span></code></pre></div><p>主流 vision encoder 設計：</p>
<table>
  <thead>
      <tr>
          <th>設計</th>
          <th>機制</th>
          <th>代表 VLM</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>CLIP ViT-L/14（或變體）</td>
          <td>OpenAI CLIP 的 image encoder 直接用</td>
          <td>LLaVA-1.5、Qwen2-VL、Pixtral</td>
      </tr>
      <tr>
          <td>SigLIP</td>
          <td>Google 的 sigmoid-loss CLIP 變體、訓得更穩</td>
          <td>Gemma 3 Vision、Idefics2</td>
      </tr>
      <tr>
          <td>自訓 / 多解析度 ViT</td>
          <td>從頭訓、支援動態解析度（不固定 224×224）</td>
          <td>Qwen2.5-VL、GPT-4V</td>
      </tr>
      <tr>
          <td>Native multimodal（單一網路）</td>
          <td>圖跟文字共用 Transformer、不分開 encoder</td>
          <td>Chameleon（Meta 研究）</td>
      </tr>
  </tbody>
</table>
<p>Vision encoder 的關鍵設計取捨：</p>
<ol>
<li><strong>解析度</strong>：固定（224×224 / 336×336）vs 動態（依輸入圖大小）</li>
<li><strong>參數量</strong>：vision encoder 0.3B-1B 是主流；太小辨識能力差、太大拖累整體推論速度</li>
<li><strong>Pretrain 來源</strong>：用 CLIP / SigLIP 預訓練的權重起始、加上 multimodal fine-tune；少數從頭訓</li>
<li><strong>跟 LLM 結合方式</strong>：見 <a href="/blog/llm/knowledge-cards/multimodal-fusion/" data-link-title="Multimodal Fusion" data-link-desc="VLM 把 vision encoder 跟 LLM 結合的方式：early fusion / cross-attention / native multimodal 三條路線">multimodal fusion</a> 卡</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 VLM model card 看到「vision tower」「ViT backbone」「image encoder」就是這部分。寫 code 場景的判讀：</p>
<ol>
<li><strong>解析度影響細節辨識</strong>：低解析度（224）對「截圖中的小字 / 細邊框」可能模糊、看不清；高解析度（1024+）能看清楚但 token 用量大</li>
<li><strong>Token 用量估算</strong>：一張 1024×1024 圖經過 vision encoder 後、產出 ~500-2500 image tokens（依設計）、相當於一段中等長度的文字 prompt</li>
<li><strong>動態解析度模型更實用</strong>：Qwen2.5-VL / GPT-4V 等支援動態解析度、不會把高清截圖縮成 224 失去細節</li>
<li><strong>Vision encoder 不能單獨 fine-tune</strong>：通常跟 LLM 一起訓、單獨換 vision encoder 會破壞 alignment</li>
</ol>
]]></content:encoded></item><item><title>VLM（Vision-Language Model）</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/vlm/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/vlm/</guid><description>&lt;p>VLM（Vision-Language Model、視覺語言模型）的核心概念是「&lt;strong>同時接受圖片 + 文字輸入、產生文字輸出的 LLM 變體&lt;/strong>」。內部結構是「&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/vision-encoder/" data-link-title="Vision Encoder" data-link-desc="VLM 內部負責把圖片轉成可進 Transformer 的向量序列的模組、ViT / CLIP encoder 為主流">vision encoder&lt;/a> 把圖片轉成 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/image-token/" data-link-title="Image Token" data-link-desc="VLM 把圖片轉成「對 Transformer 而言跟 text token 同質」的向量、計入 context window 預算">image token&lt;/a>、跟文字 token 一起進 Transformer」。寫 code 場景的 VLM 用途：看截圖 debug、看 mockup 寫前端 code、看 architecture 白板照片寫文件。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>VLM 跟純文字 LLM 的差異：&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">純文字 LLM：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> text → tokenizer → token IDs → embedding → Transformer → output token
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">VLM：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> text → tokenizer → text token IDs ─┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> ├→ 統一 token sequence → Transformer → output token
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> image → vision encoder → image tokens ─┘&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>主流 VLM family（2026/5）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Family&lt;/th>
 &lt;th>商業 / 開源&lt;/th>
 &lt;th>本地可跑&lt;/th>
 &lt;th>Coding 場景強項&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>GPT-4o / GPT-5 vision&lt;/td>
 &lt;td>商業 API&lt;/td>
 &lt;td>不可&lt;/td>
 &lt;td>截圖理解、OCR、UI 推理&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Claude 3.7 / 4 Sonnet vision&lt;/td>
 &lt;td>商業 API&lt;/td>
 &lt;td>不可&lt;/td>
 &lt;td>截圖 debug、code from mockup&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Gemini 2.5 Pro vision&lt;/td>
 &lt;td>商業 API&lt;/td>
 &lt;td>不可&lt;/td>
 &lt;td>長視訊 / 多張圖&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Qwen2.5-VL / Qwen3-VL&lt;/strong>&lt;/td>
 &lt;td>開源&lt;/td>
 &lt;td>7B / 32B / 72B 可本地&lt;/td>
 &lt;td>中英 OCR、UI 元素辨識&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Llama 3.2 Vision&lt;/strong>&lt;/td>
 &lt;td>開源&lt;/td>
 &lt;td>11B / 90B&lt;/td>
 &lt;td>通用 vision、英文場景&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Gemma 3 Vision&lt;/strong>&lt;/td>
 &lt;td>開源&lt;/td>
 &lt;td>4B / 12B / 27B&lt;/td>
 &lt;td>多語、輕量本地&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LLaVA / InternVL / Pixtral&lt;/td>
 &lt;td>開源&lt;/td>
 &lt;td>7B-34B&lt;/td>
 &lt;td>研究 / 特定 use case&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：主流 VLM family、本地可跑狀態、coding 場景強項在 2026/5 是估計、依模型更新跟推論伺服器支援度持續變化、引用前以對應 model card 跟 Hugging Face leaderboard 為準。&lt;/p>&lt;/blockquote>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 model card 看到「vision」「VL」「multimodal」「-VL」「visual」就是 VLM。寫 code 場景的判讀：&lt;/p></description><content:encoded><![CDATA[<p>VLM（Vision-Language Model、視覺語言模型）的核心概念是「<strong>同時接受圖片 + 文字輸入、產生文字輸出的 LLM 變體</strong>」。內部結構是「<a href="/blog/llm/knowledge-cards/vision-encoder/" data-link-title="Vision Encoder" data-link-desc="VLM 內部負責把圖片轉成可進 Transformer 的向量序列的模組、ViT / CLIP encoder 為主流">vision encoder</a> 把圖片轉成 <a href="/blog/llm/knowledge-cards/image-token/" data-link-title="Image Token" data-link-desc="VLM 把圖片轉成「對 Transformer 而言跟 text token 同質」的向量、計入 context window 預算">image token</a>、跟文字 token 一起進 Transformer」。寫 code 場景的 VLM 用途：看截圖 debug、看 mockup 寫前端 code、看 architecture 白板照片寫文件。</p>
<h2 id="概念位置">概念位置</h2>
<p>VLM 跟純文字 LLM 的差異：</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">純文字 LLM：
</span></span><span class="line"><span class="ln">2</span><span class="cl">  text → tokenizer → token IDs → embedding → Transformer → output token
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">VLM：
</span></span><span class="line"><span class="ln">5</span><span class="cl">  text → tokenizer → text token IDs ─┐
</span></span><span class="line"><span class="ln">6</span><span class="cl">                                     ├→ 統一 token sequence → Transformer → output token
</span></span><span class="line"><span class="ln">7</span><span class="cl">  image → vision encoder → image tokens ─┘</span></span></code></pre></div><p>主流 VLM family（2026/5）：</p>
<table>
  <thead>
      <tr>
          <th>Family</th>
          <th>商業 / 開源</th>
          <th>本地可跑</th>
          <th>Coding 場景強項</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>GPT-4o / GPT-5 vision</td>
          <td>商業 API</td>
          <td>不可</td>
          <td>截圖理解、OCR、UI 推理</td>
      </tr>
      <tr>
          <td>Claude 3.7 / 4 Sonnet vision</td>
          <td>商業 API</td>
          <td>不可</td>
          <td>截圖 debug、code from mockup</td>
      </tr>
      <tr>
          <td>Gemini 2.5 Pro vision</td>
          <td>商業 API</td>
          <td>不可</td>
          <td>長視訊 / 多張圖</td>
      </tr>
      <tr>
          <td><strong>Qwen2.5-VL / Qwen3-VL</strong></td>
          <td>開源</td>
          <td>7B / 32B / 72B 可本地</td>
          <td>中英 OCR、UI 元素辨識</td>
      </tr>
      <tr>
          <td><strong>Llama 3.2 Vision</strong></td>
          <td>開源</td>
          <td>11B / 90B</td>
          <td>通用 vision、英文場景</td>
      </tr>
      <tr>
          <td><strong>Gemma 3 Vision</strong></td>
          <td>開源</td>
          <td>4B / 12B / 27B</td>
          <td>多語、輕量本地</td>
      </tr>
      <tr>
          <td>LLaVA / InternVL / Pixtral</td>
          <td>開源</td>
          <td>7B-34B</td>
          <td>研究 / 特定 use case</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p><strong>事實查核註</strong>：主流 VLM family、本地可跑狀態、coding 場景強項在 2026/5 是估計、依模型更新跟推論伺服器支援度持續變化、引用前以對應 model card 跟 Hugging Face leaderboard 為準。</p></blockquote>
<h2 id="設計責任">設計責任</h2>
<p>讀 model card 看到「vision」「VL」「multimodal」「-VL」「visual」就是 VLM。寫 code 場景的判讀：</p>
<ol>
<li><strong>任務適合用 vision 才用</strong>：純文字描述夠清楚就別塞圖、image token 多、context 跟推論成本上升</li>
<li><strong>本地跑 VLM 比純文字 LLM 吃資源</strong>：vision encoder 通常 0.3-1B 參數、image 處理階段算力需求大、TTFT 變長</li>
<li><strong>OCR-heavy 任務不一定要 VLM</strong>：純 OCR（識別截圖中文字）用專門 OCR 工具（Tesseract / PaddleOCR）可能更穩、VLM 強項在「理解圖 + 推理」</li>
<li><strong>影片不是免費</strong>：「VLM 看影片」本質是抽 frames 變多張圖、token 用量爆炸、效益看任務</li>
</ol>
]]></content:encoded></item><item><title>Vocabulary Size</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/vocabulary-size/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/vocabulary-size/</guid><description>&lt;p>Vocabulary size（詞彙表大小）的核心概念是「&lt;strong>tokenizer 詞彙表中 token 的總數&lt;/strong>」。是模型訓練時就決定的 hyperparameter、後續不能改。Vocabulary size 影響 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-layer/" data-link-title="Embedding Layer" data-link-desc="Transformer 第一層的查表結構、把整數 token ID 轉成可運算的向量">embedding layer&lt;/a> 大小、單一文字對應的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a> 數、多語言處理品質。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>主流 LLM 的 vocab size 演化：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>模型&lt;/th>
 &lt;th>Vocab size&lt;/th>
 &lt;th>設計考量&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>GPT-2&lt;/td>
 &lt;td>50,257&lt;/td>
 &lt;td>早期 byte-level BPE、英文為主&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Llama 1 / 2&lt;/td>
 &lt;td>32,000&lt;/td>
 &lt;td>緊湊、英文 + 部分多語言&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Llama 3&lt;/td>
 &lt;td>128,256&lt;/td>
 &lt;td>大幅擴張、改善多語言（特別是非拉丁語系）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Gemma 4&lt;/td>
 &lt;td>256,000&lt;/td>
 &lt;td>進一步擴大、強化多語言 + code tokenization&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Qwen3&lt;/td>
 &lt;td>151,936&lt;/td>
 &lt;td>中文 + 多語言友善&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DeepSeek-V3&lt;/td>
 &lt;td>129,280&lt;/td>
 &lt;td>中英 + code、跟 Llama 3 同量級&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Vocabulary size 的取捨：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Vocab 小（如 32K）&lt;/th>
 &lt;th>Vocab 大（如 256K）&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Embedding 矩陣小、模型參數少&lt;/td>
 &lt;td>Embedding 矩陣大、模型參數多&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>罕見字 / 多語言被拆很細、token 數多&lt;/td>
 &lt;td>高頻多語言整詞當一 token、token 數少&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>推論計算每步輸出 softmax 較快&lt;/td>
 &lt;td>每步 softmax 較慢（vocab × hidden 矩陣大）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>API 計費 token 數量較多&lt;/td>
 &lt;td>API 計費 token 數量較少&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>範例：同段中文「你好、世界」、Llama 1 (vocab 32K) 約 6 token、Gemma 4 (vocab 256K) 約 2-3 token、差距不小。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 model card 看到 &lt;code>vocab_size&lt;/code> 就是這個值。寫 code 場景的判讀：跑同個 prompt、不同模型實際處理的 token 數差很多、影響 &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> 利用率跟雲端 API 計費；換 tokenizer = 換 vocab = 整個 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-layer/" data-link-title="Embedding Layer" data-link-desc="Transformer 第一層的查表結構、把整數 token ID 轉成可運算的向量">embedding layer&lt;/a> 失效、所以 fine-tune 通常不動 tokenizer、想增加新語言的最簡單方式是 extend embedding（加新 row 不動既有 row、再 fine-tune）。&lt;/p></description><content:encoded><![CDATA[<p>Vocabulary size（詞彙表大小）的核心概念是「<strong>tokenizer 詞彙表中 token 的總數</strong>」。是模型訓練時就決定的 hyperparameter、後續不能改。Vocabulary size 影響 <a href="/blog/llm/knowledge-cards/embedding-layer/" data-link-title="Embedding Layer" data-link-desc="Transformer 第一層的查表結構、把整數 token ID 轉成可運算的向量">embedding layer</a> 大小、單一文字對應的 <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a> 數、多語言處理品質。</p>
<h2 id="概念位置">概念位置</h2>
<p>主流 LLM 的 vocab size 演化：</p>
<table>
  <thead>
      <tr>
          <th>模型</th>
          <th>Vocab size</th>
          <th>設計考量</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>GPT-2</td>
          <td>50,257</td>
          <td>早期 byte-level BPE、英文為主</td>
      </tr>
      <tr>
          <td>Llama 1 / 2</td>
          <td>32,000</td>
          <td>緊湊、英文 + 部分多語言</td>
      </tr>
      <tr>
          <td>Llama 3</td>
          <td>128,256</td>
          <td>大幅擴張、改善多語言（特別是非拉丁語系）</td>
      </tr>
      <tr>
          <td>Gemma 4</td>
          <td>256,000</td>
          <td>進一步擴大、強化多語言 + code tokenization</td>
      </tr>
      <tr>
          <td>Qwen3</td>
          <td>151,936</td>
          <td>中文 + 多語言友善</td>
      </tr>
      <tr>
          <td>DeepSeek-V3</td>
          <td>129,280</td>
          <td>中英 + code、跟 Llama 3 同量級</td>
      </tr>
  </tbody>
</table>
<p>Vocabulary size 的取捨：</p>
<table>
  <thead>
      <tr>
          <th>Vocab 小（如 32K）</th>
          <th>Vocab 大（如 256K）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Embedding 矩陣小、模型參數少</td>
          <td>Embedding 矩陣大、模型參數多</td>
      </tr>
      <tr>
          <td>罕見字 / 多語言被拆很細、token 數多</td>
          <td>高頻多語言整詞當一 token、token 數少</td>
      </tr>
      <tr>
          <td>推論計算每步輸出 softmax 較快</td>
          <td>每步 softmax 較慢（vocab × hidden 矩陣大）</td>
      </tr>
      <tr>
          <td>API 計費 token 數量較多</td>
          <td>API 計費 token 數量較少</td>
      </tr>
  </tbody>
</table>
<p>範例：同段中文「你好、世界」、Llama 1 (vocab 32K) 約 6 token、Gemma 4 (vocab 256K) 約 2-3 token、差距不小。</p>
<h2 id="設計責任">設計責任</h2>
<p>讀 model card 看到 <code>vocab_size</code> 就是這個值。寫 code 場景的判讀：跑同個 prompt、不同模型實際處理的 token 數差很多、影響 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a> 利用率跟雲端 API 計費；換 tokenizer = 換 vocab = 整個 <a href="/blog/llm/knowledge-cards/embedding-layer/" data-link-title="Embedding Layer" data-link-desc="Transformer 第一層的查表結構、把整數 token ID 轉成可運算的向量">embedding layer</a> 失效、所以 fine-tune 通常不動 tokenizer、想增加新語言的最簡單方式是 extend embedding（加新 row 不動既有 row、再 fine-tune）。</p>
]]></content:encoded></item><item><title>VRAM</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/vram/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/vram/</guid><description>&lt;p>VRAM（Video RAM）的核心概念是「顯卡晶片上的高速記憶體、跟系統主機板上的 RAM 是物理上獨立的兩塊預算」。獨立 GPU 場景下、模型權重要載入 VRAM 才能用 GPU 高速計算；VRAM 容量直接決定能跑多大模型。跟 Apple Silicon 的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/unified-memory/" data-link-title="Unified Memory Architecture" data-link-desc="Apple Silicon 讓 CPU / GPU / NE 共用同一塊記憶體：跑大模型的優勢來源">統一記憶體&lt;/a> 不同、PC 上 VRAM 跟系統 RAM 兩塊預算要分開規劃。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>VRAM 同時影響「能載入什麼」跟「跑多快」兩個維度：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>容量&lt;/strong>（GB）：決定能放多少模型權重 + &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> + 推論中間結果。容量不夠則跑不起來、需透過 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/moe-cpu-offload/" data-link-title="MoE CPU 卸載" data-link-desc="把 Mixture-of-Experts 模型不活躍的專家層權重放在系統 RAM、用到再走 PCIe 拉回 GPU、讓有限 VRAM 跑得了更大模型">MoE CPU 卸載&lt;/a> 把部分權重放系統 RAM。&lt;/li>
&lt;li>&lt;strong>頻寬&lt;/strong>（GB/s）：影響每 token 生成速度上限、見 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth&lt;/a> 卡片。&lt;/li>
&lt;/ol>
&lt;p>常見消費級 GPU 的 VRAM 規格（廠商標稱、依世代與型號變化）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>GPU&lt;/th>
 &lt;th>VRAM 容量&lt;/th>
 &lt;th>VRAM 類型&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>RTX 5060 / 4060&lt;/td>
 &lt;td>8GB&lt;/td>
 &lt;td>GDDR6/7&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>RTX 5060 Ti / 4060 Ti&lt;/td>
 &lt;td>16GB&lt;/td>
 &lt;td>GDDR6/7&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>RTX 5070 Ti / 4070 Ti&lt;/td>
 &lt;td>16GB&lt;/td>
 &lt;td>GDDR6/7&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>RTX 4090&lt;/td>
 &lt;td>24GB&lt;/td>
 &lt;td>GDDR6X&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>RTX 5090&lt;/td>
 &lt;td>32GB&lt;/td>
 &lt;td>GDDR7&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>VRAM 容量是選 GPU 跑本地 LLM 的第一決策軸、頻寬是第二決策軸。同容量下、頻寬接近 2 倍的卡（如 5070 Ti 對 5060 Ti）生字速度差異明顯。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：上表是 2026 年 5 月主流消費級 NVIDIA GPU 規格的數量級對照、實際 VRAM 容量、頻寬、GDDR 版本依特定型號、廠商 / SKU、製造時間變化、引用前以 &lt;a href="https://www.nvidia.com/en-us/geforce/graphics-cards/">NVIDIA 官方規格頁&lt;/a> 為準。&lt;/p>&lt;/blockquote>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 VRAM 後可以解釋三個現象：為什麼同樣 16GB 容量、不同卡的生字速度差很多（頻寬不同）；為什麼 MoE 模型在 16GB VRAM 上跑得了 30B 級模型（透過卸載）；為什麼 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/pcie/" data-link-title="PCIe" data-link-desc="PC 上連接 GPU 跟主機板的高速序列匯流排、影響模型載入速度跟 MoE 卸載時的推論吞吐">PCIe&lt;/a> 頻寬在 PC 場景影響 MoE 卸載的速度（系統 RAM 跟 VRAM 之間的橋）。&lt;/p>
&lt;p>選 PC 規劃本地 LLM 時、VRAM 容量決定能跑的模型上限、VRAM 頻寬決定生字速度上限、系統 RAM 容量決定 MoE 卸載空間。詳見 &lt;a href="https://tarrragon.github.io/blog/llm/05-discrete-gpu/vram-ram-budget/" data-link-title="5.0 VRAM &amp;#43; RAM 分層預算" data-link-desc="PC 獨立 GPU 場景的記憶體預算判讀：VRAM 是快的世界、RAM 是大的世界、PCIe 把兩個世界連起來">5.0 VRAM + RAM 分層預算&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>VRAM（Video RAM）的核心概念是「顯卡晶片上的高速記憶體、跟系統主機板上的 RAM 是物理上獨立的兩塊預算」。獨立 GPU 場景下、模型權重要載入 VRAM 才能用 GPU 高速計算；VRAM 容量直接決定能跑多大模型。跟 Apple Silicon 的 <a href="/blog/llm/knowledge-cards/unified-memory/" data-link-title="Unified Memory Architecture" data-link-desc="Apple Silicon 讓 CPU / GPU / NE 共用同一塊記憶體：跑大模型的優勢來源">統一記憶體</a> 不同、PC 上 VRAM 跟系統 RAM 兩塊預算要分開規劃。</p>
<h2 id="概念位置">概念位置</h2>
<p>VRAM 同時影響「能載入什麼」跟「跑多快」兩個維度：</p>
<ol>
<li><strong>容量</strong>（GB）：決定能放多少模型權重 + <a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> + 推論中間結果。容量不夠則跑不起來、需透過 <a href="/blog/llm/knowledge-cards/moe-cpu-offload/" data-link-title="MoE CPU 卸載" data-link-desc="把 Mixture-of-Experts 模型不活躍的專家層權重放在系統 RAM、用到再走 PCIe 拉回 GPU、讓有限 VRAM 跑得了更大模型">MoE CPU 卸載</a> 把部分權重放系統 RAM。</li>
<li><strong>頻寬</strong>（GB/s）：影響每 token 生成速度上限、見 <a href="/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth</a> 卡片。</li>
</ol>
<p>常見消費級 GPU 的 VRAM 規格（廠商標稱、依世代與型號變化）：</p>
<table>
  <thead>
      <tr>
          <th>GPU</th>
          <th>VRAM 容量</th>
          <th>VRAM 類型</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>RTX 5060 / 4060</td>
          <td>8GB</td>
          <td>GDDR6/7</td>
      </tr>
      <tr>
          <td>RTX 5060 Ti / 4060 Ti</td>
          <td>16GB</td>
          <td>GDDR6/7</td>
      </tr>
      <tr>
          <td>RTX 5070 Ti / 4070 Ti</td>
          <td>16GB</td>
          <td>GDDR6/7</td>
      </tr>
      <tr>
          <td>RTX 4090</td>
          <td>24GB</td>
          <td>GDDR6X</td>
      </tr>
      <tr>
          <td>RTX 5090</td>
          <td>32GB</td>
          <td>GDDR7</td>
      </tr>
  </tbody>
</table>
<p>VRAM 容量是選 GPU 跑本地 LLM 的第一決策軸、頻寬是第二決策軸。同容量下、頻寬接近 2 倍的卡（如 5070 Ti 對 5060 Ti）生字速度差異明顯。</p>
<blockquote>
<p><strong>事實查核註</strong>：上表是 2026 年 5 月主流消費級 NVIDIA GPU 規格的數量級對照、實際 VRAM 容量、頻寬、GDDR 版本依特定型號、廠商 / SKU、製造時間變化、引用前以 <a href="https://www.nvidia.com/en-us/geforce/graphics-cards/">NVIDIA 官方規格頁</a> 為準。</p></blockquote>
<h2 id="設計責任">設計責任</h2>
<p>理解 VRAM 後可以解釋三個現象：為什麼同樣 16GB 容量、不同卡的生字速度差很多（頻寬不同）；為什麼 MoE 模型在 16GB VRAM 上跑得了 30B 級模型（透過卸載）；為什麼 <a href="/blog/llm/knowledge-cards/pcie/" data-link-title="PCIe" data-link-desc="PC 上連接 GPU 跟主機板的高速序列匯流排、影響模型載入速度跟 MoE 卸載時的推論吞吐">PCIe</a> 頻寬在 PC 場景影響 MoE 卸載的速度（系統 RAM 跟 VRAM 之間的橋）。</p>
<p>選 PC 規劃本地 LLM 時、VRAM 容量決定能跑的模型上限、VRAM 頻寬決定生字速度上限、系統 RAM 容量決定 MoE 卸載空間。詳見 <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>
]]></content:encoded></item><item><title>Autoregressive</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/autoregressive/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/autoregressive/</guid><description>&lt;p>Autoregressive（自回歸）的核心概念是「下一個 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a> 的生成需要看到前面所有 token」。LLM 每生一個 token 都要把目前的完整序列（prompt + 已生成部分）丟進神經網路跑一次，得到下一個 token 的機率分佈，挑一個輸出，再循環。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Autoregressive 是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/transformer/" data-link-title="Transformer" data-link-desc="寫 code 用的 LLM 神經網路架構：基於 attention 機制、自回歸生成 token">Transformer&lt;/a> 模型用於文字生成的運作方式。它跟生成式架構的另一條路線 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/diffusion/" data-link-title="Diffusion" data-link-desc="產圖用的生成式 AI 架構：跟寫 code 用的 Transformer 是不同路線">Diffusion&lt;/a> 形成對比：Diffusion 一次處理整張圖、autoregressive 一個 token 一個 token 接龍。寫 code 用的 LLM 都是 autoregressive。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>寫 code 場景的 streaming 輸出就是 autoregressive 的直接體現：你看到回答「邊想邊出現」，實際是每個 token 各跑一次 forward pass 後即時顯示。&lt;code>寫 fibonacci function&lt;/code> 的回答經過「&lt;code>def&lt;/code> → &lt;code>def fib&lt;/code> → &lt;code>def fib(&lt;/code> → &amp;hellip;」這樣逐 token 推進；模型回答越長等越久，跟雲端旗艦一樣，差別只在每次 forward pass 跑得多快。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 autoregressive 後可以判讀幾件事：streaming 只是把已產出的 token 即時顯示、跟生成速度本身無關；回答長度直接影響等待時間；任何「一次生多個 token」的加速技巧（&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">speculative decoding&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mtp/" data-link-title="Multi-Token Prediction (MTP)" data-link-desc="Google 為 Gemma 系列釋出的 speculative decoding 工程化實作">MTP&lt;/a>）都是針對 autoregressive 的優化、而非取代。&lt;/p></description><content:encoded><![CDATA[<p>Autoregressive（自回歸）的核心概念是「下一個 <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a> 的生成需要看到前面所有 token」。LLM 每生一個 token 都要把目前的完整序列（prompt + 已生成部分）丟進神經網路跑一次，得到下一個 token 的機率分佈，挑一個輸出，再循環。</p>
<h2 id="概念位置">概念位置</h2>
<p>Autoregressive 是 <a href="/blog/llm/knowledge-cards/transformer/" data-link-title="Transformer" data-link-desc="寫 code 用的 LLM 神經網路架構：基於 attention 機制、自回歸生成 token">Transformer</a> 模型用於文字生成的運作方式。它跟生成式架構的另一條路線 <a href="/blog/llm/knowledge-cards/diffusion/" data-link-title="Diffusion" data-link-desc="產圖用的生成式 AI 架構：跟寫 code 用的 Transformer 是不同路線">Diffusion</a> 形成對比：Diffusion 一次處理整張圖、autoregressive 一個 token 一個 token 接龍。寫 code 用的 LLM 都是 autoregressive。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>寫 code 場景的 streaming 輸出就是 autoregressive 的直接體現：你看到回答「邊想邊出現」，實際是每個 token 各跑一次 forward pass 後即時顯示。<code>寫 fibonacci function</code> 的回答經過「<code>def</code> → <code>def fib</code> → <code>def fib(</code> → &hellip;」這樣逐 token 推進；模型回答越長等越久，跟雲端旗艦一樣，差別只在每次 forward pass 跑得多快。</p>
<h2 id="設計責任">設計責任</h2>
<p>理解 autoregressive 後可以判讀幾件事：streaming 只是把已產出的 token 即時顯示、跟生成速度本身無關；回答長度直接影響等待時間；任何「一次生多個 token」的加速技巧（<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>）都是針對 autoregressive 的優化、而非取代。</p>
]]></content:encoded></item><item><title>Base Model</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/base-model/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/base-model/</guid><description>&lt;p>Base Model 的核心概念是「LLM 訓練 pipeline 第一階段的產物」，只用大量文字做 next-token prediction、尚未做 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/instruction-tuned/" data-link-title="Instruction-Tuned Model" data-link-desc="經過指令微調的模型：會跟著 prompt 走、回答使用者問題">instruction tuning&lt;/a> 或 RLHF。Base model 擅長「順著前面的文字接下去」，但對「使用者提問、模型回答」這種交互模式比較生硬。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Base model 跟 instruction-tuned model 共用底層權重結構、差別在後續微調階段。對寫 code 場景的多數使用者來說、預設選 instruction-tuned 版本；base model 主要服務想自己微調的研究人員與工程師。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>Hugging Face / Ollama 上 base model 通常會明示：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>名稱範例&lt;/th>
 &lt;th>是 base model 嗎&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;code>llama-3.3-70b-base&lt;/code>&lt;/td>
 &lt;td>是&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>llama-3.3-70b-instruct&lt;/code>&lt;/td>
 &lt;td>否（&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/instruction-tuned/" data-link-title="Instruction-Tuned Model" data-link-desc="經過指令微調的模型：會跟著 prompt 走、回答使用者問題">已 instruction-tuned&lt;/a>）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>gemma-4-31b&lt;/code>&lt;/td>
 &lt;td>視 repo 而定、要看 model card&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>qwen3-coder-30b&lt;/code>&lt;/td>
 &lt;td>否（coding-tuned 是 instruction-tuned 的特化）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>對話 base model 的體感：問「寫一個 Python fibonacci」可能得到「寫一個 Python fibonacci。寫一個 JavaScript fibonacci。寫一個&amp;hellip;」這種文字接龍式回答、而非真正寫出 function。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>下載模型前確認是 instruct 還是 base 版本。Ollama registry 預設提供 instruct 版本、但 Hugging Face 上同一個模型常同時有兩種；挑錯版本會以為「這個模型很差」、其實只是用錯類型。想做 fine-tuning 的工程師才需要 base model；其他人優先選 instruct。&lt;/p></description><content:encoded><![CDATA[<p>Base Model 的核心概念是「LLM 訓練 pipeline 第一階段的產物」，只用大量文字做 next-token prediction、尚未做 <a href="/blog/llm/knowledge-cards/instruction-tuned/" data-link-title="Instruction-Tuned Model" data-link-desc="經過指令微調的模型：會跟著 prompt 走、回答使用者問題">instruction tuning</a> 或 RLHF。Base model 擅長「順著前面的文字接下去」，但對「使用者提問、模型回答」這種交互模式比較生硬。</p>
<h2 id="概念位置">概念位置</h2>
<p>Base model 跟 instruction-tuned model 共用底層權重結構、差別在後續微調階段。對寫 code 場景的多數使用者來說、預設選 instruction-tuned 版本；base model 主要服務想自己微調的研究人員與工程師。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>Hugging Face / Ollama 上 base model 通常會明示：</p>
<table>
  <thead>
      <tr>
          <th>名稱範例</th>
          <th>是 base model 嗎</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>llama-3.3-70b-base</code></td>
          <td>是</td>
      </tr>
      <tr>
          <td><code>llama-3.3-70b-instruct</code></td>
          <td>否（<a href="/blog/llm/knowledge-cards/instruction-tuned/" data-link-title="Instruction-Tuned Model" data-link-desc="經過指令微調的模型：會跟著 prompt 走、回答使用者問題">已 instruction-tuned</a>）</td>
      </tr>
      <tr>
          <td><code>gemma-4-31b</code></td>
          <td>視 repo 而定、要看 model card</td>
      </tr>
      <tr>
          <td><code>qwen3-coder-30b</code></td>
          <td>否（coding-tuned 是 instruction-tuned 的特化）</td>
      </tr>
  </tbody>
</table>
<p>對話 base model 的體感：問「寫一個 Python fibonacci」可能得到「寫一個 Python fibonacci。寫一個 JavaScript fibonacci。寫一個&hellip;」這種文字接龍式回答、而非真正寫出 function。</p>
<h2 id="設計責任">設計責任</h2>
<p>下載模型前確認是 instruct 還是 base 版本。Ollama registry 預設提供 instruct 版本、但 Hugging Face 上同一個模型常同時有兩種；挑錯版本會以為「這個模型很差」、其實只是用錯類型。想做 fine-tuning 的工程師才需要 base model；其他人優先選 instruct。</p>
]]></content:encoded></item><item><title>Context Window</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/context-window/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/context-window/</guid><description>&lt;p>Context Window 的核心概念是「模型一次能處理的最大 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a> 序列長度」，包含 prompt 與生成內容的總和。超過上限時，較早的 token 會被截掉、模型「看不到」前面的對話。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Context window 是模型訓練時決定的硬性限制，跟 &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 window 讓模型能讀整個 repo 或長對話，但代價是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT&lt;/a> 升高與記憶體吃緊。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>2026 年 5 月各模型典型 context window：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>模型&lt;/th>
 &lt;th>Context Window&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Gemma 4 31B&lt;/td>
 &lt;td>256K tokens&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Qwen3-Coder 30B&lt;/td>
 &lt;td>256K tokens&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Llama 3.3 70B&lt;/td>
 &lt;td>128K tokens&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Claude Sonnet 4.6（雲端）&lt;/td>
 &lt;td>1M tokens&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>GPT-5（雲端）&lt;/td>
 &lt;td>400K tokens&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>「支援 128K」跟「實用 128K」是兩件事。本地跑長 context 時 KV cache 會吃掉大量記憶體，例如 32GB Mac 跑 31B 模型實用 context 大約 8 ~ 16K tokens；硬塞 128K 會 swap、跑成蝸牛。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>評估「能不能塞整個 repo 進 prompt」要綜合三個指標：模型聲稱的 context window、實際記憶體預算、可接受的 TTFT。寫 prompt 時若反覆達到上限、考慮整理 prompt 結構（移除不必要 context）或改用支援更大 context 的雲端模型，而非硬塞。&lt;/p></description><content:encoded><![CDATA[<p>Context Window 的核心概念是「模型一次能處理的最大 <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a> 序列長度」，包含 prompt 與生成內容的總和。超過上限時，較早的 token 會被截掉、模型「看不到」前面的對話。</p>
<h2 id="概念位置">概念位置</h2>
<p>Context window 是模型訓練時決定的硬性限制，跟 <a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 共同決定推論時的記憶體佔用。較大的 context window 讓模型能讀整個 repo 或長對話，但代價是 <a href="/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT</a> 升高與記憶體吃緊。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>2026 年 5 月各模型典型 context window：</p>
<table>
  <thead>
      <tr>
          <th>模型</th>
          <th>Context Window</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Gemma 4 31B</td>
          <td>256K tokens</td>
      </tr>
      <tr>
          <td>Qwen3-Coder 30B</td>
          <td>256K tokens</td>
      </tr>
      <tr>
          <td>Llama 3.3 70B</td>
          <td>128K tokens</td>
      </tr>
      <tr>
          <td>Claude Sonnet 4.6（雲端）</td>
          <td>1M tokens</td>
      </tr>
      <tr>
          <td>GPT-5（雲端）</td>
          <td>400K tokens</td>
      </tr>
  </tbody>
</table>
<p>「支援 128K」跟「實用 128K」是兩件事。本地跑長 context 時 KV cache 會吃掉大量記憶體，例如 32GB Mac 跑 31B 模型實用 context 大約 8 ~ 16K tokens；硬塞 128K 會 swap、跑成蝸牛。</p>
<h2 id="設計責任">設計責任</h2>
<p>評估「能不能塞整個 repo 進 prompt」要綜合三個指標：模型聲稱的 context window、實際記憶體預算、可接受的 TTFT。寫 prompt 時若反覆達到上限、考慮整理 prompt 結構（移除不必要 context）或改用支援更大 context 的雲端模型，而非硬塞。</p>
]]></content:encoded></item><item><title>Diffusion</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/diffusion/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/diffusion/</guid><description>&lt;p>Diffusion 的核心概念是「從純雜訊開始、逐步去噪生成完整資料的神經網路架構」。產圖（Stable Diffusion、Flux、SDXL）、產影片、產音樂多半用 Diffusion。它跟寫 code 用的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/transformer/" data-link-title="Transformer" data-link-desc="寫 code 用的 LLM 神經網路架構：基於 attention 機制、自回歸生成 token">Transformer&lt;/a> 是兩個獨立的生成式 AI 路線、推論流程、工具鏈、適合任務都不同。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Diffusion 模型一次處理整張圖、用「去噪 N 步」的方式生成；跟 Transformer 的「一個 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a> 接一個 token」生成方式根本不同。記憶體需求、硬體最適規格、生態系都是平行宇宙。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>Diffusion 跟 Transformer 工具鏈完全不通用：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>Transformer LLM&lt;/th>
 &lt;th>Diffusion&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>主流模型&lt;/td>
 &lt;td>Gemma 4、Qwen3、Llama 3.3、GPT-5&lt;/td>
 &lt;td>Stable Diffusion、Flux、SDXL&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>推論伺服器&lt;/td>
 &lt;td>Ollama、LM Studio、llama.cpp、oMLX&lt;/td>
 &lt;td>ComfyUI、Draw Things、AUTOMATIC1111、Diffusers&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>推論時間&lt;/td>
 &lt;td>每秒幾十 tok（autoregressive）&lt;/td>
 &lt;td>整張圖 15 ~ 60 秒（一次到位）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>硬體最適&lt;/td>
 &lt;td>記憶體大、頻寬高&lt;/td>
 &lt;td>GPU 算力高、VRAM 頻寬高&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Prompt 風格&lt;/td>
 &lt;td>instruction 形式&lt;/td>
 &lt;td>descriptive + negative prompt&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>量化技術&lt;/td>
 &lt;td>&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>、MLX&lt;/td>
 &lt;td>各家不同、Diffusers 為主&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>聽到「換 model 就能產圖」的說法時、回到本卡確認：產圖是另一個領域、要切換到 Diffusion 工具鏈、而非在 Ollama 上下載產圖模型。寫 code 工作流跟產圖工作流分開學、避免兩邊半生不熟。對 Mac 使用者來說、Draw Things（macOS 原生 app）是產圖入門的最低門檻路徑。&lt;/p></description><content:encoded><![CDATA[<p>Diffusion 的核心概念是「從純雜訊開始、逐步去噪生成完整資料的神經網路架構」。產圖（Stable Diffusion、Flux、SDXL）、產影片、產音樂多半用 Diffusion。它跟寫 code 用的 <a href="/blog/llm/knowledge-cards/transformer/" data-link-title="Transformer" data-link-desc="寫 code 用的 LLM 神經網路架構：基於 attention 機制、自回歸生成 token">Transformer</a> 是兩個獨立的生成式 AI 路線、推論流程、工具鏈、適合任務都不同。</p>
<h2 id="概念位置">概念位置</h2>
<p>Diffusion 模型一次處理整張圖、用「去噪 N 步」的方式生成；跟 Transformer 的「一個 <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a> 接一個 token」生成方式根本不同。記憶體需求、硬體最適規格、生態系都是平行宇宙。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>Diffusion 跟 Transformer 工具鏈完全不通用：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>Transformer LLM</th>
          <th>Diffusion</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>主流模型</td>
          <td>Gemma 4、Qwen3、Llama 3.3、GPT-5</td>
          <td>Stable Diffusion、Flux、SDXL</td>
      </tr>
      <tr>
          <td>推論伺服器</td>
          <td>Ollama、LM Studio、llama.cpp、oMLX</td>
          <td>ComfyUI、Draw Things、AUTOMATIC1111、Diffusers</td>
      </tr>
      <tr>
          <td>推論時間</td>
          <td>每秒幾十 tok（autoregressive）</td>
          <td>整張圖 15 ~ 60 秒（一次到位）</td>
      </tr>
      <tr>
          <td>硬體最適</td>
          <td>記憶體大、頻寬高</td>
          <td>GPU 算力高、VRAM 頻寬高</td>
      </tr>
      <tr>
          <td>Prompt 風格</td>
          <td>instruction 形式</td>
          <td>descriptive + negative prompt</td>
      </tr>
      <tr>
          <td>量化技術</td>
          <td><a href="/blog/llm/knowledge-cards/gguf/" data-link-title="GGUF" data-link-desc="llama.cpp 生態定義的模型權重格式：把權重、tokenizer、metadata 打包成單一檔案">GGUF</a>、MLX</td>
          <td>各家不同、Diffusers 為主</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>聽到「換 model 就能產圖」的說法時、回到本卡確認：產圖是另一個領域、要切換到 Diffusion 工具鏈、而非在 Ollama 上下載產圖模型。寫 code 工作流跟產圖工作流分開學、避免兩邊半生不熟。對 Mac 使用者來說、Draw Things（macOS 原生 app）是產圖入門的最低門檻路徑。</p>
]]></content:encoded></item><item><title>Drafter Model</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/drafter-model/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/drafter-model/</guid><description>&lt;p>Drafter Model 的核心概念是「&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">speculative decoding&lt;/a> 中用來快速預測未來幾個 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a> 的小模型」。它跑得比 target model 快很多倍、每次跑一個 forward pass 猜 N 個 token、再交給 target model 並行驗證。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Drafter 與 target 形成一對：drafter 快但較不準、target 慢但準確、兩者組合得到「跑得快的近似 target」。drafter 在記憶體中跟 target 一起載入、佔額外記憶體。Gemma 4 31B + 官方 drafter 的記憶體佔用約「target 18GB + drafter 1GB」、需要 32GB+ Mac 才順暢。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>匹配的 drafter / target 對：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Target&lt;/th>
 &lt;th>Drafter&lt;/th>
 &lt;th>來源&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Gemma 4 31B&lt;/td>
 &lt;td>Gemma 4 E4B&lt;/td>
 &lt;td>Google 官方釋出&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Llama 3.3 70B&lt;/td>
 &lt;td>Llama 3.2 1B&lt;/td>
 &lt;td>社群配對&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Qwen3-Coder 30B&lt;/td>
 &lt;td>（尚未有官方）&lt;/td>
 &lt;td>Alibaba 還未釋出 drafter&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵限制：drafter 與 target 必須用相同 tokenizer。Gemma 系列只能配 Gemma 系列、Llama 系列只能配 Llama 系列、跨家族沒有相容性。LM Studio 的 UI 在挑 drafter 時會自動過濾相容候選。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>寫 code 場景的多數使用者透過預先打包的 model tag（如 Ollama 的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mtp/" data-link-title="Multi-Token Prediction (MTP)" data-link-desc="Google 為 Gemma 系列釋出的 speculative decoding 工程化實作">MTP&lt;/a> 版本）取得 drafter、不用自己配對。想用其他模型的 speculative decoding 時、要確認社群是否有匹配的 drafter；找不到的情況下、預設用沒 speculative decoding 的版本是合理選擇、加速收益跟「找 drafter、自己配置」的成本比起來通常不划算。&lt;/p></description><content:encoded><![CDATA[<p>Drafter Model 的核心概念是「<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/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a> 的小模型」。它跑得比 target model 快很多倍、每次跑一個 forward pass 猜 N 個 token、再交給 target model 並行驗證。</p>
<h2 id="概念位置">概念位置</h2>
<p>Drafter 與 target 形成一對：drafter 快但較不準、target 慢但準確、兩者組合得到「跑得快的近似 target」。drafter 在記憶體中跟 target 一起載入、佔額外記憶體。Gemma 4 31B + 官方 drafter 的記憶體佔用約「target 18GB + drafter 1GB」、需要 32GB+ Mac 才順暢。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>匹配的 drafter / target 對：</p>
<table>
  <thead>
      <tr>
          <th>Target</th>
          <th>Drafter</th>
          <th>來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Gemma 4 31B</td>
          <td>Gemma 4 E4B</td>
          <td>Google 官方釋出</td>
      </tr>
      <tr>
          <td>Llama 3.3 70B</td>
          <td>Llama 3.2 1B</td>
          <td>社群配對</td>
      </tr>
      <tr>
          <td>Qwen3-Coder 30B</td>
          <td>（尚未有官方）</td>
          <td>Alibaba 還未釋出 drafter</td>
      </tr>
  </tbody>
</table>
<p>關鍵限制：drafter 與 target 必須用相同 tokenizer。Gemma 系列只能配 Gemma 系列、Llama 系列只能配 Llama 系列、跨家族沒有相容性。LM Studio 的 UI 在挑 drafter 時會自動過濾相容候選。</p>
<h2 id="設計責任">設計責任</h2>
<p>寫 code 場景的多數使用者透過預先打包的 model tag（如 Ollama 的 <a href="/blog/llm/knowledge-cards/mtp/" data-link-title="Multi-Token Prediction (MTP)" data-link-desc="Google 為 Gemma 系列釋出的 speculative decoding 工程化實作">MTP</a> 版本）取得 drafter、不用自己配對。想用其他模型的 speculative decoding 時、要確認社群是否有匹配的 drafter；找不到的情況下、預設用沒 speculative decoding 的版本是合理選擇、加速收益跟「找 drafter、自己配置」的成本比起來通常不划算。</p>
]]></content:encoded></item><item><title>Embedding Model</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-model/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-model/</guid><description>&lt;p>Embedding Model 的核心概念是「把文字轉成固定維度向量、讓相似內容在向量空間中靠近」。Continue.dev 等工具用 embedding model 把 codebase 索引成向量資料庫、再用語意相似度搜尋相關片段。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Embedding model 跟 chat model 是兩種不同的模型、有各自的權重檔。Chat model 用於對話與生成、embedding model 用於 retrieval。同一個推論伺服器（如 Ollama）可以同時載入兩種模型、為不同用途服務。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>寫 code 場景常用的 embedding 模型：&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>&lt;code>nomic-embed-text&lt;/code>&lt;/td>
 &lt;td>274MB&lt;/td>
 &lt;td>英文為主、Continue.dev 預設&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>mxbai-embed-large&lt;/code>&lt;/td>
 &lt;td>670MB&lt;/td>
 &lt;td>較強的英文 embedding&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>bge-m3&lt;/code>&lt;/td>
 &lt;td>1.2GB&lt;/td>
 &lt;td>多語言（含中文）embedding&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>向量維度通常 384 ~ 1024、不同模型不同；切換 embedding 模型要重建索引、向量空間互不相容。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Continue.dev 的 &lt;code>@codebase&lt;/code> 命令依賴 embedding 模型；要先 &lt;code>ollama pull nomic-embed-text&lt;/code> 並在 config.json 設 &lt;code>embeddingsProvider&lt;/code>。Embedding 模型對 codebase 搜尋品質有影響、但邊際效益遠小於 chat model；先用預設 &lt;code>nomic-embed-text&lt;/code>、需求出現再換更大模型。&lt;/p></description><content:encoded><![CDATA[<p>Embedding Model 的核心概念是「把文字轉成固定維度向量、讓相似內容在向量空間中靠近」。Continue.dev 等工具用 embedding model 把 codebase 索引成向量資料庫、再用語意相似度搜尋相關片段。</p>
<h2 id="概念位置">概念位置</h2>
<p>Embedding model 跟 chat model 是兩種不同的模型、有各自的權重檔。Chat model 用於對話與生成、embedding model 用於 retrieval。同一個推論伺服器（如 Ollama）可以同時載入兩種模型、為不同用途服務。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>寫 code 場景常用的 embedding 模型：</p>
<table>
  <thead>
      <tr>
          <th>模型</th>
          <th>大小</th>
          <th>用途</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>nomic-embed-text</code></td>
          <td>274MB</td>
          <td>英文為主、Continue.dev 預設</td>
      </tr>
      <tr>
          <td><code>mxbai-embed-large</code></td>
          <td>670MB</td>
          <td>較強的英文 embedding</td>
      </tr>
      <tr>
          <td><code>bge-m3</code></td>
          <td>1.2GB</td>
          <td>多語言（含中文）embedding</td>
      </tr>
  </tbody>
</table>
<p>向量維度通常 384 ~ 1024、不同模型不同；切換 embedding 模型要重建索引、向量空間互不相容。</p>
<h2 id="設計責任">設計責任</h2>
<p>Continue.dev 的 <code>@codebase</code> 命令依賴 embedding 模型；要先 <code>ollama pull nomic-embed-text</code> 並在 config.json 設 <code>embeddingsProvider</code>。Embedding 模型對 codebase 搜尋品質有影響、但邊際效益遠小於 chat model；先用預設 <code>nomic-embed-text</code>、需求出現再換更大模型。</p>
]]></content:encoded></item><item><title>Function Calling</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/function-calling/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/function-calling/</guid><description>&lt;p>Function Calling 的核心概念是「模型在訓練階段學到的呼叫工具能力」。SFT 階段大量「使用者 query + 該呼叫什麼工具 + 傳什麼參數」的範例、讓模型學會看到 query 知道何時呼叫、怎麼呼叫、傳什麼參數。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Function calling 是&lt;strong>模型能力&lt;/strong>層、跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">structured output&lt;/a>（**&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/sampling-constraint/" data-link-title="Sampling Constraint" data-link-desc="推論時限制下一個 token 候選集合的控制手段，用來把模型生成導向合法格式或特定選項">sampling 約束&lt;/a>**層）、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mcp/" data-link-title="MCP（Model Context Protocol）" data-link-desc="LLM application ↔ 外部 tool server 之間的標準化協議、複用 OpenAI 相容 API 的成功模式">MCP&lt;/a>（&lt;strong>server 協議&lt;/strong>層）正交。三者解的問題層級不同、可獨立或組合使用。模型訓練支撐 vs sampling 強制的差別決定行為穩定性：function calling 訓練好的模型「自然」輸出合法呼叫、不需要強約束；訓練不足靠 structured output 兜底。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>模型 function calling 強弱看四個指標：(1) 該呼叫時呼叫的準確度、(2) 呼叫格式合法率、(3) 參數準確度、(4) 多工具選對工具的準確度。寫 code 場景的本地小模型（&amp;lt; 14B）這四個都明顯弱於雲端旗艦——根因是 SFT 階段 function calling 範例量不夠、小模型容量學不全。判讀訊號：呼叫格式錯、參數胡亂填、不該呼叫時呼叫、該呼叫時不呼叫。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>選擇 function calling 還是 free-form + structured output、依模型規模跟跨 model 可移植需求決定：主流大模型走 function calling 開箱即用、跨 model / 較弱模型走 free-form + &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">grammar&lt;/a> 約束較穩。實務常組合：function calling 「正常情況」、structured output 兜底保證合法、retry + fallback 處理失敗。詳細展開見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/tool-use-principles/" data-link-title="4.3 Tool use 原理：LLM 跟外部世界互動" data-link-desc="Structured output 是 LLM 跨入工程系統的橋、function calling 取捨、為什麼本地小模型 tool use 表現崩潰">4.3 Tool use 原理&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/application-protocols/" data-link-title="4.6 應用層協議：function calling / structured output / MCP" data-link-desc="三個常被混為一談的概念：模型能力、sampling 約束、server 協議，三者的層級差異與組合方式">4.6 應用層協議&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Function Calling 的核心概念是「模型在訓練階段學到的呼叫工具能力」。SFT 階段大量「使用者 query + 該呼叫什麼工具 + 傳什麼參數」的範例、讓模型學會看到 query 知道何時呼叫、怎麼呼叫、傳什麼參數。</p>
<h2 id="概念位置">概念位置</h2>
<p>Function calling 是<strong>模型能力</strong>層、跟 <a href="/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">structured output</a>（**<a href="/blog/llm/knowledge-cards/sampling-constraint/" data-link-title="Sampling Constraint" data-link-desc="推論時限制下一個 token 候選集合的控制手段，用來把模型生成導向合法格式或特定選項">sampling 約束</a>**層）、<a href="/blog/llm/knowledge-cards/mcp/" data-link-title="MCP（Model Context Protocol）" data-link-desc="LLM application ↔ 外部 tool server 之間的標準化協議、複用 OpenAI 相容 API 的成功模式">MCP</a>（<strong>server 協議</strong>層）正交。三者解的問題層級不同、可獨立或組合使用。模型訓練支撐 vs sampling 強制的差別決定行為穩定性：function calling 訓練好的模型「自然」輸出合法呼叫、不需要強約束；訓練不足靠 structured output 兜底。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>模型 function calling 強弱看四個指標：(1) 該呼叫時呼叫的準確度、(2) 呼叫格式合法率、(3) 參數準確度、(4) 多工具選對工具的準確度。寫 code 場景的本地小模型（&lt; 14B）這四個都明顯弱於雲端旗艦——根因是 SFT 階段 function calling 範例量不夠、小模型容量學不全。判讀訊號：呼叫格式錯、參數胡亂填、不該呼叫時呼叫、該呼叫時不呼叫。</p>
<h2 id="設計責任">設計責任</h2>
<p>選擇 function calling 還是 free-form + structured output、依模型規模跟跨 model 可移植需求決定：主流大模型走 function calling 開箱即用、跨 model / 較弱模型走 free-form + <a href="/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">grammar</a> 約束較穩。實務常組合：function calling 「正常情況」、structured output 兜底保證合法、retry + fallback 處理失敗。詳細展開見 <a href="/blog/llm/04-applications/tool-use-principles/" data-link-title="4.3 Tool use 原理：LLM 跟外部世界互動" data-link-desc="Structured output 是 LLM 跨入工程系統的橋、function calling 取捨、為什麼本地小模型 tool use 表現崩潰">4.3 Tool use 原理</a> 與 <a href="/blog/llm/04-applications/application-protocols/" data-link-title="4.6 應用層協議：function calling / structured output / MCP" data-link-desc="三個常被混為一談的概念：模型能力、sampling 約束、server 協議，三者的層級差異與組合方式">4.6 應用層協議</a>。</p>
]]></content:encoded></item><item><title>GGUF</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/gguf/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/gguf/</guid><description>&lt;p>GGUF（GGML Unified Format）的核心概念是「llama.cpp 系統定義的模型權重格式」，把模型權重、tokenizer 設定、模型 metadata 全部打包進單一檔案。Ollama 內部存的就是 GGUF，多數本地推論伺服器（除了走 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mlx/" data-link-title="MLX" data-link-desc="Apple 釋出的 Apple Silicon 數值運算 framework：類似 PyTorch / JAX 的 Mac 對應物">MLX&lt;/a> 路線的）也支援。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>GGUF 屬於模型層的封裝格式，跟 Safetensors（Hugging Face 通用）、MLX format（Apple 生態）是平行的選擇。它的設計目標是「單一檔案、跨平台、支援多種&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">量化&lt;/a>等級」。Ollama、LM Studio、llama.cpp 都用 GGUF；想跑 MLX 系統的 oMLX 則要 MLX format 權重。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>Hugging Face 上 GGUF 檔案命名通常含量化標籤：&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>&lt;code>gemma-4-31b-it-Q4_K_M.gguf&lt;/code>&lt;/td>
 &lt;td>Gemma 4、31B、instruct-tuned、Q4_K_M 量化&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>Llama-3.3-70B-Instruct-Q5_K_M.gguf&lt;/code>&lt;/td>
 &lt;td>Llama 3.3、70B、instruct、Q5_K_M&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>qwen3-coder-30b-Q8_0.gguf&lt;/code>&lt;/td>
 &lt;td>Qwen3-Coder、30B、Q8 量化&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>社群常見的高品質 GGUF 提供者有 &lt;code>bartowski&lt;/code>、&lt;code>unsloth&lt;/code>、&lt;code>TheBloke&lt;/code>（已退坑）等；挑下載量高、最近更新的 repo 較安全。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>直接下載 GGUF 多半用於 LM Studio 與 llama.cpp 場景。Ollama 使用者通常透過 &lt;code>ollama pull&lt;/code> 拉模型，背後格式也是 GGUF、但細節對使用者透明。想自己量化模型（從 Safetensors 轉 GGUF）要用 llama.cpp 的 &lt;code>quantize&lt;/code> 工具，這是少數需要直接面對 GGUF 內部的場景。&lt;/p></description><content:encoded><![CDATA[<p>GGUF（GGML Unified Format）的核心概念是「llama.cpp 系統定義的模型權重格式」，把模型權重、tokenizer 設定、模型 metadata 全部打包進單一檔案。Ollama 內部存的就是 GGUF，多數本地推論伺服器（除了走 <a href="/blog/llm/knowledge-cards/mlx/" data-link-title="MLX" data-link-desc="Apple 釋出的 Apple Silicon 數值運算 framework：類似 PyTorch / JAX 的 Mac 對應物">MLX</a> 路線的）也支援。</p>
<h2 id="概念位置">概念位置</h2>
<p>GGUF 屬於模型層的封裝格式，跟 Safetensors（Hugging Face 通用）、MLX format（Apple 生態）是平行的選擇。它的設計目標是「單一檔案、跨平台、支援多種<a href="/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">量化</a>等級」。Ollama、LM Studio、llama.cpp 都用 GGUF；想跑 MLX 系統的 oMLX 則要 MLX format 權重。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>Hugging Face 上 GGUF 檔案命名通常含量化標籤：</p>
<table>
  <thead>
      <tr>
          <th>檔名範例</th>
          <th>解讀</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>gemma-4-31b-it-Q4_K_M.gguf</code></td>
          <td>Gemma 4、31B、instruct-tuned、Q4_K_M 量化</td>
      </tr>
      <tr>
          <td><code>Llama-3.3-70B-Instruct-Q5_K_M.gguf</code></td>
          <td>Llama 3.3、70B、instruct、Q5_K_M</td>
      </tr>
      <tr>
          <td><code>qwen3-coder-30b-Q8_0.gguf</code></td>
          <td>Qwen3-Coder、30B、Q8 量化</td>
      </tr>
  </tbody>
</table>
<p>社群常見的高品質 GGUF 提供者有 <code>bartowski</code>、<code>unsloth</code>、<code>TheBloke</code>（已退坑）等；挑下載量高、最近更新的 repo 較安全。</p>
<h2 id="設計責任">設計責任</h2>
<p>直接下載 GGUF 多半用於 LM Studio 與 llama.cpp 場景。Ollama 使用者通常透過 <code>ollama pull</code> 拉模型，背後格式也是 GGUF、但細節對使用者透明。想自己量化模型（從 Safetensors 轉 GGUF）要用 llama.cpp 的 <code>quantize</code> 工具，這是少數需要直接面對 GGUF 內部的場景。</p>
]]></content:encoded></item><item><title>Inference Server</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/inference-server/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/inference-server/</guid><description>&lt;p>Inference Server（推論伺服器）的核心概念是「常駐在機器上、載入模型權重、接收 API 請求、跑推論、回傳生成內容的 process」。本地 LLM 三層架構中、推論伺服器位於介面層（CLI / IDE / Web UI）與模型層（權重檔）之間。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>推論伺服器封裝模型載入、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">量化&lt;/a>、&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> 管理、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">speculative decoding&lt;/a> 等推論細節、對外提供 HTTP API。多數本地推論伺服器同時提供 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/openai-compatible-api/" data-link-title="OpenAI 相容 API" data-link-desc="本地推論伺服器跟雲端 OpenAI 共用的 API 形狀標準">OpenAI 相容 API&lt;/a> 與自家原生 API。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>2026 年 5 月主流本地推論伺服器：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>伺服器&lt;/th>
 &lt;th>預設 port&lt;/th>
 &lt;th>內部引擎&lt;/th>
 &lt;th>適合誰&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Ollama&lt;/td>
 &lt;td>11434&lt;/td>
 &lt;td>llama.cpp&lt;/td>
 &lt;td>多數使用者的預設&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LM Studio&lt;/td>
 &lt;td>1234&lt;/td>
 &lt;td>llama.cpp + GUI&lt;/td>
 &lt;td>GUI 派、探索新模型&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>llama.cpp&lt;/td>
 &lt;td>8080&lt;/td>
 &lt;td>自己&lt;/td>
 &lt;td>進階使用者、特殊量化&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>oMLX&lt;/td>
 &lt;td>8000&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mlx/" data-link-title="MLX" data-link-desc="Apple 釋出的 Apple Silicon 數值運算 framework：類似 PyTorch / JAX 的 Mac 對應物">MLX&lt;/a>&lt;/td>
 &lt;td>長 context coding agent&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>並存可行：port 不同就不衝突、Continue.dev 等介面層可以同時設多個 model、各指向不同伺服器。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>選擇推論伺服器看三件事：是否提供 OpenAI 相容 API（影響能接哪些介面層）、模型格式支援（&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>、MLX format）、加速技巧支援（&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mtp/" data-link-title="Multi-Token Prediction (MTP)" data-link-desc="Google 為 Gemma 系列釋出的 speculative decoding 工程化實作">MTP&lt;/a> 等）。寫 code 場景的多數使用者用 Ollama 已足夠；其他選擇是針對特定需求的特化路徑。&lt;/p></description><content:encoded><![CDATA[<p>Inference Server（推論伺服器）的核心概念是「常駐在機器上、載入模型權重、接收 API 請求、跑推論、回傳生成內容的 process」。本地 LLM 三層架構中、推論伺服器位於介面層（CLI / IDE / Web UI）與模型層（權重檔）之間。</p>
<h2 id="概念位置">概念位置</h2>
<p>推論伺服器封裝模型載入、<a href="/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">量化</a>、<a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 管理、<a href="/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">speculative decoding</a> 等推論細節、對外提供 HTTP API。多數本地推論伺服器同時提供 <a href="/blog/llm/knowledge-cards/openai-compatible-api/" data-link-title="OpenAI 相容 API" data-link-desc="本地推論伺服器跟雲端 OpenAI 共用的 API 形狀標準">OpenAI 相容 API</a> 與自家原生 API。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>2026 年 5 月主流本地推論伺服器：</p>
<table>
  <thead>
      <tr>
          <th>伺服器</th>
          <th>預設 port</th>
          <th>內部引擎</th>
          <th>適合誰</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Ollama</td>
          <td>11434</td>
          <td>llama.cpp</td>
          <td>多數使用者的預設</td>
      </tr>
      <tr>
          <td>LM Studio</td>
          <td>1234</td>
          <td>llama.cpp + GUI</td>
          <td>GUI 派、探索新模型</td>
      </tr>
      <tr>
          <td>llama.cpp</td>
          <td>8080</td>
          <td>自己</td>
          <td>進階使用者、特殊量化</td>
      </tr>
      <tr>
          <td>oMLX</td>
          <td>8000</td>
          <td><a href="/blog/llm/knowledge-cards/mlx/" data-link-title="MLX" data-link-desc="Apple 釋出的 Apple Silicon 數值運算 framework：類似 PyTorch / JAX 的 Mac 對應物">MLX</a></td>
          <td>長 context coding agent</td>
      </tr>
  </tbody>
</table>
<p>並存可行：port 不同就不衝突、Continue.dev 等介面層可以同時設多個 model、各指向不同伺服器。</p>
<h2 id="設計責任">設計責任</h2>
<p>選擇推論伺服器看三件事：是否提供 OpenAI 相容 API（影響能接哪些介面層）、模型格式支援（<a href="/blog/llm/knowledge-cards/gguf/" data-link-title="GGUF" data-link-desc="llama.cpp 生態定義的模型權重格式：把權重、tokenizer、metadata 打包成單一檔案">GGUF</a>、MLX format）、加速技巧支援（<a href="/blog/llm/knowledge-cards/mtp/" data-link-title="Multi-Token Prediction (MTP)" data-link-desc="Google 為 Gemma 系列釋出的 speculative decoding 工程化實作">MTP</a> 等）。寫 code 場景的多數使用者用 Ollama 已足夠；其他選擇是針對特定需求的特化路徑。</p>
]]></content:encoded></item><item><title>Instruction-Tuned Model</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/instruction-tuned/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/instruction-tuned/</guid><description>&lt;p>Instruction-Tuned Model 的核心概念是「在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/base-model/" data-link-title="Base Model" data-link-desc="未經指令微調的原始模型：擅長文字接龍、適合下游微調用途">base model&lt;/a> 之上、用指令-回答對資料進一步微調」。微調目的是讓模型理解「使用者問 X、應該回答 Y」這種交互模式。寫 code 場景該用的就是 instruction-tuned 模型（多半標 &lt;code>-instruct&lt;/code> 或 &lt;code>-it&lt;/code>）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Instruction tuning 是 LLM 訓練 pipeline 的中間階段：base model（純文字接龍）→ instruction-tuned（會跟指令走）→ RLHF（進一步對齊人類偏好）。寫 code 用的 Gemma 4 31B、Qwen3-Coder 30B、Llama 3.3 70B 等都是 instruction-tuned 版本。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>Ollama tag 中的 &lt;code>instruct&lt;/code>、&lt;code>it&lt;/code> 是 instruction-tuned 標記：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>模型 tag&lt;/th>
 &lt;th>解讀&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;code>gemma4:31b-instruct-q5_K_M&lt;/code>&lt;/td>
 &lt;td>Gemma 4、instruct-tuned&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>llama3.3:70b-instruct-q4_K_M&lt;/code>&lt;/td>
 &lt;td>Llama 3.3、instruct-tuned&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>qwen3-coder:30b&lt;/code>&lt;/td>
 &lt;td>Qwen3-Coder（預設就是 instruct，未必額外標）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Coding-tuned 是 instruction-tuned 的特化版本，再加上大量 code 訓練資料；Qwen3-Coder、Gemma 4 coding 版本都屬於這類。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>寫 code 場景的預設選擇是 instruction-tuned + coding-specialized 模型。看到 Ollama tag 沒有 &lt;code>instruct&lt;/code> 字樣（如 &lt;code>llama3.3:70b-base&lt;/code>）的版本、那是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/base-model/" data-link-title="Base Model" data-link-desc="未經指令微調的原始模型：擅長文字接龍、適合下游微調用途">base model&lt;/a>、跟指令走的能力較差、適合下游微調而非直接對話。&lt;/p></description><content:encoded><![CDATA[<p>Instruction-Tuned Model 的核心概念是「在 <a href="/blog/llm/knowledge-cards/base-model/" data-link-title="Base Model" data-link-desc="未經指令微調的原始模型：擅長文字接龍、適合下游微調用途">base model</a> 之上、用指令-回答對資料進一步微調」。微調目的是讓模型理解「使用者問 X、應該回答 Y」這種交互模式。寫 code 場景該用的就是 instruction-tuned 模型（多半標 <code>-instruct</code> 或 <code>-it</code>）。</p>
<h2 id="概念位置">概念位置</h2>
<p>Instruction tuning 是 LLM 訓練 pipeline 的中間階段：base model（純文字接龍）→ instruction-tuned（會跟指令走）→ RLHF（進一步對齊人類偏好）。寫 code 用的 Gemma 4 31B、Qwen3-Coder 30B、Llama 3.3 70B 等都是 instruction-tuned 版本。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>Ollama tag 中的 <code>instruct</code>、<code>it</code> 是 instruction-tuned 標記：</p>
<table>
  <thead>
      <tr>
          <th>模型 tag</th>
          <th>解讀</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>gemma4:31b-instruct-q5_K_M</code></td>
          <td>Gemma 4、instruct-tuned</td>
      </tr>
      <tr>
          <td><code>llama3.3:70b-instruct-q4_K_M</code></td>
          <td>Llama 3.3、instruct-tuned</td>
      </tr>
      <tr>
          <td><code>qwen3-coder:30b</code></td>
          <td>Qwen3-Coder（預設就是 instruct，未必額外標）</td>
      </tr>
  </tbody>
</table>
<p>Coding-tuned 是 instruction-tuned 的特化版本，再加上大量 code 訓練資料；Qwen3-Coder、Gemma 4 coding 版本都屬於這類。</p>
<h2 id="設計責任">設計責任</h2>
<p>寫 code 場景的預設選擇是 instruction-tuned + coding-specialized 模型。看到 Ollama tag 沒有 <code>instruct</code> 字樣（如 <code>llama3.3:70b-base</code>）的版本、那是 <a href="/blog/llm/knowledge-cards/base-model/" data-link-title="Base Model" data-link-desc="未經指令微調的原始模型：擅長文字接龍、適合下游微調用途">base model</a>、跟指令走的能力較差、適合下游微調而非直接對話。</p>
]]></content:encoded></item><item><title>KV Cache</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/kv-cache/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/kv-cache/</guid><description>&lt;p>KV Cache 的核心概念是「LLM 推論過程中、把已處理過的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a> 的 attention key / value 暫存起來、後續 token 生成時直接讀」。它讓「已 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prefill/" data-link-title="Prefill" data-link-desc="Prompt 首次處理時的計算階段：把整段輸入跑過模型、產生 KV cache">prefill&lt;/a> 過的 prompt」省下重複計算，是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">autoregressive&lt;/a> 模型能跑得起來的關鍵優化。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>KV cache 存在於記憶體中，大小跟 prompt 長度線性增加。它跟模型權重一起佔用記憶體預算；長 &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>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>Gemma 4 31B（Q4 量化）的 KV cache 估算：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Context 長度&lt;/th>
 &lt;th>KV Cache 估算&lt;/th>
 &lt;th>加上模型權重總和&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>1K tokens&lt;/td>
 &lt;td>~0.5 GB&lt;/td>
 &lt;td>18.5 GB&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>4K tokens&lt;/td>
 &lt;td>~2 GB&lt;/td>
 &lt;td>20 GB&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>16K tokens&lt;/td>
 &lt;td>~8 GB&lt;/td>
 &lt;td>26 GB&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>32K tokens&lt;/td>
 &lt;td>~16 GB&lt;/td>
 &lt;td>34 GB（32GB Mac 開始 swap）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>32GB Mac 跑 31B 模型實際可用 context 大約 8 ~ 16K tokens；超過就需要 swap、速度崩潰。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 KV cache 後可以解釋兩個現象：為何長 context 不只 TTFT 高、還會吃爆記憶體；為何 oMLX 的「paged SSD KV cache」對 coding agent 場景很有用（把 cache 推到 SSD，跨 session 復用同前綴的 prefill 結果）。設定本地伺服器時，留意 context 長度與記憶體預算的乘積、避免無意間踩到 swap。&lt;/p></description><content:encoded><![CDATA[<p>KV Cache 的核心概念是「LLM 推論過程中、把已處理過的 <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a> 的 attention key / value 暫存起來、後續 token 生成時直接讀」。它讓「已 <a href="/blog/llm/knowledge-cards/prefill/" data-link-title="Prefill" data-link-desc="Prompt 首次處理時的計算階段：把整段輸入跑過模型、產生 KV cache">prefill</a> 過的 prompt」省下重複計算，是 <a href="/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">autoregressive</a> 模型能跑得起來的關鍵優化。</p>
<h2 id="概念位置">概念位置</h2>
<p>KV cache 存在於記憶體中，大小跟 prompt 長度線性增加。它跟模型權重一起佔用記憶體預算；長 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a> 場景的 KV cache 可能比模型權重本身還大。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>Gemma 4 31B（Q4 量化）的 KV cache 估算：</p>
<table>
  <thead>
      <tr>
          <th>Context 長度</th>
          <th>KV Cache 估算</th>
          <th>加上模型權重總和</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1K tokens</td>
          <td>~0.5 GB</td>
          <td>18.5 GB</td>
      </tr>
      <tr>
          <td>4K tokens</td>
          <td>~2 GB</td>
          <td>20 GB</td>
      </tr>
      <tr>
          <td>16K tokens</td>
          <td>~8 GB</td>
          <td>26 GB</td>
      </tr>
      <tr>
          <td>32K tokens</td>
          <td>~16 GB</td>
          <td>34 GB（32GB Mac 開始 swap）</td>
      </tr>
  </tbody>
</table>
<p>32GB Mac 跑 31B 模型實際可用 context 大約 8 ~ 16K tokens；超過就需要 swap、速度崩潰。</p>
<h2 id="設計責任">設計責任</h2>
<p>理解 KV cache 後可以解釋兩個現象：為何長 context 不只 TTFT 高、還會吃爆記憶體；為何 oMLX 的「paged SSD KV cache」對 coding agent 場景很有用（把 cache 推到 SSD，跨 session 復用同前綴的 prefill 結果）。設定本地伺服器時，留意 context 長度與記憶體預算的乘積、避免無意間踩到 swap。</p>
]]></content:encoded></item><item><title>LLM Agent</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/agent/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/agent/</guid><description>&lt;p>LLM Agent 的核心概念是「把控制流的所有權從人類交給 LLM」。傳統對話 LLM 是「人類問、模型答」、每輪 turn 獨立；agent 是「LLM 自己決定下一步、自己呼叫工具、自己評估結果」、跨多步累積 context。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Agent 是應用層的工作流模式、建立在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">tool use&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/function-calling/" data-link-title="Function Calling" data-link-desc="模型訓練階段建立的「呼叫工具」能力：知道何時該呼叫、傳什麼參數">function calling&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">structured output&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">autoregressive&lt;/a> 生成之上。Agent loop 五步骨架（感知 → 推理 → 行動 → 觀察 → 判斷終止）是所有 agent framework 的共通結構、不論具體實作。本地 LLM 受 tool use 訓練不足、長 context prefill 痛點（見 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prefill/" data-link-title="Prefill" data-link-desc="Prompt 首次處理時的計算階段：把整段輸入跑過模型、產生 KV cache">prefill&lt;/a>）、規劃能力弱等限制、跑 agent 現階段失敗率高於雲端旗艦。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>寫 code 場景的代表 agent：aider、Cline、Cursor Agent。判讀 agent 失敗訊號分三類：&lt;strong>context drift&lt;/strong>（累積偏離原目標）、&lt;strong>目標漂移&lt;/strong>（子目標完成就停、原任務沒完成）、&lt;strong>tool 結果誤判&lt;/strong>（tool 回 error 模型 hallucinate「成功」繼續推）。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>決定該用 agent 還是 single-call、看任務是否有明確子步驟 + 客觀驗證訊號（test 通過、file 寫入）。模糊探索性任務不適合 agent。Agent 跑高風險任務時、人類審查粒度應該配合工具的副作用範圍——可逆任務全自動、不可逆任務 step-by-step approval。詳細展開見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/agent-architecture/" data-link-title="4.4 Agent 架構原理" data-link-desc="Agent loop 結構、失敗模式、什麼任務適合 vs 不適合、跟人類審查的協作模型">4.4 Agent 架構原理&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>LLM Agent 的核心概念是「把控制流的所有權從人類交給 LLM」。傳統對話 LLM 是「人類問、模型答」、每輪 turn 獨立；agent 是「LLM 自己決定下一步、自己呼叫工具、自己評估結果」、跨多步累積 context。</p>
<h2 id="概念位置">概念位置</h2>
<p>Agent 是應用層的工作流模式、建立在 <a href="/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">tool use</a>、<a href="/blog/llm/knowledge-cards/function-calling/" data-link-title="Function Calling" data-link-desc="模型訓練階段建立的「呼叫工具」能力：知道何時該呼叫、傳什麼參數">function calling</a>、<a href="/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">structured output</a>、<a href="/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">autoregressive</a> 生成之上。Agent loop 五步骨架（感知 → 推理 → 行動 → 觀察 → 判斷終止）是所有 agent framework 的共通結構、不論具體實作。本地 LLM 受 tool use 訓練不足、長 context prefill 痛點（見 <a href="/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT</a>、<a href="/blog/llm/knowledge-cards/prefill/" data-link-title="Prefill" data-link-desc="Prompt 首次處理時的計算階段：把整段輸入跑過模型、產生 KV cache">prefill</a>）、規劃能力弱等限制、跑 agent 現階段失敗率高於雲端旗艦。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>寫 code 場景的代表 agent：aider、Cline、Cursor Agent。判讀 agent 失敗訊號分三類：<strong>context drift</strong>（累積偏離原目標）、<strong>目標漂移</strong>（子目標完成就停、原任務沒完成）、<strong>tool 結果誤判</strong>（tool 回 error 模型 hallucinate「成功」繼續推）。</p>
<h2 id="設計責任">設計責任</h2>
<p>決定該用 agent 還是 single-call、看任務是否有明確子步驟 + 客觀驗證訊號（test 通過、file 寫入）。模糊探索性任務不適合 agent。Agent 跑高風險任務時、人類審查粒度應該配合工具的副作用範圍——可逆任務全自動、不可逆任務 step-by-step approval。詳細展開見 <a href="/blog/llm/04-applications/agent-architecture/" data-link-title="4.4 Agent 架構原理" data-link-desc="Agent loop 結構、失敗模式、什麼任務適合 vs 不適合、跟人類審查的協作模型">4.4 Agent 架構原理</a>。</p>
]]></content:encoded></item><item><title>MCP（Model Context Protocol）</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/mcp/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/mcp/</guid><description>&lt;p>MCP（Model Context Protocol、2024 年由 Anthropic 提出）的核心概念是「LLM application 跟外部 tool server 之間的標準化協議」。它解的是 LLM application 生態的 N×M 整合問題：N 個 application 接 M 個 tool、不標準化要寫 N×M 個 adapter；MCP 把這個成本拆成 N+M（application 端跟 server 端各實作協議一次）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>MCP 在&lt;strong>架構協議&lt;/strong>層、跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/function-calling/" data-link-title="Function Calling" data-link-desc="模型訓練階段建立的「呼叫工具」能力：知道何時該呼叫、傳什麼參數">function calling&lt;/a>（模型能力層）、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">structured output&lt;/a>（&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/sampling-constraint/" data-link-title="Sampling Constraint" data-link-desc="推論時限制下一個 token 候選集合的控制手段，用來把模型生成導向合法格式或特定選項">sampling 約束&lt;/a>層）正交。它跟模型怎麼呼叫工具無關、只管「工具怎麼被暴露給 application」。複用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/openai-compatible-api/" data-link-title="OpenAI 相容 API" data-link-desc="本地推論伺服器跟雲端 OpenAI 共用的 API 形狀標準">OpenAI 相容 API&lt;/a> 的標準化模式：定義最小可用標準、讓生態繞著標準長、所有 player 受益。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>MCP 涵蓋 server 該提供什麼：tool 註冊、tool schema、tool 呼叫協議、resource 暴露、prompt template 共享。2026/5 主要 LLM application（Claude Desktop、Cursor 等）支援 MCP；社群維護的 MCP server 數量快速增長（檔案系統、Git、Slack、各種 API 等）；本地推論伺服器（Ollama、LM Studio）仍以 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/openai-compatible-api/" data-link-title="OpenAI 相容 API" data-link-desc="本地推論伺服器跟雲端 OpenAI 共用的 API 形狀標準">OpenAI 相容 API&lt;/a> 為主、MCP 接入較慢。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>需不需要用 MCP 看應用規模：小型 in-process 應用（直接 Python function）用 function calling + 簡單 dispatcher 就夠、不需 MCP。要跨 application 共用 tool、或想接入既有 MCP server 生態（如標準化的 git / filesystem tools）才需要 MCP。詳細展開見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/application-protocols/" data-link-title="4.6 應用層協議：function calling / structured output / MCP" data-link-desc="三個常被混為一談的概念：模型能力、sampling 約束、server 協議，三者的層級差異與組合方式">4.6 應用層協議&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>MCP（Model Context Protocol、2024 年由 Anthropic 提出）的核心概念是「LLM application 跟外部 tool server 之間的標準化協議」。它解的是 LLM application 生態的 N×M 整合問題：N 個 application 接 M 個 tool、不標準化要寫 N×M 個 adapter；MCP 把這個成本拆成 N+M（application 端跟 server 端各實作協議一次）。</p>
<h2 id="概念位置">概念位置</h2>
<p>MCP 在<strong>架構協議</strong>層、跟 <a href="/blog/llm/knowledge-cards/function-calling/" data-link-title="Function Calling" data-link-desc="模型訓練階段建立的「呼叫工具」能力：知道何時該呼叫、傳什麼參數">function calling</a>（模型能力層）、<a href="/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">structured output</a>（<a href="/blog/llm/knowledge-cards/sampling-constraint/" data-link-title="Sampling Constraint" data-link-desc="推論時限制下一個 token 候選集合的控制手段，用來把模型生成導向合法格式或特定選項">sampling 約束</a>層）正交。它跟模型怎麼呼叫工具無關、只管「工具怎麼被暴露給 application」。複用 <a href="/blog/llm/knowledge-cards/openai-compatible-api/" data-link-title="OpenAI 相容 API" data-link-desc="本地推論伺服器跟雲端 OpenAI 共用的 API 形狀標準">OpenAI 相容 API</a> 的標準化模式：定義最小可用標準、讓生態繞著標準長、所有 player 受益。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>MCP 涵蓋 server 該提供什麼：tool 註冊、tool schema、tool 呼叫協議、resource 暴露、prompt template 共享。2026/5 主要 LLM application（Claude Desktop、Cursor 等）支援 MCP；社群維護的 MCP server 數量快速增長（檔案系統、Git、Slack、各種 API 等）；本地推論伺服器（Ollama、LM Studio）仍以 <a href="/blog/llm/knowledge-cards/openai-compatible-api/" data-link-title="OpenAI 相容 API" data-link-desc="本地推論伺服器跟雲端 OpenAI 共用的 API 形狀標準">OpenAI 相容 API</a> 為主、MCP 接入較慢。</p>
<h2 id="設計責任">設計責任</h2>
<p>需不需要用 MCP 看應用規模：小型 in-process 應用（直接 Python function）用 function calling + 簡單 dispatcher 就夠、不需 MCP。要跨 application 共用 tool、或想接入既有 MCP server 生態（如標準化的 git / filesystem tools）才需要 MCP。詳細展開見 <a href="/blog/llm/04-applications/application-protocols/" data-link-title="4.6 應用層協議：function calling / structured output / MCP" data-link-desc="三個常被混為一談的概念：模型能力、sampling 約束、server 協議，三者的層級差異與組合方式">4.6 應用層協議</a>。</p>
]]></content:encoded></item><item><title>Memory Bandwidth</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/memory-bandwidth/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/memory-bandwidth/</guid><description>&lt;p>Memory Bandwidth（記憶體頻寬）的核心概念是「每秒能從記憶體讀寫多少 bytes」。對 LLM 推論而言、它是「真正的瓶頸」、決定 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/tokens-per-second/" data-link-title="Tokens Per Second" data-link-desc="LLM 每秒能生成幾個 token：生字速度的標準量化指標">tokens per second&lt;/a> 的理論上限；CPU / GPU 算力反而很少成為瓶頸。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">Autoregressive&lt;/a> 模型每生一個 token 都要把整個模型權重從記憶體讀到處理器一次。模型多大、頻寬多快、決定每秒能讀過幾次完整權重、也就決定每秒生幾個 token。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>各代 Apple Silicon 的記憶體頻寬：&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>M2 / M3&lt;/td>
 &lt;td>100 GB/s&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>M2 Pro&lt;/td>
 &lt;td>200 GB/s&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>M4 Max&lt;/td>
 &lt;td>546 GB/s&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>M2 / M3 Ultra&lt;/td>
 &lt;td>800+ GB/s&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>H100（雲端）&lt;/td>
 &lt;td>3,300 GB/s&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>理論上限算式：&lt;code>頻寬 / 模型大小 = 最大 tok/s&lt;/code>。M4 Max 跑 Q4 量化的 31B 模型（約 18GB）、理論上限約 546 / 18 ≈ 30 tok/s。實際值會比理論低 30 ~ 50%（&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;/p>
&lt;p>H100 頻寬是 M4 Max 的 6 倍、這就是雲端旗艦速度比本地快這麼多的根本原因。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>評估「換更快 Mac 能加速多少」要看頻寬而不是 CPU 核心數。M2 升 M4 Max 對 LLM 推論的速度收益主要來自頻寬升級（200 → 546 GB/s）、約 2.7 倍。看到「N 倍加速」報導時、把頻寬與模型大小代進公式對一下、能識破不合理的數字。&lt;/p></description><content:encoded><![CDATA[<p>Memory Bandwidth（記憶體頻寬）的核心概念是「每秒能從記憶體讀寫多少 bytes」。對 LLM 推論而言、它是「真正的瓶頸」、決定 <a href="/blog/llm/knowledge-cards/tokens-per-second/" data-link-title="Tokens Per Second" data-link-desc="LLM 每秒能生成幾個 token：生字速度的標準量化指標">tokens per second</a> 的理論上限；CPU / GPU 算力反而很少成為瓶頸。</p>
<h2 id="概念位置">概念位置</h2>
<p><a href="/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">Autoregressive</a> 模型每生一個 token 都要把整個模型權重從記憶體讀到處理器一次。模型多大、頻寬多快、決定每秒能讀過幾次完整權重、也就決定每秒生幾個 token。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>各代 Apple Silicon 的記憶體頻寬：</p>
<table>
  <thead>
      <tr>
          <th>晶片</th>
          <th>頻寬</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>M2 / M3</td>
          <td>100 GB/s</td>
      </tr>
      <tr>
          <td>M2 Pro</td>
          <td>200 GB/s</td>
      </tr>
      <tr>
          <td>M4 Max</td>
          <td>546 GB/s</td>
      </tr>
      <tr>
          <td>M2 / M3 Ultra</td>
          <td>800+ GB/s</td>
      </tr>
      <tr>
          <td>H100（雲端）</td>
          <td>3,300 GB/s</td>
      </tr>
  </tbody>
</table>
<p>理論上限算式：<code>頻寬 / 模型大小 = 最大 tok/s</code>。M4 Max 跑 Q4 量化的 31B 模型（約 18GB）、理論上限約 546 / 18 ≈ 30 tok/s。實際值會比理論低 30 ~ 50%（<a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 讀寫、attention 中間結果等開銷）。</p>
<p>H100 頻寬是 M4 Max 的 6 倍、這就是雲端旗艦速度比本地快這麼多的根本原因。</p>
<h2 id="設計責任">設計責任</h2>
<p>評估「換更快 Mac 能加速多少」要看頻寬而不是 CPU 核心數。M2 升 M4 Max 對 LLM 推論的速度收益主要來自頻寬升級（200 → 546 GB/s）、約 2.7 倍。看到「N 倍加速」報導時、把頻寬與模型大小代進公式對一下、能識破不合理的數字。</p>
]]></content:encoded></item><item><title>MLX</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/mlx/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/mlx/</guid><description>&lt;p>MLX（Machine Learning eXchange）的核心概念是「Apple 為 Apple Silicon 設計的數值運算 framework」，2023 年由 Apple 釋出。它提供 Python API、自動排程 CPU / GPU / Neural Engine、利用&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/unified-memory/" data-link-title="Unified Memory Architecture" data-link-desc="Apple Silicon 讓 CPU / GPU / NE 共用同一塊記憶體：跑大模型的優勢來源">統一記憶體架構&lt;/a>避免在不同記憶體層之間搬資料。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>MLX 屬於基底設施層、跟 PyTorch、JAX、NumPy 並列、是「跑神經網路用的底層數值庫」。它本身不是&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/inference-server/" data-link-title="Inference Server" data-link-desc="載入模型權重、處理 prompt、產生 token 的常駐 process">推論伺服器&lt;/a>、不是模型、也不是加速技巧；上層工具站在 MLX 這塊地基上做封裝。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>通用世界&lt;/th>
 &lt;th>Apple 世界&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>PyTorch / JAX&lt;/td>
 &lt;td>MLX&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>CUDA&lt;/td>
 &lt;td>Metal（MLX 在 GPU 上經 Metal）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>NumPy&lt;/td>
 &lt;td>&lt;code>mlx.core&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Transformers&lt;/td>
 &lt;td>&lt;code>mlx-lm&lt;/code>、&lt;code>mlx-community&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>直接用 MLX 跑模型：&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">pip install mlx-lm
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">mlx_lm.generate --model mlx-community/Llama-3.2-3B-Instruct-4bit --prompt &lt;span class="s2">&amp;#34;hi&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>這段命令會載入 MLX format 權重、用 MLX framework 在 Apple Silicon 上跑推論。需要再 wrap 成 HTTP server 才能讓 IDE 連、&lt;code>mlx_lm.server&lt;/code> 是輕量選擇、oMLX 是建在 MLX 之上的完整推論伺服器。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>寫 code 場景的多數使用者透過 Ollama（用 llama.cpp 當引擎、跟 MLX 無關）、體驗已足夠。直接用 MLX 適合三種情境：想跑 Apple 釋出的 MLX format 模型、想用 MLX 寫研究 code、想試 MLX backend 的推論伺服器（oMLX）。看到「Ollama 用 MLX 加速」這類說法時、回到本卡確認 Ollama 內部 backend 是 llama.cpp 而非 MLX。&lt;/p></description><content:encoded><![CDATA[<p>MLX（Machine Learning eXchange）的核心概念是「Apple 為 Apple Silicon 設計的數值運算 framework」，2023 年由 Apple 釋出。它提供 Python API、自動排程 CPU / GPU / Neural Engine、利用<a href="/blog/llm/knowledge-cards/unified-memory/" data-link-title="Unified Memory Architecture" data-link-desc="Apple Silicon 讓 CPU / GPU / NE 共用同一塊記憶體：跑大模型的優勢來源">統一記憶體架構</a>避免在不同記憶體層之間搬資料。</p>
<h2 id="概念位置">概念位置</h2>
<p>MLX 屬於基底設施層、跟 PyTorch、JAX、NumPy 並列、是「跑神經網路用的底層數值庫」。它本身不是<a href="/blog/llm/knowledge-cards/inference-server/" data-link-title="Inference Server" data-link-desc="載入模型權重、處理 prompt、產生 token 的常駐 process">推論伺服器</a>、不是模型、也不是加速技巧；上層工具站在 MLX 這塊地基上做封裝。</p>
<table>
  <thead>
      <tr>
          <th>通用世界</th>
          <th>Apple 世界</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>PyTorch / JAX</td>
          <td>MLX</td>
      </tr>
      <tr>
          <td>CUDA</td>
          <td>Metal（MLX 在 GPU 上經 Metal）</td>
      </tr>
      <tr>
          <td>NumPy</td>
          <td><code>mlx.core</code></td>
      </tr>
      <tr>
          <td>Transformers</td>
          <td><code>mlx-lm</code>、<code>mlx-community</code></td>
      </tr>
  </tbody>
</table>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>直接用 MLX 跑模型：</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">pip install mlx-lm
</span></span><span class="line"><span class="ln">2</span><span class="cl">mlx_lm.generate --model mlx-community/Llama-3.2-3B-Instruct-4bit --prompt <span class="s2">&#34;hi&#34;</span></span></span></code></pre></div><p>這段命令會載入 MLX format 權重、用 MLX framework 在 Apple Silicon 上跑推論。需要再 wrap 成 HTTP server 才能讓 IDE 連、<code>mlx_lm.server</code> 是輕量選擇、oMLX 是建在 MLX 之上的完整推論伺服器。</p>
<h2 id="設計責任">設計責任</h2>
<p>寫 code 場景的多數使用者透過 Ollama（用 llama.cpp 當引擎、跟 MLX 無關）、體驗已足夠。直接用 MLX 適合三種情境：想跑 Apple 釋出的 MLX format 模型、想用 MLX 寫研究 code、想試 MLX backend 的推論伺服器（oMLX）。看到「Ollama 用 MLX 加速」這類說法時、回到本卡確認 Ollama 內部 backend 是 llama.cpp 而非 MLX。</p>
]]></content:encoded></item><item><title>Multi-Token Prediction (MTP)</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/mtp/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/mtp/</guid><description>&lt;p>Multi-Token Prediction（MTP）的核心概念是「&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">speculative decoding&lt;/a> 的工程化實作」，特指 Google 為 Gemma 4 釋出的官方版本。它包含預訓練好的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/drafter-model/" data-link-title="Drafter Model" data-link-desc="speculative decoding 中用來快速猜未來 token 的小模型">drafter&lt;/a>、target 模型整合、以及優化過的推論流程。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>MTP 屬於模型推論優化層、跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">autoregressive&lt;/a> 基底並列。它是技巧、不是模型架構、也不是 framework；任何推論伺服器都可以選擇實作或忽略 MTP、模型可以選擇有沒有官方 drafter。三件事彼此獨立。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>2026 年 5 月 MTP 在各推論伺服器的支援狀態：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>伺服器&lt;/th>
 &lt;th>Gemma 4 MTP 支援&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Ollama&lt;/td>
 &lt;td>v0.23.1（2026/5/7）一鍵支援&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LM Studio&lt;/td>
 &lt;td>支援、需手動配置 draft model&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>llama.cpp&lt;/td>
 &lt;td>speculative decoding 框架在 beta、Gemma 4 官方 drafter 整合仍是 feature request&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>oMLX&lt;/td>
 &lt;td>支援&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>啟用 MTP 的速度收益主要在寫 code 場景。Google 官方數據 coding 任務 2 ~ 3 倍加速；純文字寫作、創意任務的加速幅度約 1.5 ~ 2 倍、因為 pattern 預測度較低。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>寫 code 場景的多數使用者透過 Ollama 一行啟用 MTP：&lt;code>ollama run gemma4:31b-coding-mtp-bf16&lt;/code>。看到「N 倍加速」報導時要追問來源與任務：官方 Google 數據是 2 ~ 3 倍；「40%」這類數字常常來源不明、可能是社群文章作者的估算。判讀加速幅度時、回到&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mtp/" data-link-title="Multi-Token Prediction (MTP)" data-link-desc="Google 為 Gemma 系列釋出的 speculative decoding 工程化實作">本卡&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">speculative decoding&lt;/a> 的官方來源比對。&lt;/p></description><content:encoded><![CDATA[<p>Multi-Token Prediction（MTP）的核心概念是「<a href="/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">speculative decoding</a> 的工程化實作」，特指 Google 為 Gemma 4 釋出的官方版本。它包含預訓練好的 <a href="/blog/llm/knowledge-cards/drafter-model/" data-link-title="Drafter Model" data-link-desc="speculative decoding 中用來快速猜未來 token 的小模型">drafter</a>、target 模型整合、以及優化過的推論流程。</p>
<h2 id="概念位置">概念位置</h2>
<p>MTP 屬於模型推論優化層、跟 <a href="/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">autoregressive</a> 基底並列。它是技巧、不是模型架構、也不是 framework；任何推論伺服器都可以選擇實作或忽略 MTP、模型可以選擇有沒有官方 drafter。三件事彼此獨立。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>2026 年 5 月 MTP 在各推論伺服器的支援狀態：</p>
<table>
  <thead>
      <tr>
          <th>伺服器</th>
          <th>Gemma 4 MTP 支援</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Ollama</td>
          <td>v0.23.1（2026/5/7）一鍵支援</td>
      </tr>
      <tr>
          <td>LM Studio</td>
          <td>支援、需手動配置 draft model</td>
      </tr>
      <tr>
          <td>llama.cpp</td>
          <td>speculative decoding 框架在 beta、Gemma 4 官方 drafter 整合仍是 feature request</td>
      </tr>
      <tr>
          <td>oMLX</td>
          <td>支援</td>
      </tr>
  </tbody>
</table>
<p>啟用 MTP 的速度收益主要在寫 code 場景。Google 官方數據 coding 任務 2 ~ 3 倍加速；純文字寫作、創意任務的加速幅度約 1.5 ~ 2 倍、因為 pattern 預測度較低。</p>
<h2 id="設計責任">設計責任</h2>
<p>寫 code 場景的多數使用者透過 Ollama 一行啟用 MTP：<code>ollama run gemma4:31b-coding-mtp-bf16</code>。看到「N 倍加速」報導時要追問來源與任務：官方 Google 數據是 2 ~ 3 倍；「40%」這類數字常常來源不明、可能是社群文章作者的估算。判讀加速幅度時、回到<a href="/blog/llm/knowledge-cards/mtp/" data-link-title="Multi-Token Prediction (MTP)" data-link-desc="Google 為 Gemma 系列釋出的 speculative decoding 工程化實作">本卡</a> 與 <a href="/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">speculative decoding</a> 的官方來源比對。</p>
]]></content:encoded></item><item><title>OpenAI 相容 API</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/openai-compatible-api/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/openai-compatible-api/</guid><description>&lt;p>OpenAI 相容 API 的核心概念是「實作 OpenAI 在 2023 年定義的 &lt;code>POST /v1/chat/completions&lt;/code> 介面、讓介面層工具不改一行 code 就能切換本地與雲端」。它是事實標準、後來幾乎所有本地&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/inference-server/" data-link-title="Inference Server" data-link-desc="載入模型權重、處理 prompt、產生 token 的常駐 process">推論伺服器&lt;/a>都實作這份規格。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>OpenAI 相容 API 是介面層與伺服器層之間的標準介面。它承諾 API 形狀（request / response schema、streaming 格式、錯誤碼）一致；對「模型能力」「效能特性」「進階參數」等不承諾等價。本地 Gemma 4 跟雲端 GPT-5 都能用同一套 API 呼叫、但回答品質天差地遠。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>最小可用請求：&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">curl http://localhost:11434/v1/chat/completions &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="se">&lt;/span> -H &lt;span class="s2">&amp;#34;Content-Type: application/json&amp;#34;&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="se">&lt;/span> -d &lt;span class="s1">&amp;#39;{
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="s1"> &amp;#34;model&amp;#34;: &amp;#34;gemma4:31b-coding-mtp-bf16&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">&lt;span class="s1"> &amp;#34;messages&amp;#34;: [{&amp;#34;role&amp;#34;: &amp;#34;user&amp;#34;, &amp;#34;content&amp;#34;: &amp;#34;Hello&amp;#34;}],
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">&lt;span class="s1"> &amp;#34;stream&amp;#34;: false
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">&lt;span class="s1"> }&amp;#39;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>切換本地與雲端只改三個欄位：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>欄位&lt;/th>
 &lt;th>雲端 OpenAI&lt;/th>
 &lt;th>本地 Ollama&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>API base&lt;/td>
 &lt;td>&lt;code>https://api.openai.com/v1&lt;/code>&lt;/td>
 &lt;td>&lt;code>http://localhost:11434/v1&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>API key&lt;/td>
 &lt;td>&lt;code>sk-xxxxxxx&lt;/code>&lt;/td>
 &lt;td>任意字串、本地多半略過驗證&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Model name&lt;/td>
 &lt;td>&lt;code>gpt-5&lt;/code>&lt;/td>
 &lt;td>本地 model tag&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>進階功能參差不齊：&lt;code>response_format&lt;/code>、&lt;code>tool_choice&lt;/code>、reasoning effort 等在本地伺服器的支援度視模型而定；雲端有的功能、本地未必能用。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>寫程式接 LLM 時、把 OpenAI 相容當預設選擇。多家 SDK（OpenAI Python SDK、Vercel AI SDK 等）都支援設定 &lt;code>base_url&lt;/code>、改 endpoint 就能接本地。寫 IDE plugin 或 CLI 工具時、優先支援這份 API、能同時跟雲端、Ollama、LM Studio、llama.cpp、oMLX 對接。&lt;/p></description><content:encoded><![CDATA[<p>OpenAI 相容 API 的核心概念是「實作 OpenAI 在 2023 年定義的 <code>POST /v1/chat/completions</code> 介面、讓介面層工具不改一行 code 就能切換本地與雲端」。它是事實標準、後來幾乎所有本地<a href="/blog/llm/knowledge-cards/inference-server/" data-link-title="Inference Server" data-link-desc="載入模型權重、處理 prompt、產生 token 的常駐 process">推論伺服器</a>都實作這份規格。</p>
<h2 id="概念位置">概念位置</h2>
<p>OpenAI 相容 API 是介面層與伺服器層之間的標準介面。它承諾 API 形狀（request / response schema、streaming 格式、錯誤碼）一致；對「模型能力」「效能特性」「進階參數」等不承諾等價。本地 Gemma 4 跟雲端 GPT-5 都能用同一套 API 呼叫、但回答品質天差地遠。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>最小可用請求：</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">curl http://localhost:11434/v1/chat/completions <span class="se">\
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="se"></span>  -H <span class="s2">&#34;Content-Type: application/json&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="se"></span>  -d <span class="s1">&#39;{
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="s1">    &#34;model&#34;: &#34;gemma4:31b-coding-mtp-bf16&#34;,
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="s1">    &#34;messages&#34;: [{&#34;role&#34;: &#34;user&#34;, &#34;content&#34;: &#34;Hello&#34;}],
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="s1">    &#34;stream&#34;: false
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="s1">  }&#39;</span></span></span></code></pre></div><p>切換本地與雲端只改三個欄位：</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>雲端 OpenAI</th>
          <th>本地 Ollama</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>API base</td>
          <td><code>https://api.openai.com/v1</code></td>
          <td><code>http://localhost:11434/v1</code></td>
      </tr>
      <tr>
          <td>API key</td>
          <td><code>sk-xxxxxxx</code></td>
          <td>任意字串、本地多半略過驗證</td>
      </tr>
      <tr>
          <td>Model name</td>
          <td><code>gpt-5</code></td>
          <td>本地 model tag</td>
      </tr>
  </tbody>
</table>
<p>進階功能參差不齊：<code>response_format</code>、<code>tool_choice</code>、reasoning effort 等在本地伺服器的支援度視模型而定；雲端有的功能、本地未必能用。</p>
<h2 id="設計責任">設計責任</h2>
<p>寫程式接 LLM 時、把 OpenAI 相容當預設選擇。多家 SDK（OpenAI Python SDK、Vercel AI SDK 等）都支援設定 <code>base_url</code>、改 endpoint 就能接本地。寫 IDE plugin 或 CLI 工具時、優先支援這份 API、能同時跟雲端、Ollama、LM Studio、llama.cpp、oMLX 對接。</p>
]]></content:encoded></item><item><title>Prefill</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/prefill/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/prefill/</guid><description>&lt;p>Prefill 的核心概念是「&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">LLM 首次處理 prompt 時、把整段輸入跑過模型一次的計算階段&lt;/a>」。Prefill 階段會為 prompt 中每個 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a> 算出 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>，之後生成新 token 時可以直接讀 cache。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Prefill 是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT&lt;/a> 的主要構成部分。Prefill 結束後系統進入 decode 階段、開始一個一個生 token。兩階段的瓶頸不同：prefill 是「算力 bound」（並行處理整段 prompt）、decode 是「記憶體頻寬 bound」。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>短 prompt（500 tokens）：prefill 通常 &amp;lt; 1 秒、感覺不到。&lt;/p>
&lt;p>中等 prompt（4K tokens）：M4 Max 跑 31B 模型約 3 ~ 8 秒、開始有感。&lt;/p>
&lt;p>長 prompt（10K+ tokens）：本地 prefill 拉到 30 ~ 90 秒、是 coding agent 場景最痛的點。&lt;/p>
&lt;p>雲端旗艦 prefill 速度快得多，因為 H100 / TPU 的算力遠高於 Apple Silicon，且常用大批次平行 prefill。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>判讀「為何本地 LLM 在塞長 context 時這麼慢」要追到 prefill 階段。緩解方法有三條：縮短 prompt（移除不必要 context）、用支援 prefix cache 的伺服器（如 oMLX 的 paged SSD KV cache 可重用之前 prefill 過的結果）、切到雲端旗艦（資料中心 prefill 算力遠高於 Mac）。&lt;/p></description><content:encoded><![CDATA[<p>Prefill 的核心概念是「<a href="/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">LLM 首次處理 prompt 時、把整段輸入跑過模型一次的計算階段</a>」。Prefill 階段會為 prompt 中每個 <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a> 算出 attention 中間結果並存進 <a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a>，之後生成新 token 時可以直接讀 cache。</p>
<h2 id="概念位置">概念位置</h2>
<p>Prefill 是 <a href="/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT</a> 的主要構成部分。Prefill 結束後系統進入 decode 階段、開始一個一個生 token。兩階段的瓶頸不同：prefill 是「算力 bound」（並行處理整段 prompt）、decode 是「記憶體頻寬 bound」。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>短 prompt（500 tokens）：prefill 通常 &lt; 1 秒、感覺不到。</p>
<p>中等 prompt（4K tokens）：M4 Max 跑 31B 模型約 3 ~ 8 秒、開始有感。</p>
<p>長 prompt（10K+ tokens）：本地 prefill 拉到 30 ~ 90 秒、是 coding agent 場景最痛的點。</p>
<p>雲端旗艦 prefill 速度快得多，因為 H100 / TPU 的算力遠高於 Apple Silicon，且常用大批次平行 prefill。</p>
<h2 id="設計責任">設計責任</h2>
<p>判讀「為何本地 LLM 在塞長 context 時這麼慢」要追到 prefill 階段。緩解方法有三條：縮短 prompt（移除不必要 context）、用支援 prefix cache 的伺服器（如 oMLX 的 paged SSD KV cache 可重用之前 prefill 過的結果）、切到雲端旗艦（資料中心 prefill 算力遠高於 Mac）。</p>
]]></content:encoded></item><item><title>Quantization</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/quantization/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/quantization/</guid><description>&lt;p>Quantization（量化）的核心概念是「把模型權重從高精度（如 16-bit float）改用較低精度（如 4-bit integer）表示」。權重數量不變，但每個權重佔的 bytes 變少；模型總大小變小、每秒能讀過的權重變多，&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/tokens-per-second/" data-link-title="Tokens Per Second" data-link-desc="LLM 每秒能生成幾個 token：生字速度的標準量化指標">生字速度&lt;/a> 直接變快。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>量化是讓 LLM 跑在 consumer 等級硬體上的關鍵技術。沒有量化、Apple Silicon Mac 跑不動 30B+ 模型，因為原始 bf16 權重會超出記憶體預算。量化方法主要分兩類：&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> 系統用的 K-quants（Q4_K_M、Q5_K_M 等）、以及 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mlx/" data-link-title="MLX" data-link-desc="Apple 釋出的 Apple Silicon 數值運算 framework：類似 PyTorch / JAX 的 Mac 對應物">MLX&lt;/a> 等系統用的 4-bit / 8-bit 量化。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>常見量化等級的取捨：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>量化&lt;/th>
 &lt;th>每權重 bits&lt;/th>
 &lt;th>相對 bf16 大小&lt;/th>
 &lt;th>品質衰減&lt;/th>
 &lt;th>適合場景&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>bf16 / F16&lt;/td>
 &lt;td>16&lt;/td>
 &lt;td>1x&lt;/td>
 &lt;td>無（基準）&lt;/td>
 &lt;td>開發、評估、大記憶體機器&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Q8&lt;/td>
 &lt;td>8&lt;/td>
 &lt;td>0.5x&lt;/td>
 &lt;td>幾乎察覺不到&lt;/td>
 &lt;td>32GB+ Mac、品質敏感任務&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Q5_K_M&lt;/td>
 &lt;td>5.5&lt;/td>
 &lt;td>0.34x&lt;/td>
 &lt;td>輕微&lt;/td>
 &lt;td>24GB Mac、日常使用&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Q4_K_M&lt;/td>
 &lt;td>4.5&lt;/td>
 &lt;td>0.28x&lt;/td>
 &lt;td>可察覺、實用&lt;/td>
 &lt;td>多數場景的甜蜜點&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Q3&lt;/td>
 &lt;td>3&lt;/td>
 &lt;td>0.19x&lt;/td>
 &lt;td>明顯、code 任務開始崩&lt;/td>
 &lt;td>較大模型強塞較小機器時備用&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>「&lt;code>_K_M&lt;/code>」的 K 指 K-quants（較新的量化方法）、M 指 mixed-medium（不同層用不同量化）。Q3 70B 模型在 coding 任務上常輸給 Q5 14B 模型；模型大小跟模型實用品質是兩件事。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>選量化等級時看三個維度：記憶體預算（量化後是否塞得進）、體感速度（量化越激進、tok/s 越高）、品質容忍度（過低量化會明顯衰減）。寫 code 場景的甜蜜點通常是 Q4_K_M；想再換更激進量化前、先用同等記憶體預算下的較小模型 Q5 對比，常會發現後者品質更好。&lt;/p></description><content:encoded><![CDATA[<p>Quantization（量化）的核心概念是「把模型權重從高精度（如 16-bit float）改用較低精度（如 4-bit integer）表示」。權重數量不變，但每個權重佔的 bytes 變少；模型總大小變小、每秒能讀過的權重變多，<a href="/blog/llm/knowledge-cards/tokens-per-second/" data-link-title="Tokens Per Second" data-link-desc="LLM 每秒能生成幾個 token：生字速度的標準量化指標">生字速度</a> 直接變快。</p>
<h2 id="概念位置">概念位置</h2>
<p>量化是讓 LLM 跑在 consumer 等級硬體上的關鍵技術。沒有量化、Apple Silicon Mac 跑不動 30B+ 模型，因為原始 bf16 權重會超出記憶體預算。量化方法主要分兩類：<a href="/blog/llm/knowledge-cards/gguf/" data-link-title="GGUF" data-link-desc="llama.cpp 生態定義的模型權重格式：把權重、tokenizer、metadata 打包成單一檔案">GGUF</a> 系統用的 K-quants（Q4_K_M、Q5_K_M 等）、以及 <a href="/blog/llm/knowledge-cards/mlx/" data-link-title="MLX" data-link-desc="Apple 釋出的 Apple Silicon 數值運算 framework：類似 PyTorch / JAX 的 Mac 對應物">MLX</a> 等系統用的 4-bit / 8-bit 量化。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>常見量化等級的取捨：</p>
<table>
  <thead>
      <tr>
          <th>量化</th>
          <th>每權重 bits</th>
          <th>相對 bf16 大小</th>
          <th>品質衰減</th>
          <th>適合場景</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>bf16 / F16</td>
          <td>16</td>
          <td>1x</td>
          <td>無（基準）</td>
          <td>開發、評估、大記憶體機器</td>
      </tr>
      <tr>
          <td>Q8</td>
          <td>8</td>
          <td>0.5x</td>
          <td>幾乎察覺不到</td>
          <td>32GB+ Mac、品質敏感任務</td>
      </tr>
      <tr>
          <td>Q5_K_M</td>
          <td>5.5</td>
          <td>0.34x</td>
          <td>輕微</td>
          <td>24GB Mac、日常使用</td>
      </tr>
      <tr>
          <td>Q4_K_M</td>
          <td>4.5</td>
          <td>0.28x</td>
          <td>可察覺、實用</td>
          <td>多數場景的甜蜜點</td>
      </tr>
      <tr>
          <td>Q3</td>
          <td>3</td>
          <td>0.19x</td>
          <td>明顯、code 任務開始崩</td>
          <td>較大模型強塞較小機器時備用</td>
      </tr>
  </tbody>
</table>
<p>「<code>_K_M</code>」的 K 指 K-quants（較新的量化方法）、M 指 mixed-medium（不同層用不同量化）。Q3 70B 模型在 coding 任務上常輸給 Q5 14B 模型；模型大小跟模型實用品質是兩件事。</p>
<h2 id="設計責任">設計責任</h2>
<p>選量化等級時看三個維度：記憶體預算（量化後是否塞得進）、體感速度（量化越激進、tok/s 越高）、品質容忍度（過低量化會明顯衰減）。寫 code 場景的甜蜜點通常是 Q4_K_M；想再換更激進量化前、先用同等記憶體預算下的較小模型 Q5 對比，常會發現後者品質更好。</p>
]]></content:encoded></item><item><title>RAG</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/rag/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/rag/</guid><description>&lt;p>RAG（Retrieval-Augmented Generation）的核心概念是「給 LLM 動態外掛一份知識、在生成時從 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-source/" data-link-title="Retrieval Source" data-link-desc="RAG 從哪個 corpus、index、tool 或外部系統取回內容，決定來源可信度、freshness、權限與引用責任">retrieval source&lt;/a> 找相關片段塞進 prompt 當 context」。它解的是 LLM 參數記憶的三個天然限制：訓練 cutoff、私有資料缺席、長尾事實壓縮損失。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>RAG 跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/instruction-tuned/" data-link-title="Instruction-Tuned Model" data-link-desc="經過指令微調的模型：會跟著 prompt 走、回答使用者問題">fine-tuning&lt;/a> 跟 long context 是「讓模型知道新東西」的三條路、解的問題層次不同：RAG 動態外掛、fine-tuning 改參數、long context 直接塞 prompt。三者不互斥、常組合用。RAG 屬於應用層、依賴 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model&lt;/a> 把文字轉向量、用相似度檢索。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>寫 code 場景的典型 RAG 是 Continue.dev 的 &lt;code>@codebase&lt;/code>：把整個 repo 切 chunk、用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model&lt;/a> 索引成向量、query 時用 cosine similarity 找相關片段、塞進 prompt 給 LLM。判讀 RAG 結果好壞看：retrieval 片段相關性、塞進 prompt 後 LLM 是否真用上、答案是否能追溯到 source chunk，以及整段 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost&lt;/a> 是否划算。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>設計 RAG 系統前先評估「不做 RAG 會怎樣」：知識量小可用 long context、知識結構化可用 SQL、靜態風格特化可用 fine-tune。需要動態 + 大量 + traceable 才是 RAG 的甜蜜點。詳細展開見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &amp;#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG 原理&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>RAG（Retrieval-Augmented Generation）的核心概念是「給 LLM 動態外掛一份知識、在生成時從 <a href="/blog/llm/knowledge-cards/retrieval-source/" data-link-title="Retrieval Source" data-link-desc="RAG 從哪個 corpus、index、tool 或外部系統取回內容，決定來源可信度、freshness、權限與引用責任">retrieval source</a> 找相關片段塞進 prompt 當 context」。它解的是 LLM 參數記憶的三個天然限制：訓練 cutoff、私有資料缺席、長尾事實壓縮損失。</p>
<h2 id="概念位置">概念位置</h2>
<p>RAG 跟 <a href="/blog/llm/knowledge-cards/instruction-tuned/" data-link-title="Instruction-Tuned Model" data-link-desc="經過指令微調的模型：會跟著 prompt 走、回答使用者問題">fine-tuning</a> 跟 long context 是「讓模型知道新東西」的三條路、解的問題層次不同：RAG 動態外掛、fine-tuning 改參數、long context 直接塞 prompt。三者不互斥、常組合用。RAG 屬於應用層、依賴 <a href="/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model</a> 把文字轉向量、用相似度檢索。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>寫 code 場景的典型 RAG 是 Continue.dev 的 <code>@codebase</code>：把整個 repo 切 chunk、用 <a href="/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model</a> 索引成向量、query 時用 cosine similarity 找相關片段、塞進 prompt 給 LLM。判讀 RAG 結果好壞看：retrieval 片段相關性、塞進 prompt 後 LLM 是否真用上、答案是否能追溯到 source chunk，以及整段 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a> 是否划算。</p>
<h2 id="設計責任">設計責任</h2>
<p>設計 RAG 系統前先評估「不做 RAG 會怎樣」：知識量小可用 long context、知識結構化可用 SQL、靜態風格特化可用 fine-tune。需要動態 + 大量 + traceable 才是 RAG 的甜蜜點。詳細展開見 <a href="/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG 原理</a>。</p>
]]></content:encoded></item><item><title>Speculative Decoding</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/speculative-decoding/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/speculative-decoding/</guid><description>&lt;p>Speculative Decoding（推測解碼）的核心概念是「用一個快的小模型（drafter）先猜未來 N 個 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a>、再讓大模型（target）一次並行驗證」。大模型認同的前綴保留下來、不認同的位置之後重新生成。實際效果是「一次 forward pass 產出多個 token」、攻擊的是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">autoregressive&lt;/a> 的單 token 瓶頸。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Speculative decoding 是純加速技巧、不改變輸出品質。大模型驗證階段的數學保證：drafter 猜對時保留、猜錯時 target 自己決定下一個 token、最終結果跟「不用 drafter 直接生成」一致。它能加速的關鍵是「驗證可以並行」—— 大模型一次跑 forward pass 驗證 N 個 token 的時間、跟驗證 1 個 token 接近、因為瓶頸是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth&lt;/a> 而非算力。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>寫 code 場景的 speculative decoding 接受率特別高，因為 code 有大量可預測 pattern（縮排、括號、import 語句、常見變數名）。drafter 猜對的機率高、整體加速明顯。&lt;/p>
&lt;p>Google 為 Gemma 4 釋出官方 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/drafter-model/" data-link-title="Drafter Model" data-link-desc="speculative decoding 中用來快速猜未來 token 的小模型">drafter&lt;/a> 後、官方數據 coding 任務 2 ~ 3 倍加速、其他任務 1.5 ~ 2 倍。&lt;/p>
&lt;p>實作層面、Ollama v0.23.1（2026/5/7）一鍵啟用 &lt;code>gemma4:31b-coding-mtp-bf16&lt;/code>、LM Studio 提供 UI 設定面板、llama.cpp 的 &lt;code>--draft-model&lt;/code> 參數仍 beta。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>啟用 speculative decoding 需要 target 模型與 drafter 模型用相同 tokenizer。Gemma 4 31B 配 Gemma 4 E4B 可以工作、跨家族（Gemma 配 Llama 等）沒有相容性。多數使用者透過預先打包好的 model tag（如 Ollama 的 MTP 版本）一行啟用、無需自己挑 drafter。&lt;/p></description><content:encoded><![CDATA[<p>Speculative Decoding（推測解碼）的核心概念是「用一個快的小模型（drafter）先猜未來 N 個 <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a>、再讓大模型（target）一次並行驗證」。大模型認同的前綴保留下來、不認同的位置之後重新生成。實際效果是「一次 forward pass 產出多個 token」、攻擊的是 <a href="/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">autoregressive</a> 的單 token 瓶頸。</p>
<h2 id="概念位置">概念位置</h2>
<p>Speculative decoding 是純加速技巧、不改變輸出品質。大模型驗證階段的數學保證：drafter 猜對時保留、猜錯時 target 自己決定下一個 token、最終結果跟「不用 drafter 直接生成」一致。它能加速的關鍵是「驗證可以並行」—— 大模型一次跑 forward pass 驗證 N 個 token 的時間、跟驗證 1 個 token 接近、因為瓶頸是 <a href="/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth</a> 而非算力。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>寫 code 場景的 speculative decoding 接受率特別高，因為 code 有大量可預測 pattern（縮排、括號、import 語句、常見變數名）。drafter 猜對的機率高、整體加速明顯。</p>
<p>Google 為 Gemma 4 釋出官方 <a href="/blog/llm/knowledge-cards/drafter-model/" data-link-title="Drafter Model" data-link-desc="speculative decoding 中用來快速猜未來 token 的小模型">drafter</a> 後、官方數據 coding 任務 2 ~ 3 倍加速、其他任務 1.5 ~ 2 倍。</p>
<p>實作層面、Ollama v0.23.1（2026/5/7）一鍵啟用 <code>gemma4:31b-coding-mtp-bf16</code>、LM Studio 提供 UI 設定面板、llama.cpp 的 <code>--draft-model</code> 參數仍 beta。</p>
<h2 id="設計責任">設計責任</h2>
<p>啟用 speculative decoding 需要 target 模型與 drafter 模型用相同 tokenizer。Gemma 4 31B 配 Gemma 4 E4B 可以工作、跨家族（Gemma 配 Llama 等）沒有相容性。多數使用者透過預先打包好的 model tag（如 Ollama 的 MTP 版本）一行啟用、無需自己挑 drafter。</p>
]]></content:encoded></item><item><title>SWE-bench</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/swe-bench/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/swe-bench/</guid><description>&lt;p>SWE-bench 的核心概念是「用真實開源專案的 GitHub issue 與 PR 當測試集、評量 LLM 解程式碼問題的能力」。它把 LLM 放在「給一個 issue 描述、看能否生成解決它的 patch」的任務上、跑完用 patch 是否能讓既有測試通過作為通過率。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>SWE-bench 比早期的 HumanEval（單一 function 生成）難得多、涵蓋多檔案理解、需求拆解、實際 patch 生成。它是 2026 年量化 coding LLM 能力最常被引用的指標。SWE-bench Verified 是 OpenAI 篩選過的子集、確保任務描述清楚、是現在報告主流。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>2026 年 5 月各模型在 SWE-bench Verified 上的大致表現（僅供量級參考、實際數字以官方報告為準）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>模型&lt;/th>
 &lt;th>SWE-bench Verified&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Claude Sonnet 4.6&lt;/td>
 &lt;td>80+ 分&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>GPT-5&lt;/td>
 &lt;td>80+ 分&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Qwen3-Coder 30B（本地）&lt;/td>
 &lt;td>77.2 分&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Gemma 4 31B（本地）&lt;/td>
 &lt;td>70+ 分&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Qwen3 14B&lt;/td>
 &lt;td>50+ 分&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>「分數」是百分比、代表通過率。本地最強模型在 SWE-bench 上跟雲端旗艦仍有差距、但對寫 code 場景已堪用。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>評估模型適合不適合本地寫 code 時、SWE-bench Verified 是核心指標之一。換新模型前看分數差距：5 分以上才值得試（適應新 prompt 風格的成本不低）。看到「新模型超越 GPT-X」報導時、確認是哪個 SWE-bench 變體（Lite / Verified / Full）；變體間分數差很多、混為一談會誤判。&lt;/p></description><content:encoded><![CDATA[<p>SWE-bench 的核心概念是「用真實開源專案的 GitHub issue 與 PR 當測試集、評量 LLM 解程式碼問題的能力」。它把 LLM 放在「給一個 issue 描述、看能否生成解決它的 patch」的任務上、跑完用 patch 是否能讓既有測試通過作為通過率。</p>
<h2 id="概念位置">概念位置</h2>
<p>SWE-bench 比早期的 HumanEval（單一 function 生成）難得多、涵蓋多檔案理解、需求拆解、實際 patch 生成。它是 2026 年量化 coding LLM 能力最常被引用的指標。SWE-bench Verified 是 OpenAI 篩選過的子集、確保任務描述清楚、是現在報告主流。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>2026 年 5 月各模型在 SWE-bench Verified 上的大致表現（僅供量級參考、實際數字以官方報告為準）：</p>
<table>
  <thead>
      <tr>
          <th>模型</th>
          <th>SWE-bench Verified</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Claude Sonnet 4.6</td>
          <td>80+ 分</td>
      </tr>
      <tr>
          <td>GPT-5</td>
          <td>80+ 分</td>
      </tr>
      <tr>
          <td>Qwen3-Coder 30B（本地）</td>
          <td>77.2 分</td>
      </tr>
      <tr>
          <td>Gemma 4 31B（本地）</td>
          <td>70+ 分</td>
      </tr>
      <tr>
          <td>Qwen3 14B</td>
          <td>50+ 分</td>
      </tr>
  </tbody>
</table>
<p>「分數」是百分比、代表通過率。本地最強模型在 SWE-bench 上跟雲端旗艦仍有差距、但對寫 code 場景已堪用。</p>
<h2 id="設計責任">設計責任</h2>
<p>評估模型適合不適合本地寫 code 時、SWE-bench Verified 是核心指標之一。換新模型前看分數差距：5 分以上才值得試（適應新 prompt 風格的成本不低）。看到「新模型超越 GPT-X」報導時、確認是哪個 SWE-bench 變體（Lite / Verified / Full）；變體間分數差很多、混為一談會誤判。</p>
]]></content:encoded></item><item><title>Token</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/token/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/token/</guid><description>&lt;p>Token 的核心概念是「LLM 內部處理文字的最小單位」，介於字元（character）與單字（word）之間。模型接收 prompt 前會先用 tokenizer 把文字切成 token 序列，輸出時也以 token 為單位逐個生成。Token 是計費、速度、context 容量等所有 LLM 量化指標的共同單位。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Token 位於介面層送出文字與模型層實際運算之間的轉換點。介面層的「字串」進入模型前會被 tokenizer 切成整數序列；模型輸出的整數序列再被 tokenizer 還原成字串給介面層顯示。不同模型用不同 tokenizer，同一段文字在 GPT、Claude、Gemma 上切出的 token 數量會有差異。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>英文約「4 個字元 ≈ 1 token」，中文約「1 ~ 2 個字 ≈ 1 token」。&lt;code>Hello, world!&lt;/code> 約 4 個 token；「你好，世界」約 5 ~ 7 個 token，視 tokenizer 而定。雲端 API 的計費單據用 token 計量，本地推論的速度指標 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/tokens-per-second/" data-link-title="Tokens Per Second" data-link-desc="LLM 每秒能生成幾個 token：生字速度的標準量化指標">tokens per second&lt;/a> 也以 token 為單位。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解 token 後可以做幾件實用判斷：估算 prompt 是否會超過 &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>、估算雲端 API 費用、解讀 benchmark 數字。寫程式時用 OpenAI 的 &lt;code>tiktoken&lt;/code>、Hugging Face 的 &lt;code>transformers.AutoTokenizer&lt;/code> 可以精確計算特定模型的 token 數量。&lt;/p></description><content:encoded><![CDATA[<p>Token 的核心概念是「LLM 內部處理文字的最小單位」，介於字元（character）與單字（word）之間。模型接收 prompt 前會先用 tokenizer 把文字切成 token 序列，輸出時也以 token 為單位逐個生成。Token 是計費、速度、context 容量等所有 LLM 量化指標的共同單位。</p>
<h2 id="概念位置">概念位置</h2>
<p>Token 位於介面層送出文字與模型層實際運算之間的轉換點。介面層的「字串」進入模型前會被 tokenizer 切成整數序列；模型輸出的整數序列再被 tokenizer 還原成字串給介面層顯示。不同模型用不同 tokenizer，同一段文字在 GPT、Claude、Gemma 上切出的 token 數量會有差異。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>英文約「4 個字元 ≈ 1 token」，中文約「1 ~ 2 個字 ≈ 1 token」。<code>Hello, world!</code> 約 4 個 token；「你好，世界」約 5 ~ 7 個 token，視 tokenizer 而定。雲端 API 的計費單據用 token 計量，本地推論的速度指標 <a href="/blog/llm/knowledge-cards/tokens-per-second/" data-link-title="Tokens Per Second" data-link-desc="LLM 每秒能生成幾個 token：生字速度的標準量化指標">tokens per second</a> 也以 token 為單位。</p>
<h2 id="設計責任">設計責任</h2>
<p>理解 token 後可以做幾件實用判斷：估算 prompt 是否會超過 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a>、估算雲端 API 費用、解讀 benchmark 數字。寫程式時用 OpenAI 的 <code>tiktoken</code>、Hugging Face 的 <code>transformers.AutoTokenizer</code> 可以精確計算特定模型的 token 數量。</p>
]]></content:encoded></item><item><title>Tokens Per Second</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/tokens-per-second/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/tokens-per-second/</guid><description>&lt;p>Tokens Per Second（tok/s）的核心概念是「LLM 每秒能輸出多少個 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a>」，是生字速度的標準指標。生字速度由 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth&lt;/a> 跟模型大小共同決定，而非 CPU / GPU 算力。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Tok/s 量度的是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">autoregressive&lt;/a> 主要生成階段的吞吐量，跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT&lt;/a>（首字延遲）是兩個獨立指標。一個系統可能 TTFT 高但 tok/s 還行，也可能 TTFT 低但 tok/s 慢；兩者都要看才能完整描述體感。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>實務經驗值（僅供量級參考、視硬體與量化等級而定）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>場景&lt;/th>
 &lt;th>大致 tok/s&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Claude Sonnet 雲端&lt;/td>
 &lt;td>80 ~ 120&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>GPT-5 雲端&lt;/td>
 &lt;td>70 ~ 100&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Gemma 4 31B MTP / M4 Max&lt;/td>
 &lt;td>25 ~ 40&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Qwen3-Coder 30B / M2 Pro&lt;/td>
 &lt;td>15 ~ 25&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>體感分界：低於 10 tok/s 像 dial-up 般卡頓、20 tok/s 以上接近流暢閱讀速度、40 tok/s 以上感覺即時。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>評估本地 LLM 是否堪用時，tok/s 是核心指標之一。理論上限可用「&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth&lt;/a> ÷ 模型大小」估算，實際值會比理論低 30 ~ 50%。看到「N tok/s」的報告時要追問模型、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">量化&lt;/a> 等級、硬體，三者缺一個就無法比較。&lt;/p></description><content:encoded><![CDATA[<p>Tokens Per Second（tok/s）的核心概念是「LLM 每秒能輸出多少個 <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a>」，是生字速度的標準指標。生字速度由 <a href="/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth</a> 跟模型大小共同決定，而非 CPU / GPU 算力。</p>
<h2 id="概念位置">概念位置</h2>
<p>Tok/s 量度的是 <a href="/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">autoregressive</a> 主要生成階段的吞吐量，跟 <a href="/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT</a>（首字延遲）是兩個獨立指標。一個系統可能 TTFT 高但 tok/s 還行，也可能 TTFT 低但 tok/s 慢；兩者都要看才能完整描述體感。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>實務經驗值（僅供量級參考、視硬體與量化等級而定）：</p>
<table>
  <thead>
      <tr>
          <th>場景</th>
          <th>大致 tok/s</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Claude Sonnet 雲端</td>
          <td>80 ~ 120</td>
      </tr>
      <tr>
          <td>GPT-5 雲端</td>
          <td>70 ~ 100</td>
      </tr>
      <tr>
          <td>Gemma 4 31B MTP / M4 Max</td>
          <td>25 ~ 40</td>
      </tr>
      <tr>
          <td>Qwen3-Coder 30B / M2 Pro</td>
          <td>15 ~ 25</td>
      </tr>
  </tbody>
</table>
<p>體感分界：低於 10 tok/s 像 dial-up 般卡頓、20 tok/s 以上接近流暢閱讀速度、40 tok/s 以上感覺即時。</p>
<h2 id="設計責任">設計責任</h2>
<p>評估本地 LLM 是否堪用時，tok/s 是核心指標之一。理論上限可用「<a href="/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth</a> ÷ 模型大小」估算，實際值會比理論低 30 ~ 50%。看到「N tok/s」的報告時要追問模型、<a href="/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">量化</a> 等級、硬體，三者缺一個就無法比較。</p>
]]></content:encoded></item><item><title>Transformer</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/transformer/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/transformer/</guid><description>&lt;p>Transformer 的核心概念是「2017 年 Google 提出、基於 self-attention 機制的神經網路架構」。寫 code 用的所有 LLM（GPT、Claude、Gemma、Llama、Qwen 系列）都是 Transformer 架構；它跟產圖用的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/diffusion/" data-link-title="Diffusion" data-link-desc="產圖用的生成式 AI 架構：跟寫 code 用的 Transformer 是不同路線">Diffusion&lt;/a> 是兩個不同的生成式 AI 路線。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Transformer 是模型架構層的選擇、決定底層運算方式與適合的任務類型。它擅長「序列建模」：文字、code、語音、時間序列等都能用 Transformer 處理。配 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">autoregressive&lt;/a> 生成方式跑文字、跑出來的就是 LLM。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>Transformer 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>生成方式&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">一個 token 接一個 token&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>量化指標&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/tokens-per-second/" data-link-title="Tokens Per Second" data-link-desc="LLM 每秒能生成幾個 token：生字速度的標準量化指標">tokens per second&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>輸入處理&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prefill/" data-link-title="Prefill" data-link-desc="Prompt 首次處理時的計算階段：把整段輸入跑過模型、產生 KV cache">prefill&lt;/a> 階段&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>中間結果&lt;/td>
 &lt;td>&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>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>容量限制&lt;/td>
 &lt;td>&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>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Transformer 也被用在多模態場景（vision Transformer、speech Transformer）、但寫 code 場景接觸到的都是文字 Transformer。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>理解「寫 code 的 LLM 是 Transformer」可以幫助判讀資訊。看到「最新 Transformer 模型」報導時、知道它跟 Diffusion 是兩個路線；想跑產圖時、知道要找 Diffusion 工具（ComfyUI、Draw Things）而非 Ollama；看到「LLM 架構創新」時、可以追問是 attention 機制改良、還是換到非 Transformer 路線（如 Mamba、RWKV 等少數實驗性架構）。&lt;/p></description><content:encoded><![CDATA[<p>Transformer 的核心概念是「2017 年 Google 提出、基於 self-attention 機制的神經網路架構」。寫 code 用的所有 LLM（GPT、Claude、Gemma、Llama、Qwen 系列）都是 Transformer 架構；它跟產圖用的 <a href="/blog/llm/knowledge-cards/diffusion/" data-link-title="Diffusion" data-link-desc="產圖用的生成式 AI 架構：跟寫 code 用的 Transformer 是不同路線">Diffusion</a> 是兩個不同的生成式 AI 路線。</p>
<h2 id="概念位置">概念位置</h2>
<p>Transformer 是模型架構層的選擇、決定底層運算方式與適合的任務類型。它擅長「序列建模」：文字、code、語音、時間序列等都能用 Transformer 處理。配 <a href="/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">autoregressive</a> 生成方式跑文字、跑出來的就是 LLM。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>Transformer LLM 的共通特徵：</p>
<table>
  <thead>
      <tr>
          <th>特徵</th>
          <th>表現</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>生成方式</td>
          <td><a href="/blog/llm/knowledge-cards/autoregressive/" data-link-title="Autoregressive" data-link-desc="LLM 一次生成一個 token、把已生成內容作為下一次輸入的架構">一個 token 接一個 token</a></td>
      </tr>
      <tr>
          <td>量化指標</td>
          <td><a href="/blog/llm/knowledge-cards/tokens-per-second/" data-link-title="Tokens Per Second" data-link-desc="LLM 每秒能生成幾個 token：生字速度的標準量化指標">tokens per second</a>、<a href="/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT</a></td>
      </tr>
      <tr>
          <td>輸入處理</td>
          <td><a href="/blog/llm/knowledge-cards/prefill/" data-link-title="Prefill" data-link-desc="Prompt 首次處理時的計算階段：把整段輸入跑過模型、產生 KV cache">prefill</a> 階段</td>
      </tr>
      <tr>
          <td>中間結果</td>
          <td><a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a></td>
      </tr>
      <tr>
          <td>容量限制</td>
          <td><a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a></td>
      </tr>
  </tbody>
</table>
<p>Transformer 也被用在多模態場景（vision Transformer、speech Transformer）、但寫 code 場景接觸到的都是文字 Transformer。</p>
<h2 id="設計責任">設計責任</h2>
<p>理解「寫 code 的 LLM 是 Transformer」可以幫助判讀資訊。看到「最新 Transformer 模型」報導時、知道它跟 Diffusion 是兩個路線；想跑產圖時、知道要找 Diffusion 工具（ComfyUI、Draw Things）而非 Ollama；看到「LLM 架構創新」時、可以追問是 attention 機制改良、還是換到非 Transformer 路線（如 Mamba、RWKV 等少數實驗性架構）。</p>
]]></content:encoded></item><item><title>TTFT</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/ttft/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/ttft/</guid><description>&lt;p>TTFT（Time To First Token）的核心概念是「使用者送出 prompt 之後，等多久才看到第一個 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a> 出現」。它包含 prompt 的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prefill/" data-link-title="Prefill" data-link-desc="Prompt 首次處理時的計算階段：把整段輸入跑過模型、產生 KV cache">prefill&lt;/a> 時間、網路傳輸（雲端才有）、伺服器排隊與第一個 token 的生成。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>TTFT 跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/tokens-per-second/" data-link-title="Tokens Per Second" data-link-desc="LLM 每秒能生成幾個 token：生字速度的標準量化指標">tokens per second&lt;/a>（生字速度）是兩個獨立指標。前者描述「開始講話前的停頓」，後者描述「開始講話後講多快」。長 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context&lt;/a> 場景的 TTFT 由 prefill 主導，與 prompt 長度成正比。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>短 prompt（&amp;lt; 1K token）場景：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>環境&lt;/th>
 &lt;th>TTFT&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Claude Sonnet 雲端&lt;/td>
 &lt;td>0.5 ~ 1 秒&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Gemma 4 31B MTP / M4 Max&lt;/td>
 &lt;td>1 ~ 3 秒&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>長 prompt（10K+ token）場景：本地 TTFT 可能拉到 30 ~ 90 秒（每次都重新 prefill 整段 context）。雲端 TTFT 受影響較小，因為 H100 等資料中心 GPU 的 prefill 算力遠高於 Apple Silicon。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>寫 code 場景的 TTFT 痛點主要出現在 coding agent 模式（塞整個 repo 進 prompt）。對短 prompt 場景，TTFT 1 ~ 3 秒可接受；對長 context 場景，要評估特化伺服器（如 oMLX）的 &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> 重用方案。判讀 TTFT 報告時，務必確認 prompt 長度、否則數字無從比較。&lt;/p></description><content:encoded><![CDATA[<p>TTFT（Time To First Token）的核心概念是「使用者送出 prompt 之後，等多久才看到第一個 <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a> 出現」。它包含 prompt 的 <a href="/blog/llm/knowledge-cards/prefill/" data-link-title="Prefill" data-link-desc="Prompt 首次處理時的計算階段：把整段輸入跑過模型、產生 KV cache">prefill</a> 時間、網路傳輸（雲端才有）、伺服器排隊與第一個 token 的生成。</p>
<h2 id="概念位置">概念位置</h2>
<p>TTFT 跟 <a href="/blog/llm/knowledge-cards/tokens-per-second/" data-link-title="Tokens Per Second" data-link-desc="LLM 每秒能生成幾個 token：生字速度的標準量化指標">tokens per second</a>（生字速度）是兩個獨立指標。前者描述「開始講話前的停頓」，後者描述「開始講話後講多快」。長 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context</a> 場景的 TTFT 由 prefill 主導，與 prompt 長度成正比。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>短 prompt（&lt; 1K token）場景：</p>
<table>
  <thead>
      <tr>
          <th>環境</th>
          <th>TTFT</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Claude Sonnet 雲端</td>
          <td>0.5 ~ 1 秒</td>
      </tr>
      <tr>
          <td>Gemma 4 31B MTP / M4 Max</td>
          <td>1 ~ 3 秒</td>
      </tr>
  </tbody>
</table>
<p>長 prompt（10K+ token）場景：本地 TTFT 可能拉到 30 ~ 90 秒（每次都重新 prefill 整段 context）。雲端 TTFT 受影響較小，因為 H100 等資料中心 GPU 的 prefill 算力遠高於 Apple Silicon。</p>
<h2 id="設計責任">設計責任</h2>
<p>寫 code 場景的 TTFT 痛點主要出現在 coding agent 模式（塞整個 repo 進 prompt）。對短 prompt 場景，TTFT 1 ~ 3 秒可接受；對長 context 場景，要評估特化伺服器（如 oMLX）的 <a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 重用方案。判讀 TTFT 報告時，務必確認 prompt 長度、否則數字無從比較。</p>
]]></content:encoded></item><item><title>Unified Memory Architecture</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/unified-memory/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/unified-memory/</guid><description>&lt;p>Unified Memory Architecture（UMA、統一記憶體架構）的核心概念是「Apple Silicon 把 CPU、GPU、Neural Engine 接在同一塊記憶體上」、共用同一份位址空間。傳統 PC 把系統記憶體跟 VRAM 分開、模型權重要塞進 VRAM 才能用 GPU 跑、跨 PCIe 搬資料很慢。Mac 的統一記憶體避開這個限制。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>UMA 是 Apple Silicon 在「能跑多大模型」上佔優勢的硬體基礎。32GB 統一記憶體可以幾乎全部給模型用（留 8GB 給系統）；同等價位的 PC + NVIDIA 配置通常只有 12 ~ 24GB VRAM。能跑得動 vs 跑得快是兩件事：UMA 解前者、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth&lt;/a> 才決定後者。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>32GB Mac 跑 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">Q4 量化&lt;/a> 的 Gemma 4 31B 模型順暢（佔 18GB）、同等價位 PC（16GB VRAM 等級）跑不動同一模型、要降到 14B Q4 才行。70B 模型在 64GB Mac 上可行、PC 需要兩張 24GB VRAM GPU 配 NVLink、成本高得多。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>買 Mac 跑本地 LLM 時、把記憶體當第一順位考量、超過 CPU 規格與儲存空間。32GB 是寫 code 場景的甜蜜點（跑得起 Gemma 4 31B MTP）、48 ~ 64GB 進階配置（跑得起 70B 或同時跑兩個模型）、96GB+ 對寫 code 場景多半過度配置。MLX 等 framework 利用 UMA 的方式跟 Metal backend 略有差異、但對使用者都透明、選伺服器時無需考量 UMA 細節。&lt;/p></description><content:encoded><![CDATA[<p>Unified Memory Architecture（UMA、統一記憶體架構）的核心概念是「Apple Silicon 把 CPU、GPU、Neural Engine 接在同一塊記憶體上」、共用同一份位址空間。傳統 PC 把系統記憶體跟 VRAM 分開、模型權重要塞進 VRAM 才能用 GPU 跑、跨 PCIe 搬資料很慢。Mac 的統一記憶體避開這個限制。</p>
<h2 id="概念位置">概念位置</h2>
<p>UMA 是 Apple Silicon 在「能跑多大模型」上佔優勢的硬體基礎。32GB 統一記憶體可以幾乎全部給模型用（留 8GB 給系統）；同等價位的 PC + NVIDIA 配置通常只有 12 ~ 24GB VRAM。能跑得動 vs 跑得快是兩件事：UMA 解前者、<a href="/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth</a> 才決定後者。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>32GB Mac 跑 <a href="/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">Q4 量化</a> 的 Gemma 4 31B 模型順暢（佔 18GB）、同等價位 PC（16GB VRAM 等級）跑不動同一模型、要降到 14B Q4 才行。70B 模型在 64GB Mac 上可行、PC 需要兩張 24GB VRAM GPU 配 NVLink、成本高得多。</p>
<h2 id="設計責任">設計責任</h2>
<p>買 Mac 跑本地 LLM 時、把記憶體當第一順位考量、超過 CPU 規格與儲存空間。32GB 是寫 code 場景的甜蜜點（跑得起 Gemma 4 31B MTP）、48 ~ 64GB 進階配置（跑得起 70B 或同時跑兩個模型）、96GB+ 對寫 code 場景多半過度配置。MLX 等 framework 利用 UMA 的方式跟 Metal backend 略有差異、但對使用者都透明、選伺服器時無需考量 UMA 細節。</p>
]]></content:encoded></item></channel></rss>