# 論文閱讀 : SparseGPT
## 摘要
本論文首次證明,**大型 GPT 類生成模型可以在不進行任何再訓練的情況下,一次性(one-shot)剪枝達到至少 50% 稀疏度**,且準確率幾乎不受影響。
### 方法
- 專為大型 GPT 模型設計,在效率與準確性之間取得良好平衡。
- 能應用於目前最大的開源 GPT 模型,如:
- OPT-175B
- BLOOM-176B
- 效能
- 在 OPT-175B 和 BLOOM-176B 上執行 SparseGPT 不到 4.5 小時即可完成。
- 可以達到 60% 非結構化剪枝(unstructured sparsity),困惑度(perplexity)幾乎不增加。
- 可以忽略超過 1000 億個參數,無需 retraining,推理速度卻維持效能。
- 支援半結構化剪枝模式,如 2:4、4:8。
- 可以與現有的 權重量化方法結合使用,例如 INT8、INT4。
## Introduction
### LLMs 難以部署的挑戰
* GPT 系列雖然在多種任務中表現出色,但其龐大的 **參數數量與推理資源消耗**,成為實際部署的重大障礙。
* 以 GPT-175B 為例:
* 共有 **1750 億參數**,使用 FP16 格式需約 **320GB**。
* 至少需 **5 張 A100-80GB GPU** 才能進行推理。
### 現有的壓縮方式
* 大多數研究集中於 **量化(quantization)**,如:
* LLM.int8()
* ZeroQuant
* SmoothQuant
* GPTQ 等
### 剪枝(Pruning)作為輔助方案
* **剪枝** 是另一種模型壓縮方式,可移除:
* 單一權重(非結構化 unstructured)
* 整列或整欄(結構化 structured)
* 雖然已廣泛應用於 CV 或小型語言模型,但:
* **傳統剪枝方法多需 retraining(再訓練)**
* 對 GPT 級別的大模型來說成本太高
* 現有 one-shot 方法雖不需 retraining,但在百億參數規模下仍過於耗時
### SparseGPT 方法與貢獻
* **首次實現百億參數 LLM 的準確 one-shot 剪枝(無需再訓練)**
* 可對 **OPT-175B、BLOOM-176B** 等開源大模型,在 **單顆 GPU** 上於數小時內完成剪枝
### 方法核心
* 將剪枝問題轉換為 **超大規模稀疏回歸(sparse regression)問題**
* 採用新的 **近似求解器(approximate solver)**,快速計算每層的局部更新
* 計算過程中不需使用全域梯度資訊,完全「local」
### 實驗與發現
### OPT-175B 的非結構化剪枝

* SparseGPT 可達 **60% 每層 sparsity**,幾乎不影響 perplexity
* 傳統 one-shot baseline(如 Magnitude Pruning)僅在 **10% sparsity** 下保持準確,**超過 30% 就完全崩潰**
### 全模型與半結構化 sparsity

