ट्रांसक्रिप्ट प्रारूप
Potato जिन सभी ट्रांसक्रिप्ट और सबटाइटल प्रारूपों को पढ़ता है: Whisper, WhisperX, Deepgram, AssemblyAI, AWS Transcribe, SRT, WebVTT, TTML, YouTube कैप्शन, CTM, Praat TextGrid और ELAN EAF, साथ ही साइडकार फ़ाइलें और सामान्यीकृत टर्न मॉडल।
Potato 21 तरह के ट्रांसक्रिप्ट और सबटाइटल इनपुट पढ़ता है और कुछ भी दिखाने से पहले उन सबको एक ही टर्न मॉडल में बदल देता है। आपकी ASR पाइपलाइन या कैप्शनिंग टूल ने जो भी बनाया हो, आप Potato को सीधे उसी पर लगा सकते हैं, कोई कन्वर्ज़न स्क्रिप्ट लिखे बिना। यह पृष्ठ इस बात का संदर्भ है कि क्या काम करता है, हर प्रारूप कैसे पहचाना जाता है और हर एक क्या देता है। चरण-दर-चरण मार्गदर्शन के लिए देखें Whisper ट्रांसक्रिप्ट कैसे एनोटेट करें और YouTube सबटाइटल कैसे एनोटेट करें।
एक साइडकार SRT फ़ाइल वक्ता बुलबुलों के रूप में, हर टर्न के साथ एक प्रश्न
Potato ट्रांसक्रिप्शन नहीं करता
वाक् पहचान और वक्ता डायराइज़ेशन Potato के कुछ भी देखने से पहले होते हैं। पहले Whisper, WhisperX, pyannote या कोई क्लाउड API चलाइए; Potato उसका परिणाम पढ़ता है। इस पृष्ठ पर कुछ भी कोई मॉडल नहीं चलाता।
Note: Think-Aloud मोड वाकई एक स्थानीय Whisper मॉडल चलाता है, पर दूसरे उद्देश्य से: वह एनोटेटर्स को काम करते हुए बोलते समय रिकॉर्ड करता है। वह एक रिकॉर्डिंग सुविधा है, ट्रांसक्रिप्ट पढ़ने की नहीं।
पहचान सामग्री से होती है, एक्सटेंशन से नहीं
Potato फ़ाइल के नाम पर भरोसा करने के बजाय उसके भीतर देखता है। captions.txt नाम की WebVTT फ़ाइल फिर भी WebVTT की तरह पढ़ी जाती है। व्यावहारिक परिणाम यह है कि वही ट्रांसक्रिप्ट आपकी डेटा फ़ाइल में सीधे लिखा हो या डिस्क पर अलग फ़ाइल से पढ़ा जाए, दोनों तरह काम करता है, कॉन्फ़िगरेशन बदले बिना।
समर्थित प्रारूप
ASR आउटपुट
| प्रारूप | किससे पहचाना जाता है | वक्ता | शब्द-स्तरीय समय |
|---|---|---|---|
| Whisper JSON | segments सरणी | नहीं | हाँ, --word_timestamps के साथ |
| WhisperX / डायराइज़्ड JSON | speaker वाले segments | हाँ | हाँ |
| whisper.cpp JSON | transcription सरणी | नहीं | नहीं |
| Whisper TSV | start/end/text शीर्षक | नहीं | नहीं |
| AWS Transcribe | results.items या results.audio_segments | हाँ | हाँ |
| Deepgram | results.channels या results.utterances | हाँ, diarize=true के साथ | हाँ |
| AssemblyAI | text के साथ words/utterances | हाँ, speaker_labels के साथ | हाँ |
| Rev.ai | monologues सरणी | हाँ | हाँ |
| SPoRC | turn_text/turnText पंक्तियाँ | हाँ, अनुमानित | नहीं |
सबटाइटल और कैप्शन
| प्रारूप | किससे पहचाना जाता है | वक्ता |
|---|---|---|
SubRip (.srt) | क्यू तीर, ,mmm विभाजक | Name: उपसर्ग से |
WebVTT (.vtt) | WEBVTT शीर्षक | <v Name> टैग या Name: उपसर्ग से |
SubStation Alpha (.ass, .ssa) | [Script Info] / Dialogue: | Name फ़ील्ड से |
| TTML / DFXP | <tt> मूल तत्व | speaker/agent विशेषता से |
| YouTube srv1/srv2/srv3 | <transcript><text> XML | Name: उपसर्ग से |
| YouTube json3 | events सरणी | कोई नहीं; स्वतः कैप्शन में वक्ता नहीं होते |
SubRip और WebVTT उन ज़्यादातर चीज़ों को कवर करते हैं जो आपको मिलेंगी। TTML प्रसारण अभिलेखागार में और पेशेवर कैप्शनिंग टूल से निर्यात की गई फ़ाइलों में दिखता है।
संरेखण और भाषाई एनोटेशन
| प्रारूप | किससे पहचाना जाता है | वक्ता |
|---|---|---|
| NIST CTM | रिक्त स्थान से अलग किए स्तंभ, संख्यात्मक आरंभ और अवधि | चैनल फ़ील्ड से |
| Praat TextGrid | File type = "ooTextFile" | प्रति वक्ता एक स्तर |
| ELAN EAF | ANNOTATION_DOCUMENT मूल | PARTICIPANT से, अन्यथा स्तर की आईडी |
TextGrid के लंबे और छोटे दोनों क्रमबद्धीकरण पढ़े जाते हैं। ELAN फ़ाइलों के लिए Potato ALIGNABLE_ANNOTATION और REF_ANNOTATION को TIME_ORDER तालिका के विरुद्ध हल करता है और शीर्षलेख से मीडिया संदर्भ पढ़ता है।
TextGrid का हर स्तर एक वक्ता बन जाता है, और बीच के खाली अंतराल छोड़ दिए जाते हैं
बाकी सब कुछ
तीन सामान्य रूप 21 की गिनती पूरी करते हैं:
{speaker, start, end, text}शब्दकोशों की सादी सूची।- एक
{"audio": ..., "turns": [...]}ऑब्जेक्ट। - बिना किसी समय के सादा अनुच्छेद, जो एक ही बुलबुले के रूप में दिखता है।
असमर्थित
इनके लिए कोई पार्सर नहीं है। पहले इन्हें बदल लीजिए।
- SAMI (
.smi), MicroDVD (.sub), SubViewer (.sbv) - Transcriber (
.trs), EXMARaLDA, CHAT/CHILDES (.cha) - Montreal Forced Aligner और Gentle का मूल आउटपुट। उनसे CTM या TextGrid निर्यात कीजिए।
- असामान्य रैपर के भीतर Azure Speech, Google Speech-to-Text और Whisper API का
verbose_json - अकेले RTTM डायराइज़ेशन फ़ाइलें
जहाँ स्रोत उपलब्ध कराता है वहाँ शब्द-स्तरीय कॉन्फ़िडेंस पढ़ी और डेटा मॉडल में रखी जाती है, पर उसे देखने के लिए फ़िलहाल कोई इंटरफ़ेस नहीं है।
सामान्यीकृत टर्न मॉडल
ऊपर के सभी प्रारूप इसमें बदल जाते हैं:
{
"audio": "media/interview_01.mp3",
"turns": [
{
"turn_id": "t0",
"speaker": "host",
"start": 0.0,
"end": 6.5,
"text": "Welcome back.",
"words": [{"word": "Welcome", "start": 0.0, "end": 0.4, "confidence": 0.99}],
"confidence": 0.97
}
]
}words और confidence तभी दिखते हैं जब स्रोत में मौजूद हों। बिना डायराइज़ेशन वाले टर्न में speaker null होता है, और वे Unassigned के रूप में एक चयनकर्ता के साथ दिखते हैं ताकि एनोटेटर उन्हें भर सकें।
YouTube के स्वतः कैप्शन बिना वक्ताओं के आते हैं, इसलिए हर टर्न तब तक Unassigned रहता है जब तक कोई एनोटेटर चुन न ले
turn_id प्रति-टर्न एनोटेशन और वक्ता असाइनमेंट के लिए स्थायित्व कुंजी है। यह स्रोत में मौजूद स्पष्ट turn_id या step_id स्ट्रिंग से आती है, वरना t{सूचकांक} से। एक ही फ़ाइल हमेशा एक ही आईडी बनाती है, इसलिए एनोटेशन पुनः लोड करने पर भी बचे रहते हैं।
Warning: अलग-अलग टूल में समय की इकाइयाँ अलग होती हैं। Whisper और Deepgram दशमलव सेकंड इस्तेमाल करते हैं; AssemblyAI, whisper.cpp के ऑफ़सेट और Whisper का TSV आउटपुट पूर्णांक मिलीसेकंड इस्तेमाल करते हैं। Potato सीमा पर रूपांतरण कर देता है ताकि आगे सब कुछ सेकंड में रहे। अगर आपकी अपनी प्री-प्रोसेसिंग इन दोनों को मिला दे, तो समय 1000 गुना ग़लत निकलते हैं।
साइडकार फ़ाइलें
ऐसा फ़ील्ड मान जो एक ही पंक्ति का छोटा पथ हो और किसी ज्ञात ट्रांसक्रिप्ट एक्सटेंशन पर ख़त्म होता हो, उसे पाठ मानने के बजाय डिस्क से पढ़ा जाता है। इसलिए आपके ASR टूल ने जो व्यवस्था पहले ही बनाई है, जिसमें मीडिया फ़ाइलें अपनी .srt या .json के बगल में हैं, वह बिना किसी प्री-प्रोसेसिंग चरण के काम करती है:
{
"id": "int_001",
"conversation": {
"audio": "media/int_001.mp3",
"transcript": "media/int_001.srt"
}
}पथ task_dir के सापेक्ष हल होते हैं और हर दूसरे कॉन्फ़िगर किए पथ जैसी ही पथ-सुरक्षा जाँच से गुज़रते हैं, इसलिए कोई डेटा फ़ाइल परियोजना के बाहर नहीं पढ़ सकती।
पहचाने जाने वाले एक्सटेंशन: .srt .vtt .webvtt .json .json3 .srv1 .srv2 .srv3 .ttml .dfxp .xml .ass .ssa .tsv .ctm .TextGrid .eaf .txt
अगर आपके डेटा में वाकई एक पंक्ति के ट्रांसक्रिप्ट हैं जो फ़ाइल नाम जैसे दिखते हैं, तो यह अनुमान बंद कर दीजिए:
display_options:
transcript_is_path: auto # auto (default) | true | falseकॉन्फ़िगरेशन
प्रदर्शन: audio_dialogue
ऑडियो संवाद प्रदर्शन टर्न को ऑडियो के साथ समकालिक वक्ता बुलबुलों के रूप में दिखाता है, हर टर्न पर एक प्ले बटन के साथ।
instance_display:
fields:
- key: conversation
type: audio_dialogue
label: "Transcript"
span_target: true
display_options:
audio_key: audio
turns_key: turns
speaker_key: speaker
text_key: text
transcript_is_path: auto
show_timestamps: true
allow_speaker_assignment: auto
scroll_height: 460px| विकल्प | डिफ़ॉल्ट | क्या करता है |
|---|---|---|
audio_key | audio | फ़ील्ड मान की वह उपकुंजी जिसमें ऑडियो का URL या पथ है। |
turns_key | turns | वह उपकुंजी जिसमें टर्न सूची है। segments भी स्वीकार्य है। |
speaker_key / text_key | speaker / text | प्रति-टर्न कुंजियाँ। |
speakers | [] | {id, name, color, side} की सूची। सूची में न होने वाले वक्ताओं को नियत रंग और बारी-बारी से पक्ष मिलता है। |
allow_speaker_assignment | auto | जब बिना डायराइज़ेशन वाले टर्न हों या सुधारने के लिए सूची हो तो auto क्लिक-से-असाइन चालू कर देता है। true इसे बाध्य करता है, false बंद। |
transcript_is_path | auto | फ़ील्ड मान को साइडकार पथ की तरह पढ़ना है या नहीं। |
show_timestamps | true | हर टर्न पर mm:ss–mm:ss दिखाता है। |
scroll_height | 480px | स्क्रॉल होने वाले ट्रांसक्रिप्ट पटल की ऊँचाई। |
playback_rates | [1, 1.25, 1.5, 2] | गति चयनकर्ता के विकल्प। |
स्कीमा
2.7.1 से speech_transcript, voice_interaction और tiered_annotation सभी ट्रांसक्रिप्ट को सीधे इंस्टेंस रिकॉर्ड से पढ़ते हैं और इस पृष्ठ के हर प्रारूप को स्वीकार करते हैं। इससे पहले केवल audio_dialogue प्रदर्शन ऐसा करता था।
annotation_schemes:
- annotation_type: speech_transcript
name: transcript_review
description: "Mark transcription errors"
segments_key: segments # record field holding the transcript
- annotation_type: voice_interaction
name: barge_in
description: "Mark overlaps and barge-in"
turns_key: turnsस्तरीय एनोटेशन ट्रांसक्रिप्ट से किसी स्तर को पहले से भर सकता है, ताकि एनोटेटर हाथ से भाषण को दोबारा विभाजित करने के बजाय मौजूदा संरेखण को सुधारें:
- annotation_type: tiered_annotation
name: tiers
source_field: audio_url
media_type: audio
transcript_field: asr_output # opt-in; omit to start from a blank timeline
transcript_tier: utterance # defaults to the first tier
tiers:
- name: utterance
labels:
- name: speech
color: "#7c3aed"पहले से भरे गए एनोटेशन तब तक नहीं लिखे जाते जब तक एनोटेटर सचमुच कोई बदलाव न करे, इसलिए जिसने केवल इंस्टेंस खोला उसके नाम कुछ दर्ज नहीं होता।
potato transcripts से डेटा फ़ाइल बनाना
कन्वर्टर को ASR आउटपुट के फ़ोल्डर पर लगाइए और वह एनोटेशन के लिए तैयार डेटा फ़ाइल लिख देगा:
# Pair transcripts to media by basename
potato transcripts ./whisper_out --media-dir ./audio -o data/interviews.json
# Media served from elsewhere
potato transcripts './captions/*.vtt' \
--media-url-prefix https://cdn.example.org/audio -o data/talks.json
# What did it detect? Writes nothing.
potato transcripts ./whisper_out --dry-run--dry-run कुछ लिखे बिना बताता है कि उसे क्या मिला, और ग़लत Whisper आउटपुट फ़ाइल वाले फ़ोल्डर को पकड़ने का यही सबसे तेज़ तरीक़ा है:
Scanned 3 file(s):
talk_01.srt SRT 2 turns 5.0s 2 speaker(s): Alice, Bob
talk_02.vtt WebVTT 1 turns 3.0s undiarized
talk_03.json whisper.cpp JSON 1 turns 2.4s undiarized
3 item(s), 4 turn(s).
1 item(s) have no media. Pass --media-dir or --media-url-prefix to enable playback.
| विकल्प | उद्देश्य |
|---|---|
-o, --output | कहाँ लिखना है। --dry-run के अलावा अनिवार्य। |
--format | json (डिफ़ॉल्ट) या jsonl। |
--media-dir | वह मीडिया फ़ोल्डर जिसे मूल नाम से मिलाना है। |
--media-url-prefix | स्थानीय फ़ाइलों के बजाय मीडिया का आधार URL। |
--field | आइटम का वह फ़ील्ड जिसमें ट्रांसक्रिप्ट जाएगा। डिफ़ॉल्ट conversation। |
--id-prefix | हर बनी हुई आईडी से पहले जोड़ी जाने वाली स्ट्रिंग। |
--speaker-key | स्रोत की वह कुंजी जिसमें वक्ता लेबल है। |
-r, --recursive | उपफ़ोल्डरों में भी जाता है। |
--dry-run | प्रति फ़ाइल पहचाना गया प्रारूप और टर्न संख्या बताता है। |
--emit-config | साथ में मिलती-जुलती config.yaml का अंश भी छापता है। |
-q, --quiet | प्रति-फ़ाइल रिपोर्ट दबा देता है। |
आइटम आईडी फ़ाइल नाम से आती हैं और अंत में लगा मीडिया एक्सटेंशन हटा दिया जाता है, इसलिए Whisper की interview_01.mp3.json से interview_01 बनता है, interview_01.mp3 नहीं।
वापस निर्यात करना
स्तरीय एनोटेशन ELAN EAF और Praat TextGrid में निर्यात होते हैं, इसलिए एक ट्रांसक्रिप्ट पूरा चक्कर लगा सकता है: उसे पढ़िए, Potato में एनोटेट कीजिए, निर्यात कीजिए, ELAN या Praat में सुधारिए और परिणाम वापस पढ़ लीजिए।
python -m potato.export --config config.yaml --format eaf --output ./out/
python -m potato.export --config config.yaml --format textgrid --output ./out/दोनों निर्यातक tiered_annotation के आउटपुट से काम करते हैं। बाकी स्कीमा मानक प्रारूपों के ज़रिए निर्यात होते हैं।
समस्या निवारण
| लक्षण | क्या हुआ |
|---|---|
| सब कुछ एक ही बड़े बुलबुले जैसा दिखता है | प्रारूप पहचाना नहीं गया और सादे अनुच्छेद वाले विकल्प पर चला गया। potato transcripts <file> --dry-run चलाइए; अगर वह plain text बताता है तो समय कभी पढ़े ही नहीं गए। आम तौर पर फ़ाइल .json या .srt के बजाय Whisper की .txt होती है, जिसमें कोई समय नहीं होता। |
| कोई वक्ता नहीं, सब Unassigned | स्रोत में वक्ता लेबल नहीं हैं। अकेला Whisper डायराइज़ नहीं करता, और YouTube के स्वतः कैप्शन भी नहीं। पहले डायराइज़ेशन चलाइए या एनोटेटर्स को इंटरफ़ेस में वक्ता चुनने दीजिए। |
| समय 1000 गुना ग़लत हैं | पहले कहीं सेकंड और मिलीसेकंड मिल गए। whisper.cpp के offsets, AssemblyAI और Whisper का TSV सभी मिलीसेकंड में हैं। |
| ट्रांसक्रिप्ट का पथ ही पाठ की तरह दिखता है | साइडकार फ़ाइल पढ़ी नहीं जा सकी, इसलिए पथ को सामग्री की तरह दिखाया गया। जाँचिए कि वह task_dir के भीतर हल होता है। सर्वर लॉग में सटीक कारण दर्ज होता है। |
| एक पंक्ति का ट्रांसक्रिप्ट फ़ाइल नाम की तरह पढ़ा जा रहा है | प्रदर्शन फ़ील्ड पर transcript_is_path: false लगाइए। |
उदाहरण परियोजना
Potato रिपॉज़िटरी में examples/audio/transcript-formats/ छह प्रारूपों को साथ-साथ दिखाता है, हर एक साइडकार फ़ाइल से लोड होकर: SubRip, WebVTT, Whisper JSON, YouTube json3, Praat TextGrid और Deepgram। छहों एक जैसे वक्ता बुलबुले बनाते हैं।
python potato/flask_server.py start examples/audio/transcript-formats/config.yaml -p 8000यही कार्य डाउनलोड करने योग्य शोकेस डिज़ाइन के रूप में भी उपलब्ध है: Transcript Format Ingestion।
कार्यान्वयन के विवरण के लिए स्रोत दस्तावेज़ देखिए।
आगे पढ़ें
- Whisper ट्रांसक्रिप्ट कैसे एनोटेट करें, पूरा मार्गदर्शन
- YouTube सबटाइटल कैसे एनोटेट करें, कैप्शन और उनकी सीमाओं के लिए
- संवाद एनोटेशन, वक्ता बुलबुला प्रदर्शन
- ऑडियो एनोटेशन, शून्य से तरंगरूप विभाजन
- एनोटेशन के लिए डेटा प्रारूप डिज़ाइन करना