voice_audio_multi/docs/models/cosyvoice3.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

7.7 KiB

CosyVoice3

CosyVoice3 is a GGUF TTS family for zero-shot voice cloning, cross-lingual speech, and instruction-conditioned speech. The default package is Q8_0.

Quick Start

Download the default Q8_0 package:

python3 tools/model_manager_v2.py install cosyvoice3_q8_0 --models-root models

Zero-shot voice cloning:

audiocpp_cli \
  --task clon \
  --family cosyvoice3 \
  --model models/CosyVoice3-GGUF/cosyvoice3-q8_0.gguf \
  --backend cuda \
  --text "This is a local CosyVoice3 voice cloning test." \
  --voice-ref assets/resources/b.wav \
  --reference-text "Some call me nature. Others call me Mother Nature. I have been here for over four and a half billion years." \
  --request-option template_name=zero_shot \
  --out cosyvoice3_clone.wav

Instruction-conditioned speech:

audiocpp_cli \
  --task tts \
  --family cosyvoice3 \
  --model models/CosyVoice3-GGUF/cosyvoice3-q8_0.gguf \
  --backend cuda \
  --text "Please read this with a calm and friendly tone." \
  --voice-ref assets/resources/b.wav \
  --reference-text "Some call me nature. Others call me Mother Nature. I have been here for over four and a half billion years." \
  --request-option template_name=instruct \
  --request-option instruct="Speak warmly with clear articulation." \
  --out cosyvoice3_instruct.wav

Model

Field Value
Family cosyvoice3
Default GGUF models/CosyVoice3-GGUF/cosyvoice3-q8_0.gguf
Tasks tts, clon
Modes offline
Languages zh, en, ja, ko, de, es, fr, it, ru, yue
Voice input Required reference WAV through --voice-ref

Templates

template_name Use
zero_shot Voice cloning with prompt audio and transcript.
cross_lingual Cross-lingual voice cloning from prompt audio.
instruct Instruction-conditioned speech with prompt audio.

Common Options (use directly)

Option Values Default Meaning
--voice-ref WAV path required Prompt/reference speaker audio.
--reference-text text empty Transcript for prompt audio.

Request Options (use with --request-option)

Option Values Default Meaning
reference_text text empty Transcript for prompt audio.
template_name zero_shot, cross_lingual, instruct zero_shot Request template.
instruct text empty Instruction text for instruct mode. Legacy instruction remains accepted.
text_chunk_size integer > 0 600 Long-form text chunk size.
text_chunk_mode default, tag_aware, japanese, endline default Framework text chunk mode.
max_tokens -1 or integer > 0 -1 Automatic maximum: 20 times the target text token count.
min_tokens -1 or integer >= 0 -1 Automatic minimum: twice the target text token count; must not exceed the resolved maximum.
top_k integer > 0 25 AR speech-token top-k sampling limit.
num_inference_steps integer > 0 10 Flow decoder Euler steps.
seed integer >= 0 1986 Generation seed.

Session Options (use with --session-option)

Option Values Default Meaning
cosyvoice3.reference_cache_slots integer >= 0 4 Prepared reference-audio cache slots.
cosyvoice3.lora adapter directory or file not set PEFT LoRA, or a native checkpoint containing lora_weights.pt, config.json, speech_embedding.pt, and llm_decoder.pt. Only LLM weights are adapted.
cosyvoice3.lora_scale finite float 1 Multiplier for alpha/r. Full embedding/head replacements are not scaled.
cosyvoice3.mem_saver bool false Release cached runtime graphs after request phases.
cosyvoice3.exec_plan JSON object {} Component execution plans. The only component is flow; see the RKNN section.

Rockchip NPU (RKNN) estimator

The flow decoder is the expensive half of this family: the DiT estimator runs once per Euler step (num_inference_steps, default 10) over the whole utterance, and on an RK3588 it is ~79% of synthesis. cosyvoice3.exec_plan voices that one stage through librknnrt and leaves the AR LLM and the HiFT vocoder on the host, which is the split the reference RKNN port of this model measured best: a quantized NPU LLM degrades the speech tokens, and a quantized HiFT adds high-frequency artifacts.

RKNN has no runtime graph builder, so each engine is compiled offline for one fixed sequence length. Build them on an x86_64 host from the same checkpoint the GGUF was converted from:

python3 tools/rknn/prepare_cosyvoice3_rknn_flow.py \
    --estimator-onnx flow.decoder.estimator.fp32.onnx \
    --seq-len 200 --seq-len 500 --seq-len 900 --seq-len 1100 \
    --output-dir models/CosyVoice3-RKNN

Then point the session at the ladder (order does not matter; the smallest engine that fits is used, and an utterance longer than the largest engine runs the CPU graph). The ladder travels as the flow component's main artifact, comma-separated — see component execution plans:

audiocpp_cli --task clon --family cosyvoice3 --model models/CosyVoice3-GGUF/cosyvoice3-q8_0.gguf \
    --backend cpu --session-option 'cosyvoice3.exec_plan={"flow":{"impl":"rknn","artifacts":{"main":"models/CosyVoice3-RKNN/flow_estimator_seq200.rknn,models/CosyVoice3-RKNN/flow_estimator_seq900.rknn"}}}' \
    --text "..." --voice-ref assets/resources/b.wav --reference-text "..." --out out.wav

Build with -DENGINE_ENABLE_RKNN=ON (plus ENGINE_RKNN_LIBRARY / ENGINE_RKNN_INCLUDE_DIR pointing at the board's librknnrt); a plan selecting impl: rknn throws at load in a build without it rather than falling back silently. Each engine is ~700 MB and an utterance is padded up to the engine's length, so the ladder is a time trade: the estimator costs about S^2, and the padding is exact (measured bit-identical to an unpadded run), not a quality one.

What it measures on an RK3588

Measured on an Orange Pi 5 Plus (RK3588, 32 GB, librknnrt 2.3.2, --backend cpu --threads 4, 10 Euler steps, same text/seed/reference on both paths), dit_ms for the whole ODE loop:

mel frames engine (pad) ggml CPU RKNN
102 seq200 (98) 8.48 s 11.49 s
212 seq500 (288) 19.14 s 57.10 s
102 seq110 (8) 8.48 s 6.14 s
212 seq250 (38) 19.29 s 18.51 s
402 seq400 (2) 38.87 s 38.84 s

The estimator on the NPU is at parity with four A76 cores running the ggml graph, so the padding is what decides: a coarse ladder loses by 3x, a dense one breaks even above 200 frames and wins 1.38x only at the shortest lengths. Peak RSS is 3.8-6.8 GB against 2.3-2.6 GB.

Two ceilings bound the ladder. The flow's frame count includes the prompt mel, so a 4-second reference puts every utterance above 700 frames. And the driver's IOVA arena is 32-bit on this kernel: one engine asks 0.7 GB at seq110 and 4.71 GB at seq900, and above about 4 GB rknn_init fails with -4 (RKNPU: failed to allocate IOVA: -12), which is why the ladder is loaded lazily, one engine resident. Engines above ~700 frames are therefore unusable on this board, and long utterances — where the estimator is 79% of synthesis — run on the ggml graph.

The fp16 cost of the graph, measured on the PC simulator against the fp32 ONNX (seq200, 106 real frames): snr 44.0 dB, tail snr 60.5 dB, max_abs 0.5544, mean -3.83689 against -3.83806. There is no systematic mel bias, so no offset knob is needed.

Legacy cosyvoice3.conv_weight_type remains accepted but has no consumer and does not change convolution storage. The implementation uses the shared cosyvoice3.weight_type setting with its existing component storage rules.