Traduzione automatica · Originale inglese

Smart Turn

p99 · VAP — Modelli

Smart Turn v3.2 risponde una domanda dopo VAD ha concluso l'oratore, o sono a metà strada? Ascolta l'audio stesso — prosodia, ritmo, intonazione — piuttosto che una trascrizione, coperture 23 lingue, e corre una volta per pausa sull'ultimo 8 secondi del giro. I pesi sono il Pipecat ufficiale Smart Turn v3.2 rilascio (BSD-2-Clause), compilato a CoreML per piattaforme Apple ed esportate a ONNX per Speech Core.

Perché non è sufficiente un VAD solo

Un rilevatore di attività vocale sente solo il silenzio. La gente si ferma a metà della frase per pensare, quindi un agente di sola VAD li taglia o li aspetta un lungo, tempo fisso dopo ogni frase. Smart Turn

Come funziona

Smart Turn non è un VAD e non rileva il discorso da solo. È abbinato allo streaming Silero VAD

  1. Chiedi una volta per pausa. Quando Silero conferma una pausa ( minSilenceDuration dopo la soglia di offset), il processore consegna l'audio del giro fino ad ora — da 0,5 s prima dell'impostazione VAD del chunk corrente, tappato negli ultimi 8 secondi.
  2. Completo. Probabilità a o sopra threshold (0.5): .speechEnded
  3. Hold. Sotto la soglia il segmento rimane aperto. Se l'altoparlante riprende, lo stesso segmento continua — nessun secondo .speechStarted — e la prossima pausa confermata chiede di nuovo con il giro più lungo.
  4. Cappuccio di silenzio. Se il silenzio arriva a maxSilenceDuration (2.0 s, misurato dall'inizio della pausa), il segmento termina comunque, quindi un altoparlante che si allontana riceve ancora una risposta. Il segmento è endTime

flush() stabilisce un segmento tenuto alla fine del flusso e reset() Un classificatore che lancia il conteggio come "completo", quindi un modello inadeguato non blocca mai la conversazione. isHoldingTurn segnala lo stato di detenzione e lastTurnCompletionProbability la risposta più recente.

Modello

ProprietàValore
ArchitetturaWhisper-Tiny encoder + attenzione pooling + testa MLP con uscita sigmoid
Parametri8.0M
InputUltimi 8 s di 16 kHz audio mono (128,000 campioni); i giri più corti sono zero-paggiunta alla parte anteriore, altri tassi di campionamento sono rivenditampled
ProduzioneProbabilità in [0, 1] che la svolta è completa; soglia predefinita 0.5
Lingue23 — Arabo, Bengali, Cinese, Danese, Olandese, Inglese, Finlandese, Francese, Tedesco, Indonesiano, Italiano, Giapponese, Coreano, Marathi, Norvegese, Polacco, Portoghese, Russo, Spagnolo, Turco, Ucraino, Vietnamita
LicenzaBSD-2-Clause

Le esportazioni hanno incorporato il precedente front-end Whisper log-mel, compresa la normalizzazione delle forme d'onda con cui il modello a monte è stato addestrato, quindi i chiamanti passano l'audio grezzo — non c'è estrazione di caratteristiche in Swift o C++.

Prestazioni

EsportazioneDimensioneAccuratezzaLattice per finestra 8 s
CoreML (CPU + Neural Engine)16.8 MB92.9%3.5 ms
ONNX fp32 (ONNX Runtime, CPU)33 MB92.9%~36 ms con 2 fili, 20 ms con 4
ONNX int8 (ONNX Runtime, CPU)11.1 MB93.0%~36 ms con 2 fili, 20 ms con 4

L'accuratezza è misurata su 1,000 clip del set di test a monte; il CoreML e fp32 ONNX le esportazioni corrispondono a monte fp32 modello esattamente su quelle clip. Latency è uno 8-seconda finestra su un'Apple M5 Pro. Una chiamata per pausa non aggiunge nulla evidente alla pausa VAD già aspettato.

Swift API

Controllo di un colpo su un'enunciazione registrata:

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
}