* SparseGPT 可適用於 **2:4、4:8 半結構化剪枝**(硬體友好),儘管在小模型上略有精度損失
* **大模型反而更容易剪枝**(compressible),例如:
* OPT-175B 與 BLOOM-176B 在 50% sparsity 下,perplexity 幾乎沒變化
* SparseGPT 也可與 **權重量化(如 GPTQ)結合**
* 例如:**50% sparsity + 4-bit quantization → 幾乎無 perplexity 增加**
### 總結
| 特性 | 說明 |
| -------- | ---------------------------- |
| One-shot | 不需 retraining |
| 適用範圍 | OPT-175B、BLOOM-176B 等百億級 LLM |
| 支援格式 | 非結構化、2:4、4:8 半結構化 |
| 可與量化結合 | GPTQ, INT4 |
| 執行效率 | 單顆 GPU,數小時完成 |
| 計算方式 | Local layer-wise 稀疏回歸,不用全域梯度 |
## Background
### 1. Post-Training Pruning(後訓練剪枝)
* 定義:
* 給定一個訓練完畢的模型 $\theta^\star$,加上少量 calibration data(校準資料),對模型進行壓縮(例如剪枝或量化)。
* 應用背景:
* 最早被量化研究廣泛使用,近期也成功應用在剪枝上。
* 優點:
* 不需要 retraining(再訓練),對大型模型來說是唯一實際可行的壓縮方式之一。
* 舉例引用:
* 應用於剪枝的相關文獻有:Hubara 2021, Frantar 2022(OBC), Kwon 2022。
### 2. Layer-Wise Pruning(逐層剪枝)
* 動機:
* 為了讓問題更可控,會將整體模型壓縮問題拆成一層一層處理(每層為一個子問題)。
* 剪枝的目標:
* 找到一個 sparsity mask(稀疏遮罩) $\mathbf{M}\_\ell$(0 代表剪掉,1 代表保留)
* 更新對應保留下來的權重 $\widehat{\mathbf{W}}\_\ell$
* 最小化以下誤差:
$$
|| \mathbf{W}_\ell \mathbf{X}_\ell - (\mathbf{M}_\ell \odot \widehat{\mathbf{W}}_\ell) \mathbf{X}_\ell ||_2^2
$$
* 實作流程:
1. 每層獨立處理(layer-wise)
2. 最後把每層剪枝後的結果「縫合」成整體模型
### 3. Mask Selection 與 Weight Reconstruction
* 核心問題:
* 該目標函數涉及同時優化 mask 和權重,是一個 **NP-hard 問題**,不可有效準確求解
* 現有方法通常將問題分成兩步:
1. **Mask selection**:用某種準則選出要保留哪些參數(例如絕對值大小)
2. **Weight reconstruction**:在 mask 固定的前提下,最佳化其餘保留的參數
* 一旦 mask 確定,問題就變成簡單的 **線性平方誤差最小化問題(linear least-squares)**,可以有效求解
### 4. 現有解法(Solvers)回顧
| 方法 | 概述 | 特點與限制 |
| ------------------------------------------------- | ------------------------------------- | ------------------- |
| **Kingdon 1997** | 使用反覆線性回歸來處理小網路 | 只適合非常小的模型 |
| **AdaPrune**(Hubara 2021) | Magnitude-based 選擇權重 → 使用 SGD 重建保留權重 | 準確度與速度平衡良好,但仍不夠快 |
| **Iterative AdaPrune**(Frantar 2022) | 分多輪進行 mask + 重建 → 每輪做 re-optimization | 準確率提升,但時間增加許多 |
| **OBC (Optimal Brain Compression)**(Frantar 2022) | 每次移除一個權重、用封閉式公式完整重建其餘權重 | 精度最佳,但成本極高,無法延展到大模型 |
### 5. 現有方法的可擴展性瓶頸
* 以 AdaPrune 為例:
* 壓縮 1.3B 參數模型就需數小時
* 對 175B 模型推估需數百小時(甚至數週)
* OBC 等更精確的解法:
* 計算量遠超 AdaPrune,甚至呈現超線性增長
* 總結:
* **現有方法無法有效擴展到 100+B 參數等級的 LLM**
### 6. SparseGPT 的提出動機
* 為了解決「大模型剪枝不可能快速完成」的問題,作者提出:
* **SparseGPT**:一種新的逐層(layer-wise)剪枝求解器
* 特點:
* 使用封閉式公式的近似解法(approximate closed-form equations)
* 能兼顧:
* **執行效率(hours 級完成)**
* **壓縮準確度(幾乎無精度下降)**
* 可直接應用於 100B+ 模型,並在單顆 GPU 上運行
## The SparseGPT Algorithm
### Fast Approximate Reconstruction(快速近似重建)
### 動機
* 在固定剪枝 mask $\mathbf{M}$ 的前提下,我們希望找出最佳的保留權重。
* 可逐行(row-wise)解以下 **稀疏重建問題**:
$$
\mathbf{w^i}_{\mathbf{M_i}} = (\mathbf{X}_{\mathbf{M_i}} \mathbf{X}_{\mathbf{M_i}}^\top)^{-1} \mathbf{X}_{\mathbf{M_i}} (\mathbf{w}_{\mathbf{M_i}} \mathbf{X}_{\mathbf{M_i}})^\top
$$
* $\mathbf{X}\_{\mathbf{M\_i}}$:代表 row $i$ 中未被剪掉位置的輸入
* 需對每個 row 都反推一個 **Hessian 矩陣 $\mathbf{H}\_{\mathbf{M\_i}}$** 並反轉(inverse)
* 問題在於:每個 row 的 mask 不同 → 要各自反推 $\mathbf{H}\_{\mathbf{M\_i}}^{-1}$ → 成本高達:
$$
O(d_\text{row} \cdot d_\text{col}^3)
$$
* 對 Transformer,hidden dim = $d\_\text{hidden}$,時間複雜度會是 $O(d\_\text{hidden}^4)$
* 這在實務上難以接受
### Row-Hessian 的挑戰

