【2026 最新】模型蒸餾是什麼?Student 為何可能超越 Teacher,和 SFT、合成資料、量化差在哪

最後更新: ·
模型蒸餾是什麼:Teacher、Student 與 soft targets 的 2026 AI 新手教學首圖

2026 年 7 月 23 日,r/LocalLLaMA 接連出現兩場爭論:一邊質疑「蒸餾後的 Student 怎麼可能勝過 Teacher」,另一邊堅持「沒有讀到 logits,就不能叫模型蒸餾」。問題是,兩邊很可能在回答不同題目:有人談經典 logit distillation,有人談拿 Teacher 回覆做微調,還有人把合成資料、強化學習與量化一起塞進 distillation 這個字。

這篇模型蒸餾教學不替任何「偷模型」指控背書。我們會從 Teacher、Student、soft target、logits 與 temperature 開始,拆清現代 LLM 管線的五種做法,再跑一個 CPU 就能重現的小實驗。讀完後,你會知道 Student 為何能在某張考卷贏 Teacher,以及為何這仍不等於它整體更聰明。若你還不熟預訓練、SFT、RL 與 Evals,可先讀〈AI 模型怎麼學習?〉補齊地圖。

Table of Contents

先說結論:模型蒸餾是把 Teacher 的判斷線索變成 Student 的額外教材

🧠 模型蒸餾 = Teacher 的答案分布或行為訊號 + Student 的訓練目標。
Hard label 只給答案;soft target 還給 Teacher 的猶豫方式。Student 可以在一張考卷贏 Teacher,但不等於整體比 Teacher 更聰明。

先把角色說清楚:Teacher 是提供訓練訊號的模型,Student 是接受訊號、更新參數的模型。「Student」描述的是師生關係,不保證模型比較小。Born-Again Networks 甚至用同架構 Teacher 蒸餾給重新初始化、參數量相同的 Student,後者仍在特定影像與語言任務勝出。

因此,蒸餾也不只是「把 100 分的大模型縮成 90 分的小模型」。它更像把 Teacher 對大量題目的判斷,轉成一套比單一標準答案更密集的教材。Student 最後能否變小、變快或變準,要看資料、loss、容量、任務與評測;「用了蒸餾」本身不保證任何結果。

模型蒸餾怎麼運作?Teacher、logits、soft target 與 temperature

想像一張手寫數字圖片,正解是「7」。一般監督式訓練只看到 hard label:7 的目標機率是 100%,其他數字全是 0%。Teacher 卻可能判斷「7:0.82、1:0.10、9:0.05、其他:0.03」。Student 不只知道正解,還知道這張圖比較像 1、稍微像 9,幾乎不像 0。這些錯誤選項之間的相對關係,就是 soft target 提供的額外訊號。

模型蒸餾流程圖:Teacher 將 logits 經 temperature 轉成 soft targets,再和 hard label 一起訓練 Student
經典 logit distillation:Teacher 的 soft targets 與真實標籤共同構成 Student 的訓練訊號。

1. Logits 不是機率;softmax 之後才是機率

模型產生每個候選答案時,會先算出一組尚未正規化的分數,叫 logits。把 logits 丟進 softmax,才得到總和為 1 的機率分布。所有 logits 同時加上同一個常數,softmax 結果不變,所以單一 logit 沒有可獨立解讀的「知識量」;有意義的是它們的相對差距。

2. Temperature 把「幾乎是零」的選項攤開

Hinton、Vinyals 與 Dean 2015 年的經典公式,會先把 logits 除以溫度 T,再做 softmax。T=1 是原始分布;T 大於 1 時,最高機率下降,其他候選被攤開。蒸餾裡的 temperature 是訓練工具,和聊天介面調高抽樣 temperature、讓輸出更發散,數學操作相似但用途不同。

最小公式可寫成:soft target = softmax(teacher_logits / T)。Student 的 loss 通常混合兩部分:對真實標籤的 cross-entropy,以及對 Teacher 分布的 KL divergence;soft loss 常乘上 ,補償高溫造成的梯度縮小。這是典型 Hinton-style 配方,不是所有現代 LLM 蒸餾都必須照抄的唯一公式。

3. LLM 的「答案」不是一個類別,而是一串 token

影像分類每題只選一類;LLM 每一步都要在整個詞彙表上預測下一個 token。白盒 logit distillation 可以逐 token 對齊 Teacher 與 Student 的分布,也能對齊 hidden states 或 attention。若拿不到內部機率,還能讓 Teacher 先生成完整回答,再讓 Student 對那些序列做 SFT。後者不該叫「logit 蒸餾」,但 2016 年的 Sequence-Level Knowledge Distillation 已正式使用「蒸餾」這個名稱;「只有 logits 才算 distillation」並不是全學界共識。

模型蒸餾和 SFT、合成資料、RL、量化差在哪?

SFT 是學習方式;合成資料是教材來源;蒸餾是師生關係;RL 是評分與最佳化方式;量化是數字怎麼儲存。

這五個詞不在同一條分類軸上,因此可以同時發生。某團隊可以讓 Teacher 生成合成答案,用 SFT 做 response distillation,接著用 RL 改善可驗證任務,最後把完成的 Student 量化成 4-bit 部署。每一步都是真的,但不能因此把四步都叫「量化」或都叫「logit 蒸餾」。

Logit 蒸餾、回覆模仿、合成資料 SFT、強化學習與量化的比較圖
判斷方法時問四題:訊號來自誰、看到什麼資料、用什麼 loss 更新、部署時改了什麼。

Logit/white-box distillation

Student 直接讀 Teacher 對每個候選 token 的機率分布,通常需要模型權重、推論服務或特殊介面提供足夠資訊。這最接近經典 soft-target KD。Teacher 的內部訊號更密,但詞彙表、tokenizer、架構與容量差距也會讓對齊變難。

Sequence-level distillation/response imitation

Teacher 只輸出完成的文字,Student 再模仿這些回覆。它可能被論文稱為 sequence-level KD、black-box KD 或 response imitation。MiniLLM 的 ICLR 2024 論文也把「模仿 ChatGPT 等黑盒 API」列為既有 LLM KD 路徑;但文字回覆不含完整 token 分布,能搬走的訊號和 logit KD 不同。

Synthetic SFT

合成資料只回答「教材從哪裡來」;SFT 回答「如何更新參數」。Self-Instruct 讓模型生成指令、輸入與輸出,經過過濾後拿來 instruction tuning。若資料由固定 Teacher 產生、目的是把能力轉給 Student,也可同時稱 response distillation;若資料來自規則、模擬器或 Student 自己,就未必存在 Teacher–Student 關係。

RL/偏好與 reward transfer

RL 不是照著唯一標準答案逐 token 模仿,而是讓模型產生行為、取得 reward,再提高高分行為的機率。評分者可能是人類、AI、reward model、數學答案或測試程式。它能和蒸餾串接,例如 Student 先模仿 Teacher、再用驗證器做 RL;但「用了 AI 評分」不等於「做了 logit distillation」。想先理解完整後訓練地圖,可回到〈預訓練、SFT、RL 與 Evals〉。

Quantization/量化

量化通常把權重或 activation 從 16/32-bit 改用 8-bit、4-bit 等較低精度表示,以降低記憶體占用;在支援的硬體與 kernel 上也可能加速推論。它沒有天然的 Teacher,也通常不會減少參數個數。Hugging Face 的量化文件把它定位為模型壓縮技術。蒸餾與量化可以疊加:先訓練一個較小 Student,再把它用更少位元儲存。

Student 為何可能超越 Teacher?因為它學的通常不只 Teacher 的一次答案

