本文介紹如何微調 T5 和 Llama-2 模型以進行摘要生成任務。首先使用 Hugging Face 的 datasets 函式庫載入 XSum 資料集,接著使用 transformers 函式庫中的 T5Tokenizer 對資料進行分詞和格式化,並使用 DataCollatorForSeq2Seq 進行資料整理。利用 Seq2SeqTrainer 簡化模型訓練流程,並使用 ROUGE 分數評估模型效能。最後,構建摘要生成管道,展示模型的摘要生成能力。更進一步,示範如何使用量化技術微調 Llama-2-7B-chat 模型,以減少記憶體佔用和提升訓練效率,包含提示格式化、Tokenizer 設定、模型載入和量化引數設定等步驟,提供完整程式碼和技術說明。

模型訓練準備

初始化模型

from transformers import AutoModelForSeq2SeqLM
model = AutoModelForSeq2SeqLM.from_pretrained(model_checkpoint, device_map="auto")

內容解密:

  • 使用 AutoModelForSeq2SeqLM 從 Transformers 函式庫中載入預訓練的序列到序列模型。
  • device_map="auto" 自動選擇適合的運算裝置(CPU 或 GPU)。

設定訓練引數

from transformers import Seq2SeqTrainingArguments
batch_size = 8
num_train_epochs = 8
logging_steps = len(tokenized_datasets["train"]) // batch_size
model_name = model_checkpoint.split("/")[-1]
args = Seq2SeqTrainingArguments(
    output_dir=f"{model_name}-finetuned-xsum",
    evaluation_strategy="epoch",
    learning_rate=5.6e-5,
    per_device_train_batch_size=batch_size,
    per_device_eval_batch_size=batch_size,
    weight_decay=0.01,
    save_total_limit=3,
    num_train_epochs=num_train_epochs,
    predict_with_generate=True,
    logging_steps=logging_steps,
)

內容解密:

  • 設定訓練引數,包括批次大小、訓練輪數、學習率等。
  • evaluation_strategy="epoch" 表示在每個訓練輪數結束後進行評估。

自定義評估指標計算函式

import numpy as np
def calculate_evaluation_metrics(prediction_data):
    predicted, true_labels = prediction_data
    translated_predictions = tokenizer.batch_decode(predicted, skip_special_tokens=True)
    true_labels = np.where(true_labels != -100, true_labels, tokenizer.pad_token_id)
    translated_labels = tokenizer.batch_decode(true_labels, skip_special_tokens=True)
    formatted_predictions = ["\n".join(sent_tokenize(pred_text.strip())) for pred_text in translated_predictions]
    formatted_labels = ["\n".join(sent_tokenize(label_text.strip())) for label_text in translated_labels]
    rouge_results = rouge_score.compute(predictions=formatted_predictions, references=formatted_labels, use_stemmer=True)
    scaled_results = {metric: score * 100 for metric, score in rouge_results.items()}
    return {metric_key: round(score_value, 4) for metric_key, score_value in scaled_results.items()}

內容解密:

  • 該函式用於計算模型的評估指標,主要涉及解碼預測結果和真實標籤,並計算 ROUGE 分數。

初始化資料整理器

from transformers import DataCollatorForSeq2Seq
data_collator = DataCollatorForSeq2Seq(tokenizer, model=model)

內容解密:

  • DataCollatorForSeq2Seq 負責動態填充輸入資料,以確保同一批次內的資料具有相同的長度。

資料預處理

tokenized_datasets = tokenized_datasets.remove_columns(xsum_dataset["train"].column_names)

內容解密:

  • 清理 tokenized 資料集,移除不必要的欄位,以節省記憶體並簡化資料處理流程。

進階技術應用於大語言模型

微調T5模型進行摘要生成

在前面的章節中,我們已經瞭解瞭如何使用預訓練模型進行自然語言處理任務。現在,我們將探討如何微調T5模型以進行摘要生成。

首先,我們需要準備資料集。在這個例子中,我們使用了XSum資料集,這是一個用於訓練和評估摘要生成模型的標準資料集。

from datasets import load_dataset
xsum_dataset = load_dataset("xsum")

內容解密:

這段程式碼的作用是載入XSum資料集。load_dataset函式來自於Hugging Face的Datasets函式庫,它允許我們輕鬆地載入和處理各種自然語言處理資料集。