* 每個 row 使用不同 mask → 無法共用 Hessian inverse
* 若全部 row 使用同樣的 mask,就可以只算一次 Hessian 逆矩陣
* 但這會導致剪枝只能在整欄(column-wise)做,這種剪枝方式對準確率傷害大
### Iterative 觀點下的解法(OBS 更新)
* 透過 **Optimal Brain Surgeon (OBS)** 的觀點來看:
* OBS 可用於 **逐個權重移除** 時,最佳化其餘權重以補償誤差
* 對於 quadratic loss,OBS 是精確的最佳解
* OBS 更新公式如下:
$$
\delta_m = - \frac{w_m}{[\mathbf{H}^{-1}]_{mm}} \cdot \mathbf{H}^{-1}_{:, m}, \quad \varepsilon_m = \frac{w_m^2}{[\mathbf{H}^{-1}]_{mm}}
$$
* 意義:
* 可 **逐步剪枝每個權重**(不需一次決定整個 mask)
* OBS 可重複使用於新的剩餘權重子集 → 可遞迴解出與閉式解相同的最終重建結果
### Optimal Partial Updates(最佳局部更新)
* 若不更新全部剩餘權重,而是只更新子集 $\mathbf{U} \subseteq \mathbf{M}$:
* 可仍使用 OBS,精度可能略降,但大幅加速
* 若 $|\mathbf{U}|$ 小,Hessian 反轉成本大幅下降
### Hessian Synchronization(Hessian 同步)
主要要解決以下問題:
> 這是一種技巧,讓 **所有 row 共用一組或多組 Hessian inverse**,從而**大幅減少反覆計算 inverse 的成本**。
- 在精確的逐行重建中,我們每行都要:
- 根據該行的剪枝 mask $\mathbf{M}_i$ 取出對應的輸入 $\mathbf{X}_{\mathbf{M}_i}$
* 然後計算對應的 Hessian:
$$
\mathbf{H}_{\mathbf{M}_i} = \mathbf{X}_{\mathbf{M}_i} \mathbf{X}_{\mathbf{M}_i}^\top
$$
* 並且反轉它來解重建公式
* 但每一行的 mask 都不同,代表要做成千上萬次 **矩陣反轉**,這對大模型根本不可行。
* 希望所有 row 都能共用一組(或一系列)Hessian inverse**,不管他們的 mask 是不是一模一樣。

