Skip to content

Update ChatterboxNano - #542

Merged
jin9581 merged 1 commit into
masterfrom
chatterbox_nano
Jul 21, 2026
Merged

jin9581 merged 1 commit into
masterfrom
chatterbox_nano

Conversation

@jin9581

@jin9581 jin9581 commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@jin9581
jin9581 requested a review from enhuiz July 21, 2026 10:52
@jin9581
jin9581 merged commit 5de7a54 into master Jul 21, 2026
1 check passed
@jin9581
jin9581 deleted the chatterbox_nano branch July 21, 2026 12:27
breevido added a commit to breevido/chatterbox that referenced this pull request Sep 10, 2026
0.1.7 was published on 2026-03-26 and predates Chatterbox-Nano (resemble-ai#542),
the opt-in V3 checkpoint (resemble-ai#516), and the V3 + Single Language Pack
release. Because __version__ resolves from dist metadata, a source
install of master and a pip install of 0.1.7 both reported 0.1.7 while
exposing different APIs -- from_pretrained accepts nano= and t3_model=
on master but not in the published wheel.

Minor bump rather than patch: these are new models and new keyword
arguments, not fixes.

Also rewords the README install note from a stopgap ("the current PyPI
release predates...") into a minimum-version requirement, so it stays
correct once 0.2.0 ships rather than going stale.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
robert-dean added a commit to MaroonedSoftware/rhapsode that referenced this pull request Sep 19, 2026
Adds `nano`, Resemble's 110M-parameter Chatterbox Nano, as a fourth
build of the Chatterbox engine.

## What changes

Three commits, each leaving the tree working:

1. **Chatterbox runs on upstream's master, pinned.** Nano was merged
upstream on 2026-07-21 (resemble-ai/chatterbox#542) but is in no
release: PyPI's newest is 0.1.7 from March, and master still calls
itself 0.1.7. So `chatterbox-tts` now installs from commit `5de7a54` as
a zip archive, which needs no git in the server image. `turbo`,
`original` and `multilingual` were re-verified on MPS against it: all
load, speak and clone. Multilingual lost upstream's
`AlignmentStreamAnalyzer` in this range; English and French output still
came out at 15 to 19 characters per second of audio, so there are no
runaway endings.
2. **Chatterbox gains Nano.** Upstream loads it through
`ChatterboxTurboTTS.from_pretrained(nano=True)` and generates with
turbo's own method, so `nano` declares exactly what `turbo` does: the
eight cues, no dials, English only. It is sent the same zeroes so
upstream does not warn. Weights come from `ResembleAI/chatterbox-nano`.
`turbo` stays the default.
3. **What Nano costs, measured.** The table is in the adapter README.

| build | device | stock voice | cloned voice |
| --- | --- | --- | --- |
| `nano` | MPS | 5.0x realtime | 3.7x |
| `turbo` | MPS | 2.7x | 1.3x |
| `nano` | CPU | 1.5 to 2.3x | 0.9 to 1.4x |
| `turbo` | CPU | 0.8x | 0.9x |

Medians of five warm runs through the adapter on an Apple M5 Pro. CPU
rows are ranges because the machine was busy.

## Costs of the pin

- The adapter cannot go to PyPI while it depends on a URL. Back to a
version floor once upstream releases one with Nano in it.
- Behind a TLS-intercepting proxy, an install now also needs
`github.com,codeload.github.com` in `RHAPSODE_PIP_TRUSTED_HOSTS`.
`docs/operating.md` says so.
- Nano's fetch is 3.0 GB for 1.9 GB loaded, because upstream's loader
also pulls an `s3gen.safetensors` nano never reads. Narrowing our fetch
would only move that download to the first `/speak`.

## Testing

- `node scripts/python.mjs test`: all pass. New tests cover nano's
declaration matching turbo's, loading turbo's class with `nano=True`,
the zeroed arguments, and fetching from nano's own repository.
- `ruff` and `mypy` clean.
- Real weights, on MPS and the CPU, through the adapter: every build
loads, speaks and clones.
- Cues are performed, not only accepted: all eight lengthened the same
cloned line on three seeds out of three, by more than on turbo, and
`[chuckle]` and `[laugh]` were checked by ear against turbo's.

An engine already installed from the page keeps its old code and needs
Uninstall then Install to get `nano`.

## Also in this PR

- **The stock voice after a clone (bug fix, predates this PR).**
Upstream keeps one `conds` per model and a clone overwrites it, so every
request without a voice after the first clone spoke as that clone.
Measured with seed 7 on nano and original: the stock line reproduced
exactly until a clone ran, and never again after it. The adapter now
keeps the build's own conditionals and restores them.
- **Clone conditionals cached per voice.** Upstream re-analyses the
reference on every request it is handed a path. The adapter now calls
`prepare_conditionals` once per voice per resident build and keeps the
result (LRU of 32, about 1.3 MB each), keyed by the file's path, mtime
and size so a re-recording is a miss. On real weights: a seeded clone is
byte-identical between the miss and the hit, a dial still moves a cached
clone on `original`, and a warm clone cost what the stock voice did.
- **Conformance flake fixed.** The stub picked its audio from salted
`hash()`, which collided on about 1 hash seed in 600 per comparison. It
uses sha256 now.
Blaco pushed a commit to Blaco/whisperbox that referenced this pull request Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants