Repository navigation
Description
fish_drama3: changes needed for parity with Fish Speech's Drama 3
An analysis from Claude Code on max setting before an attempt was made to integrate audio.cpp with FS Drama 3. Feel free to close as won't fix.
We narrate audiobooks with fishaudio/drama-3 through Fish Speech 1ff3c3e. It runs on an NVIDIA T1000 (Turing, sm_75, 8 GB) with the routed experts in host RAM, and we'd like to move it to fish_drama3. We compared the port on main (as of 2026-11-03) with Fish Speech. This issue identifies possible updates necessary to run on that card. #1 needs a package or a confirmed conversion. A client can work around #2–#6, by setting the session option itself or by sending one chunk per request with its own previous_takes. Even so, the port's defaults and built-in long-form path still differ from Fish Speech's generate_long_drama3.
1. No package with 8-bit experts
- The release ships "FP8 MoE experts with the remaining weights in bf16". We dequantize the experts to BF16, so we run them at essentially the release's precision.
Jmica/Drama-3-GGUFonly has Q4_K, Q3_K and Q2_K expert banks.- The model doc's known issues say emotion and nonverbal prompts can "produce prolonged reactions, omit dialogue or reach the generation cap", and that "This occurs with both the original Q4-expert package and smaller formats." Our quotations carry such directions, so we'd want quantization ruled out as the cause.
convert_fish_drama3.pytakes--expert-type, but the doc only showsq3_kandq4_k.- Ask: confirm that
--expert-type q8_0works, and ideally publish a Q8_0-expert package.
2. BF16 reference encoding is on by default on Turing
- Turing has no native BF16 arithmetic. The doc says: "On CUDA, BF16 reference-encoder arithmetic is enabled by default with F16/BF16 codec weights." It reports testing on an RTX PRO 6000 Blackwell.
- Ask: default
fish_drama3.codec_encoder_bf16_computetofalsebelow compute capability 8.0, or confirm it's safe there.
3. History doesn't keep the first chunk
- Fish Speech's
Drama3History(chunking.py) keeps a request's first chunk in every later chunk's history and adds the most recent one (DRAMA3_HISTORY_RECENT_TURNS = 1). - The port adds only the previous chunk (
session.cpp):if (!generated_takes.empty()) context.push_back(generated_takes.back()); - Ask: keep the first generated chunk as well.
4. Prompts that outgrow the context are rejected
- When
build_drama3_promptraisesDrama3PromptTooLongError, Fish Speech (inference.py) tries shorter histories, longest first. It also caps each chunk's new tokens at the room left:limit = capacity - len(prompt),budget = min(requested, limit). - The port throws before decoding (
generator.cpp): "Drama 3 prompt plus max_tokens exceeds fish_drama3.context_length; increase it or shorten history."fish_drama3.context_lengthdefaults to 2048 andmax_tokensto 1024. - Ask: clamp
max_tokensto the context left, and fall back to shorter histories as Fish Speech does.
5. A chunk that ends before its first frame
- Fish Speech logs "The model emitted EOS before any audio frame", yields nothing for that chunk, leaves it out of the history, and goes on.
- The port throws
Drama 3 ended before producing an audio frame(generator.cpp). - Ask: skip the chunk the same way, and report the skip in
drama3_generation_v1.
6. Chunk size and per-chunk token cap
- Fish Speech splits at
DRAMA3_CHUNK_BYTES = 300UTF-8 bytes. That is a threshold, not a hard cap: a protected span such as a<|…|>token or a[bracketed]cue stays whole even when it is longer. Each chunk may addDRAMA3_CHUNK_MAX_NEW_TOKENS = 600new tokens, about 27.9 s. - The port defaults to
text_chunk_size=128characters andmax_tokens=1024. - Ask: default to Fish Speech's 300-byte budget and 600-token cap.
Activity
0xShug0 commentedon Nov 3, 2026
@DarkTyger Thanks for the suggestions!. 5/6 should not become default behavior as proposed. #891 has more measurements and context. And 5 turns an explicit failure into silence missing narration. For 5, we could add an opt-in option, similar to Higgs Audio, to skip empty chunks and continue generation. The default should still report an error so missing speech isn’t silently accepted.
For 2, the option is not merely a hardware-compatibility toggle. It can change output and performance.
I will look at 3 and 4.
0xShug0 commentedon Nov 4, 2026
@DarkTyger 3 and 4 are fixed. Could you share a test case to reproduce 5?
DarkTyger commentedon Nov 4, 2026
issue-5.md
Claude generated so hopefully it works. To use it, make an empty directory, paste the script in as issue-5.sh, chmod +x it and run it.
0xShug0 commentedon Nov 4, 2026
@DarkTyger Thanks! Reproduced the issue and added an opt-in
skip_empty_chunksoption to log a warning and skip empty chunks, matching upstream. The default still throws so downstream app can catch and handle the failure.