AMbaye018/cawlm-continents-pays-grpo-v3-7996251
cawlm-continents-pays-grpo-v3-7996251
Adaptateur LoRA (Qwen/Qwen3-0.6B) pour le Dialogue Manager de CAWLM (Conversational AI with Wolof Language Model — Orange Innovation) : à partir d'un tour de conversation en wolof/français (code-switching), le modèle décide quel flow déclencher parmi un catalogue de 78 intents (18 domaines : santé, agriculture, éducation, fintech, administration, foncier, urgences...) et extrait les slots associés, sous forme JSON {"flow": ..., "slots": {...}}.
This is a LoRA adapter fine-tuned with GRPO for a Wolof/French task-oriented dialogue manager (intent/flow classification + slot extraction), guided at both train and inference time by a hypersphere-based semantic router. See "Utilisation" below for the exact prompt format expected.
Méthode de routage : Routeur hypersphérique hiérarchique — Continents & Pays
CAWLM combine un LLM (ce modèle) avec un routeur sémantique sur l'hypersphère S^(d-1) : les énoncés utilisateurs et les flows sont encodés avec BAAI/bge-m3 puis normalisés en norme L2, et la similarité cosinus devient un simple produit scalaire. Deux niveaux hiérarchiques : un Continent par flow (centroïde global, macro-routage) et, à l'intérieur de chaque Continent, des Pays = micro-clusters regroupant les conversations qui partagent la même signature de slots (le tuple trié des clés de slots présentes). Le Pays le plus proche fournit un exemple de valeurs de slots typiques, injecté dans le prompt pour guider l'extraction (réduit les hallucinations de valeurs).
Le routeur n'est pas dans cet adapter — il est recalculé côté client (cf. legacy/scripts/hierarchical_spherical_router.py dans le dépôt CAWLM interne d'Orange Innovation, non public) et son résultat est injecté dans le system prompt à l'entraînement et à l'inférence (le modèle a été entraîné à s'appuyer sur cet indice, cf. "Utilisation").
Entraînement
- Algorithme : GRPO (Group Relative Policy Optimization, TRL), LoRA r=16, alpha=32, dropout=0.05,
target_modules=["q_proj","v_proj","k_proj","o_proj"]. - Récompense (
legacy/scripts/grpo_continents_pays_train.py) :0.1 × JSON valide + 0.1 × Flow Accuracy + 0.8 × Slot F1— le poids fort sur le Slot F1 vise spécifiquement à supprimer les hallucinations de valeurs de slots. - Dataset : split legacy CAWLM (
legacy/datasets/train/train.jsonl), 78 flows / 18 domaines, conversations wolof à dominante avec code-switching français. - Job SLURM :
7996251.
Résultats
Mesurés sur le test set legacy (2 340 conversations, 30 par flow, 78 flows), cf. `docs/etat_jobs_resultats.md` :
⚠️ Ces scores sont obtenus avec l'indice du routeur injecté dans le prompt à l'évaluation, exactement comme à l'entraînement (voir le prompt reconstruit ci-dessous) — ils mesurent la paire (routeur + LLM), pas la capacité du LLM seul sans aucun contexte.
Comparaison avec les autres adapters CAWLM "sphériques" publiés
Utilisation
L'adapter attend un system prompt enrichi par le routeur, pas seulement la question brute. Reconstruire le hint côté client (le routeur n'étant pas embarqué dans cet adapter) :
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel
base_id = "Qwen/Qwen3-0.6B"
tok = AutoTokenizer.from_pretrained(base_id)
model = AutoModelForCausalLM.from_pretrained(base_id, torch_dtype=torch.bfloat16, device_map="auto")
model = PeftModel.from_pretrained(model, "AMbaye018/cawlm-continents-pays-grpo-v3-7996251")
# pred_flow / slots_hint proviennent du routeur hypersphérique (cf. `legacy/scripts/hierarchical_spherical_router.py`),
# calculé sur l'énoncé utilisateur avant l'appel au LLM.
sys_prompt = (
"Tu es un assistant conversationnel expert en extraction de donnees. "
f"Flow detecte : '{pred_flow}'. "
f"Slots attendus pour ce flow (exemples de valeurs typiques) : {{{slots_hint}}}. "
"Extraire EXACTEMENT ces slots dans le JSON avec les vraies valeurs de la conversation. "
"Repondre uniquement avec : {\"flow\": ..., \"slots\": {...}}"
)
messages = [
{"role": "system", "content": sys_prompt},
{"role": "user", "content": "Bind naa yebal xaalis bu 25000 CFA ci sama euleuy Aida"},
]
prompt = tok.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
inputs = tok(prompt, return_tensors="pt").to(model.device)
out = model.generate(**inputs, max_new_tokens=200, do_sample=False)
print(tok.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True))
# -> {"flow": "send_money", "slots": {"AMOUNT": "25000", "RECEIVER": "Aida"}}Limites
- Format de sortie JSON brut
{"flow":..., "slots":{...}}, pas le format natif<tool_call>{...}</tool_call>des LLM récents — ce projet a depuis migré vers un nouveau pipeline "agentic" en tool-calling natif (18 domaines / 79 flows), qui remplace celui-ci. - Nécessite le hint du routeur hypersphérique pour reproduire les scores ci-dessus ; sans lui, la précision chute significativement (mesuré directement sur ce projet).
- Entraîné et évalué sur des données synthétiques/semi-synthétiques en wolof avec code-switching français ; pas de garantie de généralisation à d'autres registres de langue.
Citations
Entraîné avec TRL (GRPOTrainer).
@article{shao2024deepseekmath,
title = {{DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models}},
author = {Zhihong Shao and Peiyi Wang and Qihao Zhu and Runxin Xu and Junxiao Song and Mingchuan Zhang and Y. K. Li and Y. Wu and Daya Guo},
year = 2024,
eprint = {arXiv:2402.03300},
}@software{vonwerra2020trl,
title = {{TRL: Transformers Reinforcement Learning}},
author = {von Werra, Leandro and Belkada, Younes and Tunstall, Lewis and Beeching, Edward and Thrush, Tristan and Lambert, Nathan and Huang, Shengyi and Rasul, Kashif and Gallouédec, Quentin},
license = {Apache-2.0},
url = {https://github.com/huggingface/trl},
year = {2020}
}Framework versions
- PEFT 0.19.1 · TRL 1.5.1 · Transformers 5.9.0 · PyTorch 2.10.0 · Datasets 4.8.4 · Tokenizers 0.22.2
