PEFT documentation

RandLora : fine-tuning efficace en paramètres de rang complet de grands modèles

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

RandLora : fine-tuning efficace en paramètres de rang complet de grands modèles

RandLora est une technique de fine-tuning efficace en paramètres, similaire à LoRA et VeRA, mais qui effectue des mises à jour de rang complet pour améliorer les performances. RandLora peut s’avérer particulièrement utile lors de l’adaptation de grands modèles à des tâches difficiles nécessitant des mises à jour complexes, tout en préservant l’efficacité en paramètres de LoRA. La mise à jour de rang complet de RandLora est obtenue par un échelonnement linéaire de bases aléatoires. Les bases aléatoires sont un ensemble de plusieurs matrices de faible rang telles que la somme de leurs rangs est supérieure ou égale au rang complet des matrices de paramètres. Les paramètres entraînables de RandLora sont deux matrices diagonales (vecteurs) qui sont multipliées par les bases aléatoires de faible rang situées à droite, de manière similaire à la mise à jour de VeRA. Pour maintenir une faible utilisation de la mémoire, RandLora utilise une fonction personnalisée qui empêche le stockage en mémoire de bases inutiles pour la rétropropagation.

RandLora présente une différence notable : contrairement aux autres algorithmes PEFT de type LoRA, augmenter les rangs de base aléatoires de RandLora augmente le nombre de paramètres entraînables. Étant donné que le produit du nombre de bases par le rang des bases est constant dans RandLora, réduire le rang augmente le nombre de bases aléatoires, et donc le nombre de bases diagonales entraînables spécifiques à chaque base.

Comme la réduction du rang des bases aléatoires de RandLora entraîne une augmentation de leur nombre, RandLora peut devenir plus lent à entraîner que LoRA pour des rangs très petits, où typiquement, des rangs inférieurs à 4 entraînent une augmentation importante du temps d’entraînement. Cela n’affecte pas l’inférence, car les adaptateurs RandLora peuvent être fusionnés dans les matrices de poids pré-entraînées.

RandLora prend en outre en charge l’entraînement avec des bases aléatoires ternaires creuses (ne contenant que -1, 0 et 1). Ces bases sont décrites dans Bingham et al. et Ping et al. et pourraient théoriquement être utilisées pour réduire les besoins en calcul en effectuant des agrégations au lieu de multiplications de matrices pour créer la mise à jour des poids. Ce n’est pas actuellement pris en charge. Bien que cela ne réduise pas actuellement le calcul, l’utilisation de bases aléatoires creuses dans RandLora peut réduire le surapprentissage dans certains cas. Pour les utilisateurs intéressés par l’utilisation de bases ternaires creuses, l’option sparse est recommandée par rapport à l’option very_sparse, qui peut réduire les performances.

De la même manière que pour VeRA, lors de l’enregistrement des paramètres de RandLora, il est possible d’éviter de stocker les matrices de faible rang en définissant save_projection=False sur VeraConfig. Dans ce cas, ces matrices seront restaurées à partir de la graine aléatoire fixe fournie par l’argument projection_prng_key. Cela réduit la taille du point de contrôle, mais nous ne pouvons pas garantir la reproductibilité sur tous les appareils ni pour toutes les versions futures de PyTorch. Si vous souhaitez assurer la reproductibilité, définissez save_projection=True (ce qui est la valeur par défaut).

Comme dans Vera et afin de gérer différentes formes de couches adaptées, RandLora initialise les matrices A et B partagées avec la taille maximale requise pour chaque dimension. Lors du passage avant, les sous-matrices A et B pour une couche donnée sont extraites de ces matrices partagées et utilisées comme décrit dans l'article. Par exemple, l'adaptation de deux couches linéaires de formes (100, 20) et (80, 50) créera des matrices A et B de formes (rank, 50) et (100, rank) respectivement. Ensuite, pour adapter une couche de forme (100, 20), des sous-matrices A et B de formes (rank, 20) et (100, rank) seront extraites.

RandLora présente actuellement la contrainte suivante :

  • Seules les couches nn.Linear sont prises en charge.