Attaccato allo streaming VAD, quindi ogni pausa confermata viene controllata prima che un segmento finisca:

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 conforma alle TurnCompletionProvider protocollo in AudioCommon, così qualsiasi altro classificatore con la stessa forma può essere attaccato invece. fromPretrained(cacheDir:offlineMode:) segue la stessa cache e regole offline come gli altri modelli.

Voce principale:

VoicePipeline prende lo stesso classificatore, quindi un agente vocale smette di tagliare le persone senza alcuna modifica alla sua configurazione STT, TTS o VAD. PipelineConfig campi e un metodo lo collegano; richiedono speech-swift v0.0.27 o più tardi (SpeechCore.xcframework da speech-core v0.0.14).

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()
APIPredefinitoEffetti
turnCompletionThreshold0.5La probabilità di completamento a o sopra la quale una pausa VAD termina il turno dell'utente. Utilizzato solo una volta che un classificatore è attaccato.
turnCompletionMaxSilence2.0Secondi di silenzio, misurati dall'inizio della pausa, dopo di che un turno il vetoed classificatore termina comunque. 0
setTurnCompletion(_:)—Attacca qualsiasi TurnCompletionProvider. Chiamalo prima start(); passare nil

Con un classificatore allegato, una pausa VAD termina solo il turno dell'utente quando la probabilità raggiunge la soglia; sotto di essa il gasdotto continua ad ascoltare, il discorso che riprende continua la stessa svolta (nessun secondo speechStarted), e turnCompletionMaxSilence Eager STT rispetta il veto, e il classificatore funziona una volta per pausa sul filo audio, quindi chiama prewarm() dopo il caricamento.

Tuning

ImpostazionePredefinitoEffetti
threshold0.5I valori più bassi terminano prima e interrompono più spesso; i valori più alti aspettano più a lungo prima di rispondere. Guarda lastTurnCompletionProbability
maxSilenceDuration2.0Il tappo duro, misurato dall'inizio della pausa. Una pausa velata non può mai tenere il giro più a lungo di questo. 0 disabilita il tappo: un segmento tenuto poi aspetta per la parola o flush().
preRollDuration0,5L'audio prima dell'inizio VAD che è incluso nell'ingresso del classificatore, quindi una prima sillaba ritagliata raggiunge ancora il modello.

Silero minSilenceDuration decide ancora quando viene confermata una pausa, e quindi quando viene chiesto il classificatore. prewarm() dopo il caricamento in modo che la prima vera pausa non paga per la compilazione del grafico.

Uso CLI

# 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
OpzioneComandoDesignazione
--thresholdturnProbabilità a o sopra la quale il giro conta come completo (default 0.5)
--jsonturnEmittente probability, threshold, complete e latency_ms JSON
--model, -mturnHuggingFace repo con lo stesso layout (default aufklarer/Smart-Turn-v3.2-CoreML)
--model-dirturndirectory locale che tiene smart_turn.mlmodelc e config.json; salta il download
--smart-turnvad-streamConfermare ogni pausa con Smart Turn
--turn-thresholdvad-streamSmart Turn (default 0.5)
--turn-max-silencevad-streamSecondi di silenzio dopo una pausa vetoed che terminano comunque il segmento (default 2.0)

speech turn carica il file (qualsiasi tasso di campionamento), segna gli ultimi secondi 8 e stampa la probabilità, se sgombera la soglia e il tempo di inferenza. Riferimento CLI.

C++ / Android

Speech Core spedisce lo stesso modello di OnnxSmartTurn per Linux, Windows e Android (solo ONNX Runtime; non esiste una variante LiteRT). VoicePipeline::set_turn_completion() lo attacca prima start(); una pausa VAD poi termina solo il turno dell'utente quando la probabilità raggiunge turn_completion_threshold (0.5), e turn_completion_max_silence (2.0 s) termina comunque una svolta tenuta. La C API espone lo stesso gancio come sc_turn_completion_vtable_t + sc_pipeline_set_turn_completion(), così Kotlin o Swift host possono collegare il proprio classificatore allo stesso modo della VAD.

#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);

Il speech CLI di Speech Core segna una registrazione allo stesso modo di macOS

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

I file di modello, il contratto C API e il CLI sono documentati sul Speech Core pagina e nel repository docs/models.md.

Download del modello

ModelloIndietroDimensioneHuggingFace
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

Fonte