fenyo/H100-Qwen3-14B-MonEspaceSante-CPT-SFT
🔧 Code & reproduction complète (scripts, RUNBOOK, reproduce.sh, conversations) : https://github.com/AlexandreFenyo/MonEspaceSante-H100-reproductionQwen3-14B — Mon espace santé (CPT + SFT)
Modèle de question-réponse closed-book (sans RAG) sur la FAQ du service public français « Mon espace santé ». Les connaissances de la FAQ ont été injectées dans les poids par continued pre-training (CPT) sur un corpus synthétique massif, puis un SFT léger restaure le format question/réponse. Objectif : démontrer qu'un CPT préalable permet d'aller bien plus loin qu'un simple SFT pour ancrer durablement des faits dans un LLM.
- Modèle de base enrichi (CPT seul) : `fenyo/H100-Qwen3-14B-MonEspaceSante-CPT`
- Base d'origine : `Qwen/Qwen3-14B-Base`
- Comparé à : `fenyo/gpt-oss-20b-FAQ-MES` (SFT direct de
openai/gpt-oss-20b)
TL;DR (chiffres clés)
Le CPT préalable fait passer la précision closed-book de 37,2 % → 63,8% (strict) sur 704 questions held-out jamais vues, là où le SFT seul plafonne (le modèle « bluffe » les détails).
Données (toutes publiées)
Pipeline complet (reproductible)
Matériel : 1× NVIDIA H100 PCIe 80 Go.
1) Génération synthétique (1-hop, anti model-collapse)
- Générateur : Qwen3-32B-FP8 servi par vLLM (
VLLM_USE_DEEP_GEMM=0; thinking désactivé viachat_template_kwargs.enable_thinking=False), piloté par NVIDIA NeMo Curator. - Prompts Nemotron-CC adaptés FR (rephrase Wikipédia, distill, extract-knowledge, knowledge-list, diverse-QA) + opérateur EntiGraph custom (passages reliant paires/triplets de faits réels).
- Tag de domaine
[Mon espace santé]; filtre qualité + déduplication (shingles n-grammes). - Décontamination vs held-out : embeddings bge-m3 (cos ≥ 0,90) + n-grammes (containment ≥ 0,6).
- Volume retenu : ~3,87 M tokens distincts (plafond extractible de 88 faits ; ~×260).
2) CPT — continued pre-training (full fine-tuning) → modèle de base enrichi
- Modèle :
Qwen/Qwen3-14B-Base, tous les poids entraînés. - Corpus : corpus CPT + 18 % de replay FR généraliste (anti-oubli, Ibrahim 2403.08763).
- Hyperparamètres : 3 epochs, lr 1e-5, cosine + warmup 3 %, weightdecay 0,01, grad clip 1,0, **bf16**, seqlen 2048, micro-batch 1 × accumulation 16, gradient checkpointing, attention SDPA.
- Optimiseur : bitsandbytes `paged_adamw_8bit` (sans DeepSpeed — ZeRO-3 CPU-offload provoquait un OOM CPU ; le paged 8-bit tient en ~81 Go GPU paginé + ~25 Go RAM).
- Résultat → `fenyo/H100-Qwen3-14B-MonEspaceSante-CPT`.
3) SFT — restauration du format Q/R (pas d'injection de faits, cf. Gekhman 2405.05904)
- Données :
MonEspaceSante-SFT(428 Q/R domaine + 120 refus). - Format fixe :
Question : {q}\nRéponse : {a}; loss sur la réponse uniquement (prompt masqué). - Hyperparamètres : 12 epochs, lr 2e-5, cosine + warmup 3 %, bf16, seqlen 2048, micro-batch 4 × accumulation 4, gradient checkpointing, `pagedadamw_8bit`.
Inférence (closed-book)
prompt = f"Question : {question}\nRéponse :" # aucune donnée de contexte fournie
# greedy (temperature=0), stop sur "\nQuestion :"Résultats détaillés
Courbe accuracy vs tokens synthétiques (CPT+SFT, juge Qwen3-32B)
La précision closed-book croît ~log-linéairement avec le nombre de tokens synthétiques, puis sature (rendements décroissants au-delà de ~4 M tokens distincts).
Comparaison directe vs gpt-oss-20b-FAQ-MES (même jeu de test, même juge)
Note d'équité : gpt-oss-20b-FAQ-MES a été évalué via transformers (implémentation de référence) et non vLLM 0.22, dont le kernel MoE produisait des sorties incohérentes pour cette architecture (gpt_oss). Mêmes 704 questions held-out, même juge Qwen3-32B, même barème.
Protocole de jugement : LLM-juge Qwen3-32B, closed-book, deux barèmes — strict (faits-clés présents ET aucune contradiction) et indulgent (idée générale correcte, tolère détails imprécis).
Conclusions & enseignements (chiffres simples)
- Le CPT préalable change la donne. À jeu de test et juge identiques, le SFT direct sur la base plafonne à 37,2 % (strict, held-out) : le modèle apprend le format mais invente les détails (mauvais portail, mauvais bouton, mauvais horaire). Avec un CPT préalable, on atteint 63,8% — soit ×1,7 la précision du SFT seul.
- Plus de tokens synthétiques = plus de précision, de façon log-linéaire : 37 → 44 → 53 → 61 % (strict) pour 0 → 0,5 → 2 → 3,9 M tokens. Le levier dominant est le volume de connaissances distinctes ré-exprimées, pas la taille du modèle.
- Plafond de données : à partir de 88 faits (~15 k tokens), on extrait ~3,9 M tokens distincts (×260) ; au-delà, la génération se répète et la précision sature (+4 pts seulement en doublant l'exposition).
- Anti-hallucination : ajouter 120 exemples de refus au SFT fait chuter l'hallucination hors-domaine de 48 % → 12%, sans coût sur la précision factuelle.
- Pas d'oubli : grâce à 18 % de replay FR, la culture générale reste à 100% (aucun oubli catastrophique).
- Plus petit mais meilleur : ce modèle 14B dépasse
gpt-oss-20b-FAQ-MES(20B) sur le held-out (63,8% vs 42,5% strict), illustrant qu'injecter la connaissance dans les poids (CPT) > la montrer en SFT.
Limites
- Domaine étroit (FAQ « Mon espace santé »). Hors de ce domaine, comportement de base de Qwen3-14B.
- Précision closed-book non parfaite : pour un usage production, un RAG complémentaire reste pertinent.
- Le juge est un LLM (Qwen3-32B) ; les valeurs absolues dépendent du barème (strict/indulgent fournis).
Références
EntiGraph (arXiv:2409.07431) · WRAP (2401.16380) · Physics of LM 3.1 (2309.14316) · Gekhman et al. (2405.05904) · Continual pretraining (2403.08763) · Nemotron-CC (NVIDIA NeMo Curator).
