Skip to content
ट्यूटोरियल13 मिनट में पढ़ें

Solo Mode: एक Annotator कैसे 10,000 Examples Label कर सकता है

Potato के Solo Mode पर चरण-दर-चरण tutorial: एक seed सेट खुद label कीजिए, बाकी LLM से label करवाइए, और accuracy जाँचों से तय कीजिए कि परिणाम कब इतना अच्छा है कि रुका जा सके।

Potato Team

आपके पास 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 हो:

json
{"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 बनाएं:

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 शुरू करें

bash
potato start config.yaml -p 8000

http://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:

text
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 संभालते हैं:

text
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 चलाता है:

  1. LLM updated guidelines और अधिक few-shot examples के साथ पूरे dataset को फिर से label करता है
  2. Potato सभी human labels के मुकाबले accuracy फिर से compute करता है
  3. वह नए confusion patterns ढूँढता है
  4. वह 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 में आपको भेजता है।

text
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 सबसे ऊँचा हो:

text
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 से करता है।

text
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 से पढ़ी जाती है:

text
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 से ही निकलते हैं:

bash
python -m potato.export -c config.yaml -f jsonl -o ./export/

हर पंक्ति में label और उसका source होता है:

json
{"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 के लिए:

python
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 करता है

आगे पढ़ें