* 核心策略:
1. 對輸入維度順序固定為 $j = 1, \dots, d\_\text{col}$
2. 建立一系列 index 子集 $U\_j$:
$$
U_1 = \{1, \dots, d_\text{col}\}, \quad U_{j+1} = U_j - \{j\}
$$
3. 每個 $U_{j+1} = U_j - \{j\}$,就是從前一組移除一個 index,這樣會形成一連串「漸漸變小」的輸入子集
4. 逐步計算每個 $U\_j$ 的 Hessian 逆矩陣
* 更新方式:
$$
(\mathbf{H}_{U_{j + 1}})^{-1} = \left(\mathbf{B} - \frac{1}{[\mathbf{B}]_{11}} \cdot \mathbf{B}_{:,1} \mathbf{B}_{1,:} \right)_{2:,2:}
$$
* 每個 inverse Hessian 只算一次,可應用在所有 rows!
#### 舉例(假設輸入維度是 4):
| j | $U_j$ |
| - | ------------ |
| 1 | {1, 2, 3, 4} |
| 2 | {2, 3, 4} |
| 3 | {3, 4} |
| 4 | {4} |
* 對每個 $U_j$,計算對應的 Hessian:
$$
\mathbf{H}_{U_j} = \mathbf{X}_{U_j} \mathbf{X}_{U_j}^\top
\quad\text{再計算其逆:}\quad
\mathbf{H}_{U_j}^{-1}
$$
* 然後這一系列的逆矩陣會「**共用在所有 rows 的剪枝操作中**」,不再為每個 row 計算新 Hessian
#### 如何快速更新 Hessian inverse?
根據矩陣逆的公式(Sherman-Morrison 或 Gaussian elimination),可以用下列方法**快速從 $\mathbf{H}_{U_j}^{-1}$ 得到 $\mathbf{H}_{U_{j+1}}^{-1}$**:
$$
\mathbf{H}_{U_{j+1}}^{-1} =
\left( \mathbf{B} - \frac{1}{[\mathbf{B}]_{11}} \cdot \mathbf{B}_{:,1} \mathbf{B}_{1,:} \right)_{2:,2:}
$$
* 這是高效消除某一列與欄的技巧
* 從原始 $\mathbf{H}^{-1}$ 出發,只需執行 $d_\text{col}$ 次更新就能得到整條鏈
* 時間複雜度:**總共只要 $O(d_\text{col}^3)$**,遠小於原本 $O(d_\text{row} \cdot d_\text{col}^3)$
- 在剪掉某個 column(比如第 $j$ 欄)時:
* 你用 $\mathbf{H}_{U_j}^{-1}$ 去計算該 column 被剪掉後,其他權重的 OBS 更新
* 所有 rows 中,**凡是有剪掉該位置的**,都可以共用這組 $\mathbf{H}_{U_j}^{-1}$
* 這樣每個 inverse 只用算一次,但可跨行使用
---
### 計算複雜度(Computational Complexity)
* 三個主要部分:
1. 初始 Hessian:$\Theta(n \cdot d\_\text{col}^2)$,$n$ = sample 數量
2. 逆矩陣序列:$O(d\_\text{col}^3)$
3. 每列重建:$O(d\_\text{row} \cdot d\_\text{col}^2)$
* 總計:
$$
O(d_\text{col}^3 + d_\text{row} \cdot d_\text{col}^2) = O(d_\text{hidden}^3)
$$
* 比原本精確解法快了整整一個 $d\_\text{hidden}$ 效能等級
---
### Weight Freezing 解釋(另類觀點)
* 對於逐列逐欄剪枝來說,「compress」某個 weight 實質上就是 **凍結它(freezing)**
* 一旦剪掉,就不能再更新
* 定義壓縮操作為:
$$
\text{compress}(w^j)_i =
\begin{cases}
0 & \text{if } j \notin M_i \\
w^j_i & \text{otherwise}
\end{cases}
$$
* 因此 SparseGPT 也可視為一種 **逐欄貪婪壓縮(column-wise greedy compression)**
* 每次固定部分權重,保留其值,避免再更新
* 這讓 **剪枝 + 量化的合併壓縮**成為可能(後續會介紹)
## SparseGPT 進階設計與擴展
### 1. Adaptive Mask Selection(自適應遮罩選擇)
* 目前為止都假設剪枝 mask(哪些 weights 要剪)是固定的
* 傳統做法是「magnitude pruning」:剪掉數值最小的權重(如 AdaPrune)
* 但近期研究指出:**剪枝過程中權重會變動、彼此相關性也會影響結果**,所以應該「在剪的同時決定要剪哪些」
### SparseGPT 的做法:**自適應遮罩 + OBS 誤差排序**
* 想法:依據每個 weight 的 **OBS 誤差貢獻 $\varepsilon$** 來動態決定要剪誰
* 不再一口氣對整層決定 mask,而是:
1. **每次處理一個 block(遮罩區塊)**,例如 $B_s = 128$ 個 columns
2. 根據每個 weight 的 OBS 誤差(根據 $\varepsilon = \frac{w^2}{[\mathbf{H}^{-1}]_{jj}}$)來排序,挑最容易剪的那幾個
3. 然後剪這些,並做重建,再進到下一個 block
#### 好處
| 問題 | 解法 |
| ------------------------ | -------------------------------- |
| 原始方式會強迫 sparsity 在每欄都一樣多 | 自適應 mask 可以讓不同欄 sparsity 不同(更靈活) |
| 無法考慮之前的 weight 更新 | OBS 誤差是逐步算的,能反映前面更新影響 |
| 無法處理 outlier features | 某些欄太敏感,OBS 誤差能保護它們不被剪掉 |
### Extension to Semi-Structured Sparsity(支援半結構化剪枝)
- 問題
- 為了硬體加速,像 2:4, 4:8 的 semi-structured pruning 格式在 NVIDIA GPU 有專門支援(如 Ampere Tensor Core)
### SparseGPT 的做法
* 將遮罩區塊大小 $B_s$ 設為 block size $m$
* 對每個 row:
* 每 $m$ 個連續 weight 中選出 $n$ 個最小的 OBS 誤差 → 保留其餘
* 強制該 block 中有 $n$ 個 0
* 這種做法保證符合 n\:m 格式,例如:
* 2:4 → 每 4 個中有 2 個是 0
* 4:8 → 每 8 個中有 4 個是 0
#### 限制
* 在 semi-structured 模式下,因為要硬性限制每個 block 的 sparsity,所以不能讓遮罩分佈不均 → **不能用太大的 $B_s$**
### 總算法

