How to Configure Smart Turn Endpointing for Better Turn-Taking
Smart Turn endpointing uses a lightweight ONNX model to predict whether a user has finished speaking, allowing the system to delay assistant responses during incomplete turns and prevent conversational interruptions.
The huggingface/speech-to-speech repository implements an advanced turn-taking mechanism called Smart Turn that reduces premature interruptions in voice conversations. By configuring Smart Turn endpointing parameters, you can fine-tune how the system distinguishes between completed and incomplete user utterances. This guide explains the architecture, configuration options, and tuning strategies based on the actual source code implementation.
Smart Turn Architecture Overview
Smart Turn operates as a secondary analysis layer after the Silero VAD detects the end of a speech segment. The system predicts whether the user's utterance is complete or incomplete, then adjusts the speculative response window accordingly. This flow is exercised in the test suite (tests/test_smart_turn.py lines 44‑62).
Core Components
The implementation consists of three primary components defined across the codebase:
VAD Handler (src/speech_to_speech/VAD/vad_handler.py): The orchestration layer that initializes Smart Turn and executes turn-taking logic. The setup() method (lines 59-84) creates a SmartTurnAnalyzer instance when smart_turn=True and stores configuration values for later use.
# src/speech_to_speech/VAD/vad_handler.py (lines 59-84)
def setup(..., smart_turn: bool = True,
smart_turn_model_path: str | None = None,
smart_turn_threshold: float = 0.5,
smart_turn_max_wait_ms: int = 2000,
smart_turn_incomplete_delay_ms: int = 600,
smart_turn_cpu_count: int = 1, ...):
Smart Turn Analyzer (src/speech_to_speech/VAD/smart_turn.py): Wraps the ONNX inference model and handles audio preprocessing. The analyzer pads or trims input to a maximum of 8 seconds (MAX_AUDIO_SECONDS = 8) and resamples to 16 kHz (MODEL_SAMPLE_RATE = 16000) before running prediction.
# src/speech_to_speech/VAD/smart_turn.py
class SmartTurnAnalyzer:
def __init__(..., model_path: str | None = None,
threshold: float = 0.5,
cpu_count: int = 1, warmup: bool = True):
Argument Classes (src/speech_to_speech/arguments_classes/vad_arguments.py): Exposes all Smart Turn parameters to the CLI and configuration system through the VADHandlerArguments dataclass.
Configuration Parameters
All Smart Turn settings are accessible via the VADHandlerArguments class in src/speech_to_speech/arguments_classes/vad_arguments.py. The following table details each parameter:
| Parameter | Default | Description |
|---|---|---|
smart_turn |
True |
Master toggle to enable or disable Smart Turn analysis |
smart_turn_threshold |
0.5 |
Probability threshold for classifying a turn as "complete" |
smart_turn_max_wait_ms |
2000 |
Maximum milliseconds to keep response speculative when turn is incomplete |
smart_turn_incomplete_delay_ms |
600 |
Processing delay added after incomplete predictions to allow speech resumption |
smart_turn_cpu_count |
1 |
Number of CPU threads allocated to ONNX Runtime inference |
smart_turn_model_path |
None |
Optional path to a custom ONNX model file |
Implementation Examples
You can configure Smart Turn endpointing programmatically through the Python API or via command-line arguments when running the pipeline.
Python API Configuration
Instantiate the VADHandler and call setup() with your desired Smart Turn parameters. Note that you must provide a SpeculativeTurnTracker instance when enabling speculative turns.
from speech_to_speech.VAD.vad_handler import VADHandler
from speech_to_speech.pipeline.speculative_turns import SpeculativeTurnTracker
from threading import Event
# Initialize required tracker
tracker = SpeculativeTurnTracker()
handler = VADHandler()
handler.setup(
should_listen=Event(),
speculative_turns=tracker,
smart_turn=True,
smart_turn_threshold=0.7, # Require higher confidence for completion
smart_turn_max_wait_ms=3000, # Wait up to 3s for incomplete turns
smart_turn_incomplete_delay_ms=800,
smart_turn_cpu_count=2, # Parallel inference threads
)
CLI Configuration
Pass arguments directly when launching the pipeline from the command line:
python -m speech_to_speech.cli \
--smart_turn \
--smart_turn_threshold 0.6 \
--smart_turn_max_wait_ms 2500 \
--smart_turn_incomplete_delay_ms 500 \
--smart_turn_cpu_count 2
Turn-Taking Logic and Tuning
The method _smart_turn_timing_ms (lines 509-542 in vad_handler.py) implements the decision logic that translates model predictions into timing adjustments. This function returns a tuple (reopen_grace_ms, processing_delay_ms) that controls the speculative window and downstream processing delays.
Behavior Modes
The system responds differently based on the SmartTurnResult:
- Complete Turn: When
result.complete == True, the handler uses the standard speculative reopen window (default 800 ms) with no additional processing delay. - Incomplete Turn: The system extends the speculative grace period to
smart_turn_max_wait_msand addssmart_turn_incomplete_delay_msbefore starting STT/LLM processing. This allows users to resume speaking without the assistant interrupting. - Inference Failure: Falls back to the default speculative window to maintain conversation flow.
Tuning Strategies
Adjust these parameters to optimize for your specific use case:
- Increase
smart_turn_threshold(e.g., to 0.7 or 0.8) to make the system more conservative about declaring turns complete. This prevents cut-offs during short pauses but may increase response latency. - Raise
smart_turn_max_wait_msfor users with slower speech patterns or when running complex downstream pipelines that benefit from longer speculative windows. - Lower
smart_turn_incomplete_delay_ms(e.g., to 300-400 ms) for faster response times in high-latency environments, though this risks processing utterances that the user intends to continue. - Increase
smart_turn_cpu_counton multi-core servers to reduce inference latency, though the default single-threaded configuration is optimal for most client-side deployments.
Summary
- Smart Turn endpointing in
huggingface/speech-to-speechuses an ONNX model to classify user utterances as complete or incomplete after VAD detection. - Configure parameters via
VADHandlerArgumentsinsrc/speech_to_speech/arguments_classes/vad_arguments.pyor through CLI flags. - Key tuning knobs include
smart_turn_thresholdfor completion confidence andsmart_turn_max_wait_msfor speculative window duration. - The
_smart_turn_timing_msmethod invad_handler.pyorchestrates turn-taking by adjusting grace periods and processing delays based on model predictions.
Frequently Asked Questions
What is the default Smart Turn threshold and when should I change it?
The default threshold is 0.5, defined in src/speech_to_speech/arguments_classes/vad_arguments.py. Increase this value to 0.6-0.8 when your application serves users who pause frequently mid-thought, as it requires higher model confidence before committing the assistant's response. Lower values (0.3-0.4) create more responsive but potentially interruptive behavior for fast turn-taking scenarios.
How does Smart Turn handle incomplete user utterances?
When the analyzer predicts an incomplete turn (probability below threshold), the system activates two protective mechanisms defined in _smart_turn_timing_ms (lines 509-542 of vad_handler.py). First, it extends the speculative response window to smart_turn_max_wait_ms (default 2000 ms), allowing the user to continue speaking. Second, it introduces a processing delay of smart_turn_incomplete_delay_ms (default 600 ms) before sending audio to the STT/LLM pipeline, preventing wasted computation on partial utterances.
Can I use a custom ONNX model for Smart Turn prediction?
Yes. Pass a file path to the smart_turn_model_path parameter in the VADHandler.setup() method or via the --smart_turn_model_path CLI argument. The custom model must accept audio input preprocessed to 16 kHz sample rate and maximum 8 seconds duration, matching the interface defined in src/speech_to_speech/VAD/smart_turn.py. The SmartTurnAnalyzer handles all resampling and padding automatically.
What audio preprocessing does the Smart Turn Analyzer perform?
According to src/speech_to_speech/VAD/smart_turn.py, the SmartTurnAnalyzer resamples all input to 16 kHz (MODEL_SAMPLE_RATE = 16000) and pads or truncates audio to a maximum of 8 seconds (MAX_AUDIO_SECONDS = 8). This standardization ensures compatibility with the ONNX model's expected input dimensions while maintaining real-time performance characteristics suitable for conversational AI applications.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →