十分鐘學會微調大語言模型

萤火架构發表於2024-04-19

在之前的文章中,我分享了一些使用大語言模型開發應用的方法,也介紹了幾個開源大語言模型的部署方式,文章參見:大模型應用開發- - 螢火架構 - 部落格園 (cnblogs.com)

有同學給我留言說想知道怎麼訓練自己的大語言模型,讓它更貼合自己的業務場景。完整的大語言模型訓練成本比較高昂,不是我們業餘玩家能搞的,如果我們只是想在某個業務場景或者垂直的方面加強大模型的能力,可以進行微調訓練。

本文就來介紹一種大語言模型微調的方法,使用的工具是我最近在用的 Text Generation WebUI,它提供了一個訓練LoRA的功能。

LoRA是什麼

LoRA之於大語言模型,就像設計模式中的裝飾器模式:裝飾器模式允許向一個物件新增新的功能,而不改變其結構。具體來說,裝飾器模式會建立一個裝飾類,用來包裝原有的類,並在保持原有類方法簽名完整性的前提下,提供額外的功能。

LoRA,全稱為Low-Rank Adaptation,是一種微調大型語言模型的技術。LoRA透過向大型語言模型新增一層額外的、低秩的可訓練權重,來增強或調整模型的功能,而不需要改變原有模型的結構或重新訓練整個模型。這就像是用裝飾器包裝了一個物件,增強了其功能,但沒有改變原有物件的本質。

LoRA的關鍵思想是在模型的某些部分(通常是Transfomer注意力機制的權重矩陣)中引入低秩矩陣(低秩就是矩陣的行和列相對大模型的矩陣比較少)。在前向傳播和反向傳播過程中,這些低秩矩陣與大模型的權重矩陣相結合,從而實現對模型的微調。

相比完整的訓練,LoRA訓練具備兩個明顯的優勢:

  • 高效:微調過程中需要的計算資源和儲存空間相對很少,如果訓練資料只是幾千條對話資料,我們可以在分鐘級的時間內完成微調。
  • 靈活:因為引入的引數數量相對較少,可以在一定程度上避免過擬合問題,使得模型更容易適應新任務。

因此,研究人員和開發者使用LoRA,可以在不犧牲模型效能的前提下,以較低的成本對模型進行有效的定製和最佳化。

工具安裝

Text Generation WebUI 是一個開源專案,提供了一個Web介面方便大家做模型的推理和訓練,大家可以在Github上下載到這個程式:

https://github.com/oobabooga/text-generation-webui

安裝比較簡單,如果遇到問題,歡迎留言討論。


為了方便測試,我在雲環境也建立了一個映象,相關的環境都配置好了,可以直接使用幾個國內開源的大語言模型,比如清華智譜的ChatGLM3-6B、零一萬物的Yi-34B,還有最近阿里雲開源的Qwen1.5-32B。

映象使用方法:

