Skip to content

tests/omnivoice: add OmniVoice weight-type benchmark, report, and Python-to-C++ tests - #269

Merged
0xShug0 merged 2 commits into
0xShug0:mainfrom
kawshikbuet17:omnivoice
Aug 18, 2026
Merged

tests/omnivoice: add OmniVoice weight-type benchmark, report, and Python-to-C++ tests#269
0xShug0 merged 2 commits into
0xShug0:mainfrom
kawshikbuet17:omnivoice

Conversation

@kawshikbuet17

Copy link
Copy Markdown
Contributor

Summary

Follows up on #158, where you suggested opening a PR to add my OmniVoice test script under tests/omnivoice/.

This adds the voice-clone weight-type benchmark that produced the q8_0 audio-tokenizer finding I reported in that issue, plus two Python-to-C++ integration tests for OmniVoice.

What is here

Benchmarkstests/omnivoice/run_clone_benchmark.sh and run_clone_batch_benchmark.sh sweep every combination of --num-inference-steps (8 to 64), omnivoice.generator_weight_type, and omnivoice.audio_tokenizer_weight_type, for single requests and for --batch-text-file runs. Shared Bengali fixtures live in tests/omnivoice/assets/.

Reportdocs/reports/omnivoice_weight_type_benchmark.md holds the measurements: 375 single requests and 375 batch runs of 10 prompts on an RTX 4090.

Integrations — two ways to drive OmniVoice from Python with inference staying in C++:

  • tests/omnivoice/python_cpp_simple/ posts OpenAI-compatible requests to audiocpp_server using only the Python standard library, with a matching audiocpp_cli baseline.
  • tests/omnivoice/python_cpp_so/ is a pybind11 extension that calls the session directly, no server and no subprocess. The model loads once and is reused across generate() calls.

Docsdocs/models/omnivoice.md did not list omnivoice.generator_weight_type or omnivoice.audio_tokenizer_weight_type, so both are now in the options table.

Findings

  • omnivoice.generator_weight_type=f16 averaged 1.26x faster than native (up to 1.31x at 64 steps) and was fastest at every step count.
  • Runtime omnivoice.audio_tokenizer_weight_type=q8_0 produced unusable audio at every step count while being slower than both f16 and bf16. This is the issue Help Wanted: OmniVoice Batch Infererence #158 finding, and it is runtime quantization of SafeTensors weights — not the prebuilt Q8 GGUF package, which as you noted quantizes far more conservatively.
  • Wall time is 90-98% generator diffusion and scales linearly with step count; audio tokenizer decode stays flat near 9-10 ms. Step count is the largest latency lever, with 16 steps running 1.9x faster than the default 32.
  • Each --batch-text-file run of 10 prompts emitted 10 separate session.wall_ms values across all 375 batch combinations, matching what you described in Help Wanted: OmniVoice Batch Infererence #158: batched CLI input runs as sequential requests in one session. The 1.20x-1.36x per-request gain over an isolated single request comes from session and graph reuse, not batching — the first request in each batch is consistently the slowest.

Recommended pairing for this route:

--session-option omnivoice.generator_weight_type=f16 \
--session-option omnivoice.audio_tokenizer_weight_type=f16

Build and run

python3 tools/model_manager.py install omnivoice

cmake -S . -B build -DENGINE_ENABLE_CUDA=ON
cmake --build build --parallel --target audiocpp_cli audiocpp_server

./tests/omnivoice/run_clone_benchmark.sh
./tests/omnivoice/run_clone_batch_benchmark.sh

The pybind11 extension is opt-in behind a new ENGINE_BUILD_OMNIVOICE_PYTHON_BINDING CMake option that defaults to OFF, so existing builds are unaffected:

./tests/omnivoice/python_cpp_so/build.sh
python3 tests/omnivoice/python_cpp_so/test_so.py

build.sh passes -DENGINE_BUILD_OMNIVOICE_PYTHON_BINDING=ON rather than editing the root CMakeLists.txt. The built .so is gitignored.

