大語言模型的微調流程通常分為資料準備、模型設定與微調、以及模型評估三個階段。資料準備階段需要下載和格式化資料集,並將資料集批次化以提高訓練效率。同時,需要建立資料載入器以便在訓練過程中有效管理資料,並載入預先訓練的語言模型作為微調的基礎。模型設定與微調階段則涉及選擇合適的超引數,例如學習率和批次大小,並根據評估指標微調模型。最後,模型評估階段使用準確率、F1 分數等指標評估模型的效能,並據此調整和最佳化模型。在監督式指令微調中,資料集的準備尤為重要,需要包含指令和對應的回應,以便模型學習如何根據指令產生正確的結果。
人工智慧模型微調的三階段過程
在人工智慧領域中,尤其是在語言模型的訓練和微調中,遵循一個系統化的流程至關重要。這個流程可以分為三個主要階段:資料準備、模型設定和微調,以及模型評估。每個階段都包含多個步驟,以下將詳細介紹這些步驟。
第一階段:資料準備
資料準備是微調語言模型的基礎。這個階段包括以下步驟:
資料下載和格式化:首先,需要下載適合的資料集。這些資料集應該與模型的目標任務相關,並且需要進行格式化,以便模型能夠理解和處理。格式化可能涉及清理資料、標記資料等步驟,以確保資料的品質和一致性。
批次處理資料集:批次處理(batching)是指將資料分成小塊(批次),以便於模型的訓練。這個步驟有助於提高模型的訓練效率,因為它允許模型一次處理多個樣本,而不是一次一個樣本。
建立資料載入器:資料載入器(data loaders)是用於從資料集中載入批次資料的工具。它們使得在訓練過程中高效地存取和管理資料成為可能。
載入預先訓練的語言模型:大多數語言模型微調任務都從一個預先訓練好的模型開始。這些模型已經在大量的文字資料上進行了預先訓練,可以作為微調任務的起點。
指令微調:這是微調過程的核心部分。在這個步驟中,模型會在特定的指令或任務上進行微調,以改善其在這些任務上的效能。指令微調涉及調整模型的引數,以最小化預測輸出和真實輸出之間的差異。
第二階段:模型設定和微調
在第一階段完成後,接下來需要設定和微調模型。這包括選擇合適的超引數(如學習率、批次大小等),並根據選定的評估指標對模型進行微調。
第三階段:模型評估
最後,評估模型在指定任務上的效能是非常重要的。這通常涉及使用評估指標(如準確率、F1分數等)來衡量模型的效能,並根據評估結果對模型進行調整和最佳化。
總之,人工智慧模型的微調是一個複雜的過程,需要仔細的資料準備、模型設定和評估。透過遵循這個三階段的流程,開發者可以建立出高效能的語言模型,用於各種自然語言處理任務。
準備監督式指令微調的資料集
在開始微調預訓練的大語言模型(LLM)之前,我們需要準備一個適合的資料集。這個資料集應該包含指令和相應的回應,讓模型能夠學習如何根據指令生成正確的回應。
下載和格式化指令資料集
首先,我們需要下載指令資料集。這個資料集包含了1,100個指令和回應的配對,類別似於圖7.2所示。這個資料集是為了本章而建立的,但讀者也可以在附錄B中找到其他公開可用的指令資料集。
以下是下載和格式化指令資料集的Python程式碼:
import json
import os
import urllib.request
# 下載指令資料集
url = "https://example.com/instruction_dataset.json"
filename = "instruction_dataset.json"
urllib.request.urlretrieve(url, filename)
# 載入指令資料集
with open(filename, 'r') as f:
dataset = json.load(f)
# 格式化指令資料集
instructions = []
responses = []
for pair in dataset:
instructions.append(pair['instruction'])
responses.append(pair['response'])
這個程式碼下載了指令資料集,並將其儲存在一個名為instruction_dataset.json
的檔案中。然後,它載入了資料集,並將指令和回應分別儲存在instructions
和responses
列表中。
資料集結構
指令資料集的結構如下:
[
{
"instruction": "指令1",
"response": "回應1"
},
{
"instruction": "指令2",
"response": "回應2"
},
...
]
這個結構使用JSON格式,類別似於Python字典的結構。它提供了一個簡單的結構,讓人們和機器都能夠輕鬆地閱讀和理解。
資料集大小
指令資料集相對較小,只有204 KB。這使得它容易下載和儲存。
內容解密:
- 下載指令資料集的程式碼使用了
urllib.request.urlretrieve
函式來下載檔案。 - 載入指令資料集的程式碼使用了
json.load
函式來解析JSON檔案。 - 格式化指令資料集的程式碼使用了迴圈來分別儲存指令和回應。
圖表翻譯:
flowchart TD A[下載指令資料集] --> B[載入指令資料集] B --> C[格式化指令資料集] C --> D[微調預訓練的大語言模型]
這個流程圖顯示了下載、載入和格式化指令資料集的過程,然後使用這個資料集來微調預訓練的大語言模型。
下載和載入檔案:一個實用的範例
import os
import urllib.request
import json
def 下載和載入檔案(檔案路徑, 網址):
"""
下載檔案並載入其內容。
Args:
檔案路徑 (str): 檔案的本地路徑。
網址 (str): 檔案的網路路徑。
Returns:
dict: 載入的 JSON 資料。
"""
if not os.path.exists(檔案路徑):
# 下載檔案
with urllib.request.urlopen(網址) as 回應:
文字資料 = 回應.read().decode("utf-8")
with open(檔案路徑, "w", encoding="utf-8") as 檔案:
檔案.write(文字資料)
else:
# 載入檔案
with open(檔案路徑, "r", encoding="utf-8") as 檔案:
文字資料 = 檔案.read()
# 載入 JSON 資料
with open(檔案路徑, "r") as 檔案:
資料 = json.load(檔案)
return 資料
# 定義檔案路徑和網址
檔案路徑 = "instruction-data.json"
網址 = "/main/ch07/01_main-chapter-code/instruction-data.json"
# 下載和載入檔案
資料 = 下載和載入檔案(檔案路徑, 網址)
# 列印資料筆數
print("資料筆數:", len(資料))
# 列印一個範例資料
print("範例資料:\n", 資料[50])
內容解密:
上述程式碼定義了一個函式 下載和載入檔案
,用於下載檔案並載入其內容。函式接受兩個引數:檔案路徑
和 網址
。如果檔案不存在,則下載檔案並儲存到本地。如果檔案已經存在,則直接載入其內容。然後,程式碼定義了檔案路徑和網址,呼叫 下載和載入檔案
函式,並列印資料筆數和一個範例資料。
圖表翻譯:
flowchart TD A[開始] --> B[下載檔案] B --> C[載入檔案] C --> D[列印資料筆數] D --> E[列印範例資料]
圖表翻譯:
上述流程圖描述了程式碼的執行流程。首先,程式碼開始執行(A)。然後,程式碼下載檔案(B)。接下來,程式碼載入檔案(C)。然後,程式碼列印資料筆數(D)。最後,程式碼列印一個範例資料(E)。
微調模型以遵循指令
在微調模型的過程中,我們需要一個包含明確輸入輸出對的資料集。這些對應關係可以透過特定的格式進行協調,以便於大語言模型(LLM)進行學習。下面是一個例子,展示瞭如何構建這種資料集:
資料集範例
{
"指令": "找出以下單詞的正確拼寫。",
"輸入": "Ocassion",
"輸出": "正確拼寫是 'Occasion'。"
}
如上所示,每個資料集條目都是一個包含指令、輸入和輸出的字典物件。讓我們觀察另一個例子:
print("另一個例子條目:\n", data[999])
根據這個條目的內容,可以發現輸入欄位有時可能是空的:
{
"指令": "什麼是 'complicated' 的反義詞?",
"輸入": "",
"輸出": " 'complicated' 的反義詞是 'simple'。"
}
指令微調方法
指令微調涉及訓練模型使用一個資料集,其中輸入輸出對像上面從 JSON 檔案中提取的那樣被明確提供。有多種方法可以為 LLM 格式化這些條目。圖 7.4 展示了兩種不同的提示風格,分別是 Alpaca 和 Phi-3 風格。
Alpaca 風格
Alpaca 風格使用結構化格式,定義了指令、輸入和回應的部分:
{
"指令": "找出以下單詞的正確拼寫。",
"輸入": "Ocassion",
"輸出": "正確拼寫是 'Occasion'。"
}
Phi-3 風格
Phi-3 風格採用更簡單的格式,使用指定的 <|user|>
和 <|assistant|>
標記:
<|user|>
找出以下單詞的正確拼寫:'Ocassion'
<|assistant|>
正確拼寫是 'Occasion'。
應用 Alpaca 和 Phi-3 提示範本
以下是使用 Alpaca 和 Phi-3 提示範本的示例:
Alpaca 範本
### 指令:
找出以下單詞的正確拼寫。
### 輸入:
Ocassion
### 回應:
正確拼寫是 'Occasion'。
Phi-3 範本
<|user|>
找出以下單詞的正確拼寫:'Ocassion'
<|assistant|>
正確拼寫是 'Occasion'。
透過這些方法,可以有效地微調模型以遵循指令,從而提高其在特定任務上的效能。
訓練大語言模型的資料準備
為了訓練大語言模型(LLM),需要準備一個高品質的資料集。這個資料集應該包含多樣化的指令和輸入,以便模型能夠學習到不同的語言模式和生成高品質的回應。
資料格式化
為了格式化資料,我們可以定義一個函式 format_input
,它可以將資料集中的每個條目轉換為 Alpaca 樣式的輸入格式。Alpaca 樣式是一種常見的格式,尤其是在早期的大語言模型中被廣泛使用。
def format_input(entry):
instruction_text = (
f"以下是一個描述任務的指令。請寫出一個適當的回應來完成請求。\n\n"
f"### 指令:\n{entry['instruction']}"
)
input_text = (
f"\n\n### 輸入:\n{entry['input']}" if entry["input"] else ""
)
return instruction_text + input_text
這個函式接收一個字典 entry
作為輸入,並建構一個格式化的字串。讓我們測試一下這個函式,使用資料集中的第 50 個條目作為示例。
model_input = format_input(data[50])
desired_response = f"\n\n### 回應:\n{data[50]['output']}"
print(model_input + desired_response)
格式化的輸入看起來像這樣: 以下是一個描述任務的指令。請寫出一個適當的回應來完成請求。
指令:
識別以下單詞的正確拼寫。
輸入:
Ocassion
回應:
正確的拼寫是 ‘Occasion.’
練習 7.1 更改提示樣式
在使用 Alpaca 樣式對模型進行微調後,嘗試使用 Phi-3 樣式(如圖 7.4 所示),並觀察它是否影響模型的回應品質。
實作提示格式化函式
注意 format_input
函式跳過了可選的 ### 輸入:
部分,如果 ‘input’ 欄位是空的,我們可以透過測試之前檢查過的 data[999]
來驗證這一點:
model_input = format_input(data[999])
desired_response = f"\n\n### 回應:\n{data[999]['output']}"
print(model_input + desired_response)
輸出顯示,具有空 ‘input’ 欄位的條目不包含 ### 輸入:
部分在格式化輸入中:
以下是一個描述任務的指令。請寫出一個適當的回應來完成請求。
指令:
識別以下單詞的正確拼寫。
回應:
正確的拼寫是 ‘Occasion.’
從資料準備、模型設定與微調,到模型評估,本文深入探討了人工智慧模型微調的三階段流程,並著重闡述了監督式指令微調的資料集準備方法,包括資料下載、格式化、批次處理及載入等關鍵步驟。透過 Alpaca 和 Phi-3 兩種不同的提示風格範例,我們清晰地展示瞭如何構建有效的指令微調資料集,以及如何利用 <|user|>
和 <|assistant|>
等標記進行資料組織。此外,format_input
函式的實作更進一步說明瞭如何將原始資料轉換成適合模型訓練的格式,同時兼顧了輸入欄位可選的情況。
然而,僅僅準備好資料集並不足以保證模型的最佳效能。模型超引數的選擇、微調策略的制定,以及評估指標的選取都將顯著影響最終結果。技術團隊需要根據具體任務需求,審慎選擇合適的模型架構、調整學習率和批次大小等引數,並持續監控模型的訓練過程,以避免過擬合或欠擬合等問題。同時,Phi-3 提示風格相較於 Alpaca 風格的簡潔性,是否在特定任務上能帶來效能提升,仍需更多實驗驗證。
展望未來,隨著模型規模的不斷增大和資料量的持續擴充,指令微調技術將持續演進。如何有效地利用更大規模的資料集、設計更精巧的提示範本,以及探索更先進的微調演算法,將是未來研究的重點方向。玄貓認為,深入理解指令微調的原理和實踐,並持續關注相關技術的發展趨勢,對於構建高效能的語言模型至關重要。對於資源有限的團隊,建議優先關注資料集的品質和多樣性,並逐步探索不同提示風格和微調策略的影響,以最大化模型的效能。