Add MOSS-VoiceGenerator community model (moss_voicegen) - #278
Conversation
…n instruction) Ports the moss_tts_delay architecture: a Qwen3-1.7B backbone with 16 audio codebook embeddings and 1 + 16 heads, decoded on a delay pattern, through MOSS-Audio-Tokenizer v1 to 24 kHz mono. Supporting the v1 codec needed five additions in models/moss/shared: the hop and channel count come from the config rather than constants, the stage output projection is optional, and the attention and feed-forward weights accept v1's naming. None of them change v2 or Nano behaviour.
# Conflicts: # CMakeLists.txt
…easurements prepare() is now idempotent. The server calls it on every request against one long-lived session, and building the runtimes there re-uploaded the whole 5.7 GB package each time: about four seconds on top of roughly one second of work. extract_audio_codes() keeps only frames where every codebook carries a real code. A generation cut short by the step ceiling leaves pad in the trailing rows, which the codec rejects as out of range. The soak tool now reports RTF, failure kinds and VRAM growth over a long-lived session, and the model doc carries the measured numbers: RTF 0.23 median over 100 requests, +28 MiB VRAM, 47 long-form chunks at RTF 0.22, plus the two limitations that run exposed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
@jrohde Thanks! I will test it tomorrow. |
|
@jrohde Merged! Quick tests on RTX 5090 CUDA RTF is 0.07 to 0.15. |
Brings speech.cpp up to date with latest audio.cpp upstream main (4d383be): - Community models: MOSS-VoiceGenerator (PR 0xShug0#278), MMS-300M-1130 forced aligner (PR 0xShug0#279), F5-TTS (PR 0xShug0#275). - SenseASR encoder refactored to framework SAN-M modules (PR 0xShug0#285). - Server: max_loaded_models limit with LRU eviction (PR 0xShug0#298) and opt-in session options listing. - WebUI: reverse proxy hash routing (PR 0xShug0#297), Music3 precision packages, HeartMuLa options. - CUDA & Memory: CUDA graph-cache eviction and idle pool trimming (PR 0xShug0#293), Supertonic vector arena reduction. - GGML: tracked CUDA clear_graph and trim_pools as patch 0007. - Build & CI: native model manager build flags, C++17 cleanups, CMake model-link guards preserved.
|
Thanks for merging, and for running it on the 5090 — that was the one gap we could not Would you like MOSS-TTSD next? It is the same architecture — One thing to weigh: TTSD is 8B where VoiceGenerator was 1.7B. It quantises well, though — Happy to pick it up if you want it. |
|
@jrohde That sounds great! Really appreciate you helping expand audio.cpp. If you find components that can be cleanly abstracted and promoted into the framework as shared components/runtimes for the MOSS family, feel free to do so to reduce duplicated code. Please avoid extending existing framework runtimes/modules for now, as both dev and my local branch have ongoing refactors. |
Adds MOSS-VoiceGenerator as a community model: voice design, where the speaker comes from a
written description instead of a reference recording. This resolves #195.
moss_tts_delay— a Qwen3-1.7B backbone with 16 audio codebook embeddings and1 + 16heads, decoded on a delay pattern, over MOSS-Audio-Tokenizer v1 (24 kHz mono, hop 1920).
Offline
vdes, English and Chinese.Parity
Measured against the checkpoint's own PyTorch implementation at four layers, with the
references regenerated by scripts in
tools/community_models/and gated by tests intests/moss_voicegen/.MossTTSDelayProcessorMossTTSDelayModel, bf16 / f32generate(), f32MossAudioTokenizerModelRow-for-row greedy parity holds at f32 only. At bf16 the first 16 rows match and then
diverge on a 0.003 logit gap between near-tied candidates: greedy decoding is a step
function and bf16 rounding is coarser than that gap. The test gates f32 exactly and bf16 on
a matching prefix, so the bf16 package does not look broken to anyone who runs it.
The backbone needs bf16 or f32 — as f16 it produces NaN from position zero, since it carries
attention-sink activations beyond f16 range. The codec wants the opposite: as bf16 it drifts
1.1e-2 from the reference decode, as f16 7.1e-4, at the same size. The shipped package
converts as
--type bf16 --keep-type "audio_tokenizer_weights*=f16", with--exclude-prefix "audio_tokenizer_weights/encoder"since voice design never encodes audio.5.7 GB.
Numbers
Radeon AI PRO R9700 (ROCm/HIP), 100 requests through one long-lived
audiocpp_serversession:
Also verified on Vulkan (R9700 and a 780M iGPU) and CPU. No CUDA hardware here, so those
numbers are missing.
The two failures are the model's own behaviour: nothing forces the first step to open an
audio segment, so about 2% of runs sample an ordinary text token instead and produce no
audio. The session returns an error naming the retry rather than silence.
One change outside the model directory
src/models/moss/shared/needed five additions. MOSS-Audio-Tokenizer v1 is a differentgeneration from the v2 and Nano codecs already in the tree — mono instead of interleaved
stereo, a different hop, and different tensor names — so the shared codec could not load it
as it stood:
samples_per_frametaken from the config rather than a constantchannelsconfig field; the stereo de-interleave is skipped when it is 1in_projs.0/out_projs.0ModuleListlinear1/linear2nn.SequentialEach one widens what the existing code accepts; none changes v2 or Nano behaviour. The
alternative was copying roughly 1500 lines of codec into the model directory to change five
names and two numbers. If you would rather keep
shared/pinned to v2, say so and I willmove it to a
moss_voicegen-local codec instead.Known limitations
age, manner hold reliably — but not the individual, and a seed reproduces a take rather
than a voice. Long-form therefore comes out as one speaker per chunk. Documented rather
than worked around: upstream
generate()takes no seed at all.get_rows. Not specific to this model: the samecard runs the same workload under Vulkan, and a hand-written HIP gather kernel runs on it.
I will open a separate issue with a reproducer.
MOSS-TTSD is the natural follow-up, same family and same delay decoder.
Built with Claude and @jrohde as the human motivator, tester
and approver: the hardware, the listening verdicts and the final say are his.