|
Download docs/decisions.md from Frankenstein-Labs/Cortex-0: direct link, hf CLI and curl.
- Browser
- Download file 17 kB
-
https://huggingface.co/Frankenstein-Labs/Cortex-0/resolve/main/docs/decisions.md
- Command line
-
hf download hf://Frankenstein-Labs/Cortex-0/docs/decisions.md
-
curl -L -o decisions.md https://huggingface.co/Frankenstein-Labs/Cortex-0/resolve/main/docs/decisions.md
17 kB
Journal des décisions (ADR léger)
Chaque décision structurante est enregistrée ici : contexte → décision → conséquences.
ADR-000 — Initialisation du projet
- Date : 2026-10-10
- Statut : accepté
- Contexte : construire une IA multimodale from scratch, sans aucun poids pré-entraîné.
- Décision : démarrer par une Phase 0 de fondations (structure, config, docs, tests TDD rouges) avant tout code de modèle.
- Conséquences : socle stable, vérifiable, avant d'écrire la moindre couche de neurones.
ADR-001 — Interdiction stricte des modèles pré-entraînés
- Date : 2026-10-10
- Statut : accepté
- Contexte : le cahier des charges interdit
transformers.AutoModel, CLIP, BLIP, LLaVA, Whisper, Wav2Vec, ViT pré-entraîné, Qwen, Llama, DeepSeek, Mistral, GPT. - Décision : n'autoriser que PyTorch, numpy, torchaudio (I/O), torchvision (transforms), tokenizers (entraînement de notre tokenizer), datasets, huggingface_hub, FastAPI, Gradio, pytest, ruff, Docker.
- Conséquences :
transformersn'est pas une dépendance. Un test automatique (Phase 0) échoue si un import interdit apparaît danssrc/.
ADR-002 — Positional encoding : RoPE pour le texte, appris pour l'image/audio
- Date : 2026-10-10
- Statut : accepté
- Contexte : le texte est une séquence de longueur variable (longue portée, besoin d'extrapolation) ; l'image et l'audio ont une structure de grille/trames de taille fixe.
- Décision : RoPE (rotary) pour l'encodeur/décodeur texte ; embedding positionnel appris pour le ViT et l'encodeur audio.
- Conséquences : meilleure extrapolation en longueur pour le texte ; simplicité et
suffisance pour des grilles de taille fixe. Détails en
architecture.md.
ADR-003 — Profile 50M honnête
- Date : 2026-10-10
- Statut : accepté
- Contexte : le cahier des charges demande « ~50M params (n_layer=6, n_head=6, n_embd=384, ctx=512) », mais cette combinaison avec vocab 32k donne ~22.9 M (lié) / ~35.2 M (non lié).
- Décision : conserver le profil demandé et ajouter
text_model_50m(n_embd=512, n_head=8, n_layer=6, embeddings non liés ≈ 51.6 M). Documenter l'écart. - Conséquences : transparence ; l'utilisateur choisit le profil. Pas de fausse déclaration de taille.
ADR-004 — Aucun secret en dur ; HF_TOKEN par variable d'environnement
- Date : 2026-10-10
- Statut : accepté
- Contexte : publication sur un dépôt Hugging Face privé/public.
- Décision : le token est lu depuis
HF_TOKEN(via.envgitignoré). Jamais dans le code, la config, les notebooks ou les commits. - Conséquences :
.envet.env.exampleséparés ;.gitignorebloque.env.
ADR-005 — Tests unitaires sur CPU, entraînement sur Colab
- Date : 2026-10-10
- Statut : accepté
- Contexte : machine de développement = CPU seul (4 cœurs, 15 Go, pas de GPU).
- Décision : toutes les tailles de test dans
configs/model.yaml > testsont minuscules ; l'entraînement réel se fait via un notebook Colab par phase. - Conséquences :
pytestreste rapide ; aucune promesse d'entraînement local.
ADR-006 — Une phase à la fois, validation explicite requise
- Date : 2026-10-10
- Statut : accepté
- Contexte : règle 1 du cahier des charges.
- Décision : ne jamais passer à la phase suivante sans tests verts + commit/push Hub
- validation explicite (« phase X validée »).
- Conséquences : progression lente mais contrôlée et vérifiable.
ADR-007 — Licence Apache-2.0
- Date : 2026-10-10
- Statut : accepté
- Contexte : la Phase 0 avait posé un placeholder MIT, explicitement à remplacer.
- Décision : adopter Apache-2.0. Le texte intégral est dans
LICENSE, la model card (README.md) portelicense: apache-2.0, etpyproject.tomldéclarelicense = { text = "Apache-2.0" }. - Conséquences :
- Licence permissive avec clause de brevet explicite (section 3), avantageuse pour un projet modèle/IA réutilisé par des tiers.
- Obligation de conserver les notices et de signaler les fichiers modifiés en cas de redistribution.
- Plus verbeuse que MIT ; aucune contrainte copyleft.
ADR-008 — Nom du modèle : Cortex-0
- Date : 2026-10-10
- Statut : accepté
- Contexte : le projet était désigné « OpenDevin Multimodal ». L'auteur fixe l'identité publique du modèle.
- Décision : nommer le modèle
Cortex-0(README,configs/model.yaml > project.name, model card, packagepyproject.toml→cortex-0). Le dépôt Hugging Face conserveFrankenstein-Labs/opendevin-multimodaljusqu'à la Phase 12 (renommage prévu alors). - Conséquences : identité claire du modèle ; une variable
PROJECT_NAME=Cortex-0et un futur renommage de dépôt clairement planifié. Aucune ambiguïté entre nom du modèle et nom du dépôt.
ADR-009 — Configuration finale verrouillée
Date : 2026-10-10
Statut : accepté
Contexte : l'auteur a figé les paramètres structurants à l'issue de la Phase 0.
Décision :
Paramètre Valeur Licence Apache-2.0 Nom du modèle Cortex-0 Organisation HF Frankenstein-Labs Dépôt cible Frankenstein-Labs/opendevin-multimodal MoE (Phase 10) 20 experts, top-2 Langue principale français Matériel CPU (dev/tests) + Colab (entraînement) Conséquences :
configs/model.yaml > moe.n_expertspasse de 8 à 20 ; le coût mémoire du MoE augmente d'autant (tous les experts résident en mémoire), ce qui sera réévalué lors de la Phase 10.
ADR-010 — Tokenizer : BPE ByteLevel, corpus FR plafonné, 19 tokens spéciaux
- Date : 2026-10-10
- Statut : accepté
- Contexte : la Phase 1 exige un BPE de 32 000 tokens sur corpus français public, 100 % from scratch, capable de gérer accents, emojis et caractères inconnus.
- Décision :
- BPE avec
pre_tokenizer=ByteLevel(add_prefix_space=False),byte_fallback=True(sur le modèle),min_frequency=2. initial_alphabet=ByteLevel.alphabet(): indispensable pour un round-trip exact.- 19 tokens spéciaux réservés en premier (4 base + 6 raisonnement + 9 modalités), ids 0..18 fixes → stables entre runs.
- Corpus plafonné à ~150–200 Mo de
wikimedia/wikipedia(config20231101.fr), en streaming (pas de téléchargement des ~6 Go). - Corpus « propre » : pas d'en-tête de licence ni de boilerplate.
- BPE avec
- Conséquences :
- Round-trip exact pour toute entrée, y compris hors corpus.
vocab_sizetraité comme borne supérieure ; échec explicite si le corpus est trop pauvre (pas de résultat trompeur).- Mesuré : 32 000 tokens en 21,8 s en local (CPU) sur 150 Mo.
- Recherche d'un vocabulaire « 32000 exact » : atteint, donc aucune réduction de scope nécessaire.
ADR-011 — Transformer texte : RoPE, pre-norm, attention causale à la main
- Date : 2026-10-10
- Statut : accepté
- Contexte : Phase 2 — coder un transformer decoder-only from scratch, sans
transformersninn.MultiheadAttention. - Décision :
- RoPE (rotation des paires de dimensions de Q/K) plutôt qu'un embedding
positionnel absolu appris : position relative dans
Q·K, zéro paramètre, meilleure extrapolation, réutilisable pour toutes les modalités. - Pre-norm (
x = x + F(LN(x))) : gradient non multiplié par la norme sur le chemin résiduel → entraînement plus stable. - Masque causal triangulaire à
-infavant softmax. - FFN GELU à deux couches,
ffn_mult=4. lm_headoptionnellement lié aux embeddings.- Génération (
temperature,top-k,top-p, glouton) écrite à la main, sansmodel.generate.
- RoPE (rotation des paires de dimensions de Q/K) plutôt qu'un embedding
positionnel absolu appris : position relative dans
- Conséquences :
- Causalité et invariance relative prouvées par tests, pas supposées.
- Le profil demandé (
n_embd=384, n_layer=6) fait 22.9 M, pas 50 M : écart documenté, le profiltext_model_50m(512 dim, non lié) fait bien 51.6 M. - Mesuré en local : overfit d'un mini-corpus FR 10.45 → 0.011 en 68 s.
ADR-012 — Entraînement texte : données memmap uint16, AdamW sélectif, cosine manuel
- Date : 2026-10-10
- Statut : accepté
- Contexte : Phase 3 — entraîner le transformer texte sur corpus public, en
pur PyTorch (pas de
Trainer). - Décision :
- Tokenisation en tableau
uint16(train.bin/val.bin) +np.memmap: 2 octets/token, zéro copie RAM, découpe val séquentielle (pas de fuite). - AdamW avec weight decay appliqué seulement aux tenseurs
dim >= 2. - Warmup linéaire + cosinus écrits à la main.
- Gradient clipping 1.0, autocast bf16/fp16 sur GPU.
- Checkpoints
last.pt/best.pt, logs JSONL.
- Tokenisation en tableau
- Conséquences :
- L'entraînement réel peut tourner sur CPU (mesuré) comme sur Colab GPU.
- La cible ppl < 30 est budgétée, pas garantie sur CPU ; le notebook Colab est le chemin nominal. Aucun chiffre annoncé sans mesure.
ADR-013 — Encodeur image ViT : patchs, position apprise, attention bidirectionnelle
- Date : 2026-10-10
- Statut : accepté
- Contexte : Phase 4 — encodeur image from scratch, aligné sur l'espace texte.
- Décision :
- Patch embedding par convolution noyau/pas = patch_size.
- Positional embedding appris (grille fixe) plutôt que RoPE 2D.
- Attention bidirectionnelle (
causal=False) : vital, sinon le CLS ne voit pas les patchs (bug réellement rencontré et corrigé). - Token CLS pour le résumé global (pool
cls), alternativemean. - Projecteur MLP
LayerNorm -> Linear -> GELU -> Linearverstext_dim. - Générateur d'images jouets maison (9 classes forme x couleur) pour tester sans données externes.
- Conséquences :
- Le drapeau
causalde l'attention est partagé texte (causal) / encodeurs (non causal). - Overfit vérifié : classification acc > 0.9, reconstruction MSE < 0.05 (CPU).
- Le drapeau
ADR-014 — CLIP maison : lots à légendes uniques, masque de padding, clipping
- Date : 2026-10-10
- Statut : accepté
- Contexte : Phase 5 — alignement image-texte from scratch.
- Décision :
- Loss contrastive symétrique écrite à la main (InfoNCE lignes+colonnes).
- Masque d'attention jusqu'au pooling texte (ignorer les PAD).
- Lots construits avec des légendes uniques (
_build_batches) : sans cela, l'appariement 1-1 est violé et la perte collapse. logit_scaleapprise (température), embeddings normalisés L2.- Gradient clipping 1.0 ; lr modéré (2e-3) — un lr élevé collapse.
- Métrique de retrieval au niveau des classes.
- Conséquences :
- Convergence réelle mesurée : retrieval 0.81 (hasard 0.11), loss 2.20 -> 0.15.
- Deux bugs silencieux identifiés et corrigés avec tests de régression.
ADR-015 — VLM : fusion par embeddings, décalage des labels, métrique de grounding
- Date : 2026-10-10
- Statut : accepté
- Contexte : Phase 6 — VLM génératif image+texte from scratch.
- Décision :
- Fusion par injection d'embeddings (
inputs_embeds) : patchs projetés insérés entre<|image_start|>et<|image_end|>. - Labels décalés (
labels[t]=ids[t+1]) ; perte masquée parignore_index=-100. - Métrique principale = exactitude teacher-forced (grounding) ; la génération libre est rapportée séparément comme métrique plus difficile.
- Fusion par injection d'embeddings (
- Conséquences :
- Bug silencieux évité : labels non décalés → loss 0.0006 mais génération cassée.
- Mesuré CPU : légende 0.85 / forme 0.80 / couleur 1.00 (teacher-forced), génération libre 0.35 (biais d'exposition assumé).
ADR-016 — Audio : mel maison, encodeur bidirectionnel, données synthétiques
- Date : 2026-10-10
- Statut : accepté
- Contexte : Phase 7 — encodeur audio from scratch.
- Décision :
- Mel-spectrogramme écrit à la main (torch.fft + filtres mel) car torchaudio est absent de l'environnement (plus « from scratch », zéro dépendance audio).
- Encodeur : patch embedding 2D (fréquence × temps) + blocs bidirectionnels.
- Données : voyelles synthétiques (formants F0/F1/F2, 10 classes), faute d'accès audio dans l'environnement de dev.
- Conséquences :
- Transcription parfaite sur le jeu jouet (acc 1.00). Parole réelle non testée : réduction de scope assumée et documentée.
ADR-017 — Modèle complet : un décodeur pour trois modalités
- Date : 2026-10-10
- Statut : accepté
- Contexte : Phase 8 — texte + image + audio dans un seul modèle.
- Décision :
- Un unique décodeur texte ; image et audio projetés puis injectés comme tokens spéciaux dans la même séquence (fusion précoce).
- Dans un lot multi-tâches, n'encoder que les lignes contenant la modalité.
- Métrique principale : exactitude teacher-forced par tâche ; génération libre rapportée séparément.
- Conséquences :
- Mesuré CPU : image 0.92 / audio 1.00 / mixte 0.93 (teacher-forced) ; génération libre mixte 0.17 (limite assumée, modèle de taille jouet).
ADR-018 — Vidéo : ViT partagé sur frames + transformer spatio-temporel
- Date : 2026-10-10
- Statut : accepté
- Contexte : Phase 9 — vidéo (frames + audio synchronisés).
- Décision :
- Vidéos jouets = forme colorée qui se déplace (direction = tâche temporelle).
VideoEncoder= ViT partagé par frame + embedding temporel appris + transformer spatio-temporel bidirectionnel sur tous lesn_frames × n_patchestokens.n_framespetit (4) à cause du coût quadratique de l'attention.
- Conséquences :
- Grounding mesuré CPU : vidéo 0.78, vidéo+audio 0.85 (18 classes).
- Génération libre 0.0 : limite assumée et documentée.
ADR-019 — MoE 20 experts top-2 dans le FFN
- Date : 2026-10-10
- Statut : accepté
- Contexte : Phase 10 — capacité accrue à coût de calcul borné.
- Décision :
MoEFFNremplace le FFN dense ; config imposée : 20 experts, top-2.- Routeur linéaire top-k + renormalisation des portes + bruit d'exploration.
- Loss auxiliaire Switch-Transformer (coef 0.01) pour équilibrer le routage.
- Calcul épars : chaque expert ne traite que ses tokens.
- Conséquences :
- Mesuré CPU : perplexité val 1.005, entropie de charge 0.9999 (routage équilibré).
- 14.86M paramètres totaux / 5.42M actifs par token (~2.7x).
- Tous les experts résidents en mémoire ; routage à vectoriser à grande échelle.
ADR-020 — Mémoire : RAG (mode A) + apprentissage permanent (mode B)
- Date : 2026-10-10
- Statut : accepté (mode B : expérimental)
- Contexte : Phase 11 — « apprendre des cours ».
- Décision :
- Mode A (RAG) : embeddings maison par feature hashing IDF + index numpy cosinus ; réponse extractive verbatim avec sources (vidéo = transcription + légendes frames).
- Mode B (apprentissage permanent) : quelques pas de gradient à l'ingestion, avec tampon de rejeu. Marqué EXPÉRIMENTAL ET INSTABLE, tests qui prouvent l'oubli.
- Conséquences :
- Mode A fiable, sans hallucination ; mode B honnête mais instable, non garanti.
ADR-008 — Nom du modèle « Cortex-0 » vs nom du dépôt (renommage différé)
- Date : 2026-10-10
- Statut : accepté
- Contexte : le modèle s'appelle Cortex-0, mais le dépôt Hub reste
Frankenstein-Labs/opendevin-multimodalpour ne pas casser les liens déjà publiés. - Décision : ne pas renommer le dépôt à ce stade ; documenter l'écart (nom de modèle « Cortex-0 », dépôt « opendevin-multimodal ») dans le README. Un renommage éventuel (redirection Hub) est laissé à une décision ultérieure.
- Conséquences : README et carte de modèle portent « Cortex-0 » ; le remote reste stable.
ADR-021 — Phase 12 : moteur unique, API FastAPI, démo Gradio, Docker
- Date : 2026-10-10
- Statut : accepté
- Décision :
- Un
CortexEngineunique (texte/image/audio/vidéo) partagé par l'API et la démo. - API FastAPI testée par
TestClient; handlers Gradio testés sans serveur. - Décodage d'entrées sans dépendance lourde (numpy/Pillow/
wave), vidéo en(T,H,W,3). CORTEX_CHECKPOINT/HF_TOKENau runtime ; aucun poids pré-entraîné dans l'image.
- Un
- Conséquences : 14 tests Phase 12 ; publication du checkpoint + carte avec licence Apache-2.0.