iT邦幫忙

2024 iThome 鐵人賽

DAY 11
0
生成式 AI

Python 新手的 AI 之旅:從零開始打造屬於你的 AI / LLM 應用系列 第 11

【Day11】把知識放到腦袋中:使用 unsloth 微調 (Fine-Tune) 大型語言模型

  • 分享至 

  • xImage
  •  

前言

我們在前十天嘗試了很多操作模型的方法,包含讓模型使用工具、用 RAG 提高答案生成的精確度、用 Ollama 在本地跑模型等等等,但這些都不是「訓練」一個模型。或許你在 Prompt Engineering 那邊有聽過 “In context learning” 這個名詞,但事實上這個技術也只是將資訊提供在提示詞的上下文,對模型本身所擁有的知識沒有任何影響。

這篇文的前半段會是與微調有關的知識基本介紹,後半就是實作,有基本概念的朋友可以直接跳到後面歐~

預訓練模型 (Pre-Trained Model) 是什麼?

在前十天的內容,我常常提到語言模型做文字接龍這件事,那這個在做單純文字接龍的模型叫什麼呢?它就叫預訓練模型 (Pre-Trained Model),「預訓練 (Pre-Train)」是對模型進行初步訓練的過程,模型會在大量未標記的資料上進行訓練,這些資料可能是網路文章、書籍等等,讓模型理解語法結構、語意等複雜的規則。所以這個模型會做的事情就真的只有純文字接龍,根據輸入的字串去預測下一個出現的字是什麼,然後再接回去 (可以參考 Day2 的內容)。

你可以把這個預訓練模型想成是一個通才,它什麼都會,腦袋裡什麼都裝,但同時也什麼都做不好。

這時候你就需要去微調它。

微調 (Fine-tuning) 是什麼?

剛剛提到預訓練模型是一個什麼都懂,但什麼都不會得通才,微調就是讓這個與訓練模型針對特定的任務表現更好。那到底是在調什麼?我們都知道大型語言模型有大量的參數,而微調其實就是調整其中少量參數的過程,使其在特定任務上的性能更好。

如果你有開始實作自己的 RAG 系統,應該會發現當資料量變大,查詢的速度變慢的時候,使用者從問問題到接收答案這段過程就會被拉長,微調就相當於把知識直接塞給語言模型,讓這個系統不必再做一次查詢。

微調有以下優點

  • 速度快,不需要先查詢向量資料庫 (但其實大部分的情況都是搭配著用)
  • 利用有限的標注資料:當資料量少的時候,你更需要微調
  • 不需要從頭到尾訓練一個大型語言模型
  • 適應特定任務

過度擬合 (Overfitting)

既然都提到訓練模型了,就不能不知道機器學習中 Overfitting 的概念

什麼是 Overfitting?想像你讓一個學生死背課本的內容,你問他課本的內容他都能回答出來,不過一但給他課本沒有的題目,他就不會了,這就是 Overfitting。只會應對學過的情況,而沒有舉一反三的能力。

大型語言模型也會有這個問題,所以如何把模型訓練得恰到好處,超參數的設置就很有學問了。

LoRA / QLoRA 又是什麼?

LoRA 全名 Low Rank Adaption,最早在一篇 2021 年的論文〈LoRA: Low-Rank Adaptation of Large Language Models〉提到這個概念,是一種有效率的微調方法 (Parameter-Efficient Fine-Tuning, PEFT),LoRA 這個微調方法屬於 Adapter 的一種,至於 LoRA 的細節可以參考〈【LLM專欄】All about Lora〉這篇文章。QLoRA 的 Q 指的是 quantization 的意思,基於 LoRA 的概念,引入了量化技術,將模型的參數壓縮到較小的位數。

Adapter 是什麼?

Adapter 就是在原本的大型語言模型加上一個插件,他會先凍結 (Freeze) 預訓練模型的初始參數,完全不去動它,只有微調這個 Adapter,在要使用的時候把訓練好的 Adapter 參數直接加在初始參數後面。如此一來,這樣可以減少運算量,因為對我們來說要找大量的參數是不可能的,但找少量的參數,用 Adapter 是可以做到的。注意:LoRA 是一種 Adapter,而 Adapter 有很多種。

截圖 2024-09-18 晚上10.57.32.png

(你可以為不同的需求訓練不同的 Adapter,而且只需要存一個大型語言模型,和多個 Adapter 即可)

開始實作

介紹完一些基本概念了,這些基本概念在你之後自己設定程式碼的超參數 (hyperparameter) 會很有幫助,比方說避免 overfitting 等等,也是另一段通靈之路的開始。現在要開始實作了!不會太困難的,請放輕鬆~

準備資料集

在微調自己的模型之前,我們要先準備資料集,這邊以 Day4 找到的文章為例,我希望做一個模型他可以完美回答有關這篇文章的相關問題,那該怎麼拿到資料呢?

通常 Instruction Fine-Tuning 的資料格式會像以下的 Json 檔案

