Grai · Benchmarks

Benchmarks and figures

Every figure with its sample, streaming window and confidence interval alongside. Including the ones that don't flatter us.

The rule this page is written by

Measured means it ran on our hardware and the figure comes from that run. Declared means it is taken from the vendor's page and we could not verify it — these are closed models, in the cloud. The two are never mixed in the same column without a label.

Speech recognition

FLEURS Romanian and Russian

Model: Nemotron 3.5 ASR streaming, 0.6 billion parameters. Sample: 200 utterances per language from the test set, uniformly random, seed 20260831. Decoding on the production path — cache-aware, streaming — not offline decoding of the whole file. Hardware: M3 Max Mac, speech recognition through MLX on the integrated GPU, no dedicated graphics card.

Text normalization fixed on 5 September 2026 (thousands separators, times of day): 26.31% → 26.15% for Romanian, 9.30% → 9.15% for Russian. Same transcripts, rescored.

ChunkUs, normalized95% CI Us, rawNVIDIA, model cardSpeed (RTFx)
80 ms32.03%30.18–35.12 33.95%31.52%1.51×
320 ms29.01%27.50–32.04 31.05%29.04%3.6×
560 ms27.81%26.22–30.64 29.74%27.77%6.0×
1120 ms — our default26.15% 23.89–28.4227.94% 25.90%13.8×
1120 ms, language auto-detection27.71% 25.57–30.7729.64% 14.1×

Four independent streaming windows, each with the NVIDIA model-card figure inside our confidence interval. Our figure is not a broken test — it is the model's known behavior, consistent with its maker's card. At 80 ms the model barely keeps up with real time (1.51×), so two simultaneous sessions would no longer fit on the machine. The model saw little Romanian in training: NVIDIA's model card places Romanian in its «broad-coverage» tier, the second of three, and lists FLEURS among its training data. Our figure agrees with the card, but may be optimistic; we are checking it with a memorization probe.

Language auto-detection costs +1.6 points (27.71% vs 26.15%; paired difference on the same utterances: +1.58 points, 95% CI +0.77 to +2.49). That is why we keep the language fixed wherever it can be inferred before the first turn; auto-detection stays a fallback.

Chart: word error rate versus streaming window latency for streaming Romanian, FLEURS, 200 utterances. Nemotron goes from 32.0% at 80 ms down to 26.1% at 1120 ms; a dashed SpeD curve with local attention, from 48.8% to 22.1%, is marked as a lower bound, not a streaming system; four offline reference points between 6.7% and 11.8%.
Word error rate against streaming window latency, on the same 200 utterances, with a single normalization and 95% confidence intervals. The dashed curve (SpeD with local attention) is not a streaming system: its convolutions still look ahead, so it is an optimistic lower bound, not a performance figure to quote.

Russian, same pipeline, same run

ChunkUs, normalized95% CI Us, rawNVIDIA, model card
320 ms10.72%9.45–12.10 14.10%9.87%
1120 ms — default9.15%8.08–10.80 12.37%9.17%
26.15%Romanian
9.15%Russian
2.9×the gap between them

Romanian is 2.9× worse than Russian in the same model, on the same hardware, in the same run. It is not an impression lifted from someone's model card. Our bilingual agent does not have two equal languages; it has a good one and a weak one. The same memorization caveat applies to Russian.

Market comparison

With the measurement conditions alongside

The "how" column is what makes the table readable. A model that gets the whole file, offline, in a data center, is not solving the same problem as one that emits text while the person is still speaking, on an office Mac.

SystemWER FLEURS roHowSource
ElevenLabs Scribe v13.0%cloud, batchdeclared · ElevenLabs page, different normalization
Gemini Flash 23.9%clouddeclared · ElevenLabs comparison, different normalization
Speechmatics Enhanced5.28%cloud and on-prem, streamingdeclared · Speechmatics page, different normalization
Whisper large-v38.24%offline, whole file, 1.5 billiondeclared · arXiv 2509.14128, Tab. 11, different normalization
Amazon Transcribe8.94%clouddeclared · Speechmatics comparison, different normalization
Google Chirp 210.91%clouddeclared · Speechmatics comparison, different normalization
Whisper large-v312.31% / 13.0%offline, whole file, 1.5 billiondeclared · Speechmatics / ElevenLabs, different normalization
Microsoft Azure Speech13.33%clouddeclared · Speechmatics comparison, different normalization
Grai — Romanian26.15%local, streaming, 0.6 billion, integrated GPUmeasured
Deepgram Nova-233.89% / 35.4%clouddeclared · Speechmatics / ElevenLabs, different normalization
Grai — Russian · other language9.15% (FLEURS ru)local, streaming, integrated GPUmeasured · not part of the Romanian ranking

The offline ceiling, local, on the same 200 utterances

Measured by us, with the same normalization as Grai. Offline: the model gets the whole utterance and does not emit text while the person speaks — so it cannot stand in for streaming speech recognition.

