voice_audio_multi/docs/models/inflect_v2.md
Fabio c36510c21e
Some checks failed
Linux Build / Linux cpu (push) Has been cancelled
Linux Build / Linux cpu-clang (push) Has been cancelled
Linux Build / Linux vulkan (push) Has been cancelled
mac-build / macOS CPU (push) Has been cancelled
Nix Build / Nix (cpu) (push) Has been cancelled
Nix Build / Nix (vulkan) (push) Has been cancelled
windows-build / Windows CPU (push) Has been cancelled
Initial import: audio.cpp with Orange Pi documentation
2026-11-04 19:05:22 +01:00

13 KiB
Raw Permalink Blame History

Inflect Micro v2 and Nano v2

Default model-manager downloads use the published GGUF package when available; the original source/conversion instructions below remain valid for manual use.

inflect_v2 provides native GGML inference for the English Inflect Micro v2 and Inflect Nano v2 TTS models. Both variants use the same runtime and produce 24 kHz mono audio. The initial integration supports offline FP32 inference only.

The runtime does not use ONNX Runtime. The default download is the published GGUF package. The deprecated converter can still rebuild local safetensors from the official ONNX exports for manual testing.

Install

Inflect v2 uses the shared eSpeak-ng phonemizer, including shared synchronization with other model frontends.

With AUDIOCPP_STATIC_ESPEAK=ON, the build includes eSpeak code and stages its data beside the CLI/server; no separate installation is needed. Otherwise install eSpeak-ng and its English voice data first. On Debian or Ubuntu:

sudo apt install espeak-ng libespeak-ng1

On macOS:

brew install espeak-ng

Then install the default GGUF package:

python tools/model_manager_v2.py install inflect_micro_v2_orig --models-root models

The deprecated source-conversion workflow remains available through tools/model_manager_deprecated.py for users who want to rebuild from the upstream ONNX assets themselves.

Run

audiocpp_cli --task tts --family inflect_v2 \
  --model models/Inflect-Micro-v2-GGUF/inflect-micro-v2-orig.gguf --backend cpu \
  --text "Hello from Inflect Micro version two." \
  --seed 0 --out inflect.wav

Use a converted Nano checkpoint to run Nano. CUDA uses the same model layout and request surface. CUDA sessions keep duration alignment on the native CPU GGML path so small TF32 differences cannot change the monotone expansion; the four flows and waveform decoder execute on CUDA.

If eSpeak-ng is installed outside the dynamic loader's search path, provide the library and data paths explicitly:

audiocpp_cli --task tts --family inflect_v2 \
  --model models/Inflect-Micro-v2-GGUF/inflect-micro-v2-orig.gguf --backend cpu \
  --session-option inflect_v2.espeak_library_path=/path/to/libespeak-ng.so \
  --session-option inflect_v2.espeak_data_path=/path/to/espeak-ng-data \
  --text "A configured eSpeak installation." --out inflect.wav

On Windows, espeak-ng.dll and libespeak-ng.dll are searched automatically. If eSpeak-ng is not installed system-wide, espeakng-loader can provide the external DLL and data directory:

$espeakPaths = uv run --with espeakng-loader==0.2.4 python -c `
  "import espeakng_loader; print(espeakng_loader.get_library_path()); print(espeakng_loader.get_data_path())"
$espeakLibrary = $espeakPaths[0]
$espeakData = $espeakPaths[1]

.\audiocpp_cli.exe --task tts --family inflect_v2 `
  --model ../../models/Inflect-Micro-v2 --backend cpu `
  --session-option "inflect_v2.espeak_library_path=$espeakLibrary" `
  --session-option "inflect_v2.espeak_data_path=$espeakData" `
  --text "Hello from Inflect Micro version two." `
  --seed 0 --out inflect.wav

Python is used only to locate the external files. Synthesis remains entirely inside the native audio.cpp process.

Options

Option Range Default Meaning
speed 0.5–2.0 1.0 Inflect speed multiplier; larger values shorten the output. Legacy speaking_rate remains accepted with the same meaning.
variation 0.0–1.0 0.667 Scale of the seed-based Gaussian latent variation.
seed non-negative integer 0 Latent noise seed. Long-form chunks use seed + chunk_index.
text_chunk_mode word_budget word_budget Long-form splitting mode.
text_chunk_size positive integer 280 Maximum Unicode codepoints per chunk.

Session options (use with --session-option):

Option Description
inflect_v2.espeak_library_path Explicit path to the eSpeak-ng shared library.
inflect_v2.espeak_data_path Explicit path to espeak-ng-data.
inflect_v2.exec_plan JSON object of component execution plans. Default {} keeps existing execution. Select the RKNN decoder with {"decoder":{"impl":"rknn","artifacts":{"main":"/models/decoder.rknn"}}}. No params. Requires ENGINE_ENABLE_RKNN=ON; see Rockchip NPU.

