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

20 KiB

Fish Audio Drama 3

fish_drama3 is a community model port of fishaudio/drama-3. Inference runs in native audio.cpp with GGML; Python is used to prepare the checkpoint.

Built with Fish Audio.

The base model includes the 40-layer hybrid attention/MoE backbone, 256 experts with eight selected per token, four shared enrichment layers, nine residual codebook layers with persistent timeline caches, and the Fish DAC encoder/decoder. It supports offline and streaming TTS, voice references, speaker and event tags in text, long-form chunking, and continuation/edit history.

Variants

Both variants use --family fish_drama3 and the same CLI and server routes. The loader reads layer-specific expert counts and the output-head layout from the checkpoint, so Drama3-small does not need a separate family.

Variant GGUF packages Source
Drama3 base Q2_K, Q3_K, and Q4_K expert packages Jmica/Drama-3-GGUF
Drama3-small fish_drama3_small_iq3_xxs: Drama3-small-GGUF/drama3-small-IQ3_XXS.gguf pentacoxian-dev/drama3-small-GGUF

Install the small variant with:

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

Use --model models/Drama3-small-GGUF/drama3-small-IQ3_XXS.gguf with the generation examples below. Base-model weight sizes and memory measurements in this guide do not describe the small checkpoint.

Windows build

Install Visual Studio 2022 C++ build tools, a CUDA toolkit that supports your GPU, and Git. Use the Drama 3 branch and initialize its public frontend submodule:

git clone --branch drama-3-native https://github.com/JarodMica/audio.cpp.git
Set-Location audio.cpp
git -c submodule.external/audio.cpp-server-frontends.url=https://github.com/0xShug0/audio.cpp-server-frontends.git submodule update --init --recursive

The command-local HTTPS override lets the public frontend submodule download without GitHub SSH credentials. It does not modify .gitmodules or global Git configuration.

Run the build helper from the repository root. It selects the required model dependencies and detects the CUDA architecture:

.\scripts\build_windows.ps1 -Preset windows-cuda-release -ModelSet custom -Models fish_drama3 -Target audiocpp_cli -Jobs 4
.\scripts\build_windows.ps1 -Preset windows-cuda-release -ModelSet custom -Models fish_drama3 -Target audiocpp_server -Jobs 4

The executables are in build\windows-cuda-release\bin. A CPU runtime uses the windows-cpu-release preset with the same model selection. To override automatic CUDA detection, add -CudaArchitectures with the architecture for your GPU.

Download a runnable GGUF

Install uv, then download one package from Jmica/Drama-3-GGUF. For the Q2 expert package:

uv run --no-project --python 3.12 --with huggingface_hub hf download `
  Jmica/Drama-3-GGUF drama-3-backbone-8bit-experts-Q2_K.gguf `
  --local-dir models\Drama-3-GGUF

The model manager lists the base and small packages:

uv run --no-project --python 3.12 tools\model_manager_v2.py list | Select-String 'fish_drama3'
uv run --no-project --python 3.12 tools\model_manager_v2.py install fish_drama3_q2_experts_q8_backbone --models-root models
File Size Expert banks Other backbone matrices
drama-3-backbone-8bit-experts-Q4_K_S.gguf 22.91 GiB Q4_K Q8_0
drama-3-backbone-8bit-experts-Q3_K_S.gguf 18.93 GiB Q3_K Q8_0
drama-3-backbone-8bit-experts-Q2_K.gguf 15.88 GiB Q2_K Q8_0
drama-3-backbone-4bit-experts-Q4_K_S.gguf 21.78 GiB Q4_K Q4_K, with Q4_0 text embedding

These packages use standard GGML K-quants. The Q3_K_S and Q4_K_S file profiles use pure expert banks: all 120 routed expert projection banks have uniform Q3_K or Q4_K storage. Their storage-type selection corresponds to a standard --pure K profile with explicit precision overrides for the dense backbone, text embedding and audio components. Architecture-specific higher-bit promotion heuristics are not applied; an unmodified default llama.cpp preset can choose different types for some tensors. See the standard converter's pure and per-tensor options. The native converter takes --expert-type q3_k or --expert-type q4_k. backbone-8bit means Q8_0 backbone matrices; backbone-4bit means Q4_K matrices with a Q4_0 text embedding. Q2 experts use uniform Q2_K storage.

