【AI大模型应用开发】【Fine-Tuning】0. 从一个例子开始学习大模型Fine-Tuning

简介: 【AI大模型应用开发】【Fine-Tuning】0. 从一个例子开始学习大模型Fine-Tuning
  • 大家好,我是同学小张,日常分享AI知识和实战案例
  • 欢迎 点赞 + 关注 👏,持续学习持续干货输出
  • 一起交流💬,一起进步💪。
  • 微信公众号也可搜【同学小张】 🙏

本站文章一览:


Fine-Tuning,即微调。我尝试用我的理解叙述微调的含义:在原有模型的基础上,通过补充一些数据,用这些补充的数据对原有模型进行训练,训练的过程对原有模型的部分参数进行调整,从而使模型能在某些特定的场景下表现更优。

所以,大模型微调可以提高其在特定场景下的表现,同时,会降低大模型在通用场景下的能力。

今天,我们从一个简单的例子入手,先来感受下Fine-Tune微调到底是什么。这个例子可以在笔记本电脑上跑,需要的配置不高。在开始本文的实践案例前,你可以对模型训练一窍不通,本文将带你跑通整个过程,同时解释其中一些概念。

0. 环境准备

使用模型训练利器 huggingface 来进行模型训练和微调。执行以下代码进行安装:

# pip安装
pip install transformers # 安装最新的版本
# conda安装
conda install -c huggingface transformers  # 只4.0以后的版本

huggingface简介:

  • 相当于面向 NLP 模型的 Github
  • 尤其基于 transformer 的开源模型非常全
  • 封装了模型、数据集、训练器等,使模型的下载、使用、训练都非常方便

1. 加载训练数据集

这里可以直接使用datasets库中的load_dataset函数进行在线加载,只需要指定HuggingFace中的数据集名称即可。

本文以 rotten_tomatoes 数据集为例。

这是一个对电影评论进行情感分类的数据集。

  • 输入:电影评论
  • 输出:[‘负面’,‘正面’]

save_to_disk函数用来将加载的数据集保存到本地的一个目录下。

将加载到的数据集分成 train 部分和 validation 部分。

import datasets
from datasets import load_dataset
# 数据集名称
DATASET_NAME = "rotten_tomatoes" 
# 加载数据集
raw_datasets = load_dataset(DATASET_NAME)
raw_datasets.save_to_disk(os.path.join("D:\\GitHub\\LEARN_LLM\\FineTune\\FineTune1\\data", DATASET_NAME))
# 训练集
raw_train_dataset = raw_datasets["train"]
# 验证集
raw_valid_dataset = raw_datasets["validation"]

2. 加载模型

这里直接使用transformers库中AutoModelForCausalLM的from_pretrained函数,填入预训练的模型名称,然后它就会在运行过程中自动在线加载该模型。本文使用 gpt2 模型。

from transformers import AutoModelForCausalLM
# 模型名称
MODEL_NAME = "gpt2" 
# 加载模型 
model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True)

3. 加载 Tokenizer

通过HuggingFace,可以指定模型名称,运行时自动下载对应Tokenizer。直接使用transformers库中AutoTokenizer的from_pretrained函数,填入对应的模型名称。

from transformers import AutoTokenizer, AutoModel
# 加载tokenizer
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
tokenizer.add_special_tokens({'pad_token': '[PAD]'})
tokenizer.pad_token_id = 0

4. 处理训练数据集

使用datasets库中的map函数进行数据处理。map函数参数如下:

map(
    function: Optional[Callable] = None,
    with_indices: bool = False,
    with_rank: bool = False,
    input_columns: Optional[Union[str, List[str]]] = None,
    batched: bool = False,
    batch_size: Optional[int] = 1000,
    drop_last_batch: bool = False,
    remove_columns: Optional[Union[str, List[str]]] = None,
    keep_in_memory: bool = False,
    load_from_cache_file: bool = True,
    cache_file_names: Optional[Dict[str, Optional[str]]] = None,
    writer_batch_size: Optional[int] = 1000,
    features: Optional[Features] = None,
    disable_nullable: bool = False,
    fn_kwargs: Optional[dict] = None,
    num_proc: Optional[int] = None,
    desc: Optional[str] = None,
)
  • 该函数通过一个映射函数function,处理Dataset中的每一个元素。如果不指定function,则默认的函数为lambda x: x。
  • 参数batched表示是否进行批处理
  • 参数batch_size表示批处理的大小,也就是每次处理多少个元素,默认为1000。
  • 参数drop_last_batch表示当最后一批的数量小于batch_size,是否处理最后一批。
  • remove_columns表示要删除的列的名称,删除列是在数据处理结束后删除,不影响function的使用

数据处理过程代码:

# 标签集
named_labels = ['neg','pos']
# 标签转 token_id
label_ids = [
    tokenizer(named_labels[i],add_special_tokens=False)["input_ids"][0] 
    for i in range(len(named_labels))
]
MAX_LEN=32   #最大序列长度(输入+输出)
DATA_BODY_KEY = "text" # 数据集中的输入字段名
DATA_LABEL_KEY = "label" #数据集中输出字段名
# 定义数据处理函数,把原始数据转成input_ids, attention_mask, labels
def process_fn(examples):
    model_inputs = {
            "input_ids": [],
            "attention_mask": [],
            "labels": [],
        }
    for i in range(len(examples[DATA_BODY_KEY])):
        inputs = tokenizer(examples[DATA_BODY_KEY][i],add_special_tokens=False)
        label = label_ids[examples[DATA_LABEL_KEY][i]]
        input_ids = inputs["input_ids"] + [tokenizer.eos_token_id, label]
        
        raw_len = len(input_ids)
        input_len = len(inputs["input_ids"]) + 1
        if raw_len >= MAX_LEN:
            input_ids = input_ids[-MAX_LEN:]
            attention_mask = [1] * MAX_LEN
            labels = [-100]*(MAX_LEN - 1) + [label]
        else:
            input_ids = input_ids + [0] * (MAX_LEN - raw_len)
            attention_mask = [1] * raw_len + [tokenizer.pad_token_id] * (MAX_LEN - raw_len)
            labels = [-100]*input_len + [label] + [-100] * (MAX_LEN - raw_len)
        model_inputs["input_ids"].append(input_ids)
        model_inputs["attention_mask"].append(attention_mask)
        model_inputs["labels"].append(labels)
    return model_inputs
# 处理训练数据集
tokenized_train_dataset = raw_train_dataset.map(
    process_fn,
    batched=True,
    remove_columns=raw_train_dataset.column_names,
    desc="Running tokenizer on train dataset",
)
# 处理验证数据集
tokenized_valid_dataset = raw_valid_dataset.map(
    process_fn,
    batched=True,
    remove_columns=raw_valid_dataset.column_names,
    desc="Running tokenizer on validation dataset",
)

5. 定义数据规整器

训练时自动将数据拆分成 Batch

# 定义数据校准器(自动生成batch)
collater = DataCollatorWithPadding(
    tokenizer=tokenizer, return_tensors="pt",
)

6. 定义训练超参