接下來,我們需要對資料進行預處理,包括分詞和格式化。

from transformers import T5Tokenizer
tokenizer = T5Tokenizer.from_pretrained("t5-small")
def preprocess_data(examples):
    model_inputs = tokenizer(examples["document"], max_length=512, truncation=True)
    with tokenizer.as_target_tokenizer():
        labels = tokenizer(examples["summary"], max_length=128, truncation=True)
    model_inputs["labels"] = labels["input_ids"]
    return model_inputs
tokenized_datasets = xsum_dataset.map(preprocess_data, batched=True)

內容解密:

這段程式碼定義了一個預處理函式preprocess_data,它將原始文字資料轉換為模型可以接受的格式。tokenizer用於將文字分詞並轉換為輸入ID。max_length引數控制了輸入序列的最大長度,超出這個長度的序列將被截斷。labels代表了目標摘要,同樣被分詞和格式化。最後,預處理後的資料被儲存在tokenized_datasets中。

然後,我們需要定義一個資料整理器,用於將預處理後的資料整理成模型訓練所需的格式。

from transformers import DataCollatorForSeq2Seq
data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model="t5-small")
features = [tokenized_datasets["train"][i] for i in range(2)]
data_collator(features)

內容解密:

這段程式碼建立了一個DataCollatorForSeq2Seq例項,用於將預處理後的資料整理成模型訓練所需的格式。features變數包含了從訓練資料集中選取的一些樣本資料,data_collator將這些資料整理成批次。

接下來,我們初始化了一個Seq2SeqTrainer例項,用於進行模型的訓練。

from transformers import Seq2SeqTrainer
trainer = Seq2SeqTrainer(
    model,
    args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["validation"],
    data_collator=data_collator,
    tokenizer=tokenizer,
    compute_metrics=calculate_evaluation_metrics,
)

內容解密:

這段程式碼設定了Seq2SeqTrainer,它是一個用於簡化模型訓練過程的工具。trainer被組態了模型、訓練引數、訓練和評估資料集、資料整理器、分詞器和評估指標計算函式。

最後,我們開始訓練模型。

trainer.train()

內容解密:

這行程式碼啟動了模型的訓練過程。train()方法會根據設定的引數和資料對模型進行訓練。

模型評估

在模型訓練完成後,我們需要對其進行評估,以瞭解其在未見資料上的表現。

trainer.evaluate()

內容解密:

這行程式碼對模型進行評估,使用的是驗證資料集。評估結果提供了模型的表現指標,例如ROUGE分數等。

初始化摘要生成管道

為了使用訓練好的模型進行摘要生成,我們需要初始化一個摘要生成管道。

from transformers import pipeline
model_id = "t5-small-finetuned-xsum/checkpoint-204000/"
summarizer = pipeline("summarization", model=model_id)

內容解密:

這段程式碼建立了一個摘要生成管道,使用的是微調後的T5模型。pipeline函式來自於Hugging Face的Transformers函式庫,它簡化了模型的佈署和使用。

測試摘要生成

最後,我們定義了一個函式,用於列印原始檔案和生成的摘要。

def print_summary(idx):
    document = xsum_dataset["test"][idx]["document"]
    summary = summarizer(xsum_dataset["test"][idx]["document"])[0]["summary_text"]
    print(f"'>>> Document: {document}'")
    print(f"\n'>>> Summary: {summary}'")
print_summary(100)
print_summary(0)

內容解密:

這段程式碼定義了一個函式print_summary,它接受一個索引,列印預出對應的檔案和生成的摘要。我們測試了兩個不同的索引,以展示模型的摘要生成能力。

使用解碼器模型進行抽象摘要生成

接下來,我們將探討如何使用解碼器模型(例如Llama-2-7B-chat)進行抽象摘要生成。同樣地,我們使用了XSum資料集來微調這個模型。

大語言模型的進階技術:Llama-2-chat-7B 微調實作

步驟 1:安裝函式庫與載入資料

本步驟與前一節相同,請參照之前的指示執行以下程式碼:

!pip install -U \
accelerate bitsandbytes datasets \
peft safetensors transformers trl
from datasets import load_dataset
# 載入訓練集中的前 1,000 筆資料
train_dataset = load_dataset("EdinburghNLP/xsum", split='train[:1000]')
train_dataset[0]

