Smart Turn — Konuşma sırası sonu algılama

Smart Turn v3.2, VAD bir duraklama bildirdikten sonra tek bir soruyu yanıtlar: konuşmacı sözünü bitirdi mi, yoksa cümlenin ortasında mı? Bir transkript yerine sesin kendisini — prozodi, tempo, tonlama — dinler, 23 dili kapsar ve her duraklamada bir kez, konuşma sırasının son 8 saniyesi üzerinde çalışır. Ağırlıklar Pipecat'in resmi Smart Turn v3.2 sürümüdür (BSD-2-Clause); Apple platformları için CoreML'e derlenmiş, Speech Core için ONNX'e aktarılmıştır.

Tek başına VAD neden yetmez

Bir ses etkinliği algılayıcısı yalnızca sessizliği duyar. İnsanlar düşünmek için cümle ortasında durur; bu yüzden yalnızca VAD kullanan bir ajan ya sözlerini keser ya da her cümleden sonra uzun, sabit bir zaman aşımı bekler. Smart Turn her duraklamayı doğrular: bitmiş bir cümle anında yanıt alır, cümle ortasındaki bir duraklama ajanın dinlemeye devam etmesini sağlar.

Nasıl çalışır

Smart Turn bir VAD değildir ve tek başına konuşma algılamaz. Ne zaman sorulacağına karar veren akışlı Silero VAD ile birlikte kullanılır. Bir sınıflandırıcı bağlıyken, doğrulanan bir duraklama bir hüküm değil, bir soru olur:

  1. Her duraklamada bir kez sor. Silero bir duraklamayı doğruladığında (offset eşiğinden sonra minSilenceDuration), işlemci o ana kadarki konuşma sesini sınıflandırıcıya verir — VAD başlangıcından 0,5 s öncesinden geçerli parçaya kadar, en fazla son 8 saniye.
  2. Tamamlandı. Olasılık threshold (0,5) değerine eşit veya üzerindeyse: .speechEnded her zamanki gibi tetiklenir.
  3. Bekletme. Eşiğin altında segment açık kalır. Konuşmacı devam ederse aynı segment sürer — ikinci bir .speechStarted olmaz — ve bir sonraki doğrulanan duraklama, uzayan konuşma sırasıyla yeniden sorar.
  4. Sessizlik sınırı. Sessizlik maxSilenceDuration (2,0 s, duraklamanın başından ölçülür) değerine ulaşırsa segment yine de biter; böylece sözü askıda bırakan bir konuşmacı da yanıt alır. Segmentin endTime değeri sınırın dolduğu an değil, konuşmanın durduğu yerdir.

flush() akışın sonunda bekletilen segmenti sonuçlandırır, reset() ise temizler. Hata fırlatan bir sınıflandırıcı "tamamlandı" sayılır; dolayısıyla arızalanan bir model konuşmayı asla tıkamaz. isHoldingTurn bekletme durumunu, lastTurnCompletionProbability en son yanıtı bildirir.

Model

ÖzellikDeğer
MimariWhisper-Tiny kodlayıcı + attention pooling + sigmoid çıkışlı MLP başlığı
Parametre8,0M
Girdi16 kHz mono sesin son 8 saniyesi (128.000 örnek); daha kısa konuşmalar baştan sıfırla doldurulur, diğer örnekleme hızları yeniden örneklenir
ÇıktıKonuşma sırasının tamamlanmış olma olasılığı, [0, 1] aralığında; varsayılan eşik 0,5
Diller23 — Arabic, Bengali, Chinese, Danish, Dutch, English, Finnish, French, German, Hindi, Indonesian, Italian, Japanese, Korean, Marathi, Norwegian, Polish, Portuguese, Russian, Spanish, Turkish, Ukrainian, Vietnamese
LisansBSD-2-Clause

Dışa aktarımlar, özgün modelin eğitildiği dalga biçimi normalizasyonu dahil Whisper log-mel ön ucunu içerir; bu yüzden çağıranlar ham ses verir — Swift veya C++ tarafında özellik çıkarımı yoktur.

Performans

Dışa aktarımBoyutDoğruluk8 s pencere başına gecikme
CoreML (CPU + Neural Engine)16,8 MB%92,93,5 ms
ONNX fp32 (ONNX Runtime, CPU)33 MB%92,92 iş parçacığıyla ~36 ms, 4 ile 20 ms
ONNX int8 (ONNX Runtime, CPU)11,1 MB%93,02 iş parçacığıyla ~36 ms, 4 ile 20 ms

