mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
62 lines
3.2 KiB
Markdown
62 lines
3.2 KiB
Markdown
# 7.0. LoRA 在微调中的改进
|
||
|
||
## LoRA 改进
|
||
|
||
> [!TIP]
|
||
> 使用 **LoRA 大大减少了所需的计算** 来 **微调** 已经训练好的模型。
|
||
|
||
LoRA 使得通过仅更改模型的 **一小部分** 来高效地微调 **大型模型** 成为可能。它减少了需要训练的参数数量,从而节省了 **内存** 和 **计算资源**。这是因为:
|
||
|
||
1. **减少可训练参数的数量**:LoRA 不更新模型中的整个权重矩阵,而是将权重矩阵 **拆分** 为两个较小的矩阵(称为 **A** 和 **B**)。这使得训练 **更快**,并且需要 **更少的内存**,因为需要更新的参数更少。
|
||
|
||
1. 这是因为它不计算层(矩阵)的完整权重更新,而是将其近似为两个较小矩阵的乘积,从而减少了更新计算:\
|
||
|
||
<figure><img src="../../images/image (9) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
2. **保持原始模型权重不变**:LoRA 允许您保持原始模型权重不变,仅更新 **新的小矩阵**(A 和 B)。这很有帮助,因为这意味着模型的原始知识得以保留,您只需调整必要的部分。
|
||
3. **高效的任务特定微调**:当您想将模型适应于 **新任务** 时,您只需训练 **小的 LoRA 矩阵**(A 和 B),而将模型的其余部分保持不变。这比重新训练整个模型 **高效得多**。
|
||
4. **存储效率**:微调后,您只需存储 **LoRA 矩阵**,而不是为每个任务保存 **整个新模型**,这些矩阵与整个模型相比非常小。这使得将模型适应于多个任务而不占用过多存储变得更容易。
|
||
|
||
为了在微调过程中实现 LoraLayers 而不是线性层,这里提出了以下代码 [https://github.com/rasbt/LLMs-from-scratch/blob/main/appendix-E/01_main-chapter-code/appendix-E.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/appendix-E/01_main-chapter-code/appendix-E.ipynb):
|
||
```python
|
||
import math
|
||
|
||
# Create the LoRA layer with the 2 matrices and the alpha
|
||
class LoRALayer(torch.nn.Module):
|
||
def __init__(self, in_dim, out_dim, rank, alpha):
|
||
super().__init__()
|
||
self.A = torch.nn.Parameter(torch.empty(in_dim, rank))
|
||
torch.nn.init.kaiming_uniform_(self.A, a=math.sqrt(5)) # similar to standard weight initialization
|
||
self.B = torch.nn.Parameter(torch.zeros(rank, out_dim))
|
||
self.alpha = alpha
|
||
|
||
def forward(self, x):
|
||
x = self.alpha * (x @ self.A @ self.B)
|
||
return x
|
||
|
||
# Combine it with the linear layer
|
||
class LinearWithLoRA(torch.nn.Module):
|
||
def __init__(self, linear, rank, alpha):
|
||
super().__init__()
|
||
self.linear = linear
|
||
self.lora = LoRALayer(
|
||
linear.in_features, linear.out_features, rank, alpha
|
||
)
|
||
|
||
def forward(self, x):
|
||
return self.linear(x) + self.lora(x)
|
||
|
||
# Replace linear layers with LoRA ones
|
||
def replace_linear_with_lora(model, rank, alpha):
|
||
for name, module in model.named_children():
|
||
if isinstance(module, torch.nn.Linear):
|
||
# Replace the Linear layer with LinearWithLoRA
|
||
setattr(model, name, LinearWithLoRA(module, rank, alpha))
|
||
else:
|
||
# Recursively apply the same function to child modules
|
||
replace_linear_with_lora(module, rank, alpha)
|
||
```
|
||
## 参考文献
|
||
|
||
- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|