AMbaye018/cawlm-spherical-grpo-7978992
cawlm-spherical-grpo-7978992
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 — Continent seul
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. Chaque flow a un centroïde (moyenne normalisée des embeddings d'exemples de ce flow) — le flow retenu est celui dont le centroïde a la plus grande similarité cosinus avec l'énoncé utilisateur (routage "Continent" uniquement, pas de sous-clustering).
Le routeur n'est pas dans cet adapter — il est recalculé côté client (cf. legacy/scripts/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_spherical_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 :
7978992.
Résultats
Mesurés sur le test set legacy (2 340 conversations, 30 par flow, 78 flows), évalué avec le harnais Continents & Pays (test set legacy, 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-spherical-grpo-7978992")
# pred_flow / slots_hint proviennent du routeur hypersphérique (cf. `legacy/scripts/spherical_router.py`),
# calculé sur l'énoncé utilisateur avant l'appel au LLM.
sys_prompt = (
"Tu es un assistant conversationnel. "
f"Flow suggéré par la sphère hypersphérique : '{pred_flow}'. "
"Extraire le JSON exact avec 'flow' et '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
