大模型(LLM)训练微调综述学习

news2024/11/24 5:48:18

总览

  • 介绍大模型训练的微调方法,包括prompt tuning、prefix tuning、LoRA、p-tuning和AdaLoRA等。
  • 介绍使用deepspeed和LoRA进行大模型训练的相关代码。
  • 给出petals的介绍,它可以将模型划分为多个块,每个用户的机器负责其中一块,分摊了计算压力。

prompt tuning

在这里插入图片描述
固定预训练参数,为每一个任务额外添加一个或多个embedding,之后拼接query正常输入LLM,并只训练这些embedding。左图为单任务全参数微调,右图为prompt tuning。
在这里插入图片描述

  • 标准的T5模型(橙色线)多任务微调实现了强大的性能,但需要为每个任务存储单独的模型副本。
  • prompt tuning也会随着参数量增大而效果变好,同时使得单个冻结模型可重复使用于所有任务。
  • 显著优于使用GPT-3进行fewshot prompt设计。
  • 当参数达到100亿规模与全参数微调方式效果无异。
from peft import PromptTuningConfig, get_peft_model
peft_config = PromptTuningConfig(task_type="SEQ_CLS", num_virtual_tokens=10)
model = AutoModelForCausalLM.from_pretrained(model_name_or_path, return_dict=True)
model = get_peft_model(model, peft_config)

prefix tuning

在这里插入图片描述
prefix tuning依然是固定预训练参数,但除为每一个任务额外添加一个或多个embedding之外,利用多层感知编码prefix,注意多层感知机就是prefix的编码器,不再像prompt tuning继续输入LLM。

embedding = torch.nn.Embedding(num_virtual_tokens, token_dim)
transform = torch.nn.Sequential(
    torch.nn.Linear(token_dim, encoder_hidden_size),
    torch.nn.Tanh(),
    torch.nn.Linear(encoder_hidden_size, num_layers * 2 * token_dim),
)

在三个数据集中prefix和全参数微调的表现对比:
在这里插入图片描述

peft_config = PrefixTuningConfig(task_type="CAUSAL_LM", num_virtual_tokens=20)
model = AutoModelForCausalLM.from_pretrained(model_name_or_path, return_dict=True)
model = get_peft_model(model, peft_config)

LoRA

在这里插入图片描述
LoRA冻结了预训练模型的参数,并在每一层decoder中加入dropout+Linear+Conv1d额外的参数

那么,LoRA是否能达到全参数微调的性能呢?

根据实验可知,全参数微调要比LoRA方式好的多,但在低资源的情况下也不失为一种选择
在这里插入图片描述
细致到每个任务中的差距如下图:
在这里插入图片描述

peft_config = LoraConfig(task_type="SEQ_CLS", inference_mode=False, r=8, lora_alpha=16, lora_dropout=0.1)
model = AutoModelForCausalLM.from_pretrained(model_name_or_path, return_dict=True)
model = get_peft_model(model, peft_config)

p-tuning

在这里插入图片描述
手动尝试最优的提示无异于大海捞针,于是便有了自动离散提示搜索的方法(左图),但提示是离散的,神经网络是连续的,所以寻找的最优提示可能是次优的。p-tuning依然是固定LLM参数,利用多层感知机和LSTM对prompt进行编码,编码之后与其他向量进行拼接之后正常输入LLM。注意,训练之后只保留prompt编码之后的向量即可,无需保留编码器。

self.lstm_head = torch.nn.LSTM(
                    input_size=self.input_size,
                    hidden_size=self.hidden_size,
                    num_layers=num_layers,
                    dropout=lstm_dropout,
                    bidirectional=True,
                    batch_first=True,
  )

self.mlp_head = torch.nn.Sequential(
    torch.nn.Linear(self.hidden_size * 2, self.hidden_size * 2),
    torch.nn.ReLU(),
    torch.nn.Linear(self.hidden_size * 2, self.output_size),
)
self.mlp_head(self.lstm_head(input_embeds)[0])

以上代码可清晰展示出prompt编码器的结构。
在这里插入图片描述
如上图所示,GPT在P-tuning的加持下可达到甚至超过BERT在NLU领域的性能。下图是细致的对比:
在这里插入图片描述
MP: Manual prompt