1、訪問AutoDL(https://www.autodl.com),註冊個賬號,充上幾個米,金額要大於所租用伺服器的小時單價。

2、GPU型號:最好選擇 3090 或者 4090。因為大模型需要的視訊記憶體一般都不低,6B、7B的模型做推理都需要15G左右的視訊記憶體。GPU數量選擇1個就夠了。

十分鐘學會微調大語言模型

3、映象:選擇“社群映象”,輸入 yinghuoai-text-generation-webui ,即可選擇到我分享的映象。

十分鐘學會微調大語言模型

4、伺服器開機後,點選“JupyterLab”進入一個可程式設計的Web互動環境。

十分鐘學會微調大語言模型

5、映象內建了一個“啟動器”,點選其中的啟動按鈕可以直接啟動WebUI。

十分鐘學會微調大語言模型

程式預設載入的是阿里開源的 Qwen1.5-7B-Chat 模型,你也可以更換別的模型,只需要去掉命令前邊的“#”,注意同時只能載入一個模型,其它模型不使用時,請使用“#”註釋掉。

十分鐘學會微調大語言模型

6、在下方的日誌中看到類似輸出的時候,就代表啟動成功了。其中的 https://xxx.gradio.live 就是WebUI的連結,點選就可以在瀏覽器開啟它的使用介面。

十分鐘學會微調大語言模型

Lora訓練方法

終於來到重點環節了。

訓練

訓練需要一個基礎模型,映象預設載入的是 Qwen1.5-7B-Chat。你也可以在WebUI中更換別的模型(前提是已經下載到模型目錄),在 Model 頁籤這裡選擇別的模型,然後點選 Load 載入它。

十分鐘學會微調大語言模型

我們先來快速的過一遍訓練過程,請按照下邊的步驟開啟LoRA訓練:

1、切換到 Training 頁籤。

2、點選 Train LoRA,進入LoRA訓練設定頁面。

3、填寫Lora模型的名字,注意名字中不能包含英文的點(.)。

4、點選 Formatted DataSet,代表訓練將使用格式化的資料集。

5、Data Format 資料格式,這裡選擇 alpaca-format,這是一種Json資料格式,每條資料宣告瞭指令、輸入和輸出(其中input是可選的,我們可以把input的內容填寫到instructions中,從而去掉input節點),如下所示:

{
    "instruction": "下面是一個對話:",
    "input":"只剩一個心臟了還能活嗎?",
    "output": "能,人本來就只有一個心臟。"
}

6、Dataset 選擇資料集,我這裡從 huggingface 上下載了一份弱智吧的問答資料集,映象中已經內建。你如果使用自己的訓練資料集,請上傳到 text-generation-webui/training/datasets 中,然後在這裡重新整理後就可以選擇到。

7、點選 Start LoRA Training 開始訓練。

8、這裡會展示訓練的進度,還剩多長時間。

十分鐘學會微調大語言模型

訓練完成後,這裡會顯示“Done”。注意這裡有個問題:如果WebUI和伺服器斷開了網路連線,這裡就不更新進度了,此時可以去 AutoDL的 jupyterlab 或者你的命令介面中檢視訓練進度。

十分鐘學會微調大語言模型

驗證

訓練完成後,我們需要測試下效果,參考如下步驟:

1、切換到 Model 頁面。

2、點選 Reload 重新載入模型,因為此時模型已經被訓練汙染了。

3、重新整理LoRA列表。

4、選擇我們訓練出來的模型。

5、Apply LoRAs 應用LoRA模型。

十分鐘學會微調大語言模型

然後在 Parameters 中選擇內建的聊天對話角色。

十分鐘學會微調大語言模型

最後切換到 Chat 頁面,開始對話測試。下面是我分別使用基礎模型和新增LoRA模型後的對話截圖,測試不是很嚴謹,但也能看到比較明顯的差別。

兩個 Qwen1.5-7B-Chat 很難回答正確的問題:

  • 生魚片是死魚片嗎?
  • 小明的爸爸媽媽為什麼不邀請小明參加他們的婚禮?

十分鐘學會微調大語言模型

十分鐘學會微調大語言模型

訓練引數

在上邊的步驟中我們使用的都是預設的訓練引數,一般也就夠了。但有時候對訓練出的生成效果不太滿意,就可以手動調整下訓練引數,重新訓練。

我這裡把主要的幾個引數介紹下:

1、目標模組

這個引數僅針對 llama 型別的模型結構,預設勾選的是 q_proj 和 v_proj,具體的名詞不容易理解,我就不多說了,可以簡單的認為是對模型的理解能力進行最佳化,一般這兩個就夠了。當然我們可以勾選更多的專案,最佳化模型的生成效果。但是可能會導致兩個問題,一是訓練要使用更多的資源,更慢;二是可能導致過擬合問題,也就是隻在訓練的資料上表現的好,面對新問題就不靈了。Qwen1.5-7B的模型結構也是llama型別的。

十分鐘學會微調大語言模型

2、Epochs

這個引數代表我們要訓練多少輪。訓練的輪次越多,模型從訓練資料中學到的越多,生成就越精確,不過也可能會導致過擬合的問題,所以需要根據實際測試的結果進行調整。

3、LoRA Rank

維度計數,模型權重的更新量。值越大越檔案越大,內容控制力更強;較低的值則表示檔案更小,控制程度較低。

對於較為簡單的任務或者資料量較小的應用場景,可以選擇較低的值,比如4或8。這樣可以保持模型的簡潔性,減少所需的儲存空間和計算資源,同時避免過擬合。

對於複雜的自然語言處理任務,特別是需要捕捉精細語義關係、句法結構或領域專業知識的任務,或者大規模訓練資料時,可能需要選擇較高的值,如128、256甚至1024以上,這樣才有足夠的容量來學習到複雜的模式。更高的LoRA Rank需要更多的視訊記憶體支援。

LoRA Rank還應該與LLM的基礎模型規模相匹配,百億權重的模型可以設定更大值,因為它可以承受更多的權重調整而不會過擬合。

4、LoRA Alpha

數值越高代表LoRA的影響力越大,預設是LoRA Rank值的兩倍。當這個值較高時,適應新任務的能力會增強,但是對基礎模型的影響會比較大,有過擬合的風險,尤其是在資料量有限的情況下。當這個值比較低時,對基礎模型引數的改變較為溫和,這可以保持預訓練模型的泛化能力,但也會降低對新任務的適應性,特別是LoRA任務與預訓練任務差異比較大時。

5、Learning Rate

學習率。機器學習在訓練過程中會不斷檢查自己與訓練資料的偏離程度,它有個名詞叫損失(loss),一個合適的學習率會讓損失逐漸收斂在一個最小值。如果學習率太大,步子就會邁的太大,不能獲取較好的效果;但是如果學習率太小,又會訓練的很慢,成本太高。如下圖所示:

十分鐘學會微調大語言模型

預設值 3e-4 表示 3 乘以 10 的負 4 次方,也就是 0.0003。最大1e-2表示0.01,最小1e-6表示0.000001。

另外需要平衡學習率和輪次:

高學習率 + 低輪次 = 非常快但質量較低的訓練。

低學習率 + 高輪次 = 較慢但質量較高的訓練。

6、LR Scheduler

學習率排程演算法,預設的是線性衰減,也就是隨著學習輪次的增加學習率逐漸降低。

還有使用常量、餘弦退火、逆平方根、多項式時間等演算法,線性衰減和餘弦退火比較簡單有效,平常使用的比較多,逆平方根衰減和多項式時間衰減在處理大規模資料或需要長時間訓練時能提供更為穩定的收斂表現


一個好的模型與訓練資料和訓練引數都有很大的關係,很難一蹴而就。

如果你對訓練的結果不滿意,可以調整這幾個引數試試。注意重新訓練前,先把基礎模型重新載入。

十分鐘學會微調大語言模型

以上就是本文的主要內容,如有問題,歡迎給我留言交流。

相關文章