L'abstract de l'article est :

Low-Rank Adaptation (LoRA) et ses variantes ont montré des résultats impressionnants en réduisant le nombre de paramètres entraînables et les exigences en mémoire des grands réseaux transformers, tout en maintenant les performances de fine-tuning. La nature de rang faible de la mise à jour des poids limite toutefois intrinsèquement la puissance de représentation des modèles affinés, compromettant potentiellement les performances sur des tâches complexes. Cela soulève une question cruciale : lorsqu'un écart de performance est observé entre LoRA et le fine-tuning standard, est-il dû au nombre réduit de paramètres entraînables ou au défaut de rang ? Cet article vise à répondre à cette question en introduisant RandLora, une méthode efficace en paramètres qui effectue des mises à jour de rang complet à l'aide de combinaisons linéaires apprises de matrices aléatoires non entraînables de rang faible. Notre méthode limite le nombre de paramètres entraînables en restreignant l'optimisation aux matrices de mise à l'échelle diagonales appliquées aux matrices aléatoires fixes. Cela nous permet de surmonter efficacement les limitations de rang faible tout en maintenant l'efficacité en paramètres et en mémoire pendant l'entraînement. Grâce à des expérimentations approfondies sur des benchmarks de vision, de langage et de vision-langage, nous évaluons systématiquement les limites de LoRA et des méthodes de base aléatoire existantes. Nos résultats révèlent que les mises à jour de rang complet sont bénéfiques pour les tâches de vision et de langage individuellement, et encore plus pour les tâches de vision-langage, où RandLora réduit considérablement — et élimine parfois — l'écart de performance entre le fine-tuning standard et LoRA, démontrant son efficacité.

Aperçu des benchmarks

API

RandLoraConfig

classe peft.RandLoraConfig

< >

( task_type: Optional[Union[str, TaskType]] = Nonepeft_type: Optional[Union[str, PeftType]] = Noneauto_mapping: Optional[dict] = Nonepeft_version: Optional[str] = Nonebase_model_name_or_path: Optional[str] = Nonerevision: Optional[str] = Noneinference_mode: bool = Falser: int = 32target_modules: list[str] | str | None = Noneprojection_prng_key: int = 0save_projection: bool = Truesparse: bool = Falsevery_sparse: bool = Falserandlora_dropout: float = 0.0fan_in_fan_out: bool = Falserandlora_alpha: int = 640bias: str = 'none'modules_to_save: list[str] | None = Noneinit_weights: bool = Truelayers_to_transform: list[int] | int | None = Nonelayers_pattern: str | None = None )

