PEFT documentation

PSOFT

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

PSOFT

PSOFT est une méthode de fine-tuning efficace en paramètres basée sur le fine-tuning orthogonal (OFT) qui préserve les relations géométriques des vecteurs de colonnes des poids pré-entraînés tout en atteignant un équilibre entre les performances et l'efficacité multi-dimensionnelle, incluant le nombre de paramètres, l'utilisation de la mémoire et le coût de calcul. En restreignant les transformations orthogonales à un sous-espace principal de faible rang dérivé des poids pré-entraînés, PSOFT comble l'écart entre LoRA et OFT, offrant à la fois des garanties théoriques et une adaptabilité pratique. Son efficacité est validée par des évaluations étendues sur divers benchmarks, notamment GLUE, VTAB-1K, GSM8K, MATH et des benchmarks de raisonnement de bon sens.

  • Seules les couches nn.Linear sont prises en charge.
  • Les couches quantifiées ne sont pas prises en charge.

L'abstract de l'article est :

Porté par la croissance rapide du nombre de paramètres des modèles, le fine-tuning efficace en termes de paramètres (PEFT) est devenu essentiel pour adapter les grands modèles à diverses tâches en aval dans des conditions de ressources computationnelles limitées. Dans ce paradigme, le fine-tuning orthogonal et ses variantes préservent les représentations sémantiques des modèles pré-entraînés, mais peinent à concilier expressivité et efficacité en termes de nombre de paramètres, de mémoire et de calcul. Pour surmonter cette limitation, nous proposons le fine-tuning orthogonal efficace avec adaptation du sous-espace principal (PSOFT), qui restreint les transformations orthogonales au sous-espace principal des poids pré-entraînés. Plus précisément, PSOFT construit ce sous-espace via une décomposition matricielle pour permettre des transformations compatibles, établit une condition théorique qui maintient strictement la géométrie de ce sous-espace pour une préservation sémantique essentielle, et introduit des vecteurs ajustables efficaces qui relâchent progressivement l'orthogonalité pendant l'entraînement pour améliorer l'adaptabilité. Des expériences étendues sur 35 tâches de NLP et de CV à travers quatre modèles représentatifs démontrent que PSOFT offre une solution pratique et évolutive pour atteindre simultanément la préservation sémantique, l'expressivité et l'efficacité multidimensionnelle dans le PEFT.

Fonctionnement de PSOFT

PSOFT décompose chaque matrice de poids WpreW_{pre} en WpriW_{pri} et WresW_{res} en utilisant la SVD : Wpre=USV⊤W_{\text{pre}} = U S V^\top

Le sous-espace principal Wpri=UrSrVr⊤=ABW_{\text{pri}} = U_r S_r V_r^\top = AB est construit à partir des $r$ premières composantes singulières :

Wpre=Wpri+Wres=AB+Wres,W_{\text{pre}} = W_{\text{pri}} + W_{\text{res}} = AB + W_{\text{res}},

Wps-tuned=ARB+Wres.W_{\text{ps-tuned}} = ARB + W_{\text{res}}. (PSOFT-SO : PSOFT avec orthogonalité stricte)

