Le moteur d'étiquetage
Étiquetez un jeu de données avec des modèles, testez les étiquettes machine sur un échantillon aléatoire d'étiquettes humaines recueillies en aveugle, et livrez le jeu de données avec un certificat de ce qui a été testé.
Le moteur d'étiquetage étiquette un jeu de données avec des modèles et s'appuie sur des personnes pour mesurer à quelle fréquence les modèles se trompent. Vous déclarez dans un contrat ce que les étiquettes finales doivent respecter, par exemple « au plus 5 % des étiquettes machine acceptées sont fausses, avec une confiance de 90 % ». Le moteur demande aux personnes les étiquettes dont il a besoin pour tester cette affirmation, accepte les étiquettes machine que le test justifie et envoie les items restants à des personnes. Il produit le jeu de données accompagné d'un certificat qui consigne ce qui a été testé et sur combien d'étiquettes humaines.
Le moteur est disponible à partir de Potato 2.11. Le serveur d'annotation, la ligne de commande potato label, la REST API, le serveur MCP et un Python SDK le pilotent tous à travers le même fichier engine.sqlite, dans le répertoire de la tâche.
Quand le moteur convient à une étude
Le moteur est rentable quand les personnes ne peuvent pas tout étiqueter et qu'un modèle peut en étiqueter la plus grande partie. Si des personnes étiquetteront de toute façon chaque item, le moteur n'apporte rien, et une stratégie d'attribution ordinaire est le meilleur choix. Trois situations s'y prêtent :
- Vous avez plus d'items que les personnes ne peuvent en étiqueter, et un modèle qui a raison la plupart du temps.
- Vous devez indiquer la qualité des étiquettes, et pas seulement qu'un modèle les a produites, pour un article, la publication d'un jeu de données ou un jeu d'entraînement que quelqu'un d'autre utilisera.
- Vous évaluez un modèle ou un agent avec un juge LLM et devez savoir si le juge peut remplacer des personnes.
De la prédiction du modèle à l'étiquette finale
Le moteur conserve les prédictions machine, les demandes adressées aux personnes et les résultats des contrats dans un même stockage, et chaque item passe par les six mêmes étapes :
- Les sources sont les modèles. Une source peut être un LLM, un modèle vision-langage, un modèle de décision (Laya, Jev ou OpenJev), un détecteur d'objets, un juge LLM, un modèle entraîné sur les propres étiquettes de l'étude, un jury formé d'autres sources, ou des étiquettes que vous avez déjà. Chaque source enregistre une confiance avec chaque prédiction.
- La cascade ordonne les sources. Un item va à la première source, et si le contrat n'accepte pas sa réponse, la source suivante l'essaie. Après la dernière source, l'item va à une personne.
- Les demandes sont ce que le moteur demande aux personnes. Chaque demande enregistre son motif (par exemple calibration, certification, vérification, audit), la probabilité que son item ait été tiré et si la personne pouvait voir une réponse machine. Les demandes de calibration sont tirées au hasard et toujours présentées en aveugle.
- Les contrats testent les étiquettes machine contre les étiquettes humaines de l'échantillon aléatoire. Une moitié de cet échantillon (la partition dev) choisit la règle d'acceptation, et l'autre moitié (la partition cert) la teste. Le statut d'un contrat est
met,insufficient(il faut plus d'étiquettes, avec une estimation du nombre),infeasible,violatedoustale. - La résolution donne à chaque item son étiquette finale. Cette étiquette est une étiquette machine acceptée sous un contrat respecté, l'étiquette d'une personne, ou elle est en attente.
- Le certificat consigne le résultat de chaque contrat, la cascade avec les versions des modèles et des prompts, le nombre d'étiquettes humaines consacrées à chaque motif, la dépense en modèles et une empreinte du journal des appels.
Les règles derrière les garanties
Un contrat respecté est un énoncé statistique sur l'échantillon aléatoire que des personnes ont étiqueté, et il tient grâce à la façon dont cet échantillon est tiré et utilisé. Le moteur applique cinq règles :
- Les demandes en aveugle ne montrent aucune réponse machine. Tant qu'une personne détient une demande de calibration, de certification ou d'audit, le serveur retient toute réponse machine pour cet item. Les pré-annotations, le juge en ligne, l'assistant IA (qui répond
403) et les boutons d'aide IA sont tous désactivés. Une étiquette donnée après avoir vu la réponse de la machine ne constitue pas une vérification indépendante de cette réponse. - Choisir et tester reposent sur des étiquettes différentes. Les seuils sont choisis sur les étiquettes dev et testés sur les étiquettes cert. Chaque nouveau test sur les étiquettes cert se fait à un niveau plus strict, si bien que recertifier jusqu'à ce qu'un test passe ne gonfle pas la confiance.
- Seules les personnes certifient. Les annotateurs machine peuvent participer à l'inférence des étiquettes finales, jamais aux étiquettes contre lesquelles un contrat est testé.
- Un changement rend le certificat périmé. Modifier une source, un prompt, un seuil ou le schéma fait passer chaque contrat concerné à
staleet place ses étiquettes acceptées enpending_recertjusqu'à ce que le contrat soit testé de nouveau. Les étiquettes humaines sont conservées. - Les prédictions machine n'occupent pas de places d'annotateur. Les prédictions du moteur ne comptent pas dans les plafonds d'annotateurs par item.
Le moteur ne vérifie pas que les étiquettes humaines sont justes. Chaque contrat mesure les machines par rapport aux personnes qui ont étiqueté l'échantillon, si bien qu'un contrat testé sur des personnes peu fiables certifie l'accord avec des personnes peu fiables. Utilisez le contrôle de la qualité, le recouvrement (humans.overlap) et le contrat no_worse_than_human pour vérifier aussi les personnes.
Une première étude
Potato fournit trois études d'exemple sous examples/labeling-engine/, une pour le texte, une pour les images et une pour les traces d'agents. Le tableau indique les sources et les contrats de chacune :
| Exemple | Sources | Contrats |
|---|---|---|
text-certified-sentiment/ | Laya (modèle de décision), un LLM Ollama | risque sélectif à 10 %, prévalence PPI |
image-objects-and-people/ | détecteur YOLOv8n, un modèle de vision Ollama | risque sélectif sur les boîtes (IoU) et sur une étiquette de présence de personne |
agent-trace-judge/ | un juge LLM avec permutation de l'ordre des étiquettes | risque sélectif, no-worse-than-human, succès de la tâche par PPI |
L'exemple texte tient en quatre commandes. La première étiquette chaque item avec la cascade et tire le premier échantillon en aveugle, la deuxième sert cet échantillon aux personnes, et les deux dernières testent les contrats et affichent le certificat une fois l'échantillon étiqueté :
potato label run examples/labeling-engine/text-certified-sentiment/config.yaml
potato start examples/labeling-engine/text-certified-sentiment/config.yaml -p 8000
potato label certify examples/labeling-engine/text-certified-sentiment/config.yaml
potato label certificate examples/labeling-engine/text-certified-sentiment/config.yaml --format mdPour ajouter le moteur à votre propre étude, ajoutez ces clés à une configuration qui contient déjà data_files et un schéma d'annotation nommé sentiment. Le contrat demande qu'au plus 10 % des étiquettes machine acceptées soient fausses, avec une confiance de 90 %, et budgets.human_labels plafonne le nombre de demandes humaines que le moteur peut ouvrir :
assignment_strategy: engine
labeling_engine:
enabled: true
sources:
- id: gemma
kind: llm
endpoint_type: vllm
model: google/gemma-4-12B-it-qat-w4a16-ct
base_url: http://localhost:8001/v1
confidence: {method: logprob}
contracts:
- id: accuracy
kind: selective_risk
schema: sentiment
error: 0.1
confidence: 0.9
budgets:
human_labels: 400La source tire sa confiance des log-probabilités des tokens (method: logprob), ce qui demande un appel par item et donne en général la confiance la mieux calibrée des différentes méthodes. Configuration liste toutes les clés, et Contrats indique ce que teste chaque contrat.
Les demandes sur la page d'annotation
Avec assignment_strategy: engine, les annotateurs reçoivent les demandes du moteur, par ordre de priorité décroissante : arbitrage, certification, calibration, annotateurs supplémentaires pour les contrats distributionnels, items qu'aucune machine n'a pu étiqueter, vérification, puis audits. Les demandes de calibration sont servies dans un ordre aléatoire fixe, les demandes dev et cert entremêlées. Une personne reçoit d'un coup toutes les demandes ouvertes sur un item, une par schéma, et jamais deux demandes pour le même schéma sur le même item.
Une courte note au-dessus de l'item indique de quel type de demande il s'agit et, sur une page à plusieurs questions, nomme la question :
- En aveugle. La note indique « Label this one yourself. Suggestions are off for this item. » L'item reste en aveugle pour cette personne après l'enregistrement, au rechargement comme au retour en arrière.
- Vérification. La réponse de la machine est préremplie, et la note invite à la garder si elle est juste et à la modifier sinon. La page enregistre la réponse préremplie, ce qui permet de mesurer à quelle fréquence les personnes l'acceptent. Rien n'est enregistré tant que la personne n'agit pas, de sorte qu'une page restée ouverte ne répond pas à sa place. Les schémas dont la page ne peut pas préremplir les réponses (segments temporels, objets 3D, traces d'agents) sont servis en aveugle à la place.
- Résolution. Aucune étiquette machine n'a pu être acceptée, donc la réponse de la personne devient l'étiquette.
Une demande qu'une personne détient sans y répondre pendant runtime.hold_minutes (60 par défaut) retourne dans le pool et quitte sa page. Une étiquette enregistrée sur un item que le moteur n'a pas servi à cette personne ne clôt jamais la demande de quelqu'un d'autre, et le moteur la conserve comme étiquette organique. Quand une nouvelle certification accepte des étiquettes machine, le moteur annule les demandes de vérification et de résolution ouvertes sur les items désormais couverts. Les demandes qu'une personne détient déjà lui restent, et sa réponse remplace l'étiquette machine.
Le compteur de progression compte les demandes qu'une personne peut encore prendre, pas le corpus. Quand il n'y a encore rien à faire, l'annotateur voit une courte page d'attente et reçoit de nouvelles demandes à mesure que le planificateur les ouvre. Quand plus rien ne viendra, parce que chaque item a une étiquette, que le budget d'étiquettes humaines est épuisé ou que la personne a atteint son propre plafond, sa participation se termine comme d'habitude avec les pages de fin d'étude et, sur une plateforme de crowdsourcing, le code de validation. Personne n'a terminé avant le premier passage du planificateur.
Le Mode poche sert lui aussi les demandes du moteur, un lot complet à la fois, et en redemande avant d'afficher « All caught up ». Le Mode poche n'affiche jamais de réponse machine, donc une demande de vérification servie là est enregistrée en aveugle, sauf si la page de bureau avait déjà montré la réponse à cette personne. Sur les cartes de résolution et d'arbitrage, il affiche la même note que la page de bureau.
La page d'administration
Quand le moteur est activé, le tableau de bord d'administration renvoie vers Labeling engine à /admin/labeling-engine. Chaque graphique de la page a aussi une vue en tableau. La page affiche :
- le statut de chaque contrat, sa couverture, son numéro d'examen et le nombre d'étiquettes qu'il lui faut encore, avec l'énoncé complet qu'il formule (un contrat non respecté énonce sa cible, pas une garantie) ;
- les intervalles de chaque contrat
ppi, à côté des intervalles obtenus avec les seules personnes ; - un avertissement pour toute source dont la dernière exécution a échoué ou dont chaque réponse était une erreur ;
- la courbe erreur-couverture du dernier niveau de la cascade, avec la borne supérieure garantie et la cible ;
- un diagramme de fiabilité par niveau, qui confronte la confiance déclarée à la part de réponses justes sur les étiquettes humaines, avec l'ECE et le score de Brier, les classes peu fournies en étiquettes étant dessinées plus pâles ;
- les audits des étiquettes acceptées, sous forme d'erreurs rapportées à la cible, et l'indication qu'il y a trop peu d'audits pour conclure ;
- les demandes humaines par motif et par statut ;
- le journal des appels aux modèles, du plus récent au plus ancien, avec les tokens, la latence et le coût ; et
- des boutons pour lancer un passage du planificateur, certifier immédiatement et ouvrir le certificat.
Ouverte sans session d'administration, la page renvoie au formulaire de clé du tableau de bord. Avec le moteur désactivé, elle le signale et nomme la clé qui l'active.
Pour aller plus loin
- Contrats du moteur d'étiquetage : les six types de contrats et ce que teste chacun
- Configuration du moteur d'étiquetage : toutes les clés de
labeling_engine - Ligne de commande, REST API, outils MCP et SDK
- Migrer vers le moteur d'étiquetage depuis
icl_labeling,judge_calibrationetpre_annotation - Solo Mode, pour un expert qui travaille avec un LLM
- Pré-annotation par LLM et accord des juges LLM
Pour les détails d'implémentation, consultez la documentation source.