LLM 微调实战指南:Pythia 模型 Fine Tuning 全流程解析
引言
大语言模型(LLM)的微调(Fine Tuning)是将通用预训练模型适配特定领域任务的关键技术。本文将详细介绍微调的核心步骤,并通过 Python 代码示例展示如何使用 Hugging Face Transformers 库完成从数据准备到模型评估的全过程。
微调核心步骤
- 准备训练数据集:收集高质量、与场景相关的文本或对话数据,格式通常为 JSON/JSONL/TXT。
- 选择基础模型:根据任务需求选择预训练模型,如 Pythia、Llama 等。
- 设置训练超参数:包括学习率、Batch Size、Epochs 等,直接影响收敛效果。
- 加载模型与数据:使用 Transformers 库加载模型权重及分词器,处理数据集。
- 执行微调训练:配置 Trainer 对象启动训练循环。
- 保存与评估:保存最佳检查点,并在测试集上验证性能提升。
代码实现详解
1. 导入依赖库
import os
import datasets
import tempfile
import logging
import random
import yaml
import time
import torch
import transformers
import pandas as pd
import jsonlines
from transformers import AutoTokenizer, AutoModelForCausalLM, TrainingArguments, Trainer
2. 加载数据集
dataset_name = "lamini_docs.jsonl"
dataset_path = f"/content/{dataset_name}"
use_hf = True
# 假设使用 Hugging Face Datasets 加载
dataset_path = "lamini/lamini_docs"
3. 配置模型与分词器
model_name = "EleutherAI/pythia-70m"
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token
# 模拟数据分词与划分函数
def tokenize_and_split_data(config, tokenizer):
# 此处应包含实际的数据加载、分词逻辑
# 返回 train_dataset, test_dataset
pass
train_dataset, test_dataset = tokenize_and_split_data({}, tokenizer)
4. 加载基础模型
base_model = AutoModelForCausalLM.from_pretrained(model_name)
device_count = torch.cuda.device_count()
device = torch.device("cuda" if device_count > 0 else "cpu")
base_model.to(device)
5. 定义推理函数
def inference(text, model, tokenizer, max_input_tokens=1000, max_output_tokens=100):
inputs = tokenizer(text, return_tensors="pt", truncation=True, max_length=max_input_tokens).to(device)
outputs = model.generate(**inputs, max_new_tokens=max_output_tokens)
return tokenizer.decode(outputs[0], skip_special_tokens=True)
6. 设置训练参数
max_steps = 3
output_dir = f"lamini_docs_{max_steps}_steps"
training_args = TrainingArguments(
output_dir=output_dir,
learning_rate=1.0e-5,
num_train_epochs=1,
max_steps=max_steps,
per_device_train_batch_size=1,
overwrite_output_dir=False,
disable_tqdm=False,
eval_steps=120,
save_steps=120,
warmup_steps=1,
per_device_eval_batch_size=1,
evaluation_strategy="steps",
logging_strategy="steps",
logging_steps=1,
optim="adafactor",
gradient_accumulation_steps=4,
gradient_checkpointing=False,
load_best_model_at_end=True,
save_total_limit=1,
metric_for_best_model="eval_loss",
greater_is_better=False
)
7. 初始化 Trainer 并训练
trainer = Trainer(
model=base_model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=test_dataset,
)
training_output = trainer.train()
8. 保存与推理对比
save_dir = f'{output_dir}/final'
trainer.save_model(save_dir)
finetuned_model = AutoModelForCausalLM.from_pretrained(save_dir, local_files_only=True)
finetuned_model.to(device)
# 推理示例
test_question = test_dataset[0]['question']
print("Question:", test_question)
print("Finetuned Answer:", inference(test_question, finetuned_model, tokenizer))
关键参数说明
- learning_rate: 控制学习速度,1e-5 适合微调以防灾难性遗忘。
- max_steps: 覆盖 Epochs,精确控制训练步数。
- gradient_accumulation_steps: 模拟大 Batch Size,节省显存。
- load_best_model_at_end: 自动保留验证集表现最好的模型。
数据预处理最佳实践
在正式训练前,建议对数据进行清洗和格式化:
- 去重:移除重复样本以避免过拟合。
- 标准化:统一文本编码和特殊字符处理。
- 指令对齐:对于对话模型,确保输入输出符合指令格式(如
Instruction,Input,Output)。
评估指标与部署
训练完成后,需关注以下指标:
- Loss 曲线:观察训练集与验证集 Loss 是否收敛且无发散。
- Perplexity (PPL):衡量模型预测不确定性的常用指标。
- 业务指标:根据具体任务(如问答准确率、生成流畅度)进行人工或自动化评估。
部署时,可考虑量化(Quantization)以减少显存占用,或使用 ONNX Runtime 加速推理。
总结
通过上述步骤,我们完成了对 Pythia 模型的基础微调。在实际生产中,建议结合 LoRA 等高效微调技术以降低成本,并持续监控验证集 Loss 以防止过拟合。掌握微调流程有助于开发者灵活定制大模型能力,满足垂直领域需求。