先做一個邏輯檢查:如果 Student 在每一題的輸出都和 Teacher 完全相同,而且解碼與評分也相同,兩者分數必然相同。Student 要嚴格勝出,就必須在部分題目做出不同決定,或比較本身含有抽樣誤差。差異通常來自以下六件事。

  1. Student 本來就不是白紙:現代 Student 往往已有預訓練能力,Teacher 訊號是在重新配置它,不是從零灌入所有知識。
  2. 同時保留真實標籤:經典 loss 可混合 hard labels 與 soft targets。Teacher 判錯時,正確標籤仍能把 Student 拉回來。
  3. 教材經過抽樣、驗證與篩選:Student 可能學到的是 Teacher 多次作答後通過 verifier 的答案,而不是 Teacher 的單次即席輸出。真正的「老師」其實是 Teacher+資料管線+驗證器。
  4. 任務專訓對上評測分布:Student 反覆練同一類題,Teacher 卻只用 zero-shot/few-shot 應考;專科生在專科考卷勝過通才並不矛盾。
  5. 容量限制可能成為正則化:較小模型、新初始化或不同架構,可能平滑 Teacher 的噪音與過擬合。但 capacity gap 太大也會讓 Student 根本學不動。
  6. 評測與隨機性會改變名次:prompt、sampling、推理預算、grader、資料污染與 seed 都能影響差距;沒有信賴區間的小勝,可能只是測量噪音。

兩個研究把界線畫得很清楚。Born-Again Networks 的同尺寸 Student 在 CIFAR-100 某個 DenseNet 設定把錯誤率從 18.25% 降到 16.95%,說明「Student」不必比較小;但那是影像與舊式語言模型實驗,不是現代通用聊天模型。Distilling Step-by-Step 則讓 770M T5 在 ANLI R1 使用 80% 標註資料時,勝過 few-shot CoT 的 540B PaLM;Student 同時取得任務訓練與 Teacher rationales,兩邊不是同一種備考條件。

可以直覺地想成:Student 成績 = Base 能力 + Teacher 訊號 + 額外資料/驗證器 + 任務專訓 − 壓縮損失。
這是幫助記憶的帳本,不是可直接估計的加法模型;它只說明「贏一個 benchmark」完全可能,「全面比 Teacher 聰明」則是另一個尚未被證明的命題。

自己跑一次模型蒸餾:約 15 秒 CPU 實驗,還要保留 hard-only 對照

若直接拿 LLM 回覆做 SFT,我們示範到的是 response imitation,不是本文前半段的 logits 與 temperature。為了讓機制乾淨可見,這裡用 scikit-learn 內建的 load_digits:1,797 張 8×8 手寫數字,10 個類別。資料源自 E. Alpaydin、C. Kaynak 的 UCI Optical Recognition of Handwritten Digits 資料集,上游頁面標示 CC BY 4.0 與 DOI 10.24432/C50P49

這是一個小型開源神經網路的機制實驗,不是現代 LLM 的縮小版。Teacher 是 64→128→64→10 的 MLP(17,226 個參數);Student 是 64→16→10(1,210 個參數,約小 14.2 倍)。同一個 test split 永久隔離,只用 validation 在 T={1,2,4,8} 與 hard-loss weight 中選設定,再用 10 個未參與調參的 seed 評估;下文 Student 的 ± 都是這 10 次的平均值 ± 樣本標準差,Teacher 則是固定 seed 42 的單一模型。

先建立鎖版環境

python3.9 -m venv .venv
source .venv/bin/activate
python -m pip install "numpy==1.26.4" "torch==2.2.2" "scikit-learn==1.5.2"
python kd_digits.py

下方數字在 Apple M4/16GB、macOS arm64、CPU 單執行緒、Python 3.9.6 上量測;兩個模式與 grid search 合計 14.53 秒。即使固定 seed,PyTorch 官方也不保證跨版本、平台或 CPU/GPU 逐位相同,所以你應檢查方向與差距,而不是要求最後一位小數完全一致。

展開完整可重跑程式碼(存成 kd_digits.py)
import copy, random, time
import numpy as np
import torch
from sklearn.datasets import load_digits
from sklearn.metrics import f1_score
from sklearn.model_selection import train_test_split
from torch import nn
from torch.nn import functional as F