Long-form text is split near punctuation. Adjacent chunks receive 5 ms edge fades and punctuation-dependent pauses. A request is rejected if its expanded latent would exceed 4000 frames. The model has one fixed voice and exposes no language, speaker, cloning, or streaming controls.

Standalone GGUF

The inflect_v2 model specification supports standalone GGUF packaging. Pack the FP32 model.safetensors together with config.json:

audiocpp_gguf \
  --input weights=models/Inflect-Nano-v2/model.safetensors \
  --root models/Inflect-Nano-v2 \
  --output models/Inflect-Nano-v2-FP32/model.gguf \
  --type orig --family inflect_v2 \
  --model-spec model_specs/inflect_v2.json

eSpeak-ng remains an external runtime dependency and is never embedded in the GGUF.

FP16 and quantized packages are intentionally unsupported until separate parity and listening validation is available.

Validation

The frontend goldens use phonemizer==3.3.0 and espeakng-loader==0.2.4. Fixed-latent CPU output was checked against the official FP32 ONNX graphs:

Variant Mean absolute error Maximum error Correlation
Micro v2 1.54e-5 9.16e-5 0.999999976
Nano v2 1.53e-5 9.16e-5 0.999999964

Fixed-input CUDA comparisons produced mean absolute errors of 2.81e-4 and 3.39e-4, with correlations of 0.999892 and 0.999832, respectively. The component run also covered deterministic seeds, rate control, long-form output without non-finite samples, the 4000-frame rejection, and standalone FP32 GGUF loading.

The committed inflect_v2_tts_longform path case runs two 783-codepoint requests through one loaded session. Each Micro request produces 12 chunks and a 48.544-second WAV. The Windows host used a Ryzen 7 7800X3D and RTX 4090 with CUDA 13.3. The Linux CPU run used Debian 13 under WSL2, GCC 14.2, and the system libespeak-ng.so.1 without explicit session paths:

Environment Cold request Repeated request RTF cold / repeat Memory
Windows CPU, Micro v2 12180.5 ms 11901.2 ms 0.251 / 0.245 352.04 MiB observed peak RSS
Windows CPU, Nano v2 5776.82 ms 5670.52 ms 0.119 / 0.117 220.94 MiB observed peak RSS
Windows CUDA, Micro v2 714.823 ms 535.650 ms 0.0147 / 0.0110 Per-process VRAM unavailable from NVML under Windows WDDM
Windows CUDA, Nano v2 531.946 ms 443.968 ms 0.0110 / 0.00915 Per-process VRAM unavailable from NVML under Windows WDDM
WSL2 Debian 13 CPU, Micro v2 8848.11 ms 8737.13 ms 0.182 / 0.180 Not measured
WSL2 Debian 13 CPU, Nano v2 4652.59 ms 4044.53 ms 0.0959 / 0.0834 Not measured

For Micro v2, the two generated WAVs have identical frame counts and SHA-256 hashes within each environment: f78254203b26d28f4acd97bf8883617f21c2f33f38cf43452a7640aba1acb778 on Windows CPU, 01b0d2e3bd035bb942a2626c73680d442ebd18388f98d144a381134adb801e9e on CUDA, and 03a4b533ce442bab73c169426335f56d3908cc9112ca4c4858bf455ba74e30f6 under WSL2. Trace output records duration- and decoder-graph cache hits; the retained caches are bounded to four duration shapes and two decoder shapes.

On Windows CPU, Nano v2 produced two byte-identical 48.512-second WAVs with SHA-256 37de9733c5db6827c5875865cbce3fb63b632e846508e9572e6e67c2184da5aa. The Windows CUDA Nano v2 outputs were byte-identical with SHA-256 99c5c76f794adc12d491978e63346dabf0619714dc02d1291a99dadecca7ecab. The WSL2 Nano v2 outputs were also byte-identical, with SHA-256 56679f720574b6bd0470eed8ee82c0b7147be2d514ddf71afc9a53ea94c440fd.

The CUDA figures are cold and repeated requests within a fresh session after the NVIDIA kernel cache has been populated. The first request immediately after a new CUDA build spent an additional 9.5 seconds compiling kernels. For the complete long-form outputs, CPU-to-CUDA correlation was 0.999889 for Micro and 0.999759 for Nano; mean absolute errors were 2.43e-4 and 3.38e-4, respectively.

The maintainer's preview/inflect-micro-v2 branch was measured separately with the same 6026-codepoint input, Micro v2 weights, CPU, eight threads, and Ryzen 7 7800X3D host:

Implementation Wall time Audio duration RTF Real-time factor
preview/inflect-micro-v2 102.178 s 330.096 s 0.3095 3.23x
This implementation 96.825 s 335.269 s 0.2888 3.46x

This implementation has a 6.7% lower RTF in that comparison. The preview branch uses its bundled Misaki G2P resources while this implementation uses the approved external eSpeak-ng frontend, so waveform and duration parity are not implied. The native runtime incorporates the preview branch's useful backend-addressable layout reuse, indexed channel reversal, 1x1 convolution matmul, broadcast bias, and direct CPU transposed-convolution paths.