Doğruluk, özgün test kümesinden 1.000 klip üzerinde ölçülmüştür; CoreML ve fp32 ONNX dışa aktarımları bu kliplerde özgün fp32 modeliyle birebir eşleşir. Gecikme, Apple M5 Pro üzerinde tek bir 8 saniyelik penceredir. Duraklama başına tek çağrı, VAD'ın zaten beklediği duraklamaya fark edilir bir şey eklemez.

Swift API

Kaydedilmiş bir ifade üzerinde tek seferlik kontrol:

import SpeechVAD

let turn = try await SmartTurnModel.fromPretrained()
try turn.prewarm()   // compile the graph before the first real pause

let probability = try turn.turnCompleteProbability(
    audio: utterance, sampleRate: 16_000)
if probability >= SmartTurnModel.defaultThreshold {
    // finished turn — reply now
}

Akışlı VAD'a bağlandığında, doğrulanan her duraklama segment bitmeden önce kontrol edilir:

let vad = try await SileroVADModel.fromPretrained(engine: .coreml)
let turn = try await SmartTurnModel.fromPretrained()

let processor = StreamingVADProcessor(
    model: vad,
    config: .sileroDefault,
    turnCompletion: turn,
    turnCompletionConfig: TurnCompletionConfig(threshold: 0.5, maxSilenceDuration: 2.0))

for chunk in microphoneChunks {            // Float32 @ 16 kHz
    for event in processor.process(samples: chunk) {
        switch event {
        case .speechStarted(let time): print("speech at \(time)s")
        case .speechEnded(let segment): print("turn \(segment.startTime)–\(segment.endTime)s")
        }
    }
}
let remaining = processor.flush()

SmartTurnModel, AudioCommon içindeki TurnCompletionProvider protokolüne uyar; dolayısıyla aynı biçimdeki başka herhangi bir sınıflandırıcı onun yerine bağlanabilir. fromPretrained(cacheDir:offlineMode:) diğer modellerle aynı önbellek ve çevrimdışı kurallarını izler.

VoicePipeline

VoicePipeline aynı sınıflandırıcıyı kabul eder; böylece sesli ajan, STT, TTS veya VAD kurulumunda hiçbir değişiklik yapmadan insanların sözünü kesmeyi bırakır. PipelineConfig'in iki alanı ve bir metot bağlantıyı kurar; speech-swift v0.0.27 veya üstü (speech-core v0.0.14'ten gelen SpeechCore.xcframework) gerekir.

import SpeechCore
import SpeechVAD

let smartTurn = try await SmartTurnModel.fromPretrained()
try smartTurn.prewarm()

var config = PipelineConfig()
config.turnCompletionThreshold = 0.5   // pause ends the turn when p >= this
config.turnCompletionMaxSilence = 2.0  // seconds of silence that end a held turn anyway; 0 = never

let pipeline = VoicePipeline(stt: stt, tts: tts, vad: vad, config: config, onEvent: { print($0) })
pipeline.setTurnCompletion(smartTurn)   // before start(); nil detaches
pipeline.start()
APIVarsayılanEtki
turnCompletionThreshold0,5Bir VAD duraklamasının kullanıcının konuşma sırasını bitirmesi için gereken tamamlanma olasılığı alt sınırı. Yalnızca bir sınıflandırıcı bağlandıktan sonra kullanılır.
turnCompletionMaxSilence2,0 sDuraklamanın başından itibaren ölçülen sessizlik saniyesi; bu süre dolunca sınıflandırıcının reddettiği konuşma sırası yine de biter. 0 = asla.
setTurnCompletion(_:)Herhangi bir TurnCompletionProvider bağlar. start() öncesinde çağırın; ayırmak için nil geçin. Hata fırlatan bir sınıflandırıcı "tamamlandı" sayılır, bu yüzden arızalı bir model konuşmayı asla askıda bırakmaz.

Sınıflandırıcı bağlıyken bir VAD duraklaması, kullanıcının konuşma sırasını yalnızca olasılık eşiğe ulaştığında bitirir; altında kaldığında ardışık düzen dinlemeye devam eder, yeniden başlayan konuşma aynı sırayı sürdürür (ikinci bir speechStarted olmaz) ve turnCompletionMaxSilence bekletilen sırayı yine de sonlandırır. Eager STT bu reddi dikkate alır ve sınıflandırıcı ses iş parçacığında her duraklamada bir kez çalışır; bu yüzden yükledikten sonra prewarm() çağırın.

Ayarlama

