大模型进阶微调篇(三):微调GPT2大模型实战

简介: 本文详细介绍了如何在普通个人电脑上微调GPT2大模型,包括环境配置、代码实现和技术要点。通过合理设置训练参数和优化代码,即使在无独显的设备上也能完成微调,耗时约14小时。文章还涵盖了GPT-2的简介、数据集处理、自定义进度条回调等内容,适合初学者参考。

在之前的两篇文章:基于人类反馈的强化学习RLHF原理、优点介绍 以定制化3B模型为例,各种微调方法对比-选LoRA还是PPO 介绍了一下微调相关的知识

在本文中,我带大家在一般设备上微调GPT2大模型(例如无GPU的ECS或者个人电脑) - qwen2.5-0.5B也可以,但时长需要80个小时左右对于集显太慢了。尽管大模型的训练通常需要强大的计算资源,但借助合理的配置和代码优化,可以在普通的个人电脑上对GPT2进行微调。
本次微调是在一台i5-9500 3GHz CPU,32GB内存,无独立显卡的计算资源上进行,训练时长大约为14个小时。本文将从环境配置、代码拆解、以及技术要点等方面进行详尽介绍。

GPT-2 简介

GPT-2 是由 OpenAI 开发的生成式预训练 Transformer(GPT)模型,是 GPT 系列模型的第二代版本。GPT-2 采用了 12 层 Transformer 编码器,拥有 1.5 亿参数。该模型基于大量文本数据进行无监督训练,具备了生成高质量自然语言的能力。GPT-2 适合多种下游任务,包括文本生成、对话系统和文本分类等。

环境配置与依赖安装

首先,需要安装以下主要依赖项(python3.8,建议用miniconda):

  • torch:用于深度学习模型的训练与推理。
  • transformers:用于加载 GPT-2 模型和处理相关任务。
  • datasets:用于加载和处理数据集。
  • tqdm:用于显示进度条。

通过以下命令来安装这些依赖:

pip install torch transformers datasets

代码拆解与说明

下面是完整的微调代码,将逐步对其进行拆解和说明。

1. 加载 GPT-2 模型和分词器

from transformers import GPT2Tokenizer, GPT2LMHeadModel

model_name = "openai-community/gpt2"
model = GPT2LMHeadModel.from_pretrained(model_name)
tokenizer = GPT2Tokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token

首先,使用 GPT2LMHeadModel 加载 GPT-2 预训练模型,并使用 GPT2Tokenizer 加载对应的分词器。这里将 pad_token 设置为 eos_token,以便模型在处理填充时不会引入额外的混淆。

2. 加载数据集

from datasets import load_dataset

dataset = load_dataset("wikitext", "wikitext-2-raw-v1", split="train")

使用 datasets 库加载 Wikitext-2 数据集。这个数据集包含了丰富的自然语言文本,非常适合用于语言模型的微调。

3. 数据集分词

def tokenize_function(examples):
    tokens = tokenizer(examples["text"], padding="max_length", truncation=True, max_length=128)
    tokens["labels"] = tokens["input_ids"].copy() #这个地儿是为了兼容,不然会报错无labels呢
    return tokens

tokenized_datasets = dataset.map(tokenize_function, batched=True, remove_columns=["text"])

为了适应 GPT-2 的输入,定义了 tokenize_function 对数据集进行分词,并将 input_ids 复制为 labels,使得模型在训练时可以通过对比输入和标签进行自回归学习。

4. 设置训练参数

from transformers import TrainingArguments

training_args = TrainingArguments(
    output_dir="./gpt2-finetuned",
    overwrite_output_dir=True,
    num_train_epochs=3,
    per_device_train_batch_size=8,
    warmup_steps=500,
    weight_decay=0.01,
    logging_dir="./logs",
    logging_steps=50,
    save_steps=1000,
    save_total_limit=2,
    eval_strategy="steps",
    report_to="none"
)

这里定义了模型训练的参数。主要的参数有:

  • output_dir:模型和检查点保存的目录。
  • overwrite_output_dir:是否覆盖已有的输出目录。
  • num_train_epochs:训练轮数,设置为3,表示模型将在整个数据集上迭代3次。
  • per_device_train_batch_size:每个设备上的训练批次大小为8,这会影响显存的占用和训练速度。
  • warmup_steps:学习率预热的步数,设置为500,用于在训练初期逐步提高学习率,避免模型收敛过快。
  • weight_decay:权重衰减系数,用于防止过拟合,设置为0.01。
  • logging_dir:日志保存的目录,用于保存 TensorBoard 等日志信息。
  • logging_steps:每50步记录一次日志,方便跟踪训练的进度和损失变化。
  • save_steps:每1000步保存一次模型,用于断点续训或选择最佳的训练结果。
  • save_total_limit:保存模型的最大数量,超过此数量后会自动删除旧的模型检查点,保持存储空间。
  • eval_strategy:设置为在训练过程中按步评估模型,以便及时了解模型的性能。
  • report_to:设置为 "none",表示不将训练日志报告给外部工具,如 TensorBoard。

5. 自定义进度条回调

为了更好地监控训练过程,定义了一个自定义进度条回调 ProgressCallback,使用 tqdm 显示训练进度:

from transformers import Trainer, TrainerCallback
from tqdm import tqdm

class ProgressCallback(TrainerCallback):
    def __init__(self, total_steps):
        self.progress_bar = tqdm(total=total_steps, desc="Training Progress")

    def on_step_end(self, args, state, control, **kwargs):
        self.progress_bar.update(1)

    def on_train_end(self, args, state, control, **kwargs):
        self.progress_bar.close()

