Accueil / Articles

Distillation à étiquettes souples pour un agent SQL de 0,8 milliard : pourquoi un enseignant Qwen plus faible a gagné

L’ajustement fin LoRA à l’aide d’étiquettes souples top-k issues de traces figées a permis à un agent SQL de 0,8 milliard de paramètres d’atteindre 55 des 220 tâches, et un modèle enseignant Qwen moins performant a surpassé le modèle GPT plus puissant.

Éditeur : REACTAPP.TOP20 min de lecture4637 mots

Sources: Small-Model Distillation — Part 2: Off-Policy Soft-Label KD for a 0.8B SQL Agent

La version courte

Une tentative précédente a permis à un agent SQL de 0,8 milliard de tokens de passer de 1 tâche résolue sur 220 à 46, en le faisant copier progressivement un token à la fois depuis un modèle « enseignant » plus volumineux. Cette fois, une seule chose change : que se passe-t-il si l’élève perçoit également une partie de l’incertitude de l’enseignant, et non seulement le token qu’il a fini par choisir ? Tout le reste reste inchangé : le système de suivi, l’évaluation sur 220 tâches, le schéma d’action, l’élève de 0,8 milliard de tokens ainsi que la configuration de fine-tuning LoRA. Seul le signal d’apprentissage change.

Les traces de l’enseignant ont été réévaluées. À chaque position, les 20 probabilités de tokens les plus élevées ont été enregistrées, accompagnées d’une petite masse résiduelle représentant tout le reste. Une formation classique à base de tokens pondérés a ensuite été comparée à une distillation à étiquettes souples top-k. La meilleure tentative a permis de résoudre 55 des 220 tâches, contre 46 pour l’élève utilisant des tokens rigides et 49 pour une tentative combinant ces deux approches.

Le chiffre principal n’est pas la partie la plus intéressante. Les étiquettes douces ont aggravé la situation lors de deux des huit essais utilisant une seule source. Le meilleur enseignant n’était pas non plus le plus fort. Qwen, un modèle moins performant de la même famille avec un score de 96/220, a reproduit ses propres traces bien plus fidèlement que le modèle GPT plus puissant (115/220), ce qui a permis à ses probabilités de fournir une leçon plus claire au « élève ». La véritable avantage réside dans le mélange des deux sources.

Il convient de mentionner une réservation dès le début : les probabilités de token propres au GPT n’ont jamais été disponibles. Les traces GPT présentées ici ont été évaluées par Qwen, ce qui en fait un indicateur approximatif et non une véritable distillation des logit du GPT.

Qu’a été testé

Le but général est de rendre les petits modèles plus performants pour des tâches spécifiques. L’agent est le même agent de réparation SQL que précédemment. Il reçoit un problème soulevé par l’utilisateur ainsi que du SQL défectueux, peut examiner une base de données SQLite, exécuter des requêtes de diagnostic, lire les résultats et soumettre du SQL corrigé. L’évaluation se fait à l’aide de tests déterministes cachés, sans intervention d’un modèle de langage grand public.

La tentative précédente avec des tokens fixes avait déjà montré qu’un petit modèle pouvait fonctionner dans ce cycle. Le modèle de base non ajusté se contentait le plus souvent de répéter des actions sans jamais soumettre quoi que ce soit. Après un entraînement par substitution de tokens fixes, il examinait, effectuait des requêtes et soumettait des résultats bien plus fréquemment.

La formation sur des tokens difficiles est un outil rudimentaire. On demande à l’apprenant de reproduire exactement le token écrit par l’enseignant, sans aucune indication sur le degré de certitude de cet enseignant, sur ce qu’il a pris en compte d’autre, ou sur le fait que la deuxième meilleure option soit presque aussi bonne. Pour SQL, ces informations manquantes peuvent être cruciales pour les noms de tables et de colonnes, les prédicats, les jointures, les valeurs littérales ainsi que pour la syntaxe des actions structurées.

La question était donc de savoir si la distillation à étiquettes souples top-k améliorait le même agent de 0,8 milliard de paramètres lorsque les traces et les benchmarks restaient inchangés.

Deux points de départ ont été comparés. Le premier était le modèle de base unsloth/Qwen3.5-0.8B. Le second était l’adaptateur de tokens difficiles Qwen3.5-0,8B, entraîné précédemment à partir de trajectoires réussies issues de Qwen3.5-35B-A3B 8-bit. En d’autres termes : la formation à étiquettes souples devrait-elle commencer à zéro, ou reprendre à partir de l’apprenant utilisant des tokens difficiles ?

La tâche de l’agent SQL

La configuration correspond à l’exécution précédente avec des tokens fixes. Chaque tâche comprend un problème posé par l’utilisateur, une requête défectueuse et une base de données SQLite. Le modèle choisit parmi des actions structurées : examiner le schéma, exécuter une requête SQL ou soumettre une requête SQL finale. Une tâche n’est considérée comme résolue que si la requête SQL soumise passe les tests cachés.

Une tâche typique, petite mais réelle : sur la base de données chinook, l’utilisateur souhaite obtenir le dernier track_id afin de l’utiliser pour filtrer les lignes de la table track. La requête défectueuse est :

