【LLM教程-llama】如何Fine Tuning大语言模型?

今天给大家带来了一篇超级详细的教程,手把手教你如何对大语言模型进行微调(Fine Tuning)!(代码和详细解释放在后文)

目录

大语言模型进行微调(Fine Tuning)需要哪些步骤?

大语言模型进行微调(Fine Tuning)训练过程及代码


大语言模型进行微调(Fine Tuning)需要哪些步骤?

大语言模型进行微调(Fine Tuning)的主要步骤🤩

  1. 📚 准备训练数据集
    首先你需要准备一个高质量的训练数据集,最好是与你的应用场景相关的数据。可以是文本数据、对话数据等,格式一般为JSON/TXT等。

  2. 📦 选择合适的基础模型
    接下来需要选择一个合适的基础预训练模型,作为微调的起点。常见的有GPT、BERT、T5等大模型,可根据任务场景进行选择。

  3. ⚙️ 设置训练超参数
    然后是设置训练的各种超参数,比如学习率、批量大小、训练步数等等。选择合理的超参数对模型效果影响很大哦。

  4. 🧑‍💻 加载模型和数据集
    使用HuggingFace等库,把选定的基础模型和训练数据集加载进来。记得对数据集进行必要的前处理和划分。

  5. ⚡ 开始模型微调训练
    有了模型、数据集和超参数后,就可以开始模型微调训练了!可以使用PyTorch/TensorFlow等框架进行训练。

  6. 💾 保存微调后的模型
    训练结束后,别忘了把微调好的模型保存下来,方便后续加载使用哦。

  7. 🧪 在测试集上评估模型
    最后在准备好的测试集上评估一下微调后模型的效果。看看与之前的基础模型相比,是否有明显提升?

大语言模型进行微调(Fine Tuning)训练过程及代码

那如何使用 Lamini 库加载数据、设置模型和训练超参数、定义推理函数、微调基础模型、评估模型效果呢?

  • 首先,导入必要的库
import os
import lamini
import datasets
import tempfile
import logging
import random
import config
import os
import yaml
import time
import torch
import transformers
import pandas as pd
import jsonlines

from utilities import *
from transformers import AutoTokenizer
from transformers import AutoModelForCausalLM
from transformers import TrainingArguments
from transformers import AutoModelForCausalLM
from llama import BasicModelRunner

这部分导入了一些必需的Python库,包括Lamini、Hugging Face的Datasets、Transformers等。

  • 加载Lamini文档数据集
dataset_name = "lamini_docs.jsonl"
dataset_path = f"/content/{dataset_name}"
use_hf = False
dataset_path = "lamini/lamini_docs"
use_hf = True

这里指定了数据集的路径,同时设置了use_hf标志,表示是否使用Hugging Face的Datasets库加载数据。

  • 设置模型、训练配置和分词器
model_name = "EleutherAI/pythia-70m"
training_config = { ... }
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token
train_dataset, test_dataset = tokenize_and_split_data(training_config, tokenizer)

这部分指定了基础预训练模型的名称,并设置了训练配置(如最大长度等)。然后,它使用AutoTokenizer从预训练模型中加载分词器,并对分词器进行了一些调整。最后,它调用tokenize_and_split_data函数对数据进行分词和划分训练/测试集。

  • 加载基础模型
base_model = AutoModelForCausalLM.from_pretrained(model_name)
device_count = torch.cuda.device_count()
if device_count > 0:
    device = torch.device("cuda")
else:
    device = torch.device("cpu")
base_model.to(device)

这里使用AutoModelForCausalLM从预训练模型中加载基础模型,并根据设备(GPU或CPU)将模型移动到相应的设备上。

  • 定义推理函数
def inference(text, model, tokenizer, max_input_tokens=1000, max_output_tokens=100):
    ...

这个函数用于在给定输入文本的情况下,使用模型和分词器进行推理并生成输出。它包括对输入文本进行分词、使用模型生成输出以及解码输出等步骤。

  • 尝试使用基础模型进行推理
test_text = test_dataset[0]['question']
print("Question input (test):", test_text)
print(f"Correct answer from Lamini docs: {test_dataset[0]['answer']}")
print("Model's answer: ")
print(inference(test_text, base_model, tokenizer))

这部分使用上一步定义的inference函数,在测试数据集的第一个示例上尝试使用基础模型进行推理。它打印了输入问题、正确答案和模型的输出。

  • 设置训练参数