EPOCHS = 200
TUNE_SEEDS = range(5)
TEST_SEEDS = range(10, 20)
GRID = [(t, a) for t in (1., 2., 4., 8.)
        for a in (0., .2, .5, .8)]
torch.set_num_threads(1)
torch.use_deterministic_algorithms(True)

def seed_all(seed):
    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)

def make_model(widths):
    layers, size = [], 64
    for width in widths:
        layers += [nn.Linear(size, width), nn.ReLU()]
        size = width
    layers += [nn.Linear(size, 10)]
    return nn.Sequential(*layers)

def fit_ce(model, x, y):
    opt = torch.optim.AdamW(
        model.parameters(), lr=.01, weight_decay=1e-4)
    for _ in range(EPOCHS):
        opt.zero_grad()
        loss = F.cross_entropy(model(x), y)
        loss.backward()
        opt.step()

def fit_kd(model, teacher, x, y, T, hard_weight):
    opt = torch.optim.AdamW(
        model.parameters(), lr=.01, weight_decay=1e-4)
    teacher.eval()
    with torch.no_grad():
        teacher_logits = teacher(x)
    for _ in range(EPOCHS):
        opt.zero_grad()
        student_logits = model(x)
        hard = F.cross_entropy(student_logits, y)
        soft = F.kl_div(
            F.log_softmax(student_logits / T, dim=1),
            F.softmax(teacher_logits / T, dim=1),
            reduction="batchmean",
        ) * T**2
        loss = hard_weight * hard + (1-hard_weight) * soft
        loss.backward()
        opt.step()

def score(model, x, y):
    model.eval()
    with torch.no_grad():
        pred = model(x).argmax(1).numpy()
    truth = y.numpy()
    return (
        100 * (pred == truth).mean(),
        100 * f1_score(truth, pred, average="macro"),
    )

# 固定 70/15/15;test 永不參與調參
X, y = load_digits(return_X_y=True)
X = (X / 16).astype("float32")
y = y.astype("int64")
Xtr, Xtmp, ytr, ytmp = train_test_split(
    X, y, test_size=.30, random_state=42, stratify=y)
Xva, Xte, yva, yte = train_test_split(
    Xtmp, ytmp, test_size=.50, random_state=42,
    stratify=ytmp)
Xtr, Xva, Xte, ytr, yva, yte = map(
    torch.from_numpy, (Xtr, Xva, Xte, ytr, yva, yte))

def student_case(seed, sample_count):
    if sample_count == len(ytr):
        keep = np.arange(len(ytr))
    else:
        keep, _ = train_test_split(
            np.arange(len(ytr)),
            train_size=sample_count,
            random_state=100+seed,
            stratify=ytr.numpy(),
        )
    seed_all(1000+seed)
    initial = copy.deepcopy(make_model((16,)).state_dict())
    return Xtr[keep], ytr[keep], initial

def run_mode(teacher, sample_count):
    validation = {}
    for T, hard_weight in GRID:
        runs = []
        for seed in TUNE_SEEDS:
            x, y, initial = student_case(seed, sample_count)
            kd = make_model((16,))
            kd.load_state_dict(initial)
            fit_kd(kd, teacher, x, y, T, hard_weight)
            runs.append(score(kd, Xva, yva)[0])
        validation[(T, hard_weight)] = np.mean(runs)

    T, hard_weight = max(validation, key=validation.get)
    rows = []
    for seed in TEST_SEEDS:
        x, y, initial = student_case(seed, sample_count)
        hard = make_model((16,))
        hard.load_state_dict(initial)
        fit_ce(hard, x, y)
        kd = make_model((16,))
        kd.load_state_dict(initial)
        fit_kd(kd, teacher, x, y, T, hard_weight)
        rows.append((*score(hard, Xte, yte),
                     *score(kd, Xte, yte)))

    result = np.asarray(rows)
    print("\nstudent inputs:", sample_count)
    print("selected T/hard weight:", T, hard_weight)
    print("hard acc/f1 mean±sd:",
          result[:, :2].mean(0),
          result[:, :2].std(0, ddof=1))
    print("KD acc/f1 mean±sd:",
          result[:, 2:].mean(0),
          result[:, 2:].std(0, ddof=1))
    print("KD-hard accuracy pp:",
          (result[:, 2]-result[:, 0]).mean())
    print("KD wins/ties:",
          (result[:, 2] > result[:, 0]).sum(),
          (result[:, 2] == result[:, 0]).sum())

