Streaming डिक्टेशन
Parakeet-EOU-120M एक छोटा RNN-T streaming ASR मॉडल है जिसमें explicit end-of-utterance (EOU) head है, Apple Silicon के Neural Engine पर रियल-टाइम डिक्टेशन के लिए बनाया गया। यह गाइड DictateDemo को भी कवर करती है, macOS मेन्यू-बार संदर्भ ऐप जो हैंड्स-फ़्री, paste-anywhere डिक्टेशन के लिए streaming मॉडल को Silero VAD के साथ जोड़ता है।
यह क्या है
- Live partials — आप बोलते ही text अपडेट होता है, प्रत्येक chunk के बाद ~340 ms
- Explicit EOU — मॉडल तय करता है कि utterance कब समाप्त होती है, कोई मैनुअल बटन नहीं
- VAD-driven force-finalize — Silero backstop utterances को commit करता है भले ही EOU बैकग्राउंड नॉइज़ पर stall हो जाए
- 120 MB INT8 CoreML — Neural Engine पर चलता है, अन्य मॉडलों के लिए GPU को फ़्री छोड़ देता है
- 25 यूरोपीय भाषाएँ — upstream NeMo Parakeet TDT के समान vocabulary परिवार
आर्किटेक्चर
प्रति ऑडियो chunk तीन CoreML मॉडल पाइपलाइन्ड:
| कॉम्पोनेंट | विवरण |
|---|---|
| Encoder | Cache-aware Conformer। एक 64-frame mel chunk (640 ms) प्लस छह state tensors — attention KV cache, depthwise conv cache, और एक pre_cache mel loopback जो हाल के ऑडियो को prepend करता है ताकि FFT chunk boundaries में निरंतर signal देखे। |
| Decoder | Single-step LSTM prediction नेटवर्क। पिछले non-blank token का उपभोग करता है, एक embedding प्लस updated (h, c) state उत्सर्जित करता है। |
| Joint + EOU head | Encoder और decoder outputs को vocab + blank + EOU पर logits में fuse करता है। EOU class मॉडल का hard signal है कि utterance समाप्त हो गई। |
एक अलग EOU token क्यों
Plain RNNT silence के दौरान blanks उत्सर्जित करता है, जिसे decoder "utterance finished" signal किए बिना खुशी से absorb करता है। एक dedicated EOU head मॉडल को partial को final में commit करने के लिए hard cut करने देता है, punctuation/capitalization state को रीसेट करता है, और paste-to-app जैसी downstream actions को trigger करता है।
एक "silent" pause के दौरान keyboard clicks, mouse movement, और room tone कभी-कभी joint को non-blank token उत्सर्जित करने पर मजबूर कर सकते हैं, जो EOU debounce timer को रीसेट करता है और commit को stall करता है। Production पाइपलाइन joint EOU को एक external VAD-driven forceEndOfUtterance() backstop के साथ जोड़ती हैं — नीचे DictateDemo देखें।
मॉडल
| मॉडल | आकार | HuggingFace |
|---|---|---|
| Parakeet-EOU-120M (CoreML INT8) | ~120 MB | aufklarer/Parakeet-EOU-120M-CoreML-INT8 |
परफ़ॉर्मेंस
| मेट्रिक | मान |
|---|---|
| Weight memory | ~120 MB (INT8) |
| Peak inference memory | ~200 MB |
| Chunk latency (M-series) | ~30 ms compute / 640 ms ऑडियो (RTF ~0.056) |
| Partial latency end-to-end | ~340 ms (एक chunk) |
| Commit latency (VAD path) | speech बंद होने के बाद ~1 s |
| Compute target | Neural Engine (CoreML) |
त्वरित प्रारंभ — batch transcription
Streaming मॉडल SpeechRecognitionModel के अनुरूप भी है, इसलिए यह किसी भी generic STT मॉडल लेने वाले कोड के लिए drop-in के रूप में काम करता है:
import ParakeetStreamingASR
let model = try await ParakeetStreamingASRModel.fromPretrained()
let text = try model.transcribeAudio(audioSamples, sampleRate: 16000)
त्वरित प्रारंभ — async streaming
for await partial in model.transcribeStream(audio: samples, sampleRate: 16000) {
if partial.isFinal { print("FINAL: \(partial.text)") }
else { print("... \(partial.text)") }
}
प्रत्येक PartialTranscript text, isFinal, confidence, eouDetected (joint fired vs force-finalized), और एक monotonic segmentIndex carry करता है।
Long-lived session API (मिक इनपुट)
लाइव डिक्टेशन के लिए, एक बार एक session बनाएँ और माइक से आने वाले chunks को feed करें। Session आंतरिक रूप से buffer करता है और पर्याप्त samples जमा होने पर encoder चलाता है, इसलिए आप arbitrary chunk sizes push कर सकते हैं:
let session = try model.createSession()
// each mic chunk:
let partials = try session.pushAudio(float32Chunk16kHz)
for p in partials {
if p.isFinal { commit(p.text) }
else { showPartial(p.text) }
}
// when the stream ends:
let trailing = try session.finalize()
VAD force-finalize पैटर्न
जब आपकी पाइपलाइन में Silero VAD पहले से चल रहा है, तो fallback commit को drive करने के लिए इसका उपयोग करें ताकि बैकग्राउंड नॉइज़ EOU debounce timer को stall नहीं कर सके:
if hasPendingUtterance && !vadSpeechActive && vadSilentChunks >= 30 {
// ~960 ms of sustained silence per Silero
if let forced = session.forceEndOfUtterance() {
commit(forced.text)
}
hasPendingUtterance = false
}
// guardrail: don't double-commit if joint already fired EOU
if partials.contains(where: { $0.isFinal }) {
hasPendingUtterance = false
}
DictateDemo — macOS मेन्यू-बार संदर्भ ऐप
DictateDemo streaming session के ऊपर बना एक पूर्ण macOS मेन्यू-बार एजेंट है। यह एक बैकग्राउंड ऐप के रूप में चलता है, live partials के साथ माइक से ट्रांसक्राइब करता है, EOU या VAD silence पर utterances को ऑटो-commit करता है, और results को frontmost ऐप में paste करता है।
- ग्लोबल
Cmd+Shift+Dhotkey के साथ मेन्यू-बार ऐप - Floating HUD और ऑडियो लेवल indicator के साथ live partials
- VAD-guarded force-finalize (ऊपर का production पैटर्न)
Cmd+Shift+Vके साथ paste-to-frontmost-app- पहले लॉन्च पर मॉडल ऑटो-डाउनलोड (~120 MB)
cd Examples/DictateDemo
swift build
.build/debug/DictateDemo
पूर्ण कार्यान्वयन Examples/DictateDemo/DictateDemo/DictateViewModel.swift में रहता है: एक lock-protected buffer के साथ off-main ऑडियो sink, इसे drain करने के लिए 300 ms timer tick, leftover-sample carry-over के साथ Silero VAD, और एक guarded force-finalize। Examples/DictateDemo/Tests/DictateDemoTests.swift में matching regression tests multi-utterance, stuck-EOU, और noisy-silence परिदृश्यों को कवर करते हैं।
Streaming बनाम batch Parakeet
| Parakeet-EOU-120M (streaming) | Parakeet TDT 0.6B (batch) | |
|---|---|---|
| उपयोग केस | लाइव डिक्टेशन, रियल-टाइम captioning | फ़ाइल ट्रांसक्रिप्शन, offline jobs |
| Decoder | RNN-T + EOU head | Token-and-Duration Transducer |
| Chunk size | 640 ms streaming | Whole-file batch |
| Weight memory | ~120 MB | 500 MB |
| Throughput | ~18x रियल-टाइम | ~32x रियल-टाइम |
| Latency | ~340 ms partials | केवल end-of-file |
…आपको उपयोगकर्ता के बोलना समाप्त करने से पहले partials चाहिए। ऑडियो फ़ाइलों के batch ट्रांसक्रिप्शन के लिए, बड़ा Parakeet TDT 0.6B end-to-end तेज़ और अधिक सटीक है। दोनों मॉडल समान SentencePiece vocabulary साझा करते हैं, इसलिए आप tokenization बदले बिना उनके बीच swap कर सकते हैं।