FT: Fine-tuning

MP+FT: Manual prompt augmented fine-tuning

PT: P-tuning

peft_config = PromptEncoderConfig(task_type="CAUSAL_LM", num_virtual_tokens=20, encoder_hidden_size=128)
model = AutoModelForCausalLM.from_pretrained(model_name_or_path, return_dict=True)
model = get_peft_model(model, peft_config)

p-tuning v2

在这里插入图片描述
p-tuning的问题是在小参数量模型上表现差(如上图所示),于是有了V2版本,类似于LoRA每层都嵌入了新的参数(称之为Deep FT),下图中开源看到p-tuning v2 集合了多种微调方法。p-tuning v2 在多种任务上下进行微调,之后对于不同的任务如token classification与sentence classification添加了随机初始化的任务头(AutoModelForTokenClassification、AutoModelForSequenceClassification),而非使用自然语言的方式,可以说V2是集大成者。
在这里插入图片描述
KP: Knowledge Probe,知识探针,用于检测LLM的世界知识掌握能力:https://github.com/facebookresearch/LAMA

SeqTag: Sequence Tagging,如抽取式问答、命名实体识别

Re-param.:Reparameterization,对提示词做单独的编码器

No verb.: No verbalizer,不直接使用LLM head而接一个随机初始化的linear head

以下表格对比了[CLS] label linear head 和 verbalizer with LM head,[CLS] label linear head的方式药略好。
在这里插入图片描述
v1到v2的可视化:蓝色部分为参数冻结,橙色部分为可训练部分
在这里插入图片描述
下图中对比了FT、PT、PT-2三种方法,粗体为性能最好的,下划线为性能次好的。
在这里插入图片描述

peft_config = PrefixTuningConfig(task_type="SEQ_CLS", num_virtual_tokens=20)
model = AutoModelForSequenceClassification.from_pretrained(model_name_or_path, return_dict=True)
model = get_peft_model(model, peft_config)

AdaLoRA

预训练语言模型中的不同权重参数对下游任务的贡献是不同的。因此需要更加智能地分配参数预算,以便在微调过程中更加高效地更新那些对模型性能贡献较大的参数。

具体来说,通过奇异值分解将权重矩阵分解为增量矩阵,并根据新的重要性度量动态地调整每个增量矩阵中奇异值的大小。这样可以使得在微调过程中只更新那些对模型性能贡献较大或必要的参数,从而提高了模型性能和参数效率。

详细的算法如下:
在这里插入图片描述
对比不同方法的性能:
在这里插入图片描述

peft_config = AdaLoraConfig(peft_type="ADALORA", task_type="SEQ_2_SEQ_LM", r=8, lora_alpha=32, target_modules=["q", "v"],lora_dropout=0.01)
model = AutoModelForCausalLM.from_pretrained(model_name_or_path, return_dict=True)
model = get_peft_model(model, peft_config)

Code related

注:以下代码在pytorch 1.12.1版本下运行,其他包都是最新版本

deepspeed

官方的demo所需要的配置如下:
在这里插入图片描述
注意到官方给的样例单卡V100只能训练13亿规模的模型,如果换成67亿是否能跑起来呢?

按照官方文档搭建环境:

pip install deepspeed>=0.9.0

git clone https://github.com/microsoft/DeepSpeedExamples.git
cd DeepSpeedExamples/applications/DeepSpeed-Chat/
pip install -r requirements.txt

请注意如果你之前装了deepspeed,请更新至0.9.0

试试全参数微调,这毫无疑问OOM

deepspeed --num_gpus 1 main.py \
      --data_path Dahoas/rm-static \
      --data_split 2,4,4 \
      --model_name_or_path facebook/opt-6.5b \
       --gradient_accumulation_steps 2 \
     --lora_dim 128 \
     --zero_stage 0 \
       --deepspeed \
      --output_dir $OUTPUT \
      &> $OUTPUT/training.log

答案是:我们需要卸载,这次便能愉快的run起来了

