趋近智
低秩适应(LoRA)可以应用于实际模型,使用Hugging Face的PEFT(参数 (parameter)高效微调 (fine-tuning))库。该库提供了一个高级API,简化了将LoRA适配器注入现有Transformer模型的过程,只需几行代码。它处理修改模型架构和冻结相应权重 (weight)的复杂工作,让您能够专注于配置训练。
PEFT库的工作流程使用PEFT的核心思路是:取一个预训练 (pre-training)的基础模型,为您的LoRA适配器定义配置,然后将它们结合起来创建一个新的、可训练的模型。这个新模型保持原始权重 (weight)冻结,只训练注入的小型适配器层。
此过程包含三个主要步骤:
LoraConfig对象,以指定适配器层的超参数 (parameter) (hyperparameter),例如它们的秩(r)以及基础模型的哪些部分需要修改。PeftModel: 使用get_peft_model函数,根据您的配置将LoRA适配器封装到基础模型中。我们来逐一详细说明每个步骤。
LoraConfig配置LoRA适配器LoraConfig类是您LoRA实现的核心控制部分。它允许您定义适配器层的所有必要参数 (parameter)。
以下是您将使用的最主要参数:
r:这个整数表示低秩更新矩阵( 和 )的秩。它直接控制可训练参数的数量。较小的r会导致更少的参数和更快的训练,但可能捕获较少的任务特定信息。较大的r会以更多参数为代价增加模型容量。r的常见取值范围是4到64。lora_alpha:这是LoRA激活的缩放因子,作用类似于适配器的学习率。LoRA更新按lora_alpha / r进行缩放,因此调整此值会影响适配器所做更改的幅度。常见做法是将lora_alpha设置为r值的两倍。target_modules:一个字符串列表,指定基础模型架构中哪些模块应用LoRA。对于Transformer模型,这通常是注意力机制 (attention mechanism)中的线性层,例如query、key和value。例如,["q_proj", "v_proj"]。确定正确的模块名称需要检查基础模型的架构。lora_dropout:一个浮点值,表示应用于LoRA层的Dropout概率。这作为一种正则化 (regularization)技术,以防止适配器权重 (weight)过拟合 (overfitting)。task_type:指定您正在微调 (fine-tuning)的任务类型。例如,对于文本生成模型,您可以将其设置为TaskType.CAUSAL_LM。这有助于PEFT库正确配置模型的正向传播。from peft import LoraConfig, TaskType
# 因果语言模型的LoRA配置示例
lora_config = LoraConfig(
r=16,
lora_alpha=32,
target_modules=["q_proj", "v_proj"],
lora_dropout=0.1,
bias="none",
task_type=TaskType.CAUSAL_LM
)
PeftModel一旦您加载了基础模型并定义了LoraConfig,您可以使用get_peft_model函数将它们结合起来。该函数将基础模型和配置作为输入,并返回一个PeftModel对象。返回的模型已准备好进行训练,所有基础模型权重 (weight)都被冻结,只有新的LoRA适配器权重被标记 (token)为可训练。
下图说明了此工作流程。
get_peft_model函数接收一个冻结的基础模型和一个LoraConfig来生成一个PeftModel,其中只有注入的小型LoRA适配器矩阵是可训练的。
我们将通过一个完整的示例来演示如何为LoRA微调 (fine-tuning)设置模型。我们将使用meta-llama/Llama-2-7b-chat-hf模型作为基础,但同样的原理适用于Hugging Face Hub上的任何Transformer模型。
首先,请确保您已安装必要的库:
pip install torch transformers peft accelerate bitsandbytes
现在,我们来编写准备模型的Python代码。
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
# 1. 定义模型ID并加载分词器
model_id = "meta-llama/Llama-2-7b-chat-hf"
tokenizer = AutoTokenizer.from_pretrained(model_id)
# 2. 配置量化以4比特加载模型
# 这是一种节省内存的技术,我们将在QLoRA部分做进一步介绍
quantization_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.float16,
)
# 3. 加载量化的基础模型
base_model = AutoModelForCausalLM.from_pretrained(
model_id,
quantization_config=quantization_config,
device_map="auto" # 自动将层映射到可用硬件
)
# 4. 为k比特训练准备模型(可选但推荐)
base_model = prepare_model_for_kbit_training(base_model)
# 5. 定义LoRA配置
lora_config = LoraConfig(
r=8,
lora_alpha=16,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
# 6. 创建PeftModel
peft_model = get_peft_model(base_model, lora_config)
# 7. 打印可训练参数的百分比
def print_trainable_parameters(model):
"""
打印模型中可训练参数的数量。
"""
trainable_params = 0
all_param = 0
for _, param in model.named_parameters():
all_param += param.numel()
if param.requires_grad:
trainable_params += param.numel()
print(
f"trainable params: {trainable_params} || all params: {all_param} || "
f"trainable%: {100 * trainable_params / all_param:.2f}"
)
print_trainable_parameters(peft_model)
运行此代码时,print_trainable_parameters的输出将体现PEFT的效能。对于一个70亿参数 (parameter)的模型,输出会类似这样:
trainable params: 8,388,608 || all params: 3,508,801,536 || trainable%: 0.24
这是LoRA的主要优势。我们已经成功地为微调准备了一个70亿参数的模型,而只需训练总参数的不到0.25%。优化器状态和梯度的内存需求大幅减少,使得在单个消费级GPU上运行训练过程成为可能。
一旦您有了PeftModel,您就可以像进行完整微调一样,将其与标准的Hugging Face Trainer API一起使用。Trainer会自动处理只针对可训练LoRA参数的梯度更新。这小组适配器权重 (weight)可以独立于大型基础模型进行保存和加载,从而方便管理同一基础模型的多个专门版本。
简洁的语法。内置调试功能。从第一天起就可投入生产。
为 ApX 背后的 AI 系统而构建
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造