Skip to content

Reduce listener recomputation with exact embedding reuse - #90

Closed
petebytes wants to merge 1 commit into
livekit:mainfrom
petebytes:perf/streaming-embedding-cache
Closed

petebytes wants to merge 1 commit into
livekit:mainfrom
petebytes:perf/streaming-embedding-cache

Conversation

@petebytes

Copy link
Copy Markdown

Summary

  • keep WakeWordModel.predict() stateless and add isolated WakeWordStream cache state
  • have WakeWordListener automatically use a fresh stream while retaining fallback compatibility for predict-only wrappers
  • reuse a speech embedding only when its 76-frame mel input exactly matches the shifted prior input
  • batch all changed embedding windows into one ONNX call and reset stream state after detection

Why

The Python listener advances an overlapping 2-second window every 80 ms. Before this change, one prediction ran one mel inference, sixteen speech-embedding inferences, and one classifier inference. With one classifier that is 18 ONNX calls per prediction, or 225 calls/second at the listener's 12.5 Hz cadence.

A naive rolling mel buffer is not score-equivalent because the mel model can produce window-dependent values around silence. This implementation still computes the full mel tensor and uses exact equality before reusing any embedding.

Verification

Full upstream suite:

uv run --frozen pytest tests/ -q
79 passed, 2 skipped

The changed Python files pass Ruff check and format check. The package builds as both wheel and sdist.

A 107-clip downstream regression corpus covering 4,032 overlapping windows produced identical peak scores and identical results at every threshold:

Threshold Recall before/after False accepts before/after
0.5 20/25 50/82
0.6 20/25 48/82
0.7 20/25 48/82
0.8 20/25 46/82
0.9 18/25 34/82

Measured work on that corpus:

mel invocations:        4,032
embedding invocations:  4,032
classifier invocations: 4,032
total:                  12,096 = 37.5 invocations/second
embedding windows:      17,527 / 64,512
max peak score delta:   0

On 187 overlapping quiet-audio windows with single-threaded ONNX Runtime:

stateless CPU: 2.9967s
stream CPU:    0.2488s
reduction:     12.05x
max score delta: 0

Remaining gate

This is intentionally a draft until it completes a live microphone workday to compare real-world detections and false accepts.

Refs max-brain/stop-the-25x-recompute-in-the-mb-wake-detection-loop.
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@petebytes petebytes closed this Sep 25, 2026
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.

2 participants