started = time.perf_counter()
seed_all(42)
teacher = make_model((128, 64))
fit_ce(teacher, Xtr, ytr)
print("teacher acc/f1:", score(teacher, Xte, yte))
print("params teacher/student:",
      sum(p.numel() for p in teacher.parameters()),
      sum(p.numel() for p in make_model((16,)).parameters()))
run_mode(teacher, 200)
run_mode(teacher, len(ytr))
print("seconds:", time.perf_counter()-started)
十個未參與調參的隨機種子之手寫數字模型蒸餾實驗結果比較圖
固定 test、validation 選設定、10 個新 seed。在本設定、每個 seed 只看 200 筆輸入時,KD 高於 hard-only;看完整資料時差距只剩 0.037 個百分點。

結果 A:Student 只看 200 筆,KD 比 hard-label 訓練高 1.889 個百分點

Teacher 先用全部 1,257 筆訓練資料學習;每個 seed 再各自做一次可重現的分層抽樣,取 200 個輸入,而同一 seed 的 hard/KD Student 共用這批資料與完全相同的初始權重。Validation 選到 T=8、hard weight=0,也就是純 logit KD。Held-out test 上,Teacher accuracy 為 96.667%;hard Student 為 92.296%±1.220%,KD Student 為 94.185%±0.495%。KD 在 10 個 seed 中贏 9 次,平均多 1.889 個百分點;macro-F1 也從 92.141% 提高到 94.145%。

這不是「Student 憑空長出知識」。Teacher 看過 1,257 個標籤,Student 雖只看到 200 個輸入,卻透過 logits 接到 Teacher 從更多資料學到的類別關係。資料優勢被轉移,正是蒸餾本來要做的事。

結果 B:Student 看完整資料後略勝 Teacher,但不能把功勞算給蒸餾

完整資料對照把 Student 也改成看全部 1,257 筆,並重新只用 validation 選設定。Teacher 仍是 96.667%;hard Student 為 97.333%±0.383%,KD Student 為 97.370%±0.324%。兩個 Student 都略高於 Teacher,KD 相對 hard-only 只多 0.037 個百分點,而且 10 次裡有 9 次完全同分。

Test 只有 270 筆,答對一題就約等於 0.370 個百分點;本文不宣稱這個差距有統計顯著性。這組結果反而精準回答標題:Student 確實可能在一張窄考卷贏 Teacher,但 hard-only Student 也贏了,所以不能反推「蒸餾創造了超越老師的新智慧」。較小架構的歸納偏誤、最佳化與測試抽樣,都可能參與結果。參數少 14.2 倍也不等於實際延遲一定快 14.2 倍,速度仍須在目標硬體量測。

你可以先只改兩個旋鈕:temperature 與 hard weight,再觀察 validation 選擇如何變。若把實驗換成 LLM,Teacher 只提供完成文字、Student 用 SFT 模仿,應改稱 response imitation/synthetic SFT;要重現本節的 logit KD,則必須取得每個 token 的 Teacher 分布。PyTorch 的官方 Knowledge Distillation Tutorial也使用同樣的 softmax、KL、 與 hard-label CE 骨架。

怎麼公平判斷 Student 真的贏了 Teacher?先鎖定比較合約