max_steps = 3
trained_model_name = f"lamini_docs_{max_steps}_steps"
output_dir = trained_model_name
training_args = TrainingArguments(

  # Learning rate
  learning_rate=1.0e-5,

  # Number of training epochs
  num_train_epochs=1,

  # Max steps to train for (each step is a batch of data)
  # Overrides num_train_epochs, if not -1
  max_steps=max_steps,

  # Batch size for training
  per_device_train_batch_size=1,

  # Directory to save model checkpoints
  output_dir=output_dir,

  # Other arguments
  overwrite_output_dir=False, # Overwrite the content of the output directory
  disable_tqdm=False, # Disable progress bars
  eval_steps=120, # Number of update steps between two evaluations
  save_steps=120, # After # steps model is saved
  warmup_steps=1, # Number of warmup steps for learning rate scheduler
  per_device_eval_batch_size=1, # Batch size for evaluation
  evaluation_strategy="steps",
  logging_strategy="steps",
  logging_steps=1,
  optim="adafactor",
  gradient_accumulation_steps = 4,
  gradient_checkpointing=False,

  # Parameters for early stopping
  load_best_model_at_end=True,
  save_total_limit=1,
  metric_for_best_model="eval_loss",
  greater_is_better=False
)

这一部分设置了训练的一些参数,包括最大训练步数、输出模型目录、学习率等超参数。

为什么要这样设置这些训练超参数:

  1. learning_rate=1.0e-5
    学习率控制了模型在每个训练步骤中从训练数据中学习的速度。1e-5是一个相对较小的学习率,可以有助于稳定训练过程,防止出现divergence(发散)的情况。

  2. num_train_epochs=1
    训练的轮数,即让数据在模型上循环多少次。这里设置为1,是因为我们只想进行轻微的微调,避免过度训练(overfitting)。

  3. max_steps=max_steps
    最大训练步数,会覆盖num_train_epochs。这样可以更好地控制训练的总步数。

  4. per_device_train_batch_size=1
    每个设备(GPU/CPU)上的训练批量大小。批量大小越大,内存占用越高,但训练过程可能更加稳定。

  5. output_dir=output_dir
    用于保存训练过程中的检查点(checkpoints)和最终模型的目录。

  6. overwrite_output_dir=False
    如果目录已存在,是否覆盖它。设为False可以避免意外覆盖之前的结果。

  7. eval_steps=120, save_steps=120
    每120步评估一次模型性能,并保存模型。频繁保存可以在训练中断时恢复。

  8. warmup_steps=1
    学习率warmup步数,一开始使用较小的学习率有助于稳定训练早期阶段。

  9. per_device_eval_batch_size=1
    评估时每个设备上的批量大小。通常与训练时相同。

  10. evaluation_strategy="steps", logging_strategy="steps"
    以步数为间隔进行评估和记录日志,而不是以epoch为间隔。

  11. optim="adafactor"
    使用Adafactor优化器,适用于大规模语言模型训练。

  12. gradient_accumulation_steps=4
    梯度积累步数,可以模拟使用更大批量大小的效果,节省内存。

  13. load_best_model_at_end=True
    保存验证集上性能最好的那个检查点,作为最终模型。

  14. metric_for_best_model="eval_loss", greater_is_better=False
    根据验证损失评估模型,损失越小越好。

model_flops = (
  base_model.floating_point_ops(
    {
       "input_ids": torch.zeros(
           (1, training_config["model"]["max_length"])
      )
    }
  )
  * training_args.gradient_accumulation_steps
)

print(base_model)
print("Memory footprint", base_model.get_memory_footprint() / 1e9, "GB")
print("Flops", model_flops / 1e9, "GFLOPs")


print(base_model)
print("Memory footprint", base_model.get_memory_footprint() / 1e9, "GB")
print("Flops", model_flops / 1e9, "GFLOPs")

这里还计算并打印了模型的内存占用和计算复杂度(FLOPs)。

最后,使用这些参数创建了一个Trainer对象,用于实际进行模型训练。

trainer = Trainer(
    model=base_model,
    model_flops=model_flops,
    total_steps=max_steps,
    args=training_args,
    train_dataset=train_dataset,
    eval_dataset=test_dataset,
)
  • 训练模型几个步骤
training_output = trainer.train()

这一行代码启动了模型的微调训练过程,并将训练输出存储在training_output中。

  • 保存微调后的模型
