Tie: Danish end-of-turn detector

Tie is Danish for "to fall silent". It is a sibling of Hviske (ASR) and Plapre (TTS).

A small audio-only model that answers one question for voice agents: the Danish speaker just went quiet. Are they done, or only pausing?

It listens to the last 8 seconds of audio, 200 ms into a pause, and returns P(done). No transcript is needed. The int8 ONNX model is 25 MB and takes 28 ms on 2 CPU threads per decision (15 ms on 4, 54 ms on 1).

Try it in the demo. It runs in your browser.

Results

Held-out test set of 96,110 pauses the model has never seen.

AUC F1 (50/50)
Unambiguous pauses (12,120) 0.963 0.907
Same, int8 ONNX 0.963 0.906
All test pauses 0.917 0.847

"Unambiguous pauses" are the test pauses where the right answer is clear. On those, the model gets 9 out of 10 decisions right at threshold 0.5. "50/50" weights turn ends and holds equally.

As a turn-taking policy

Respond 200 ms into the pause if P(done) > threshold, otherwise fall back to a 2 s silence timer (all test pauses, natural frequencies):

Policy Cuts off a speaker who was only pausing Mean reply latency when they were done
silence timer 0.5 s 47.2% 0.50 s
silence timer 0.8 s 18.6% 0.80 s
model, threshold 0.5 13.4% 0.55 s
model, threshold 0.8 9.0% 0.72 s
model, threshold 0.9 6.7% 0.88 s

Usage

Input: audio, float32 [1, 128000]. This is 16 kHz mono: the last 8 s up to the decision point, left-padded with zeros if shorter. Output: p_done, the probability that the turn is over. Call it about 200 ms after the last word.

import numpy as np, onnxruntime as ort
sess = ort.InferenceSession("eot.int8.onnx", providers=["CPUExecutionProvider"])
w = audio_16k[-128000:].astype(np.float32); w = np.pad(w, (128000 - len(w), 0))[None]
p_done = sess.run(None, {"audio": w})[0].item()

example.py wraps this. eot.onnx is the fp32 export, identical to PyTorch. model.safetensors + model.py are the PyTorch weights and architecture. PyTorch forward returns a logit; the ONNX export applies the sigmoid.

Model

  • Transformer audio encoder over 8 s of log-mel features, attention pooling, and a 2-layer MLP head.
  • Binary cross-entropy loss.
  • Exported to ONNX with the STFT as a fixed DFT convolution.
  • Dynamic int8 quantization of the MatMul weights, per channel. Default per-tensor int8 lost 1.6 F1 points; per-channel loses 0.04.

Limitations

  • Audio only. It hears prosody, not grammar. A speaker who stops mid-sentence with falling intonation can sound finished. Combining it with an ASR-based text signal should help.
  • Natural speech. Synthetic (TTS) voices fool it. Phone-quality and far-field audio are untested.
  • Ambiguous pauses. On pauses where even people would disagree, accuracy drops. The remaining errors look like genuine ambiguity in the audio.
Downloads last month

-

Downloads are not tracked for this model. How to track
Safetensors
Model size
20.2M params
Tensor type
F32
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Spaces using syvai/tie 2