Qwen3-8B — Mon Espace Santé (CPT + SFT)

Injection des connaissances de la FAQ Mon espace santé dans les poids d'un LLM sans RAG, via génération synthétique → continued pre-training (CPT) → SFT. Modèle final : Qwen3-8B (8 Md paramètres, dense).

TL;DR — Sur une évaluation closed-book identique (696 questions au phrasing inédit, juge Qwen3-32B), ce modèle de 8 B atteint 86,9 % et dépasse fenyo/gpt-oss-20b-FAQ-MES (70,8 %), un modèle 2,5× plus gros (MoE 20 B), grâce au CPT synthétique. → comparaison détaillée.

🛡️ Pour un usage en production (service public de santé), préférez la variante anti-hallucination : fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT-anti-hallucination. Ce modèle-ci maximise le factuel mais invente souvent sur les questions hors-périmètre (refus correct ≈ 12,8 %). La variante anti-hallucination refuse ~79 % des questions hors-périmètre (au lieu d'inventer) tout en restant plus précise que gpt-oss-20B — meilleur compromis pour un contexte de santé.

Modèle de base enrichi par CPT fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT ← lui-même issu de Qwen/Qwen3-8B-Base
Corpus CPT fenyo/L40S-MonEspaceSante-CPT-corpus
Données SFT fenyo/L40S-MonEspaceSante-SFT-dataset
Suite d'évaluation + juge fenyo/L40S-MonEspaceSante-eval-suite
Matériel 1× NVIDIA L40S (48 Go)

1. Pipeline (vue d'ensemble)

88 faits réels (FAQ Mon espace santé)
   │  ① Génération synthétique (Qwen3-32B-FP8 + NeMo Curator + EntiGraph)  → corpus ~7,3M tokens
   │  ② Décontamination vs jeu de test gelé → sous-ensembles 0,5M / 2M / 6M
   ▼
Qwen3-8B-Base ──③ CPT full FT (next-token)──► Qwen3-8B-CPT ──④ SFT (format Q/R)──► CE MODÈLE
   │
   └─ ⑤ Évaluation closed-book (juge Qwen3-32B) : positives + négatives

Fondements scientifiques. Le texte brut ne suffit pas : un fait doit être augmenté sous de nombreuses formes pour devenir extractible (Allen-Zhu & Li, Physics of LM 3.1, arXiv:2309.14316). La précision closed-book croît avec le volume de tokens synthétiques (EntiGraph, arXiv:2409.07431 ; WRAP, arXiv:2401.16380). La connaissance s'injecte au CPT, pas au SFT — qui ne fait qu'apprendre à utiliser (Gekhman et al., arXiv:2405.05904).


2. ① Génération synthétique

Générateur : Qwen3-32B-FP8 servi par vLLM (mode thinking désactivé). Pilotage par les prompts Nemotron-CC de NVIDIA NeMo Curator (conteneur nvcr.io/nvidia/nemo-curator:26.04), traduits en français. Toute génération est 1-hop depuis les 88 faits réels (jamais de synthétique-sur-synthétique → anti model collapse).

Deux familles de documents :

  1. Reformulations multi-styles (par fait) — opérateurs Nemotron-CC : wikipedia-rephrase, distill, extract-knowledge, knowledge-list, diverse-QA. 15 répétitions stochastiques (temp 0,95).
  2. EntiGraph (implémentation d'après arXiv:2409.07431) — passages de synthèse reliant des paires/triplets de faits : 5 chunks × 2 400 groupes, tailles de groupe {2,3,3}. Produit aussi 2 251 questions compositionnelles (multi-faits) filtrées par un juge de cohérence factuelle.

Échantillonnage : temp 0,9–0,95, top_p 0,95. Pool brut ≈ 7,3 M tokens (18 700 documents).

Décontamination & paliers. Suppression de tout document trop proche (embeddings paraphrase-multilingual-MiniLM-L12-v2, cosine ≥ 0,85) d'une question de test held-out (357 retirés). Tokenisation au tokenizer Qwen3-8B, puis sous-ensembles emboîtés : cpt_500kcpt_2Mcpt_6M.


3. ③ CPT — continued pre-training (full fine-tuning)

Next-token prediction sur cpt_6M.jsonl depuis Qwen3-8B-Base.

Paramètre Valeur
Type full fine-tuning (tous les poids)
Précision bf16
Longueur de séquence 2048 (packing)
Époques 3
Learning rate 2e-5, scheduler cosine, warmup 5 %
Optimiseur paged_adamw_8bit (bitsandbytes)
Batch per-device 1 × grad-accum 16 (= 16 séquences/step)
Gradient checkpointing oui · attn_implementation="sdpa" · max_grad_norm 1.0
Replay généraliste aucun (cf. limites)

Le full FT d'un 8 B tient sur 48 Go grâce à paged_adamw_8bit + gradient checkpointing (pic mesuré ≈ 45,5 Go ; PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True).

Sortie : fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT.


4. ④ SFT — restauration du format Q/R

SFT par-dessus le checkpoint CPT, sur MonEspaceSante-SFT-dataset (2 771 paires). Template chat Qwen3 (ChatML), loss masquée sur le prompt (calculée uniquement sur la réponse).

Paramètre Valeur
Type full fine-tuning · bf16 · grad-checkpointing
Époques 3 (voir balayage du nombre d'époques)
Learning rate 1e-5, cosine, warmup 3 %
Optimiseur paged_adamw_8bit · batch 1 × grad-accum 16 · max_len 2048

Note de robustesse : 1 époque de SFT ne suffisait pas à réapprendre la terminaison (<|im_end|>) après le full-FT CPT → le modèle dégénérait. 3 époques corrigent ce point. À l'inférence, ajouter <|im_end|> aux eos_token_id.


5. ⑤ Protocole d'évaluation

Closed-book (aucun contexte). Jeux gelés avant toute génération d'entraînement et décontaminés :

  • Positives : test_heldout (696 = 8 paraphrases inédites × 88 faits) et eval_official (30, split validation d'origine).
  • Négatives : 47 questions hors-périmètre (refus attendu).

Juge : Qwen3-32B-FP8 (LLM-as-judge). Positives → binaire CORRECT/INCORRECT. Négatives → REFUS (bon) vs INVENTION (mauvais). Tous les fichiers + détails : eval-suite.

Étude d'échelle (accuracy held-out, n=696)

Tokens CPT synthétiques Accuracy closed-book
0 (SFT direct, sans CPT) 55,5 %
500 000 66,7 %
2 000 000 78,0 %
6 000 000 (ce modèle) 86,9 %

La précision croît de façon quasi log-linéaire avec le volume de tokens synthétiques — confirmant EntiGraph/WRAP. Le SFT direct (sans CPT) plafonne à 55,5 % : c'est bien le CPT qui injecte la connaissance.


6. Comparaison vs gpt-oss-20b-FAQ-MES

Même protocole, même juge, mêmes questions. Référence : fenyo/gpt-oss-20b-FAQ-MES (openai/gpt-oss-20b, MoE ~20 B, SFT sur la même FAQ).

Modèle Taille Positives held-out (696) Positives officiel (30) Négatives — refus correct (47)
gpt-oss-20b-FAQ-MES MoE 20 B 70,8 % 70,0 % 12,8 %
Qwen3-8B — SFT direct (0 CPT) 8 B 55,5 % 50,0 % 6,4 %
Qwen3-8B — CPT 2M + SFT 8 B 78,0 % 76,7 % 19,1 %
Qwen3-8B — CPT 6M + SFT (ce modèle) 8 B 86,9 % 73,3 % 12,8 %
+ 588 refus (anti-hallucination) 8 B 82,2 % 70,0 % 78,7 %

Conclusion. Sur la couverture factuelle (positives), ce modèle de 8 B dépasse nettement le gpt-oss-20b (86,9 % vs 70,8 %), avec un modèle 2,5× plus petit. Sur les négatives (anti-hallucination), ce modèle factuel-max et gpt-oss sont faibles (≈ 13 % de refus) — mais la variante anti-hallucination (dernière ligne), entraînée avec des exemples de refus, atteint 78,7 % tout en restant plus précise que gpt-oss : elle domine le 20 B sur les deux axes.

Caveats : (i) le jeu de test porte sur les 88 faits de MonEspaceSante-FAQ-QA ; gpt-oss a été entraîné sur fenyo/FAQ-MES (même domaine, couverture possiblement différente) → léger avantage de terrain. (ii) Juge différent de celui du rapport d'origine de gpt-oss → seuls les classements au sein de CE protocole sont comparables.


7. Balayage du nombre d'époques SFT

Pour vérifier que 3 époques est le plafond (held-out, n=696) :

Tokens CPT SFT 3 ép. SFT 6 ép. Δ(6−3)
0 (SFT seul) 55,5 % 62,9 % +7,5
500k 66,7 % 67,1 % +0,4
2M 78,0 % 76,4 % −1,6
6M 86,9 % 84,2 % −2,7

Pour les modèles post-CPT, passer à 6 époques n'aide pas, voire dégrade (sur-apprentissage) → 3 époques suffisent. Seul le SFT-seul gagne à sur-entraîner (il n'a que ce canal pour apprendre), mais reste loin derrière le CPT.


8. Reproduction

Pipeline complet (génération → CPT → SFT → éval). Hyperparamètres = ceux des sections 2–5.

# ① Génération synthétique (conteneur NeMo Curator → vLLM Qwen3-32B-FP8 sur l'hôte)
#    opérateurs Nemotron-CC reps=15 + EntiGraph 5×2400 groupes  → pool ~7,3M tokens
#    puis décontamination + sous-ensembles emboîtés → cpt_6M.jsonl
#    (corpus déjà fourni : dataset MonEspaceSante-CPT-corpus)

# ③ CPT full fine-tuning de Qwen3-8B-Base sur cpt_6M.jsonl
python cpt_train.py --model Qwen/Qwen3-8B-Base --corpus cpt_6M.jsonl --tag 6M \
  --seq-len 2048 --epochs 3 --lr 2e-5 --warmup-ratio 0.05 \
  --bs 1 --grad-accum 16 --optim paged_adamw_8bit
# → models/CPT_6M  (= fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT)

# ④ SFT sur les paires Q/R (loss masquée sur le prompt, template ChatML)
python sft_train.py --base models/CPT_6M --data sft.jsonl --tag 6M \
  --epochs 3 --lr 1e-5 --bs 1 --grad-accum 16 --max-len 2048 --optim paged_adamw_8bit
# → models/SFT_6M  (= CE MODÈLE)

# ⑤ Évaluation closed-book + juge Qwen3-32B (positives + négatives)

Stack : Python 3.x · torch (CUDA) · transformers 5.9 · TRL/Trainer · bitsandbytes 0.49 · vLLM · NeMo Curator (conteneur NGC). 1× L40S 48 Go. Anti-fuite : test gelé avant génération + décontamination par embeddings (cosine ≥ 0,85).


9. Utilisation

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

mid = "fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT"
tok = AutoTokenizer.from_pretrained(mid)
model = AutoModelForCausalLM.from_pretrained(mid, dtype=torch.bfloat16).cuda().eval()

# le tour assistant se termine par <|im_end|> : l'ajouter aux eos
eos = [tok.eos_token_id, tok.convert_tokens_to_ids("<|im_end|>")]
msgs = [{"role": "user", "content": "Où peut-on télécharger l'application Mon espace santé ?"}]
prompt = tok.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True, enable_thinking=False)
enc = tok(prompt, return_tensors="pt", add_special_tokens=False).to("cuda")
out = model.generate(**enc, max_new_tokens=320, do_sample=False, eos_token_id=eos)
print(tok.decode(out[0][enc.input_ids.shape[1]:], skip_special_tokens=True))

Le modèle a été entraîné sans system prompt (questions utilisateur seules).


10. Limites

  • Anti-hallucination faible : sur les questions hors-périmètre, le modèle invente souvent (refus ~13 %). Aucun exemple de refus dans le SFT. Piste : ajouter des négatives au SFT.
  • Pas de replay au CPT : un mélange de 10–30 % de texte FR généraliste réduirait l'oubli catastrophique et lisserait peut-être la courbe (itération future).
  • Domaine étroit : 88 faits d'un service public français précis ; hors de ce périmètre, le modèle conserve surtout le comportement de Qwen3-8B-Base.
  • Éval : eval_official (n=30) est bruité ; la référence est test_heldout (n=696).

Références

EntiGraph — arXiv:2409.07431 · WRAP — arXiv:2401.16380 · Physics of LM 3.1 — arXiv:2309.14316 · Gekhman et al. (hallucinations) — arXiv:2405.05904 · LoRA Learns Less — arXiv:2405.09673.

Downloads last month
8
Safetensors
Model size
8B params
Tensor type
BF16
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT

Finetuned
(2)
this model

Datasets used to train fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT

Papers for fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT