微调llama 3 — PEFT微调和全量微调

这篇具有很好参考价值的文章主要介绍了微调llama 3 — PEFT微调和全量微调。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. llama 3 微调基础

1.1 llama 3 简介

官方blog
llama 3 目前有两个版本:8B版和70B版。8B版本拥有8.03B参数,其尺寸较小,可以在消费者硬件上本地运行。

  • meta-llama/Meta-Llama-3-8B
  • meta-llama/Meta-Llama-3-70B
  • 超过400B个参数的第三个版本目前仍在训练中……

Llama 3与Llama 2具有相同的架构,但词汇表要大得多,包含128k entries,而Llama 2只有32k entries,根据Meta的说法,词汇表的扩展显著提高了模型表现。Llama 3的预训练数据包含5%的高质量非英语数据。注意:Meta在model card中仍然提到Llama 3更适合用于英语任务。

另一方面,词汇表的扩展意味着token embeddings需要更多的数据才能被训练的更准确。Meta在15T tokens上训练Llama 3。相比之下,Llama 2只在2T tokens上训练,Google Gemma在6T tokens训练,这在当时似乎已经很多了。

模型的性能表现如下图所示:
微调llama 3 — PEFT微调和全量微调,llama,人工智能,深度学习

1.2 llama 3 8b Fully Fine-tuning内存占用分析

Fully Fine-tuning an LLM需要更新其所有参数,这种微调需要大量的内存。

  • 模型需要被完全加载到 GPU 内存中
  • 此外,通常用于微调 LLMs 的优化器 AdamW 会为模型中的每个参数创建并存储 2 个参数在 GPU 内存中
  • 并且我们还需要存储在微调过程中创建的张量,即激活值,以便在反向传播过程中用于更新模型参数的梯度。

对Llama 3 8B进行微调,例如,批量大小为8,序列长度为512,将消耗128.87GB的显存。注意:这个内存消耗是一个估计值,没有考虑任何的优化,比如梯度检查点和张量并行。

model loading the model optimizer states activations total
llama 3 8b 14.96GB 59.83GB 54.08GB 128.87GB

(我会在下一篇文章中提供估算大型语言模型(LLM)内存消耗的计算方法)

幸运的是,我们可以很容易地减少这三种参数的内存消耗:

  • Optimizer states:默认情况下,AdamW 的参数为 float32,每项占用 4 字节。AdamW-8bit 是另一种不错的选择,它将参数量化为 8 位,即减少了内存消耗从 59.8 GB 到 15 GB。如果使用的框架不复制模型参数,内存消耗会大大减少。
  • Model:我们可以将模型量化为4位。它将内存消耗分成近4份,即从15 GB到4 GB。在实践中,为了保持其性能,并不是所有的LLM模块都会被量化。
  • Activations:我们需要存储激活来计算梯度。然而,使用gradient checkpointing,我们可以在反向传播过程中动态地重新计算激活值,而不是在整个训练过程中都存储这些激活值。它大大减少了激活的内存消耗,从54GB减少到10 GB。

在应用了所有这些优化措施之后,微调过程需要29GB的内存。虽然这仍然太多,但至少现在可以使用两个24GB的GPU来对模型进行微调了。

1.3 llama 3 8b PEFT Fine-tuning内存占用分析

使用PEFT方法,如LoRA,我们可以在模型顶部微调一个适配器,不需要完全重新训练模型。为了进一步降低内存消耗。

  1. 使用LoRA,需要一个带有24 GB RAM的GPU来微调Llama 3;
  2. 使用QLoRA,只需要一个带有16 GB RAM的GPU。

2. PEFT方法微调llama 3

1、QLoRA 是量化的 LoRA 与 LLMs 的结合。要使用这种方法对 Llama 3 8B 进行微调,我们需要安装

pip install --upgrade bitsandbytes transformers peft accelerate datasets trl

2、然后导入需要的pkgs

import torch, os
from datasets import load_dataset
from peft import LoraConfig, prepare_model_for_kbit_training
from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    BitsAndBytesConfig,
    TrainingArguments,
)
from trl import SFTTrainer

