---
# System prepended metadata

title: What is LoRA?（Low-Rank-Adaption）
tags: [LLM]

---

# What is LoRA?（Low-Rank-Adaption）
LoRA（Low-Rank Adaptation）是一種用來微調大型語言模型（LLM）的技術方法。由於當前開源的模型規模非常龐大，以常見的7B或8B模型為例，7B代表該模型擁有70億個參數，而每個參數在訓練時都需要相應的記憶體空間來存儲。

參數的存儲通常以8位元（8-bit）或16位元（16-bit）格式表示。以8-bit為例，1 Byte = 8 bits。因此，若7B模型中的每個參數都以8-bit格式存儲，則7B模型(70億個參數)，大約需要7GB的顯存（GPU memory）。（補充：1GB約等於 10.24億個Bytes，這是因為1GB = 1024MB，且1MB = 1024百萬Bytes，因此1GB約為10.24億Bytes。）

這僅是用於存儲參數所需的顯存，實際訓練還需考慮中間計算、梯度等額外的記憶體需求，這會進一步增加顯存的消耗。

### LoRA技術優勢
LoRA的技術優勢在於它只需要微調部分參數，大大減少了顯存的需求，使得對這類超大模型的微調變得更加可行和高效。

我們可以看到下圖，左邊的藍色 W 矩陣代表原先訓練好的模型參數矩陣，而維度自然而然為 
$𝑅^{𝑑×𝑑}$（若對此部分有疑問，可以參考 Self-Attention 相關文章，會有更詳細的說明）。

