Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1469,6 +1469,24 @@ audiocpp_add_model(chatterbox
engine::models::chatterbox::make_chatterbox_loader
)

audiocpp_add_model(chatterbox_turbo
SOURCES
src/community_models/chatterbox_turbo/t3_turbo_weights.cpp
src/community_models/chatterbox_turbo/t3_turbo_component.cpp
src/community_models/chatterbox_turbo/s3gen_turbo.cpp
src/community_models/chatterbox_turbo/text_tokenizer_turbo.cpp
src/community_models/chatterbox_turbo/assets.cpp
src/community_models/chatterbox_turbo/loader.cpp
src/community_models/chatterbox_turbo/session.cpp
src/community_models/chatterbox_turbo/tts.cpp
INCLUDES
engine/community_models/chatterbox_turbo/loader.h
LOADERS
engine::community_models::chatterbox_turbo::make_chatterbox_turbo_loader
DEPENDS
chatterbox
)

audiocpp_add_model(ace_step
SOURCES
src/models/ace_step/assets.cpp
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ Community model ports live under `community_models` to make the ownership bounda
| Family | Task | Lang | Runtime | Contributor | What They Added |
|---|---|---|---|---|---|
| **audio8_asr** | ASR | en, zh, yue, ja, ko, fr, de | GGUF Q8, Safetensors | [@0xShug0](https://github.com/0xShug0) | [Audio8-ASR-0.1B](docs/community_models/audio8_asr.md) compact multilingual autoregressive ASR reusing the Qwen3-ASR encoder with an MLP-tower adapter and an 8-layer Qwen2-style decoder (CC-BY-NC, local conversion only) |
| **chatterbox_turbo** | TTS, Clone (testing) | en | GGUF 16/Q8 | [@pannagaps](https://github.com/pannagaps) | [Chatterbox Turbo](docs/community_models/chatterbox_turbo.md) distilled 350M GPT2 T3 backbone + 2-step meanflow S3Gen decoder; built-in voice only for now |
| **f5_tts** | TTS, Clone | en, ar (Habibi) | GGUF | [@tareko](https://github.com/tareko) | [F5-TTS](docs/community_models/f5_tts.md) flow-matching DiT synthesis and voice cloning, with Habibi Arabic aliases `habibi`/`habibi_tts` |
| **glm_tts** | TTS, Clone | zh, en | GGUF | Mirek [@mirek190](https://github.com/mirek190) | [GLM-TTS](docs/community_models/glm_tts.md) zero-shot synthesis and voice cloning support |
| **granite5asr** | ASR | en | GGUF Q8 | [@ampersandru](https://github.com/ampersandru) | [IBM Granite Speech 5.0 470M TurboCTC](docs/community_models/granite5asr.md) ultra-fast Conformer-CTC ASR with Shaw relative positional embeddings and ByteLevel BPE |
Expand Down
84 changes: 84 additions & 0 deletions docs/community_models/chatterbox_turbo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Chatterbox Turbo (community model)

[Chatterbox Turbo](https://huggingface.co/ResembleAI/chatterbox-turbo) is Resemble AI's
distilled 350M-parameter sibling of Chatterbox (see [the Chatterbox section in docs/tts.md](../tts.md#chatterbox)): a GPT2-style T3
backbone (vs. the base model's 0.5B Llama-style backbone), a GPT2 BPE tokenizer with 19 built-in
emotion/style tags (`[laugh]`, `[sigh]`, ...), and a 2-step meanflow-distilled S3Gen decoder (vs.
the base model's 10-step CFG decoder) for substantially faster generation. English-only.

**Status: testing.** The T3 backbone and the built-in default voice both load and generate
audio end to end. Custom voice cloning (a caller-supplied reference clip) is not implemented
yet — it depends on the checkpoint's speaker-encoder and S3-tokenizer sections, whose tensor
layout has not been validated. This family lives under `community_models` rather than the core
model tree because it does not yet have the CUDA/Vulkan/Metal runtime test coverage core models
carry.

## Packaging: audio.cpp-native, self-contained GGUF

Resemble AI has not published Chatterbox Turbo weights in a format audio.cpp can convert
directly. The only available conversion is a **third-party GGUF**,
[`cstr/chatterbox-turbo-GGUF`](https://huggingface.co/cstr/chatterbox-turbo-GGUF), published by
`cstr` for their own CrispASR project (MIT-relicensed) — not published by ResembleAI or
audio.cpp. It ships as two loose GGUF files (T3 and S3Gen) with a flat dot-separated tensor
namespace and abbreviated S3Gen tensor names that don't match this codebase's own naming.

Rather than teach the runtime a compatibility layer for that third-party layout,
[`tools/community_models/chatterbox_turbo/repack_chatterbox_turbo_gguf.py`](../../tools/community_models/chatterbox_turbo/repack_chatterbox_turbo_gguf.py)
repacks it offline into one self-contained, audio.cpp-native GGUF:

- T3 and built-in-conditional tensors are moved from the upstream flat `t3.`/`conds.` dot
namespace into this project's own `/`-delimited packed-GGUF namespace convention.
- S3Gen tensors are renamed back to the exact names base Chatterbox's own S3Gen flow/HiFT-vocoder
loader (`src/models/chatterbox/s3gen_flow.cpp`,
`src/framework/modules/vocoders/hift_vocoder.cpp`) already expects, so that loader runs
completely unmodified for Turbo — no tensor-name translation code exists in this family at
runtime.
- The GPT2 BPE tokenizer (vocab, merges, and the trailing emotion/style special tokens) is
extracted into plain `vocab.json`/`merges.txt`/`special_tokens.json` sidecar files instead of
being read from raw GGUF metadata at load time.
- The result is fed through this project's own `audiocpp_gguf` converter, which quantizes,
embeds the package spec (`model_specs/chatterbox_turbo.json`), and embeds the sidecar files —
producing one file that loads with nothing else needed, like every other GGUF family here.

The `ve.*` (LSTM speaker-verification voice encoder) and `s3.se.*`/`s3.tok.*` (ResNet speaker
encoder / S3 speech tokenizer) sections of the upstream checkpoint are not repacked: nothing in
this codebase reads them yet (see Current limitations above).

### Repacking it yourself

```bash
# 1. Build the converter
cmake --build build/debug --parallel --target audiocpp_gguf

# 2. Get the upstream third-party GGUF pair (~1 GB for Q8_0)
huggingface-cli download cstr/chatterbox-turbo-GGUF \
chatterbox-turbo-t3-q8_0.gguf chatterbox-turbo-s3gen-q8_0.gguf \
--local-dir /tmp/chatterbox-turbo-src

# 3. Repack
pip install gguf numpy safetensors
python3 tools/community_models/chatterbox_turbo/repack_chatterbox_turbo_gguf.py \
--t3-source /tmp/chatterbox-turbo-src/chatterbox-turbo-t3-q8_0.gguf \
--s3gen-source /tmp/chatterbox-turbo-src/chatterbox-turbo-s3gen-q8_0.gguf \
--output models/Chatterbox-Turbo-GGUF/chatterbox-turbo-q8_0.gguf \
--type q8_0 --overwrite
```

Verify with `build/debug/bin/audiocpp_gguf --inspect models/Chatterbox-Turbo-GGUF/chatterbox-turbo-q8_0.gguf` (expect `embedded_sidecars=true`, `embedded_model_spec=true`, and `t3`/`conds`/`s3gen` namespaces).

## Usage

```bash
audiocpp_cli --task clon --family chatterbox_turbo \
--model models/Chatterbox-Turbo-GGUF/chatterbox-turbo-q8_0.gguf \
--backend cuda --text "Hello from Chatterbox Turbo." --out out.wav
```

See the [Chatterbox Turbo section in docs/tts.md](../tts.md#chatterbox-turbo) for the full option
table.

## Checkpoints

| Model | Source | License |
|---|---|---|
| Chatterbox Turbo (T3 + S3Gen) | `cstr/chatterbox-turbo-GGUF` (third-party repack of `ResembleAI/chatterbox-turbo`) | MIT |
1 change: 1 addition & 0 deletions docs/community_models/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Practical expectations:
| Family | Task | Supported language(s) | Contributor | What They Added |
|---|---|---|---|---|
| **audio8_asr** | ASR | en, zh, yue, ja, ko, fr, de | [@0xShug0](https://github.com/0xShug0) | [Audio8-ASR-0.1B](audio8_asr.md) compact multilingual autoregressive ASR reusing the Qwen3-ASR encoder with an MLP-tower adapter and an 8-layer Qwen2-style decoder (CC-BY-NC, local conversion only) |
| **chatterbox_turbo** | TTS, voice cloning (testing) | en | [@pannagaps](https://github.com/pannagaps) | [Chatterbox Turbo](chatterbox_turbo.md) Resemble AI's distilled 350M GPT2 T3 backbone + 2-step meanflow S3Gen decoder for fast English TTS; built-in default voice only for now |
| **echo_tts** | TTS, voice cloning | en | Tym [@5uck1ess](https://github.com/5uck1ess), [@dignome](https://github.com/dignome) | [Echo-TTS](echo_tts.md) 44.1 kHz zero-shot voice cloning: 2.8B diffusion transformer in 80-D PCA space, decoded by the Fish S1-DAC autoencoder. Byte-level text, no phonemiser, no reference transcript |
| **f5_tts** | TTS, voice cloning | en, ar (Habibi) | Community | [F5-TTS](f5_tts.md) flow-matching DiT — M0 scaffolding, aliases `habibi`/`habibi_tts` |
| **glm_tts** | TTS, voice cloning | zh, en | Mirek [@mirek190](https://github.com/mirek190) | [GLM-TTS](glm_tts.md) zero-shot synthesis and voice cloning support |
Expand Down
47 changes: 47 additions & 0 deletions docs/tts.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,53 @@ audiocpp_cli --task vc --family chatterbox --model models/chatterbox --backend c
| `--max-tokens` | integer | `1000` | Maximum generated T3 tokens per chunk. |
| `--do-sample` | `true`, `false` | `true` | Enable stochastic T3 sampling. |

## Chatterbox Turbo

Chatterbox Turbo is a [community model](community_models/chatterbox_turbo.md): Resemble AI's
distilled 350M-parameter sibling of Chatterbox, with a GPT2-style T3 backbone (vs. the base
model's 0.5B Llama-style backbone), a GPT2 BPE tokenizer with 19 built-in emotion/style tags
(`[laugh]`, `[sigh]`, ...), and a 2-step meanflow-distilled S3Gen decoder (vs. the base model's
10-step CFG decoder) for substantially faster generation. It is English-only.

`chatterbox_turbo` is a separate model family from `chatterbox` (not a variant selectable within
it): its T3 backbone and tokenizer differ from the base model's, and it reuses base Chatterbox's
own S3Gen/HiFT-vocoder loader code for the flow decoder and vocoder half.

The package is one self-contained, audio.cpp-native GGUF produced by repacking Resemble AI's
weights (via the third-party `cstr/chatterbox-turbo-GGUF` conversion published for the CrispASR
project, MIT-relicensed) with
[`tools/community_models/chatterbox_turbo/repack_chatterbox_turbo_gguf.py`](../tools/community_models/chatterbox_turbo/repack_chatterbox_turbo_gguf.py)
— see that model's community doc for details.

**Current limitations:** only the built-in default voice baked into the package is supported —
custom voice cloning (a caller-supplied reference clip) is not implemented yet, since it depends
on the checkpoint's speaker-encoder and S3-tokenizer sections, whose exact tensor layout hasn't
been validated. `--voice-ref` is rejected with an explicit error rather than silently ignored.

| Field | Value |
|---|---|
| Family | `chatterbox_turbo` |
| Model directory | `Chatterbox-Turbo-GGUF/chatterbox-turbo-{q8_0,f16}.gguf` (single self-contained file) |
| Tasks | `clon` (built-in voice only) |
| Modes | `offline` |
| Languages | `en` |
| Voice input | Not yet supported — omit `--voice-ref` to use the built-in voice |
| Built-in voices | One, embedded in the package |

```bash
audiocpp_cli --task clon --family chatterbox_turbo --model models/Chatterbox-Turbo-GGUF/chatterbox-turbo-q8_0.gguf --backend cuda --text "Hello from Chatterbox Turbo." --out out.wav
```

| Option | Values | Default | Meaning |
|---|---|---:|---|
| `--temperature` | float | `0.8` | T3 sampling temperature. |
| `--top-p` | float | `0.95` | T3 nucleus sampling limit. |
| `top_k` (session option) | integer | `1000` | T3 top-k sampling limit. |
| `--repetition-penalty` | float | `1.2` | T3 repetition penalty. |
| `--max-tokens` | integer | `1000` | Maximum generated T3 tokens. |

`--guidance-scale`/exaggeration/min_p have no effect on Turbo (it was distilled without CFG) and are accepted but ignored, matching upstream's own behavior.

## Confucius4-TTS

Confucius4-TTS is an experimental multilingual voice-cloning TTS model packaged as a standalone GGUF bundle. It supports offline generation and streaming text input, using reference speech, language-aware text normalization, T2S semantic generation, S2A flow matching, style encoding, semantic audio features, and BigVGAN vocoding.
Expand Down
20 changes: 20 additions & 0 deletions include/engine/community_models/chatterbox_turbo/assets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

#include "engine/framework/assets/resource_bundle.h"
#include "engine/framework/assets/tensor_source.h"

#include <filesystem>
#include <memory>

namespace engine::community_models::chatterbox_turbo {

struct ChatterboxTurboAssets {
engine::assets::ResourceBundle resources;
std::shared_ptr<const engine::assets::TensorSource> t3_turbo_weights;
std::shared_ptr<const engine::assets::TensorSource> builtin_conditionals_turbo;
std::shared_ptr<const engine::assets::TensorSource> s3gen_weights;
};

std::shared_ptr<const ChatterboxTurboAssets> load_chatterbox_turbo_assets(const std::filesystem::path & model_path);

} // namespace engine::community_models::chatterbox_turbo
33 changes: 33 additions & 0 deletions include/engine/community_models/chatterbox_turbo/loader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

#include "engine/framework/runtime/model.h"
#include "engine/community_models/chatterbox_turbo/assets.h"

#include <filesystem>
#include <memory>

namespace engine::community_models::chatterbox_turbo {

class ChatterboxTurboLoadedModel final : public runtime::ILoadedVoiceModel {
public:
ChatterboxTurboLoadedModel(
runtime::ModelMetadata metadata,
runtime::CapabilitySet capabilities,
std::shared_ptr<const ChatterboxTurboAssets> assets);

const runtime::ModelMetadata & metadata() const noexcept override;
const runtime::CapabilitySet & capabilities() const noexcept override;
std::unique_ptr<runtime::IVoiceTaskSession> create_task_session(
const runtime::TaskSpec & task,
const runtime::SessionOptions & options) const override;

private:
runtime::ModelMetadata metadata_;
runtime::CapabilitySet capabilities_;
std::shared_ptr<const ChatterboxTurboAssets> assets_;
};

std::unique_ptr<ChatterboxTurboLoadedModel> load_chatterbox_turbo_model(const std::filesystem::path & model_root);
std::shared_ptr<runtime::IVoiceModelLoader> make_chatterbox_turbo_loader();

} // namespace engine::community_models::chatterbox_turbo
49 changes: 49 additions & 0 deletions include/engine/community_models/chatterbox_turbo/s3gen_turbo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#pragma once

#include "engine/framework/assets/tensor_source.h"
#include "engine/framework/core/execution_context.h"
#include "engine/framework/modules/vocoders/hift_vocoder.h"
#include "engine/models/chatterbox/components.h"
#include "engine/models/chatterbox/s3gen_flow.h"
#include "engine/models/chatterbox/s3gen_inference.h"

#include <cstdint>
#include <memory>
#include <vector>

namespace engine::community_models::chatterbox_turbo {

// Loads and runs Chatterbox Turbo's S3Gen half (speech tokens -> waveform) by delegating to the
// existing chatterbox family's flow encoder/decoder and HiFT vocoder code (architecturally
// identical apart from the meanflow decoder branch already added to
// engine::models::chatterbox::S3FlowDecoderWeights). The native, repacked GGUF (see
// tools/community_models/chatterbox_turbo/repack_chatterbox_turbo_gguf.py) stores S3Gen tensors
// under the same names those loaders already expect, so no name translation is needed here.
//
// MVP scope: only the built-in default voice baked into the T3 GGUF's `conds.gen.*` tensors is
// supported (no custom voice cloning yet) -- that path needs the turbo checkpoint's `s3.se`
// (ResNet-style speaker encoder, not CAMPPlus) and `s3.tok` (S3 speech tokenizer) sections, which
// are unverified and out of scope for this pass. See ChatterboxTurboAssets.
class ChatterboxTurboS3Gen {
public:
static std::shared_ptr<ChatterboxTurboS3Gen> load(
std::shared_ptr<const engine::assets::TensorSource> s3gen_source,
const engine::core::ExecutionContext & execution_context,
engine::assets::TensorStorageType weight_storage_type = engine::assets::TensorStorageType::Native);

// speech_tokens: T3 output (S3 codebook ids, < 6561; caller strips control tokens).
engine::models::chatterbox::S3GenInferenceOutputs synthesize(
const engine::models::chatterbox::EmbedReferenceOutputs & ref_dict,
const std::vector<int32_t> & speech_tokens,
uint64_t flow_seed,
uint64_t vocoder_seed) const;

private:
std::shared_ptr<const engine::models::chatterbox::S3FlowEncoderWeights> encoder_weights_;
std::shared_ptr<const engine::models::chatterbox::S3FlowDecoderWeights> decoder_weights_;
std::shared_ptr<engine::modules::HiftVocoderComponent> vocoder_;
mutable engine::models::chatterbox::S3GenSessionCache cache_;
const engine::core::ExecutionContext * execution_context_ = nullptr;
};

} // namespace engine::community_models::chatterbox_turbo
34 changes: 34 additions & 0 deletions include/engine/community_models/chatterbox_turbo/session.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#include "engine/framework/runtime/session_base.h"
#include "engine/community_models/chatterbox_turbo/assets.h"
#include "engine/community_models/chatterbox_turbo/tts.h"

#include <memory>
#include <string>

namespace engine::community_models::chatterbox_turbo {

class ChatterboxTurboSession final
: public runtime::RuntimeSessionBase
, public runtime::IOfflineVoiceTaskSession {
public:
ChatterboxTurboSession(
runtime::TaskSpec task,
runtime::SessionOptions options,
std::shared_ptr<const ChatterboxTurboAssets> assets);
~ChatterboxTurboSession() override;

std::string family() const override;
runtime::VoiceTaskKind task_kind() const override;
runtime::RunMode run_mode() const override;
void prepare(const runtime::SessionPreparationRequest & request) override;
runtime::TaskResult run(const runtime::TaskRequest & request) override;

private:
runtime::TaskSpec task_;
std::shared_ptr<const ChatterboxTurboAssets> assets_;
std::unique_ptr<ChatterboxTurboTtsComponent> component_;
};

} // namespace engine::community_models::chatterbox_turbo
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#pragma once

#include "engine/framework/assets/tensor_source.h"
#include "engine/framework/core/backend.h"
#include "engine/framework/core/execution_context.h"
#include "engine/community_models/chatterbox_turbo/t3_turbo_types.h"

#include <memory>

namespace engine::community_models::chatterbox_turbo {

std::shared_ptr<const T3TurboInferenceWeights> load_t3_turbo_inference_weights(
const engine::assets::TensorSource & source,
const engine::core::ExecutionContext & execution_context,
engine::assets::TensorStorageType graph_weight_storage_type = engine::assets::TensorStorageType::Native,
bool load_reference_f32_graph_weights = true);

class T3TurboInferenceComponent {
public:
explicit T3TurboInferenceComponent(
std::shared_ptr<const T3TurboInferenceWeights> weights,
const engine::core::ExecutionContext & execution_context);

T3TurboGenerateOutputs generate_speech_tokens(const T3TurboGenerateRequest & request) const;
void release_runtime_graphs() const;
void release_runtime_cache() const;

private:
struct State;

std::shared_ptr<const T3TurboInferenceWeights> weights_;
const engine::core::ExecutionContext * execution_context_ = nullptr;
std::shared_ptr<State> state_;
};

} // namespace engine::community_models::chatterbox_turbo
Loading
Loading