Skip to content

[GenAI/PostTraining] LoRA from scratch : low-rank adaptation fine-tuning de LLM sans lib peft #16059

Closed

Description

@jsboige

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, B reçoivent des gradients, W est 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)

  1. Notebook LoRA-from-scratch : implémenter un Linear layer custom LoRALinear(W_frozen, A, B, r, α) en PyTorch pur, sans peft, sans loralib. 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=False sur 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
  2. 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.
  3. Stack cohérente : PyTorch + numpy. Pas de peft, pas de loralib, pas de trl. Tout est réimplémenté.

Bloc B — geste SOTA / lib complémentaire (le pendant industriel)

  1. Notebook LoRA-SOTA-comparison : reprendre peft.LoraConfig + peft.get_peft_model sur 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 : peft est l'implémentation SOTA maintenue par HuggingFace, standard de production.
  2. 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.ipynb qui couvre déjà ce cas à l'échelle 7B — ce notebook en donne une version comparative sur mini-tâche.
  3. 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).
  4. 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.ipynb reste la couverture vision-langage SOTA
      Cette issue ne double pas, elle complète par le from scratch.

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

Activity

  1. jsboige commented on Sep 14, 2026

    @jsboige
    OwnerAuthor

    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 :

    • Budget LoRA 512->10, r=4 : 2088 (r(d+k)), pas 4128 — 4128 correspondrait à r=8. Full = 5130 en comptant le biais.
    • La fusion n'est pas bit-exacte : x@W.T + s(xAᵀ)Bᵀ vs x(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 execute SUCCESS 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, canon SERIES_NUM_RE matche) — voir le corps de PR si la hiérarchie fundamentals/ est préférée.

    A.2 (ablation rank/alpha) et bloc B (peft/QLoRA comparatifs) restent ouverts → See #16059.

  2. jsboige commented on Sep 14, 2026

    @jsboige
    OwnerAuthor

    [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)

  3. myia-ai-01 commented on Sep 15, 2026

    @myia-ai-01
    Collaborator

    [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.)

  4. myia-ai-01 commented on Sep 15, 2026

    @myia-ai-01
    Collaborator

    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 + bitsandbytes 4-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.

  5. added a commit that references this issue on Sep 15, 2026
  6. added
    candidate-deliveredReferenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)
    on Sep 16, 2026
  7. myia-ai-01 commented on Sep 23, 2026

    @myia-ai-01
    Collaborator

    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.

  8. jsboige commented on Sep 23, 2026

    @jsboige
    OwnerAuthor

    [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.)

  9. jsboige commented on Sep 23, 2026

    @jsboige
    OwnerAuthor

    [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.

  10. added a commit that references this issue on Sep 27, 2026
  11. jsboige commented on Sep 28, 2026

    @jsboige
    OwnerAuthor

    [CLAIMED] lane myia-po-2026:CoursIA — dossier de fermeture (Lot D #18140). Tiers : aucun carrier Grain/[DELIVERED] de cette lane sur cette issue.

  12. jsboige commented on Sep 28, 2026

    @jsboige
    OwnerAuthor

    [CLOSURE PREFLIGHT]
    schema: 1
    lane: myia-po-2026:CoursIA
    issue: 16059
    verdict: CLOSE
    acceptance:

    • Notebook LoRA-from-scratch (LoRALinear custom, W gele, init A random / B=0, mini-tache FashionMNIST) -> MyIA.AI.Notebooks/GenAI/FineTuning/FT-00a-LoRA-from-scratch-Python.ipynb : LoRALinear x9 et requires_grad x10 dans les cellules code, FashionMNIST present, 11/11 cellules code executees 0 erreur — ajoute par PR Add: FT-00a LoRA from scratch (bloc A.1, See #16059) #16080
    • Notebook LoRA-Hyperparams-from-scratch (ablation rang r et alpha) -> MyIA.AI.Notebooks/GenAI/FineTuning/FT-00b-LoRA-Hyperparams-from-scratch-Python.ipynb : ablation alpha/rang (73 occurrences du couple dans le corpus), 14/14 cellules executees 0 erreur — ajoute par PR Add: FT-00b LoRA hyperparams from scratch (bloc A.2, See #16059) #16100
    • Stack bloc A pure (aucune dependance peft / loralib / trl) -> FT-00a et FT-00b : 0 occurrence de peft, loralib et trl dans l'ensemble des cellules code des deux carnets (reluction grep sur origin/main c74b5cb)
    • Notebook LoRA-SOTA-comparison (peft sur exactement la meme mini-tache) -> MyIA.AI.Notebooks/GenAI/FineTuning/FT-00c-LoRA-SOTA-Comparison-Python.ipynb : peft x54, save_pretrained x6, FashionMNIST meme mini-tache, exactitude 0.7379 (adapter) vs 0.8242 (full FT) mesuree au titre du commit d'ajout 2d61fec — ajoute par PR feat(genai,#16059): FT-00c LoRA SOTA comparison — peft vs from scratch (bloc B.4) #16248
    • Notebook LoRA-QLoRA-SOTA-comparison (NF4 + bitsandbytes, version comparative sur mini-tache) -> MyIA.AI.Notebooks/GenAI/FineTuning/FT-00d-LoRA-QLoRA-SOTA-Comparison-Python.ipynb : NF4 x13, bitsandbytes x13, renvois FT-02 x12, 9/9 cellules executees 0 erreur — ajoute par PR feat(genai,#16059): FT-00d LoRA + QLoRA SOTA Comparison (bloc B.5) #17506
    • Comparaison explicite bloc A vs bloc B -> FT-00c tableau recap : « deux lignes remplacent les ~60 lignes de FT-00a », « peft libere exactement les memes 3 752 parametres que le from scratch », exactitude comparable a meme graine et meme protocole, artefact portable save_pretrained
    • Branchement explicite aux notebooks SOTA existants -> FT-00c renvoie a 21_LoRA_FineTuning x4 ; FT-00d renvoie a FT-02-QLoRA-Quantization x12 ; FT-06-Vision-Language-LoRA non modifie (couverture vision SOTA conservee)
      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), 0 raise 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/ et FT-00b-LoRA-SOTA-comparison/ ; la livraison est plate en FT-00a/b/c/d dans GenAI/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.

  13. jsboige commented on Sep 28, 2026

    @jsboige
    OwnerAuthor

    [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.

  14. myia-ai-01 commented on Oct 5, 2026

    @myia-ai-01
    Collaborator

    Fermeture — urne delivered, vérifiée sur origin/main par 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:mlcandidate-deliveredReferenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions