Instructions to use fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT") model = AutoModelForCausalLM.from_pretrained("fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=40) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT
- SGLang
How to use fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT with Docker Model Runner:
docker model run hf.co/fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT
- Qwen3-8B — Mon Espace Santé (CPT + SFT)
- 1. Pipeline (vue d'ensemble)
- 2. ① Génération synthétique
- 3. ③ CPT — continued pre-training (full fine-tuning)
- 4. ④ SFT — restauration du format Q/R
- 5. ⑤ Protocole d'évaluation
- 6. Comparaison vs gpt-oss-20b-FAQ-MES
- 7. Balayage du nombre d'époques SFT
- 8. Reproduction
- 9. Utilisation
- 10. Limites
- Références
- 1. Pipeline (vue d'ensemble)
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 :
- 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).
- 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_500k ⊂ cpt_2M ⊂ cpt_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|>auxeos_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) eteval_official(30, splitvalidationd'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 esttest_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
Model tree for fenyo/L40S-Qwen3-8B-MonEspaceSante-CPT-SFT
Base model
Qwen/Qwen3-8B-Base