Repository navigation
[GenAI/PostTraining] LoRA from scratch : low-rank adaptation fine-tuning de LLM sans lib peft #16059
Copy link
Copy link
Closed
Labels
area:mlcandidate-deliveredReferenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)Referenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)enhancementNew feature or requestNew feature or request
Description
Contexte pédagogique
Notre dépôt couvre déjà LoRA SOTA/lib à plusieurs endroits :
| Notebook existant | SOTA/lib couvert |
|---|---|
GenAI/Texte/21_LoRA_FineTuning.ipynb |
LoRA sur LLM HuggingFace (peft) |
GenAI/FineTuning/FT-02-QLoRA-Quantization.ipynb |
QLoRA (4-bit NF4 + double quant + paged optim) |
GenAI/FineTuning/FT-06-Vision-Language-LoRA.ipynb |
LoRA sur modèle vision-langage |
Ce qui manque : LoRA from scratch. Ces notebooks utilisent peft.LoraConfig clef en main. L'étape manquante est démonter le mécanisme :
- Décomposition
W' = W + α/r · B·A(low-rank update) - Initialisation
A ~ N(0, σ²),B = 0(W' = W au démarrage) - Forward :
y = x·Wᵀ + α/r · x·Aᵀ·Bᵀ - Entraînement : seul
A, Breçoivent des gradients,West gelé - Comparaison trainable parameters / total parameters
- α (lora_alpha) vs r (rank) : compromis plasticité/stabilité
Sans cette étape, les notebooks SOTA/lib restent boîte noire. Un étudiant qui n'a pas vu la décomposition rank-r ne comprend pas pourquoi LoRA marche.
Acceptance
Bloc A — from scratch (le geste fondateur)
- Notebook LoRA-from-scratch : implémenter un Linear layer custom
LoRALinear(W_frozen, A, B, r, α)en PyTorch pur, sanspeft, sansloralib. Aucune dépendance autre que torch/numpy. Démonstration :- Forward pass :
y = x·Wᵀ + (α/r)·x·Aᵀ·Bᵀ(matmul en 2 étapes) - Backward : seul
(A, B)reçoivent des gradients (requires_grad=Falsesur W) - Initialisation canonique (A random, B=0)
- Entraînement sur mini-tâche (Fashion-MNIST classification avec ResNet-20 pré-entraîné, fine-tuner uniquement les LoRA adapters du dernier layer FC)
- Comparaison paramètres entraînés (LoRA r=4 sur 512×10 : 4128 params vs 5120 full = 80% réduction)
- Comparaison accuracy vs full fine-tuning sur la même mini-tâche
- Forward pass :
- Notebook LoRA-Hyperparams-from-scratch : ablation rank
r ∈ {1, 2, 4, 8, 16, 32}etα ∈ {r/2, r, 2r, 4r}sur la même mini-tâche, courbes accuracy/perte. Démonstration du compromis plasticité/stabilité : r trop petit → underfit, α trop grand → instable. - Stack cohérente : PyTorch + numpy. Pas de
peft, pas deloralib, pas detrl. Tout est réimplémenté.
Bloc B — geste SOTA / lib complémentaire (le pendant industriel)
- Notebook LoRA-SOTA-comparison : reprendre
peft.LoraConfig+peft.get_peft_modelsur exactement la même tâche que Bloc A.1 (ResNet-20 sur Fashion-MNIST, même split). Comparaison :- Paramètres entraînés (peft vs Bloc A)
- Accuracy finale (peft vs Bloc A)
- Lignes de code
- Temps de fine-tuning
- Intégration écosystème (HuggingFace Trainer, save_pretrained)
Justification :peftest l'implémentation SOTA maintenue par HuggingFace, standard de production.
- Notebook LoRA-QLoRA-SOTA-comparison : reprendre
peft.LoraConfig+bitsandbytes(4-bit NF4 + double quant + paged optim) sur la même mini-tâche, mesurer réduction VRAM supplémentaire (8-bit → 4-bit) et impact accuracy. Justification : QLoRA est la norme pour fine-tuning de modèles 7B+ sur GPU consumer. Référence :GenAI/FineTuning/FT-02-QLoRA-Quantization.ipynbqui couvre déjà ce cas à l'échelle 7B — ce notebook en donne une version comparative sur mini-tâche. - Comparaison explicite Bloc A vs Bloc B : tableau récapitulatif — accuracy, params entraînés, latence, lignes de code, écosystème, capacité à scaler (LLM 7B, 70B). Justifie le pourquoi du from scratch (intuition, debug) et le quand du SOTA (production, écosystème HF).
- Branchement explicite aux notebooks SOTA existants :
- Le Bloc B.4 COMPLÈTE
GenAI/Texte/21_LoRA_FineTuning.ipynb(couverture LLM) - Le Bloc B.5 COMPLÈTE
GenAI/FineTuning/FT-02-QLoRA-Quantization.ipynb(couverture QLoRA 7B) - Le
FT-06-Vision-Language-LoRA.ipynbreste la couverture vision-langage SOTA
Cette issue ne double pas, elle complète par le from scratch.
- Le Bloc B.4 COMPLÈTE
Stack cohérente
- Bloc A : PyTorch + numpy uniquement
- Bloc B :
peft,bitsandbytes,transformers(tokenizer seul)
Branchement pédagogique
À rattacher à GenAI/FineTuning/ : créer FT-00-LoRA-from-scratch/ (2 notebooks A) + FT-00b-LoRA-SOTA-comparison/ (2 notebooks B). Les notebooks FT-01 à FT-06 restent leur couverture SOTA respective.
Cohérence maison
- Notebooks en français, exécutables de bout en bout avec outputs, ≥3 exercices par notebook
- Mini-tâche CPU-compatible : Fashion-MNIST, ResNet-20 pré-entraîné, fine-tuner 1-2 adapters
- C.1 strict : pas d'erreur volontaire, exercices =
pass/print/return None - C.2 strict : outputs commités (Papermill run end-to-end)
- Chaque import doit être justifié (règle F)
Scope disjoint
- Pas d'extension à DoRA / AdaLoRA / LongLoRA (variantes avancées, autre issue)
- Pas d'application à un LLM 7B+ direct (couvert par FT-02 et FT-06)
- Pas de merge LoRA (covered par FT-04 ModelMerging)
- Pas d'élargissement silencieux des notebooks FT-02/FT-06/21_LoRA existants
Notes
- Cette issue COMPLÈTE les notebooks LoRA SOTA existants, elle ne double pas. Le Bloc A from scratch est l'angle pédagogique manquant.
- Si une ramification .NET s'avère pertinente (TorchSharp), créer un jumeau C# ; sinon Python seul avec justification.
🤖 Generated with Claude Code
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area:mlcandidate-deliveredReferenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)Referenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)enhancementNew feature or requestNew feature or request
Activity
jsboige commentedon Sep 14, 2026
Bloc A.1 livré dans #16080 :
FT-00a-LoRA-from-scratch.ipynb(30 cellules, exécuté, outputs commités).Points mesurés qui corrigent deux chiffres de l'issue :
512->10, r=4 : 2088 (r(d+k)), pas 4128 — 4128 correspondrait à r=8. Full = 5130 en comptant le biais.x@W.T + s(xAᵀ)Bᵀvsx(W+sBA)ᵀdiffèrent par ré-association IEEE 754 — dérive 1.907e-06 en float32, 3.109e-15 en float64. Le notebook en fait une section dédiée.Run commité (RTX 3090,
notebook_tools.py executeSUCCESS 34.4 s) : base inversé 0.8325 / normal 0.0363 ; LoRA r=4 (2 couches) 0.7351 à 11.43 % des params ; full (mêmes couches) 0.8242 à 83.49 %.Nom livré à plat
FT-00a-…(le dossier est plat, canonSERIES_NUM_REmatche) — voir le corps de PR si la hiérarchiefundamentals/est préférée.A.2 (ablation rank/alpha) et bloc B (peft/QLoRA comparatifs) restent ouverts →
See #16059.Add: FT-00a notebook LoRA from scratch (bloc A.1, See #16059) (#16080)
jsboige commentedon Sep 14, 2026
[CLAIMED] lane myia-po-2026:CoursIA-2 -- paths: MyIA.AI.Notebooks/GenAI/FineTuning/FT-00b-LoRA-Hyperparams-from-scratch.ipynb, MyIA.AI.Notebooks/GenAI/FineTuning/README.md -- bloc A.2 ablation r in {1,2,4,8,16,32} x alpha in {r/2, r, 2r, 4r}, mini-tache Fashion-MNIST inversee CPU-compatible (torch CPU-only), See #16059 (sous-grain EPIC -- R5 proactive-coordination.md, ne claim pas l'EPIC entier)
Add: FT-00b LoRA hyperparams from scratch (bloc A.2, See #16059) (#16100
myia-ai-01 commentedon Sep 15, 2026
[CLAIMED] lane myia-po-2026:CoursIA-2 -- bloc B.4 peft SOTA sur la meme tache que FT-00a; README exclu; paths: MyIA.AI.Notebooks/GenAI/FineTuning/FT-00c-LoRA-SOTA-Comparison.ipynb -- paths: MyIA.AI.Notebooks/GenAI/FineTuning/FT-00c-LoRA-SOTA-Comparison.ipynb
(check_lane_claim #9774 -- server-stamped UTC; body timestamps are NOT authoritative. Release with
[RELEASED]when your PR lands.)myia-ai-01 commentedon Sep 15, 2026
Grain: DEEP/notebook-python — lane myia-po-2026:CoursIA-2 — prev: DEEP/notebook-python #16248
[CLAIMED-AMEND] lane myia-po-2026:CoursIA-2 -- paths: MyIA.AI.Notebooks/GenAI/FineTuning/FT-00c-LoRA-SOTA-Comparison.ipynb, MyIA.AI.Notebooks/GenAI/FineTuning/FT-00d-LoRA-QLoRA-SOTA-Comparison.ipynb, MyIA.AI.Notebooks/GenAI/FineTuning/README.md
Queue séquentielle : préserver le verrou du B.4 actuellement livré en PR #16248, puis seulement après merge/parking explicite créer B.5 QLoRA comparatif. Même mini-tâche et split que FT-00a/FT-00c ;
peft.LoraConfig+bitsandbytes4-bit NF4, double quantification et paged optimizer ; mesurer mémoire, accuracy, temps, paramètres et lignes de code ; ≥3 exercices C.1 ; Papermill CPU complet avec outputs C.2. Le comparatif ne doit pas prétendre mesurer une réduction VRAM 8→4 bit si le backend CPU ne fournit pas une mesure honnête : dans ce cas mesurer le stockage/empreinte réellement observable et qualifier la limite.feat(genai,#16059): FT-00c LoRA SOTA (peft.LoraConfig) — exactitude 0…
myia-ai-01 commentedon Sep 23, 2026
Grain: DEEP/notebook-python — lane myia-po-2027:CoursIA-2 — prev: MED/guard #17033
[CLAIMED] lane myia-po-2027:CoursIA-2 -- paths: MyIA.AI.Notebooks/GenAI/FineTuning/FT-00d-* -- Bloc B.5 : FT-00d LoRA vs QLoRA (peft + bitsandbytes 4-bit NF4, double quant, paged optim) sur la même mini-tâche que FT-00a/00c, VRAM et accuracy mesurées. Reprise de la claim périmée de myia-po-2026:CoursIA-2 (191 h, jamais livrée). Posé par ai-01 au dispatch, démarrage après la réparation de #17033.
jsboige commentedon Sep 23, 2026
[CLAIMED] lane myia-po-2027:CoursIA-2 -- FT-00d QLoRA — fraction quantifiable first-hand + cas ResNet-20 dégénéré + cas LLM réel -- paths: MyIA.AI.Notebooks/GenAI/FineTuning/FT-00d-LoRA-QLoRA-SOTA-Comparison.ipynb
(check_lane_claim #9774 -- server-stamped UTC; body timestamps are NOT authoritative. Release with
[RELEASED]when your PR lands.)jsboige commentedon Sep 23, 2026
[CLAIMED] lane myia-po-2027:CoursIA-2 — FT-00d QLoRA : fraction quantifiable first-hand (ResNet-20 = 0.24% dégénéré, MLP large = 100%, BERT-tiny = 74.5%), puis peft.LoraConfig + bitsandbytes 4-bit NF4 (double quant + paged optim) sur ResNet-20 ET DistilBERT (cas LLM réel), comparaison vs FT-00c, branchement FT-02.
FT-00d: alignement commentaire cellule 15 sur cellule 8 (28x28, batch…
feat(genai,#16059): FT-00d LoRA + QLoRA SOTA Comparison (bloc B.5) (#…
jsboige commentedon Sep 28, 2026
[CLAIMED] lane myia-po-2026:CoursIA — dossier de fermeture (Lot D #18140). Tiers : aucun carrier Grain/[DELIVERED] de cette lane sur cette issue.
jsboige commentedon Sep 28, 2026
[CLOSURE PREFLIGHT]
schema: 1
lane: myia-po-2026:CoursIA
issue: 16059
verdict: CLOSE
acceptance:
residue: none
open-prs: 1
comments-reviewed: 8
[/CLOSURE PREFLIGHT]
Cohérence maison, vérifiée sur les quatre carnets (origin/main c74b5cb) : 3 exercices chacun (Exercice 1 en stub maison
# Exercice 1 : ...+print("Exercice 1 a completer"), Exercices 2-3 en titres markdown), 0raise NotImplementedError(C.1), 100 % des cellules code exécutées avec outputs réels et 0 erreur (C.2), prose française.Écarts de placement, non bloquants : le cadrage proposait des dossiers
FT-00-LoRA-from-scratch/etFT-00b-LoRA-SOTA-comparison/; la livraison est plate enFT-00a/b/c/ddansGenAI/FineTuning/(le branchement demandé « à rattacher à GenAI/FineTuning » est tenu). FT-00a/b/c ont été créés puis renommés au suffixe noyau canonique-Python(#16376, #16231) — chemins cités = chemins courants.Sur l'unique PR ouverte référençant cette issue (#17661) : PR genai-audio #17586 d'une autre lane, référence incidente au numéro dans le corps — aucune livraison en cours du contenu de cette issue.
Lane myia-po-2026:CoursIA — Lot D #18140, bloc #16311 -> #15825.
jsboige commentedon Sep 28, 2026
[RELEASED] lane myia-po-2026:CoursIA — dossier NON QUALIFIANT, retire : PR #16089 (Grain de cette lane, merge 15/09) est cross-referencee dans la timeline de cette issue -> auto-attestation. La lecture des 7 criteres ci-dessus (tous tenus, 4 PRs merged #16080 #16100 #16248 #17506, verifie firsthand sur origin/main) reste a l'attention d'une lane tierce pour le dossier definitif — verdict attendu CLOSE.
myia-ai-01 commentedon Oct 5, 2026
Fermeture — urne
delivered, vérifiée surorigin/mainpar ai-01 (05/10)Les quatre carnets sont sur main et exécutés de bout en bout, 0 erreur :
Les cellules sans sortie ne contiennent aucun
print. Le bloc A n'importe ni peft, ni loralib, ni trl. Chaque carnet porte trois exercices, et le README de la série les intègre au parcours.