與前一節的不同之處在於,我們只使用了資料集的子集,即前 1,000 筆資料,以避免災難性遺忘(catastrophic forgetting),如第六章所述。

內容解密:

上述程式碼安裝了必要的函式庫,並載入了 EdinburghNLP/xsum 資料集的前 1,000 筆訓練資料。輸出的第一筆資料範例如下:

{'document': '...', 'summary': '...', 'id': '35232142'}

這裡的 document 是原始文字,summary 是對應的摘要。

步驟 2:資料前處理

我們將準備資料以微調 Llama-2-chat-7B 模型。首先,定義一個實用函式來格式化提示(prompt),指示大語言模型(LLM)進行摘要任務。

def prompt_formatter(sample):
    return f"""<s>### 指示:
你是一個有幫助、尊重和誠實的助手。\
你的任務是摘要以下對話。\
你的答案應僅根據提供的對話。

### 對話:
{sample['document']}

### 摘要:
{sample['summary']} </s>"""
n = 0
print(prompt_formatter(train_dataset[n]))

內容解密:

prompt_formatter 函式接收一個 sample 引數,格式化一個提示字串,包含特殊標記和指示資訊,以便 LLM 能夠理解任務。該函式傳回一個格式化的字串,包含三個主要部分:

  • 指示:提供明確的指示給 LLM,描述其任務和行為。
  • 對話:包含需要被摘要的文字,即 sample['document']
  • 摘要:指定摘要的位置,使用 sample['summary']

接下來,我們將設定資料集的 tokenizer:

tokenizer = AutoTokenizer.from_pretrained(model_id)
tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "right"

內容解密:

首先,從預訓練模型 model_id 載入 tokenizer。然後,將 pad_token 設定為與 eos_token 相同,表示填充應該被視為句子結尾。最後,指定填充應該新增到序列的右側(結尾),以確保文字輸入的一致處理。

步驟 3:模型訓練

首先,使用量化技術設定預訓練模型 Llama-2-chat-7B 進行訓練:

import torch
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
from peft import prepare_model_for_kbit_training
# model_id = "meta-llama/Llama-2-7b-chat-hf"
model_id = "daryl149/llama-2-7b-chat-hf"
# 以 NF4 量化載入模型,啟用雙重量化,計算資料型別設為 bfloat16
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_use_double_quant=True,
    bnb_4bit_compute_dtype=torch.bfloat16
)

內容解密:

上述程式碼載入了 Llama-2-chat-7B 模型,並使用 BitsAndBytesConfig 設定量化引數。量化技術能夠減少模型的記憶體佔用和計算需求,從而提高訓練效率。

此圖示呈現了模型的量化設定流程:

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title 微調T5與Llama2模型實作摘要生成

package "摘要生成微調" {
    package "資料處理" {
        component [XSum 資料集] as xsum
        component [T5Tokenizer] as tokenizer
        component [DataCollator] as collator
    }

    package "模型架構" {
        component [T5 Seq2Seq] as t5
        component [Llama-2-7B] as llama
        component [量化技術] as quant
    }
}

package "訓練與評估" {
    component [Seq2SeqTrainer] as trainer
    component [ROUGE 分數] as rouge
    component [摘要管道] as pipeline
}

xsum --> tokenizer : 原始文本
tokenizer --> collator : Token IDs
collator --> t5 : 批次資料
collator --> llama : 批次資料
llama --> quant : 記憶體優化
t5 --> trainer : 訓練
trainer --> rouge : 效能評估
rouge --> pipeline : 摘要生成

note right of rouge
  ROUGE 指標:
  - 特徵選擇
  - 特徵轉換
  - 降維處理
end note

note right of eval
  評估指標:
  - 準確率/召回率
  - F1 Score
  - AUC-ROC
end note

@enduml

圖表翻譯: 該圖表展示了使用量化技術訓練 Llama-2-chat-7B 模型的流程。首先載入模型,接著設定量化引數,然後啟用量化,最後開始訓練。

本章節介紹瞭如何使用量化技術微調 Llama-2-chat-7B 模型,包括資料準備、模型設定和訓練流程。透過這些步驟,可以有效地提高模型的效能和效率。