Paramètres

  • r (int, facultatif, valeur par défaut 32) — Dimension du rang de la base aléatoire de RandLora. Contrairement à Lora, ce paramètre est inversement proportionnel à la quantité de paramètres entraînables, car sa réduction augmente le nombre de paramètres entraînables.
  • target_modules (Union[list[str], str]) — Les noms des modules auxquels appliquer RandLora. Seules les couches linéaires sont prises en charge.
  • projection_prng_key (int) — Clé d’initialisation du PRNG de RandLora. Utilisée pour initialiser basis_A et basis_B pour de nouveaux modèles ou lors du chargement d’un point de contrôle qui ne contenait pas ces projections. Valeur par défaut : 0.
  • save_projection (bool) — Indique s'il faut enregistrer la base aléatoire globale basis_A / basis_B dans le state dict aux côtés des matrices diagonales lambda / gamma par couche. Cela augmentera la taille du checkpoint, mais garantira que nous pouvons recharger le checkpoint sur toutes les configurations système. La valeur par défaut est True.
  • sparse (bool) — Indique s'il faut utiliser des bases aléatoires creuses telles que décrites dans l'article RandLora. Les bases sont des bases ternaires creuses (ne contenant que -1, 0 et 1) où la probabilité d'attribution est de 1/6 pour -1 et 1 et de 2/3 pour 0. Ces matrices creuses visent à être utilisées pour des calculs sans matmul à l'avenir, voir https://huggingface.co/papers/2406.02528v1 L'implémentation actuelle est une preuve de concept où la sparsité n'est pas exploitée pour améliorer la vitesse ou l'utilisation de la mémoire. L'utilisation de matrices creuses ne réduit généralement pas les performances et peut même aider à réduire le surapprentissage. La valeur par défaut est False.
  • very_sparse (bool) — Indique s'il faut utiliser des bases aléatoires très creuses, telles que décrites dans l'article RandLora. Les bases très creuses sont des bases creuses ternaires (ne contenant que -1, 0 et 1) : pour une matrice dont la plus petite dimension est d, la probabilité d'attribution est de 1/√D pour -1 et 1, et de 1- 2/√D pour 0. L'utilisation de ces matrices creuses peut réduire davantage le surapprentissage par rapport aux alternatives sparse, mais diminuera très probablement les performances en conséquence. À utiliser avec prudence. La valeur par défaut est False.
  • randlora_dropout (float) — Probabilité de dropout pour les couches RandLora.
  • randlora_alpha (float) — Le coefficient de mise à l’échelle pour les couches RandLora, qui est généralement 20 fois le rang. Étant donné que le coefficient randlora_alpha est élevé par défaut, il peut entraîner des instabilités numériques, en particulier lorsque les taux d’apprentissage sont élevés. Si l’entraînement est instable, envisagez de réduire le taux d’apprentissage ou le coefficient randlora_alpha.
  • fan_in_fan_out (bool) — Définissez cette valeur sur True si la couche à remplacer stocke les poids sous la forme (fan_in, fan_out). Par exemple, gpt-2 utilise Conv1D qui stocke les poids sous la forme (fan_in, fan_out) et il convient donc de définir cette valeur sur True.
  • bias (str) — Type de biais. Peut être ‘none’, ‘all’ ou ‘randlora_only’. Si ‘all’ ou ‘randlora_only’, les biais correspondants seront mis à jour pendant l’entraînement. Notez que cela signifie que, même en désactivant les adaptateurs, le modèle ne produira pas la même sortie que le modèle de base sans adaptation.
  • modules_to_save (list[str]) — liste des modules, à l'exception des couches RandLora, à définir comme entraînables et à enregistrer dans le point de contrôle final.
  • init_weights (bool) — Indique s'il faut initialiser les poids des couches RandLora avec leur initialisation par défaut. Ne modifiez pas ce paramètre, sauf si vous savez exactement ce que vous faites.
  • layers_to_transform (Union[list[int],int]) — Les index de couches à transformer. Si cet argument est spécifié, les transformations RandLora sont appliquées aux index de couches indiqués dans cette liste. Si un seul entier est transmis, les transformations RandLora sont appliquées à la couche située à cet index.
  • layers_pattern (str) — Le nom du motif de couche, utilisé uniquement si layers_to_transform est différent de None et si le motif de couche ne figure pas dans les motifs de couches courants.

Ceci est la classe de configuration destinée à stocker la configuration d'un RandLoraModel.

Article : https://huggingface.co/papers/2502.00987.

RandLoraModel

classe peft.RandLoraModel

< >

( modelpeft_config: Union[PeftConfig, dict[str, PeftConfig]]adapter_name: strlow_cpu_mem_usage: bool = Falsestate_dict: Optional[dict[str, torch.Tensor]] = None ) → torch.nn.Module

Paramètres

  • model (PreTrainedModel) — Le modèle à adapter.
  • config (RandLoraConfig) — La configuration du modèle RandLora.
  • adapter_name (str) — Le nom de l'adaptateur, par défaut "default".
  • low_cpu_mem_usage (bool, optional, par défaut False) — Crée des poids d'adaptateurs vides sur l'appareil méta. Utile pour accélérer le processus de chargement.

Retourne

torch.nn.Module

Le modèle RandLora.

Crée un modèle RandLoRA à partir d'un modèle transformers pré-entraîné.

Exemple :

>>> from transformers import AutoModelForCausalLM
>>> from peft import RandLoraConfig, get_peft_model

>>> base_model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m")
>>> config = RandLoraConfig(r=32)
>>> model = get_peft_model(base_model, config)

Attributs :

Update on GitHub