mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
62 lines
3.7 KiB
Markdown
62 lines
3.7 KiB
Markdown
# 7.0. Améliorations de LoRA dans le fine-tuning
|
|
|
|
## Améliorations de LoRA
|
|
|
|
> [!TIP]
|
|
> L'utilisation de **LoRA réduit beaucoup le calcul** nécessaire pour **affiner** des modèles déjà entraînés.
|
|
|
|
LoRA permet d'affiner **de grands modèles** de manière efficace en ne changeant qu'une **petite partie** du modèle. Cela réduit le nombre de paramètres que vous devez entraîner, économisant ainsi de la **mémoire** et des **ressources informatiques**. Cela est dû au fait que :
|
|
|
|
1. **Réduit le Nombre de Paramètres Entraînables** : Au lieu de mettre à jour l'ensemble de la matrice de poids dans le modèle, LoRA **divise** la matrice de poids en deux matrices plus petites (appelées **A** et **B**). Cela rend l'entraînement **plus rapide** et nécessite **moins de mémoire** car moins de paramètres doivent être mis à jour.
|
|
|
|
1. Cela est dû au fait qu'au lieu de calculer la mise à jour complète des poids d'une couche (matrice), il l'approxime à un produit de 2 matrices plus petites réduisant la mise à jour à calculer :\
|
|
|
|
<figure><img src="../../images/image (9) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
2. **Garde les Poids du Modèle Original Inchangés** : LoRA vous permet de garder les poids du modèle original identiques, et ne met à jour que les **nouvelles petites matrices** (A et B). Cela est utile car cela signifie que les connaissances originales du modèle sont préservées, et vous ne modifiez que ce qui est nécessaire.
|
|
3. **Affinage Efficace Spécifique à la Tâche** : Lorsque vous souhaitez adapter le modèle à une **nouvelle tâche**, vous pouvez simplement entraîner les **petites matrices LoRA** (A et B) tout en laissant le reste du modèle tel quel. Cela est **beaucoup plus efficace** que de réentraîner l'ensemble du modèle.
|
|
4. **Efficacité de Stockage** : Après le fine-tuning, au lieu de sauvegarder un **nouveau modèle entier** pour chaque tâche, vous n'avez besoin de stocker que les **matrices LoRA**, qui sont très petites par rapport à l'ensemble du modèle. Cela facilite l'adaptation du modèle à de nombreuses tâches sans utiliser trop de stockage.
|
|
|
|
Afin d'implémenter LoraLayers au lieu de Linear lors d'un fine-tuning, ce code est proposé ici [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)
|
|
```
|
|
## Références
|
|
|
|
- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)
|