3、如果你拥有较新的GPU,就可以使用bfloat16数据类型以获得更好的训练稳定性,并使用FlashAttention来减少处理长序列时的内存消耗。下面的代码会自动检测GPU是否兼容bfloat16FlashAttention

#use bf16 and FlashAttention if supported
if torch.cuda.is_bf16_supported():
  os.system('pip install flash_attn')
  compute_dtype = torch.bfloat16
  attn_implementation = 'flash_attention_2'
else:
  compute_dtype = torch.float16
  attn_implementation = 'sdpa'

4、然后,我们需要初始化并配置Tokenizer。通常,LLMs在预训练时不包含pad_token。然而,在微调过程中,由于我们的训练示例长度不相同,我们需要将其填充到batch中。我们可以创建并添加一个pad_token到词汇表中,但更简单的选择是将eos_token指定为pad_token。

model_name = "meta-llama/Meta-Llama-3-8B"
#Tokenizer
tokenizer = AutoTokenizer.from_pretrained(model_name, add_eos_token=True, use_fast=True)
tokenizer.pad_token = tokenizer.eos_token
tokenizer.pad_token_id =  tokenizer.eos_token_id
tokenizer.padding_side = 'left'

注意,我们使用的是左边填充。如果想使用flash_attention,右填充是不兼容的。

5、至于微调数据集,可以选择了 timdettmers/openassistant-guanaco,因为这个数据集足够小。

6、然后,我们创建bnb_config并加载模型:

bnb_config = BitsAndBytesConfig(
        load_in_4bit=True,
        bnb_4bit_quant_type="nf4",
        bnb_4bit_compute_dtype=compute_dtype,
        bnb_4bit_use_double_quant=True,
)
model = AutoModelForCausalLM.from_pretrained(
          model_name, quantization_config=bnb_config, device_map={"": 0}, attn_implementation=attn_implementation
)

7、bnb_config定义了在4位精度下加载模型,并对量化常数进行量化(即双重量化)。在前向传递过程中,如果你的GPU支持bfloat16数据类型,则将创建bfloat16张量。请注意:如果你的GPU不支持bfloat16,则笔记本将使用float16。然而,这可能会导致训练不稳定。如果你发现训练损失降至0或NaN,请将compute_dtype更改为torch.float32。

8、为了减少激活的内存消耗,我们还需要启用梯度检查点,这是通过

model = prepare_model_for_kbit_training(model)

9、对于 LoRA 的配置,可以使用:

peft_config = LoraConfig(
        lora_alpha=16,
        lora_dropout=0.05,
        r=16,
        bias="none",
        task_type="CAUSAL_LM",
        target_modules= ['k_proj', 'q_proj', 'v_proj', 'o_proj', "gate_proj", "down_proj", "up_proj"]
)

可以增加rank来获得更好的结果。增加rank也会增加内存消耗,因为rank增大,适配器的参数也会增加。

10、接下来,定义训练参数和超参数:

training_arguments = TrainingArguments(
        output_dir="./Llama3_8b_QLoRA",
        evaluation_strategy="steps",
        do_eval=True,
        optim="paged_adamw_8bit",
        per_device_train_batch_size=8,
        gradient_accumulation_steps=4,
        per_device_eval_batch_size=8,
        log_level="debug",
        save_strategy="epoch",
        logging_steps=100,
        learning_rate=1e-4,
        fp16 = not torch.cuda.is_bf16_supported(),
        bf16 = torch.cuda.is_bf16_supported(),
        eval_steps=100,
        num_train_epochs=3,
        warmup_ratio=0.1,
        lr_scheduler_type="linear",
)

11、使用"paged_adamw_8bit",会在需要时将一些优化器状态存储到CPU RAM中,以进一步减少GPU内存消耗。