看到「小模型擊敗大模型」時,不要先找立場,先把比較合約補完整。至少記錄以下七項:

  • 模型快照:Teacher/Student 的確切版本、參數量、tokenizer 與是否已預訓練。
  • 訓練訊號:logits、完整回覆、rationale、hidden states、偏好或 reward,究竟用了哪一種。
  • 額外教材:Student 是否取得人類標籤、更多資料、資料增強、拒絕採樣或 verifier。
  • 推論設定:prompt、system message、工具、temperature、rollout 次數與 token/時間預算是否一致。
  • 題庫與指標:資料 split、版本、污染檢查、metric 與 grader 是什麼。
  • 不確定性:樣本數、重跑 seeds、信賴區間或統計檢定;不要只看小數點後一位。
  • 能力範圍:勝出的是一項任務、某個領域、人類偏好,還是涵蓋能力與安全的多組 held-out evals。

NeurIPS 2021 的研究還顯示,Student 的泛化成績與「忠實模仿 Teacher 分布」不是同一件事:模仿得更像不一定考得更好,考得更好也不代表完整複製 Teacher。這也是為什麼單一榜單無法反推出訓練來源。

拿 API 回覆訓練可以嗎?技術分類、合約權限與指控證據要分開

「能不能用文字做 response distillation」是技術問題;「能不能用某個服務的輸出訓練」是合約與授權問題;「某模型是否真的這樣訓練」則是證據問題。三者不能互相代答。

截至 2026 年 7 月 30 日,三份官方條款對競爭模型的限制寫法並不相同:OpenAI Services Agreement §3.3(e)(2026 年 1 月 1 日生效)限制用 Output 開發競爭 AI 模型,並另列 permitted exceptions;Anthropic Commercial Terms D.4(2025 年 6 月 17 日生效)限制存取 Services 建立競爭產品,包括訓練競爭 AI 模型,除非取得明確批准;Gemini API Additional Terms(2026 年 3 月 23 日生效)則限制用 Services 開發與其競爭的模型。這些是特定商用或開發者產品的條款,不能直接套到其他帳戶、產品或雲端合約。

輸出權利與使用限制也要分開:OpenAI 與 Anthropic 的條款談到客戶對 Output 的權利,Google 對部分服務所生成的原創內容表示不主張所有權;這些文字都不等於取得不受限制的訓練用途。反過來,也不能只看到「蒸餾」兩字就斷言違約、侵權或其他違法,因為還要確認產品、條款版本、Order Form 或書面批准、法域與實際行為。

若要判斷一項「蒸餾指控」,證據強度可分三層:

  • 較強、仍須交叉驗證:技術報告或 model card 具體揭露 Teacher 與資料管線;能把 API 查詢與回覆連到訓練資料或特定 run 的來源鏈與紀錄;經盲測、誤報率校準且可獨立重現的模型鑑識。單獨的大量 API traffic 只能證明曾存取,不能證明回覆進入訓練。
  • 支持假說、仍不能定案:異常集中的查詢模式、罕見錯誤高度重複、能力輪廓與發布時序相符;仍需排除共同資料、公開模型與其他 Teacher。
  • 弱線索:模型自稱某品牌、語氣相似、某個 benchmark 接近、模型更小或價格更便宜。它們最多只能產生查核問題。

這正是兩場 Reddit 爭論——「Student 能否勝過 Teacher」與「什麼才算 distillation」——最容易錯位的地方。技術術語很寬,不代表證據門檻可以很低。若想理解「開放權重」和「可任意使用」也不是同義詞,可延伸讀〈AI 巨頭為何捍衛開放權重模型〉。

模型蒸餾 8 個常見問題(FAQ)

Q1. 模型蒸餾一定是大模型教小模型嗎?

不一定。常見目標確實是把大 Teacher 壓進小 Student,但兩者也可同尺寸、同架構,或是同一模型的不同 checkpoint。Teacher/Student 描述訊號提供者與學習者,不是參數量的正式定義。

Q2. 沒有 Teacher logits,還能叫蒸餾嗎?

不能叫 logit distillation,但正式文獻也使用 sequence-level KD、black-box KD 與 response distillation。最精確的做法不是爭奪一個唯一名稱,而是說清楚 Student 實際看到了 logits、文字回覆、rationale,還是偏好分數。