System, offlineWER normalized95% CIWhere it ran
SpeD 110M (UPB, Apache), CTC + KenLM6.70%5.51–8.01local, CPU
Whisper large-v3 turbo8.26%7.20–9.85local, MLX
SpeD 110M, TDT without a language model8.34%7.19–10.17local, CPU
Parakeet TDT 0.6B v311.79%10.45–13.66local
Grai — Romanian, streaming, 1120 ms26.15%23.89–28.42local, MLX, integrated GPU

What beats us on Romanian, on our own machine, is an open Romanian model, offline. The ~19-point gap is the price of emitting text while streaming; that is why the next step is distilling it into a small model that streams, not tuning Nemotron.

The calibration that shows what the table above is worth

Two vendor pages publish figures for the same two third-party models, and they don't match: Whisper large-v3 shows up as 12.31% on one and 13.0% on the other; Deepgram Nova-2 as 33.89% and 35.4%. So between two published "FLEURS Romanian" figures there are 0.7–1.5 points of difference from split and normalization alone. A 2025 paper (arXiv 2509.14128) gives the same Whisper large-v3 8.24% — one model name, three figures in three sources.

That margin matters when you compare 3.0% with 5.28%. It doesn't matter at all when you compare any of them with 26.15%. The honest position: on Romanian accuracy, streaming, we lose by a factor of 5–9×.

What we have instead, and they don't

Only one vendor on the list also offers on-prem with streaming Romanian — so it is the only one that attacks our argument head-on. Against it, the argument remains cost and control, not accuracy.

Where it breaks

Numbers. Exactly the part that matters on the phone.

Splitting the 200 utterances by whether the reference contains digits:

UtterancesnWER normalizedWER rawWhat it says
without digits16325.08%25.43% normalization barely matters
with digits3729.65%36.94% normalization hides 7.3 points

An utterance with digits is 4.6 points worse normalized and 11.5 points worse raw. Real examples from the run (in Romanian, as transcribed):

ReferenceWhat came out
din 1988 urnele de vot… (since 1988 the ballot boxes…)Denomin ustie xopt, urnele de votre… (the year garbled into nonsense syllables)
în 1537 paraguay… (in 1537 Paraguay…)în o mie cinu ste și șapte, Paraguay… (the year half spelled out, misspelled)
pușca sa m16 (his M16 rifle)ca să M Shaișpe ("so that M sixteen", phonetic)
cele 25 de postere dunlap (the 25 Dunlap posters)Cele douăze și inci de postere Danop (number spelled out and broken, name misheard)

Any normalization that spells numbers out in words before scoring makes us look better than we are on the phone. That is why we also report raw scores. For an agent that takes phone numbers, times, prices and dates, the most important part of the language is also the most broken one. Why normalization matters →

Latency

From your last sound to its first

Two different runs, answering two different questions. They do not add up.

Filler on — what the person hears

n=29 turns, p50, measured at the client, from the person's last speech sample.

1235ms to first sound · p95 1616 · it is a filler ("mm-hm")
2667ms to the first sound of the answer · p95 6003

Filler off — where the milliseconds go

n=17 turns, p50, gpt-5.4-nano. Each segment has two observed endpoints, not computed ones — the six segments add up to the total within half a millisecond.

turn-taking decision
586 ms
speech recognition
92 ms
gate, start-up
3 ms
language model
2180 ms
speech synthesis
305 ms
queue, transport
6 ms
3172ms to first sound = the answer · 586+92+3+2180+305+6
69%of the latency is the language model (p50, gpt-5.4-nano; 71% on gpt-5.6-luna)

The 92 ms of speech recognition is the flush after the person stops talking; partial text during speech arrives with the streaming window's delay, ~1.1 s at 1120 ms. The only piece that does not run locally is also 69% of the delay.

Reference point: HumDial, ICASSP 2026, reports 1.26 s for the winner, under the challenge's own definition. It is a different quantity from the 1235 ms or 2667 ms above; one is not subtracted from the other. What the reference shows: where full-duplex is actually measured, the figures are on the order of a second, not 300 ms.

Turn detection

Prosody versus the stopwatch

820ms · fixed threshold, same rate of wrong cuts
560ms · on intonation
52.0%of pauses still cut wrongly (down from 69.4%) · lower is better
0.42ms cost per pause decision, on M3 Max

Measured on real human conversations from CANDOR, in English: 80 clips, 98 pauses, offline replay. The metric is TOR — the share of mid-sentence pauses in which the system wrongly decided the person had finished. With a fixed 0.6 s threshold, 69.4%; on intonation, at a 560 ms wait, 52.0% — which the stopwatch needs 820 ms to reach. The gain does not come from deciding less often: the prosody decision makes more decisions than the fixed threshold, and still errs less. Public reference points: 9.9% false cuts at 300 ms and 4.5% at 600 ms, for LiveKit v1 — declared, English, a different metric (false-cut rate, not TOR), so not directly comparable.

Why these figures can't be compared with anyone else's

The study explains the six methodology traps that make published tables incomparable — with examples from our own mistakes.