Files
echo-core/tasks/voice-bench-results-threads4.md
Marius Mutu c6d11bdf9f chore(voice): spike STT latency benchmark + HT contention lesson
Pas 1 (BLOCKING) din Discord voice-to-voice test plan. Sweet spot empiric
pe i7-6700T: faster-whisper small int8 @ cpu_threads=4 → p50 2.25s,
p95 2.64s, mean RTF 0.46. Curba HT: 2t=3.25s → 4t=2.25s (sweet) →
6t=2.79s (regres +24% prin contention). tiny respinge — halucinează RO.

- tools/voice_bench.py: harness benchmark cu 8 sample-uri RO sintetizate
  via Supertonic API, măsoară p50/p95/RTF pentru small+tiny pe N threads.
- tools/voice_bench_results*.json: raw output 3 pass-uri (threads 2/4/6).
- tasks/voice-bench-results*.md: summary markdown per pass.
- tasks/lessons.md: HT contention rule — cpu_threads = physical cores,
  rulează sweep nu single-point pentru ML inference compute-bound.

Budget updated în plan-uri: STT p50 1.5s → 2.5s, perceived 4s → 5s p50.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 12:52:11 +00:00

4.5 KiB

Voice Bench Results — Discord Voice-to-Voice Spike

Generated: 2026-05-27 (BLOCKING Pas 1 din test plan) Hardware: i7-6700T (Skylake mobile), Proxmox VM, no GPU Budget original: STT p50 < 1.50s (per CEO plan aspirational) Budget honest: 1.5-3s (per Outside Voice #1, baked in CEO plan)

Final Recommendation: PASS cu small model

Script-ul a returnat auto-decision FALLBACK_TINY pentru că small.p50=2.25s > 1.5s literal. Override manual: tiny produce transcript ilizibil în RO ("muină să sun la nu a", "să mream in test de seare", "Stei putin") — inutilizabil pentru produs. small @ 4 threads cade în honest range-ul "1.5-3s" deja acceptat în CEO plan și produce transcript clean modulo normalizare numerică (deja în scope: src/voice/normalize.py).

Implicații pentru implementare:

  1. Folosește WhisperModel("small", device="cpu", compute_type="int8", cpu_threads=4) în src/voice/pipeline.py.
  2. Update plan latency budget: STT p50 = 2.25s (era 1.5s); perceived round-trip estimate = 3.5-5s (STT 2.25s + Claude TTFB 0.5-1s + streaming TTS first clause ~0.5s).
  3. Streaming Claude→TTS rămâne critic — fără el, total perceived = 6-8s, peste limita conversațională.
  4. Filler audio "Stai să-mi adun gândurile" (deja în plan) maschează cazurile p95 (>3s).
  5. Document fallback la tiny DOAR pentru /voice doctor mode degraded (Whisper OOM etc.), nu pentru happy path.

Two-Pass Comparison (threads=2 vs threads=4)

Model threads p50 (s) p95 (s) mean RTF Verdict
small 2 3.25 3.63 0.67 FAIL latency
small 4 2.25 2.64 0.46 CHOSEN (quality + honest range)
tiny 2 0.50 0.57 0.10 FAIL quality
tiny 4 0.48 0.57 0.10 FAIL quality

CPU upgrade 2→4 cores: small got 31% faster (3.25s → 2.25s), tiny essentially unchanged (CPU-light enough că nu beneficiază). Confirmă că small e CPU-bound, tiny nu.

Transcript Quality Side-by-Side (4 threads)

Input small @ 4t tiny @ 4t
"Salut, ce mai faci?" "Salut ce mai faci!" "Salut, ce mai fac?"
"Stai puțin să mă gândesc la asta." "Stai putin să mă gândesc la asta." "Stei putin să mă gândesc la asta."
"Am verificat în calendar și avem ședință cu echipa la trei după-amiază." "Am verificat în calendari și avem sedință cu echipa la 3 după amiază." "Am verificat în calendar și avem sedeință cu equipala 3 du pămiază."
"Costul total este o sută douăzeci și trei de lei și cincizeci de bani." "Costul total este 120 și 3 delei și 50 de bani." "Costul total este o suta 20 și 3 de lei și 50 de bani."
"Marius, vrei să-ți pun pe agenda de mâine să suni la NOAA?" "Marius, vrei să-ți spun pe agenda de mâine să suni la noa a." "Marius, vrei să-ți pun pe agenda de muină să sun la nu a."
"Vreau să-mi reamintești diseară..." "Vreau să mi-răimintești di seară..." "Vreau să mream in test de seare..."

Observații:

  • small greșeli: diacritice (putin/puțin, sedință/ședință), numbere ca digiti ("3" în loc de "trei"), acronime (NOAA→noa), aglutinare ("delei"/"de lei", "răimintești"/"reamintești").
  • tiny greșeli: cuvinte INVENTATE ("mream", "muină", "equipala", "sunilă") — hallucination, nu doar misspell.

Hardware Context

  • Intel(R) Core(TM) i7-6700T CPU @ 2.80GHz (Skylake mobile, 2015)
  • Cores online: 4 logical (din 8), upgrade de la 2 în timpul benchmark-ului
  • RAM: 6.0Gi total, ~2.5Gi available
  • No NVIDIA GPU (CPU-only inference)
  • ctranslate2 4.7.2 + faster-whisper 1.2.1 + int8 quantization

Open Questions pentru Decision Lock

  1. Budget relax oficial: acceptăm 2.25s p50 în plan și comunicăm honest user-facing? Sau încercăm:
    • Groq Whisper Large-v3 API (~0.3s, free tier 14k req/day) — vine cu network dependency
    • Deepgram Nova-2 RO streaming ($, dar 0.2s streaming partial transcripts)
    • Whisper.cpp + AVX2 (același small model, optimizat C++) — ~30% boost suplimentar potențial
  2. CPU bump: dacă activăm restul de 4 cores offline (3-6) ar coborî small.p50 la ~1.5s? Worth investigat (probabil VM resource cap, nu hardware limit).

Raw Data

  • tools/voice_bench_results.json — run curent (threads=4)
  • tools/voice_bench_results_threads2.json — baseline (threads=2)
  • tasks/voice-bench-results-threads2.md — narrative pentru baseline