Reproduce the validation

Run the build commands from an MSVC x64 developer shell:

cmake -S . -B build-inflect -G Ninja `
  -DCMAKE_BUILD_TYPE=Release -DENGINE_BUILD_TESTS=ON
cmake --build build-inflect --parallel 8 `
  --target audiocpp_cli inflect_v2_frontend_test

cmake -S . -B build-inflect-cuda -G Ninja `
  -DCMAKE_BUILD_TYPE=Release -DENGINE_BUILD_TESTS=OFF -DGGML_CUDA=ON
cmake --build build-inflect-cuda --parallel 8 --target audiocpp_cli

Install the exact package used by the path test and resolve the external eSpeak-ng paths:

uv run --with onnx --with safetensors python tools/model_manager_deprecated.py `
  install inflect_micro_v2 --models-root build-inflect/models

$espeakLibrary = uv run --with espeakng-loader python -c `
  "import espeakng_loader; print(espeakng_loader.get_library_path())"
$espeakData = uv run --with espeakng-loader python -c `
  "import espeakng_loader; print(espeakng_loader.get_data_path())"

Run the catalog, frontend, CPU long-form, and CUDA long-form checks:

uv run python tools/check_loader_catalog_sync.py --self-test
uv run python tools/check_loader_catalog_sync.py
ctest --test-dir build-inflect -R "inflect_v2_frontend_test|model_spec_system_test" `
  --output-on-failure

uv run --with psutil --with nvidia-ml-py python `
  tools/audiocpp_cli/run_audiocpp_cli_path_tests.py `
  --cases tools/audiocpp_cli/audiocpp_cli_longform_tts_clone_cases.json `
  --only inflect_v2_tts_longform `
  --audiocpp-cli-bin build-inflect/bin/audiocpp_cli.exe `
  --model-path build-inflect/models/Inflect-Micro-v2 `
  --backend cpu --threads 8 --measure-resources `
  --out-root build-inflect/validation/inflect-v2-cpu `
  --session-option "inflect_v2.espeak_library_path=$espeakLibrary" `
  --session-option "inflect_v2.espeak_data_path=$espeakData" --log

uv run python tools/audiocpp_cli/run_audiocpp_cli_path_tests.py `
  --cases tools/audiocpp_cli/audiocpp_cli_longform_tts_clone_cases.json `
  --only inflect_v2_tts_longform `
  --audiocpp-cli-bin build-inflect-cuda/bin/audiocpp_cli.exe `
  --model-path build-inflect/models/Inflect-Micro-v2 `
  --backend cuda --threads 8 `
  --out-root build-inflect-cuda/validation/inflect-v2-cuda `
  --session-option "inflect_v2.espeak_library_path=$espeakLibrary" `
  --session-option "inflect_v2.espeak_data_path=$espeakData" --log

The generated WAVs, request files, commands, logs, and summaries are under:

  • build-inflect/validation/inflect-v2-cpu/inflect_v2_tts_longform/
  • build-inflect-cuda/validation/inflect-v2-cuda/inflect_v2_tts_longform/

The Linux CPU validation can be reproduced from Debian 13 under WSL2. A system eSpeak-ng installation is discovered automatically, so no session options are needed:

sudo apt install build-essential cmake python3 espeak-ng libespeak-ng1

cmake -S . -B build-inflect-wsl \
  -DCMAKE_BUILD_TYPE=Release -DENGINE_BUILD_TESTS=ON
cmake --build build-inflect-wsl --parallel "$(nproc)" \
  --target audiocpp_cli inflect_v2_frontend_test

build-inflect-wsl/bin/inflect_v2_frontend_test
build-inflect-wsl/bin/audiocpp_cli --list-loaders --json

python3 tools/audiocpp_cli/run_audiocpp_cli_path_tests.py \
  --cases tools/audiocpp_cli/audiocpp_cli_longform_tts_clone_cases.json \
  --only inflect_v2_tts_longform \
  --audiocpp-cli-bin build-inflect-wsl/bin/audiocpp_cli \
  --model-path build-inflect/models/Inflect-Micro-v2 \
  --backend cpu --threads 8 \
  --out-root build-inflect-wsl/validation/inflect-v2-wsl --log

Use build-inflect/models/Inflect-Nano-v2 as --model-path to repeat the same path test with Nano.

Known limitations

  • English, one fixed voice, and offline TTS only.
  • eSpeak-ng and its data remain external runtime dependencies.
  • Only FP32 packages are supported.
  • Windows CPU/CUDA and Linux CPU under WSL2 are runtime-validated. Native Linux CUDA, Vulkan, and Metal are not practically validated for this release.
  • CUDA deliberately performs duration alignment on CPU. CPU and CUDA are deterministic within a backend but are not bit-identical to each other.
  • Windows WDDM did not expose per-process VRAM through NVML, so no CUDA peak VRAM figure is claimed.