# lora **Repository Path**: yuwei_2_838529949/lora ## Basic Information - **Project Name**: lora - **Description**: 微软lora - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-09-14 - **Last Updated**: 2025-09-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # LoRA:大型语言模型的低秩适配 本仓库包含 Python 包 `loralib` 的源代码,以及多个如何将其集成到 PyTorch 模型(如 Hugging Face 中的模型)的示例。目前我们仅支持 PyTorch。有关 LoRA 的详细描述请参阅我们的论文。 **LoRA:大型语言模型的低秩适配** *Edward J. Hu\*,Yelong Shen\*,Phillip Wallis,Zeyuan Allen-Zhu,Yuanzhi Li,Shean Wang,Lu Wang,Weizhu Chen* 论文地址:https://arxiv.org/abs/2106.09685 视频讲解:https://www.youtube.com/watch?v=DhRoTONcyZE *2023年2月更新:LoRA 现已被 Hugging Face 的[最先进参数高效微调(PEFT)](https://github.com/huggingface/peft)库支持。* LoRA 通过学习成对的低秩分解矩阵并冻结原始权重,减少可训练参数的数量。这极大地降低了针对特定任务适配的大型语言模型的存储需求,并实现了高效的任务切换,且不会增加推理延迟。LoRA 的效果优于包括 Adapter、Prefix-tuning 和 Fine-tuning 在内的多种适配方法。 我们在 GLUE 基准上,只训练和存储部分参数的情况下,使用 [RoBERTa (Liu et al., 2019)](https://arxiv.org/abs/1907.11692) base 和 large,以及 [DeBERTa (He et al., 2020)](https://arxiv.org/abs/2006.03654) XXL 1.5B,获得了与全量微调相当或更优的结果。点击下方数字可下载 RoBERTa 和 DeBERTa 的 LoRA 检查点。 | | | RoBERTa base
Fine-tune | RoBERTa base
LoRA | DeBERTa XXL
Fine-tune | DeBERTa XXL
LoRA | |---|-------------------------|----------------|--------------------------|-----------------|-----------------| | | 可训练参数数目 | 125M | 0.8M | 1.5B | 4.7M | | | MNLI (m-Acc/mm-Acc) | 87.6 | [87.5±.3/86.9±.3](https://github.com/microsoft/LoRA/releases/download/RoBERTa-base/roberta_base_lora_mnli.bin) |91.7/91.9| [91.9±.1/91.9±.2](https://github.com/microsoft/LoRA/releases/download/DeBERTa/deberta_v2_xxlarge_lora_mnli.bin) | | | SST2 (Acc) | 94.8 | [95.1±.2](https://github.com/microsoft/LoRA/releases/download/RoBERTa-base/roberta_base_lora_sst2.bin) | 97.2 | [96.9±.2](https://github.com/microsoft/LoRA/releases/download/DeBERTa/deberta_v2_xxlarge_lora_sst2.bin) | | | MRPC (Acc) | 90.2 | [89.7±.7](https://github.com/microsoft/LoRA/releases/download/RoBERTa-base/roberta_base_lora_mrpc.bin) | 92.0 | [92.6±.6](https://github.com/microsoft/LoRA/releases/download/DeBERTa/deberta_v2_xxlarge_lora_mrpc.bin) | | | CoLA (Matthew's Corr) | 63.6 | [63.4±1.2](https://github.com/microsoft/LoRA/releases/download/RoBERTa-base/roberta_base_lora_cola.bin) | 72.0 | [72.4±1.1](https://github.com/microsoft/LoRA/releases/download/DeBERTa/deberta_v2_xxlarge_lora_cola.bin) | | | QNLI (Acc) | 92.8 | [93.3±.3](https://github.com/microsoft/LoRA/releases/download/RoBERTa-base/roberta_base_lora_qnli.bin) | 96.0 | [96.0±.1](https://github.com/microsoft/LoRA/releases/download/DeBERTa/deberta_v2_xxlarge_lora_qnli.bin) | | | QQP (Acc) | 91.9 | [90.8±.1](https://github.com/microsoft/LoRA/releases/download/RoBERTa-base/roberta_base_lora_qqp.bin) | 92.7 | [92.9±.1](https://github.com/microsoft/LoRA/releases/download/DeBERTa/deberta_v2_xxlarge_lora_qqp.bin) | | | RTE (Acc) | 78.7 | [86.6±.7](https://github.com/microsoft/LoRA/releases/download/RoBERTa-base/roberta_base_lora_rte.bin) | 93.9 | [94.9±.4](https://github.com/microsoft/LoRA/releases/download/DeBERTa/deberta_v2_xxlarge_lora_rte.bin) | | | STSB (Pearson/Spearman Corr) | 91.2 | [91.5±.2/91.3±.2](https://github.com/microsoft/LoRA/releases/download/RoBERTa-base/roberta_base_lora_stsb.bin) |92.9/92.6| [93.0±.2/92.9±.3](https://github.com/microsoft/LoRA/releases/download/DeBERTa/deberta_v2_xxlarge_lora_stsb.bin) | | | 平均值 | 86.40 | 87.24 | 91.06 | 91.32 | 注意:要使用 LoRA 检查点,仍需从 [Hugging Face](https://huggingface.co/) 获取原始预训练模型。 Fine-tuning 数据取自 [Liu et al. (2019)](https://arxiv.org/abs/1907.11692) 和 [He et al. (2020)](https://arxiv.org/abs/2006.03654)。我们在实验结果中包含置信区间。请按照 `examples/NLU/` 目录下的说明复现我们的结果。 在 GPT-2 上,LoRA 相较于全量微调与其他高效微调方法(例如 [adapter (Houlsby et al., 2019)](https://arxiv.org/abs/1902.00751) 和 [prefix tuning (Li and Liang, 2021)](https://arxiv.org/abs/2101.00190))表现同样优秀。我们在 E2E NLG Challenge、DART 和 WebNLG 上进行了评测: | | 方法 | 可训练参数数目 | E2E (BLEU) | DART (BLEU) | WebNLG (BLEU-U/S/A) | |---|---------------------|-----------------------|--------------|--------------|--------------------------------| | | GPT-2 M (Fine-Tune) | 354.92M | 68.2 | 46.0 | 30.4/63.2/47.6 | | | GPT-2 M (Adapter) | 0.37M | 66.3 | 42.4 | 45.1/54.5/50.2 | | | GPT-2 M (Prefix) | 0.35M | 69.7 | 45.7 | 44.1/63.1/54.4 | | | GPT-2 M (LoRA) | 0.35M |70.4±.1|47.1±.2| 46.7±.4/62.1±.2/55.3±.2 | | | GPT-2 L (Fine-Tune) | 774.03M | 68.5 | 46.5 | 41.7/64.6/54.2 | | | GPT-2 L (Adapter) | 0.88M | 69.1±.1 | 45.7±.1 | 49.8±.0/61.1±.0/56.0±.0 | | | GPT-2 L (Prefix) | 0.77M | 70.3 | 46.5 | 47.0/64.2/56.4 | | | GPT-2 L (LoRA) | 0.77M |70.4±.1|47.5±.1| 48.4±.3/64.0±.3/57.0±.1 | 除 GPT-2 large 的 adapter 外,非 LoRA 基线均取自 [Li and Liang (2021)](https://arxiv.org/abs/2101.00190)。我们在实验结果中附加置信区间。 下载 GPT-2 LoRA 检查点: * [GPT-2 Medium E2E](https://github.com/microsoft/LoRA/releases/download/GPT-2/gpt2_md_lora_e2e.pt) (1.5 MB) * [GPT-2 Medium DART](https://github.com/microsoft/LoRA/releases/download/GPT-2/gpt2_md_lora_dart.pt) (1.5 MB) * [GPT-2 Medium WebNLG](https://github.com/microsoft/LoRA/releases/download/GPT-2/gpt2_md_lora_webnlg.pt) (1.5 MB) * [GPT-2 Large E2E](https://github.com/microsoft/LoRA/releases/download/GPT-2/gpt2_lg_lora_e2e.pt) (2.3 MB) * [GPT-2 Large DART](https://github.com/microsoft/LoRA/releases/download/GPT-2/gpt2_lg_lora_dart.pt) (2.3 MB) * [GPT-2 Large WebNLG](https://github.com/microsoft/LoRA/releases/download/GPT-2/gpt2_lg_lora_webnlg.pt) (2.3 MB) 请按照 `examples/NLG/` 目录下的说明复现我们的结果。 ## 仓库概览 (本仓库的初始版本已归档于 "snapshot-9-15-2021" 分支) 本仓库包含以下目录: * [loralib/](loralib) 包含 `loralib` 的源代码,需安装后方可运行我们提供的示例; * [examples/NLG/](examples/NLG) 包含在 GPT-2 上使用我们包实现的 LoRA 示例,可用于复现论文结果; * [examples/NLU/](examples/NLU) 包含在 RoBERTa 和 DeBERTa 上使用我们包实现的 LoRA 示例,在 GLUE 基准上取得有竞争力的结果; * 查看我们如何在 [GPT-2](examples/NLG/src/model.py)、[RoBERTa](examples/NLU/src/transformers/models/roberta/modeling_roberta.py) 和 [DeBERTa v2](examples/NLU/src/transformers/models/deberta_v2/modeling_deberta_v2.py) 中使用 `loralib` ## 快速开始 1. 安装 `loralib` 非常简单 ```bash pip install loralib # 或者 # pip install git+https://github.com/microsoft/LoRA ``` 2. 你可以选择将部分层替换为 `loralib` 实现的对应层,进行适配。目前仅支持 `nn.Linear`、`nn.Embedding` 和 `nn.Conv2d`。我们还支持 `MergedLinear`,适用于一个 `nn.Linear` 代表多层的情况,如某些注意力 `qkv` 投影的实现(详见附加说明)。 ```python # ===== 替换前 ===== # layer = nn.Linear(in_features, out_features) # ===== 替换后 ===== import loralib as lora # 添加秩为16的一对低秩适配矩阵 layer = lora.Linear(in_features, out_features, r=16) ``` 3. 在训练循环开始前,仅将 LoRA 参数标记为可训练。 ```python import loralib as lora model = BigModel() # 将所有名字不包含 "lora_" 的参数的 requires_grad 设为 False lora.mark_only_lora_as_trainable(model) # 训练循环 for batch in dataloader: ... ``` 4. 保存检查点时,仅保存 LoRA 参数的 `state_dict`。 ```python # ===== 之前 ===== # torch.save(model.state_dict(), checkpoint_path) # ===== 之后 ===== torch.save(lora.lora_state_dict(model), checkpoint_path) ``` 5. 使用 `load_state_dict` 加载检查点时,需设置 `strict=False`。 ```python # 先加载预训练检查点 model.load_state_dict(torch.load('ckpt_pretrained.pt'), strict=False) # 再加载 LoRA 检查点 model.load_state_dict(torch.load('ckpt_lora.pt'), strict=False) ``` #### 之后即可像往常一样开始训练。 ## 附加说明 1. 虽然我们的示例主要关注于简单且有效的设置,即仅适配 Transformer 中的 `q` 和 `v` 投影,但 LoRA 实际可应用于任意子集的预训练权重。我们鼓励你探索不同的配置,比如将 `nn.Embedding` 替换为 `lora.Embedding` 以适配嵌入层,和/或适配 MLP 层。不同模型结构和任务的最优配置很可能不同。 2. 某些 Transformer 实现中,查询、键和值的投影矩阵共用一个 `nn.Linear`。如需分别限制各自矩阵的秩,可以将其拆分为三个独立矩阵,或使用 `lora.MergedLinear`。如拆分层,请相应修改检查点。 ```python # ===== 替换前 ===== # qkv_proj = nn.Linear(d_model, 3*d_model) # ===== 替换后 ===== # 拆分(记得相应修改预训练检查点) q_proj = lora.Linear(d_model, d_model, r=8) k_proj = nn.Linear(d_model, d_model) v_proj = lora.Linear(d_model, d_model, r=8) # 或者,推荐使用 lora.MergedLinear qkv_proj = lora.MergedLinear(d_model, 3*d_model, r=8, enable_lora=[True, False, True]) ``` 3. 与 LoRA 同时训练偏置向量,或许是提升任务性能的高性价比方式(需仔细调整学习率)。虽然我们在论文中未深入研究其影响,但在 `lora` 中你可以方便地尝试。调用 `mark_only_lora_as_trainable` 时通过 `bias=` 传递 "all" 或 "lora_only" 可标记部分偏置为可训练。保存检查点时记得传递一致的 `bias=` 参数给 `lora_state_dict`。 ```python # ===== 之前 ===== # lora.mark_only_lora_as_trainable(model) # 不训练任何偏置向量 # ===== 之后 ===== # 训练所有 LoRA 应用模块的偏置向量 lora.mark_only_lora_as_trainable(model, bias='lora_only') # 或训练模型中所有偏置,包括 LayerNorm 偏置 lora.mark_only_lora_as_trainable(model, bias='all') # 保存检查点时使用一致的 bias= ('all' 或 'lora_only') torch.save(lora.lora_state_dict(model, bias='all'), checkpoint_path) ``` 解释 部分Transformer实现用一个 nn.Linear 层表示 query、key、value 的投影。如需分别对其中每项进行低秩约束,可以将其拆分为三个单独矩阵,或用 lora.MergedLinear。如选择拆分层,请相应调整预训练检查点 背景 Transformer 里的 Self-Attention 通常会用三个映射(Query、Key、Value),常见做法: * nn.Linear合并做法:用一个线性层(例如 nn.Linear(dim, 3*dim)),然后在前向传播时用 torch.chunk 分出Q/K/V。 * nn.Linear拆分做法:用三个独立的 nn.Linear 层分别实现 Query、Key、Value 的映射。 ``` 低秩约束(low-rank约束,比如LoRA)常常要求分别为Q/K/V分配低秩参数,因此希望直接拆分为三个单独的nn.Linear,方便分配。 ``` 为什么需要调整? 如果你的预训练权重是按照“合并的一个nn.Linear”保存的,而你现在模型结构“改成三个nn.Linear”,那么直接用原始的检查点文件(权重文件)加载参数会出现不匹配,因为: * 原模型有一组QKV合并的大权重(比如qkv_proj.weight), * 新模型有三个分开的权重(q_proj.weight, k_proj.weight, v_proj.weight)。 结构和名字都变了,对应不上,直接加载就报错,或者用strict=False参数只加载匹配上的(这样Q/K/V权重全部是新随机初始化的,低效也可能影响收敛)。 “调整”具体操作就是“把老权重文件的QKV大矩阵切分成Q、K、V三部分,并存回新权重文件” ```python import torch # 假设原有QKV合并权重为 (embed_dim, 3*embed_dim) state_dict = torch.load('old_checkpoint.pt') # 原名 'attention.qkv_proj.weight' qkv_weight = state_dict['attention.qkv_proj.weight'] # [3*dim, in_dim] q_weight, k_weight, v_weight = qkv_weight.chunk(3, dim=0) # [dim, in_dim]各自 state_dict['attention.q_proj.weight'] = q_weight state_dict['attention.k_proj.weight'] = k_weight state_dict['attention.v_proj.weight'] = v_weight # 同理处理 bias qkv_bias = state_dict['attention.qkv_proj.bias'] q_bias, k_bias, v_bias = qkv_bias.chunk(3, dim=0) state_dict['attention.q_proj.bias'] = q_bias state_dict['attention.k_proj.bias'] = k_bias state_dict['attention.v_proj.bias'] = v_bias # 删除原来的 qkv_proj del state_dict['attention.qkv_proj.weight'] del state_dict['attention.qkv_proj.bias'] torch.save(state_dict, 'new_checkpoint.pt') ``` 4. 调用 `model.eval()` 将触发将 LoRA 参数与对应预训练参数合并,消除后续前向传播的额外延迟。再次调用 `model.train()` 会撤销合并。如需禁用此行为,可在 LoRA 层传递 `merge_weights=False`。 ## 联系方式 如有任何问题,请联系我们或提交 issue。 关于 `loralib` 包相关问题: * Edward Hu (edward@edwardjhu.com) * Phillip Wallis (phwallis@microsoft.com) * Weizhu Chen (wzchen@microsoft.com) GPT-2 示例: * Phillip Wallis (phwallis@microsoft.com) * Yelong Shen (yeshe@microsoft.com) RoBERTa/DeBERTa 示例: * Lu Wang (luw@microsoft.com) ## 致谢 我们感谢(按字母顺序)Jianfeng Gao、Jade Huang、Jiayuan Huang、Lisa Xiang Li、Xiaodong Liu、Yabin Liu、Benjamin Van Durme、Luis Vargas、Haoran Wei、Peter Welinder 和 Greg Yang 提供的宝贵反馈。 ## 引用 ```BibTeX @inproceedings{ hu2022lora, title={Lo{RA}: Low-Rank Adaptation of Large Language Models}, author={Edward J Hu and Yelong Shen and Phillip Wallis and Zeyuan Allen-Zhu and Yuanzhi Li and Shean Wang and Lu Wang and Weizhu Chen}, booktitle={International Conference on Learning Representations}, year={2022}, url={https://openreview.net/forum?id=nZeVKeeFYf9} } ``` ## 贡献 欢迎对本项目提出贡献和建议。大多数贡献要求你同意一份 贡献者许可协议(CLA),声明你有权利且实际授权我们 使用你的贡献。详情请访问 https://cla.opensource.microsoft.com。 当你提交 pull request 时,CLA 机器人会自动判断你是否需要签署 CLA,并相应地为 PR 添加标记(如状态检查、评论)。只需按机器人的提示操作即可。你只需为所有使用我们 CLA 的仓库做一次操作。 本项目采用了 [微软开源行为准则](https://opensource.microsoft.com/codeofconduct/)。 更多信息请参阅 [行为准则 FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 或联系 [opencode@microsoft.com](mailto:opencode@microsoft.com) 以获取更多问题或意见。