deepspeed main.py \
   --data_path Dahoas/rm-static \
   --data_split 2,4,4 \
   --model_name_or_path facebook/opt-6.7b \
   --per_device_train_batch_size 4 \
   --per_device_eval_batch_size 4 \
   --max_seq_len 512 \
   --learning_rate 9.65e-6 \
   --weight_decay 0.1 \
   --num_train_epochs 2  \
   --gradient_accumulation_steps 1 \
   --lr_scheduler_type cosine \
   --num_warmup_steps 0 \
   --seed 1234 \
   --lora_dim 128 \
   --gradient_checkpointing \
   --zero_stage 3 \
   --deepspeed \
   --output_dir $OUTPUT_PATH \
   &> $OUTPUT_PATH/training.log

可以加上LoRA

deepspeed --num_gpus 1 main.py \
   --data_path Dahoas/rm-static \
   --data_split 2,4,4 \
   --model_name_or_path facebook/opt-6.7b \
   --per_device_train_batch_size 8 \
   --per_device_eval_batch_size 8 \
   --max_seq_len 512 \
   --learning_rate 1e-3 \
   --weight_decay 0.1 \
   --num_train_epochs 2 \
   --gradient_accumulation_steps 16 \
   --lr_scheduler_type cosine \
   --num_warmup_steps 0 \
   --seed 1234 \
   --gradient_checkpointing \
   --zero_stage 0 \
   --lora_dim 128 \
   --lora_module_name decoder.layers. \
   --deepspeed \
   --output_dir $OUTPUT_PATH \
   &> $OUTPUT_PATH/training.log

peft

#以下代码省略了数据处理
初始化
from datasets import load_dataset,load_from_disk
import transformers
from transformers import AutoModelForCausalLM, AutoTokenizer,default_data_collator
from peft import prepare_model_for_int8_training, LoraConfig, get_peft_model

MICRO_BATCH_SIZE = 1  
BATCH_SIZE = 1
GRADIENT_ACCUMULATION_STEPS = BATCH_SIZE // MICRO_BATCH_SIZE
EPOCHS = 3  
LEARNING_RATE = 3e-6  
CUTOFF_LEN = 256  
LORA_R = 16
LORA_ALPHA = 32
LORA_DROPOUT = 0.05

模型加载,并使用int8进行训练

model_path = "facebook/opt-6.7b"
output_dir = "model"
model = AutoModelForCausalLM.from_pretrained(model_path)
tokenizer = AutoTokenizer.from_pretrained(model_path, add_eos_token=True)
model = prepare_model_for_int8_training(model)  
config = LoraConfig(
    r=LORA_R,
    lora_alpha=LORA_ALPHA,
    target_modules=None,
    lora_dropout=LORA_DROPOUT,
    bias="none",
    task_type="CAUSAL_LM",
)
model = get_peft_model(model, config)
tokenizer.pad_token_id = 0  
data = load_from_disk("data")

训练与保存

trainer = transformers.Trainer(
    model=model,
    train_dataset=data["train"],
    eval_dataset=data["validation"],
    args=transformers.TrainingArguments(
        per_device_train_batch_size=MICRO_BATCH_SIZE,
        per_device_eval_batch_size=MICRO_BATCH_SIZE,
        gradient_accumulation_steps=GRADIENT_ACCUMULATION_STEPS,
        warmup_steps=1000,
        num_train_epochs=EPOCHS,
        learning_rate=LEARNING_RATE,
        # bf16=True,  
        fp16=True,  
        logging_steps=1,
        output_dir=output_dir,
        save_total_limit=4,
    ),
    data_collator=default_data_collator,
)
model.config.use_cache = False
trainer.train(resume_from_checkpoint=False)
model.save_pretrained(output_dir)

直接这么启动当然会OOM,依然需要卸载

编写accelerate配置文件accelerate.yaml

compute_environment: LOCAL_MACHINE
deepspeed_config:
  gradient_accumulation_steps: 1
  gradient_clipping: 1.0
  offload_optimizer_device: none
  offload_param_device: none
  zero3_init_flag: true
  zero3_save_16bit_model: true
  zero_stage: 3
distributed_type: DEEPSPEED
downcast_bf16: 'yes'
dynamo_backend: 'yes'
fsdp_config: {}
machine_rank: 0
main_training_function: main
megatron_lm_config: {}
mixed_precision: fp16
num_machines: 1
num_processes: 2
rdzv_backend: static
same_network: true
use_cpu: true

deepspeed配置文件:ds.json

{
    "fp16": {
        "enabled": true,
        "loss_scale": 0,
        "loss_scale_window": 500,
        "initial_scale_power": 16,
        "hysteresis": 2,
        "min_loss_scale": 1
    },

    "optimizer": {
        "type": "AdamW",
        "params": {
            "lr": "auto",
            "betas": "auto",
            "eps": 1e-8,
            "weight_decay": "auto"
        }
    },

    "scheduler": {
        "type": "WarmupLR",
        "params": {
            "warmup_min_lr": 0,
            "warmup_max_lr": 2e-05,
            "warmup_num_steps": 0
        }
    },

    "zero_optimization": {
        "stage": 2,
        "offload_optimizer": {
            "device": "cpu",
            "pin_memory": false
        },
        "allgather_partitions": true,
        "allgather_bucket_size": 2e8,
        "overlap_comm": true,
        "reduce_scatter": true,
        "reduce_bucket_size": 2e8,
        "contiguous_gradients": true
    },

    "gradient_accumulation_steps":2,
    "gradient_clipping": "auto",
    "steps_per_print": 2000,
    "train_batch_size": 4,
    "train_micro_batch_size_per_gpu": 1,
    "wall_clock_breakdown": false
}

启动

accelerate launch --dynamo_backend=nvfuser  --config_file accelearte.yaml finetune.py

注:其他方法与Lora使用方法差距不大,不再赘述,在peft项目中均有代码样例。
顺便提一嘴:petals
在这里插入图片描述
petals将模型划分为多个块,每个用户的机器负责其中一块,分摊了计算压力,类似于某磁力链接下载工具,利用hivemind库进行去中心化的训练与推理。当然你也可以创建自己局域网的群组,对自己独有的模型进行分块等自定义操作。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PS学习记录-PPI与DPI

先说两者的重点: dpi是印刷图像时候用的,ppi是设计图像时候用的dpi:【点/英寸】 是印刷计量单位,是每英寸上所印刷的【墨点数】,打印图片一般300dpi左右,代表打印的解析度。ppi:【像素/英寸】是…

快速精通Git

一、 版本控制工具 1.1. 什么是版本控制系统? 版本控制系统(Version Control System):是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。版本控制系统不仅可以应用于软件源代码的文本文件,而且…

温度调制式差示扫描量热法(MTDSC)中的正弦波温度控制技术

摘要:在调制温度式差式扫描量热仪(MTDSC)中,关键技术之一是正弦波加热温度的实现,此技术是制约目前国内无法生产MTDSC量热仪的重要障碍,这主要是因为现有的PID温控技术根本无法实现不同幅值和频率正弦波这样…

uie-base使用记录(paddlenlp)

参考文章:https://aistudio.baidu.com/aistudio/modelsdetail?modelId22 参考文章:https://paddlenlp.readthedocs.io/zh/latest/FAQ.html 参考文章:https://developer.aliyun.com/article/1066857 参考文章:https://github.com/…

【计算机基本原理-数据结构】八大数据结构分类

【计算机基本原理-数据结构】八大数据结构分类 1)数组2)链表3)队列4)栈5)树6)图7)堆8)散列表(哈希表) 数据结构是计算机存储、组织数据的方式。一种好的数据结构可以带来更高的运行或…

Java基础(十三)系统相关类

1. 系统相关类 1.1 java.lang.System类 System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包。 由于该类的构造器是private的,所以无法创建该类的对象。其内部的成员变量和成员方法都是static的,所以也可…

Netty(一)深入Hotspot源码与Linux内核理解NIO与Epoll

深入Hotspot源码与Linux内核理解NIO与Epoll 前言介绍Netty 的介绍Netty 的应用场景理解阻塞和同步关键字初始BIO、NIO、AIOBIO(Blocking IO)缺点:应用场景: NIO(Non Blocking IO)应用场景:NIO非阻塞代码示例存在的问题 NIO 有三大核心组件&am…

Mybatis学习基础篇(一)——使用Maven快速搭建一个mybatis项目,并实现简单的增删改查

题外话: 在了解mybatis框架之前,我先说明一句,目前主流的框架技术层出不穷,每个人都有自己喜欢的技术框架,自己喜欢用就行。技术并没有高低之分,喜欢用就用,虽然目前大部分人都喜欢向新技术看齐…

