非結構化對結構化:那個其實不存在的加速
剪枝把權重設為零。最誘人的版本是「非結構化(unstructured)」剪枝——把矩陣中任何位置數量級最小的權重歸零。你常能用這方式移除 50% 的權重而幾乎不損準確度,參數量看起來棒極了。但對稠密 GPU 核心而言,一個散布著零的矩陣,與滿矩陣一樣昂貴。你省了儲存空間,卻省下零實際時間。
結構化剪枝(structured pruning)解決了這問題:它移除硬體看得懂的整個「單位」——整條通道、整顆注意力頭或整層。通道更少的網路,是貨真價實更小的稠密網路——在任何裝置上都更快,無需特殊核心。代價是結構化剪枝較為粗糙,因此每移除一個參數通常損失更多準確度,並能受益於事後的微調,有時還會以原模型的蒸餾來引導。
多層網路示意圖,其節點與帶權連接代表剪枝所移除的單元與權重。
2:4 的折衷:半結構化稀疏
在非結構化剪枝的彈性與結構化剪枝的硬體友善之間,有個巧妙的中間地帶:N:M 稀疏(N:M sparsity)。最重要的情況是 2:4——每連續四個權重中,至多兩個可為非零。這個模式夠細緻,能保住準確度;又夠規律,使現代 GPU 內建專用的稀疏張量核心,跳過零值並帶來真實約 2 倍的矩陣乘法加速。
# enforce 2:4 within each block of 4 weights along a row
for block in reshape(row, [-1, 4]):
keep = top2_by_magnitude(block) # indices of 2 largest |w|
block[not in keep] = 0 # the other two -> 02:4 規則即一個約束:每四個連續權重中至多保留兩個非零值,恰好得到 50% 稀疏度。
2:4 是論文指標與實際時間難得一致的情況,這也是它成為量產 transformer 預設「免費」稀疏的原因。一般做法是套用它,再短暫微調以挽回那一點準確度的下降。
免重訓的剪枝:Wanda
重新訓練一個剪枝後的十億參數模型代價高昂,因此一個關鍵問題是:你能多好地「一次性」剪枝。經典的數量級剪枝移除最小的權重——但在 LLM 中,一個乘上大激活值的小權重,可能比乘上微小激活值的大權重更重要。Wanda(Weights AND Activations,權重與激活)修正了評分:它以每個權重的數量級「乘上」其對應輸入激活的範數來排序,再逐輸出剪去得分最低者。不需梯度、不需重訓、只要一次校準。
Wanda 的重要性評分:權重幅值乘以該輸入特徵激活的 L2 範數——高激活通道上的小權重仍可能至關重要。
留意它與上一篇 AWQ 的呼應:兩者都領悟到,在已訓練的 transformer 中,「激活尺度」會告訴你哪些權重是承重的。同一個洞見——用激活而非單靠權重來衡量重要性——驅動了量化與剪枝兩邊最佳的一次性方法。
低秩結構:壓縮矩陣本身
第三種選擇保留每個輸出,但重新表達權重。低秩分解(low-rank factorization)把一個 m×n 權重矩陣換成一個 m×r 與一個 r×n 矩陣的乘積,其中秩 r 遠小於 m 或 n。若原矩陣能被某個低秩物件良好近似——許多學到的矩陣確實如此——你儲存與計算的數字便大幅減少。經典工具是截斷的奇異值分解(SVD):只保留前 r 個奇異方向。
低秩分解用兩個瘦因子替換 m×n 權重矩陣,只要秩 r 較小,就把參數量從 mn 降到 r(m+n)。
低秩思維比壓縮更為深遠。同一個觀察——權重的「更新」往往是低秩的——正是讓參數高效微調得以運作的原因,那是另一個系列的主題。此處的重點是結構性的:當某層確實是低秩時,分解它是一個乾淨、核心友善的勝利,並能愉快地與其上的量化疊加。