返回文章列表

微調GPT4oMini模型提升RAG系統效能

本文介紹如何使用 OpenAI 的 GPT-4o-mini 模型微調技術最佳化根據檢索增強生成(RAG)的系統,解決資料量過大造成的效能瓶頸。文章涵蓋了從環境設定、資料集準備、模型微調到測試評估的完整流程,並以 SciQ 資料集為例示範如何將資料轉換為 JSONL 格式,最後利用 OpenAI API

機器學習 Web 開發

隨著資料量的增加,根據檢索增強生成(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中,彩色部分代表本章節將重點介紹的微調元件:

  1. 資料收集(D1)和準備(D2):下載並處理SciQ資料集,將其轉換為適合微調的JSONL格式。
  2. 人類反饋(E2):SciQ資料集經過人類控制和更新,可以視為可靠的人類反饋模擬。
  3. 微調(T2):使用GPT-4o-mini模型進行微調。
  4. 提示工程(G3)和生成輸出(G4):根據OpenAI的建議設計提示並展示輸出結果。
  5. 指標(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金鑰。主要步驟包括:

  1. 從掛載的Google Drive中讀取API金鑰檔案。
  2. 安裝openai套件並設定環境變數。
  3. 安裝jsonlinesdatasets套件,用於處理JSONL格式資料和資料集下載。

準備微調資料集

微調OpenAI模型需要仔細準備資料集,否則微調作業可能會失敗。以下是準備資料集的步驟:

  1. 下載資料集:從Hugging Face下載SciQ資料集。
  2. 處理資料集欄位:將資料集轉換為適合微調的格式。
  3. 將資料集串流至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進行微調。主要步驟包括:

  1. 將資料集的每個樣本轉換為包含promptcompletion的JSON物件。
  2. 使用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模型,以應答科學問題。接下來的章節將進一步探討如何評估和最佳化微調後的模型。

  1. 擴充套件資料集:使用更多樣化的科學問題資料集進行微調,以提高模型的泛化能力。
  2. 超引數調優:調整微調任務的超引數,如訓練輪數、批次大小和學習率,以最佳化模型效能。
  3. 模型評估:設計全面的評估指標和方法,以評估微調後模型的效能和準確性。

圖表翻譯:

此圖示顯示了微調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引數控制了輸出的隨機性。我們將系統訊息和使用者提示傳遞給模型,以取得相應的回應。最後,我們提取並格式化模型的回應文字,使其更易於閱讀。