版本說明:本文依據 CMU 11-868 LLM Systems 2026 春季版。主要材料是 4/8 的 第 23 講投影片 Parameter Efficient Fine-Tuning for LLM(Lei Li,PDF 共 46 頁;下文頁碼指 PDF 頁序,不是投影片角落的編號),以及 Syllabus 列的三篇 reading:CIAT、LoRA、QLoRA。事實皆於 2026-09-30 打開官方材料核對。存取等級 A3:投影片公開;拿不到的是課堂錄影(本課沒有公開錄影)與 Canvas 上的課後 Quiz。
系列位置:上一篇 L12–L13 TPU、JAX 與 Pallas/Splash Attention|下一篇 L22、L24 LLM 服務:排程、RadixAttention 與 PagedAttention|系列總覽
前幾講一直在問「怎麼把一次訓練跑快、跑得下」。第 23 講換一個場景:模型已經預訓練好了,你只想讓它學會一個新任務或新領域,手上卻只有一兩張卡。
這講的回答分兩層。第一層是 LoRA:凍結原權重,只訓練一個低秩的增量。第二層是 QLoRA:連凍結的權重也壓成 4-bit。兩層加起來,投影片把 LLaMA-8B 的微調記憶體從約 80GB 算到約 9.2GB。
投影片第 2 頁先回顧上一講的量化(absmax、zero-point、LLM.int8()、GPTQ),因為 QLoRA 會直接用到。沒讀過的話,先看本系列的 L19–L20 模型量化。
先算帳:全參數微調為什麼貴
投影片第 4–6 頁用同一張「每個參數要花多少 bit」的表,比較三種做法:
| 做法 | 權重 | 權重梯度 | optimizer state | adapter 權重 | LLaMA-8B 工作記憶體 |
|---|---|---|---|---|---|
| 半精度全參數(Adam) | 16 bit | 16 bit | 2 × 16 bit | — | 約 80GB |
| LoRA | 16 bit | 約 0.4 bit | 約 0.8 bit | 約 0.4 bit | 約 33GB,單張 A100 放得下 |
| QLoRA | 4 bit | 約 0.4 bit | 約 0.8 bit | 約 0.4 bit | 約 9.2GB |
三列的 activation 都寫成「約參數量的 1–2 倍」,不因方法而變。這張表的讀法是:全參數微調最貴的不是權重本身,是梯度加上 Adam 的兩份 moment;LoRA 砍的就是這兩塊。
第 7 頁把 PEFT 分三類,引自 Lialin et al. 的綜述:
- Selective:只微調挑出來的一部分參數。
- Reparameterization:用低秩表示權重的更新。LoRA 在這一類。
- Additive:加上可訓練的新層或新參數,例如 adapter、soft prompt。
LoRA:凍結 W,只學 A·B
第 9–10 頁的式子就一行:凍結預訓練權重 W,學一個低秩增量。
W′ = W + A·B,其中 A 是 d×r、B 是 r×d,r 遠小於 d。
第 10 頁特別寫了這個想法的來歷:最早出現在多語翻譯的 Counter-Interference Adapter(CIAT,EMNLP 2021),後來由 LoRA(ICLR 2022)「re-invented」。兩篇的 arXiv 首版分別是 2021 年 4 月與 6 月。之後投影片一律寫成「LoRA/CIAT」。
放在哪幾個矩陣。第 11 頁的建議是 rank 取 8 或 16,套在 attention 的 W_Q、W_K、W_V、W_O,不套在 FFN 的線性層;投影片的理由是 FFN「storing knowledge」。同一頁也補了一句:CIAT 把它同時套在 embedding 與 FFN 上,效果有提升。這兩句放在一起,代表「只套 attention」是一個預設,不是定律。
推論時怎麼用(第 12 頁)。直接算出 W′ = W + A·B 當成一般權重用,額外只需要存 A、B。要換任務時,減掉舊的、加上新的:W″ = W′ − A·B + A″·B″。一個底座模型因此可以掛很多組領域專用的小 adapter。
反向傳播只算兩個小梯度(第 13 頁)。W₀ 固定,只需要對 A、B 求導:
- ∂L/∂A = g_out · (Bx)ᵀ
- ∂L/∂B = (g_out · A) · xᵀ(照投影片的寫法;把轉置按維度寫清楚是 (Aᵀ · g_out) · xᵀ)
如果你做過本系列的 HW2 MiniTorch,這就是把 matmul 的反向規則套兩次。
要存什麼(第 14 頁):原參數本身,加上 adapter 權重、adapter 梯度、adapter 的兩份 Adam moment(各 2×d×r),以及 activation。原參數不需要梯度與 optimizer state。
第 15 頁把數字放在一起看:LLaMA 8B 的 80 億參數在 BF16 下是 16GB,Adam 的 optimizer state 是 48GB;換成 LoRA,可訓練參數只剩約 4M,對應 8MB 權重與 24MB optimizer state。第 16 頁的結論是記憶體與訓練時間都下降,推論則跟一般 LLM 一樣。
rank 要取多大
第 17–21 頁整理 LoRA 論文的實驗:NLU 用 RoBERTa、DeBERTa 跑 GLUE 的八個子任務,NLG 用 GPT-2、GPT-3,和全參數微調、BitFit、兩種 prefix tuning、adapter tuning 比較。投影片擷取的要點有兩個:
- 第 19 頁:把 rank 調高並不會涵蓋更多有意義的子空間,r=8 的低秩矩陣就夠。
- 第 20 頁:把規模拉到 175B 的 GPT-3 做壓力測試,不是每種方法都會隨可訓練參數增加而單調變好。
第 21 頁另外放了一張 LoRA 在 GSM8K 數學題上的表現圖,投影片沒有配文字說明結論,這裡不替它下結論。
QLoRA:連凍結的權重也壓成 4-bit
第 23 頁先分清兩種量化。上一講的 GPTQ 是 post-training quantization:模型訓練完才轉低精度,不再訓練。QLoRA 則被歸在 quantization-aware training:量化發生在訓練階段,通常效果較好。
第 24 頁列出 QLoRA(NeurIPS 2023) 的三項創新:4-bit NormalFloat 儲存、double quantization、paged optimizer;計算一律用 BF16。投影片引論文的結果:65B 模型的微調記憶體平均需求從 780GB 降到單張 GPU 的 48GB,表現與 16-bit 微調相當。
第 25 頁的演算法是一條「存 4-bit、算 16-bit」的管線:
- 用雙重量化把權重存成 NF4。
- 用到時反量化成 BF16。
- 前向與反向都在 BF16 做。
- 只對 LoRA 參數算 BF16 權重梯度。
NF4:為什麼不用等寬分箱
4-bit 只有 16 個值。第 26 頁指出,absmax 那種等寬分箱遇到分布不均的資料會很吃虧:大量彼此差很少的小數值會被量化到同一格。
第 27 頁的 NF4 做法:
- 每 64 個權重一組。
- 找組內最大絕對值當 scale。
- 把 64 個數除以 scale,落到 [−1, 1]。
- 在一張 16 值的查表裡找最近的值,輸出它的索引(−7 到 8)。
這張查表不是等距的:靠近 0 的格子密,靠近 ±1 的格子疏。第 29 頁說明這些值取自分位數(probably quantile)。
第 28 與 30 頁手算一個例子,值得跟著算一次:
- 原值 0.0045,組內 scale 0.0071,正規化後約 0.63。
- 查表最近的是 0.5626,索引是 6。
- 反量化:0.5626 × 0.0071 ≈ 0.00399,誤差約 0.0005。
Double quantization:scale 本身也要壓
第 31 頁點出小 block 的代價:每 64 個參數配一個 32-bit 常數,平均每個參數多花 32/64 = 0.5 bit。
第 32 頁的解法是再量化一次:每 64 個值做一次 NF4,產生的 scale 每 256 個一組用 FP8 量化,第二層的 scale 才用 FP32 存。投影片算出的結果是每個參數約 0.52 bytes。
第 33 頁把 QLoRA 的完整配置收在一起:預訓練權重存 NF4 加雙重量化,LoRA 權重存 BF16,輸入與所有計算(前向、反向、optimizer)都用 BF16。
Paged optimizer:快爆時先換到 CPU
第 34–36 頁處理的是訓練中偶發的 OOM。做法是用 NVIDIA unified memory 配置 optimizer state:GPU 記憶體不夠時,這些 state 自動逐頁移到 CPU,到 optimizer 更新那一步需要時再搬回 GPU。投影片把它比作 CPU RAM 與硬碟之間的一般分頁。
第 37–38 頁引論文的兩個結果:LoRA 的預設超參數追不上 16-bit 的表現;NF4 比 4-bit float(FP4)好;調好之後,4-bit QLoRA 可以對上 16-bit 全參數微調與 16-bit LoRA。
程式碼導覽
第 40–42 頁是 LoRA 層的實作截圖,重點有三個:初始化 A、B 兩層;凍結預訓練權重;前向時把兩條分支(原權重、低秩分支)的結果加起來,訓練完可以把 LoRA 權重併回原權重。
第 43 頁示範 QLoRA 的用法:用帶 quantization config 的方式載入模型,再照常套 LoRA;底層的 CUDA 量化運算由 bitsandbytes 的 wrapper 提供。投影片上的設定大致如下(模型名稱照投影片):
AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-2-70b",
quantization_config=BitsAndBytesConfig(
load_in_4bit=args.bits == 4,
load_in_8bit=args.bits == 8,
llm_int8_threshold=6.0,
llm_int8_has_fp16_weight=False,
bnb_4bit_compute_dtype=compute_dtype,
bnb_4bit_use_double_quant=args.double_quant,
bnb_4bit_quant_type=args.quant_type,
),
)
同頁附了 QLoRA repo 的 Guanaco 7B Colab 範例。
這講跟作業的關係
LoRA 會在 HW6 直接用到:作業要你在 DeepSpeed ZeRO 上打開 LoRA,讓 Llama-2-7B 的訓練塞進 2 張 16GB 的 V100。這講的記憶體帳,就是你在作業裡調參數時要心算的那張表;ZeRO 那一半請先讀 L18 ZeRO。
第 44–45 頁的總結:LoRA/CIAT 用少量低秩參數就能便宜地適配大模型,對 GPT-3 這種規模也有效,低資料量時表現更好;QLoRA 用 NF4 雙重量化存權重、用 BF16 計算,表現與原本的 LoRA 相當,投影片稱它是第一個能在單張消費級 GPU 上微調 33B LLM 的方法。
自學怎麼做
- 讀投影片第 4–6 頁,自己用「每參數 bit 數 × 參數量」重算一次三列記憶體,確認你知道哪一塊被砍掉。
- 跟著第 28、30 頁手算 NF4 的量化與反量化,再換一個數字算一次。
- 讀 LoRA 論文談 rank 的實驗段落,對照投影片第 19 頁。
- 有 GPU 的話,用第 43 頁的設定載入一個小模型,比較開關
bnb_4bit_use_double_quant前後的顯存。
延伸閱讀
- 量化的前因:L19–L20 模型量化
- 訓練端的另一種省記憶體方式:L18 ZeRO
- 從記憶體與算力的角度估算訓練成本:CS336 資源估算
參考資料
- CMU 11-868 LLM Systems(Spring 2026)課程首頁
- 11-868 Syllabus(Spring 2026) — 4/8 講次與 CIAT、LoRA、QLoRA 三篇 reading
- 第 23 講投影片:Parameter Efficient Fine-Tuning for LLM — 記憶體帳、LoRA/CIAT、NF4、double quantization、paged optimizer、程式碼導覽
- Zhu et al., Counter-Interference Adapter for Multilingual Machine Translation(arXiv 2104.08154)
- Hu et al., LoRA: Low-Rank Adaptation of Large Language Models(arXiv 2106.09685)
- Dettmers et al., QLoRA: Efficient Finetuning of Quantized LLMs(arXiv 2305.14314)
- Lialin et al., Scaling Down to Scale Up: A Guide to Parameter-Efficient Fine-Tuning(arXiv 2303.15647) — 投影片第 7 頁的 PEFT 分類出處
- artidoro/qlora GitHub repo — 投影片第 43 頁連的 Guanaco 範例
- bitsandbytes — QLoRA 程式碼使用的量化 wrapper
Loading...