### 5. Weight Freezing 解釋 & GPTQ 整合
SparseGPT 的操作流程其實和 GPTQ 的「逐欄 greedy 量化策略」非常接近:
* 每個被剪掉的權重就像是「凍結」(freezing)→ 不再更新
* 可與 GPTQ 的 lazy batch 更新、Cholesky decomposition 搭配使用
* 所有這些強化技巧都能應用在 SparseGPT 裡
### 6. Joint Sparsification & Quantization(剪枝 + 量化單一流程)
**傳統**
過去剪枝與量化通常是分開做:
1. 先剪枝
2. 再對剩下權重做量化
這會導致兩者之間「無法互相補償」誤差。
**SparseGPT 改成:**
* 每次剪掉一部分權重,同時把剩下的做量化
* 在 OBS 更新時補償「剪掉 + 量化」帶來的誤差
* OBS 誤差補償公式改成:
$$
\mathbf{E}_{:, j - i} \gets (\mathbf{W}_{:, j} - \mathbf{M}_{:, j} \cdot \text{quant}(\mathbf{W}_{:, j})) \, / \, [\mathbf{H}^{-1}]_{jj}
$$
* 即:
* 若某個 weight 被保留 → 就把它量化後拿來重建
* 若被剪掉 → 直接設 0
* 全流程在「**一輪通過(single pass)**」中完成剪枝 + 量化 → 幾乎無額外成本!
### SparseGPT 完整演算法整理
| 模組 | 核心貢獻 |
| ------------------ | -------------------------------------------------- |
| 自適應遮罩 | 動態選擇剪枝位置,考慮 OBS 誤差與 outlier 保護 |
| Semi-structured 支援 | 符合硬體格式需求(2:4, 4:8),保留加速性 |
| 單一剪枝 + 量化流程 | 在 single pass 中完成兩種壓縮,誤差可互補 |
| GPTQ 技術整合 | 支援 lazy batch update、Cholesky、column-wise freezing |
## Experiments
### 🔧 1. 實驗環境(Setup)
#### 系統與工具
* 使用 **PyTorch** 作為實作框架
* 搭配 **HuggingFace Transformers** 處理模型與資料
#### 訓練硬體
* 所有實驗都在 **單張 NVIDIA A100-80GB GPU** 上完成
* 能夠在 **4 小時內完成對 OPT-175B 模型的完整剪枝(sparsify)**
#### 執行策略
* **Sequential Layer-wise pruning**:
* 一層一層依序剪(非全模型一次剪)
* 優點:大幅降低記憶體需求(避免同時載入全部層)
#### Calibration 資料
* 取自 C4 corpus 的第一個分片,隨機選擇 128 段長度為 2048 的文本片段
* 特性:
* 資料為網路文本(非任務特定)
* 保持 **zero-shot pruning 環境**,不會有任務偏見
### 2. 模型與資料集(Models, Datasets & Evaluation)
#### 模型選擇
* 主要使用 Meta 的 **OPT 模型系列**,涵蓋:
* 小型:125M、350M、1.3B
* 大型:2.7B、6.7B、13B、30B、66B、175B
* 也納入 **BLOOM-176B** 作為額外驗證
#### 評估資料集
* 主要用於語言建模任務的標準資料:
* **WikiText2 (raw)**
* **Penn Treebank (PTB)**
* **C4 validation subset**
* 額外用於 zero-shot 任務準確率評估的資料集:
* **Lambada**(長文本完形填空)
* **ARC-Easy / ARC-Challenge**(常識問答)
* **PIQA**(物理常識)
* **StoryCloze**(故事邏輯判斷)
#### 評估原則
* **重點放在稀疏模型與原始 dense 模型的「相對表現」**
* 絕對值可能會因資料前處理差異有出入
* 但相對精度變化具穩定性與比較價值
* 所有結果(dense/sparse)使用完全相同的程式碼測量
* 包含 perplexity 計算與 zero-shot 任務
#### 工具鏈
* perplexity:使用 HuggingFace 官方方法,搭配 full stride
* zero-shot:使用 GPTQ 提供的實作(基於 EleutherAI eval-harness)
### 4. 比較基準方法(Baselines)
| 方法 | 特性 | 適用範圍 |
| --------------------- | ------------------- | ---------------------- |
| **Magnitude Pruning** | 根據權重大小逐層剪枝(簡單但延展性強) | 可套用到最大模型(如 175B) |
| **AdaPrune** | 考慮重要性 + 重建,精度佳 | 僅適用於 < 1B 模型(受限於資源與時間) |
| **SparseGPT** | 本研究提出的新法 | 可擴展至 175B 並達成優異速度與精度 |
### 實驗結果
### 1. Pruning vs. Model Size 模型越大越容易剪
#### 實驗設定
* 對 **OPT 全系列模型**進行實驗,剪枝範圍為所有 linear 層(不含 embedding 和 head)
* 比較三種 sparsity:
* **50% unstructured**
* **4:8 semi-structured**
* **2:4 semi-structured**(最嚴格)
### 結果