flex布局下两端对齐,不满左对齐

文章目录 解决方案一 (利用父级的 :after 占位)解决方案二(利用:last-child和:nth-child()占位)解决方案三(补位添加节点法,这种方案适用于多种排列方式) 问题情境: 在flex布局下,多行排列,如何让flex布局最后一行没有排满时&…

如何构建适合自己的DevOps软件测试改进方案

根据2022年的DevOps全球调查报告显示,主流软件企业采用或部分采用DevOps且已获得良好成效的占比已达70%,DevOps俨然成为当下软件开发研究的重要方向。 测试作为软件开发的必要过程,是提升软件可靠性、保证软件质量的关键环节。然而&#xff…

上海亚商投顾:沪指失守3300点 传媒、游戏板块逆市大涨

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 市场情绪 三大指数今日继续调整,沪指午后跌超1%,失守3300点整数关口,创业板指一度跌逾2%…

基于PWM技术的三相光伏逆变器研究(Simulink)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

【手把手做ROS2机器人系统开发二】熟悉ROS2基本命令

【手把手做ROS2机器人系统开发二】熟悉ROS2基本命令 一、上讲回顾 在上一讲开发环境搭建中,我们讲解了如何搭建Ubuntu系统环境和ROS2开发运行环境。 1.Ubuntu系统安装 2.ROS2系统环境安装 二、ROS2核心命令讲解 1、daemon-各种守护进程相关的子命令 查看帮助&am…

[网络原理] 详解Cookie与Session

做好准备,迎接所有的成功吧 文章目录 1. Cookie的概念2. Session的概念3. Cookie与Session的关联与区别3.1 关联3.2 区别 4. Cookie与Session中的核心方法 1. Cookie的概念 Cookie是用户首次登陆网站成功之后,对应页面的服务器会返回给用户一个身份标识,被保存在用户主机的硬盘…

无人机视频与GIS融合三维实景怎么实现?

无人机视频与GIS融合三维实景怎么实现?无人机三维GIS作为一项新兴的测绘重要手段,具有续航时间长、成本低、机动灵活等优点,为城市的规划建设带来极大便利。 那么此项技术有什么样的特点呢?下面智汇云舟就带大家一起来了解一下。 三维是将采集以及经运…

leetcode 1416. Restore The Array(恢复数组)

一台打印机没有把空格打印出来,以至于不知道打印出的 s 中到底有哪些数字。 现在知道数字的取值范围在1 ~ k, 数字开头不能是0. 返回可能的数字个数。取模1097. 思路: DP 假设dp[ i ]为 i ~ n位的s 所能组成的数字组合数。 从右到左遍历,…

【云原生进阶之容器】第六章容器网络6.7.1--阿里云Terway网络模式综述

《云原生进阶之容器》专题索引: 第一章Docker核心技术1.1节——Docker综述第一章Docker核心技术1.2节——Linux容器LXC第一章Docker核心技术1.3节——命名空间Namespace第一章Docker核心技术1.4节——chroot技术第一章Docker核心技术1.5.1节——cgroup综述

如何在在一个账户内管理多个WhatsApp号

许多企业拥有多个WhatsApp Business账户。这可能是因为他们在多个地点都有商店,或者可能在全球范围内都有客户,并希望用当地语言迎合他们每个人。 无论出于何种原因,管理多个WhatsApp企业帐户既耗时又困难。但是,如果我们说有一种…

LoadRunner参数化最佳实践:让你的性能测试更加出色!

距离上次使用loadrunnr 已经有一年多的时间了。初做测试时在项目中用过,后面项目中用不到,自己把重点放在了工具之外的东西上,认为性能测试不仅仅是会用工具,最近又想有一把好的利器毕竟可以帮助自己更好的完成性能测试工作。这算…

【AI实战】微小目标检测模型MMDet-RFLA--训练环境从零开始搭建

【AI实战】微小目标检测模型MMDet-RFLA--训练环境搭建 RFLA介绍环境搭建安装依赖参考 RFLA介绍 官方连接 https://github.com/Chasel-Tsui/mmdet-rflaarxiv https://arxiv.org/abs/2208.08738 环境搭建 我的机器的cuda是10.2,根据自己的cuda版本到 https://hub.do…