थेट भाषांतरातील बहुतेक विलंब ही प्रतीक्षा असते: स्ट्रीमची, पुढच्या शब्दाची, वाक्याची. त्यातील एक भाग तुमच्या नियंत्रणात असतो: लेटन्सी मोड, म्हणजे कमी विलंब किंवा कमी बदल.
थेट भाषांतर वाचणाऱ्या श्रोत्याला प्रत्येक ओळ वक्त्याने बोलल्यानंतर काही सेकंदांनी दिसते. हे अंतर एकच विलंब नसून अनेक विलंब एकत्र जोडलेले असतात, आणि त्यांपैकी बहुतेक एक प्रकारची प्रतीक्षा असते. कोणती प्रतीक्षा कोणती आहे हे समजले, की लेटन्सी मोड निवडणे सोपे होते, आणि रीडर बनवणाऱ्या डेव्हलपरला काय दाखवायचे आणि केव्हा, हे कळते.
आकड्यांपूर्वी एक उपयुक्त मापदंड: मानवी समांतर दुभाषी साधारणपणे वक्त्यापेक्षा 2 ते 4 सेकंद मागे बोलतो. दुभाषी या अंतराला ear-voice span म्हणतात. क्रियापद शेवटी येणाऱ्या भाषांशी ते क्रियापदाची वाट पाहत नाहीत, तर त्याचा अंदाज घेतात, किंवा वाक्य स्वतंत्रपणे उभे राहू शकतील अशा तुकड्यांमध्ये विभागतात. एक-दोन सेकंदांचा विलंब हा सॉफ्टवेअरचा दोष नाही; एक चांगला मानवी दुभाषीदेखील तेवढाच विलंब घेतो.
VocalStack वरील प्रत्येक थेट ट्रान्सक्रिप्शन याच टप्प्यांमधून, याच क्रमाने जातो, आणि प्रत्येक टप्पा आधीच्या टप्प्याची वाट पाहतो.
मूळ भाषेतील मजकूर बोलल्याबरोबर जवळजवळ तसाच वाचकापर्यंत पोहोचतो. भाषांतर एक-दोन सेकंदांनी मागून येते, आणि बोललेले वाक्य त्याच्या भाषांतरानंतर येते; म्हणूनच आवाजाची क्लिप नेहमी सर्वात शेवटी पोहोचते. पण साखळीचा पहिला दृश्य परिणाम आवाजाच्या खूप आधी दिसतो: मजकूर स्वतः हलू लागतो.
थेट ट्रान्सक्रिप्टमध्ये लोकांच्या पहिल्या लक्षात येणारी गोष्ट म्हणजे सर्वात नवीन शब्द हलतात. एखादा वाक्यांश दिसतो, बदलतो आणि मग स्थिर होतो. हा ड्राफ्ट टप्प्याचा परिणाम आहे, आणि त्यामागे प्रत्येक स्पीच रेकग्निशन प्रणालीला लागू होणारे कारण आहे.
एखादा शब्द कसा ठरतो हे रेकग्निशन प्रणाली त्या शब्दानंतर काय येते ते पाहून ठरवते. "I scream" आणि "ice cream" पुढचा शब्द ऐकू येईपर्यंत सारखेच वाजतात; शेवटचा "s" या शब्दाचा असू शकतो किंवा पुढच्या शब्दाचा. शब्दाच्या उजवीकडे आवाज येईपर्यंत त्याचे स्पेलिंग अंदाजच असते, म्हणून कोणत्याही थेट ट्रान्सक्रिप्टमधील सर्वात नवीन शब्द नेहमी सर्वात कमी खात्रीचे असतात. ड्राफ्ट म्हणजे हा अंदाज लपवून न ठेवता आधीच दाखवलेला असतो.
प्रत्येक ड्राफ्ट थेट शेपटीची जागा पूर्णपणे घेतो: शेवटच्या कमिटनंतर ऐकलेले, अजूनही बदलणारे शब्द. कमिट अंतिम असते. ती कधीच बदलत नाही, तिच्यासोबत शब्द-स्तरावरील वेळ असते, आणि वाचकाला काही चुकले आहे का हे कळावे म्हणून कमिट्स अंतर न ठेवता क्रमांकित असतात.
डेव्हलपरसाठी realtime API चा हा एक नियम आहे: प्रत्येक कमिट केलेला सेगमेंट रेंडर करा, मग त्यानंतर नवीनतम ड्राफ्ट दाखवा, आणि कमिट आल्यावर ड्राफ्ट साफ करा. ड्राफ्ट जोडत गेलात तर डुप्लिकेट आणि चमकणारा मजकूर तयार होतो; कमिट फक्त शेपटी वापरून टाकते. WebSocket tutorial हा नेमका याच पद्धतीवर आधारित रीडर बनवतो.
होस्टसाठी, मजकूर हलणे ही कमी विलंबाची किंमत आहे. वाक्यांश पूर्ण होण्याआधीच शब्द दाखवल्यामुळेच ट्रान्सक्रिप्ट थेट वाटते. पण भाषांतर ही युक्ती परवडू शकत नाही, कारण अर्ध्या वाक्यावरून एखादा शब्द अंदाजाने सांगता येतो, पण भाषांतर अंदाजाने करता येत नाही.
शब्दांचा क्रम हेच कारण आहे की भाषांतर ड्राफ्टच्या बरोबरीने जाऊ शकत नाही. जर्मन भाषेत क्रियापद कलमाच्या शेवटी येऊ शकते, आणि जपानी भाषेत क्रियापद शेवटी येते. कोणत्याही भाषांतरकाराला योग्य अर्थ देण्यासाठी पूर्ण कलम हवे असते. शब्दशः भाषांतर केल्यास श्रोत्याच्या हातात असे तुकडे पडतात, जे कलम संपेपर्यंत न समजता धरून ठेवावे लागतात. जर्मन भाषेमुळे दुभाष्यांना सॉफ्टवेअरने असा प्रयत्न करण्याच्या खूप आधीपासून क्रियापदाची वाट पाहावी लागत आहे.
VocalStack म्हणूनच शब्दांऐवजी वाक्यांचे भाषांतर करते. वाक्ये डीफॉल्टनुसार चालू असतात, आणि त्या स्थितीत सर्व्हर कमिट्सना एका वाक्यात जोडून संपूर्ण वाक्याचे भाषांतर करतो. वाक्य उघडे असताना त्याचे भाषांतर तात्पुरते असते; ते बंद झाल्यावर भाषांतर अंतिम होते. वाचक प्रत्येक वाक्यासाठी एकच नोंद ठेवतो, आणि अपडेट येईल तसे ती बदलतो.
बोलण्यासाठी आणखी प्रतीक्षा लागते. फक्त बंद झालेले वाक्यच मोठ्याने वाचले जाते, कारण जे वाक्य अजून बदलत आहे ते प्रत्येक बदलावर पुन्हा संश्लेषित करावे लागेल. लांब वाक्य तुकड्यांमध्ये वाचले जाते, त्यामुळे बाकीचे तयार होत असताना पहिला तुकडा वाजू शकतो.
वाक्ये बंद असतील तर प्रत्येक कमिटला स्वतःची भाषांतर फ्रेम मिळते. त्या पद्धतीत कोणतीही प्रतीक्षा नसते, पण संपूर्ण वाक्ये खूप चांगली वाचली जातात.
हे सर्व विलंब ऑडिओ VocalStack पर्यंत पोहोचल्याच्या क्षणापासून मोजले जातात. अनेक प्रसारणांसाठी, तो ऑडिओ तिथे पोहोचला तेव्हाच आधीच उशिरा आलेला असतो.
जेव्हा स्रोत मायक्रोफोन नसून स्ट्रीम असतो, तेव्हा काहीही ट्रान्सक्राइब होण्याआधीच ऑडिओ मागे असतो. तो लाइव्ह एजच्या, म्हणजे स्ट्रीमने प्रकाशित केलेल्या सर्वात नवीन क्षणाच्या मागे असतो.
सामान्य इंटरनेट रेडिओ स्टेशन प्रकाशित करतात तसा साधा HTTP ऑडिओ स्ट्रीम साधारणपणे 1 ते 3 सेकंद मागे चालतो. सर्व्हर एक burst buffer ठेवतो: अलीकडच्या ऑडिओचे काही सेकंद, एकदम पाठवलेले, जेणेकरून नवीन श्रोत्याचा प्लेयर अडखळल्याशिवाय सुरू होऊ शकतो. प्रत्येक श्रोता, VocalStack सुद्धा, तितक्या मागे सामील होतो. HLS अधिक वाईट आहे: त्याची प्लेलिस्ट क्लायंटला लाइव्ह एजपासून तीन सेगमेंट मागे सुरू करते, जे सेगमेंटच्या लांबीनुसार प्रत्यक्षात अनेक सेकंद ते अर्ध्या मिनिटापर्यंत असते. स्टँडर्ड DASH साधारणपणे HLS च्याच पट्ट्यात येतो; फक्त त्याचा लो-लेटन्सी प्रकार त्यापेक्षा खूप कमी असतो. स्टेशनचा "लाइव्ह" स्ट्रीम हा कदाचित त्या पत्रासारखा लाइव्ह असतो जे "ताजे" म्हणून पोहोचते.
हे आकडे अंदाजे आहेत, आणि ते स्ट्रीमचे आहेत, ट्रान्सक्रिप्शनचे नाहीत: VocalStack च्या बाजूचे कोणतेही सेटिंग ते सेकंद परत मिळवू शकत नाही. त्या सेकंदांना एखाद्या इव्हेंटसाठी महत्त्व असेल, तर सार्वजनिक स्ट्रीमऐवजी मायक्रोफोन किंवा एन्कोडरमधून स्टेजचा ऑडिओ द्या. स्ट्रीमचा विलंब VocalStack ने एक शब्दही ऐकण्याआधीच निश्चित झालेला असतो; ज्याला तुम्ही खरोखर हलवू शकता तो म्हणजे लेटन्सी मोड.
लेटन्सी मोड एकच गोष्ट करतो: विलंब आणि अचूकता यांमधील संतुलन ठरवतो. ही सेटिंग थेट ट्रान्सक्रिप्शन तयार करताना Advanced खाली असते, आणि ते चालू असताना Speed टॅबवर असते. तिथे चिप AUTO, SPEED किंवा ACCURACY असे दिसते (Fast हे SPEED म्हणून दिसते). API वर session.update चालू स्ट्रीममध्ये मोड बदलते.
व्यापार हा नावांवरून सुचतो तसाच आहे. Fast मजकूर लवकर बाहेर काढतो, पण त्यातील अधिक भाग पुन्हा बदलतो; Accuracy थोडा जास्त वेळ घेतो आणि कमी बदलतो. खाली बसून भाषांतरित सबटायटल वाचणारे प्रेक्षक अतिरिक्त सेकंद क्वचितच लक्षात घेतात, पण सतत बदलणारे शब्द मात्र लगेच लक्षात येतात. म्हणूनच विलंब चार्ट सपाट राहिल्यास Accuracy हे अनेकदा अधिक सौम्य सेटिंग असते. Auto आपली भूमिका स्पष्ट दाखवतो: अंतर भरून काढण्यासाठी गती वाढवलेल्या ओळीला होस्टच्या ट्रान्सक्रिप्टमध्ये FAST MODE बॅज असतो, आणि तिथे अचूकता कमी असू शकते अशी टीप असते.
मोड कोणताही असो, पहिल्या शब्दाआधी ट्रान्सक्रिप्शन तयार असले पाहिजे, आणि ते तयार करण्याचा विलंब हा साखळीतील असा एकच विलंब आहे जो एकदाच भरावा लागतो.
काही प्लॅनवर थेट ट्रान्सक्रिप्शन सुरू व्हायला काही सेकंद लागतात. किती वेळ लागतो हे प्लॅनवर अवलंबून असते: pricing page वरील Start-up speed या ओळीत Pay as you go वर 15 सेकंदांपर्यंतच्या कोल्ड स्टार्टपासून Enterprise वर नेहमी वॉर्म असण्यापर्यंत मूल्ये दिली आहेत.
API वापरताना, ही प्रतीक्षा सत्र सुरू होत असताना session.loading फ्रेम्समध्ये दिसते, आणि त्यानंतर session.ready येते; session.ready आल्यावरच क्लायंट ऑडिओ पाठवतो. यादरम्यान लिंक उघडणाऱ्या श्रोत्याला "लाइव्ह. पहिली ओळ थोड्याच वेळात दिसेल." असा संदेश दिसतो. ट्रान्सक्रिप्शन चालू झाले, की ही प्रतीक्षा मागे पडते, आणि उरतो तो एकच प्रश्न: उरलेल्या विलंबापैकी किती भाग तुम्ही अजूनही सोबत घेऊन चालत आहात.
लाइव्ह ट्रान्सक्रिप्शन चालू असताना, होस्टच्या Speed टॅबवर या सर्वांची बेरीज दिसते: वक्ता आणि मजकूर यांच्यातील सध्याचे अंतर, त्यासोबत मोड चिप, आणि संपूर्ण रेकॉर्डिंगमधील त्या अंतराचा आलेख, त्याची सरासरी आणि सर्वोच्च मूल्य यांसह. ट्रान्सक्रिप्टमध्ये, श्रोत्यांपर्यंत उशिरा पोहोचलेल्या ओळीवर, ती बोलली गेली आणि ती पोहोचली यामधील सेकंदांची संख्या दाखवणारा बॅज असतो.
आलेख कमी आणि सपाट राहिला, तर मोड ऑडिओला योग्य आहे. आलेख चढत राहिला, तर पाइपलाइन मागे पडत आहे. Accuracy वर असताना, हीच वेळ Auto वर जाण्याची असू शकते; तो अंतर भरून निघेपर्यंत काही अचूकता देऊन गती मिळवतो.
डेव्हलपरला मात्र एकच आकडा मिळतो. realtime सत्र संपते तेव्हा session.done मध्ये stats.realtimeFactor असतो: ट्रान्सक्राइब केलेला ऑडिओ भागिले तो ट्रान्सक्राइब करायला लागलेला वेळ. एक नोंद महत्त्वाची: स्पीच रेकग्निशनच्या साहित्यात real-time factor म्हणजे साधारणपणे त्याचा व्युत्क्रम, प्रक्रिया वेळ भागिले ऑडिओ वेळ, जिथे कमी आकडा चांगला. VocalStack तो उलट पद्धतीने नोंदवतो, म्हणून येथे जास्त आकडा चांगला: थेट सत्र सुमारे 1 च्या जवळ असते, आणि 1 पेक्षा कमी म्हणजे पाइपलाइनला ट्रान्सक्रिप्शन करता येण्यापेक्षा ऑडिओ वेगाने पोहोचला.
यातील कोणताही सेकंद रहस्यमय नाही. काही स्ट्रीमचे आहेत, काही एखादा शब्द पुढच्या शब्दाची वाट पाहतो त्यातून येतात, काही वाक्य भाषांतराला लागते त्यासाठी, आणि उरलेले तुम्ही निवडलेल्या लेटन्सी मोडचे आहेत. फ्रेम-फ्रेम तपशिलासाठी API reference पाहा, आणि home page वरील डेमोमध्ये संपूर्ण साखळी चालताना दिसते.