* **Magnitude Pruning 表現崩潰**:
* 隨著模型越大(尤其是 >1B),簡單的權重大小剪枝(magnitude)導致 **困惑度爆炸**
* 和 vision model 的剪枝結果形成強烈對比(vision 模型常能安全剪掉 50% 以上)
* **SparseGPT 效能穩定甚至提升**:
* OPT-2.7B 僅損失約 1 perplexity
* OPT-66B 幾乎無損失
* OPT-175B 在某些資料集甚至略優於原始模型(dataset-specific)
* **AdaPrune 雖比 magnitude 好,但仍不如 SparseGPT**
* 速度也慢很多(AdaPrune 對 1.3B 需約 4.3 小時,而 SparseGPT 可在同時間內剪完 66B 或 175B)
#### 結論:大型 LLM 越大越容易剪(可能因 overparameterization)
### 2. Sparsity Scaling for 100B+ Models


對兩個最大模型:**OPT-175B** 與 **BLOOM-176B**,進行不同 sparsity 等級的實驗:
#### OPT-175B
* **Magnitude Pruning**:
* 超過 10% sparsity 就會造成重大精度損失
* **SparseGPT**:
* 可安全到 **60% sparsity**
* 到 **80% sparsity** 還能保持 reasonable perplexity
* 移除近 **100B 個參數** 幾乎不影響結果
#### BLOOM-176B
* magnitude pruning 稍微好一些(30% 可接受)
* 但 SparseGPT 仍優於其,能達成 **50% sparsity** 且精度相當
#### 結論
* magnitude pruning 在 40\~60% sparsity 時,困惑度急升到 >100(模型崩潰)
* SparseGPT 即使到 80% 也可穩定輸出
### 3. ZeroShot 評估實驗(泛化能力)

* **Magnitude 完全崩潰(表現近隨機)**
* **SparseGPT 表現接近甚至優於原始 dense 模型**
* 部分特例如 Lambada 在 2:4 剪枝後還略升(解釋:zero-shot noise,但平均仍穩定)
### Joint Sparsification & Quantization (聯合剪枝與量化)

將 **剪枝(Sparsity)** 與 **量化(Quantization)** 結合,以同時達成:
* **運算加速**(剪掉多餘參數 → 減少乘法數)
* **記憶體節省**(每個權重位元數下降)
### 空間節省對比
* 假設模型:
* 採用 **50% sparsity**(只保留一半權重)
* 剩餘權重用 **4-bit 量化**
* 並使用一個 **bitmask** 表示哪些權重為非零
**這樣的儲存空間 ≈ 純量化 3-bit 模型**
| 模型大小 | 方法 | Perplexity |
| -------- | -------------------- | ---------- |
| OPT-175B | GPTQ (3-bit) | 8.68 |
| OPT-175B | SparseGPT 50% + 4bit | 8.29 |
* 在 OPT-2.7B 以上的模型中,**SparseGPT(剪 + 量)優於純 3-bit 量化**
* 同樣也測試了:
* 2:4 + 4bit → 8.55
* 4:8 + 4bit → 8.85
* 顯示:**在 semi-structured sparsity 基礎上加入 4bit quantization,perplexity 只增加約 0.1**(非常小)
### Sensitivity & Partial N:M Sparsity