Wps-tuned=A diag(α) R diag(β) B+Wres.W_{\text{ps-tuned}} = A \, \mathrm{diag}(\alpha) \, R \, \mathrm{diag}(\beta) \, B + W_{\text{res}}. (PSOFT-RO : PSOFT avec orthogonalité relâchée

Lors de l'entraînement, $A$, $B$ et WresW_{\text{res}} sont figés, et seul RR (ou RR avec α\alpha et $\beta$) est entraînable.

Pour assurer la compatibilité avec le framework PEFT (qui s'attend à des mises à jour additives des poids), PSOFT est implémenté sous la forme additive suivante : Wps-tuned=Wpre+A(R−Ir)BW_{\text{ps-tuned}} = W_{\text{pre}} + A (R - I_r) B

Paramètres entraînables

Après l'application de PSOFT :

  • Les poids du modèle d'origine ($A$, $B$ et $W_{\text{res}}$) sont figés.
  • Seule la matrice orthogonale RR (et éventuellement $\alpha$, $\beta$) est entraînable.
  • Aucun paramètre de biais supplémentaire n'est introduit.

Utilisation de base

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PsoftConfig, get_peft_model

# Load base model
model_id = "facebook/opt-125m"
model = AutoModelForCausalLM.from_pretrained(model_id)

# Configure PSOFT
config = PsoftConfig(
    r=32,                                   # the dimension of trainable matrix R,
    psoft_alpha=32,                         # scaling factor (typically set to r in PSOFT),
    target_modules=["q_proj", "v_proj"],    # target attention projection layers
    ab_svd_init="psoft_init",        # principal subspace initialization
    psoft_svd="full",                       # SVD method
    psoft_orth=True,                        # enable orthogonal R (Cayley parameterization)
    psoft_mag_a=True,                       # enable tunable vector alpha
    psoft_mag_b=True,                       # enable tunable vector beta
    use_cayley_neumann=False,               # disable Cayley–Neumann approximation
    num_cayley_neumann_terms=5,             # number of Neumann series terms
    cayley_neumann_eps=None,                # improve numerical stability
)

# Apply PSOFT
model = get_peft_model(model, config)
model.train()

tokenizer = AutoTokenizer.from_pretrained(model_id)
tokenizer.pad_token = tokenizer.eos_token

# Train
inputs = tokenizer("Hello world", return_tensors="pt", padding=True)
loss = model(**inputs, labels=inputs["input_ids"]).loss
loss.backward()

trainable = [p for p in model.parameters() if p.requires_grad]
optimizer = torch.optim.AdamW(trainable, lr=5e-4)
optimizer.step()
optimizer.zero_grad(set_to_none=True)

Options de configuration

Mode différent

(PSOFT-SO : PSOFT avec orthogonalité stricte)

config = PsoftConfig(psoft_orth=True,psoft_mag_a=False,psoft_mag_b=False)

(PSOFT-RO : PSOFT avec orthogonalité relâchée)

config = PsoftConfig(psoft_orth=True,psoft_mag_a=True,psoft_mag_b=True)

Bonnes pratiques

  1. Choix du rang : les rangs plus petits (par exemple 32–128) conviennent aux tâches plus simples, tandis que les rangs plus grands (par exemple 64–256) offrent une expressivité accrue pour les tâches plus complexes, au prix d'un nombre de paramètres et de calculs plus élevés.
  2. Scaling Factor: Le facteur d'échelle est généralement défini sur rr dans PSOFT.
  3. Taux d'apprentissage : utilisez des taux d'apprentissage standard (par exemple, 1e-4 à 5e-3) pour un entraînement stable.
  4. Initialisation SVD : l'option lowrank est plus efficace en mémoire et en calcul que full, ce qui la rend plus adaptée aux grands modèles.
  5. Approximation de Cayley–Neumann : lorsque le rang est élevé, l’activation de l’approximation de Cayley–Neumann peut améliorer considérablement l’efficacité computationnelle, tandis que le bénéfice est moins marqué pour les petits rangs. En pratique, un petit nombre de termes de la série de Neumann (généralement 5) offre généralement un bon équilibre entre précision et efficacité.

Aperçu des benchmarks

API

PsoftConfig

classe peft.PsoftConfig

< >

( 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: Optional[Union[list[str], str]] = Noneexclude_modules: Optional[Union[list[str], str]] = Nonepsoft_alpha: int = 32psoft_dropout: float = 0.0fan_in_fan_out: bool = Falseab_svd_init: Literal['psoft_init', 'pissa_init'] = 'psoft_init'psoft_svd: Literal['full', 'lowrank'] = 'full'psoft_svd_lowrank_niter: int = 10random_seed: int = 0psoft_orth: bool = Truepsoft_mag_b: bool = Truepsoft_mag_a: bool = Trueuse_cayley_neumann: bool = Falsenum_cayley_neumann_terms: int = 5cayley_neumann_eps: Optional[float] = Nonemodules_to_save: Optional[list[str]] = Noneinit_weights: bool = Truelayers_to_transform: Optional[Union[list[int], int]] = Nonelayers_pattern: Optional[Union[list[str], str]] = None )

Paramètres

  • r (int) — Valeur par défaut : 32. Le rang PSOFT (r) contrôle la capacité de l’adaptateur via une transformation R de taille r*r. Des rangs plus faibles, de 32 à 128, sont généralement suffisants pour des tâches simples. Les tâches plus complexes peuvent bénéficier de rangs de 64 à 256, ce qui augmente l’expressivité au prix de paramètres et de calculs supplémentaires. Consultez l’article pour des configurations validées empiriquement : https://openreview.net/forum?id=FSHrinMArK.
  • target_modules (Optional[Union[List[str], str]]) — Les noms des modules auxquels appliquer l’adaptateur. Si ce paramètre est spécifié, seuls les modules portant les noms indiqués seront remplacés. En cas de chaîne de caractères, une correspondance par expression régulière est effectuée. En cas de liste de chaînes de caractères, une correspondance exacte est réalisée ou il est vérifié si le nom du module se termine par l’une des chaînes fournies. Si la valeur est « all-linear », tous les modules linéaires/Conv1D sont sélectionnés (si le modèle est un PreTrainedModel, la couche de sortie est exclue). Si ce paramètre n’est pas spécifié, les modules sont choisis en fonction de l’architecture du modèle. Si l’architecture est inconnue, une erreur est levée — dans ce cas, vous devez spécifier manuellement les modules cibles.
  • exclude_modules (Optional[Union[List[str], str]]) — Les noms des modules auxquels l’adaptateur ne doit pas être appliqué. Si une chaîne de caractères est transmise, une correspondance par expression régulière est effectuée. Si une liste de chaînes de caractères est transmise, une correspondance exacte est effectuée ou il est vérifié si le nom du module se termine par l’une des chaînes transmises.
  • psoft_alpha (int) — Valeur par défaut : 32. Il contrôle le facteur d'échelle de PSOFT. Sémantique identique à alpha de LoRA.
  • psoft_dropout (float) — Valeur par défaut : 0.0. Dropout pour le chemin PSOFT. Même sémantique que le dropout LoRA.
  • 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.
  • ab_svd_init (Literal["psoft_init", "pissa_init"]) — Valeur par défaut : ‘psoft_init’. Stratégie d’initialisation pour A et B utilisée pour construire le sous-espace principal dans PSOFT. ‘psoft_init’ : initialisation basée sur la SVD avec A orthogonale par ligne, garantissant une orthogonalité stricte (PSOFT). ‘pissa_init’ : initialisation basée sur la SVD avec A et B symétriques (PiSSA standard).
  • psoft_svd (Literal["full", "lowrank"]) — Valeur par défaut : ‘full’. Backend SVD pour l’initialisation : ‘full’ utilise torch.linalg.svd ; ‘lowrank’ utilise torch.svd_lowrank.
  • psoft_svd_lowrank_niter (int) — Utilisé uniquement lorsque psoft_svd=‘lowrank’. Valeur par défaut : 10. Nombre d’itérations de puissance utilisées par torch.svd_lowrank lorsque psoft_svd=‘lowrank’.
  • psoft_orth (bool) — Valeur par défaut : ‘True’. Si True, contraint R à être orthogonale via la paramétrisation de Cayley, préservant les relations géométriques entre les colonnes des vecteurs de poids pré-entraînés. Si False, R est une matrice libre sans contraintes d’orthogonalité.
  • psoft_mag_b (bool) — Valeur par défaut : ‘True’. Si True, apprend un vecteur de mise à l’échelle diagonale sur le côté ‘output’ de R. Souvent associé à psoft_mag_a pour augmenter l’adaptabilité à la tâche, au prix d’une légère distorsion de la géométrie pré-entraînée.
  • psoft_mag_a (bool) — Valeur par défaut : ‘True’. Si True, apprend un vecteur d’échelle diagonale sur le côté ‘input’ de R. Souvent associé à psoft_mag_b pour augmenter l’adaptabilité à la tâche, au prix d’une légère distorsion de la géométrie pré-entraînée.
  • use_cayley_neumann (bool) — Valeur par défaut : ‘False’. Indique s’il faut utiliser la formulation de Cayley-Neumann de PSOFT ou non. Définissez-la sur True pour améliorer l’efficacité computationnelle, au prix d’une erreur d’approximation plus importante pour l’orthogonalité.
  • num_cayley_neumann_terms (int) — Valeur par défaut : 5. Utilisé uniquement lorsque use_cayley_neumann=True. Nombre de termes de Cayley-Neumann à utiliser. Un nombre plus élevé réduit l'erreur d'approximation liée à l'orthogonalité.
  • cayley_neumann_eps (optional[float]) — Valeur par défaut : ‘None’. Utilisé uniquement lorsque use_cayley_neumann=True. Limite optionnelle de la norme de Frobenius pour la matrice génératrice Q dans l’approximation de Cayley-Neumann. Si None (par défaut), aucun rééchelonnement n’est appliqué. Si défini à une valeur dans (0, 1) (par ex. 0,9), Q est rééchelonné chaque fois que ||Q||_F dépasse le seuil afin d’améliorer la stabilité numérique. Voir https://spherelab.ai/oftv2/ pour plus de détails.
  • init_weights (bool) — Valeur par défaut : ‘True’. Indique s’il faut initialiser les poids des couches PSOFT avec leur initialisation par défaut. Ne modifiez pas ce paramètre, sauf si vous savez exactement ce que vous faites.
  • modules_to_save (List[str]) — Liste des modules, en dehors des couches d’adaptateur, à définir comme entraînables et à enregistrer dans le point de contrôle final.
  • layers_to_transform (Union[List[int], int]) — Les indices de couches à transformer. Si une liste d'entiers est transmise, l'adaptateur sera appliqué aux indices de couches spécifiés dans cette liste. Si un seul entier est transmis, les transformations seront appliquées à la couche située à cet index.
  • layers_pattern (Optional[Union[List[str], str]]) — Le nom du motif de couche, utilisé uniquement si layers_to_transform est différent de None. Il doit cibler le nn.ModuleList du modèle, souvent appelé 'layers' ou 'h'.

Configuration pour PSOFT (Efficient Orthogonal Fine-Tuning with Principal Subspace Adaptation).

PSOFT insère une transformation orthogonale R de rang r*r entre les matrices de faible rang A et B, de sorte que la mise à jour de faible rang est ΔW = B @ (R-I) @ A. Seule R (et les vecteurs ajustables optionnels) est entraînée ; A et B sont initialisées avec psoft_init (basé sur la SVD, A orthogonale par ligne) et figées.

PsoftModel

classe peft.PsoftModel

< >

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

Paramètres

  • model — Le modèle à adapter.
  • config — PsoftConfig.
  • adapter_name — Nom de l'adaptateur, valeur par défaut « default ».
  • low_cpu_mem_usage — Crée des poids d'adaptateurs vides sur l'appareil méta.

Modèle PSOFT (Efficient Orthogonal Fine-Tuning with Principal Subspace Adaptation).

Insère une transformation orthogonale (ou mise à l’échelle) R de rang r*r entre A et B de faible rang : ΔW = B @ (R-I) @ A. Utilisez ab_svd_init="psoft_init" pour initialiser A/B à partir de la SVD et les geler, en n’entraînant que R (et les vecteurs d’amplitude optionnels).

Update on GitHub