feat(audio): add audio round-trip example pipeline (TTS → Whisper → export)#22
Merged
Conversation
… export) Add a fourth example modality, `audio`, alongside images/video/pdf. It is a self-contained text -> speech -> text round-trip that runs fully offline in local mode with auto-downloading models (no pre-placed model files): ingest-audio -> synthesize-audio -> transcribe-audio -> export-audio - tts.py: our own transformers-native MMS-TTS UDF (facebook/mms-tts-eng, VitsModel) emitting list<float32> @ 16 kHz. Chosen over the shipped ONNX kokoro UDF (needs a local model_dir) and the kokoro pip package (needs the espeak-ng system binary) so the demo installs with pip alone. - transcribe.py: reuses Geneva's shipped WhisperChunkTranscriber via attrs.evolve, rebinding its input column from `samples` to `audio`. MMS-TTS's 16 kHz output matches whisper's TARGET_SAMPLE_RATE, so it feeds in with no download_audio and no resampling. Default openai/whisper-large-v3-turbo, overridable with --model-id. - export.py: writes each waveform to <out-dir>/<id>.wav (16-bit PCM, stdlib wave; default /tmp/geneva_audio). Registered in the three usual points (examples/__init__.py, cli.py, pyproject.toml scripts) so it appears in both the generated CLIs and the TUI. New run/model bodies are added to the coverage omit list per the existing frame_embed/clip precedent; their factories + the WAV helper are unit-tested, and ingest/export are smoke-tested (tests/test_audio.py). Registry/TUI/UDF tests updated for the new modality. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
sarwarbhuiyan
approved these changes
Jul 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a fourth example modality,
audio, alongsideimages/video/pdf. It's a self-contained text → speech → text round-trip that runs fully offline in local mode with auto-downloading models (no pre-placed model files, no system binaries):Seed text prompts → synthesize speech with MMS-TTS → transcribe back with Whisper → export the waveforms to
.wav.Implements the Audio pipeline tickets: GEN-806 (parent scaffolding + ingest), GEN-807 (TTS UDF), GEN-808 (Whisper transcription). The export stage was added on top per follow-up request.
What's included
examples/audio/ingest.pyaudiotable withid+textprompts. No external media — audio is produced downstream, so the whole pipeline runs offline.examples/audio/tts.pyfacebook/mms-tts-eng,VitsModel) →list<float32>@ 16 kHz. Factory + decorated-class shape mirrors_shared/clip.py.examples/audio/synthesize.pyaudiowaveform column fromtext(mirrorsvideo/frame_embed.py).examples/audio/transcribe.pyWhisperChunkTranscriberviaattrs.evolve(likepdf/document.py), rebinding inputsamples→audio.examples/audio/export.py<out-dir>/<id>.wav(16-bit PCM, stdlibwave; default/tmp/geneva_audio).Registered in the three usual points (
examples/__init__.py,examples/cli.py,pyproject.toml[project.scripts]), so it appears in both the generateduv run …CLIs and the TUI.Design notes
pip install. MMS-TTS is transformers-native and auto-downloads viafrom_pretrainedwith zero system deps for English — chosen over the shipped ONNXkokoro_base_tts_udf(needs a localmodel_dir) and thekokoropip package (needs theespeak-ngsystem binary). Whisper (transformers) auto-downloads/caches too.TARGET_SAMPLE_RATE, so the TTSaudiocolumn feeds the transcriber directly — nodownload_audio, no resampling. The rate is recorded in the column'sfield_metadata.openai/whisper-large-v3-turbo, overridable with--model-id. Note: in testing, model size barely moved round-trip accuracy — the limiter is MMS-TTS pronunciation of uncommon words, not Whisper capacity.whisper-tinyis much lighter (~75 MB vs ~1.6 GB) if a smaller default is preferred later.--mode local(CPU) and enterprise on Cantina (GPU), via the sharedresolve_resources/local_or/runtime_sessionhelpers.Testing
Verified end-to-end locally (
--mode local): all 4 stages ran, 5 rows synthesized → transcribed → exported to valid 16-bit mono 16 kHz WAV files. Example round-trip:ruff+tyclean.tests/test_audio.py: UDF factory bindings (input column / data type / metadata / manifest rebind), WAV export round-trip + clipping, ingest/export CLI smoke tests.test_registry.py,test_tui.py,test_udfs.pyfor the new modality.frame_embed/clipprecedent (they need Ray + model weights); their factories and the pure WAV helper are unit-tested.Try it
🤖 Generated with Claude Code