Đọc chính tả streaming

Parakeet-EOU-120M là một mô hình ASR streaming RNN-T nhỏ với một đầu ra phát hiện kết thúc câu nói (EOU) rõ ràng, được xây dựng cho đọc chính tả thời gian thực trên Neural Engine của Apple Silicon. Hướng dẫn này cũng đề cập đến DictateDemo, ứng dụng tham chiếu trên thanh menu macOS kết nối mô hình streaming với Silero VAD để đọc chính tả rảnh tay, dán-mọi-nơi.

Đây là gì

Kiến trúc

Ba mô hình CoreML được nối ống theo từng chunk âm thanh:

Thành phầnMô tả
Bộ mã hoáConformer có cache. Nhận một chunk mel 64 frame (640 ms) cùng sáu tensor trạng thái — cache KV attention, cache conv depthwise, và một loopback mel pre_cache chèn âm thanh quá khứ gần đây vào phía trước để FFT thấy tín hiệu liên tục qua các biên chunk.
Bộ giải mãMạng dự đoán LSTM một bước. Nhận token non-blank trước đó, sinh ra embedding cùng với trạng thái (h, c) đã cập nhật.
Joint + đầu ra EOUHợp nhất đầu ra của bộ mã hoá và bộ giải mã thành logit trên vocab + blank + EOU. Lớp EOU là tín hiệu rõ ràng của mô hình rằng một câu nói đã kết thúc.

Tại sao cần một token EOU riêng

RNNT thuần sinh ra blank trong khi im lặng, mà bộ giải mã vui vẻ hấp thụ mà không phát tín hiệu "câu nói đã kết thúc". Một đầu ra EOU chuyên dụng cho phép mô hình thực hiện một cú cắt dứt khoát để commit phần tạm thời thành phần cuối cùng, reset trạng thái dấu câu/viết hoa, và kích hoạt các hành động downstream như dán-vào-ứng-dụng.

EOU bị nhiễu trong thực tế

Tiếng gõ phím, cử động chuột, và tiếng ồn phòng trong một khoảng "im lặng" có thể khiến joint thi thoảng sinh ra một token non-blank, reset bộ đếm debounce của EOU và làm đứng commit. Pipeline production ghép EOU của joint với một chỗ dựa forceEndOfUtterance() bên ngoài điều khiển bởi VAD — xem DictateDemo bên dưới.

Mô hình

Mô hìnhKích thướcHuggingFace
Parakeet-EOU-120M (CoreML INT8)~120 MBaufklarer/Parakeet-EOU-120M-CoreML-INT8

Hiệu năng

Chỉ sốGiá trị
Bộ nhớ trọng số~120 MB (INT8)
Bộ nhớ suy luận đỉnh~200 MB
Độ trễ mỗi chunk (chip series M)~30 ms tính toán / 640 ms âm thanh (RTF ~0.056)
Độ trễ từng phần end-to-end~340 ms (một chunk)
Độ trễ commit (đường VAD)~1 s sau khi ngừng nói
Đích tính toánNeural Engine (CoreML)

Bắt đầu nhanh — phiên âm theo lô

Mô hình streaming cũng tuân thủ SpeechRecognitionModel, nên nó hoạt động như một thay thế trực tiếp trong bất kỳ mã nào nhận một mô hình STT chung:

import ParakeetStreamingASR

let model = try await ParakeetStreamingASRModel.fromPretrained()
let text = try model.transcribeAudio(audioSamples, sampleRate: 16000)

Bắt đầu nhanh — streaming bất đồng bộ

for await partial in model.transcribeStream(audio: samples, sampleRate: 16000) {
    if partial.isFinal { print("FINAL: \(partial.text)") }
    else               { print("... \(partial.text)") }
}

Mỗi PartialTranscript mang text, isFinal, confidence, eouDetected (do joint kích hoạt vs. force-finalize), và một segmentIndex đơn điệu.

API session dài hạn (đầu vào micro)

Cho đọc chính tả trực tiếp, tạo session một lần rồi đẩy chunk vào khi nhận được từ micro. Session đệm bên trong và chạy bộ mã hoá khi tích luỹ đủ mẫu, nên bạn có thể đẩy chunk với kích thước tuỳ ý:

let session = try model.createSession()

// mỗi chunk từ micro:
let partials = try session.pushAudio(float32Chunk16kHz)
for p in partials {
    if p.isFinal { commit(p.text) }
    else          { showPartial(p.text) }
}

// khi stream kết thúc:
let trailing = try session.finalize()

Mẫu force-finalize với VAD

Khi đã có một Silero VAD chạy trong pipeline, hãy dùng nó để kích hoạt một commit dự phòng để tiếng ồn nền không thể làm đứng bộ đếm debounce của EOU:

if hasPendingUtterance && !vadSpeechActive && vadSilentChunks >= 30 {
    // ~960 ms im lặng kéo dài theo Silero
    if let forced = session.forceEndOfUtterance() {
        commit(forced.text)
    }
    hasPendingUtterance = false
}

// chốt chặn: đừng commit hai lần nếu joint đã kích hoạt EOU
if partials.contains(where: { $0.isFinal }) {
    hasPendingUtterance = false
}

DictateDemo — ứng dụng tham chiếu trên thanh menu macOS

DictateDemo là một agent hoàn chỉnh trên thanh menu macOS được xây trên session streaming. Nó chạy như một ứng dụng nền, phiên âm từ micro với bản tạm thời trực tiếp, tự động commit câu nói khi EOU hoặc khi VAD im lặng, và dán kết quả vào ứng dụng đang ở phía trước.

cd Examples/DictateDemo
swift build
.build/debug/DictateDemo

Toàn bộ phần triển khai nằm trong Examples/DictateDemo/DictateDemo/DictateViewModel.swift: một sink âm thanh ngoài luồng main với một buffer được bảo vệ bằng lock, một tick timer 300 ms để rút buffer, Silero VAD với truyền tiếp các mẫu thừa, và một force-finalize có bảo vệ. Các test hồi quy tương ứng trong Examples/DictateDemo/Tests/DictateDemoTests.swift bao gồm các kịch bản nhiều câu nói, EOU bị kẹt, và im lặng có nhiễu.

Streaming so với Parakeet theo lô

Parakeet-EOU-120M (streaming)Parakeet TDT 0.6B (lô)
Tình huống dùngĐọc chính tả trực tiếp, phụ đề thời gian thựcPhiên âm tệp, công việc offline
Bộ giải mãRNN-T + đầu ra EOUToken-and-Duration Transducer
Kích thước chunkStreaming 640 msTheo lô toàn tệp
Bộ nhớ trọng số~120 MB500 MB
Throughput~18× thời gian thực~32× thời gian thực
Độ trễBản tạm thời ~340 msChỉ ở cuối tệp
Chọn mô hình streaming khi…

…bạn cần các bản tạm thời trước khi người dùng nói xong. Cho phiên âm theo lô các tệp âm thanh, Parakeet TDT 0.6B lớn hơn nhanh hơn end-to-end và chính xác hơn. Hai mô hình dùng chung cùng một vocabulary SentencePiece, nên bạn có thể chuyển đổi giữa chúng mà không cần thay đổi tokenization.