# LoRA

> [!WARNING]
> Ceci est expérimental et l'API peut évoluer à l'avenir.

[LoRA (Low-Rank Adaptation of Large Language Models)](https://hf.co/papers/2106.09685) est une technique d’entraînement populaire et légère qui réduit considérablement le nombre de paramètres entraînables. Elle fonctionne en insérant un plus petit nombre de nouveaux poids dans le modèle, et seuls ceux-ci sont entraînés. Cela rend l’entraînement avec LoRA beaucoup plus rapide, plus efficace en mémoire, et produit des poids de modèle plus petits (quelques centaines de Mo), plus faciles à stocker et à partager. LoRA peut également être combiné avec d’autres techniques d’entraînement comme DreamBooth pour accélérer l’entraînement.

> [!TIP]
> LoRA est très polyvalent et pris en charge pour [DreamBooth](https://github.com/huggingface/diffusers/blob/main/examples/dreambooth/train_dreambooth_lora.py), [Kandinsky 2.2](https://github.com/huggingface/diffusers/blob/main/examples/kandinsky2_2/text_to_image/train_text_to_image_lora_decoder.py), [Stable Diffusion XL](https://github.com/huggingface/diffusers/blob/main/examples/text_to_image/train_text_to_image_lora_sdxl.py) et [text-to-image](https://github.com/huggingface/diffusers/blob/main/examples/text_to_image/train_text_to_image_lora.py).

Ce guide examine le script [train_text_to_image_lora.py](https://github.com/huggingface/diffusers/blob/main/examples/text_to_image/train_text_to_image_lora.py) afin de vous familiariser avec celui-ci et de vous montrer comment l'adapter à votre propre cas d'usage.

Avant d'exécuter le script, assurez-vous d'installer la bibliothèque à partir du code source :

```bash
git clone https://github.com/huggingface/diffusers
cd diffusers
pip install .
```

Accédez au dossier d'exemple contenant le script d'entraînement et installez les dépendances requises pour le script que vous utilisez :

```bash
cd examples/text_to_image
pip install -r requirements.txt
```

> [!TIP]
> 🤗 Accelerate est une bibliothèque qui vous aide à entraîner sur plusieurs GPU/TPU ou avec une précision mixte. Elle configure automatiquement votre configuration d'entraînement en fonction de votre matériel et de votre environnement. Consultez le [tour rapide](https://huggingface.co/docs/accelerate/quicktour) de 🤗 Accelerate pour en savoir plus.

Initialiser un environnement 🤗 Accelerate :

```bash
accelerate config
```

Pour configurer un environnement 🤗 Accelerate par défaut sans choisir de configuration :

```bash
accelerate config default
```

Sinon, si votre environnement ne prend pas en charge un shell interactif, comme un notebook, vous pouvez utiliser :

```py
from accelerate.utils import write_basic_config

write_basic_config()
```

Enfin, si vous souhaitez entraîner un modèle sur votre propre jeu de données, consultez le guide [Create a dataset for training](create_dataset) pour apprendre à créer un jeu de données compatible avec le script d'entraînement.

> [!TIP]
> Les sections suivantes mettent en évidence les parties du script d'entraînement importantes pour comprendre comment le modifier, mais elles ne couvrent pas tous les aspects du script en détail. Si vous souhaitez en savoir plus, n'hésitez pas à lire le [script](https://github.com/huggingface/diffusers/blob/main/examples/text_to_image/train_text_to_image_lora.py) et à nous faire part de vos questions ou préoccupations.

## Paramètres du script

Le script d’entraînement comporte de nombreux paramètres pour vous aider à personnaliser votre session d’entraînement. Tous les paramètres et leurs descriptions se trouvent dans la fonction [`parse_args()`](https://github.com/huggingface/diffusers/blob/dd9a5caf61f04d11c0fa9f3947b69ab0010c9a0f/examples/text_to_image/train_text_to_image_lora.py#L85). Des valeurs par défaut sont fournies pour la plupart des paramètres et fonctionnent très bien, mais vous pouvez également définir vos propres valeurs dans la commande d’entraînement si vous le souhaitez.

Par exemple, pour augmenter le nombre d'époches d'entraînement :

```bash
accelerate launch train_text_to_image_lora.py \
  --num_train_epochs=150 \
```

De nombreux paramètres de base et importants sont décrits dans le guide d’entraînement [Text-to-image](text2image#script-parameters), ce guide se concentre donc uniquement sur les paramètres spécifiques à LoRA :

- `--rank` : la dimension interne des matrices de faible rang à entraîner ; un rang plus élevé signifie plus de paramètres entraînables
- `--learning_rate` : le taux d'apprentissage par défaut est 1e-4, mais avec LoRA, vous pouvez utiliser un taux d'apprentissage plus élevé

## Script d'entraînement

Le code de prétraitement du jeu de données et la boucle d’entraînement se trouvent dans la fonction [`main()`](https://github.com/huggingface/diffusers/blob/dd9a5caf61f04d11c0fa9f3947b69ab0010c9a0f/examples/text_to_image/train_text_to_image_lora.py#L371), et si vous devez adapter le script d’entraînement, c’est ici que vous apporterez vos modifications.

Comme pour les paramètres du script, un parcours détaillé du script d’entraînement est fourni dans le guide d’entraînement [Text-to-image](text2image#training-script). En revanche, ce guide se concentre sur les parties du script relatives à LoRA.

Diffusers utilise [LoraConfig](https://huggingface.co/docs/peft/main/en/package_reference/lora#peft.LoraConfig) de la bibliothèque [PEFT](https://hf.co/docs/peft) pour configurer les paramètres de l'adaptateur LoRA, tels que le rang, alpha et les modules dans lesquels insérer les poids LoRA. L'adaptateur est ajouté au UNet, et seules les couches LoRA sont filtrées pour l'optimisation dans `lora_layers`.

```py
unet_lora_config = LoraConfig(
    r=args.rank,
    lora_alpha=args.rank,
    init_lora_weights="gaussian",
    target_modules=["to_k", "to_q", "to_v", "to_out.0"],
)

unet.add_adapter(unet_lora_config)
lora_layers = filter(lambda p: p.requires_grad, unet.parameters())
```

Diffusers prend également en charge l’ajustement fin de l’encodeur de texte avec LoRA à l’aide de la bibliothèque [PEFT](https://hf.co/docs/peft) lorsque cela est nécessaire, par exemple pour l’ajustement fin de Stable Diffusion XL (SDXL). Le [LoraConfig](https://huggingface.co/docs/peft/main/en/package_reference/lora#peft.LoraConfig) est utilisé pour configurer les paramètres de l’adaptateur LoRA, qui sont ensuite ajoutés à l’encodeur de texte, et seules les couches LoRA sont filtrées pour l’entraînement.

```py
text_lora_config = LoraConfig(
    r=args.rank,
    lora_alpha=args.rank,
    init_lora_weights="gaussian",
    target_modules=["q_proj", "k_proj", "v_proj", "out_proj"],
)

text_encoder_one.add_adapter(text_lora_config)
text_encoder_two.add_adapter(text_lora_config)
text_lora_parameters_one = list(filter(lambda p: p.requires_grad, text_encoder_one.parameters()))
text_lora_parameters_two = list(filter(lambda p: p.requires_grad, text_encoder_two.parameters()))
```

L'[optimizer](https://github.com/huggingface/diffusers/blob/e4b8f173b97731686e290b2eb98e7f5df2b1b322/examples/text_to_image/train_text_to_image_lora.py#L529) est initialisé avec les `lora_layers` car ce sont les seuls poids qui seront optimisés :

```py
optimizer = optimizer_cls(
    lora_layers,
    lr=args.learning_rate,
    betas=(args.adam_beta1, args.adam_beta2),
    weight_decay=args.adam_weight_decay,
    eps=args.adam_epsilon,
)
```

En plus de la configuration des couches LoRA, le script d’entraînement est plus ou moins identique à train_text_to_image.py !

## Lancer le script

Une fois que vous avez apporté toutes vos modifications ou que vous êtes satisfait de la configuration par défaut, vous êtes prêt à lancer le script d'entraînement ! 🚀

Entraînons-nous sur le jeu de données [Naruto BLIP captions](https://huggingface.co/datasets/lambdalabs/naruto-blip-captions) pour générer vos propres personnages de Naruto. Définissez les variables d'environnement `MODEL_NAME` et `DATASET_NAME` sur le modèle et le jeu de données respectivement. Vous devez également indiquer où enregistrer le modèle dans `OUTPUT_DIR`, ainsi que le nom du modèle à enregistrer sur le Hub avec `HUB_MODEL_ID`. Le script crée et enregistre les fichiers suivants dans votre dépôt :

- points de contrôle des modèles enregistrés
- `pytorch_lora_weights.safetensors` (les poids LoRA entraînés)

Si vous entraînez sur plus d'un GPU, ajoutez le paramètre `--multi_gpu` à la commande `accelerate launch`.

> [!WARNING]
> Une session d'entraînement complète prend environ 5 heures sur un GPU 2080 Ti avec 11 Go de VRAM.

```bash
export MODEL_NAME="stable-diffusion-v1-5/stable-diffusion-v1-5"
export OUTPUT_DIR="/sddata/finetune/lora/naruto"
export HUB_MODEL_ID="naruto-lora"
export DATASET_NAME="lambdalabs/naruto-blip-captions"

accelerate launch --mixed_precision="fp16"  train_text_to_image_lora.py \
  --pretrained_model_name_or_path=$MODEL_NAME \
  --dataset_name=$DATASET_NAME \
  --dataloader_num_workers=8 \
  --resolution=512 \
  --center_crop \
  --random_flip \
  --train_batch_size=1 \
  --gradient_accumulation_steps=4 \
  --max_train_steps=15000 \
  --learning_rate=1e-04 \
  --max_grad_norm=1 \
  --lr_scheduler="cosine" \
  --lr_warmup_steps=0 \
  --output_dir=${OUTPUT_DIR} \
  --push_to_hub \
  --hub_model_id=${HUB_MODEL_ID} \
  --report_to=wandb \
  --checkpointing_steps=500 \
  --validation_prompt="A naruto with blue eyes." \
  --seed=1337
```

Une fois l’entraînement terminé, vous pouvez utiliser votre modèle pour l’inférence :

```py
from diffusers import AutoPipelineForText2Image
import torch

pipeline = AutoPipelineForText2Image.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16).to("cuda")  # or "mps", "xpu", "cpu"
pipeline.load_lora_weights("path/to/lora/model", weight_name="pytorch_lora_weights.safetensors")
image = pipeline("A naruto with blue eyes").images[0]
```

## Étapes suivantes

Félicitations pour l'entraînement d'un nouveau modèle avec LoRA ! Pour en savoir plus sur l'utilisation de votre nouveau modèle, les guides suivants peuvent vous être utiles :

- Apprenez à [charger différents formats LoRA](../tutorials/using_peft_for_inference) entraînés à l'aide d'entraîneurs communautaires tels que Kohya et TheLastBen.
- Apprenez à utiliser et à [combiner plusieurs LoRA](../tutorials/using_peft_for_inference) avec PEFT pour l'inférence.