### 實驗設定
以 OPT-175B 和 BLOOM-176B 為例:
* 將 **2/3 的層**套用 **2:4 剪枝**
* 剩下的 1/3 層「不剪」
* 測試兩種選擇方式:
1. **不剪某一類型層**(如 attention / FFN1 / FFN2)
2. **不剪某一段位置的層**(前 1/3、中間 1/3、後 1/3)
### 結果觀察
* 不同模型對不同 layer type 敏感度不一
* 但明顯趨勢:**後段層(last third)較敏感**
* 若要保留一段不剪 → **保留最後 1/3 精度最好**
### 總結
| 項目 | 觀察 |
| -------------------- | --------------------------------------------------- |
| 聯合壓縮 | 50% sparsity + 4bit quantization 表現 **優於純 3bit 量化** |
| semi-structured + 量化 | 即便是 2:4 或 4:8,再加上 4bit 量化也只會增加 0.1 的 perplexity |
| 部分剪枝建議 | 若不能全部剪,可選擇 **後段層不剪**,效果最佳 |
| 剪枝流程優勢 | SparseGPT 可在 **一次剪枝過程中輸出多版本模型**,提升部署彈性 |
## 結論
本研究提出了一種全新的 **後訓練剪枝方法**,名為 **SparseGPT**,專為大規模 GPT 系列語言模型設計,具備以下幾項突破:
### 一次性剪枝(One-shot Pruning)
* **不需要再訓練(no retraining)**:
* SparseGPT 能直接在已有的 GPT 模型上進行剪枝
* 僅需少量校準資料(calibration data)
* 就能 **一次性(one-shot)達成高 sparsity**
* 成效良好(Accuracy preserved):
* 在 **perplexity**(語言建模精度)與 **Zero-shot 任務**(泛化能力)下都表現穩定
### 剪枝最大規模模型
* 模型規模:OPT-175B 與 BLOOM-176B(超過 1000 億參數)
* 剪枝結果:
* 達到 **50–60% sparsity**
* 移除超過 **1000 億個權重**
* 精度幾乎無損
#### 利用 GPT 模型的 **高參數冗餘性(overparameterization)**
* 原始 dense 模型的「鄰近區域」中,存在可行的高 sparsity 子模型
* 即使 **不使用 gradient 訊息**,也能夠直接搜尋到這些稀疏模型
* 剪枝後的模型輸出與 dense 模型非常接近,維持語言理解能力
### 更大的模型反而更容易剪枝
* **實驗觀察**:
* 相同 sparsity(如 50%)情況下:
* 小模型會有明顯精度下滑
* 大模型的精度幾乎不變
* 解釋:
* 可能是因為大模型「冗餘更多」,有更多空間能剪枝
* 顯示未來在 compress 更大模型時 **具高度潛力與應用價值**
## Ablation Studies
### 實驗對象與目標
* 模型:**OPT-2.7B**
* 資料集:**raw-WikiText2**
* 剪枝比例:固定為 **50% sparsity**
* 目的:探索幾個核心參數對 SparseGPT 效果的影響
### 1. 校準樣本數量(Calibration Samples)

* 測試不同數量的 2048-token calibration segments(2、4、8、16...)
* **結果**:
* 即使樣本數很少(例如 4 條樣本)也能產出「可用結果」
* 但樣本數量 **愈多效果愈好**
* 增益在超過某個點後 **漸漸趨緩(飽和)**
* **選定設定**:
* 使用 **128 段樣本** 是效能與資源的良好平衡點
### 2. Hessian 抑制因子(Hessian Dampening)

* 使用類似 GPTQ 的技巧:在計算 Hessian inverse 前對對角線加上阻尼
* 減少數值不穩定問題
* 減少過擬合
* 測試範圍:`0.0001` 到 `1.0`(乘上 Hessian 對角平均值)
* **結果**:
* `0.001` \~ `0.1` 效果接近
* 抑制過強(如 `1.0`)→ 會造成精度顯著下降
* **選定設定**:使用 **`0.01`(1%)** 作為穩定且保守的選擇,適用於最大模型
### 3. Mask 選擇區塊大小(Mask Selection Blocksize)

* 探討 mask 計算時的 column block size 對剪枝效果的影響
* `1` 表示 column-wise 計算
* `4096+` 表示接近整個行
* **結果**:
* 極端值(太小或太大)會導致效果變差
* 最佳範圍落在 **幾百的區塊大小**
* **選定設定**:使用 **`128`**
* 準確率穩定
* 與 lazy weight update 批次大小相符 → **簡化實作**
### 4. 隨機性敏感度(Random Seed Sensitivity)
* 重複相同實驗(50% sparsity)**5 次**,但使用不同的 calibration data sampling 隨機種子
* 結果:`13.52 ± 0.075` perplexity
* **結論**:
* SparseGPT 對 calibration data 的隨機性 **不敏感**
* 與其他 post-training 方法一致(如 GPTQ、OBC 等)
### 小結
| 項目 | 發現 | 結論 |
| -------------- | ---------------------- | ---------- |
| Calibration 數量 | 多樣本會更準,但 128 已足夠 | 計算效率與準確平衡點 |
| Hessian 抑制 | 太高會降準確,但在合理區間效果穩定 | 建議值:0.01 |
| Blocksize | column-wise 太細、整塊太粗都不佳 | 建議值:128 |
| Random Seed | 小幅度浮動,不敏感 | 高穩定性 |
### Approximation Quality
SparseGPT 在進行剪枝時,為了節省時間與記憶體成本,**並不重建完整權重矩陣**,而是採用「**Partial Update Approximation(部分更新近似)**」。
### 實驗設計
* 模型:OPT-2.7B
* Sparsity:50%
* 分析項目:比較每層的 **重建誤差**:
* `SparseGPT` 的近似重建
* vs.
* 同樣 mask 與 Hessian 下的 **精確重建(exact reconstruction)**
### 實驗發現

