Research270M params

ThinkSpark-Realtime-270M

A realtime referee that decides who holds the floor in a conversation — so agents stop talking over people and stop waiting too long.

Voice agents do not fail mid-sentence. They fail at the seams — talking over a caller, or leaving dead air after they finish. Kupe-ThinkSpark-Realtime-270M is the small model that sits in that seam: one decision every 80ms, ten possible flags, under 3ms to decide.

Data card

What it does

It reads Mimi audio tokens directly — no transcript in the loop — and emits one control flag per frame. Not ASR, not the LLM, not the voice. The referee that tells the other three when to act.

FlagMeaning
LISTENuser has the floor
HOLDpaused mid-thought — do not jump in
INCOMPLETEutterance not finished
TURN_ENDuser is done — commit and reply
BARGE_SOFTtalking over the agent — duck audio
BARGE_HARDactively interrupting — stop now
CONTINUEagent may keep speaking
PREFETCH_LLMsafe to start a speculative call
COMMIT_LLMplay the prefetched reply
SILENCE_BREAKdead air — say something

Data card

Performance

MetricResultTarget
VAD F10.976≥ 0.85
Barge-in F10.861≥ 0.85
False-barge rate0.000≤ 0.05
Ctrl macro-F1 (±240ms)0.860
Decode p50 / p952.9 / 4.2 msp95 ≤ 40 ms

Frames are 80ms long; the model finishes in ~3ms — roughly 20× faster than the audio it is judging. That headroom is deliberate: the referee should never be the thing making an agent feel slow.

Try it

Quickstart

Pass audio in, get decisions back. Mic, a call leg, a file — anything.

python — pip install kupe
from kupe import ThinkSpark

ts = ThinkSpark()

for decision in ts.stream(source="mic"):
    print(decision.flag, decision.latency_ms)
typescript — npm install kupe-sdk
import { ThinkSpark } from "kupe-sdk"

const ts = new ThinkSpark()

for await (const d of ts.stream("mic")) {
  console.log(d.flag, d.latencyMs)
}
raw runtime — pip install thinkspark
from thinkspark import ThinkSparkPipeline

pipeline = ThinkSparkPipeline.from_pretrained(
    "anuj-inavlabs/Kupe-ThinkSpark-Realtime-270M"
)
decision = pipeline(audio_frame, sample_rate=24_000)

In production

Where it earns its keep

TURN_END

Phone support

Cuts the awkward gap after a hold-music return — the agent replies the instant the caller stops, not 600ms later.

BARGE_HARD

IVR replacement

Lets a caller interrupt a menu read-out mid-sentence instead of waiting through it.

PREFETCH_LLM

Live sales calls

Speculatively starts the next LLM turn while the prospect is still finishing their sentence.

BARGE_SOFT

In-app voice assistants

Ducks the assistant's own TTS instead of a hard cut when the user talks over it.

SILENCE_BREAK

Long lookups / ledger checks

Fills dead air with a filler instead of silence that reads as a dropped call.

en · hi · gu

Multilingual support lines

One model across English, Hindi, and Gujarati — no per-language referee to maintain.

Data card

Languages & limits

Trained on en · hi · gu only. Other languages are untested and unsupported.

  • CANCEL_LLM exists in the label space but the model does not reliably emit it — do not build cancellation logic on it.
  • Expects 24kHz mono audio. Resample before calling.
  • Two-party conversation. Multi-speaker rooms are untested.
  • Decisions are frame-local — long-horizon dialogue state is your orchestrator's job.
ThinkSpark-Realtime-270M · Kupe