Skip to content

perf(silero-native): faster engine load (parallel sessions, lazy PQMF) - #173

Merged
xilec merged 3 commits into
mainfrom
xilec/silero_native_load
Aug 1, 2026
Merged

perf(silero-native): faster engine load (parallel sessions, lazy PQMF)#173
xilec merged 3 commits into
mainfrom
xilec/silero_native_load

Conversation

@xilec

@xilec xilec commented Aug 1, 2026

Copy link
Copy Markdown
Owner

What

Cuts native engine load from ~650 ms to ~440 ms (~1.5x) — ~3.8x faster
than the Python ttsd spawn-to-ready (~1680 ms) on the same machine
(Ryzen 9 7900).

Closes #165.

Changes

  • Measure first: per-phase tracing timings (manifest verify, each
    ONNX session open, frontend, total) via RUST_LOG=silero_native=info;
    the bench example now reports load_ms.
  • Concurrent session creation: the four always-needed sessions open
    on scoped threads (507 → ~340 ms), assembled by model name.
  • Concurrent sha256 verify (115 → ~60 ms).
  • Lazy PQMF: pqmf_24k/pqmf_8k open on the first synthesis at
    that rate; a missing PQMF file still fails at load.
  • Warmup at app start: already covered (spawn_initial_warmup via
    the engine switcher) — verified, no change needed.

Measured and rejected: ORT graph optimization level (Level3 ≈ Level1 ≈
Disable) and the .ort compiled-model cache — session creation is
dominated by model parse/arena init, not the optimizers.

Baseline + final numbers and methodology: new "Engine load time"
section in silero-native/docs/benchmarks.md.

Verification

  • just test — green (Rust incl. the bundle-gated parity suite, TS, Python)
  • just lint — green
  • Behavior unchanged: same models, same output (parity suite pins it)

xilec added 3 commits August 1, 2026 17:42
Add tracing timings for manifest verify, each ONNX session open,
frontend load and the total in Engine::load, and surface them via
RUST_LOG=silero_native=info. The bench example now reports load_ms
alongside the synthesis stats, so engine load (previously excluded
from the benchmark) is measurable. Baseline on Ryzen 9 7900:
~650 ms native load vs ~1680 ms ttsd spawn-to-ready (issue #165).
… lazy PQMF)

- Sessions::open creates the four always-needed sessions concurrently
  on scoped threads (507 ms -> ~340 ms).
- Manifest::verify hashes files concurrently (115 ms -> ~60 ms).
- pqmf_24k/pqmf_8k sessions are lazy-opened on the first synthesis at
  that sample rate instead of at engine load.
- Measured and rejected: ORT graph optimization level and the .ort
  compiled-model cache (no effect; model parse/arena init dominates).

Engine load ~650 ms -> ~440 ms, ~3.8x faster than ttsd spawn-to-ready.
Numbers and methodology recorded in silero-native/docs/benchmarks.md.
Closes #165.
- Sessions::open assembles the struct by model name (tagged results)
  instead of spawn position — a reordered NAMES can no longer silently
  swap sessions.
- Engine::load fails fast when a PQMF model file is missing; lazy open
  must not defer an incomplete-bundle error to the first synthesis.
- Thread-panic payloads are included in the Bundle error message.
- Pin verify's first-mismatch-in-manifest-order contract with tests
  (plus a multi-entry happy path exercising the hash fan-out).
- Doc comments updated for lazy PQMF.
@xilec
xilec merged commit 2a2897c into main Aug 1, 2026
6 checks passed
@xilec
xilec deleted the xilec/silero_native_load branch August 1, 2026 11:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf(silero-native): engine load is noticeably slower than the Python ttsd startup

1 participant