kobkrit's picture
Mac: the server uses 1 CPU thread on macOS (more threads are slower on Apple silicon); card: measured M3 Max speeds, and the 8-thread CPU figure is a server, not a laptop
1dc764a verified
|
Raw History Blame Contribute Delete
4.38 kB

OpenThai2.0 ASR Streaming service: reference

Install, start and example calls: see the main README.

Endpoints

endpoint what it does
POST /v1/transcribe multipart file + the fields below → JSON
WS /v1/live a live stream of any length: JSON config → PCM16 LE 16 kHz mono frames → text end. Replies partial (the sentence so far) and one final each time the speaker pauses, then done
WS /v1/stream one utterance: JSON config → frames → end; replies partial… then one final
GET /v1/health loaded model and settings
field values default
mode standard · conversation · meeting standard
lang th-TH · th-mix th-TH
latency_ms 80 · 320 · 560 · 1120 560
diarize true · false on for meeting
split (files) auto · on · off auto: cut files longer than 30 s at pauses
end_silence_ms (/v1/live) 300–3000 700

Response fields:

  • text (raw, as scored) and display_text (for display).
  • duration_s, lang, latency_ms, mode, policy, delta, model, processing_s.
  • A file cut at pauses also has segments [{start, end, text}], one per piece.
  • With speaker labels, also segments [{speaker, start, end, text}] and speakers.

Errors: 400 empty file · 415 unreadable audio · 422 bad option.

What each mode does

The blank bias δ controls how readily the model writes something: the more negative it is, the fewer words get dropped.

mode decode
standard δ −1.0; clips under 2 s re-decoded at −2.5; empty output re-decoded at −4.0
conversation δ −2.0; empty output re-decoded at −4.0
meeting δ −1.0 + speaker labels from nvidia/Nemotron-3-Diarization (downloaded on first use)

Environment variables

var default meaning
CHINDA_DEVICE cpu cuda for GPU
CHINDA_MODEL ../openthai2.0-asr-streaming_raw.nemo must be the raw file; *_bias-* files are refused (the bias would apply twice)
CHINDA_PRELOAD unset 1 = load at start-up; otherwise the first request waits about 20 s
CHINDA_REPLICAS 1 model copies, about 2.6 GB each; each copy runs one decode step at a time
CHINDA_NUM_THREADS min(16, CPUs); 1 on macOS CPU threads. On Apple silicon each extra thread makes decoding slower, so macOS uses 1
CHINDA_DIAR_MODEL download path to a local Nemotron-3-Diarization.nemo
CHINDA_CUDA_GRAPHS 0 leave at 0: 1 crashes on the request after speaker labels
CHINDA_SPLIT_FROM_S 30 split=auto cuts files longer than this many seconds

Long audio

Do not decode a long recording as one stream. After a pause of near-silence this model drops some of the speech that follows: TVSpeech's videos, rebuilt by joining their clips with one second of silence, score 23.5% character errors as one stream and 12.7% cut at pauses (12.4% clip by clip). So:

  • POST /v1/transcribe cuts any file longer than 30 s where nobody speaks for 0.7 s, and decodes the pieces on their own (split=auto). Speaker labels (mode=meeting) still decode one stream.
  • WS /v1/live ends an utterance at each pause and starts the next one fresh, like iApp's hosted OpenThai ASR Realtime.
  • WS /v1/stream decodes everything you send as one utterance; keep it for short commands and single sentences.
  • In Python: chinda_realtime.transcribe_long(asr, audio) for recordings, chinda_realtime.RealtimeSession for live audio.

The pause detector is an energy rule (chinda_realtime.Endpointer): a 20 ms frame is speech when it is louder than both the loudest recent level − 30 dB and the quietest recent level + 8 dB. Stretches with no speech are skipped.

Good to know

  • No authentication or rate limiting.
  • With diarize on /v1/stream, speaker labels arrive with the final message only; /v1/live has no speaker labels. Speakers are anonymous (speaker_0, …).
  • Live text equals decoding the finished utterance on its own. Batch decoding (the benchmark) can differ by the last word on clips under 2 s.
  • With ffmpeg on the PATH, the API also accepts mp3, m4a and ogg.
  • The decode loop is adapted from NVIDIA NeMo's speech_to_text_cache_aware_streaming_infer.py (Apache-2.0).