WITH vars AS (SELECT COUNT(*) AS vars_id FROM track)
SELECT * FROM track WHERE track_id = vars_id

Le défaut n’a rien à voir avec le formatage. COUNT(*) n’est pas l’identifiant le plus récent, et une correction du type MAX(track_id) est nécessaire. Le modèle doit gérer cela au sein d’une boucle d’outil : il peut examiner le schéma, exécuter une vérification, lire l’observation, puis soumettre une requête SQL dans le format structuré exact accepté par l’outil.

BAML, abréviation de Boundary Markup Language, continue d’encadrer l’instruction en tant que couche de sortie structurée. Elle définit la forme d’une décision et assemble la requête envoyée au modèle. Le texte explicatif libre n’est jamais inclus dans les données d’entraînement de l’étudiant ; ce que celui-ci apprend, ce sont des décisions JSON canoniques composées d’un bref draft et d’une action output exécutable.

{"draft":"Need schema first.","output":{"action":"inspect_schema"}}
{"draft":"Test a candidate query.","output":{"action":"run_sql_query","sql":"SELECT ..."}}
{"draft":"Submit corrected SQL.","output":{"action":"submit_sql","sql":["SELECT ..."]}}

Chaque évaluation a réutilisé les paramètres de l’exécution précédente, de sorte que le signal d’entraînement était la seule chose qui changeait. Deux paramètres méritent une attention particulière. La limite de séquence de 8192 représente le budget total alloué à la fois au prompt et à la génération : le prompt système, la tâche, les actions antérieures, le schéma, les résultats de la recherche, les instructions relatives à la sortie structurée ainsi que la réserve de génération y participent toutes. Le nombre maximal de tokens générés est indiqué séparément, car il limite un seul appel au modèle. L’étudiant peut prendre connaissance d’un état détaillé, mais doit néanmoins émettre une action concise à chaque tour. Les résultats sont rapportés à travers les sorties du terminal et des métriques de comportement telles que les soumissions, les soumissions incorrectes, les erreurs SQL, les arrêts dus à des actions répétées et les arrêts au tour maximal.

Les meilleurs étudiants ne échouent pas principalement sur le JSON. Ils parviennent à appeler submit_sql sans difficulté. La partie difficile réside dans le jugement SQL et dans la capacité à se remettre en selle lorsque les tentatives échouent.

L’idée d’entraînement

La distillation à jeton dur fournit à l’apprenant un seul jeton cible par position. La distillation à étiquette molle, quant à elle, fournit une petite distribution de probabilités. Supposons que la cible de l’enseignant contienne un jeton de tableau comme dans ... FROM users .... L’entraînement à jeton dur indique que le jeton suivant est users. L’entraînement à étiquette molle peut également indiquer quelle probabilité l’enseignant a attribuée à quelques alternatives proches. Le jeton choisi reste pris en compte, mais l’apprenant voit en plus que certaines alternatives étaient plus proches que d’autres.

Stocker les probabilités de tout le vocabulaire est coûteux pour un grand modèle de langage. Un vocabulaire peut contenir des centaines de milliers de jetons, et chaque décision de l’enseignant concerne de nombreuses positions cibles de l’assistant. Le compromis pratique a été une version sparse : les 20 probabilités les plus élevées de l’enseignant par position cible de l’assistant, plus la masse résiduelle pour tous les autres jetons.

Pourquoi conserver la partie restante ? Supposons que les 20 probabilités les plus élevées sauvegardées ajoutent 0,996. Les 0,004 restants appartiennent toujours à la distribution de l’enseignant, et si l’on ramenait ces 20 valeurs à 1,0, cela donnerait à l’élève un objectif trop confiant. Ainsi, l’objectif est délibérément conçu pour rappeler qu’une partie de la masse se trouve en dehors de ce qui a été sauvegardé.

Cette approche reste hors politique. L’élève apprend à partir de traces collectées précédemment et n’agit jamais pendant que l’évaluation a lieu.

Un bref aperçu du code

Le moyen le plus simple de suivre cette méthode consiste à suivre une seule ligne à travers le pipeline. Aucun nouvel environnement d’agent n’a été créé pour les étiquettes souples. Les mêmes décisions réussies de l’enseignant issues de la trajectoire avec des tokens rigides ont été réutilisées, présentées sous la même forme de prompt BAML, puis enrichies d’informations sur les probabilités relatives aux tokens cibles de l’assistant.

Voici une ligne relative à l’ajustement fin supervisé par des tokens fixes (SFT). Le SFT consiste en un entraînement sur des paires entrée-sortie où seuls les tokens de réponse contribuent à la perte :

row = {
    "messages": conversation_before_teacher_decision + [
        {"role": "assistant", "content": canonical_decision_json(teacher_decision)}
    ],
    "teacher_draft": teacher_decision.draft,
    "teacher_action": teacher_decision.output,
}

