PEFT documentation

Adaptation de rang faible décomposée par poids (DoRA)

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.21.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Adaptation de rang faible décomposée par poids (DoRA)

Il s’agit d’une variante de LoRA et, par conséquent, tout ce qui est possible avec LoRA s’applique à cette méthode, sauf indication contraire sur cette page.

Cette technique décompose les mises à jour des poids en deux parties, l’amplitude et la direction. La direction est gérée par LoRA standard, tandis que l’amplitude est gérée par un paramètre apprenable distinct. Cela peut améliorer les performances de LoRA, en particulier à faible rang. Pour plus d’informations sur DoRA, voir https://huggingface.co/papers/2402.09353.

from peft import LoraConfig

config = LoraConfig(use_dora=True, ...)

Si des parties du modèle ou de l’adaptateur DoRA sont déchargées sur le CPU, vous pouvez obtenir une accélération significative au prix d’un léger surcoût temporaire (éphémère) en VRAM en utilisant ephemeral_gpu_offload=True dans config.runtime_config.

from peft import LoraConfig, LoraRuntimeConfig

config = LoraConfig(use_dora=True, runtime_config=LoraRuntimeConfig(ephemeral_gpu_offload=True), ...)

Un PeftModel avec un adaptateur DoRA peut également être chargé avec le drapeau ephemeral_gpu_offload=True en utilisant la méthode from_pretrained ainsi que la méthode load_adapter.

from peft import PeftModel

model = PeftModel.from_pretrained(base_model, peft_model_id, ephemeral_gpu_offload=True)

Optimisation

DoRA est optimisé (calculs plus rapides et moins de mémoire) pour les modèles en mode d'évaluation, ou lorsque dropout est réglé sur 0. Nous réutilisons le résultat de base dans ces cas pour obtenir l'accélération. L'exécution de dora finetuning avec CUDA_VISIBLE_DEVICES=0 ZE_AFFINITY_MASK=0 time python examples/dora_finetuning/dora_finetuning.py --quantize --lora_dropout 0 --batch_size 16 --eval_step 2 --use_dora sur une 4090, avec l'accumulation de gradients réglée sur 2 et le nombre maximal d'étapes sur 20, a donné les observations suivantes :

Sans optimisationAvec l’optimisation
durée d'exécution de l'entraînement (sec)359.7298279.2676
échantillons d'entraînement par seconde1.7792.292
étapes d'entraînement par seconde0.0560.072

De plus, il est possible d’augmenter encore les performances d’exécution de DoRA en utilisant le contexte auxiliaire DoraCaching. Cela nécessite que le modèle soit en mode eval :

from peft.helpers import DoraCaching

model.eval()
with DoraCaching():
    output = model(inputs)

Pour meta-llama/Llama-3.1-8B, le script de benchmark de mise en cache DoRA montre que, par rapport à LoRA :

  • DoRA sans mise en cache nécessite 139 % de temps supplémentaire
  • DoRA sans mise en cache nécessite 4 % de mémoire supplémentaire
  • DoRA avec mise en cache nécessite 17 % de temps supplémentaire
  • DoRA avec mise en cache nécessite 41 % de mémoire supplémentaire

Le cache peut donc accélérer considérablement l'inférence avec DoRA, mais il nécessite également beaucoup plus de mémoire. Idéalement, si le cas d'usage le permet, il est préférable de fusionner l'adaptateur DoRA afin d'éviter à la fois la surcharge mémoire et celle liée au temps d'exécution.

Limites

  • DoRA ne prend en charge que les couches embedding, linear et Conv2d pour le moment.
  • DoRA introduit un surcoût plus important que le LoRA pur, il est donc recommandé de fusionner les poids pour l'inférence, voir LoraModel.merge_and_unload().
  • DoRA devrait fonctionner avec des poids quantifiés via bitsandbytes (« QDoRA »). Toutefois, des problèmes ont été signalés lors de l’utilisation de QDoRA avec DeepSpeed Zero2.
Update on GitHub