Server path:

./tests/omnivoice/python_cpp_simple/run_server.sh      # terminal 1
python3 tests/omnivoice/python_cpp_simple/test_python.py   # terminal 2

Environment tested

Item Value
Backend CUDA, NVIDIA GeForce RTX 4090, 24 GiB
Model models/OmniVoice SafeTensors
Python 3.12 for the pybind11 extension
Task tts voice cloning, Bengali reference audio and text

Known limitations

  • Single-request rows in the report are one sample each after 10 warmup runs; only the aggregate means (75 runs per weight type) average out run-to-run noise.
  • The q8_0 audio-tokenizer failure is a listening judgement. The sweep WAVs were not retained, so the report does not attach a numeric similarity metric. Reproducing it means listening to the generated audio.
  • CUDA only. No CPU, Vulkan, or Metal coverage.
  • Measured on one GPU with one reference voice and one short prompt, so absolute times are not a general baseline.
  • test_so_2.py keeps a multi_infer() path that is skipped: binding.cpp does not expose generate_batch(), since there is no fused batch entry point to bind yet.
  • Raw sweep logs are not included here, since they are about 4.6 MB of CLI output. They are on my dev_kawshik branch: single inference, batch. The report tables are parsed directly from these two files.

Refs #158

@0xShug0

0xShug0 commented Aug 18, 2026

Copy link
Copy Markdown
Owner

@kawshikbuet17 Thanks for the PR! The test harness is heavier than I expected. Could you keep the benchmark report/docs and the lightweight python_cpp_simple, but drop python_cpp_so from this PR?

kawshikbuet17 and others added 2 commits August 18, 2026 21:38
Adds two CUDA sweep scripts for OmniVoice voice cloning that cover every
combination of --num-inference-steps (8 to 64), generator weight type, and
audio tokenizer weight type, for single requests and for --batch-text-file
runs. Shared Bengali reference audio, reference text, and batch prompts live
under tests/omnivoice/assets/.

The measured results are in docs/reports/omnivoice_weight_type_benchmark.md,
covering 375 single requests and 375 batch runs on an RTX 4090. Main findings:

- omnivoice.generator_weight_type=f16 is 1.26x faster than native on average,
  and up to 1.31x at 64 steps. It is the fastest setting at every step count.
- Runtime omnivoice.audio_tokenizer_weight_type=q8_0 produces unusable audio at
  every step count while being slower than both f16 and bf16, so there is no
  reason to select it. This is runtime quantization of SafeTensors weights, not
  a prebuilt Q8 GGUF package, which quantizes far more conservatively.
- Wall time is 90-98% generator diffusion and scales linearly with step count,
  while audio tokenizer decode stays flat near 9-10 ms. Step count is therefore
  the largest latency lever.
- Each --batch-text-file run of 10 prompts emits 10 separate session.wall_ms
  values, confirming that batched CLI input runs as sequential requests in one
  session rather than as a fused batch.

Also documents omnivoice.generator_weight_type and
omnivoice.audio_tokenizer_weight_type in docs/models/omnivoice.md, which did
not list either option.

Refs 0xShug0#158

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds a lightweight way to drive OmniVoice from Python while keeping all
inference in C++, reusing the shared Bengali fixtures in
tests/omnivoice/assets/.

test_python.py posts an OpenAI-compatible request to audiocpp_server using only
the Python standard library, and run_cpp.sh is a matching audiocpp_cli baseline
so the server path and the direct CLI path can be compared under identical
settings. Paths in server.json resolve relative to the config file.

No build files are touched.

Refs 0xShug0#158

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@kawshikbuet17

Copy link
Copy Markdown
Contributor Author

@0xShug0 thanks, now please check.

@0xShug0
0xShug0 merged commit ea5475a into 0xShug0:main Aug 18, 2026
7 of 8 checks passed
@0xShug0

0xShug0 commented Aug 18, 2026

Copy link
Copy Markdown
Owner

Thanks @kawshikbuet17! Merged!

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