Une ligne à étiquette souple conserve les mêmes messages canoniques et les métadonnées de l’enseignant, et obtient des scores de tokens imposés par l’enseignant aux positions cibles de l’assistant. Le terme « forcing de l’enseignant » désigne ici la transmission du texte cible connu au modèle de probabilité et la demande, token par token, de savoir quelle est la probabilité que ce texte apparaisse dans son contexte. Ce sont les probabilités logarithmiques qui sont stockées plutôt que les probabilités brutes, car elles sont plus faciles à écrire et à utiliser pour l’entraînement du modèle :

row = {
    "messages": [..., {"role": "assistant", "content": target_decision_json}],
    "distillation": {
        "probability_model": "Qwen3.5-35B-A3B 8-bit",
        "top_k": 20,
        "row_weight": 1.18,
        "token_scores": [
            {
                "position": 1661,              # full-sequence token position
                "target_token_id": 412,
                "target_logprob": -0.21,
                "top_token_ids": [412, 879, 91],
                "top_logprobs": [-0.21, -2.81, -3.51],
                "top_mass": 0.90,
                "tail_mass": 0.10,
            }
        ],
    },
}

Le scoreur a une seule fonction : prendre une ligne figée et y appliquer des probabilités de token. Le scoreur Qwen3.5-35B-A3B 8-bit n’est jamais sollicité pour écrire une nouvelle décision. Le prompt est généré sans la réponse de l’assistant, la séquence complète est générée avec celle-ci, et la partie cible est évaluée token par token :

prompt = chat_template(messages[:-1], add_generation_prompt=True)
full = chat_template(messages, add_generation_prompt=False)
prompt_ids = tokenize(prompt)
full_ids = tokenize(full)
target_ids = full_ids[len(prompt_ids):]
prefill_teacher_cache(prompt_ids[:-1])
driver_ids = [prompt_ids[-1]] + target_ids[:-1]
for i, target_id in enumerate(target_ids):
    logits = qwen_35b(driver_ids[i]).logits
    logprobs = log_softmax(logits)
    top_ids, top_logprobs = top_k(logprobs, k=20)
    save_token_score(
        position=len(prompt_ids) + i,
        target_token_id=target_id,
        target_logprob=logprobs[target_id],
        top_token_ids=top_ids,
        top_logprobs=top_logprobs,
        tail_mass=1.0 - sum(exp(top_logprobs)),
    )

Le masquage réservé uniquement à l’assistant reste inchangé par rapport à l’exécution avec des tokens fixes. Les tokens de prompt constituent le contexte, tandis que les tokens cibles de l’assistant servent de supervision. Cela revêt une importance plus grande pour un agent que pour une simple réponse à des questions, car le prompt contient des observations de schéma, des résultats d’outils précédents ainsi que des résultats SQL. Ces tokens sont là pour servir de base à la prise de décision, et non pour être prédits :

labels = full_ids.copy()
labels[: len(prompt_ids)] = -100
hard_ce = cross_entropy(student_logits, labels)

La formation nécessite également plus de tenseurs que le SFT ordinaire. Un lot contient comme d’habitude input_ids, attention_mask et labels masqués, mais en plus il inclut un poids pour chaque position, les identifiants des tokens du top-k avec leurs probabilités logarithmiques, un masque sur ces k positions, ainsi que les probabilités restantes de la queue. Le padding insère des valeurs neutres dans les positions inactives, de sorte que la perte les ignore sans problème :

batch = {
    "input_ids": pad(input_ids, pad_id),
    "attention_mask": pad(attention_mask, 0),
    "labels": pad(labels, -100),
    "position_weights": pad(position_weights, 0.0),
    "topk_token_ids": pad(topk_token_ids, [0] * top_k),
    "topk_logprobs": pad(topk_logprobs, [0.0] * top_k),
    "topk_mask": pad(topk_mask, [False] * top_k),
    "tail_probs": pad(tail_probs, 0.0),
}

La condition de contrôle est le réglage fin sur des tokens fixes pondérés. Un token choisi reste la cible, mais l’entropie croisée des tokens d’assistant est multipliée par un poids de confiance tiré de la probabilité logarithmique du scoreur pour cette cible. Une cible facile pour le scoreur peut avoir un poids plus élevé, tandis qu’une cible peu probable peut en avoir un plus faible :

z = (mean_target_logprob - dataset_mean_logprob) / dataset_logprob_std
row_weight = clip(2 / (1 + exp(-z)), 0.25, 1.75)
loss = row_weight * hard_ce

Le découpage dans la plage [0.25, 1.75] empêche qu’une seule ligne atypique ne domine un lot, tandis que les lignes fiables peuvent toujours surpasser celles incertaines d’une marge importante.

Dans le cas des étiquettes souples, un terme de correspondance de probabilité est ajouté à la perte. Ce qui suit est un aperçu de sa forme et non le code de production exact :

teacher_top_probs = exp(top_logprobs) * topk_mask
teacher_top_probs *= (1.0 - tail_mass) / sum(teacher_top_probs)
student_logprobs = log_softmax(student_logits_at_target_positions)
student_top_logprobs = gather(student_logprobs, topk_token_ids)
student_tail_prob = 1.0 - sum(exp(student_top_logprobs))
topk_kl = sum(teacher_top_probs * (log(teacher_top_probs) - student_top_logprobs))
tail_kl = tail_mass * (log(tail_mass) - log(student_tail_prob))
loss = hard_ce + topk_kl + tail_kl

