PEFT 的工作流程

我是参数高效微调(PEFT)方法和库(peft
)的新手。PEFT 是一种旨在通过关注参数子集来提高大型模型微调效率的方法。peft
是一个有助于各种 PEFT 方法的库。
PEFT 中流行的一种技术是 低秩适应(Low-Rank Adaptation) (LoRA),我将通过 peft
库来演示它。
阅读了 peft
快速入门后,我掌握了该库的基本工作流程。在这篇短文中,我将探讨如何创建基础模型并使用它来构建 LoRA 模型。此外,我将简要了解 peft
库的内部机制,以便更好地理解其工作原理。
为什么要使用 PEFT 和 LoRA?
PEFT 方法,如 LoRA,旨在通过关注模型的特定部分来减少微调期间的计算负载。这使得您能够以显著减少的可训练参数实现高性能,使其成为资源有限场景的理想选择。
创建基础模型
import torch
from torch import nn
from peft import LoraConfig, get_peft_model, PeftType
# create a base model
class BaseModel(nn.Module):
def __init__(self, dim_in, dim_out):
super().__init__()
self.linear = nn.Linear(dim_in, dim_out)
def forward(self, x):
return self.linear(x)
base_model = BaseModel(dim_in=2, dim_out=4)
print("### BASE MODEL")
for name, param in base_model.named_parameters():
print(name, param)
BaseModel 由一个 Linear 层组成。当我们打印模型的名称和参数时,我们观察到参数具有 requires_grad=True
,表明它们是可训练的。
### BASE MODEL
linear.weight Parameter containing:
tensor([[-0.4009, -0.6960],
[-0.1067, -0.3404],
[-0.1151, -0.5108],
[ 0.3779, -0.3602]], requires_grad=True)
linear.bias Parameter containing:
tensor([-0.2076, -0.0166, -0.1409, 0.3477], requires_grad=True)
创建 PEFT 配置
每种 PEFT 方法都需要一个**配置**来确定如何应用微调。下面是 LoRA 的配置
# you always start with a configuration
config = LoraConfig(
inference_mode=False,
r=1,
lora_alpha=4,
lora_dropout=0.1,
target_modules=["linear"],
peft_type=PeftType.LORA,
)
创建 PEFT 模型
使用基础模型和配置,我们通过 get_peft_model
方法实例化 PEFT 模型。
lora_model = get_peft_model(model=base_model, peft_config=config)
print("\n\n### LORA MODEL")
for name, param in lora_model.named_parameters():
print(name, param)
### LORA MODEL
base_model.model.linear.base_layer.weight Parameter containing:
tensor([[-0.4009, -0.6960],
[-0.1067, -0.3404],
[-0.1151, -0.5108],
[ 0.3779, -0.3602]])
base_model.model.linear.base_layer.bias Parameter containing:
tensor([-0.2076, -0.0166, -0.1409, 0.3477])
base_model.model.linear.lora_A.default.weight Parameter containing:
tensor([[-0.5649, 0.3173]], requires_grad=True)
base_model.model.linear.lora_B.default.weight Parameter containing:
tensor([[0.],
[0.],
[0.],
[0.]], requires_grad=True)
在这里,基础模型的线性层不再具有 requires_grad=True
,这意味着 lora_model 将只训练 LoRA 特定的层,只优化 LoRA 引入的额外参数。
PEFT 幕后揭秘
为了更好地理解工作流程,我们来探讨一下调用 get_peft_model 方法时会发生什么。
get_peft_model
函数位于src/peft/mapping.py
文件中,它会预处理配置并创建一个 PeftModel。PeftModel
类位于src/peft/peft_model.py
中,它是各种 PEFT 方法(包括 LoRA)的基础模型。它选择合适的 PEFT 模块并创建一个实例,例如本例中的 LoraModel。- 每个 PEFT 调谐器都在
src/peft/tuners/
文件夹中实现。例如,LoraModel
类在src/peft/tuners/lora/model.py
中定义。这个类继承自BaseTuner
类,该类为所有 PEFT 调谐器提供了通用方法和属性。
要进行更详细的探索,您可以查看 LoRA 论文并浏览 GitHub 上的 PEFT 代码。
结论
我希望这篇帖子能让您对执行 get_peft_model 方法时发生的事情以及如何在模型中实现 LoRA 等 PEFT 方法有一个概览。如果您想深入了解,请随时联系我。
我要感谢 Benjamin Bossan,他是 Hugging Face PEFT 的核心贡献者,他审阅了这篇帖子并提供了宝贵的建议。