LoRA


LoRA: Low-Rank Adaptation of Large Language Models

原论文链接:arXiv:2106.09685
项目主页:GitHub - microsoft/LoRA

研究背景

随着大型语言模型(LLMs)如 GPT-3 的广泛应用,如何高效地将其适配到特定任务成为了一个关键问题。传统的微调方法需要更新模型中所有的参数,这在计算资源和存储方面都带来了巨大的挑战。为了解决这一问题,微软研究院提出了 LoRA(Low-Rank Adaptation)方法,旨在以更低的计算成本实现对大型模型的高效微调。

核心思想

LoRA 的核心理念是:在微调过程中,模型参数的更新可以被近似为一个低秩矩阵的形式。具体而言,LoRA 冻结预训练模型的原始权重,仅在每一层中引入可训练的低秩矩阵,从而大幅减少需要更新的参数数量。

通过这种方式,LoRA 实现了以下目标:

  • 参数高效:相比全量微调,LoRA 将可训练参数数量减少了约 10,000 倍。
  • 内存节省:GPU 内存需求降低了约 3 倍。
  • 性能保持:在多个任务上,LoRA 的性能与全量微调相当,甚至更优。

方法流程详解

LoRA 的实现过程如下:

  1. 冻结原始权重:预训练模型的原始权重保持不变。
  2. 引入低秩矩阵:在每一层中,添加两个可训练的低秩矩阵 A 和 B,使得权重更新可以表示为 $\Delta W = A \times B$,其中 A 的维度为 $d \times r$,B 的维度为 $r \times d$,r 是远小于 d 的秩。
  3. 训练低秩矩阵:仅训练 A 和 B 两个矩阵,其他参数保持不变。
  4. 推理阶段:在推理时,将 $\Delta W$ 加到原始权重上,得到更新后的权重。

这种方法的优势在于,只需训练少量参数即可实现模型的适配,极大地降低了计算成本。

实验设置与结果

研究团队在多个模型和任务上对 LoRA 进行了评估,包括 RoBERTa、DeBERTa、GPT-2 和 GPT-3。实验结果表明,LoRA 在以下方面表现出色:

  • 参数效率:在 GPT-3 175B 上,LoRA 将可训练参数数量减少了约 10,000 倍。
  • 内存使用:GPU 内存需求降低了约 3 倍。
  • 性能表现:在多个任务上,LoRA 的性能与全量微调相当,甚至更优。

此外,LoRA 的训练吞吐量更高,且在推理阶段不会引入额外的延迟。

总结

LoRA 提供了一种高效的微调大型语言模型的方法,显著降低了计算资源的需求,同时保持了模型的性能。其核心思想是利用低秩矩阵近似参数更新,从而实现参数高效的微调。

如何使用

在实践中,使用 LoRA(Low-Rank Adaptation)对大型语言模型进行高效微调,可以显著减少训练所需的参数和计算资源。以下是一个典型的 LoRA 微调流程,适用于如 LLaMA、GPT-2、BERT 等模型,结合了 Hugging Face Transformers 和 PEFT(Parameter-Efficient Fine-Tuning)库的使用。

1. 安装必要的库

确保安装了以下 Python 库:

1
pip install torch transformers datasets peft

2. 加载预训练模型和分词器

以 LLaMA 模型为例,加载预训练模型和对应的分词器:

1
2
3
4
5
from transformers import AutoTokenizer, AutoModelForCausalLM

model_name = "huggingface/llama-7b"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)

3. 应用 LoRA 配置

使用 PEFT 库配置 LoRA 参数,并将其应用到模型中:

1
2
3
4
5
6
7
8
9
10
11
12
from peft import get_peft_model, LoraConfig, TaskType

lora_config = LoraConfig(
r=8,
lora_alpha=16,
target_modules=["q_proj", "v_proj"],
lora_dropout=0.05,
bias="none",
task_type=TaskType.CAUSAL_LM
)

model = get_peft_model(model, lora_config)

在此配置中:

  • r:低秩矩阵的秩,控制参数的压缩程度。
  • lora_alpha:缩放因子,影响学习速率。
  • target_modules:指定应用 LoRA 的模块,通常选择自注意力机制中的查询(q_proj)和键(v_proj)投影层。

4. 冻结原始模型参数

为了实现参数高效微调,冻结预训练模型的原始参数,仅训练 LoRA 模块的参数:

1
2
for param in model.base_model.parameters():
param.requires_grad = False

5. 准备训练数据

使用 Hugging Face 的 datasets 库加载和预处理训练数据:

1
2
3
from datasets import load_dataset

dataset = load_dataset("your_dataset_name")

根据任务需求,进行必要的数据清洗和格式转换。

6. 定义训练参数和训练器

设置训练参数,并使用 Trainer 进行模型训练:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from transformers import Trainer, TrainingArguments

training_args = TrainingArguments(
output_dir="./lora-llama",
per_device_train_batch_size=4,
num_train_epochs=3,
learning_rate=1e-4,
logging_dir="./logs",
save_total_limit=2,
save_steps=500,
evaluation_strategy="steps",
eval_steps=500,
logging_steps=100,
load_best_model_at_end=True,
)

trainer = Trainer(
model=model,
args=training_args,
train_dataset=dataset["train"],
eval_dataset=dataset["validation"],
)

7. 开始训练

启动训练过程:

1
trainer.train()

8. 保存和加载 LoRA 模型

训练完成后,保存 LoRA 模型的权重:

1
model.save_pretrained("lora-llama")

在需要时,加载保存的模型进行推理或进一步训练:

1
2
3
4
from peft import PeftModel

model = AutoModelForCausalLM.from_pretrained(model_name)
model = PeftModel.from_pretrained(model, "lora-llama")
Contents
  1. 1. LoRA: Low-Rank Adaptation of Large Language Models
    1. 1.1. 研究背景
    2. 1.2. 核心思想
    3. 1.3. 方法流程详解
    4. 1.4. 实验设置与结果
    5. 1.5. 总结
    6. 1.6. 如何使用
      1. 1.6.1. 1. 安装必要的库
      2. 1.6.2. 2. 加载预训练模型和分词器
      3. 1.6.3. 3. 应用 LoRA 配置
      4. 1.6.4. 4. 冻结原始模型参数
      5. 1.6.5. 5. 准备训练数据
      6. 1.6.6. 6. 定义训练参数和训练器
      7. 1.6.7. 7. 开始训练
      8. 1.6.8. 8. 保存和加载 LoRA 模型
|