* 絕大多數 layer 的重建誤差僅比精確版本多出 **約 20%**
* 特例:早期 attention out-projection layers 的誤差較高(為 outlier)
* 在後半部如 `fully-connected-2` layers,誤差甚至僅約 **10%**
* 推測原因:輸入維度非常大 → 即使只看部分相關性,資訊損失也不大
#### Perplexity 計算方式
* 完全依照 HuggingFace 的官方標準流程 hfperplexity:
1. **將資料集中所有樣本串接起來**
2. 使用對應的 tokenizer 編碼為 tokens
3. 切割為不重疊的 **2048-token segments**
* 這是 LLM 的最大上下文長度
4. 每段輸入模型,計算其 **平均 loss**
5. 將 loss 指數化,即為 **perplexity**
### Additional Results
### 不同資料集上的剪枝難度(PTB & C4)

對 OPT 各模型在 PTB 與 C4 資料集上進行同樣的剪枝實驗,延伸主文中在 WikiText2 的分析:
* **趨勢一致**:SparseGPT 的效能在各資料集上皆顯著優於 Magnitude 與 AdaPrune。
* **資料集特異性差異**:
* 在 WikiText2 中,50% sparsity 時大型模型甚至有略微 **perplexity 改善**(可能來自 regularization 效果),
* 但此現象未在 PTB 或 C4 重現,因此被視為資料集特有。
### Sparsity Acceleration
目標:驗證 SparseGPT 剪枝後的模型,**在不需 retraining 的情況下是否能實現推論加速**,並評估目前現成工具對稀疏模型的支持程度。
> 此處僅為初步實驗,未針對特定模型作最佳化;作者認為未來仍有大量加速潛力。
### CPU 推論加速:Unstructured Sparsity
* **環境設定**:
* 使用 [DeepSparse](https://neuralmagic.com/deepsparse/) 引擎(支援 unstructured sparsity)
* 模型:`OPT-2.7B`
* 設備:Intel i9-7980XE(18 核)
* 任務:單批次 400 tokens 的 end-to-end 推論
* 備註:DeepSparse 的 dense 模型本身就比 ONNXRuntime 快 1.5 倍
#### 結果(相對於 dense DeepSparse):
| Sparsity Level | Speedup |
| -------------- | ------- |
| 40% | 1.57× |
| 50% | 1.82× |
| 60% | 2.16× |
**幾乎達到理論最佳值**:代表在 CPU 上執行稀疏 Transformer 推論,已經相當實用。
### GPU 推論加速:2:4 Structured Sparsity
* NVIDIA 自 Ampere 架構起,支援 2:4 結構化稀疏加速(透過稀疏矩陣乘法 kernel)
* 工具:NVIDIA CUTLASS(使用 profiler 尋找最佳 kernel)
* 對照:cuBLAS dense kernel(PyTorch 用的 dense matmul)
* 條件:
* 模型:OPT-175B 中典型矩陣大小
* 批次大小:2048 tokens
#### 測試結果:
| Layer Type | Dense (ms) | 2:4 Sparse (ms) | Speedup |
| ---------- | ---------- | --------------- | ------- |
| Q/K/V/Out | 2.84 ms | 1.59 ms | 1.79× |
| FC1 | 10.26 ms | 6.15 ms | 1.67× |
| FC2 | 10.23 ms | 6.64 ms | 1.54× |
* 所有主層類型都有明顯加速
* 儘管理論上是 **2×** 加速,實際約 **1.5–1.8×**,已是非常可觀的提升
* **整體端到端加速** 可能會略低,因為仍存在 attention、I/O 等非 matmul 成分