LR=2e-5         # 学习率
BATCH_SIZE=8    # Batch大小
INTERVAL=100    # 每多少步打一次 log / 做一次 eval
# 定义训练参数
training_args = TrainingArguments(
    output_dir="./output",              # checkpoint保存路径
    evaluation_strategy="steps",        # 每N步做一次eval
    overwrite_output_dir=True,
    num_train_epochs=1,                 # 训练epoch数
    per_device_train_batch_size=BATCH_SIZE,     # 每张卡的batch大小
    gradient_accumulation_steps=1,              # 累加几个step做一次参数更新
    per_device_eval_batch_size=BATCH_SIZE,      # evaluation batch size
    logging_steps=INTERVAL,             # 每INTERVAL步log 一次
    save_steps=INTERVAL,                # 每INTERVAL步保存一个checkpoint
    learning_rate=LR,                   # 学习率
)
  • 学习率:是指导我们该如何通过损失函数的梯度调整网络权重的超参数,通过设置学习率控制参数更新的速度。以下公式,在更新参数 w 时,其中 α 就是学习率。

  • Batch Size:是指在训练时,一次提供给模型的数据的数量。在训练时,模型需要对整个训练数据集进行训练,但是数据集通常很大,如果一次把整个数据集提供给模型训练,可能导致内存不足或运算时间太长。因此,我们通常将数据集分成若干个Batch,每次提供一个Batch给模型训练。Batch Size就是指一个Batch中数据的数量。
  • 训练epoch数:在训练模型时,通常会设定训练的epoch数,这意味着模型会在训练数据集上训练多少遍。训练epoch数较多意味着模型会更加充分地学习训练数据集,但同时也会增加训练时间。
  • 检查点(CheckPoints):是指通过周期性(迭代/时间)的保存模型的完整状态,在模型训练失败时,可以从保存的检查点模型继续训练,以避免训练失败时每次都需要从头开始带来的训练时间浪费。检查点模式适用于模型训练时间长、训练需要提前结束、fine-tune等场景,也可以拓展到异常时的断点续训场景。

7. 定义训练器

# 节省显存
model.gradient_checkpointing_enable()
# 定义训练器
trainer = Trainer(
    model=model, # 待训练模型
    args=training_args, # 训练参数
    data_collator=collater, # 数据校准器
    train_dataset=tokenized_train_dataset,  # 训练集
    eval_dataset=tokenized_valid_dataset,   # 验证集
    # compute_metrics=compute_metric,         # 计算自定义评估指标
)

8. 开始训练

# 开始训练
trainer.train()

全部的依赖包如下:

import datasets
from datasets import load_dataset
from transformers import AutoTokenizer, AutoModel
from transformers import AutoModelForCausalLM
from transformers import TrainingArguments, Seq2SeqTrainingArguments
from transformers import Trainer, Seq2SeqTrainer
import transformers
from transformers import DataCollatorWithPadding
from transformers import TextGenerationPipeline
import torch
import numpy as np
import os, re
from tqdm import tqdm
import torch.nn as nn

运行成功后的样子如下,会显示当前训练进度、预计耗时等:

训练完之后:

9. 总结

本文以Hugging face上的情感分类数据集和gpt2模型为例,展示了训练过程。同时针对Hugging face训练模型的一些接口和一些概念做了简要介绍,零基础也可以跑通该例子。

总结模型训练的过程:

(1)加载数据集

(2)数据预处理

  • 将输入输出按特定格式拼接
  • 文本转 Token IDs
  • 通过 labels 标识出哪部分是输出(只有输出的 token 参与 loss 计算)

(3)加载模型

(4)加载模型的Tokenizer

(5)定义数据规整器

(6)定义训练超参:学习率、批次大小、…

(7)定义训练器

(8)开始训练

通过这个流程,你就能跑通模型训练过程。

如果觉得本文对你有帮助,麻烦点个赞和关注呗 ~~~


  • 大家好,我是同学小张,日常分享AI知识和实战案例
  • 欢迎 点赞 + 关注 👏,持续学习持续干货输出
  • 一起交流💬,一起进步💪。
  • 微信公众号也可搜【同学小张】 🙏

本站文章一览:

相关文章
|
3天前
|
机器学习/深度学习 人工智能 自然语言处理
当前AI大模型在软件开发中的创新应用与挑战
2024年,AI大模型在软件开发领域的应用正重塑传统流程,从自动化编码、智能协作到代码审查和测试,显著提升了开发效率和代码质量。然而,技术挑战、伦理安全及模型可解释性等问题仍需解决。未来,AI将继续推动软件开发向更高效、智能化方向发展。
|
4天前
|
人工智能 自然语言处理 机器人
文档智能与RAG技术如何提升AI大模型的业务理解能力
随着人工智能的发展,AI大模型在自然语言处理中的应用日益广泛。文档智能和检索增强生成(RAG)技术的兴起,为模型更好地理解和适应特定业务场景提供了新方案。文档智能通过自动化提取和分析非结构化文档中的信息,提高工作效率和准确性。RAG结合检索机制和生成模型,利用外部知识库提高生成内容的相关性和准确性。两者的结合进一步增强了AI大模型的业务理解能力,助力企业数字化转型。
34 3
|
7天前
|
人工智能 弹性计算 Serverless
触手可及,函数计算玩转 AI 大模型 | 简单几步,轻松实现AI绘图
本文介绍了零售业中“人—货—场”三要素的变化,指出传统营销方式已难以吸引消费者。现代消费者更注重个性化体验,因此需要提供超出预期的内容。文章还介绍了阿里云基于函数计算的AI大模型,特别是Stable Diffusion WebUI,帮助非专业人士轻松制作高质量的促销海报。通过详细的部署步骤和实践经验,展示了该方案在实际生产环境中的应用价值。
38 6
触手可及,函数计算玩转 AI 大模型 | 简单几步,轻松实现AI绘图
|
3天前
|
人工智能 新制造 芯片
2024年中国AI大模型产业发展报告解读
2024年,中国AI大模型产业迎来蓬勃发展,成为科技和经济增长的新引擎。本文解读《2024年中国AI大模型产业发展报告》,探讨产业发展背景、现状、挑战与未来趋势。技术进步显著,应用广泛,但算力瓶颈、资源消耗和训练数据不足仍是主要挑战。未来,云侧与端侧模型分化、通用与专用模型并存、大模型开源和芯片技术升级将是主要发展方向。
|
4天前
|
存储 人工智能 固态存储
如何应对生成式AI和大模型应用带来的存储挑战
如何应对生成式AI和大模型应用带来的存储挑战
|
7天前
|
机器学习/深度学习 人工智能 自然语言处理
AI在医疗领域的应用及其挑战
【10月更文挑战第34天】本文将探讨人工智能(AI)在医疗领域的应用及其面临的挑战。我们将从AI技术的基本概念入手,然后详细介绍其在医疗领域的各种应用,如疾病诊断、药物研发、患者护理等。最后,我们将讨论AI在医疗领域面临的主要挑战,包括数据隐私、算法偏见、法规合规等问题。
26 1
|
10天前
|
存储 XML 人工智能
深度解读AI在数字档案馆中的创新应用:高效识别与智能档案管理
基于OCR技术的纸质档案电子化方案,通过先进的AI能力平台,实现手写、打印、复古文档等多格式高效识别与智能归档。该方案大幅提升了档案管理效率,确保数据安全与隐私,为档案馆提供全面、智能化的电子化管理解决方案。
100 48
|
5天前
|
机器学习/深度学习 人工智能 算法
AI在医疗领域的应用与挑战
本文探讨了人工智能(AI)在医疗领域的应用,包括其在疾病诊断、治疗方案制定、患者管理等方面的优势和潜力。同时,也分析了AI在医疗领域面临的挑战,如数据隐私、伦理问题以及技术局限性等。通过对这些内容的深入分析,旨在为读者提供一个全面了解AI在医疗领域现状和未来发展的视角。
28 10
|
6天前
|
机器学习/深度学习 人工智能 监控
探索AI在医疗领域的应用与挑战
本文深入探讨了人工智能(AI)在医疗领域中的应用现状和面临的挑战。通过分析AI技术如何助力疾病诊断、治疗方案优化、患者管理等方面的创新实践,揭示了AI技术为医疗行业带来的变革潜力。同时,文章也指出了数据隐私、算法透明度、跨学科合作等关键问题,并对未来的发展趋势进行了展望。
|
9天前
|
机器学习/深度学习 人工智能 自然语言处理
当前AI大模型在软件开发中的创新应用与挑战
【10月更文挑战第31天】2024年,AI大模型在软件开发领域的应用取得了显著进展,从自动化代码生成、智能代码审查到智能化测试,极大地提升了开发效率和代码质量。然而,技术挑战、伦理与安全问题以及模型可解释性仍是亟待解决的关键问题。开发者需不断学习和适应,以充分利用AI的优势。