Solo Mode: एक Annotator कैसे 10,000 Examples Label कर सकता है
Potato के Solo Mode पर चरण-दर-चरण tutorial: एक seed सेट खुद label कीजिए, बाकी LLM से label करवाइए, और accuracy जाँचों से तय कीजिए कि परिणाम कब इतना अच्छा है कि रुका जा सके।
आपके पास 10,000 product reviews हैं जिन्हें sentiment (Positive, Neutral, Negative) के लिए label करना है। सभी को label करने के लिए तीन annotators hire करने में हफ्ते लगते हैं और हजारों डॉलर खर्च होते हैं। Solo Mode से एक domain expert केवल 500-1,000 instances label करके तुलनीय quality पा सकता है। बाकी को LLM संभालता है, और जिन मामलों में LLM अनिश्चित हो, उनकी समीक्षा इंसान करता है।
यह tutorial पूरी प्रक्रिया से होकर गुज़रता है।
आपको क्या चाहिए होगा
- Potato 2.3.0 या उसके बाद का संस्करण, LLM providers के लिए AI extras के साथ:
pip install potato-annotation[ai] - एक OpenAI या Anthropic API key (LLM component के लिए)
- JSONL format में आपका dataset
- एक जानकार annotator (जो आप स्वयं हो सकते हैं)
चरण 1: अपना Data तैयार करें
data/reviews.jsonl बनाएं, जिसमें प्रति पंक्ति एक review हो:
{"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"}इस tutorial के लिए मान लीजिए कि इस फ़ाइल में 10,000 reviews हैं।
चरण 2: Configuration बनाएं
config.yaml बनाएं:
annotation_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
# The model that labels. A list, so you can give fallbacks.
labeling_models:
- endpoint_type: openai
model: "gpt-4o"
api_key: ${OPENAI_API_KEY}
temperature: 0.1
max_tokens: 1024
embedding:
model_name: "all-MiniLM-L6-v2"
uncertainty:
strategy: direct_confidence
# When you are allowed to stop labeling
thresholds:
end_human_annotation_agreement: 0.93
minimum_validation_sample: 50
confidence_low: 0.5
confidence_high: 0.85
periodic_review_interval: 100
# What decides which instance you see next
instance_selection:
low_confidence_weight: 0.30
disagreement_weight: 0.25
diversity_weight: 0.20
llm_predicted_weight: 0.15
random_weight: 0.10
batches:
llm_labeling_batch: 25
max_parallel_labels: 200
labeling_functions:
enabled: true
auto_extract: true
max_functions: 15
min_confidence: 0.92
min_coverage: 3
edge_case_rules:
enabled: true
auto_extract_on_labeling: true
confusion_analysis:
enabled: true
min_instances_for_pattern: 3
max_patterns: 20
prompt_optimization:
enabled: true
target_accuracy: 0.93
refinement_loop:
enabled: true
trigger_interval: 50
min_improvement: 0.02
max_cycles: 3
state_dir: "solo_state_reviews"
# --- 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/"
export_annotation_format:
- jsonl
- parquetचरण 3: Server शुरू करें
potato start config.yaml -p 8000http://localhost:8000 खोलें और log in करें। Solo Mode dashboard दिखाई देता है, जो project को setup अवस्था में दिखाता है, ताकि आप उसके द्वारा तैयार किए गए prompt की समीक्षा कर सकें।
चरण 4: Parallel annotation, आपके पहले 50
Potato ने embedding-based clustering से 50 विविध reviews चुने हैं। ये random नहीं हैं। इन्हें इस तरह चुना गया है कि ये आपके data distribution को जितना हो सके उतना व्यापक रूप से cover करें।
हर एक को label करें। यही वह phase है जो सबसे ज़्यादा मायने रखता है, क्योंकि आपके seed labels की quality यह ऊपरी सीमा तय करती है कि LLM कितना सीख सकता है। समय लें और consistent रहें।
समय का अनुमान: प्रति instance 20-30 सेकंड की दर से 15-25 मिनट।
जब इनमें से पर्याप्त label हो जाते हैं, तो LLM बिना कहे आपके साथ-साथ label करना शुरू कर देता है।
चरण 5: LLM बराबरी पर आता है
यह phase अपने आप चलता है। Potato LLM को 200 instances का एक batch भेजता है, जिसमें आपके 50 seed labels few-shot examples के रूप में होते हैं, फिर baseline accuracy का अनुमान लगाने के लिए predictions की तुलना 10 held-out seed labels से करता है।
Dashboard में एक progress indicator दिखता है। LLM provider के आधार पर इसमें आमतौर पर 1-2 मिनट लगते हैं।
सामान्य परिणाम: पहले calibration पर LLM 75-85% accuracy पर पहुँचता है। यह अपेक्षित है। उसने अभी तक आपकी annotation style नहीं सीखी है।
चरण 6: Confusion analysis
Potato एक confusion matrix दिखाता है, जिससे पता चलता है कि LLM आपके labels से कहाँ असहमत है। एक सामान्य output:
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%)
इससे यहाँ LLM की मुख्य कमज़ोरी सामने आती है: वह neutral reviews को बार-बार positive में upgrade कर देता है। यह आम गलती है, क्योंकि LLMs positive की ओर झुकते हैं।
आपकी action: Confusion pairs देखें। हर pair पर click करके वे specific instances देखें जिनमें LLM गलत था। LLM कैसे चूकता है, यह समझने का यही सबसे तेज़ तरीका है।
चरण 7: फिर से prompt review
Confusion analysis के आधार पर Potato LLM के लिए refined guidelines का draft बनाता है और उन्हें side by side दिखाता है: एक तरफ़ current prompt, और दूसरी तरफ़ error patterns से निकाले गए specific edits जो वह प्रस्तावित करता है।
उदाहरण के लिए, Potato यह जोड़ने का सुझाव दे सकता है:
"जो reviews किसी product को बिना किसी तीव्र भावना के 'ठीक', 'ओके' या 'ठीक-ठाक' बताते हैं, उन्हें Neutral label किया जाना चाहिए, भले ही उनमें दोबारा खरीदने का ज़िक्र हो।"
हर suggested edit देखें और उसे approve, modify या reject करें। आप अपने स्पष्टीकरण भी लिख सकते हैं।
समय का अनुमान: 5-10 मिनट।
चरण 8: Labeling functions
Potato आपके seed labels के patterns से programmatic labeling functions बनाता है। ये तेज़, deterministic rules हैं जो आसान cases संभालते हैं:
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)
Labeling functions आपके dataset का 18% हिस्सा 92% से अधिक precision पर cover करते हैं। वे instances अपने आप label हो जाते हैं, जिससे LLM और इंसान कठिन cases के लिए खाली हो जाते हैं।
आपकी action: Generated functions देखें और जो अविश्वसनीय लगें उन्हें disable करें। यह step optional है, क्योंकि Potato वैसे भी केवल आपके configured precision threshold से ऊपर वाले functions ही रखता है।
चरण 9: Active annotation (125-375 instances)
यहीं आप अपनी ज़्यादातर labeling करते हैं। Potato ऊपर instance_selection में तय किए गए weighted pools से instances चुनता है:
low_confidence_weight(0.30): वे reviews जहाँ LLM की confidence सबसे कम हैdisagreement_weight(0.25): वे reviews जहाँ LLM और labeling functions असहमत हैंdiversity_weight(0.20): वे reviews जिन्हें embedding space में एक जगह जमा होने के बजाय फैला हुआ रहने के लिए चुना गया हैllm_predicted_weight(0.15): LLM द्वारा label किए गए reviews, जिन्हें human तुलना के लिए वापस लाया जाता हैrandom_weight(0.10): Calibration के लिए random reviews
दो और weights मौजूद हैं, जो यहाँ अपने default मान शून्य पर छोड़े गए हैं, इसलिए उनका कोई योगदान नहीं है: edge_case_rule_weight, उन instances के लिए जो किसी खोजे गए edge-case rule से मेल खाते हैं, और cartography_weight, उन instances के लिए जिनकी confidence rounds के बीच ऊपर-नीचे होती है। Potato जाँचता है कि weights का योग 1.0 हो और ऐसा न होने पर warning log करता है, लेकिन मानों को वैसे ही इस्तेमाल करता है जैसे लिखे गए हैं, इसलिए योग सही है यह आपको खुद सुनिश्चित करना होगा।
आप इन्हें 25 के batches में label करते हैं। हर batch के बाद Potato LLM की accuracy का अनुमान update करता है और तय करता है कि आगे बढ़ना है या नहीं।
सामान्य trajectory:
- Batch 1-3 (75 instances): Accuracy 82% से बढ़कर 87% होती है
- Batch 4-6 (150 instances): Accuracy 90% तक पहुँचती है
- Batch 7-10 (250 instances): Accuracy 91-92% पर plateau करती है
अगर agreement आपके end_human_annotation_agreement तक पहुँच जाता है, तो Solo Mode autonomous labeling की ओर बढ़ता है। अन्यथा वह review और refinement का चक्र चलाता रहता है।
समय का अनुमान: कुल 45-90 मिनट, इस पर निर्भर करते हुए कि कितने batches चाहिए।
चरण 10: Refinement loop
अगर active labeling के बाद भी accuracy threshold से नीचे है, तो Potato refinement loop का एक और round चलाता है:
- LLM updated guidelines और अधिक few-shot examples के साथ पूरे dataset को फिर से label करता है
- Potato सभी human labels के मुकाबले accuracy फिर से compute करता है
- वह नए confusion patterns ढूँढता है
- वह guidelines को फिर से refine करता है
इस phase में आपको लगभग कुछ नहीं करना होता। आपको केवल guideline changes approve करने होते हैं।
सामान्य परिणाम: हर refinement round में accuracy 2-4% सुधरती है।
चरण 11: Disagreement resolution
Potato सबसे विवादित instances सामने रखता है: ऐसे cases जहाँ LLM, labeling functions और nearest-neighbor analysis तीनों अलग-अलग जवाब देते हैं। हर instance के लिए आप देखते हैं:
- Review text
- LLM prediction और उसकी confidence
- Labeling function votes
- 3 सबसे नज़दीकी labeled examples, उनके labels के साथ
- LLM की chain-of-thought reasoning
ये कठिन cases हैं, और यहाँ आपके labels का वज़न प्रक्रिया में किसी भी और जगह से ज़्यादा है।
समय का अनुमान: 100-150 instances के लिए 20-30 मिनट।
चरण 12: Edge case synthesis
Potato बचे हुए confusion patterns को target करते हुए synthetic reviews बनाता है। उदाहरण के लिए, अगर LLM अब भी "दोबारा खरीदने का ज़िक्र करने वाले neutral reviews" में उलझता है, तो वह इस तरह के examples बनाता है:
"कीमत के हिसाब से product ठीक-ठाक है। अगर sale लगी तो शायद एक और ले लूँ।"
आप इन synthetic examples को label करते हैं, और Potato उन्हें LLM के few-shot context में जोड़ देता है।
समय का अनुमान: 30 examples के लिए 10-15 मिनट।
चरण 13: Periodic review
अब तक LLM dataset का ज़्यादातर हिस्सा label कर चुका है। Potato उसके सभी labels को confidence के हिसाब से rank करता है और सबसे कम confidence वाले labels 25 के batches में आपको भेजता है।
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
जब accuracy लगातार तीन batches तक बदलना बंद कर देती है, तो Solo Mode बचे हुए high-confidence labels को भरोसेमंद मान लेता है। ध्यान दें कि यह stability है, perfection नहीं। ऊपर वाला run 92%, 96% और 100% के बाद इसलिए रुकता है क्योंकि संख्या स्थिर हो गई है, इसलिए नहीं कि आख़िरी batch में कोई गलती नहीं थी।
समय का अनुमान: 15-20 मिनट।
चरण 14: Prompt optimization
यह phase अपने आप चलता है। Potato 8 prompt variants आज़माता है और उसे रखता है जिसका आपके जमा हुए human labels पर F1 score सबसे ऊँचा हो:
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
फिर वह सबसे अच्छे prompt का इस्तेमाल एक अंतिम re-labeling pass के लिए करता है।
चरण 15: Final validation
Potato आपकी समीक्षा के लिए LLM द्वारा label किए गए 100 random instances निकालता है। आप उन्हें label करते हैं, और Potato आपके labels की तुलना LLM के labels से करता है।
Final Validation:
Reviewed: 100 instances
LLM correct: 94/100 (94%)
Threshold: 93%
-> PASSED
अगर LLM आपका threshold पार कर लेता है, तो project पूरा हो जाता है। अगर नहीं, तो वह एक और round के लिए active annotation पर लौट जाता है। Final validation से केवल यही एक वापसी वाला transition संभव है।
समय का अनुमान: 10-15 मिनट।
Results Summary
अंत में dashboard बताता है कि labels कहाँ से आए। Solo Mode का कोई command-line interface नहीं है (यह server के अंदर चलता है और अपने ही pages से संचालित होता है), इसलिए यह जानकारी terminal से नहीं, बल्कि चल रहे instance से पढ़ी जाती है:
Solo 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%
इंसान ने 10,000 में से 612 instances label किए, यानी लगभग 6%। बाकी को LLM और labeling functions ने 94% से अधिक accuracy पर संभाला।
Results Export करें
Solo Mode उसी storage में लिखता है जिसमें कोई भी दूसरा project लिखता है, इसलिए labels सामान्य exporter से ही निकलते हैं:
python -m potato.export -c config.yaml -f jsonl -o ./export/हर पंक्ति में label और उसका 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}Parquet export के लिए:
import pandas as pd
df = pd.read_parquet("output/exports/parquet/annotations.parquet")
print(df["sentiment"].value_counts())annotations.parquet में हर instance और annotator के लिए एक row होती है, और हर annotation scheme अपने अलग column में flatten होती है, इसलिए आप scheme को उसके नाम से चुनते हैं, किसी generic value column से नहीं।
Quality Assurance: Hybrid Verification
Publication-quality datasets के लिए, एक sample की समीक्षा करने हेतु दूसरा annotator जोड़ें। Solo Mode source documentation में verification विकल्पों का विस्तार से वर्णन है।
Solo Mode का अपना कोई verification block नहीं है, इसलिए यह एक सामान्य दूसरा pass है: labels export करें, उन्हें एक सामान्य project के रूप में फिर से Potato में चलाएं जिसमें एक reviewer 10% sample देखे, और reviewer तथा Solo Mode labels के बीच agreement उसी तरह compute करें जैसे किन्हीं भी दो annotators के लिए करते हैं। (icl_labeling में एक verification block ज़रूर है, लेकिन वह in-context labeling का हिस्सा है, Solo Mode का नहीं।)
Troubleshooting
LLM accuracy threshold से नीचे plateau हो जाती है
- Seed count बढ़ाएं: 50 के बजाय 75-100 seed instances आज़माएं
- LLM बदलें: GPT-4o के बजाय
claude-sonnet-4-20250514आज़माएं (या इसका उल्टा) - Threshold कम करें: अगर 93% हासिल नहीं हो पा रहा, तो सोचें कि क्या आपके use case के लिए 90% स्वीकार्य है
- अपना data जाँचें: कुछ datasets स्वाभाविक रूप से ambiguous होते हैं। अगर इंसानों के बीच आपसी agreement केवल 90% होता, तो LLM से बेहतर की उम्मीद न करें
Active annotation में बहुत ज़्यादा batches लगते हैं
- Batch size बढ़ाएं:
batch_sizeको 25 से 50 करें - Pool weights adjust करें: अगर ज़्यादातर escalated instances low-confidence pool से आते हैं, तो
low_confidence_weightघटाएं औरdisagreement_weightयाdiversity_weightबढ़ाएं
Labeling functions की coverage कम है
- ऐसे tasks के लिए यह सामान्य है जिनमें मज़बूत lexical signals नहीं होते (जैसे sarcasm detection, implicit sentiment)
- Labeling functions स्पष्ट, keyword-आधारित patterns के लिए सबसे अच्छा काम करते हैं
- Solo Mode labeling functions के बिना भी काम करता है, और तब उन instances को LLM cover करता है
आगे पढ़ें
- Solo Mode Documentation: पूरा configuration reference
- सक्रिय अधिगम (Active Learning): इसके पीछे का selection algorithm
- AI सपोर्ट: LLM provider configuration
- गुणवत्ता नियंत्रण: quality assurance के अतिरिक्त विकल्प
- Parquet एक्सपोर्ट: कुशल data export