save_dir = f'{output_dir}/final'
trainer.save_model(save_dir)
print("Saved model to:", save_dir)
finetuned_slightly_model = AutoModelForCausalLM.from_pretrained(save_dir, local_files_only=True)
finetuned_slightly_model.to(device)

这部分将微调后的模型保存到指定的目录中。

然后,它使用AutoModelForCausalLM.from_pretrained从保存的模型中重新加载该模型,并将其移动到相应的设备上。

  • 使用微调后的模型进行推理
test_question = test_dataset[0]['question']
print("Question input (test):", test_question)
print("Finetuned slightly model's answer: ")
print(inference(test_question, finetuned_slightly_model, tokenizer))
test_answer = test_dataset[0]['answer']
print("Target answer output (test):", test_answer)

这里使用之前定义的inference函数,在测试数据集的第一个示例上尝试使用微调后的模型进行推理。

打印了输入问题、模型输出以及正确答案。

  • 加载并运行其他预训练模型
finetuned_longer_model = AutoModelForCausalLM.from_pretrained("lamini/lamini_docs_finetuned")
tokenizer = AutoTokenizer.from_pretrained("lamini/lamini_docs_finetuned")
finetuned_longer_model.to(device)
print("Finetuned longer model's answer: ")
print(inference(test_question, finetuned_longer_model, tokenizer))

bigger_finetuned_model = BasicModelRunner(model_name_to_id["bigger_model_name"])
bigger_finetuned_output = bigger_finetuned_model(test_question)
print("Bigger (2.8B) finetuned model (test): ", bigger_finetuned_output)

这部分加载了另一个经过更长时间微调的模型,以及一个更大的2.8B参数的微调模型。它使用这些模型在测试数据集的第一个示例上进行推理,并打印出结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/762558.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Qt:7.QWidget属性介绍(cursor属性-光标形状、font属性-控件文本样式、tooltip属性-控件提示信息)

目录 一、cursor属性-光标形状: 1.1cursor属性介绍: 1.2获取当前光标形状——cursor(): 1.3 设置光标的形状——setCursor(): 1.4 设置自定义图片为光标: 二、font属性-控件文本样式: 2.1font属性介绍…

一句话介绍什么是AI智能体?

什么是AI智能体? 一句话说就是利用各种AI的功能的api组合,完成你想要的结果。 例如你希望完成一个关于主题为啤酒主题的小红书文案图片,那么它就可以完成 前面几个步骤类似automa的组件,最后生成一个结果。

信息学奥赛初赛天天练-41-CSP-J2021基础题-n个数取最大、树的边数、递归、递推、深度优先搜索应用

PDF文档公众号回复关键字:20240701 2021 CSP-J 选择题 单项选择题(共15题,每题2分,共计30分:每题有且仅有一个正确选项) 4.以比较作为基本运算,在N个数中找出最大数,最坏情况下所需要的最少比…

汽车内饰塑料件光照老化实验箱

塑料件光照老化实验箱概述 塑料件光照老化实验箱,又称为氙灯老化试验箱,是一种模拟自然光照条件下塑料材料老化情况的实验设备。它通过内置的氙灯或其他光源,产生接近自然光的紫外线辐射,以此来加速塑料及其他材料的光老化过程。…

进程,线程,虚拟内存,交换技术

参考资料: 参考视频1https://www.bilibili.com/video/BV1Hs421M78w/?spm_id_from333.999.0.0&vd_source97411b9a8288d7869f5363f72b0d7613 参考视频2https://www.bilibili.com/video/BV1jE411W7e8/?spm_id_from333.337.search-card.all.click&vd_source…

【创建者模式-建造者模式】

概要 将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。 建造者模式包含以下角色 抽象建造者类(Builder):这个接口规定要实现复杂对象的那些部分的创建,并不涉及具体的部件对象的创建。具体建…

使用explain优化慢查询的业务场景分析

问:你最害怕的事情是什么?答:搓澡问:为什么?答:因为有些人一旦错过,就不在了 Explain 这个词在不同的上下文中有不同的含义。在数据库查询优化的上下文中,“EXPLAIN” 是一个常用的 …

基于PHP的初中数学题库管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的初中数学题库管理系统 一 介绍 此初中数学题库管理系统基于原生PHP开发,数据库mysql,系统角色分为学生,教师和管理员。(附带参考设计文档) 技术栈:phpmysqlphpstudyvscode 二 功能 …

YOLOv10改进教程|C2f-CIB加入注意力机制

