Recettes LoRA & QLoRA
Cette skill suppose que la décision de routage a déjà eu lieu — finetuning-method-selection devrait déjà avoir pointé ici parce que la forme des données est des démonstrations (SFT), pas des paires de préférence ou un signal de récompense vérifiable. Ce qui suit est la recette de meilleure pratique actuelle pour configurer l'adaptateur lui-même : quels modules cibler, comment dimensionner le rank et alpha, quel taux d'apprentissage utiliser, et quand QLoRA offre un vrai gain d'espace versus quand cela ajoute juste du risque. La préparation du dataset et les vérifications de qualité sont une préoccupation distincte — voir dataset-curation.
Entrée : une décision de routage (SFT via LoRA/QLoRA) plus une classe de taille cible.
Format de sortie : une config d'adaptateur validée — les valeurs de kwargs ci-dessous, pas des conseils en texte libre — que llm-finetuning-training-engineer consomme directement quand il génère un script exécutable.
La Recette de Référence
La recette de référence est « LoRA Without Regret » (Thinking Machines/Schulman, 2025-09), désormais la convention établie pour SFT LoRA/QLoRA.
Modules Cibles
Ciblez tous les modules linéaires, pas juste l'attention :
target_modules = [
"q_proj", "k_proj", "v_proj", "o_proj", # attention
"gate_proj", "up_proj", "down_proj", # MLP — matters most
]
Les couches MLP (gate_proj, up_proj, down_proj) importent le plus — le ciblage attention-only était l'ancienne convention, plus faible. Supprimer des modules pour économiser la mémoire est un Mode de Défaillance ci-dessous, pas une optimisation valide.
Alpha et Taux d'Apprentissage
- *`lora_alpha = 2 r`** est la convention établie (résultat « intruder dimensions » NeurIPS 2025). Ne réglez pas alpha indépendamment du rank — dérivez-le du rank à chaque fois.
- Le taux d'apprentissage LoRA ≈ 10x le LR de fine-tune complet équivalent. Pour QLoRA spécifiquement, 2e-4 est le point de départ standard. Tableaux d'hyperparamètres complets et exemples élaborés :
references/hyperparameters.md.
Rank par Tâche
Le rank est façonné par la tâche, pas un défaut global unique :
| Tâche | Rank |
|---|---|
| RL (adaptateurs GRPO/RLVR) | 1–32 |
| Défaut général | 16–32 |
| SFT à grande échelle | jusqu'à ~256 |
Un rank plus élevé n'est pas automatiquement meilleur — il augmente la capacité à mémoriser aussi vite qu'il augmente la capacité à généraliser. Commencez à la ligne correspondant à la tâche, et ne montez une ligne que si le rank inférieur underfits mesurément sur l'eval retenue, pas comme une couverture par défaut.
Taille de Batch Effective
Maintenez la taille de batch effective en dessous de 32. Cette recette a été validée à cette échelle — pousser le batch effectif plus haut est une extrapolation non testée, pas une victoire de débit gratuite.
Défauts Unsloth
Unsloth est l'implémentation de référence que ce plugin suppose comme le chemin rapide par défaut — sauf pour SFT conversationnel en forme de messages avec assistant_only_loss=True, où le trainer compilé d'Unsloth 2026.7.x n'a aucun chemin en forme de messages et l'échappatoire plain-TRL (references/unsloth-trl-mapping.md) est le défaut pour cette combinaison, pas une fallback de rare-regression. Ses défauts out-of-the-box, et pourquoi chacun est défini de cette façon :
lora_dropout=0— le chemin du kernel optimisé suppose un dropout zéro ; définir une valeur non-nulle abandonne l'accélération du kernel fusionné.bias="none"— les termes de biais ajoutent des paramètres d'adaptateur pour un gain de qualité négligeable à cette plage de rank.use_gradient_checkpointing="unsloth"— la variante de checkpointing d'Unsloth, pas le checkpointing HF vanilla ; économise environ 30% de VRAM par rapport à pas de checkpointing.optim="adamw_8bit"— 8-bit AdamW réduit la mémoire d'état d'optimiseur avec un impact de qualité négligeable à l'échelle de l'adaptateur LoRA/QLoRA.random_statefixé — épingle l'initialisation LoRA pour la reproductibilité entre les exécutions ; traitez-le comme n'importe quelle seed, pas un tunable.
Ceux-ci apparaissent ensemble sur l'appel get_peft_model :
model = FastLanguageModel.get_peft_model(
model,
r=32,
target_modules=target_modules,
lora_alpha=64, # 2 * r
lora_dropout=0,
bias="none",
use_gradient_checkpointing="unsloth",
random_state=3407,
)
Noms exacts de kwargs et leurs équivalents plain-TRL/PEFT, plus une config élaborée complète incluant SFTConfig : references/unsloth-trl-mapping.md et references/hyperparameters.md.
LoRA vs QLoRA vs Full FT
| Situation | Choix par défaut |
|---|---|
| Adapter le comportement sur des démonstrations | LoRA |
| Le modèle de base ne rentre pas en bf16 au rank cible | QLoRA |
| Injecter des connaissances de domaine denses et nouvelles | Full FT (voir finetuning-method-selection) |
| Incertain quel choisir | LoRA — passez à QLoRA uniquement si la mémoire le force |
- QLoRA = poids de base gelés quantifiés en NF4 + adaptateurs BF16. C'est ce qui rend un modèle de classe 65B entraînable sur 48GB — la base quantifiée est la victoire en mémoire, pas l'adaptateur lui-même.
- Le fine-tuning complet n'est pas un défaut. Réservez-le pour l'injection de connaissances denses où l'objectif change ce que le modèle sait au niveau des poids, pas adapter un comportement. Pour tout le reste dans la portée de cette skill, LoRA ou QLoRA est l'hypothèse de départ.
- Sur DGX Spark, QLoRA peut OOM avant une exécution LoRA bf16 équivalente, même si la trace en état stable de QLoRA est plus petite — les buffers de dequantization bitsandbytes sont des allocations CUDA-side transitoires qui montent en pic pendant le load. Un OOM QLoRA ne prouve pas que le modèle ne rentre pas ; la skill
spark-memory-thermal-opsdu plugindgx-spark-opscouvre l'échelle de remédiation OOM complète (bf16 LoRA est la prochaine chose à essayer, pas une réduction QLoRA supplémentaire).
Modes de Défaillance
-
Divergence fp16 sur les GPUs non-BF16. L'entraînement en fp16 sur du matériel sans support BF16 solide est une source connue de pics de perte et de divergence silencieuse. Forcez
bf16=Truepartout où le matériel le supporte ; ne retombez pas à fp16 comme si c'était équivalent. Vérifiez le support du matériel avant de choisir un dtype :python -c "import torch; print(torch.cuda.is_bf16_supported())" -
Rank trop élevé sur un petit dataset overfitte. Un rank choisi pour « SFT à grande échelle » (jusqu'à ~256) sur un dataset qui n'a pas d'échelle derrière lui mémorise plutôt que généralise. Faites correspondre le rank à la table Rank par Tâche ci-dessus, pas au plus grand nombre disponible.
-
Supprimer des modules cibles pour économiser la mémoire coûte la qualité pour des économies négligeables. Les paramètres de l'adaptateur sur
gate_proj/up_proj/down_projsont une petite fraction de la taille totale du modèle — les couper bouge à peine la mémoire mais blesse mesurément la qualité. Si la mémoire est serrée, passez à QLoRA ou réduisez le rank/batch/longueur de pack avant de trimmer les modules cibles.
Ces trois modes de défaillance partagent un motif : ils ressemblent à un bug de boucle d'entraînement (pics de perte, plateaux, mémorisation) mais sont en réalité un choix de config qui contredit la recette de référence ci-dessus. Vérifiez la configuration contre cette skill avant de déboguer la boucle d'entraînement elle-même.
Références
references/hyperparameters.md— tableaux rank/alpha/LR complets par type de tâche, notes rsLoRA, interactions batch/packing, et un bloc config Unsloth élaboré complet.references/unsloth-trl-mapping.md— chaque kwarg Unsloth mappé à son équivalent TRL/PEFT, notes API TRL actuelles, et la règle d'échappatoire pour quand retomber à plain TRL.
Skills connexes : finetuning-method-selection route ici ; dataset-curation couvre le côté données que cette skill ne couvre pas ; llm-finetuning-training-engineer est le consommateur en aval de la config que cette skill produit.