Add classifier-free guidance support for Chatterbox (fixes multilingual) + MinPLogitsWarper - #1705
Add classifier-free guidance support for Chatterbox (fixes multilingual) + MinPLogitsWarper#1705tibzejoker wants to merge 1 commit into
Conversation
- ChatterboxModel: when generation_config.guidance_scale > 1, run an internal batch of two sequences (conditional + unconditional with zeroed text token embeddings), matching the reference PyTorch implementation (resemble-ai/chatterbox T3.inference, cfg_weight=0.5). The multilingual checkpoint requires CFG to produce intelligible speech. - Move ClassifierFreeGuidanceLogitsProcessor to the front of the processor list, matching the python transformers ordering (the cond/uncond batches must be combined before any other processor). - Add MinPLogitsWarper and the min_p generation config option (used by the official Chatterbox sampling parameters). Fixes huggingface#1656
nico-martin
left a comment
There was a problem hiding this comment.
Hi @tibzejoker, thank you so much for looking into this! The CFG approach follows the reference implementation and looks solid overall. Could you add tests for the CFG path itself, make MinP reject NaN, and share the model/tokenizer revision used for the WebGPU checks? I'm holding off on merging because the main CFG behavior is currently untested and NaN silently disables MinP filtering.
| // parity with the python defaults) to a value > 1. The two rows are | ||
| // recombined by `ClassifierFreeGuidanceLogitsProcessor`, so the | ||
| // batch size visible to `generate()` remains 1. | ||
| const use_cfg = generation_config?.guidance_scale > 1; |
There was a problem hiding this comment.
Please add deterministic coverage for the CFG path: two-row prefill, text-only unconditional masking, retained speaker/speech conditioning, cached-token duplication, two-row cache/mask state, and reduction back to the user-visible batch size. The current tests exercise only MinP.
| */ | ||
| constructor(min_p, { filter_value = -Infinity, min_tokens_to_keep = 1 } = {}) { | ||
| super(); | ||
| if (typeof min_p !== 'number' || min_p < 0 || min_p > 1.0) { |
There was a problem hiding this comment.
This accepts NaN, after which the threshold is NaN and filtering silently does nothing. Please require Number.isFinite(min_p) and add a rejection test.
|
+1 |
Fixes #1656
TL;DR
The Chatterbox multilingual checkpoint was thought to be unsupported ("requires special setup"). After a full investigation (ONNX graph diffing against the English export, tokenizer comparison, and step-by-step replication of the reference PyTorch sampling loop), it turns out the architecture is already fully supported by the existing
ChatterboxModel— the missing piece in the library is classifier-free guidance (CFG), which the reference implementation (resemble-ai/chatterboxT3.inference) always applies withcfg_weight=0.5. Without CFG the multilingual model only produces short unintelligible vocalizations followed by an early EOS; with it, it produces correct cloned speech (validated in-browser on WebGPU in French and German with a 10s reference voice).Changes
ChatterboxModel: CFG support, enabled viaguidance_scale(=1 + cfg_weight, i.e.1.5for parity with the python defaults). Whenguidance_scale > 1,forwardinternally runs a batch of two sequences — the conditional input and an unconditional copy whose text token embeddings are zeroed (matchingtext_emb[1].zero_()in the reference implementation; speaker conditioning, exaggeration and speech tokens are shared between the two rows). The two rows are recombined by the existingClassifierFreeGuidanceLogitsProcessor, so the batch size visible togenerate()stays 1. Opt-in: no behavior change whenguidance_scaleis unset.ClassifierFreeGuidanceLogitsProcessorto the front of the list, matching the pythontransformersordering — the cond/uncond logits must be combined back into a single batch before any other processor (e.g. repetition penalty) runs.MinPLogitsWarper+ themin_pgeneration option (full implementation incl.min_tokens_to_keep, with unit tests). The official Chatterbox sampling parameters usemin_p=0.05.Usage (multilingual)
Note on the multilingual model files (for anyone reproducing)
There is currently no official ONNX repo with complete configs for the multilingual checkpoint. The community mirror's
tokenizer.jsonhas a brokenpost_processor(itsTemplateProcessingspecial tokens are referenced without brackets —"BOS","EOS","START_SPEECH","EXAGGERATION"— which don't exist in the vocab, so all five special tokens encode to[UNK]). The correct template, identical to the working English export, is:[EXAGGERATION](6563) [START](255) …text… [STOP](0) [START_SPEECH](6561) [START_SPEECH](6561). Happy to help fix/publish corrected model files if useful.Validation
pnpm build✓ (incl. typegen),pnpm format:check✓,logits_processtest suite ✓ (incl. 3 newMinPLogitsWarperunit tests).