一、 导读 论文链接:https://arxiv.org/abs/2311.11587 代码链接:GitHub - CV-ZhangXin/AKConv YOLOv10训练、验证及推理教程 二、 C2f-CIB加入注意力机制 2.1 复制代码 打开ultralytics->nn->modules->block.py文件,复制SE注意力机…

Android 大话binder通信

戳蓝字“牛晓伟”关注我哦! 用心坚持输出易读、有趣、有深度、高质量、体系化的技术文章 由于 Android 大话binder通信(上) 和 Android 大话binder通信(下) 分为两篇阅读体验不好,顾合并为一篇。 本文摘要 用故事的方式把binder通信的整个过程都描述…

分享一个在 WinForm 桌面程序中使用进度条展示报表处理进度的例子,提升用户体验

前言 在有些比较消耗时间的业务场景中,比如生成报表等,如果没有在操作的过程中向用户反馈操作进度,会让用户以为程序 “死” 掉了,用户体验非常不好。 WinForm 桌面程序项目与 Console 项目不一样,如果 Console 项目…

C++ initializer_list类型推导

目录 initializer_list C自动类型推断 auto typeid decltype initializer_list<T> C支持统一初始化{ }&#xff0c;出现了一个新的类型initializer_list<T>&#xff0c;一切类型都可以用列表初始化。提供了一种更加灵活、安全和明确的方式来初始化对象。 class…

MIT6.s081 2021 Lab Page tables

Speed up system calls 思路 题目要求在每个进程初始化时为它的页表插入一个页表项&#xff0c;内核通过这样预先缓存页表项的操作&#xff0c;来加速特定系统调用的执行速度。 由于前不久刚过完一遍《OSTEP》&#xff0c;因此我认为自己对页表机制还算比较熟悉&#xff0c;…

Open AI Stream Completion Set Variable Inside Function PHP With Openai-php SDK

题意&#xff1a;使用 OpenAI 的 PHP SDK&#xff08;例如 openai-php&#xff09;来在函数内部设置和完成一个流&#xff08;stream&#xff09;相关的变量 问题背景&#xff1a; How to set variable inside this openai-php sdk function in stream completion ? I am usi…

【笔记】手工部署之linux中开放已安装的mysql与tomcat端口

在需要打包的springboot项目中输入mvn clean package 在target下面获得jar包 进入linux中你想要该jar包存在的位置 将jar包上传至linux中 此时在浏览器中输入linux的ip地址&#xff1a;端口号/mapping路径为404 故&#xff1a; 在linux中另开一个标签页 检查mysql和tomcat已…

JavaFX布局-BorderPane

JavaFX布局-BorderPane 实现方式Java实现FXML实现 综合案例 将容器空间分成五个区域&#xff1a;顶部&#xff08;Top&#xff09;、底部&#xff08;Bottom&#xff09;、左侧&#xff08;Left&#xff09;、右侧&#xff08;Right&#xff09;和中心&#xff08;Center&#…

Java案例找素数(三种方法)

目录 一&#xff1a;问题&#xff1a; 二&#xff1a;思路分析&#xff1a; 三&#xff1a;具体代码&#xff1a; 四&#xff1a;运行结果&#xff1a; 一&#xff1a;问题&#xff1a; 二&#xff1a;思路分析&#xff1a; 三&#xff1a;具体代码&#xff1a; Ⅰ&#xf…

03 _ 类型基础(2):动态类型与静态类型

静态类型语言与动态类型语言 通俗定义 静态类型语言&#xff1a;在编译 阶段确定所有变量的类型 动态类型语言&#xff1a;在执行阶段确定所有变量的类型 Javascript 与 C 对比 静态类型与动态类型对比 其他定义 强类型语言&#xff1a;不允许程序在发生错误后继续执行 语…

【STM32】温湿度采集与OLED显示

一、任务要求 1. 学习I2C总线通信协议&#xff0c;使用STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集&#xff0c;并将采集的温度-湿度值通过串口输出。 任务要求&#xff1a; 1&#xff09;解释什么是“软件I2C”和“硬件I2C”&#xff1f;&#xff08;阅读野火配…

视频号视频怎么下载保存到手机,视频号视频如何下载到电脑本地

在数字化浪潮的推动下&#xff0c;视频号成为了我们获取信息、分享生活的重要平台。但有时候&#xff0c;我们遇到一些精彩的内容&#xff0c;想要保存下来以便日后观看&#xff0c;却发现视频号并不提供直接的下载功能。下面我就来为大家详细介绍视频号视频下载的方法&#xf…