6. 创建 Trainer

total_steps = len(tokenized_datasets) // training_args.per_device_train_batch_size * training_args.num_train_epochs

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets,
    tokenizer=tokenizer,
    callbacks=[ProgressCallback(total_steps)]
)

使用 Trainer 类来管理训练过程,并添加自定义的进度条回调,以便可以实时查看训练进度。

7. 开始微调

trainer.train()

启动微调过程,Trainer 会自动处理训练循环,包括数据加载、前向传播、反向传播和梯度更新等。

8. 保存模型和评估

model.save_pretrained("./gpt2-finetuned")
tokenizer.save_pretrained("./gpt2-finetuned")

# 评估模型
eval_results = trainer.evaluate()
print(f"Perplexity: {torch.exp(torch.tensor(eval_results['eval_loss']))}")

训练完成后,将模型和分词器保存到指定目录。随后,通过 trainer.evaluate() 对模型进行评估,并计算困惑度(Perplexity),以评估模型生成文本的质量。

微调相关技术要点

  1. 微调原理:GPT-2 的微调基于预训练权重,使用下游任务数据继续训练,使模型在特定领域上具有更好的表现。
  2. 自回归训练:GPT-2 使用自回归的方式,即通过预测下一个词的方式学习文本的生成。
  3. 训练资源:由于 GPT-2 模型参数较多,训练过程通常较为耗时。在个人电脑上进行微调时,建议尽量使用较小的数据集,并适当减少训练轮数和批次大小。

总结

通过本文的实战演示,我成功地在一台普通的个人电脑上对 GPT-2 进行了微调。虽然设备性能有限,但借助优化的训练参数和合理的代码结构,依然能够完成大模型的微调任务。希望这篇文章能帮助你更好地理解和实践大模型的微调技术,让 AI 模型训练变得更加触手可及。

相关实践学习
使用PAI+LLaMA Factory微调Qwen2-VL模型,搭建文旅领域知识问答机器人
使用PAI和LLaMA Factory框架,基于全参方法微调 Qwen2-VL模型,使其能够进行文旅领域知识问答,同时通过人工测试验证了微调的效果。
机器学习概览及常见算法
机器学习(Machine Learning, ML)是人工智能的核心,专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能,它是使计算机具有智能的根本途径,其应用遍及人工智能的各个领域。 本课程将带你入门机器学习,掌握机器学习的概念和常用的算法。
相关文章
|
4月前
|
存储 机器学习/深度学习 人工智能
大模型微调技术:LoRA原理与实践
本文深入解析大语言模型微调中的关键技术——低秩自适应(LoRA)。通过分析全参数微调的计算瓶颈,详细阐述LoRA的数学原理、实现机制和优势特点。文章包含完整的PyTorch实现代码、性能对比实验以及实际应用场景,为开发者提供高效微调大模型的实践指南。
2568 2
|
6月前
|
XML JSON 数据库
大模型不听话?试试提示词微调
想象一下,你向大型语言模型抛出问题,满心期待精准回答,得到的却是答非所问,是不是让人抓狂?在复杂分类场景下,这种“大模型不听话”的情况更是常见。
374 9
|
5月前
|
人工智能 自然语言处理 API
快速集成GPT-4o:下一代多模态AI实战指南
快速集成GPT-4o:下一代多模态AI实战指南
481 101
|
6月前
|
物联网
直播预告 | Qwen-lmage 技术分享+实战攻略直播
通义千问团队最新开源的图像生成模型 Qwen-Image,凭借其出色的中文理解与文本渲染能力,自发布以来获得了广泛关注与好评。
289 0
|
6月前
智谱发布GLM-4.5V,全球开源多模态推理新标杆,Day0推理微调实战教程到!
视觉语言大模型(VLM)已经成为智能系统的关键基石。随着真实世界的智能任务越来越复杂,VLM模型也亟需在基本的多模态感知之外,逐渐增强复杂任务中的推理能力,提升自身的准确性、全面性和智能化程度,使得复杂问题解决、长上下文理解、多模态智能体等智能任务成为可能。
925 0
|
5月前
|
人工智能 自然语言处理 测试技术
有没有可能不微调也能让大模型准确完成指定任务?(少样本学习)
对于我这种正在从0到1构建AI产品的一人公司来说,Few Shots学习的最大价值在于:用最少的资源获得最大的效果。我不需要大量的标注数据,不需要复杂的模型训练,只需要精心设计几个示例,就能让大模型快速理解我的业务场景。
412 43
|
4月前
|
存储 监控 算法
1688 图片搜索逆向实战:CLIP 多模态融合与特征向量落地方案
本文分享基于CLIP模型与逆向工程实现1688图片搜同款的实战方案。通过抓包分析破解接口签名,结合CLIP多模态特征提取与Faiss向量检索,提升搜索准确率至91%,单次响应低于80ms,日均选品效率提升4倍,全程合规可复现。
|
5月前
|
机器学习/深度学习 算法 数据可视化
从零开始训练推理模型:GRPO+Unsloth改造Qwen实战指南
推理型大语言模型兴起,通过先思考再作答提升性能。本文介绍GRPO等强化学习算法,详解其原理并动手用Qwen2.5-3B训练推理模型,展示训练前后效果对比,揭示思维链生成的实现路径。
744 2
从零开始训练推理模型:GRPO+Unsloth改造Qwen实战指南