Instructions to use fenyo/Qwen2.5-7B-base2instruct with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use fenyo/Qwen2.5-7B-base2instruct with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="fenyo/Qwen2.5-7B-base2instruct") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoTokenizer, AutoModelForMultimodalLM tokenizer = AutoTokenizer.from_pretrained("fenyo/Qwen2.5-7B-base2instruct") model = AutoModelForMultimodalLM.from_pretrained("fenyo/Qwen2.5-7B-base2instruct") 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/Qwen2.5-7B-base2instruct with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "fenyo/Qwen2.5-7B-base2instruct" # 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/Qwen2.5-7B-base2instruct", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/fenyo/Qwen2.5-7B-base2instruct
- SGLang
How to use fenyo/Qwen2.5-7B-base2instruct 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/Qwen2.5-7B-base2instruct" \ --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/Qwen2.5-7B-base2instruct", "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/Qwen2.5-7B-base2instruct" \ --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/Qwen2.5-7B-base2instruct", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use fenyo/Qwen2.5-7B-base2instruct with Docker Model Runner:
docker model run hf.co/fenyo/Qwen2.5-7B-base2instruct
# Load model directly
from transformers import AutoTokenizer, AutoModelForMultimodalLM
tokenizer = AutoTokenizer.from_pretrained("fenyo/Qwen2.5-7B-base2instruct")
model = AutoModelForMultimodalLM.from_pretrained("fenyo/Qwen2.5-7B-base2instruct")
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]:]))- Qwen2.5-7B-base2instruct
- Un cours condensé : transformer un modèle de base en modèle instruct
- 0. L'idée fondamentale : savoir ≠ savoir obéir
- 1. SFT — apprendre le format chat (full fine-tuning)
- 2. DPO — aligner sur des préférences (l'étape décisive)
- 3. RLVR via GRPO — récompense vérifiable (amplifier)
- Les 3 grandes leçons transférables
- Piège d'évaluation à connaître
- Recette & stack
- Datasets utilisés
- Utilisation
- Limites
- Crédits
- 0. L'idée fondamentale : savoir ≠ savoir obéir
Qwen2.5-7B-base2instruct
Modèle conversationnel construit à partir du modèle de base Qwen/Qwen2.5-7B
(non-instruct), via un pipeline SFT → DPO → RLVR entièrement reproduit sur un seul GPU H100 80 Go.
Objectif de l'expérience : reproduire nous-mêmes la transformation base→instruct, la comparer à l'instruct
officiel Qwen/Qwen2.5-7B-Instruct, et en tirer une recette
et des leçons réutilisables.
📦 Code, scripts et recette complète : https://github.com/AlexandreFenyo/qwen2.5-7b-base2instruct
Résultats (lm-evaluation-harness, backend vLLM)
| modèle | IFEval (suivi d'instructions) | GSM8K (maths) | MMLU (connaissances) |
|---|---|---|---|
| base Qwen2.5-7B | 27.4 | 83.0 | 71.8 |
| + SFT (300k) | 51.2 | 77.6 | 69.2 |
| + DPO ciblé | 68.9 | 80.1 | 70.0 |
| + RLVR gradué (ce modèle) | 75.0 | 79.7 | 70.2 |
| instruct officiel | 71.9 | 84.7 | 68.8 |
Ce modèle dépasse l'instruct officiel sur IFEval (75.0 vs 71.9) et MMLU (70.2 vs 68.8), et reste en retrait sur les maths (79.7 vs 84.7). ⚠️ Honnêteté : on a spécialisé le modèle vers le suivi d'instructions (DPO et RLVR tous deux ciblés là-dessus) ; l'officiel est généraliste. On le bat donc sur l'axe optimisé, pas « partout » (chat ouvert, sécurité, code, multi-tours non évalués ici).
Un cours condensé : transformer un modèle de base en modèle instruct
0. L'idée fondamentale : savoir ≠ savoir obéir
Un modèle de base (pré-entraîné sur ~18 000 milliards de tokens) possède déjà la connaissance et le raisonnement. La preuve : avant tout post-training, il fait 83 sur GSM8K et 71.8 sur MMLU. Ce qui lui manque, c'est le comportement d'assistant : répondre à une consigne, en 0-shot, dans un format de chat. Le post-training n'ajoute pas de savoir — il installe un comportement.
C'est visible dans le tableau : le base est fort en MMLU/GSM8K (évalués en few-shot, par complétion de motif, sans obéissance requise) mais faible en IFEval (27.4) — précisément la compétence « obéir à une consigne » qui lui manque. Tout le pipeline sert à combler ce 27 → 75.
1. SFT — apprendre le format chat (full fine-tuning)
- Méthode : Supervised Fine-Tuning. On entraîne le modèle à reproduire des réponses d'assistant au
format ChatML (
<|im_start|>role … <|im_end|>), loss calculée sur la réponse seule (assistant_only_loss). - Données :
allenai/tulu-3-sft-mixture, sous-ensemble de 300k exemples. - Effet : IFEval 27 → 51. C'est le SFT qui « réveille » le comportement d'assistant et la plus grande part du raisonnement latent du base.
- Ce qui a marché : plus de données SFT aide (180k→300k : +6 IFEval vs une version antérieure).
- Ce qui a coincé : instabilité numérique. Le SFT a divergé deux fois (gradient
NaN) à cause d'overflows bf16 du forward sur des échantillons pathologiques (logits →inf). Correctif : un garde-fou qui neutralise les gradients non-finis avant le pas d'optimisation (nan_to_num) → le batch fautif est sauté sans corrompre le modèle. Leçon : sur de longs runs full-FT en bf16, prévoir une protection anti-NaN.
2. DPO — aligner sur des préférences (l'étape décisive)
- Méthode : Direct Preference Optimization. Apprentissage hors-ligne à partir de paires
chosen/rejected: le modèle apprend à préférer la bonne réponse à la mauvaise. Implémenté en LoRA (référence = modèle adaptateur désactivé). - Ce qui a moins marché — DPO générique : avec
ultrafeedback_binarized(préférences générales de qualité), IFEval n'a pas bougé (≈ +0). Le signal « réponse globalement meilleure » ne dit rien sur « réponse qui respecte la consigne ». - Ce qui a été DÉCISIF — DPO ciblé : avec
allenai/tulu-3-pref-personas-instruction-following(~20k paires où la réponse choisie respecte une contrainte et la rejetée la viole) + 10k génériques pour la diversité, IFEval 51 → 69 (+17.7) — quasi le niveau officiel, d'un coup. - Leçon centrale : même algorithme, données génériques vs ciblées → +17.7 d'écart. Pour progresser sur une capacité, il faut des données qui ciblent exactement cette capacité.
3. RLVR via GRPO — récompense vérifiable (amplifier)
- Méthode : Reinforcement Learning with Verifiable Rewards, algorithme GRPO (Group Relative Policy Optimization). Le modèle génère lui-même ~8 réponses par prompt ; un programme vérificateur note chacune ; l'avantage = écart à la moyenne du groupe → renforce les meilleures. En LoRA, génération via transformers (vLLM 0.22 incompatible avec le GRPO de TRL 1.5.1).
- Récompenses vérifiables (sans reward model) :
- maths : réponse correcte (parse
\boxed{},openai/gsm8k) - suivi d'instructions : contraintes vérifiées par programme (24 validateurs maison : minuscules,
nombre de paragraphes, mots-clés, format… inspirés de
allenai/RLVR-IFeval).
- maths : réponse correcte (parse
- Ce qui a échoué — récompense BINAIRE : 1 contrainte/prompt, reward 0/1. Résultat : effondrement de
l'avantage GRPO. Dans un groupe de 8, soit toutes réussissent (contrainte facile), soit toutes échouent
(dure) → écart-type nul → gradient nul (
frac_reward_zero_std → 1.0). IFEval inchangé. - Ce qui a marché — récompense GRADUÉE : prompts à 2-3 contraintes, reward = fraction satisfaite (0 / 0.33 / 0.66 / 1.0) → variance dans le groupe → gradient vivant → IFEval 69 → 75 (+6.1).
- Leçon : le RLVR amplifie une capacité que le modèle sait déjà parfois produire (ici, le DPO l'avait installée) — « installer (DPO/SFT) puis amplifier (GRPO) ». Si le modèle ne sait pas du tout faire, GRPO n'a rien à renforcer (pas de variance).
Les 3 grandes leçons transférables
- Le savoir vient du base ; le post-training installe un comportement. Reproduire une capacité précise est bon marché ; ce qui est cher (pré-entraînement) est hérité gratuitement du base open-weights.
- Le signal doit cibler la capacité visée. Vérifié 3 fois : SFT 180k→300k (+6), DPO générique→ciblé (+17.7), RLVR binaire→gradué (+6). Le générique ne transfère pas.
- Installer puis amplifier. SFT/DPO installent (imitation, hors-ligne) ; GRPO amplifie (exploration, en-ligne). Le RLVR brille surtout là où existe un vérificateur (maths, code, contraintes) et où l'exploration aide (raisonnement) — pas pour des comportements déjà bien couverts par des paires.
Piège d'évaluation à connaître
En GSM8K strict-match, l'instruct officiel tombait à 21 % — pur artefact (il n'émet pas le format
#### N et sa CoT verbeuse dépassait la limite de tokens). Mesuré équitablement (flexible-extract,
1024 tokens) : 84.7 %. Toujours vérifier ce que le parser attend avant de conclure.
Recette & stack
- SFT : full fine-tuning, ChatML,
assistant_only_loss, bf16, SDPA, gradient checkpointing, optimadamw_8bit, lr 4e-6, garde-fou anti-NaN. - DPO : LoRA r=32, β=0.1, lr 5e-6, référence en direct (⚠️
precompute_ref_log_probs=Trueprovoque des NaN en bf16 — à désactiver). - RLVR : GRPO-LoRA r=16, 8 générations/prompt, récompense graduée multi-contraintes, lr 2e-6, 2500 steps.
- Stack : PyTorch cu128 · transformers · TRL 1.5.1 · PEFT · vLLM 0.22 (éval) · lm-eval 0.4.12 · suivi Weights & Biases.
Datasets utilisés
| étape | dataset | rôle |
|---|---|---|
| SFT | allenai/tulu-3-sft-mixture |
format chat + instructions |
| DPO | allenai/tulu-3-pref-personas-instruction-following |
préférences ciblées suivi d'instructions (décisif) |
| DPO | HuggingFaceH4/ultrafeedback_binarized |
préférences génériques (diversité) |
| RLVR | openai/gsm8k |
récompense vérifiable maths |
| RLVR | allenai/RLVR-IFeval |
inspiration contraintes d'instructions |
| Éval | google/IFEval, openai/gsm8k, cais/mmlu |
benchmarks |
Utilisation
from transformers import AutoModelForCausalLM, AutoTokenizer
tok = AutoTokenizer.from_pretrained("fenyo/Qwen2.5-7B-base2instruct")
model = AutoModelForCausalLM.from_pretrained("fenyo/Qwen2.5-7B-base2instruct", torch_dtype="bfloat16", device_map="auto")
msgs = [{"role": "user", "content": "Explique en deux phrases pourquoi le ciel est bleu."}]
inputs = tok.apply_chat_template(msgs, add_generation_prompt=True, return_tensors="pt").to(model.device)
print(tok.decode(model.generate(inputs, max_new_tokens=200)[0][inputs.shape[1]:], skip_special_tokens=True))
Format ChatML, identique à l'instruct officiel.
Limites
Modèle expérimental, spécialisé suivi d'instructions (peut être moins poli que l'officiel en chat ouvert, sécurité, code, multi-tours — non évalués). En retrait sur les maths. Peut halluciner.
Crédits
Base/instruct de référence : Qwen2.5 (Alibaba, Apache-2.0). Données : AllenAI Tülu-3, HuggingFace H4, OpenAI GSM8K. Entraînement : TRL (Hugging Face). Recette & code : github.com/AlexandreFenyo/qwen2.5-7b-base2instruct.
- Downloads last month
- 60
Model tree for fenyo/Qwen2.5-7B-base2instruct
Base model
Qwen/Qwen2.5-7B
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="fenyo/Qwen2.5-7B-base2instruct") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)