huggingface 笔记:peft

1 介绍

  • PEFT 提供了参数高效的方法来微调大型预训练模型。
  • 传统的范式是为每个下游任务微调模型的所有参数,但由于当前模型的参数数量巨大,这变得极其昂贵且不切实际。
  • 相反,训练较少数量的提示参数或使用诸如低秩适应 (LoRA) 的重新参数化方法来减少可训练参数数量是更有效的

2 训练

2.1 加载并创建 LoraConfig 类

  • 每种 PEFT 方法都由一个 PeftConfig 类定义,该类存储了构建 PeftModel 的所有重要参数
  • eg:使用 LoRA 进行训练,加载并创建一个 LoraConfig 类,并指定以下参数
    • task_type:要训练的任务(在本例中为序列到序列语言建模)
    • inference_mode:是否将模型用于推理
    • r:低秩矩阵的维度
    • lora_alpha:低秩矩阵的缩放因子
    • lora_dropout:LoRA 层的丢弃概率
from peft import LoraConfig, TaskType

peft_config = LoraConfig(
    task_type=TaskType.SEQ_2_SEQ_LM, 
    inference_mode=False, 
    r=8, 
    lora_alpha=32, 
    lora_dropout=0.1)

2.2 创建 PeftModel

  • 一旦设置了 LoraConfig,就可以使用 get_peft_model() 函数创建一个 PeftModel
    • 需要一个基础模型 - 可以从 Transformers 库加载 -
    • 以及包含如何配置 LoRA 模型参数的 LoraConfig

2.2.1 加载需要微调的基础模型

from transformers import AutoModel,AutoTokenizer
import os
import torch

os.environ["HF_TOKEN"] = '*'
#huggingface的私钥

tokenizer=AutoTokenizer.from_pretrained('meta-llama/Meta-Llama-3-8B')
model=AutoModel.from_pretrained('meta-llama/Meta-Llama-3-8B',
                                                torch_dtype=torch.bfloat16, 
                                                low_cpu_mem_usage=True)

2.2.2 创建 PeftModel

将基础模型和 peft_config 与 get_peft_model() 函数一起包装以创建 PeftModel

from peft import get_peft_model

model = get_peft_model(model, peft_config)
model.print_trainable_parameters()
#了解模型中可训练参数的数量
#trainable params: 3,407,872 || all params: 7,508,332,544 || trainable%: 0.0454

之后就可以train了

3保存模型

模型训练完成后,可以使用 save_pretrained 函数将模型保存到目录中。

model.save_pretrained("output_dir")

4 推理

  • 使用 AutoPeftModel 类和 from_pretrained 方法加载任何 PEFT 训练的模型进行推理
    • 对于没有明确支持 AutoPeftModelFor 类的任务,可以使用基础的 AutoPeftModel 类加载任务模型
from peft import AutoPeftModelForCausalLM
from transformers import AutoTokenizer
import torch

model = AutoPeftModelForCausalLM.from_pretrained("ybelkada/opt-350m-lora")
#LORA过的模型
tokenizer = AutoTokenizer.from_pretrained("facebook/opt-350m")
#普通的tokenizer

model.eval()
inputs = tokenizer("Preheat the oven to 350 degrees and place the cookie dough", return_tensors="pt")

outputs = model.generate(input_ids=inputs["input_ids"].to("cuda"), max_new_tokens=50)
print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True)[0])

# "Preheat the oven to 350 degrees and place the cookie dough in the center of the oven. In a large bowl, combine the flour, baking powder, baking soda, salt, and cinnamon. In a separate bowl, combine the egg yolks, sugar, and vanilla."

5LoraConfig主要参数

r (int)

LoRA 注意力维度(“秩”)

【默认8】

target_modules

应用适配器的模块名称。

  • 如果指定,则仅替换具有指定名称的模块。
    • 传递字符串时,将执行正则表达式匹配。
    • 传递字符串列表时,将执行精确匹配或检查模块名称是否以传递字符串之一结尾。
    • 如果指定为 'all-linear',则选择所有线性/Conv1D 模块,排除输出层。
    • 如果未指定,将根据模型架构选择模块。
    • 如果架构未知,将引发错误
      • - 在这种情况下,应手动指定目标模块。

【默认None]

lora_alpha

LoRA 缩放的 alpha 参数

【默认8】

lora_dropout

LoRA 层的 dropout 概率

【默认0】

fan_in_fan_out

如果要替换的层存储权重为 (fan_in, fan_out),则设置为 True

例如,GPT-2 使用 Conv1D,它存储权重为 (fan_in, fan_out),因此应设置为 True

bias

LoRA 的偏置类型。可以是 'none'、'all' 或 'lora_only'。

如果是 'all' 或 'lora_only',则在训练期间将更新相应的偏置

use_rslora
  • 设置为 True 时,使用 Rank-Stabilized LoRA,将适配器缩放因子设置为 lora_alpha/math.sqrt(r),因为其效果更好。
  • 否则,将使用原始默认值 lora_alpha/r
modules_to_save除适配器层外,在最终检查点中设置为可训练和保存的模块列表
init_lora_weights

如何初始化适配器层的权重。

  • 传递 True(默认)将导致来自微软参考实现的默认初始化。
  • 传递 'gaussian' 将导致高斯初始化,按 LoRA 秩缩放。
  • 将初始化设置为 False 会导致完全随机初始化,不建议使用。
  • 传递 'loftq' 使用 LoftQ 初始化。
  • 传递 'pissa' 使用 PiSSA 初始化,收敛速度更快,性能更优。
  • 传递 pissa_niter_[number of iters]使用快速 SVD 基于 PiSSA 的初始化,其中 [number of iters] 表示执行 FSVD 的子空间迭代次数,必须为非负整数。
    • 当 [number of iters] 设置为 16 时,可以在几秒钟内完成 7b 模型的初始化,训练效果大致相当于使用 SVD。
layers_to_transform

要转换的层索引列表。

  • 如果传递一个整数列表,则将适配器应用于该列表中指定的层索引。
  • 如果传递单个整数,则在该索引处的层上应用转换。
layers_pattern层模式名称,仅在 layers_to_transform 不为 None 时使用
rank_pattern层名称或正则表达式到秩的映射
alpha_pattern层名称或正则表达式到 alpha 的映射

6举例

6.1 初始 model

from transformers import AutoModel,AutoTokenizer
import os
import torch

os.environ["HF_TOKEN"] = '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'

tokenizer=AutoTokenizer.from_pretrained('meta-llama/Meta-Llama-3-8B')
model=AutoModel.from_pretrained('meta-llama/Meta-Llama-3-8B',
                                                torch_dtype=torch.bfloat16, 
                                                low_cpu_mem_usage=True)

model

6.2 经典lora

from peft import LoraConfig, TaskType

peft_config = LoraConfig(
                         r=8, 
                         lora_alpha=32, 
                         lora_dropout=0.1)

from peft import get_peft_model

lora_model = get_peft_model(model, peft_config)
lora_model.print_trainable_parameters()

lora_model

6.3 查看可训练参数

for name,tensor in model.named_parameters():
    print(name,tensor.requires_grad)

for name,tensor in lora_model.named_parameters():
    print(name,tensor.requires_grad)

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UQI-LIUWJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值