# 論文閱讀 : QLoRA
[論文連結](https://arxiv.org/pdf/2305.14314)
## 研究核心
- QLoRA 是一種高效的微調方法,允許在 單張 48GB GPU 上微調 65B 參數模型,同時保留接近 完整 16-bit 微調效能。
- 方法:將梯度反向傳播至 Low-Rank Adapters (LoRA),而非原始模型,後者是4-bit 量化的 frozen 預訓練模型。
- 所訓練的 Guanaco 模型系列 在 Vicuna benchmark 上表現出色,達到 ChatGPT 效能的 99.3%。
- 僅需 24 小時在單顆 GPU 上完成微調。
### 技術核心
- 4-bit NormalFloat (NF4):
- 為常態分布權重設計的資訊理論最佳 4-bit 數據類型。
- Double Quantization:
- 將量化常數進行再次量化,進一步壓縮記憶體需求。
- Paged Optimizers:
- 解決訓練過程中的記憶體尖峰問題。
### 大規模實驗與分析
- 使用 QLoRA 微調超過 1,000 個模型,橫跨:
- 8 個 instruction dataset
- 多種模型架構(如 LLaMA、T5)
- 多種模型規模(如 33B、65B)
- 即使使用較小模型,配合高品質資料集,也能超越先前 SOTA 模型。
#### 評估與觀察
- 使用 GPT-4 評估 代替人類評估,發現兩者高度一致,可作為成本效益高的替代方案。
- 指出目前常見 chatbot benchmark 存在可信度問題。
### Block-wise k-bit Quantization
**給定傳統量化公式 Equation (1)**
$$
\mathbf{X}^{\text{Int8}} = \text{round}\left( \frac{127}{\text{absmax}(\mathbf{X}^{\text{FP32}})} \cdot \mathbf{X}^{\text{FP32}} \right)
$$
其中:
* $\mathbf{X}^{\text{FP32}}$:原始浮點數張量
* $\mathbf{X}^{\text{Int8}}$:量化後的整數張量
* $c = \frac{127}{\text{absmax}}$:量化常數(scale factor)
**反量化**
$$
\mathbf{X}^{\text{FP32}} = \frac{\mathbf{X}^{\text{Int8}}}{c}
$$
### 全域量化的問題:Outlier 影響
因此採用 Block-wise Quantization,將張量切成「小區塊(blocks)」,**每個區塊單獨計算自己的 absmax 與量化常數**
#### 作法:
1. 假設輸入張量為 $\mathbf{X} \in \mathbb{R}^{b \times h}$。
2. 將它**展平成一維向量**,然後切成大小為 $B$ 的 $n$ 個連續區塊(block)。
$$
n = \frac{b \times h}{B}
$$
3. 每個 block 都**單獨使用 Equation (1)** 做量化,得到對應的量化常數 $c_i$。
### 顯存需求 : LoRA 在訓練期間的效能與負載
- LoRA 的記憶體佔用非常低
- LoRA 的引入僅需極少量的參數(約為原始模型的 0.2%)。
- 在 LLaMA 7B 模型上,LoRA 參數僅佔 26 MB。
- 主要記憶體瓶頸在於梯度(activations gradients)
- 即使使用 LoRA,訓練時仍需儲存 LoRA 輸入梯度:
- 原始未優化:567 MB
- 使用 gradient checkpointing 後可降低至:18 MB / 序列
- ➜ 仍然遠大於 LoRA 參數本身的大小
- 由於 LoRA 本身極輕量,可以增加更多 Adapter 以提高效能,而不會大幅增加訓練記憶體。
- 這對於恢復接近 full 16-bit 精度的效能非常關鍵。
## 方法重點
- 目標:在 單台機器上穩定進行高效的 4-bit finetuning,同時保留接近 full-precision 效能。
- 三大技術
- 4-bit NormalFloat (NF4):一種為常態分布優化的量化格式
- Double Quantization:進一步壓縮記憶體
- Paged Optimizers:避免 gradient checkpointing 過程中的記憶體尖峰導致 OOM
### 訓練與量化流程架構
- 儲存格式:4-bit(低精度)
- 運算格式:BFloat16(計算用)
- 運算流程:使用時先 dequant 到 BFloat16,再進行 16-bit matrix multiplication
### 4-bit NormalFloat (NF4)
- 建立於 Quantile Quantization:透過分位數讓每個 quantization bin 有等量的數值落入,是資訊理論上的最佳方式。
- 針對常態分布優化
- 多數神經網路權重具有 0 均值、標準差為 σ 的常態分布。
- 將所有 weight tensor 經過標準化(rescale 到標準常態分布),就可以精確地使用固定 quantile 值來量化。
- 過程
- 1. 將理論標準常態分布 $N(0, 1)$ 分成 $2^k + 1$ 段,取得其 quantile 值
- 2. 把這些 quantile 值正規化到 $[-1, 1]$
- 3. 將實際的 weight tensor 也正規化到 $[-1, 1]$,即可對應到這些量化 bin
- 計算每個 bin 的代表值:
$$
q_i = \frac{1}{2}\left( Q_X\left(\frac{i}{2^k+1}\right) + Q_X\left(\frac{i+1}{2^k+1}\right)\right)
$$
#### Asymmetric NormalFloat
* **問題**:對稱的 k-bit 量化無法保證剛好有「0」這個離散值,但這對於 padding 和零值元素至關重要(在 Padding token、Masking 的 zero 值、稀疏矩陣中本來就是 0 的元素,這些「本身就該是零」的數值,在量化時必須能夠被準確表示為零)。
* **解法**:分別對負值與正值區間取不同數量的 quantile(如負側 $2^{k-1}$,正側 $2^{k-1}+1$),合併後移除重複的 0。
* 最終結果:稱為 **NFk(NormalFloat-k)**,能保證:
* 0 為可精確表示的值
* 每個 bin 期望落入等量數值
* 適合 zero-centered normal 分布,為資訊理論上最優的量化方案
### Double Quantization
- 目的:進一步降低記憶體佔用
- 雖然 4-bit 精準量化需要較小的 block size(如 64),但這會帶來額外的記憶體開銷,因為每個 block 都需要額外儲存一個 32-bit 的量化常數(scale)。
- 在 block size 為 64 的情況下,這等同於 每個參數多佔用 0.5 bits。
**記憶體節省效果**
| 項目 | 計算方式 | 每參數佔用 (bits) |
| ----------------------------- | ------------------------------ | ---------------- |
| 原始 32-bit 常數(block size = 64) | $32 / 64$ | **0.5 bits** |
| DoubleQuant 後 | $8 / 64 + 32 / (64 \cdot 256)$ | **≈ 0.127 bits** |
🔻 節省:**0.373 bits/參數**
#### 量化「量化常數」本身
- 第一層量化:
- 原始張量 $\mathbf{W}$ → 使用 4-bit 量化
- 會得到一組 **32-bit 的量化常數** $c_2^{\text{FP32}}$
- 第二層量化(DoubleQuant)
- 將這些量化常數 $c_2^{\text{FP32}}$ 當作輸入
- 使用 **8-bit Float** + block size 256 進行再次量化:
- 得到 **量化後的量化常數** $c_2^{\text{FP8}}$
- 以及 **新的量化常數** $c_1^{\text{FP32}}$
- 因為 $c_2^{\text{FP32}}$ 為正值,為了更有效率地量化,先 **做 mean subtraction**,使其中心化,再使用**對稱量化**(更節省 bits)。
### 完整定義
### Forward Pass 計算公式:
$$
\mathbf{Y}^{\text{BF16}} = \mathbf{X}^{\text{BF16}} \cdot \text{doubleDequant}(c_1^{\text{FP32}}, c_2^{\text{k-bit}}, \mathbf{W}^{\text{NF4}}) + \mathbf{X}^{\text{BF16}} \cdot \mathbf{L}_1^{\text{BF16}} \cdot \mathbf{L}_2^{\text{BF16}}
$$
其中
| 項目 | 說明 |
| ----------------------------- | ---------------------------- |
| $\mathbf{X}^{\text{BF16}}$ | 輸入資料(已轉為 BFloat16) |
| $\mathbf{W}^{\text{NF4}}$ | 儲存為 4-bit NormalFloat 的權重 |
| $\text{doubleDequant}(\cdot)$ | 將權重從 NF4 經雙層反量化,轉回 BF16 精度 |
| $\mathbf{L}_1, \mathbf{L}_2$ | LoRA adapter 的可訓練權重(BF16 精度) |
| $\mathbf{Y}^{\text{BF16}}$ | 最終輸出結果,仍在 BF16 精度下 |
#### Double Dequantization
$$
\text{doubleDequant}(c_1^{\text{FP32}}, c_2^{\text{k-bit}}, \mathbf{W}^{\text{k-bit}}) = \text{dequant}(\text{dequant}(c_1, c_2), \mathbf{W})
$$
* 先將量化常數 $c_2^{\text{k-bit}}$ 使用 $c_1^{\text{FP32}}$ 做反量化 → 得到 FP32 scale
* 再用這個 scale 去反量化 $\mathbf{W}^{\text{NF4}}$ → 得到 $\mathbf{W}^{\text{BF16}}$
| 元件 | Blocksize | 精度 | 理由 |
| ------------ | --------- | --------- | ------------------- |
| $\mathbf{W}$ | 64 | 4-bit NF4 | 提高量化精度 |
| $c_2$ | 256 | FP8 | 減少儲存成本(DoubleQuant) |
### 實驗與分析
#### 核心問題與目標
- 問題:QLoRA 是否能在極低記憶體需求下,表現接近或等同 full-model finetuning?
- 進一步探討:
- NF4 資料型態 vs. 一般 4-bit 浮點數的表現差異
- 各元件(如 Double Quantization、PagedOptim)對效能的貢獻與限制
#### 實驗觀察
#### 模型與資料集
* 模型涵蓋:RoBERTa、T5(80M~11B)、LLaMA(7B~65B)
* 任務資料集:
* **GLUE**(文本分類)
* **Super-NaturalInstructions**(指令式任務)
* **MMLU**(5-shot 評估)
* 評估指標:
* GLUE:Accuracy
* Super-NaturalInstructions:Rouge-L
* MMLU:5-shot accuracy
#### 資料型態比較
* Int4
* FP4(E2M1、E3M0 variants)
* **NF4 + Double Quantization**
* 所有模型尺寸:125M ~ 65B
1. 預設 LoRA 設定 無法達到 full finetuning 效能
- 常見做法只對 query / value 做 LoRA,對於大型模型(如 LLaMA 7B)來說 不夠用。
- 要達到 16-bit 全微調表現,需要對 所有 Transformer block 中的線性層都加入 LoRA。
- 投影維度$r$等超參數影響反而不大。

2. 圖表(Figure hyper)說明
- Stanford Alpaca 預設超參數 vs. QLoRA 全層 LoRA 超參數
- 發現 QLoRA 搭配合理超參數能接近甚至超越 full finetuning
3. NF4 > 其他 4-bit 資料型態
- 實驗資料:Common Crawl 子集(Perplexity 評估)
- 使用模型:OPT, BLOOM, LLaMA, Pythia
-
| 資料型態 | 平均 Perplexity (PPL) |
| ------------- | ------------------- |
| Int4 | 34.34 |
| Float4 (E2M1) | 31.07 |
| Float4 (E3M0) | 29.48 |
| **NF4 + DQ** | **27.41** |
**NF4 + Double Quantization** 在保留精度與節省記憶體之間達到最佳平衡。
#### 可恢復 4-bit 量化帶來的效能損失
* 雖然 4-bit inference 通常會降低準確率,但透過 **adapter-based finetuning(如 QLoRA)** 可**完全恢復性能**
* 在 GLUE 與 Super-NaturalInstructions 任務中:
* **16-bit LoRA ≒ 8-bit ≒ 4-bit QLoRA(NF4) ≒ Full finetuning**
* 在 LLaMA 7B~65B + MMLU 評估中:
* **QLoRA(NF4+DQ)** 幾乎與 16-bit LoRA 相同
* 使用 **FP4** 則落後約 **1% 的準確率**
#### 實驗表格
| 方法 | GLUE (Acc.) | T5-3B RougeL | T5-11B RougeL |
| ------------------ | ----------- | ------------ | ------------- |
| BF16 全微調 | 88.6 | 54.3 | 62.0 |
| LoRA BF16 | 88.8 | 55.4 | 60.7 |
| QLoRA Int8 | 88.8 | 56.5 | 60.7 |
| QLoRA FP4 | 88.6 | 55.6 | 60.9 |
| **QLoRA NF4 + DQ** | - | **55.3** | **60.9** |
#### 不同資料型態下的 LLaMA 模型 MMLU 表現比較
* 比較 LLaMA 模型在不同參數規模(7B、13B、33B、65B)下,使用不同精度資料型態微調後,在 **5-shot MMLU** 測試的平均正確率。
* 微調資料集包含 **Alpaca** 與 **FLAN v2**
* 資料型態包括:
* BFloat16(全精度)
* Float4(低精度)
* **NormalFloat4 + Double Quantization(NF4 + DQ)**
### 表現結果(平均 MMLU Accuracy)
| 資料型態 | 7B | 13B | 33B | 65B | 平均 |
| ------------ | ------------- | ------------- | ------------- | ------------- | ---------- |
| **BFloat16** | 38.4–45.6 | 47.2–50.6 | 57.7–60.5 | 61.8–62.5 | 53.0 |
| **Float4** | 37.2–44.0 | 47.3–50.0 | 55.9–58.5 | 61.3–63.3 | 52.2 |
| **NF4 + DQ** | **39.0–44.5** | **47.5–50.7** | **57.3–59.2** | **61.8–63.9** | **53.1** |
結論:
* **NF4 + DQ 完全重現 BFloat16 的表現**
* **Float4 consistently 落後約 1%**

### 主要結論
- 最佳模型僅用 約 9,000 條樣本訓練
- 支持「資料品質 > 數量」的觀點,與 LIMA, PALMS 一致
- 僅使用 Cross-Entropy(監督學習),無需 RLHF,即可達 SOTA 表現
- 在 MMLU 與聊天任務中甚至超越 16-bit 模型與商用系統 (MMLU 測的是知識與分類(如考試),Vicuna 測的是對話互動品質)
- 33B 模型可在單張 24GB GPU 上 <12 小時完成