All four packages retain FP16 audio-tower matrices and waveform codec weights. Backbone and audio-tower normalization vectors stay FP32; codec normalization vectors use FP16 with the rest of the codec. The packages embed their tokenizer, configuration and model contract. Stock audio.cpp releases without this port cannot run Drama 3.

Prepare weights with uv

Conversion is optional when using a downloaded package. Build the native converter if you want to prepare a different precision:

.\scripts\build_windows.ps1 -Preset windows-cpu-release -ModelSet custom -Models fish_drama3 -Target audiocpp_gguf -Jobs 4

Download the complete official checkpoint into models\drama-3-original. The revision below is the checkpoint used for validation:

uv run --no-project --python 3.12 --with huggingface_hub hf download fishaudio/drama-3 --revision dd64a85cd82e9521f7202610ede97b367fc83946 --local-dir models\drama-3-original

Its original per-expert FP8 tensors have 128-by-128 inverse scales. The preparation script applies those scales and packs each projection into an expert bank.

uv run --python 3.12 tools\community_models\convert_fish_drama3.py `
  --checkpoint models\drama-3-original `
  --output models\drama3-f16-local.gguf `
  --quantized-output models\drama-3-backbone-8bit-experts-Q4_K_S.gguf `
  --gguf-tool build\windows-cpu-release\bin\audiocpp_gguf.exe

The intermediate tensor archive is approximately 68.2 GiB. The runnable package is approximately 22.9 GiB, with Q4_K routed experts, Q8_0 backbone matrices, FP16 audio tower and codec weights, and embedded configuration, tokenizer and license files. Codec weight normalization is folded during packaging. Allow space for both files during conversion. The intermediate archive is retained.

An existing intermediate can be reused with --input-gguf in place of --output. --expert-type selects the routed expert format; --backbone-type selects other backbone matrices; --embedding-type selects the text embedding format. Keep the embedding at a CUDA-supported lookup type such as Q8_0 or Q4_0. Conversion uses CPU PyTorch dependencies managed by uv and does not load weights onto a GPU.

Generate and stream

Host sampling is used by default. Set --session-option fish_drama3.device_sampling=true to enable tower decode and codebook sampling in one cached backend graph, or select the cuda_perf preset. Graph probability arithmetic is F32, so sampled outputs may differ from host sampling.

fish_drama3.perf_mode defaults to off. The opt-in cuda_perf preset sets the following defaults; explicit session options override the preset:

Session option off cuda_perf Effect
fish_drama3.fused_moe false true Cached-decode routing and SwiGLU fusion.
fish_drama3.kv_cache_type f16 f16 KV storage precision, not weight precision. Set f32 to use F32 KV storage.
fish_drama3.kv_cache_alignment 1 256 Cached attention-prefix buckets; all history retained.
fish_drama3.device_sampling false true Cached tower decode and device sampling.
fish_drama3.codec_batch_frames 4 4 Streaming codec batch ceiling; existing default retained.
fish_drama3.codec_async_decode true true Streaming AR/codec overlap; existing default retained.
fish_drama3.backbone_prefill_cache_mb 256 256 Backbone prefill graph-cache budget in MiB; existing default retained.
fish_drama3.tower_prefill_cache_mb 256 256 Tower prefill graph-cache budget in MiB; existing default retained.

off retains the defaults listed above. Explicit session options override either preset, including fish_drama3.device_sampling=false with cuda_perf.

Fused arithmetic and attention shapes can change sampled audio. To enable the combined CUDA path, add:

--session-option fish_drama3.perf_mode=cuda_perf

Streaming defaults to a four-frame codec batch ceiling with AR/codec overlap. To use one-frame synchronous decoding:

--session-option fish_drama3.codec_batch_frames=1
--session-option fish_drama3.codec_async_decode=false

Batching starts with one frame, grows to the configured ceiling, and flushes the final partial batch. Larger batches retain more codec workspace and can introduce small waveform rounding differences without changing AR sampling. Overlap uses the dedicated codec backend and completes all audio before the request returns. Offline decoding is unchanged.

