Solo Mode : Comment un seul annotateur peut étiqueter 10 000 exemples
Tutoriel étape par étape sur l'utilisation du Solo Mode de Potato pour étiqueter efficacement de grands ensembles de données grâce à la collaboration humain-LLM, réduisant les coûts d'annotation jusqu'à 90%.
Solo Mode : Comment un seul annotateur peut étiqueter 10 000 exemples
Vous avez 10 000 avis de produits à étiqueter pour le sentiment (Positif, Neutre, Négatif). Engager trois annotateurs pour tout étiqueter prendrait des semaines et coûterait des milliers de dollars. Avec le Solo Mode, un seul expert du domaine peut atteindre une qualité comparable en n'étiquetant que 500 à 1 000 instances tandis qu'un LLM gère le reste -- l'humain ne révisant que les cas où le LLM a des difficultés.
Ce tutoriel vous guide à travers l'ensemble du processus de bout en bout.
Ce dont vous aurez besoin
- Potato 2.3.0+ avec les extras Solo Mode :
pip install potato-annotation[solo] - Une clé API OpenAI ou Anthropic (pour le composant LLM)
- Votre ensemble de données au format JSONL
- Un annotateur compétent (ce pourrait être vous)
Étape 1 : Préparer vos données
Créez data/reviews.jsonl avec un avis par ligne :
{"id": "rev_001", "text": "Absolutely love this product! Best purchase I've made all year.", "source": "amazon"}
{"id": "rev_002", "text": "It works fine. Nothing special but gets the job done.", "source": "amazon"}
{"id": "rev_003", "text": "Broke after two weeks. Complete waste of money.", "source": "amazon"}
{"id": "rev_004", "text": "The quality is decent for the price point. I might buy again.", "source": "amazon"}
{"id": "rev_005", "text": "Arrived damaged and customer service was unhelpful.", "source": "amazon"}Pour ce tutoriel, imaginez que ce fichier contient 10 000 avis.
Étape 2 : Créer la configuration
Créez config.yaml :
task_name: "Product Review Sentiment (Solo Mode)"
task_dir: "."
data_files:
- "data/reviews.jsonl"
item_properties:
id_key: id
text_key: text
# --- Solo Mode Configuration ---
solo_mode:
enabled: true
llm:
endpoint_type: openai
model: "gpt-4o"
api_key: ${OPENAI_API_KEY}
temperature: 0.1
max_tokens: 64
# Quality targets
seed_count: 50
accuracy_threshold: 0.93
confidence_threshold: 0.85
# Phase-specific settings
phases:
seed:
count: 50
selection: diversity
embedding_model: "all-MiniLM-L6-v2"
calibration:
batch_size: 200
holdout_fraction: 0.2
labeling_functions:
enabled: true
max_functions: 15
min_precision: 0.92
min_coverage: 0.01
active_labeling:
batch_size: 25
strategy: hybrid
max_batches: 15
refinement_loop:
max_iterations: 3
improvement_threshold: 0.02
disagreement_exploration:
max_instances: 150
show_llm_reasoning: true
show_nearest_neighbors: 3
edge_case_synthesis:
enabled: true
count: 30
confidence_escalation:
escalation_budget: 150
batch_size: 25
stop_when_stable: true
prompt_optimization:
enabled: true
candidates: 8
metric: f1_macro
final_validation:
sample_size: 100
min_accuracy: 0.93
# Instance prioritization
prioritization:
pools:
- name: uncertain
weight: 0.30
- name: disagreement
weight: 0.25
- name: boundary
weight: 0.20
- name: novel
weight: 0.10
- name: error_pattern
weight: 0.10
- name: random
weight: 0.05
# --- Annotation Schema ---
annotation_schemes:
- annotation_type: radio
name: sentiment
description: "What is the overall sentiment of this review?"
labels:
- "Positive"
- "Neutral"
- "Negative"
label_requirement:
required: true
sequential_key_binding: true
output_annotation_dir: "output/"
output_annotation_format: "jsonl"
parquet_export:
enabled: true
output_dir: "output/parquet/"Étape 3 : Démarrer le serveur
potato start config.yaml -p 8000Ouvrez http://localhost:8000 et connectez-vous. Le tableau de bord Solo Mode apparaîtra, indiquant que vous êtes en Phase 1 : Annotation initiale.
Étape 4 : Phase 1 -- Annotation initiale (50 instances)
Potato a sélectionné 50 avis diversifiés en utilisant un clustering basé sur les embeddings. Ce ne sont pas des avis aléatoires ; ils sont choisis pour maximiser la couverture de la distribution de vos données.
Étiquetez chacun d'eux. C'est la phase la plus importante -- la qualité de vos étiquettes initiales détermine dans quelle mesure le LLM apprendra. Prenez votre temps et soyez cohérent.
Estimation de temps : 15-25 minutes à 20-30 secondes par instance.
Lorsque vous terminez la 50e instance, Potato passe automatiquement à la Phase 2.
Étape 5 : Phase 2 -- Calibration initiale du LLM
Cette phase s'exécute automatiquement. Potato envoie au LLM un lot de 200 instances avec vos 50 étiquettes initiales comme exemples few-shot. Il compare ensuite les prédictions du LLM à 10 étiquettes initiales de validation pour estimer la précision de base.
Vous verrez un indicateur de progression dans le tableau de bord. Cela prend généralement 1 à 2 minutes selon le fournisseur LLM.
Résultat typique : Le LLM atteint 75-85% de précision à la première calibration. C'est attendu -- le LLM n'a pas encore appris votre style d'annotation spécifique.
Étape 6 : Phase 3 -- Analyse de confusion
Potato affiche une matrice de confusion montrant où le LLM est en désaccord avec vos étiquettes. Un résultat typique :
Confusion Analysis (Round 1)
============================
Overall Accuracy: 0.82 (target: 0.93)
Top Confusion Pairs:
Neutral -> Positive: 14 instances (7.0%)
Negative -> Neutral: 9 instances (4.5%)
Positive -> Neutral: 4 instances (2.0%)
Cela vous indique la principale faiblesse du LLM : il a tendance à surclasser les avis neutres en positifs. C'est courant -- les LLM ont souvent un biais vers le sentiment positif.
Votre action : Examinez les paires de confusion. Cliquez sur chaque paire pour voir les instances spécifiques que le LLM a mal classées. Cela vous aide à comprendre les modes de défaillance du LLM.
Étape 7 : Phase 4 -- Affinement des directives
Sur la base de l'analyse de confusion, Potato génère des directives affinées pour le LLM. Vous voyez une vue côte à côte :
- Directives actuelles : le prompt initial utilisé pour le LLM
- Modifications suggérées : des changements spécifiques que le LLM propose basés sur les schémas d'erreurs
Par exemple, Potato pourrait suggérer d'ajouter :
"Les avis qui décrivent un produit comme 'correct', 'ok' ou 'décent' sans émotion forte doivent être étiquetés Neutre, même s'ils mentionnent racheter."
Examinez chaque modification suggérée. Approuvez, modifiez ou rejetez chacune. Vous pouvez aussi ajouter vos propres clarifications.
Estimation de temps : 5-10 minutes.
Étape 8 : Phase 5 -- Génération de fonctions d'étiquetage
Potato génère des fonctions d'étiquetage programmatiques à partir des schémas dans vos étiquettes initiales. Ce sont des règles rapides et déterministes qui gèrent les cas faciles :
Generated Labeling Functions:
LF1: Strong positive words (love, amazing, best, excellent)
Precision: 0.97, Coverage: 0.06
LF2: Strong negative words (terrible, awful, worst, waste)
Precision: 0.95, Coverage: 0.04
LF3: Exclamation + positive adjective
Precision: 0.94, Coverage: 0.03
LF4: Return/refund mention + negative context
Precision: 0.92, Coverage: 0.02
...
Total coverage: 0.18 (1,800 of 10,000 instances)
Les fonctions d'étiquetage couvrent 18% de votre ensemble de données avec une précision de 92%+. Ces instances sont étiquetées automatiquement, libérant l'effort du LLM et de l'humain pour les cas plus difficiles.
Votre action : Examinez les fonctions générées. Désactivez celles qui semblent peu fiables. C'est optionnel -- Potato ne garde que les fonctions au-dessus de votre seuil de précision configuré.
Étape 9 : Phase 6 -- Étiquetage actif (125-375 instances)
C'est la phase principale d'étiquetage humain. Potato sélectionne les instances en utilisant le système de priorisation à six pools :
- Incertain (30%) : avis où la confiance du LLM est inférieure à 85%
- Désaccord (25%) : avis où le LLM et les fonctions d'étiquetage donnent des étiquettes différentes
- Frontière (20%) : avis proches de la frontière de décision dans l'espace des embeddings
- Nouveau (10%) : avis différents de tout ce que vous avez étiqueté jusqu'ici
- Schéma d'erreur (10%) : avis correspondant à des schémas de confusion connus (par ex. positif tiède)
- Aléatoire (5%) : avis aléatoires pour la calibration
Vous étiquetez par lots de 25. Après chaque lot, Potato met à jour l'estimation de précision du LLM et décide de continuer ou non.
Trajectoire typique :
- Lots 1-3 (75 instances) : la précision passe de 82% à 87%
- Lots 4-6 (150 instances) : la précision atteint 90%
- Lots 7-10 (250 instances) : la précision plafonne à 91-92%
Si la précision atteint 93% (votre seuil), le Solo Mode saute directement à la Phase 10. Sinon, il continue à la Phase 7.
Estimation de temps : 45-90 minutes au total, selon le nombre de lots nécessaires.
Étape 10 : Phase 7 -- Boucle de raffinement automatisée
Si la précision est toujours en dessous du seuil après l'étiquetage actif, Potato lance un nouveau tour de la boucle de raffinement :
- Le LLM ré-étiquette l'ensemble de données complet avec des directives mises à jour et plus d'exemples few-shot
- La précision est recalculée par rapport à toutes les étiquettes humaines
- De nouveaux schémas de confusion sont identifiés
- Les directives sont affinées à nouveau
Cette phase est essentiellement automatique. Vous n'avez qu'à approuver les changements de directives.
Résultat typique : la précision s'améliore de 2 à 4% par tour de raffinement.
Étape 11 : Phase 8 -- Exploration des désaccords
Potato présente les instances les plus controversées : les cas où le LLM, les fonctions d'étiquetage et l'analyse des plus proches voisins donnent tous des réponses différentes. Pour chaque instance, vous voyez :
- Le texte de l'avis
- La prédiction et la confiance du LLM
- Les votes des fonctions d'étiquetage
- Les 3 exemples étiquetés les plus proches avec leurs étiquettes
- Le raisonnement chaîne-de-pensée du LLM
Ce sont des cas véritablement difficiles. Vos étiquettes ici ont la valeur marginale la plus élevée de toute annotation dans l'ensemble du processus.
Estimation de temps : 20-30 minutes pour 100-150 instances.
Étape 12 : Phase 9 -- Synthèse de cas limites
Potato génère des avis synthétiques ciblant les schémas de confusion restants. Par exemple, si le LLM a encore du mal avec les « avis neutres qui mentionnent racheter », il génère des exemples comme :
"C'est un produit correct pour le prix. J'en reprendrais peut-être s'il y a une promo."
Vous étiquetez ces exemples synthétiques, et ils sont ajoutés au contexte few-shot du LLM.
Estimation de temps : 10-15 minutes pour 30 exemples.
Étape 13 : Phase 10 -- Escalade de confiance en cascade
Le LLM a maintenant étiqueté la majorité de l'ensemble de données. Potato classe toutes les instances étiquetées par le LLM par confiance et vous envoie celles à plus faible confiance par lots de 25.
Confidence Escalation Progress:
Batch 1: 25 instances, 23/25 correct (92%)
Batch 2: 25 instances, 24/25 correct (96%)
Batch 3: 25 instances, 25/25 correct (100%)
-> Stopping: last 3 batches stable
Une fois que vous voyez trois lots consécutifs où le LLM a tout réussi, le Solo Mode conclut que les étiquettes à haute confiance restantes sont fiables.
Estimation de temps : 15-20 minutes.
Étape 14 : Phase 11 -- Optimisation de prompt
Cette phase s'exécute automatiquement. Potato essaie 8 variantes de prompt et sélectionne celle avec le meilleur score F1 sur vos étiquettes humaines accumulées :
Prompt Optimization Results:
Variant 1 (direct, 5 examples): F1=0.91
Variant 2 (CoT, 5 examples): F1=0.93
Variant 3 (direct, 10 examples): F1=0.92
Variant 4 (CoT, 10 examples): F1=0.94 <-- selected
Variant 5 (direct, 15 examples): F1=0.92
Variant 6 (CoT, 15 examples): F1=0.93
Variant 7 (self-consistency, 5x): F1=0.94
Variant 8 (self-consistency, 10x): F1=0.94
Le meilleur prompt est utilisé pour une passe finale de ré-étiquetage.
Étape 15 : Phase 12 -- Validation finale
Potato sélectionne 100 instances aléatoires étiquetées par le LLM pour votre révision. Vous les étiquetez, et Potato compare avec les étiquettes du LLM.
Final Validation:
Reviewed: 100 instances
LLM correct: 94/100 (94%)
Threshold: 93%
-> PASSED
Si la précision du LLM atteint votre seuil, l'ensemble de données est complet. Sinon, le Solo Mode revient à la Phase 6 pour un autre tour d'étiquetage actif.
Estimation de temps : 10-15 minutes.
Résumé des résultats
Après avoir traversé les 12 phases, vérifiez les statistiques finales :
python -m potato.solo status --config config.yamlSolo Mode Complete
==================
Dataset: 10,000 instances
Total human labels: 612
Seed: 50
Active labeling: 275
Disagreement exploration: 137
Edge case synthesis: 30
Confidence escalation: 75
Final validation: 45
LLM labels: 8,200 (accuracy: 94.1%)
LF labels: 1,800 (precision: 95.3%)
Unlabeled: 0
Final label distribution:
Positive: 4,823 (48.2%)
Neutral: 3,011 (30.1%)
Negative: 2,166 (21.7%)
Total human time: ~3.5 hours
Estimated multi-annotator cost (3x): ~$4,500
Solo Mode cost: ~$450 (API fees) + ~$175 (annotator time)
Savings: ~88%
L'humain a étiqueté 612 des 10 000 instances (6,1%). Le LLM et les fonctions d'étiquetage ont géré le reste à plus de 94% de précision.
Exporter les résultats
Exportez l'ensemble de données étiqueté final :
python -m potato.solo export --config config.yaml --output final_labels.jsonlChaque ligne inclut l'étiquette et sa source :
{"id": "rev_001", "sentiment": "Positive", "source": "human", "confidence": 1.0}
{"id": "rev_002", "sentiment": "Neutral", "source": "llm", "confidence": 0.91}
{"id": "rev_003", "sentiment": "Negative", "source": "labeling_function", "confidence": 0.97}Pour l'export Parquet :
import pandas as pd
df = pd.read_parquet("output/parquet/annotations.parquet")
print(df["value"].value_counts())Assurance qualité : vérification hybride
Pour des ensembles de données de qualité publication, ajoutez un second annotateur pour réviser un échantillon :
solo_mode:
verification:
enabled: true
sample_fraction: 0.10
annotator: "reviewer_1"Cela assigne 1 000 instances aléatoires à un second annotateur. Vous pouvez ensuite calculer l'accord inter-annotateurs entre les étiquettes du Solo Mode et celles du réviseur.
Dépannage
La précision du LLM plafonne en dessous du seuil
- Augmentez le nombre initial : essayez 75-100 instances initiales au lieu de 50
- Changez de LLM : essayez
claude-sonnet-4-20250514au lieu de GPT-4o (ou vice versa) - Baissez le seuil : si 93% n'est pas atteignable, considérez si 90% est acceptable pour votre cas d'usage
- Vérifiez vos données : certains ensembles de données sont intrinsèquement ambigus. Si l'accord humain-humain ne serait que de 90%, n'attendez pas du LLM qu'il fasse mieux
La Phase 6 prend trop de lots
- Augmentez la taille des lots : changez
batch_sizede 25 à 50 - Ajustez les poids des pools : si la plupart des instances escaladées viennent du pool « incertain », réduisez son poids et augmentez « désaccord » et « schéma d'erreur »
Les fonctions d'étiquetage ont une faible couverture
- C'est normal pour les tâches sans signaux lexicaux forts (par ex. détection de sarcasme, sentiment implicite)
- Les fonctions d'étiquetage fonctionnent mieux pour les schémas explicites basés sur les mots-clés
- Le Solo Mode fonctionne quand même sans fonctions d'étiquetage -- le LLM prend le relais
Pour aller plus loin
- Documentation du Solo Mode -- référence de configuration complète
- Apprentissage actif -- l'algorithme de sélection sous-jacent
- Support IA -- configuration du fournisseur LLM
- Contrôle qualité -- options supplémentaires d'assurance qualité
- Export Parquet -- export efficace des données