Les informations circulent du professeur à l’étudiant : c’est la distribution du professeur que l’étudiant vise, et une pénalité est appliquée lorsqu’elle attribue une probabilité trop faible à cette masse. Dans le simulateur réel, l’entropie croisée et la distillation sont toutes deux calculées uniquement sur des positions cibles de l’assistant décalées.

La formation réelle de l’étudiant reste une fine-tuning LoRA. La LoRA, ou adaptation à faible rang, conserve le modèle de base principalement figé et ajoute de petites matrices d’adaptateur entraînables aux modules d’attention et MLP sélectionnés. Cela permet de comparer facilement de nombreuses exécutions sans devoir fine-tuner entièrement le modèle de 0,8 milliard de paramètres à chaque fois :

student = load_student("unsloth/Qwen3.5-0.8B", max_seq_length=4096)
student = add_lora_adapters(
    student,
    rank=32,
    alpha=32,
    target_modules=[
        "q_proj", "k_proj", "v_proj", "o_proj",
        "gate_proj", "up_proj", "down_proj",
    ],
)
trainer_class = make_trainer_class(Trainer, soft_label_args)
trainer = trainer_class(
    model=student,
    train_dataset=scored_train_examples,
    eval_dataset=scored_validation_examples,
    data_collator=distillation_collator,
    batch_size=1,
    gradient_accumulation_steps=8,
    learning_rate=5e-5,
    epochs=3,
)
trainer.train()
adapter = save_lora_adapter(student)

La mise en œuvre réelle est similaire : make_trainer_class renvoie une sous-classe de Trainer de Hugging Face qui applique la perte sparse top-k ainsi que la perte résiduelle. Notez la différence avec DistillationTrainer en ligne de TRL, où les scores du modèle enseignant sont calculés à l’intérieur du traineur. Les poids des étiquettes souples ont tous été conservés à 1,0 : pour l’entropie croisée stricte, la distillation et la température. La température a été laissée à sa valeur par défaut, car les artefacts dus à la structure sparse étaient déjà fixés à 1,0 et une étude sur l’échellement de la température n’était pas l’objectif.

L’évaluation finale correspond à un déploiement réel et non à une imposition par le modèle enseignant. L’adaptateur entraîné est ensuite intégré au système SQL-agent et doit traiter les 220 tâches non utilisées, en agissant une étape à la fois :

for task in held_out_eval_tasks:
    state = start_sql_agent_task(task)
    for turn in range(8):
        messages = render_baml_messages(state)
        decision = model_with_adapter.generate_action(
            messages,
            max_new_tokens=512,
            temperature=0.0,
        )
        state = execute_action_and_append_observation(state, decision)
        if state.solved or state.stopped:
            break
    results.append(score_final_submission(state))

De nombreuses idées de distillation hors ligne échouent à cette dernière étape. Le test imposé par l’enseignant permet de vérifier si l’élève peut prédire ce que l’enseignant fera ensuite dans un contexte qu’il a lui-même défini. Une mise en œuvre réelle teste si l’élève peut accepter ses propres choix antérieurs, choisir des questions utiles, éviter les répétitions et soumettre du SQL correct. Seul le deuxième chiffre est important ici.

Comment se déroule l’expérience

Il serait facile de considérer cela comme une distillation en temps réel, mais ce n’est pas le cas. Rien de ce que génère l’élève n’est jamais noté. Il n’apprend que par la suite, à partir des traces déjà produites par l’enseignant.

Les données proviennent d’une évaluation basée sur des traces réussies et gelées. Les actions de l’enseignant existent déjà, et le modèle de probabilité se contente de déterminer quelle est la probabilité que chaque token choisi apparaisse dans ce contexte. Il ne prend jamais de décision nouvelle. Les deux ensembles de données évalués ont été conservés séparément (les traces GPT évaluées par Qwen, les traces Qwen évaluées par Qwen) et chacun a été filtré en fonction de la longueur de la séquence entièrement générée, car les observations du schéma ainsi que les résultats des outils précédents font partie de ce que l’étudiant doit assimiler, et non seulement la réponse finale. Limitation : les traces GPT sont considérées comme évaluées par un proxy Qwen et n’ont pas été évaluées à l’aide des probabilités propres à GPT, de plus l’étudiant ne prend jamais d’action pendant l’évaluation.

