隨著資料量的增加,根據檢索增強生成(RAG)的系統效能和成本效益會受到影響。此時,微調大語言模型成為最佳化 RAG 系統的關鍵技術。本文將以 OpenAI 的 GPT-4o-mini 模型為例,詳細說明如何透過微調技術提升 RAG 系統效能。首先,我們需要準備 SciQ 資料集,並將其轉換成 OpenAI API 所需的 JSONL 格式。接著,利用 OpenAI API 上傳訓練資料並啟動微調任務。過程中,我們可以透過 API 監控微調任務的狀態,並在完成後取得微調後的模型。最後,我們將使用微調後的模型進行推理,驗證其在科學問答方面的效能提升。
微調大語言模型的技術:以OpenAI GPT-4o-mini為例
隨著人工智慧技術的快速發展,根據檢索增強生成(RAG)的系統在多個領域展現出強大的應用潛力。然而,當RAG資料量超過可管理的門檻時,系統的效能和成本效益將受到嚴重影響。本篇文章將探討如何透過微調(fine-tuning)技術來最佳化RAG系統,重點介紹使用OpenAI的GPT-4o-mini模型進行微調的完整流程。
RAG資料管理的限制
RAG系統依賴於大量的靜態資料來提供準確的生成結果。然而,當資料量不斷增長時,系統的處理和儲存成本將急劇增加。此外,資料的冗餘性和檢索效率也會成為瓶頸。因此,確定何時需要對RAG資料進行微調至關重要。
圖9.1:RAG資料的微調門檻
在圖9.1中,我們可以看到當靜態資料的處理和儲存門檻被突破時,系統需要採取微調措施來最佳化效能。影響微調門檻的因素包括:
- RAG資料的處理量:嵌入資料需要大量的人力和機器資源。
- RAG資料的儲存和檢索量:過多的資料會導致冗餘和資源浪費。
- 檢索所需的資源:即使用開源系統,資源管理也會變得越來越複雜。
微調的架構
微調是解決RAG資料門檻問題的有效方法。本文將介紹微調的架構和關鍵元件。
圖9.2:RAG生態系統中的微調元件
在圖9.2中,彩色部分代表本章節將重點介紹的微調元件:
- 資料收集(D1)和準備(D2):下載並處理SciQ資料集,將其轉換為適合微調的JSONL格式。
- 人類反饋(E2):SciQ資料集經過人類控制和更新,可以視為可靠的人類反饋模擬。
- 微調(T2):使用GPT-4o-mini模型進行微調。
- 提示工程(G3)和生成輸出(G4):根據OpenAI的建議設計提示並展示輸出結果。
- 指標(E1):使用OpenAI的指標介面監控技術指標,如準確性和使用情況。
環境安裝
為了進行微調,首先需要安裝必要的環境和套件。以下是具體步驟:
# 從檔案中檢索API金鑰
from google.colab import drive
drive.mount('/content/drive')
f = open("drive/MyDrive/files/api_key.txt", "r")
API_KEY = f.readline()
f.close()
# 安裝openai並設定API金鑰
try:
import openai
except:
!pip install openai==1.42.0
import openai
import os
os.environ['OPENAI_API_KEY'] = API_KEY
openai.api_key = os.getenv("OPENAI_API_KEY")
# 安裝jsonlines以生成JSONL資料
!pip install jsonlines==4.0.0
# 安裝datasets
!pip install datasets==2.20.0
內容解讀:
上述程式碼片段展示瞭如何安裝必要的Python套件並設定OpenAI的API金鑰。主要步驟包括:
- 從掛載的Google Drive中讀取API金鑰檔案。
- 安裝
openai套件並設定環境變數。 - 安裝
jsonlines和datasets套件,用於處理JSONL格式資料和資料集下載。
準備微調資料集
微調OpenAI模型需要仔細準備資料集,否則微調作業可能會失敗。以下是準備資料集的步驟:
- 下載資料集:從Hugging Face下載SciQ資料集。
- 處理資料集欄位:將資料集轉換為適合微調的格式。
- 將資料集串流至JSONL檔案:生成符合OpenAI微調要求的JSONL格式檔案。
下載和視覺化資料集
# 下載SciQ資料集
from datasets import load_dataset
dataset = load_dataset("sciq")
# 檢視資料集結構
print(dataset)
內容解讀:
本段程式碼展示瞭如何從Hugging Face下載SciQ資料集並檢視其結構。SciQ是一個包含科學問題和答案的資料集,適合用於微調模型。
微調GPT-4o-mini模型
下載並準備好資料集後,我們將使用OpenAI的GPT-4o-mini模型進行微調。
# 將資料集轉換為JSONL格式
import jsonlines
def convert_to_jsonl(dataset, output_file):
with jsonlines.open(output_file, mode='w') as writer:
for example in dataset:
prompt = example['question']
completion = example['answer']
writer.write({'prompt': prompt, 'completion': completion})
convert_to_jsonl(dataset['train'], 'train.jsonl')
convert_to_jsonl(dataset['test'], 'test.jsonl')
# 上傳JSONL檔案到OpenAI進行微調
import openai
# 建立微調任務
response = openai.File.create(
file=open('train.jsonl', 'rb'),
purpose='fine-tune'
)
fine_tune_response = openai.FineTune.create(
training_file=response.id,
model='gpt-4o-mini'
)
內容解讀:
本段程式碼展示瞭如何將SciQ資料集轉換為JSONL格式並上傳至OpenAI進行微調。主要步驟包括:
- 將資料集的每個樣本轉換為包含
prompt和completion的JSON物件。 - 使用OpenAI的API上傳JSONL檔案並建立微調任務。
微調後的模型測試與評估
微調完成後,我們需要測試模型並評估其效能。
# 使用微調後的模型進行預測
fine_tuned_model = fine_tune_response.model
response = openai.Completion.create(
model=fine_tuned_model,
prompt='What is the capital of France?',
max_tokens=50
)
print(response.choices[0].text.strip())
內容解讀:
本段程式碼展示瞭如何使用微調後的GPT-4o-mini模型進行預測。我們輸入一個問題並取得模型的生成結果。
圖表翻譯:
此圖示展示了微調過程中的資料流和關鍵步驟,包括資料下載、格式轉換、模型微調和結果評估。
隨著AI技術的持續進步,微調技術將在更多領域發揮重要作用。未來,我們可以期待更高效的微調方法和更強大的模型架構,為各行各業帶來更多創新應用。
微調GPT-4o-mini模型以應答科學問題
1. 資料集準備與視覺化
1.1. 下載與視覺化資料集
本章節將使用Hugging Face的sciq資料集進行模型微調。首先,我們下載並過濾資料集,以確保只包含有支援文字的科學問題。
# 匯入必要的函式庫
from datasets import load_dataset
import pandas as pd
# 從HuggingFace下載SciQ資料集
dataset_view = load_dataset("sciq", split="train")
# 過濾資料集,只保留有支援文字的資料
filtered_dataset = dataset_view.filter(lambda x: x["support"] != "")
# 列印過濾後的問題數量
print("Number of questions with support: ", len(filtered_dataset))
輸出結果顯示,我們得到了10,481筆有效的科學問題資料。
#### 內容解密:
load_dataset("sciq", split="train")用於從Hugging Face下載sciq資料集的訓練部分。filter(lambda x: x["support"] != "")確保只保留包含支援文字的資料。- 列印結果確認資料集的大小。
接著,我們將過濾後的資料集轉換為pandas DataFrame,並移除包含錯誤答案的欄位。
# 將過濾後的資料集轉換為pandas DataFrame
df_view = pd.DataFrame(filtered_dataset)
# 定義需要移除的欄位
columns_to_drop = ['distractor3', 'distractor1', 'distractor2']
# 移除指定的欄位
df_view = df_view.drop(columns=columns_to_drop)
# 顯示DataFrame的前幾行
df_view.head()
#### 內容解密:
pd.DataFrame(filtered_dataset)將Hugging Face的資料集轉換為pandas DataFrame。drop(columns=columns_to_drop)移除包含錯誤答案的欄位。head()用於顯示DataFrame的前幾行,以確認資料正確性。
1.2. 準備資料集以進行微調
為了微調GPT-4o-mini模型,我們需要將資料集轉換為JSONL格式。以下是具體步驟:
# 準備JSONL檔案的資料專案
items = []
for idx, row in df.iterrows():
detailed_answer = row['correct_answer'] + " Explanation: " + row['support']
items.append({
"messages": [
{"role": "system", "content": "Given a science question, provide a detailed answer."},
{"role": "user", "content": row['question']},
{"role": "assistant", "content": detailed_answer}
]
})
# 將資料寫入JSONL檔案
import jsonlines
with jsonlines.open('/content/QA_prompts_and_completions.json', mode='w') as writer:
writer.write_all(items)
#### 內容解密:
detailed_answer結合正確答案和支援文字,形成詳細的答案。items.append({...})構建符合OpenAI模型輸入格式的資料結構。jsonlines.open(...).write_all(items)將資料寫入JSONL檔案。
2. 微調模型
2.1. 建立微調任務
首先,我們需要建立OpenAI客戶端並上傳訓練檔案。
# 匯入必要的函式庫
from openai import OpenAI
import jsonlines
# 建立OpenAI客戶端
client = OpenAI()
# 上傳訓練檔案
result_file = client.files.create(
file=open("QA_prompts_and_completions.json", "rb"),
purpose="fine-tune"
)
# 列印檔案資訊
print(result_file)
param_training_file_name = result_file.id
print(param_training_file_name)
#### 內容解密:
client = OpenAI()初始化OpenAI客戶端。client.files.create(...)上傳之前準備好的JSONL檔案,用於微調模型。result_file.id取得上傳檔案的ID,供後續微調任務使用。
接著,建立並顯示微調任務:
# 建立微調任務
ft_job = client.fine_tuning.jobs.create(
training_file=param_training_file_name,
model="gpt-4o-mini-2024-07-18"
)
# 列印微調任務資訊
print(ft_job)
#### 內容解密:
client.fine_tuning.jobs.create(...)建立微調任務,指定訓練檔案和模型。print(ft_job)顯示微調任務的詳細資訊,包括任務ID、狀態和超引數。
2.2. 監控微調任務
為了監控微調任務的進度,我們可以查詢最近的微調任務:
# 查詢最近的三個微調任務
fine_tuning_jobs = client.fine_tuning.jobs.list(limit=3)
# 列印任務資訊
for job in fine_tuning_jobs:
print(job)
#### 內容解密:
client.fine_tuning.jobs.list(limit=3)取得最近的三個微調任務。for job in fine_tuning_jobs遍歷並列印每個任務的詳細資訊。
透過上述步驟,我們成功準備了資料集並微調了GPT-4o-mini模型,以應答科學問題。接下來的章節將進一步探討如何評估和最佳化微調後的模型。
- 擴充套件資料集:使用更多樣化的科學問題資料集進行微調,以提高模型的泛化能力。
- 超引數調優:調整微調任務的超引數,如訓練輪數、批次大小和學習率,以最佳化模型效能。
- 模型評估:設計全面的評估指標和方法,以評估微調後模型的效能和準確性。
圖表翻譯:
此圖示顯示了微調GPT-4o-mini模型的流程,包括資料集準備、微調任務建立和監控等步驟。
圖表翻譯:
- 資料集準備:下載並過濾
sciq資料集,將其轉換為JSONL格式。 - 微調任務建立:上傳JSONL檔案,建立微調任務。
- 監控微調任務:查詢並列印最近的微調任務資訊。
透過這些步驟,我們可以有效地微調GPT-4o-mini模型,使其在應答科學問題時表現更好。
微調OpenAI模型並進行推理的完整流程
在人工智慧和自然語言處理領域,微調大語言模型以適應特定任務或領域是一項重要的技術。本文將探討如何使用OpenAI的API來微調GPT-4o-mini模型,並展示如何使用微調後的模型進行推理。
1. 準備工作:檢索微調任務狀態
首先,我們需要檢索之前提交的微調任務的狀態。為此,我們使用OpenAI的Python客戶端函式庫來與API進行互動。
程式碼實作:檢索微調任務
import pandas as pd
from openai import OpenAI
# 初始化OpenAI客戶端
client = OpenAI()
# 檢索最近的三個微調任務
response = client.fine_tuning.jobs.list(limit=3)
# 初始化列表以儲存提取的資料
job_ids = []
created_ats = []
statuses = []
models = []
training_files = []
error_messages = []
fine_tuned_models = []
# 迭代任務以檢索所需資訊
for job in response.data:
job_ids.append(job.id)
created_ats.append(job.created_at)
statuses.append(job.status)
models.append(job.model)
training_files.append(job.training_file)
error_message = job.error.message if job.error else None
error_messages.append(error_message)
fine_tuned_model = job.fine_tuned_model if hasattr(job, 'fine_tuned_model') else None
fine_tuned_models.append(fine_tuned_model)
# 建立DataFrame以儲存微調任務資訊
df = pd.DataFrame({
'Job ID': job_ids,
'Created At': created_ats,
'Status': statuses,
'Model': models,
'Training File': training_files,
'Error Message': error_messages,
'Fine-Tuned Model': fine_tuned_models
})
# 將時間戳轉換為可讀格式並排序
df['Created At'] = pd.to_datetime(df['Created At'], unit='s')
df = df.sort_values(by='Created At', ascending=False)
# 顯示DataFrame
print(df)
內容解密:
此段程式碼的主要功能是檢索最近提交的三個微調任務的狀態,並將相關資訊儲存到一個pandas DataFrame中。首先,我們使用client.fine_tuning.jobs.list(limit=3)來取得最近的三個微調任務。然後,我們迭代這些任務,提取諸如任務ID、建立時間、狀態、使用的模型、訓練檔案、錯誤訊息和微調後的模型名稱等資訊。最後,我們將這些資訊組織成一個DataFrame,並將時間戳轉換為可讀的日期時間格式。
2. 取得最新的微調模型
在檢索到微調任務的狀態後,我們需要確定最新的微調模型是否已經可用。
程式碼實作:取得最新的微調模型
generation = False # 預設為False,直到找到可用的微調模型
# 嘗試找到第一個非空的微調模型
non_empty_models = df[df['Fine-Tuned Model'].notna()]
if not non_empty_models.empty:
first_non_empty_model = non_empty_models['Fine-Tuned Model'].iloc[0]
print("最新的微調模型是:", first_non_empty_model)
generation = True
else:
first_non_empty_model = 'None'
print("未找到微調模型。")
# 顯示第一個非空的微調模型
print("最新的微調模型是:", first_non_empty_model)
內容解密:
這段程式碼檢查DataFrame中是否存在非空的微調模型。如果存在,它將最新的微調模型名稱儲存在first_non_empty_model變數中,並將generation標誌設為True。如果沒有找到任何微調模型,它將輸出相應的訊息。
3. 使用微調後的OpenAI模型進行推理
一旦我們有了可用的微調模型,就可以開始使用它進行推理。
程式碼實作:使用微調模型進行推理
# 定義提示
prompt = "什麼現象使全球風向東北吹向西南?"
if generation:
# 使用微調模型進行推理
response = client.chat.completions.create(
model=first_non_empty_model,
temperature=0.0, # 調整以控制輸出的變化
messages=[
{"role": "system", "content": "給定一個問題,重複我們的資料集中的完成。"},
{"role": "user", "content": prompt}
]
)
else:
print("錯誤:模型為None,無法繼續進行API請求。")
# 列印原始回應
if generation:
print(response)
# 提取回應文字
if generation:
response_text = response.choices[0].message.content
print(response_text)
# 格式化回應文字
import textwrap
if generation:
wrapped_text = textwrap.fill(response_text.strip(), 60)
print(wrapped_text)
內容解密:
此段程式碼首先定義了一個提示(prompt),然後使用微調後的模型進行推理。client.chat.completions.create方法用於生成回應,其中model引數指定了要使用的微調模型,temperature引數控制了輸出的隨機性。我們將系統訊息和使用者提示傳遞給模型,以取得相應的回應。最後,我們提取並格式化模型的回應文字,使其更易於閱讀。