![截圖-2024-04-29-下午1.44.44](https://hackmd.io/_uploads/Sy3pJDJg1e.png)
圖片來源: https://arxiv.org/pdf/2311.11696

如果每次訓練都要更新 $𝑑×𝑑$的矩陣，那麼訓練量將非常龐大，因此有前人提出了一種新的方法來微調模型，即固定住原先已訓練好的參數，只對部分參數進行調整，這樣可以大幅度減少訓練的計算量。這就是 LoRA 方法的核心理念。

在 LoRA 方法中，我們將原本的$W$矩陣固定，並新增兩個矩陣$A$和$B$（橘色矩陣），通過降維度來微調模型。這樣，參數更新只針對這兩個較小的矩陣$A$和$B$，而不是原本龐大的$𝑊$矩陣。

### 訓練過程

原本的參數更新方法為：

$$h=W×x(注意：h和x是d維的向量，Ｗ \in d \times d的矩陣)$$

故每次都需要更新 $W$矩陣內$𝑑 \times 𝑑$個參數。但在 LoRA 的方法中，我們將$W$矩陣固定，並使用如下更新方式，利用$W'$取代原先的$W$：
$$W^′=W+Δ(W),Δ(W)=A \times B$$ 

在這裡，矩陣 $A$ 的維度為 $𝑑 \times 𝑟$，矩陣 $B$ 的維度為 $𝑟 \times 𝑑$。通過矩陣乘法$A \times B$，相乘的結果為:
$$A^{d \times r} \times B^{r \times d} = ΔW^{d \times d}$$
我們透過將參數空間降維，然後再提升回原來的維度。這樣，我們雖然犧牲了一部分資訊，但依然能夠進行有效的微調。

### 計算量降低

每次訓練更新的參數數量，原本是 $𝑑 \times 𝑑$ 個參數量。而在 LoRA 中，我們只需要更新 $A$ 和 $B$ 兩個矩陣，參數數量降為 $d \times r \times 2 = 2dr$ 個參數量（遠小於當初模型的$d \times d$個參數量）。這樣，計算量將大幅降低，尤其是當 $r$ 選擇較小的值（如 1, 2, 4, 8, 16, 32 等範圍時），訓練所需的顯存將大大減少。不過，當 $r = 1$ 或 $2$ 時，參數更新量雖然變少，但可能會影響微調效果，因為當$r=1$時，此時為線性轉換，就完全失去矩陣相乘的優勢了；因此，通常推薦使用 **$r = 4$ 或 $8$**（此為有人證明得出的結果），以平衡計算量和模型效能。

### 疑難雜症排解

Q: 雖然微調時參數量變少了，訓練時間變短了，但為什麼我還需要加載原來的模型？

A: 沒錯，雖然微調的參數量變少了，但你仍然需要加載原始模型的所有參數，因為微調過程中，我們是將原來的參數固定住，只對新增的部分進行調整。因此，你仍然需要足夠的顯存來容納原模型的參數。即便如此，相比於全量參數訓練，LoRA 仍然具有顯著優勢，因為它只調整一小部分參數，大幅減少了訓練所需的計算量和顯存需求。

Q: 什麼是 Adapter，和 LoRA 有什麼區別？

A: Adapter 是另一種微調大型模型的方法，類似於 LoRA。Adapter 通常通過在模型的每一層中插入小型的專用層來進行微調，而不改動原始模型的主要參數。這些插入的層參數量較小，訓練時只更新這些專用層的參數，從而減少計算負擔。

與 LoRA 的區別在於，LoRA 是通過將模型的投影矩陣分解為低秩矩陣來進行微調，從而減少更新的參數數量。相比之下，Adapter 是通過在模型內部引入額外的小型參數層，並且通常會應用非線性變換。兩者都旨在實現更高效的微調過程，但具體實現方式不同。

Q: 使用 Adapter 微調和 LoRA 微調，哪個方法更好？

A: Adapter 和 LoRA 都各有優勢。LoRA 通常在顯存有限的情況下表現更好，因為它不需要添加新的層，只是通過矩陣分解來減少參數更新量。Adapter 則通過在模型層之間插入小型的調整層，也能大幅減少參數更新，並且在某些特定任務上可能表現更佳。具體選擇哪種方法，取決於你的硬件資源和應用場景。

## Adapter 和 LoRA 的具體區別
- LoRA： LoRA 的設計是針對模型的投影矩陣進行低秩分解。它會將投影矩陣 $W$ 分解為兩個較小的矩陣 $A$ 和 $B$，只更新這兩個矩陣，從而減少參數的更新量。這樣，它能在不改動模型主要架構的前提下進行微調，並保證顯存和計算量的節省。

- Adapter： Adapter 的核心思想是在模型的層與層之間（例如 Transformer 的 Feedforward 層後）插入額外的小型專用層，這些插入的層通常是一些簡單的線性變換，加上非線性激活函數。這些層的參數量較小，且只有 Adapter 層的參數會在微調過程中進行更新，原有模型的主要參數不會改變。

![20fe35156474fcd2676d784b57bf54e9](https://hackmd.io/_uploads/HJOvst1eye.png)
圖片參考: https://arxiv.org/pdf/2304.01933


### 更具體的對比：
#### 位置：

- LoRA 的更新發生在模型權重矩陣的內部，通常是在自注意力層或其他線性層的權重矩陣上。
- Adapter 則是在模型的層與層之間添加專用的adapter layer（例如常見的在 Feedforward 層之後），這些適配器層有自己的權重矩陣，不影響原始模型的權重。

#### 矩陣操作：

- LoRA 主要通過矩陣拆解來減少計算量，使用 $A \times B$ 的形式來代替更新全權重矩陣 $W$。
- Adapter 則是在原模型層之間插入"額外的小型線性變換矩陣"，這些矩陣通常是低維的，因此參數量較少，但與 LoRA 的矩陣分解方式不同。

## 總結
- PEFT（Parameter-Efficient Fine-Tuning）是一種參數高效微調技術，通過只調整部分模型參數而非整個模型，來適應新任務需求。這對於大型語言模型（LLM）尤為適用，因為微調整個模型既耗時又資源密集。PEFT 透過更少的變動來達到優化效果，其中有三種著名的方法：
    - LoRA（Low-Rank Adaptation）：
        透過對權重矩陣進行低秩分解（low-rank decomposition），僅微調權重矩陣的低秩部分。這樣可以大幅降低需要調整的參數數量，同時保留模型原本的能力。LoRA 的關鍵在於它只需要對原始運算的 W 矩陣進行小規模的干預。
        
    - Adapter：
        在模型中的特定位置插入一個額外的層，這些層用於處理新任務時的特定信息(就好比我們要讓模型學習狗、貓的特徵，我們可以針對每個特定任務，各自微調一個專用的 Adapter layer，並將這些層插入到原始模型中。這樣模型就能夠利用這些微調過的 Adapter 層來處理新特徵，而不需要重新訓練或更改模型的大部分參數。)
        
    - Prefix Tuning：
        透過為每次輸入添加一段可學習的「前綴向量」，讓模型在生成時受到這段向量的影響。簡單來說，這就是將 prompt 也變成模型的一部分參數，並且讓模型學習和調整這些參數。這與以往我們執行 LLM 時直接下達 prompt 不同：傳統的 prompt 是依據模型已經學習過的參數生成結果，而在 Prefix Tuning 中，特定的 prompt 會被轉化為可調參數，並在訓練過程中進行優化。這些前綴向量雖然看似 prompt 的一部分，但實際上它們存在於模型內部，是專門為特定任務設計的參數，無需微調整個模型即可提升模型在該任務上的表現。

- LoRA使用範例:
    - 待補


## 備註
圖片皆為網路上抓取，當中內容也有參考部分介紹網站，若有違反版權之疑慮，請來信告知: tyteng064@gmail.com，若造成您的不便，請見諒。