Files
rustytorch/crates/models/rtx-csm/Cargo.toml
T
osobhandClaude Opus 4.7 c3eddc8873 rtx-csm: tts_server /v1/tts_stream — chunked PCM streaming endpoint
Streams 16-bit little-endian PCM (24 kHz mono) as Mimi produces chunks.
Wraps Generator::generate_streaming via spawn_blocking + tokio::sync::mpsc
bridge into an axum Body::from_stream response.

Same JSON request format as /v1/tts; Content-Type is
audio/L16; rate=24000; channels=1 per RFC 2586.

First-byte (first audio chunk) latency on Metal: ~880 ms vs ~6 s wall
for the non-streaming /v1/tts path — 6.8x faster perceived UX, the
difference between "the app froze" and "the app started speaking."

Caveat: streaming endpoint does NOT apply post-processing or the inline
watermarker (those operate on the full utterance). For watermarked
output use /v1/tts. A chunked AudioSeal port is the natural follow-up
for streaming watermarking.

Adds futures-util as a dev-dependency for the Stream trait.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-04-26 03:42:50 -07:00

171 lines
4.5 KiB
TOML

[package]
name = "rtx-csm"
version.workspace = true
edition.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
description = "Rust-native port of Sesame CSM-1B (Conversational Speech Model) on candle + moshi"
# NOTE: candle-transformers 0.8 (workspace pin) does NOT contain the `csm`
# model module — it was added in 0.9.0. We deliberately pull candle 0.9 + moshi
# 0.6 directly here, NOT via workspace deps. Cargo will compile candle 0.8 (for
# the rest of rustytorch) and candle 0.9 (for rtx-csm) side-by-side. No Tensor
# types are shared across that boundary today.
[dependencies]
# Candle 0.9 — required for the csm model module
candle-core = { version = "0.9.1", default-features = false }
candle-nn = { version = "0.9.1", default-features = false }
candle-transformers = { version = "0.9.1", default-features = false }
# Mimi neural audio codec: we use the HF-compatible `candle-transformers::models::mimi`
# (not the `moshi` crate, which expects different weight-key naming).
# Tokenizer (Llama-3.2 BPE)
tokenizers = { version = "0.20", default-features = false, features = ["onig"] }
# HF Hub asset resolution (synchronous via ureq + rustls)
hf-hub = { version = "0.5", default-features = false, features = ["ureq", "rustls-tls"] }
# Audio I/O
hound = "3.5"
symphonia = { version = "0.5", features = ["all"] }
rubato = "0.15"
# Loudness normalization (EBU R128 / ITU-R BS.1770-4)
ebur128 = "0.1"
# In-process ASR via whisper.cpp bindings. Optional via the `asr` feature
# because it pulls a C++ build (cmake + clang). Provides Metal acceleration.
whisper-rs = { version = "0.16", default-features = false, optional = true }
# Text normalization
unicode-normalization = "0.1"
regex = "1"
# Weight loading
safetensors = "0.4"
# Errors / logging / serde
anyhow.workspace = true
thiserror.workspace = true
tracing.workspace = true
serde.workspace = true
serde_json.workspace = true
# Numerics
half = "2.3"
rand = "0.8"
bytemuck = { version = "1.14", features = ["derive"] }
[dev-dependencies]
clap = { version = "4.5", features = ["derive"] }
tempfile = "3.0"
approx = "0.5"
tracing-subscriber = "0.3"
# For the TTS HTTP server example.
axum = { version = "0.7", features = ["multipart"] }
tokio = { version = "1", features = ["macros", "rt-multi-thread", "signal", "sync"] }
tower = "0.5"
tower-http = { version = "0.6", features = ["trace"] }
# HTTP client for the tts_server_bench example.
reqwest = { version = "0.12", default-features = false, features = ["json", "multipart", "rustls-tls"] }
# Streaming Stream trait for tts_server's /v1/tts_stream endpoint.
futures-util = "0.3"
[features]
default = ["cpu"]
cpu = []
cuda = ["candle-core/cuda", "candle-nn/cuda", "candle-transformers/cuda"]
metal = ["candle-core/metal", "candle-nn/metal", "candle-transformers/metal"]
accelerate = ["candle-core/accelerate", "candle-nn/accelerate"]
mkl = ["candle-core/mkl", "candle-nn/mkl"]
# In-process Whisper ASR via whisper.cpp bindings. Brings in C++ build deps.
asr = ["dep:whisper-rs"]
asr-metal = ["asr", "whisper-rs/metal"]
asr-cuda = ["asr", "whisper-rs/cuda"]
[[example]]
name = "generate"
path = "examples/generate.rs"
[[example]]
name = "bench"
path = "examples/bench.rs"
[[example]]
name = "quantize"
path = "examples/quantize.rs"
[[example]]
name = "inspect_gguf"
path = "examples/inspect_gguf.rs"
[[example]]
name = "qmatmul_repro"
path = "examples/qmatmul_repro.rs"
[[example]]
name = "qmm_layer_diff"
path = "examples/qmm_layer_diff.rs"
[[example]]
name = "lora_train_step"
path = "examples/lora_train_step.rs"
[[example]]
name = "forward_loss_demo"
path = "examples/forward_loss_demo.rs"
[[example]]
name = "lora_finetune_step"
path = "examples/lora_finetune_step.rs"
[[example]]
name = "tts_server"
path = "examples/tts_server.rs"
[[example]]
name = "lora_train"
path = "examples/lora_train.rs"
[[example]]
name = "audioseal_inspect"
path = "examples/audioseal_inspect.rs"
[[example]]
name = "audioseal_convert"
path = "examples/audioseal_convert.rs"
[[example]]
name = "audioseal_demo"
path = "examples/audioseal_demo.rs"
[[example]]
name = "audioseal_apply"
path = "examples/audioseal_apply.rs"
[[example]]
name = "wavlm_sv_convert"
path = "examples/wavlm_sv_convert.rs"
[[example]]
name = "wavlm_sv_demo"
path = "examples/wavlm_sv_demo.rs"
[[example]]
name = "wavlm_sv_inspect"
path = "examples/wavlm_sv_inspect.rs"
[[example]]
name = "pipeline"
path = "examples/pipeline.rs"
[[example]]
name = "generate_long"
path = "examples/generate_long.rs"
[[example]]
name = "tts_server_bench"
path = "examples/tts_server_bench.rs"