Q3. Teacher 生成的資料就一定是合成資料嗎?

由模型產生的 prompt、回答、rationale 或標籤通常可稱 synthetic data;但合成資料也能由規則、模擬器或多模型協作產生。Synthetic 描述來源,沒有自動保證正確、合法或適合訓練。

Q4. SFT 和蒸餾可以同時發生嗎?

可以。若固定 Teacher 產生回答,Student 用 next-token cross-entropy 模仿,訓練方法是 SFT,資料來源是 synthetic,師生關係則可稱 response distillation。三個描述同時成立。

Q5. 蒸餾後一定更快、更省記憶體嗎?

不一定。只有 Student 架構、參數量或推論方式更省時,才會得到部署優勢;同尺寸 self-distillation 可能只追求準確率或正則化。速度還要在相同硬體、batch、序列長度與軟體堆疊實測。

Q6. 量化會讓模型變笨嗎?

低精度表示會引入近似誤差,品質可能小幅下降,也可能在特定評測因噪音而持平或波動;不能從「4-bit」直接推算智力損失。量化的主要目的不是教新行為,而是改變權重/activation 如何表示與運算;低精度近似仍可能改變輸出,QAT(quantization-aware training)也會在量化模擬下更新參數。

Q7. Student 某項分數比較高,就證明它來自該 Teacher 嗎?

不能。相同公開資料、相近架構、benchmark 專訓、不同提示與其他 Teacher 都可能產生類似分數。訓練來源需要 provenance、紀錄、流量或經校準的鑑識證據,不能只靠輸出觀感。

Q8. 一般人該先學蒸餾、量化,還是提示工程?

若只想讓現成模型把一次任務答好,先改善 prompt 與 context;需要最新或私有資料,再加搜尋/RAG;有大量重複任務與可量測 eval,才考慮 SFT 或蒸餾;部署記憶體不足再評估量化。〈Context Engineering 上下文工程〉會先教你不更新 weights 的低成本槓桿。

給新手的 6 個重點

  1. 先問 Student 看到了什麼:logits、文字、rationale、偏好或 reward,名稱才有意義。
  2. 記住五個維度:SFT 是方法、synthetic 是來源、distillation 是關係、RL 是評分迴圈、quantization 是表示壓縮。
  3. Student 不一定小:它是一個訓練角色,不是尺寸規格。
  4. 窄任務勝出完全可能:額外標籤、篩選、專訓與正則化,都可能讓 Student 贏一張考卷。
  5. 單榜勝出不是全面超越:比較必須附模型版本、資料、prompt、metric、推理預算與不確定性。
  6. 技術可行不等於取得授權:先查實際服務的現行條款與資料 provenance,再談訓練。

📚 延伸閱讀

結語:別再問「算不算蒸餾」,先把訊號、資料、方法與評測寫出來

模型蒸餾真正值得理解的,不是哪一派搶到 distillation 的字典定義,而是 Teacher 的什麼訊號,經過什麼資料管線與 loss,改變了哪個 Student。只要把這四件事寫清楚,logit KD、response imitation、synthetic SFT、RL 與量化就不會再攪成一團。

下次看到「小模型超越大模型」,先做一件事:找出 benchmark、Teacher 的提示方式、Student 的額外資料與重跑誤差。若四項缺任何一項,把結論先降級成「在目前公開設定下的單項勝出」。你也可以從本文的 CPU 小實驗開始,改動 temperature 與蒸餾權重,親眼看見 Teacher 訊號何時有幫助、何時反而拖累 Student。想系統化練習把技術拆成可驗證流程,也可查看 AlphaLab 的教學課程

ALPHALAB 社群

有問題?來 Telegram 聊

和 Terry、編輯、其他網友一起討論這篇文章。提問、分享觀點,回覆更即時。

加入 Telegram 討論

📩 訂閱 AlphaLab 電子報

每週一封,第一時間收到新文章與投資觀察。

我們不會 spam,隨時可退訂。