本節代碼是一個完整的機器學習工作流程,用于訓練一個基于GPT-2的語言模型。下面是對這段代碼的詳細解釋:
文件目錄如下
1. 初始化和數據準備
-
設置隨機種子
random.seed(1002)
確保結果的可重復性。
-
定義參數
test_rate = 0.2 context_length = 128
-
test_rate
:測試集占總數據集的比例。 -
context_length
:模型處理的文本長度。
-
-
獲取數據文件
all_files = glob(pathname=os.path.join("data","*"))
使用
glob
獲取data
目錄下的所有文件。 -
劃分數據集
test_file_list = random.sample(all_files, int(len(all_files) * test_rate)) train_file_list = [i for i in all_files if i not in test_file_list]
將數據集隨機劃分為訓練集和測試集。
-
加載數據集
raw_datasets = load_dataset("csv", data_files={"train": train_file_list, "vaild": test_file_list}, cache_dir="cache_data")
使用
datasets
庫加載 CSV 格式的數據集,并緩存到cache_data
目錄。
2. 數據預處理
-
初始化分詞器
tokenizer = BertTokenizerFast.from_pretrained("D:/bert-base-chinese") tokenizer.add_special_tokens({"bos_token":"[begin]","eos_token":"[end]"})
從本地路徑加載預訓練的 BERT 分詞器,并添加自定義的開始和結束標記。
-
數據預處理
tokenize_datasets = raw_datasets.map(tokenize, batched=True, remove_columns=raw_datasets["train"].column_names)
使用
map
方法對數據集進行預處理,將文本轉換為模型可接受的格式。-
tokenize
函數對文本進行分詞和截斷。 -
batched=True
表示批量處理數據。 -
remove_columns
刪除原始數據集中的列。
-
3. 模型配置和初始化
-
模型配置
config = GPT2Config.from_pretrained("config",vocab_size=len(tokenizer),n_ctx=context_length,bos_token_id=tokenizer.bos_token_id,eos_token_id=tokenizer.eos_token_id,)
加載預訓練的 GPT-2 配置,并根據分詞器的詞匯表大小和上下文長度進行調整。
-
初始化模型
model = GPT2LMHeadModel(config) model_size = sum([t.numel() for t in model.parameters()]) print(f"model_size: {model_size/1000/1000} M")
根據配置初始化 GPT-2 語言模型,并計算模型參數的總數,打印模型大小(以兆字節為單位)。
4. 訓練設置
-
數據整理器
data_collator = DataCollatorForLanguageModeling(tokenizer, mlm=False)
使用
DataCollatorForLanguageModeling
整理訓練數據,設置mlm=False
表示不使用掩碼語言模型。 -
訓練參數
args = TrainingArguments(learning_rate=1e-5,num_train_epochs=100,per_device_train_batch_size=10,per_device_eval_batch_size=10,eval_steps=2000,logging_steps=2000,gradient_accumulation_steps=5,weight_decay=0.1,warmup_steps=1000,lr_scheduler_type="cosine",save_steps=100,output_dir="model_output",fp16=True, )
配置訓練參數,包括學習率、訓練輪數、批大小、評估間隔等。
-
初始化訓練器
trianer = Trainer(model=model,args=args,tokenizer=tokenizer,data_collator=data_collator,train_dataset=tokenize_datasets["train"],eval_dataset=tokenize_datasets["vaild"] )
-
啟動訓練
trianer.train()
使用
Trainer
類啟動模型訓練。
需復現完整代碼
from glob import glob
import os
from torch.utils.data import Dataset
from datasets import load_dataset
import random
from transformers import BertTokenizerFast
from transformers import GPT2Config
from transformers import GPT2LMHeadModel
from transformers import DataCollatorForLanguageModeling
from transformers import Trainer,TrainingArgumentsdef tokenize(element):outputs = tokenizer(element["content"],truncation=True,max_length=context_length,return_overflowing_tokens=True,return_length=True)input_batch = []for length,input_ids in zip(outputs["length"],outputs["input_ids"]):if length == context_length:input_batch.append(input_ids)return {"input_ids":input_batch}if __name__ == "__main__":random.seed(1002)test_rate = 0.2context_length = 128all_files = glob(pathname=os.path.join("data","*"))test_file_list = random.sample(all_files,int(len(all_files)*test_rate))train_file_list = [i for i in all_files if i not in test_file_list]raw_datasets = load_dataset("csv",data_files={"train":train_file_list,"vaild":test_file_list},cache_dir="cache_data")tokenizer = BertTokenizerFast.from_pretrained("D:/bert-base-chinese")tokenizer.add_special_tokens({"bos_token":"[begin]","eos_token":"[end]"})tokenize_datasets = raw_datasets.map(tokenize,batched=True,remove_columns=raw_datasets["train"].column_names)config = GPT2Config.from_pretrained("config",vocab_size=len(tokenizer),n_ctx=context_length,bos_token_id = tokenizer.bos_token_id,eos_token_id = tokenizer.eos_token_id,)model = GPT2LMHeadModel(config)model_size = sum([ t.numel() for t in model.parameters()])print(f"model_size: {model_size/1000/1000} M")data_collator = DataCollatorForLanguageModeling(tokenizer,mlm=False)args = TrainingArguments(learning_rate=1e-5,num_train_epochs=100,per_device_train_batch_size=10,per_device_eval_batch_size=10,eval_steps=2000,logging_steps=2000,gradient_accumulation_steps=5,weight_decay=0.1,warmup_steps=1000,lr_scheduler_type="cosine",save_steps=100,output_dir="model_output",fp16=True,)trianer = Trainer(model=model,args=args,tokenizer=tokenizer,data_collator=data_collator,train_dataset=tokenize_datasets["train"],eval_dataset=tokenize_datasets["vaild"])trianer.train()