LLM 相關知識
精度 (Precision)
精度決定了用多少位元(bits)來表示一個數字,位元數越多,表示越精確,但佔用記憶體也越多。
| 精度類型 | 位元數 | 記憶體大小 | 說明 |
|---|---|---|---|
| FP32 | 32-bit | 4 bytes | 標準單精度浮點數,訓練時最常用 |
| FP16 | 16-bit | 2 bytes | 半精度,速度快但範圍小 |
| BF16 | 16-bit | 2 bytes | Google 開發,數值範圍與 FP32 相同 |
| INT8 | 8-bit | 1 byte | 整數量化,推理常用 |
| INT4 | 4-bit | 0.5 bytes極度壓縮,適合在消費級 GPU 上跑大模型 |
浮點數的儲存格式分三個部分:
| |
FP32 (32 bytes)
| |
FP16 (16 bytes)
| |
INT8 (8 bytes)
| |
可以看出精度越下降,代表該數字的位元也會減少,模型中的權重也是透過數值儲存,因次若使用較低精度,會造成一定程度的資訊遺漏。
舉例:2.3 2.3 為一循環小數,所以會有小數點
|精度實際儲存的值|誤差| |FP32|2.29999995231628…|約 0.000000048| |FP16|2.30078125|約 0.00078 |BF16|2.296875|約 0.003 |INT8|2|誤差 0.3(直接截斷小數!)
當模型具有數億參數時,即使原本的誤差很小,也會被放大,因此需要進行量化
量化(Quantization)
| |
量化的兩種類型
- PTQ (Post-Training Quantization) 模型訓練完之後才進行量化,不需要重新訓練
| |
- QAT (Quantization-Aware Training) 在訓練過程中就模擬量化的誤差
| |
主流量化格式比較
| 格式 | 全名 | 主要用途 | 特點 |
|---|---|---|---|
| GGUF | GPT-Generated Unified Format | 本地部署 | llama.cpp 使用,CPU 也能跑 |
| GPTQ | GPT Quantization | GPU 推理 | 精度損失小,速度快 |
| AWQ | Activation-aware Weight Quantization | GPU 推理 | 比 GPTQ 更準確 |
| BNBQ | BitsAndBytes Quantization | 訓練/推理 | 整合進 HuggingFace,使用方便 |
GGUF(最適合本地部署) 專為 llama.cpp 設計,可以在沒有強力 GPU 的情況下運行:
- CPU + GPU 混合運算
- 支援 Mac M系列晶片
- 量化等級多樣(Q2 到 Q8)
- Ollama、LM Studio 都使用這個格式
GPTQ(GPU 推理首選) 針對 每一層 做最佳化量化:
| |
AWQ(目前最先進之一) GPTQ 的進化版,關鍵洞察:
| |
懶人包:
| |
微調 (QLoRA)
1. 為什麼需要 QLoRA?
全量微調(Full Fine-tuning)需要更新模型所有權重,對於數十億參數的 LLM 來說,所需的 GPU 記憶體遠超過一般硬體能負擔。
QLoRA 的目標是:在消費級 GPU 上也能微調大型模型,例如在單張 RTX 4090 上微調 13B 模型。
2. QLoRA 的兩個核心概念
QLoRA = Quantization(量化)+ Low Rank Adaptation(低秩適應)
2-1. 量化(Quantization)
將 Base Model 的權重從 BF16 壓縮為 INT4,大幅節省記憶體。
| |
- INT4 代表每個數值只用 4 個 bit 儲存
- 量化後精度會有損失,但這個損失在量化時就已接受
2-2. LoRA(低秩適應)
不直接修改原始權重,而是在旁邊外掛兩個小矩陣 A 和 B,只訓練這兩個矩陣。
| |
3. LoRA 的核心假設
微調時,權重的更新量 ΔW 本身就是低秩的
代表模型學習新任務所需的「調整方向」很少,不需要動到整個高維度的權重矩陣。
低秩分解的意義
| |
4. 兩個部分的分工
| 部分 | 格式 | 是否訓練 | 目的 |
|---|---|---|---|
| Base Model 權重 | INT4 | ❌ 凍結 | 節省記憶體 |
| LoRA 矩陣(A、B) | BF16 | ✅ 訓練 | 學習新知識 |
5. 動態反量化(Dynamic Dequantization)
前向傳播時,INT4 的 Base Model 不是直接用 INT4 做計算,而是逐層、即時還原成 BF16:
| |
為什麼逐層而非一次全部還原? 若一次全部還原,記憶體用量等同直接載入 BF16 模型,失去量化省記憶體的意義。
6. LoRA 插入的位置
Transformer 每一層的結構
| |
LoRA 掛載位置的選擇
| 設定 | 插入位置 |
|---|---|
| 保守 | Wq、Wv |
| 常見(推薦) | Wq、Wk、Wv、Wo |
| 激進 | Attention 全部 + FFN |
- LoRA 每一層 Transformer 都會掛,不是只有最後一層
- Attention 負責調整「關注模式」,FFN 負責儲存知識
- 需要注入大量新知識時,才需要在 FFN 加 LoRA
為什麼 Wo 也需要加?
Attention 使用 Multi-Head 機制,每個 Head 各自運算後 Concat 在一起,Wo 負責整合所有 Head 的結果並壓回原始維度。若只調整 Wq/Wk/Wv 而不調整 Wo,新學到的關注模式無法被有效傳遞。
7. 超參數 r(秩)
r 決定 LoRA 矩陣的維度大小,代表「給模型可以調整的方向數量」。
| 情境 | 建議 r |
|---|---|
| 風格、語氣調整 | 8 ~ 16 |
| 特定領域知識注入 | 16 ~ 64 |
| 複雜指令、多任務 | 64 ~ 128 |
r = 16 是穩健的起點。
| 問題 | 說明 |
|---|---|
| r 太小 | 學習空間不足,任務能力不足 |
| r 太大 | 接近全量微調,失去省資源優勢,可能過擬合 |
8. LoRA 的合併(Merge)
為什麼要合併?
若不合併,推論時每層都要分別計算 Base 輸出和 LoRA 輸出再相加,速度較慢。
合併的數學
| |
合併後 A、B 矩陣可以丟棄,只保留 W_new。
合併流程(因 INT4 無法直接與 BF16 相加)
| |
也可以選擇不合併的情境
- 同一個 Base Model 需要切換多個 LoRA(不同任務)
- 仍在持續微調階段
- 快速實驗比較不同 LoRA 效果
9. QLoRA 完整生命週期
| |
10. 精度選擇總結
| 階段 | 格式 | 原因 |
|---|---|---|
| 推論(Inference) | INT4、GGUF 等 | 省記憶體、加速 |
| 微調 Base Model | INT4(凍結) | 省記憶體 |
| 微調 LoRA 矩陣 | BF16 | 梯度計算需要足夠精度 |
| 合併後部署 | INT4 / GGUF | 重新量化以節省資源 |
精度損失只發生在往下降的時候,往上升不會新增損失,只是無法找回已丟失的資訊。