Trois variantes d’entraînement ont été appliquées aux données évaluées :

  • Ajustement fini par tokens durs pondérés (le contrôle). Un token choisi par position, chaque ligne étant pondérée en fonction de la confiance du juge. Il s’agit d’un SFT avec un réglage de confiance. Différence : ce n’est pas une distillation par étiquettes souples, car l’apprenant voit le poids et jamais la distribution top-k.
  • Distillation par étiquettes souples top-k (la méthode testée). Le même objectif dur associé à un deuxième signal qui demande à l’apprenant de répartir la probabilité sur les top-k alternatives identifiées par le juge, réservant le reste de la masse à tout le reste. Différence : il s’agit d’une approche hors politique d’apprentissage et forçée par un enseignant sur des traces figées, et l’enseignant ne juge jamais les propres échantillons de l’apprenant.
  • Mélange combiné d’enseignants et de sources. Les lignes GPT-proxy et Qwen-self sont combinées, mélangées, puis utilisées pour entraîner le modèle étudiant de base des deux manières. Différence : ce mélange combine les données provenant de différents enseignants au lieu de fusionner leurs distributions en une seule, et chaque ligne conserve le scoreur qui l’a générée.
  • Le mélange des sources donne le résultat le plus propre et le moins déroutant : des traces réussies plus variées ainsi qu’un objectif par token plus riche permettent au petit modèle de base d’apprendre davantage que s’il ne s’appuyait que sur une seule source.

    Ensemble de données et filtrage

    Les traces des enseignants n’ont pas été régénérées intentionnellement. Elles ont été conservées telles quelles depuis l’exécution avec les tokens difficiles, afin que la comparaison porte sur le signal de supervision et non sur une nouvelle génération de données.

    Lors de cette première série d’essais, les deux modèles ont été soumis aux mêmes 879 tâches d’entraînement. GPT 5.5 medium a réussi 446 de ces 879 tâches, ce qui a donné 1046 lignes de données SFT. Qwen3.5-35B-A3B 8-bit a obtenu 394 bonnes réponses, produisant 1232 lignes, car ses trajectoires réussies étaient plus longues. Lors de l’évaluation sur 220 tâches, GPT 5.5 medium s’est montré plus performant, avec 115 réponses contre 96 pour Qwen ; par conséquent, cette comparaison relève d’un test au sein de la même famille de modèles et non de la méthode utilisant le meilleur modèle enseignant.

    La précaution liée aux proxies est importante. Pour obtenir des étiquettes fiables de GPT 5.5 medium, il faudrait disposer des probabilités de tokens propres à ce modèle, ce qui n’était pas le cas. Ainsi, l’expérience avec les trajectoires GPT pose une question plus restreinte : un évaluateur Qwen appartenant à la même famille ajoute-t-il quelque chose d’utile aux choix effectués par GPT ?

    Pour chaque ligne, la requête BAML réellement utilisée par le système a été générée. La cible assistante connue a ensuite été imposée par l’enseignant via Qwen3.5-35B-A3B ; seuls les scores en 8 bits et les scores de tokens ont été enregistrés pour les positions de la cible assistante.

    Avant tout entraînement, deux éléments concernant les données évaluées doivent être vérifiés : quelle partie d’entre elles rentre dans un budget de 4096 tokens, et dans quelle mesure l’évaluateur Qwen est en accord avec chaque source d’empreinte. Une valeur plus faible de la log-verosimilité négative est préférable, car cela signifie que le modèle de probabilité trouve les actions cibles plus faciles à expliquer. C’est pourquoi les données auto-évaluées par Qwen diffèrent tant de celles évaluées par proxy avec GPT : Qwen était bien plus confiant dans ses propres empreintes que dans celles de GPT 5.5 medium. La valeur moyenne de la log-verosimilité négative cible était de 0,297 pour les lignes auto-évaluées par Qwen et de 0,876 pour celles évaluées par proxy avec GPT. Le token cible se trouvait parmi les 20 meilleurs enregistrés dans 100,00 % des positions auto-évaluées par Qwen, et dans 98,56 % des positions évaluées par proxy avec GPT.

    Le jeu de données fusionné comptait initialement 2278 lignes. Après le filtre des 4096 tokens, il en restait 2253, réparties en 2141 pour l’entraînement et 112 pour la validation. Une graine fixe a mélangé les lignes avant la séparation, afin que l’ensemble de validation ne reflète pas l’ordre des sources.

    Configuration de l’entraînement

    Huit essais ont constitué le réseau principal, résultat d’une combinaison complète de trois choix binaires : quelle source de trace (proxy GPT ou Qwen propre), quelle méthode (étiquette pondérée stricte ou souple) et quel point de départ pour l’élève (base ou démarrage progressif avec tokens difficiles). Deux essais supplémentaires, réalisés à partir du modèle de base sur les données combinées, l’un avec des tokens difficiles pondérés et l’autre avec des étiquettes souples, ont permis d’obtenir au total dix élèves entraînés. Les essais de démarrage progressif combinés ont été exclus. Les huit premiers essais ont montré que les démarrages progressifs dépendaient fortement de la source de trace, tandis que les essais combinés visaient à répondre à une question plus simple : avec le modèle de base, le mélange de professeurs est-il utile ?

    Les hyperparamètres d’entraînement suivaient la ligne de référence de trajectoire hard-token. Les adaptateurs utilisaient LoRA avec un rang de 32 et une valeur alpha de 32 pour les projections d’attention (q_proj, k_proj, v_proj, o_proj) ainsi que pour les projections MLP (gate_proj, up_proj, down_proj). Autres paramètres : un taux d’apprentissage de 5e-5, un lot par appareil de 1 avec 8 étapes d’accumulation, trois époches, le format bf16 sur une GPU NVIDIA, Unsloth, et FlashAttention 2 lorsque disponible. Les autres paramètres étaient un ratio de validation de 5 %, l’utilisation de packing off, une valeur de seed de 42, ainsi qu’une limite de 4096 tokens pour les séquences d’entraînement complètes.

    Pour les étiquettes douces, la température était de 1,0, avec des poids de 1,0 tant pour l’entropie croisée stricte que pour la distillation. Le code conserve la masse top-k stockée ainsi que la masse de la queue résiduelle, ce qui constitue une correction numérique simple pour des probabilités qui ont été serialisées de manière sparsaire.

    Les tailles des ensembles d’entraînement n’étaient pas identiques. Les essais GPT proxy-scored ont été entraînés sur 990 lignes, ceux Qwen self-scored sur 1151, et les essais combinés sur 2141. Avec une taille de lot de 1 et 8 étapes d’accumulation, trois époches ont donné respectivement 372, 432 et 804 mises à jour de l’optimiseur. Dans les étiquettes des essais, Base désigne le modèle unsloth/Qwen3.5-0.8B non ajusté, GPT proxy fait référence aux traces provenant de GPT 5.5 medium évaluées par Qwen3.5-35B-A3B 8-bit, Qwen self signifie que les traces du modèle Qwen sont évaluées par lui-même, et Combined correspond aux ensembles d’évaluation combinés avant l’entraînement.

    Faites attention aux pertes de validation. Elles ont un sens au sein d’un objectif unique, mais les exécutions avec étiquettes lourdes pondérées et étiquettes douces ne peuvent pas être comparées entre elles, car leurs pertes comprennent des termes différents. La plus faible perte de validation a été enregistrée par l’exécution lourde pondérée auto-évaluée de Qwen de base, qui n’a résolu que 40/220 problèmes, tandis que le meilleur résultat provient de l’exécution combinée avec étiquettes douces, malgré sa perte plus élevée.

    La préparation et l’entraînement ont eu lieu sur des matériel différents. Une machine à forte mémoire était pratique pour charger et évaluer localement Qwen3.5-35B-A3B en 8 bits, bien que l’évaluation forcée par un enseignant ait nécessité environ 60 minutes pour les traces GPT et 41 minutes pour celles de Qwen. Les étudiants ont entraîné sur des GPU NVIDIA. Ces exécutions à source unique, dont la durée était enregistrée, ont duré environ 23 à 30 minutes chacune, tandis que les exécutions combinées plus volumineuses ont nécessité environ 52 minutes (étiquettes lourdes pondérées) et 55 minutes (étiquettes douces).

    Résultats, organisés par question

    Un premier graphique tentait de montrer tout en même temps et confondait deux questions distinctes : ce qui se passe lorsque l’entraînement commence à partir du modèle de base, et ce qui se passe lorsqu’il continue à partir du modèle de trajectoire de tokens difficiles. Les résultats ont donc été séparés par question de recherche.

    À titre de référence, les enseignants et références utilisés dans l’évaluation sur les 220 tâches fixes étaient : pas de fine-tuning 1/220, l’élève avec tokens difficiles 46/220, Qwen en tant qu’enseignant 96/220 et GPT en tant qu’enseignant 115/220. L’objectif de l’expérience avec les étiquettes souples top-k n’était jamais de surpasser les enseignants. Il s’agissait plutôt de voir si un signal de supervision plus riche pouvait faire progresser davantage l’élève de 0,8 milliard de paramètres dans les mêmes conditions.

    En partant du modèle de base. Tous les essais d’entraînement surpassent le modèle non ajusté qui obtient 1/220. L’entraînement uniquement avec GPT ou uniquement avec Qwen donne des résultats proches, avec 41 à 43 tâches résolues selon la méthode utilisée. La combinaison des deux sources crée une différence plus marquée : l’approche combinée utilisant des tokens durs pondérés atteint 49/220, tandis que l’approche combinée utilisant des étiquettes souples top-k atteint 55/220, soit environ un quart des tâches. Ces résultats sont modestes en termes absolus et loin des 115/220 du meilleur modèle de référence, mais l’intérêt réside dans la capacité d’un modèle de 0,8 milliard de paramètres à progresser de presque zéro, plutôt que dans sa capacité à égaler le modèle de référence. Pour un départ avec un modèle de base, la conclusion est de s’appuyer sur les deux modèles de référence, les étiquettes souples étant supérieures aux tokens durs pondérés sur ces données combinées.

    En poursuivant avec l’étudiant utilisant des tokens durs. Ici, la situation est moins claire. Le point de contrôle avait déjà résolu 46/220. Un entraînement supplémentaire sur des traces GPT utilisant des tokens durs pondérés l’a amené à 48/220, tandis que des étiquettes douces appliquées aux mêmes traces l’ont fait redescendre à 44/220. Sur les traces auto-évaluées par Qwen, le schéma s’est inversé : les tokens durs pondérés sont passés à 38/220, et les étiquettes douces sont montées à 49/220.

    La découverte inattendue : les étiquettes douces n’étaient utiles que lorsque l’évaluateur et la trace étaient en accord. Qwen3.5-35B-A3B 8-bit s’est avéré être l’enseignant le moins performant avec 96/220, contre 115/220 pour GPT ; cependant, ses probabilités correspondaient bien à ses propres traces, et les étiquettes douces fonctionnaient dans ce cas (49/220), tandis qu’elles nuisaient aux traces GPT évaluées de manière indirecte (44/220). L’accord entre les données primait sur la force intrinsèque de l’enseignant.

    Qu’ils a changé dans la boucle de l’agent. Le modèle de base ne soumettait presque jamais de réponses. L’entraînement par trajectoires à jetons fixes lui a appris à entrer dans la boucle et à soumettre des réponses, mais beaucoup de ces soumissions étaient incorrectes. La séance d’entraînement combinée avec des étiquettes souples a de nouveau amélioré les résultats, ce qui en fait la meilleure séance globalement. Néanmoins, l’agent a soumis 171 tâches et en a résolu 55, ce qui signifie que 116 requêtes soumises ont échoué aux tests cachés, et il y a eu encore 39 arrêts dus à des actions répétées.

    Telle est la réalité honnête des résultats. Le modèle échoue principalement non pas parce qu’il ne peut pas générer des actions BAML valides, mais parce qu’il prend encore de mauvaises décisions en matière de SQL et qu’il se retrouve parfois bloqué dans la boucle.

    Le signal de comportement le plus fiable était le nombre de tours. La moyenne des essais avec étiquettes douces combinées était de 3,39 tours, contre 3,48 pour le démarrage à chaud avec tokens rigides ; la différence est suffisamment faible pour que des étapes supplémentaires ne puissent expliquer l’amélioration. Une combinaison d’actions légèrement meilleure y parvient : plus de soumissions correctes que lors du démarrage à chaud, moins d’erreurs que lors des essais combinés avec tokens rigides pondérés, ainsi que moins d’erreurs SQL et moins d’arrêts en raison de la limite de tours. Le nombre de tokens générés par appel d’évaluation n’a pas été enregistré, ce qui explique l’absence de chiffres concernant les tokens de sortie. Les données que l’on peut rapporter avec certitude proviennent de l’entraînement : le nombre de tokens d’entrée et de sortie, la longueur totale de la séquence et le taux de couverture top-k.

    Remarque concernant la lecture des tableaux derrière les graphiques : « submitted » englobe à la fois les soumissions correctes et incorrectes, et « wrong submits » correspond à « submitted » moins le nombre de réussites. La colonne « SQL-error tasks » n’est pas exclusive ; une tâche y figure si l’une de ses requêtes SQL a généré une erreur au cours de la boucle, ce qui peut coïncider avec n’importe quel résultat final.

    Analyse des échecs

    Si l’on se base uniquement sur l’exécution combinée du modèle de base, le résultat paraîtrait trop simple : des enseignants de niveaux différents associés à des étiquettes douces, et c’est tout. Les vues séparées ne sont pas aussi claires. Ce qui est surprenant, c’est qu’un enseignant moins performant ait donné de meilleurs résultats qu’un enseignant plus performant, car ses probabilités correspondaient à ses propres traces. Les étiquettes douces ont obtenu les meilleurs résultats sur les chemins Qwen de même famille, et de manière évidente lorsque les sources ont été combinées. Elles ont obtenu de moins bons résultats sur les traces GPT que Qwen n’avait évaluées qu’indirectement, et elles ont nui à la cellule de démarrage rapide GPT.

    Cela est plausible : les probabilités 8 bits de Qwen3.5-35B-A3B décrivent bien les actions 8 bits de ce modèle, ce qui permet à l’étudiant Qwen de 0,8B de disposer d’un signal plus clair à imiter.

    Le mécanisme de déploiement conserve le dernier mot. La question posée par l’enseignant est de savoir si l’étudiant peut deviner la prochaine action de l’enseignant lorsque le contexte est similaire au sien. Le système de test demande quelque chose de plus difficile : peut-il se remettre de ses propres mouvements précédents, choisir des tests pertinents, éviter les boucles et produire un SQL correct en fin de processus ? Les deux sont liés, mais ils ne sont pas identiques.

    La perte de validation raconte la même histoire sous un angle différent. Avec un ratio de 55/220, l’exécution combinée à étiquettes souples a présenté une perte de validation de 0,5684, supérieure à 0,3478 obtenue par l’exécution combinée à tokens fermes, qui a résolu 49 problèmes. La plus faible perte, à 0,2544, a été enregistrée par l’exécution basique de Qwen à tokens fermes auto-évalués, qui n’a résolu que 40 problèmes sur 220. Une faible perte due à l’intervention du formateur ne signifie pas nécessairement un agent de meilleure qualité.

    Le résultat obtenu avec l’approche combinée au formateur est le plus instructif. Les traces GPT ont incité l’agent étudiant à soumettre des réponses plus fréquemment. Les traces Qwen étaient plus faciles à évaluer et appartenaient à la même famille, mais elles ont entraîné davantage de boucles. L’exécution mixte à étiquettes souples n’a pas simplement combiné les meilleurs aspects des deux approches, et les arrêts dus à des boucles se sont poursuivis. Néanmoins, son nombre de réussites était le plus élevé, et par rapport à l’exécution mixte à tokens fermes, elle a rencontré moins d’erreurs d’exécution SQL et a terminé moins d’épisodes au-delà de la limite de tours.

    Le contrôle à pondération élevée avait sa propre leçon à enseigner. Pondérer les lignes en fonction de la confiance du scoreur est moins coûteux que d’appliquer des distributions de probabilité sparses, et sur les données de démarrage pré-évaluées par GPT, il a produit la meilleure cellule. Ce qu’il ne peut pas faire, c’est informer l’apprenant sur les alternatives voisines à chaque position ; il indique simplement « copier ce token de manière plus ou moins stricte ». Les étiquettes souples top-k conviennent aux cas où le scoreur correspond à la source d’origine et où la diversité des données est suffisante pour que l’apprenant ne surajuste pas au style d’un seul enseignant.

    Leçons sur le matériel

    Deux types de machines étaient nécessaires. Pour l’évaluation, il fallait conserver Qwen3.5-35B-A3B en 8 bits en mémoire et le faire fonctionner sur des cibles figées, ce qui rendait logique l’utilisation d’un Mac doté de 128 GB de mémoire unifiée, capable de stocker l’enseignant quantifié. Il n’était pas rapide, mais il permettait de réaliser toutes les préparations localement avant d’utiliser du temps GPU payant.

    La formation visait l’inverse. Le fine-tuning avec LoRA repose fortement sur des matrices, avec des passes avant et arrière, des noyaux d’attention et des étapes d’optimiseur ; la GPU NVIDIA était bien plus rapide malgré moins de mémoire totale, car ces tenseurs restaient dans la VRAM et étaient traités par des noyaux CUDA. La leçon récurrente est que la capacité et le débit sont deux problèmes distincts. Une grande quantité de RAM système permet de stocker et de préparer les données, tandis que la VRAM de la GPU combinée à CUDA permet de les entraîner rapidement. Le flux de travail a fini par consister à effectuer tout ce qui est possible sur le Mac et à démarrer la GPU à distance uniquement une fois que les données et les scripts étaient prêts.

    Leçons apprises

    La distillation à étiquettes souples mérite d’être essayée pour le fine-tuning d’agents, à condition d’évaluer ses résultats par des mises en œuvre réelles. L’incertitude au niveau des tokens contient plus d’informations que les tokens « durs », mais il s’agit toujours d’une supervision locale qui ne suffit pas à elle seule pour apprendre à un modèle à se remettre d’une mauvaise appel d’outil, à éviter les boucles ou à interroger plus efficacement lors de l’arrivée de nouvelles observations.

    Les étiquettes souples proxy doivent être définies de manière honnête. Les valeurs affichées pour GPT ne correspondent pas aux probabilités propres de GPT, mais à des valeurs évaluées avec le score Qwen. Il s’agit néanmoins d’une expérience utile, même si ce n’est pas une véritable distillation de logit de GPT.

    Un enseignant appartenant à la même famille peut surpasser un enseignant plus puissant. La qualité avec laquelle le scoreur correspondait au comportement réel comptait davantage que son score d’évaluation lui-même.

    Le top-k sparsifié avec une queue est un compromis praticable. Enregistrer les logits de tout le vocabulaire serait plus complet, mais cela nécessite beaucoup d’espace de stockage, de ressources pour le transfert et l’entraînement. Vingt tokens accompagnés d’une queue résiduelle suffisamment préservée permettent au token cible de rester visible presque partout.

    Mélanger plusieurs sources d’entraînement est préférable à le choix d’une seule source. Le meilleur résultat a été obtenu en combinant les lignes évaluées par GPT 5.5 medium avec celles évaluées par Qwen, puis en entraînant le modèle de base à l’aide d’étiquettes douces.

    Ce que cela laisse en suspens

    Alors, cela aide-t-il ? Oui, dans certaines conditions. Dans la meilleure configuration, la distillation par étiquettes douces top-k a amélioré les performances de l’agent SQL de 0,8 milliard de paramètres : les lignes évaluées par GPT combinées à celles évaluées par Qwen, alimentées au modèle de base unsloth/Qwen3.5-0,8B, ont permis de résoudre 55 problèmes sur 220, ce qui est nettement supérieur aux résultats obtenus avec la méthode basée sur des tokens rigides hors politique (46/220) ainsi qu’avec la méthode combinant tokens rigides (49/220).

    Ne comprenez pas cela comme si « les étiquettes douces l’emportaient toujours ». La source enseignante, l’initialisation de l’élève, l’alignement des probabilités et le comportement de déploiement étaient tous importants, et l’enseignante qui a fini par l’emporter n’était pas celle ayant la meilleure note d’évaluation. Ce qui continue de poser problème concerne l’aspect agentique : requêtes SQL incorrectes, actions répétées et capacité de récupération imparfaite au sein du boucle.

    C’est précisément pour cette raison que le benchmark mérite d’être conservé. Un élève peut sembler performant sous la contrainte de l’enseignante mais trébucher dès qu’il doit agir par lui-même. Toute étude complémentaire devrait maintenir les paramètres constants et vérifier si une nouvelle idée de formation améliore réellement le fonctionnement du boucle, et non seulement la perte hors ligne.

    Lectures complémentaires