# 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維的向量,W \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,若造成您的不便,請見諒。