AyarVarsayılanEtki
threshold0,5Daha düşük değerler konuşma sıralarını daha erken bitirir ve daha sık araya girer; daha yüksek değerler yanıtlamadan önce daha uzun bekler. Değiştirmeden önce gerçek konuşmalarda lastTurnCompletionProbability değerini izleyin.
maxSilenceDuration2,0 sDuraklamanın başından ölçülen kesin sınır. Reddedilen bir duraklama konuşma sırasını bundan daha uzun süre bekletemez. 0 sınırı kapatır: bekletilen segment o zaman konuşmayı veya flush() çağrısını bekler.
preRollDuration0,5 sSınıflandırıcı girdisine dahil edilen, VAD başlangıcından önceki ses; böylece kesilen ilk hece de modele ulaşır.

Silero'nun minSilenceDuration değeri, bir duraklamanın ne zaman doğrulanacağına ve dolayısıyla sınıflandırıcıya ne zaman sorulacağına karar vermeye devam eder. İlk gerçek duraklamanın graf derleme maliyetini ödememesi için yüklemeden sonra prewarm() çağırın.

CLI kullanımı

# Probability, complete/incomplete verdict and inference time for one utterance
speech turn utterance.wav

# Custom threshold, JSON output
speech turn utterance.wav --threshold 0.7 --json

# Local bundle, no download
speech turn utterance.wav --model-dir ~/smart-turn-coreml

# Streaming VAD with Smart Turn confirming each pause; mid-sentence pauses merge
speech vad-stream call.wav --smart-turn
speech vad-stream call.wav --smart-turn --turn-threshold 0.6 --turn-max-silence 1.5
SeçenekKomutAçıklama
--thresholdturnKonuşma sırasının tamamlanmış sayıldığı olasılık eşiği (varsayılan 0,5)
--jsonturnprobability, threshold, complete ve latency_ms değerlerini JSON olarak verir
--model, -mturnAynı düzene sahip HuggingFace deposu (varsayılan aufklarer/Smart-Turn-v3.2-CoreML)
--model-dirturnsmart_turn.mlmodelc ve config.json içeren yerel dizin; indirmeyi atlar
--smart-turnvad-streamBir segmenti bitirmeden önce her duraklamayı Smart Turn ile doğrular
--turn-thresholdvad-streamSmart Turn tamamlanma eşiği (varsayılan 0,5)
--turn-max-silencevad-streamReddedilen bir duraklamadan sonra segmenti yine de bitiren sessizlik saniyesi (varsayılan 2,0)

speech turn dosyayı (herhangi bir örnekleme hızı) yükler, son 8 saniyeyi puanlar ve olasılığı, eşiği aşıp aşmadığını ve çıkarım süresini yazdırır. Eşiği kendi kayıtlarınızda ayarlamak için kullanın. Tam bayrak listesi CLI başvurusunda yer alır.

C++ / Android

Speech Core aynı modeli Linux, Windows ve Android için OnnxSmartTurn olarak sunar (yalnızca ONNX Runtime; LiteRT sürümü yoktur). VoicePipeline::set_turn_completion() onu start() öncesinde bağlar; bundan sonra bir VAD duraklaması kullanıcının konuşma sırasını yalnızca olasılık turn_completion_threshold (0,5) değerine ulaştığında bitirir ve turn_completion_max_silence (2,0 s) bekletilen bir konuşma sırasını yine de sonlandırır. C API aynı kancayı sc_turn_completion_vtable_t + sc_pipeline_set_turn_completion() olarak sunar; böylece Kotlin veya Swift ana bilgisayarları kendi sınıflandırıcılarını VAD ile aynı şekilde köprüleyebilir.

#include <speech_core/models/onnx_smart_turn.h>

speech_core::OnnxSmartTurn model("/models/smart-turn-v3.2-int8.onnx");

// Audio of the turn so far at any rate (resampled to 16 kHz internally).
float p = model.turn_complete_probability(turn.data(), turn.size(), rate);

// Or let the pipeline ask it on every VAD pause (before start()).
pipeline.set_turn_completion(&model);

Speech Core'un speech CLI'si bir kaydı macOS'takiyle aynı şekilde puanlar:

speech download-models        # fetches the int8 graph with the other ONNX models
speech turn recording.wav --threshold 0.5 --json

Model dosyaları, C API sözleşmesi ve CLI, Speech Core sayfasında ve deponun docs/models.md dosyasında belgelenmiştir.

Model indirmeleri

ModelBackendBoyutHuggingFace
Smart-Turn-v3.2CoreML16,8 MBaufklarer/Smart-Turn-v3.2-CoreML
Smart-Turn-v3.2ONNX (fp32 + int8)33 MB / 11,1 MBsoniqo/Smart-Turn-v3.2-ONNX

Kaynak