[
    {
        "instruction": "行政罰和罰金有何不同?",
        "input": "",
        "output": "行政罰是行政法的一種處罰,而罰金則是刑法的一種處罰。行政罰由行政機關執行,不會有前科紀錄,而罰金由法院宣告,會有前科紀錄。"
    },
    {
        "instruction": "請說明無照駕駛撞傷人可能面對的不同法律責任?",
        "input": "",
        "output": "無照駕駛可能要面對行政責任和刑事責任,如果撞傷人還需承擔民事責任。"
    }
]

我們可以利用 In context learning 給模型這個 Json 格式的資料以及文章本身,讓他幫我們產生有關的資料。你可以用昨天架好的 Open WebUI 來做,也可以直接用 ChatGPT,以下是我的 Prompt

請閱讀這篇文章,以下是文章的內容
"""
{這邊放文章內容}
"""
請參考以下資料格式,產生十筆與文章內容相關的 QA 資料
[
    {
        "instruction": "行政罰和罰金有何不同?",
        "input": "",
        "output": "行政罰是行政法的一種處罰,而罰金則是刑法的一種處罰。行政罰由行政機關執行,不會有前科紀錄,而罰金由法院宣告,會有前科紀錄。"
    },
    {
        "instruction": "請說明無照駕駛撞傷人可能面對的不同法律責任?",
        "input": "",
        "output": "無照駕駛可能要面對行政責任和刑事責任,如果撞傷人還需承擔民事責任。"
    }
]

效果不錯,我們可以直接把這些 JSON 資料複製到一個檔案中

image.png

注意:資料請務必符合 JSON 的格式,你可以用 JSONLint 來檢查格式是否正確,他還會順便幫你把縮排排好,舒服~

image.png

使用 Unsloth 在 Google Colab 上微調模型!

Unsloth 是一個開源的系統,專門用來微調 LLM,號稱可以提高微調速度並減少記憶體開銷。

我們可以用 Unsloth 提供的 Google Colab 連結來準備微調,這邊我用的是 Llama3.1 的連結

image.png

  1. 第一步,選擇 GPU:先到 Colab 上的執行階段 → 變更執行階段類型 → 選擇 T4 GPU

    image.png

  2. 上傳資料:在左邊的檔案新增一個資料夾,這邊我命名為 data,然後把剛剛的 json 檔案放進去

    image.png

  3. 你可以在這邊把 model_name 改成你想要的模型,你可以到 unsloth 的 huggingface 上找到自己喜歡的模型

    image.png

  4. 修改資料路徑,在 Data Prep 這邊把路徑改成 /content/資料夾名稱

    image.png

你可以去修改參數,也可以直接用預設值,剩下的就是點一點左邊的小三角形執行程式碼就可以了,想不到微調可以這麼簡單吧~

image.png

訓練完成之後,我們要把模型存下來,滑到這個 Colab 的 GGUF/llama.cpp Conversion 這邊去設定儲存模型

你可以到下面選擇要存成什麼格式的 GGUF 檔,根據你的需求把 False 改成 True。你可以把 q4_k_m 的這一行改成 True,他會把 gguf 下載到 colab 的資料夾。你也可以把 gguf 上傳到 huggingface 上,這邊我就是用這種方式,不過你要先到 huggingface 上取得 access token。記得把 hf/model 改成 [你的 user name]/[模型名稱] ,這邊我就改成 yenslife/it-ironman-llama3-demo

image.png

整個過程大概需要跑二三十分鐘,老實說蠻久的,你可以去泡杯咖啡,運動一下也好,不過要注意不要讓螢幕休眠,不然 Colab 會斷線歐

完成後的樣子

image.png

模型已經被上傳到 Huggingface 了!

image.png

將模型導入 Ollama 並用 Open WebUI 測試

下載好 GGUF 之後,我們可以用昨天的方法來導入 Ollama,你也可以直接到 Open WebUI 上傳 GGUF

到管理員控制台 → 模型 → 實驗性功能 → 上傳 GGUF 模型 → 按右邊的上傳按鈕

image.png

如果上傳失敗,你可以嘗試用 url 模式,上傳 download 網址 (右鍵複製網址)

image.png

image.png

加入完成後,你就可以在聊天選擇模型的地方看到這個 unsloth 模型,來測試一下吧!

image.png

看來結果是不錯的,畢竟我只有用 10 筆資料,最後還是有出現一些出乎意料的回應 (交通部?是要翻譯啥QQ)

如果我問 llama3.1 一樣的問題,他則會說不知道

image.png

小結

我在使用 Unsloth 微調的時候我遇到蠻多問題的,花了好幾個小時才順利跑一次,不過幸好最後有成功弄出來~ 希望今天的內容可以讓你對模型微調有基本的認識,之後在做更大的 LLM 系統,如果公司有速度上的考量不妨嘗試一下微調吧!

明天來點輕鬆的(?),分享用 AI 寫 Prompt 的技巧還有評估驅動開發,期待一下吧~


上一篇
【Day10】不想讓資料外洩怎麼辦:在本地用 Ollama 搭配 Open WebUI 做一個聊天界面吧!
下一篇
【Day12】初探 LLM 評估驅動開發 (Eval-Driven Development) 與 Prompt 生成器:用 AI 來調教 AI
系列文
Python 新手的 AI 之旅:從零開始打造屬於你的 AI / LLM 應用12
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言