补充:QLoRA其实是核心就是在LoRA的技术加上深度的量化过程。核心优化思想包括以下三点:

  • 4bit NoramlFloat Quantization:一种新的数据类型,只用4字节表征参数并且保证整个模型的精度损失极小.(和我们之前的Int8,int4量化方式不同, 原理这篇先不展开了)
  • Double Quantization:对第一次量化后的那些常量再进行一次量化,减少存储空间。
  • Paged optimizers:使用NVIDIA统一内存功能,该功能在CPU和GPU之间进行自动page对page传输,以便在GPU偶尔OOM的情况下进行。可以从现象上理解成出现训练过程中偶发OOM时能够自动处理,保证训练正常训练下去。

对于批量大小,随机选择了一个批量大小为32(每个设备的批量大小为8,梯度累积步骤为4(8x4=32)的配置)。该配置消耗了16.6 GB的GPU内存。如果你只有16 GB的GPU,请将每个设备的批量大小减少到4。

12、最后,开始微调时,运行以下命令:

trainer = SFTTrainer(
        model=model,
        train_dataset=ds['train'],
        eval_dataset=ds['test'],
        peft_config=peft_config,
        dataset_text_field="text",
        max_seq_length=512,
        tokenizer=tokenizer,
        args=training_arguments,
)

trainer.train()

13、使用Google Colab的L4实例完成这3个epoch大约需要10个小时。

3. 将微调后的adapter集成到Llama 3中

为了避免每次使用时都加载adapter,你可以将其合并到 Llama 3 中。当适配器已经使用 QLoRA 进行微调时,必须小心进行合并,以保持adapter的大部分准确性。我们必须遵循以下步骤:

  1. 加载并量化Llama 3
  2. Dequantize Llama 3 to the compute dtype used during QLoRA fine-tuning
  3. Merge the adapter into the dequantized model
  4. Save the resulting model
    最后得到一个没有量化的模型。我们不能像微调那样用bitsandbytes量化它,否则会严重降低模型的性能。使用AWQ或GPTQ来代替即可。

4. 使用AWQ对llama 3进行4位量化

AWQ是一种量化方案,它保留了模型的重要权重。AWQ很准确,也受到高效的推理核的支持。首先需要安装AutoAWQ:

pip install autoawq

然后,用几行代码执行量化,例如,要量化前一节合并后得到的模型:

from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer

tokenizer_path = "meta-llama/Meta-Llama-3-8B"
model_path = './dqz_merge/'
quant_path = 'llama-3-oasstguanaco3e-awq-4bit'
quant_config = { "zero_point": True, "q_group_size": 128, "w_bit": 4, "version": "GEMM" }

# Load model and tokenizer
model = AutoAWQForCausalLM.from_pretrained(model_path, safetensors=True)
tokenizer = AutoTokenizer.from_pretrained(tokenizer_path, use_fast=True)

# Quantize
model.quantize(tokenizer, quant_config=quant_config)

# Save quantized model with safetensors
model.save_quantized("./"+quant_path, safetensors=True)
tokenizer.save_pretrained("./"+quant_path)

这将把量化模型保存到一个名为“llama-3-oasstguanaco3e-awq-4bit”的目录中。

5. 完全微调模型

QLoRA和LoRA只是微调适配器。如果你真的想微调整个模型,你可以尝试GaLore。GaLore将梯度投影到低秩子空间,以显著减少它们的维数,从而减少它们的内存消耗。虽然GaLore大大降低了优化器状态的内存需求,但你仍然需要48GB的GPU RAM。

CODE

具体的notebook代码可以在github仓库中拿到。

notebook中包含了4个部分:文章来源地址https://www.toymoban.com/news/detail-859897.html

  1. QLoRA fine-tuning
  2. Merging the fine-tuned adapter into the base model
  3. Quantization the Llama 3 with AWQ
  4. Appendices: LoRA and GaLore fine-tuning

到了这里,关于微调llama 3 — PEFT微调和全量微调的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Peft库使用技巧(一):合并基座模型与Lora模型【使用Peft库微调基座模型(比如LLaMA-7B)后会得到Lora参数模块,将基座模型与Lora参数合并后才能得到完整的微调后的大模型】

    使用Peft库微调基座模型(比如LLaMA-7B)后会得到Lora参数模块,将基座模型与Lora参数合并后才能得到完整的微调后的大模型

    2024年02月15日
    浏览(52)
  • 探索人工智能:深度学习、人工智能安全和人工智能编程(文末送书)

    人工智能知识对于当今的互联网技术人来说已经是刚需。但人工智能的概念、流派、技术纷繁复杂,选择哪本书入门最适合呢? 这部被誉为人工智能“百科全书”的《人工智能(第3版)》,可以作为每个技术人进入 AI 世界的第一本书。 购书链接,限时特惠5折 这本书是美国

    2024年02月03日
    浏览(119)
  • 人工智能 | Llama大模型:与AI伙伴合二为一,共创趣味交流体验

    Llama 大模型介绍 我们介绍 LLaMA,这是一个基础语言模型的集合,参数范围从 7B 到 65B。我们在数万亿个Token上训练我们的模型,并表明可以专门使用公开可用的数据集来训练最先进的模型,而无需诉诸专有的和无法访问的数据集。特别是,LLaMA-13B 在大多数基准测试中都优于

    2024年02月03日
    浏览(44)
  • 人工智能深度学习

    目录 人工智能 深度学习 机器学习 神经网络 机器学习的范围 模式识别 数据挖掘 统计学习 计算机视觉 语音识别 自然语言处理 机器学习的方法 回归算法 神经网络 SVM(支持向量机) 聚类算法 降维算法 推荐算法 其他 机器学习的分类 机器学习模型的评估 机器学习的应用 机

    2024年02月22日
    浏览(58)
  • 人工智能之深度学习

    第一章 人工智能概述 1.1人工智能的概念和历史 1.2人工智能的发展趋势和挑战 1.3人工智能的伦理和社会问题 第二章 数学基础 1.1线性代数 1.2概率与统计 1.3微积分 第三章 监督学习 1.1无监督学习 1.2半监督学习 1.3增强学习 第四章 深度学习 1.1神经网络的基本原理 1.2深度学习的

    2024年02月09日
    浏览(55)
  • 边缘智能:边缘计算和人工智能的深度融合

    随着通信技术的飞速发展和移动设备使用的激增,一种全新的计算范式——边缘计算正在迅速普及。与此同时,随着深度学习的突破和硬件架构的许多改进,人工智能(AI)应用正在蓬勃发展。在网络边缘产生数十亿字节的数据,对数据处理和结构优化提出了巨大的要求。因此,

    2024年02月11日
    浏览(64)
  • 人工智能的深度学习如何入门

    人工智能深度学习近年来成为热门的技术领域,被广泛应用于许多领域,如自然语言处理、图像识别、机器翻译等。学习人工智能深度学习需要具备一定的数学和编程基础,但对于初学者来说,并不需要过于复杂的数学和编程知识。本文将介绍人工智能深度学习的基本概念和

    2024年03月27日
    浏览(63)
  • 深度学习:探索人工智能的前沿

    人工智能(Artificial Intelligence,简称AI)是一门研究如何使计算机能够执行通常需要人类智能的任务的领域。从早期的符号推理到现代的深度学习,人工智能经历了漫长的发展过程。 20世纪50年代,AI的奠基性工作开始,研究者们试图通过符号推理来模拟人类思维过程。然而,

    2024年01月19日
    浏览(75)
  • 深度学习:数据驱动的人工智能革命

    一般青年的任务,尤其是共产主义青年团及其他一切组织的任务,可以用一句话来表示,就是要学习。 深度学习的崛起标志着人工智能领域迈出了重要的一步,同时也为各行各业带来了巨大的机遇和挑战。通过模拟人类大脑的学习过程,深度学习能够自动提取特征、识别模式

    2024年02月20日
    浏览(47)
  • LabVIEW人工智能深度学习指南

    ‍‍🏡博客主页: virobotics的CSDN博客:LabVIEW深度学习、人工智能博主 🎄所属专栏:『LabVIEW深度学习实战』 🍻上期文章: 【YOLOv8】实战三:基于LabVIEW TensorRT部署YOLOv8 📰如觉得博主文章写的不错或对你有所帮助的话,还望大家多多支持呀! 欢迎大家✌关注、👍点赞、✌收

    2024年02月06日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包