.\build\windows-cuda-release\bin\audiocpp_cli.exe `
  --task tts --family fish_drama3 --backend cuda --mode streaming `
  --model models\Drama-3-GGUF\drama-3-backbone-8bit-experts-Q2_K.gguf `
  --text 'A quick test of Drama Three on Windows.' `
  --max-tokens 500 --seed 123 --threads 8 `
  --session-option fish_drama3.cpu_expert_layers=8 `
  --session-option fish_drama3.context_length=2048 `
  --out speech.wav

For the tested 16 GB offload configurations, use 8 CPU expert layers with Q2, 12 with Q3, 24 with Q4-experts, or 20 with Q4-backbone. For a 24 GB configuration, use 4 with Q4-experts or 0 with the other packages. These are starting settings, not enforced memory limits. They were measured on a 96 GB GPU; physical 16 GB and 24 GB cards have not been tested. These counts control where expert weights and matmuls run. The backbone's attention/dense weights and the audio tower use the selected backend. fish_drama3.codec_backend=cpu moves codec computation to CPU as well.

If Vulkan voice cloning produces incomplete speech or reaches the token limit, try --session-option fish_drama3.codec_encoder_f32_accumulation=true.

This opt-in control uses F32 accumulation in the Vulkan reference encoder while keeping F16 storage. It defaults to false and does not change codec decoding or other backends. It also works with existing GGUFs without replacing their specs.

On CUDA, BF16 reference-encoder arithmetic is enabled by default with F16/BF16 codec weights. Set --session-option fish_drama3.codec_encoder_bf16_compute=false to restore the previous encoder arithmetic. This changes reference-conditioned generation but does not change codec decoding or backbone inference.

To reduce reference-encoder convolution memory, set --session-option fish_drama3.codec_encoder_chunk_samples=65536. The value is measured in samples at the codec sample rate and must be zero (the default, full encoding) or a positive multiple of 512. Chunking starts when the padded reference exceeds the chunk size plus 16,384 context samples; shorter references use the full graph. Overlapping convolution windows reuse one cached graph; the transformer and quantizer still process the full feature sequence, so total memory is not constant. Chunking can cost additional time and produce small backend-dependent numerical differences. Existing GGUFs accept the option without a spec override.

Sampling defaults to top_k=4097, which keeps every candidate for the semantic token and each tower codebook, so only top_p=0.9 filters. This matches Fish's official Drama 3 Space, which dropped the top-k cap because top_k=30 left takes stuck in silence. With --request-option top_k=30, long chunked requests can stall for about 9-21 s. The repetition-avoiding resample keeps its own top_k=30, top_p=0.95.

Host memory is required for offloaded weights. Context capacity includes text, reference audio frames, prior takes, and the requested generation budget.

Disk-backed experts

Set fish_drama3.disk_experts=true to keep the full routed expert banks in the GGUF file and read only selected experts into a bounded native-format cache. fish_drama3.expert_cache_size sets resident slots per layer (8 to 256; default 32). Dense backbone, tower, and codec weights remain resident. The existing cpu_expert_layers setting still selects CPU execution for those layers, but their expert caches are bounded too. No GGUF conversion is required.

fish_drama3.disk_expert_read_threads selects 1 to 64 host workers for copying selected experts from the memory-mapped GGUF into staging. The default is 1 (serial); try 4 to enable parallel copies using OpenMP or Apple dispatch. This applies only with disk_experts=true and pin_experts=false. Backend uploads and inference are unchanged. The host reader is backend-independent; Apple builds do not require OpenMP for parallel reads.

This is a memory/speed trade-off, not a faster MoE kernel. With cpu_expert_layers=0, prompt prefill groups tokens by expert within each layer, so one upload serves multiple tokens. Attention and shared/router projections retain the resident batched-prefill path; cached experts retain their vector projection path. Session-owned graphs share one activation workspace and are reused for the same exact prompt length while retained. A different length replaces that graph set rather than reusing a rounded capacity for stateful attention. Offline disk mode releases backbone and tower prefill graphs before waveform decoding, without clearing continuation state. Later full prefills rebuild those workspaces; resident execution keeps its existing cache policy. Mixed CPU/backend expert execution retains token-wise prefill. Storage speed still matters, and resident mode remains the default. For the minimum cache:

--session-option fish_drama3.disk_experts=true
--session-option fish_drama3.expert_cache_size=8
--session-option fish_drama3.cpu_expert_layers=0

When sufficient host RAM is available, add fish_drama3.pin_experts=true and set fish_drama3.cpu_expert_layers=0. This loads full expert banks into pinned host memory once, then uploads cache misses directly without an intermediate host copy. Expert matmuls still run on the selected backend, and GPU cache size is unchanged. This option is off by default and requires pinned host-buffer support; allocation failure is an error, not a fallback to a different memory policy.

Logs report disk_experts.bytes_read, disk_experts.expert_loads, disk_experts.cache_hits, disk_experts.buffer_mb, and disk_experts.host_buffer_mb when the session is destroyed. These describe expert I/O and cache allocation, not total process peak VRAM. With pinned experts, bytes read include the initial host-bank load instead of per-request cache-miss reads.

Serve over HTTP

Save the following as drama3-server.json in the repository root:

{
  "host": "127.0.0.1",
  "port": 8035,
  "backend": "cuda",
  "threads": 8,
  "lazy_load": true,
  "max_loaded_models": 1,
  "idle_unload_ms": 300000,
  "ui": true,
  "models": [{
    "id": "drama-3",
    "family": "fish_drama3",
    "path": "models/Drama-3-GGUF/drama-3-backbone-8bit-experts-Q2_K.gguf",
    "task": "tts",
    "mode": "streaming",
    "session_options": {
      "fish_drama3.cpu_expert_layers": 8,
      "fish_drama3.context_length": 2048
    },
    "default_request_options": {"max_tokens": 500}
  }]
}
.\build\windows-cuda-release\bin\audiocpp_server.exe --config drama3-server.json

The server exposes POST /v1/audio/speech and the task APIs, including streaming events and continuation artifacts. See the server guide.

Voice references

For cloning, add --voice-ref reference.wav and --request-option 'reference_text=What the reference says.'. Use --task clon to require a reference. Ordered references can also be supplied through multi_reference_cond or references as a JSON string:

[{"text":"<|speaker:0|> First reference.","audio_path":"first.wav"},
 {"text":"<|speaker:1|> Second reference.","audio_path":"second.wav"}]

Descriptors accept vq_codes instead of audio_path: a nonempty integer grid with ten rows, one per codebook. Text accepts <|speaker:0|> through <|speaker:15|> and event tags such as [sighs] and [laughs].

Continuation and editing

previous_takes is a JSON string containing ordered earlier takes. Each object has text and either vq_codes or audio_path. Earlier text strings can also be given; the runtime generates their codes before the requested take. previous_takes_file accepts the same data from a JSON file, including a single take object. Use it for VQ grids that exceed the Windows command-line limit.

--request-option 'previous_takes=["The report is due on Wednesday."]'
--text 'The report is due on Thursday.'

The library returns an AcousticTokens artifact named drama3_take, with family=fish_drama3 and schema=drama3_take_v1. Its UTF-8 JSON payload contains the text and VQ grid. Keep this artifact and pass it in the next request's input_artifacts to reuse the original codes for an edit. Multiple artifacts carry chained history. The current take's audio is returned separately.

Streaming sessions use IStreamingVoiceTaskSession. start_stream() runs synchronously and calls the event sink while audio is generated; finalize() returns the complete audio and the reusable take artifact. An application can invoke generation on its worker thread to keep its UI responsive.

Long-form text uses the framework chunker, with text_chunk_size=128 and text_chunk_mode=tag_aware by default. Each new chunk includes the previous chunk as context. Caller-supplied history remains ordered in every chunk.

Validation limits

Reproducible codec, tokenizer, quantization and HTTP smoke commands are in the Drama 3 test guide.

The port was exercised on native Windows with an RTX PRO 6000 Blackwell 96 GB, CUDA 12.8 and eight CPU worker threads. English speech, voice references, streaming audio and continuation/edit artifacts were checked. Streaming emits 44.1 kHz audio, with streamed chunks matching the complete output in the tests.

Independent checks cover hybrid backbone prefill and cached decode, actual Q2_K, Q3_K and Q4_K expert bank types and layouts against dequantized PyTorch weights, CPU/GPU expert splits, audio tower prefill/cached decode, and exact prompt rows against the official builder. Repeated seeded generation and offline/streaming generation produced identical codes within each profile. English transcript checks recovered the requested speech, including Wednesday-to-Thursday and noon-to-five edits.

This is an experimental port. Some emotion and nonverbal prompts produce prolonged reactions, omit dialogue or reach the generation cap. This occurs with both the original Q4-expert package and smaller formats. A heavier Q2 CPU offload trial also reached the long-form cap; the documented eight-layer configuration completed that case. These checks do not establish full perceptual parity with the original checkpoint. Multilingual pronunciation, speaker similarity and event delivery have not received a broad perceptual evaluation. A native seed reproduces a take within the same execution configuration; changing offload placement can change floating-point results and the sampled take.

The weights are subject to the Fish Audio Community License. See the model repository's LICENSE and NOTICE.