c98a12baf4
asset-engine shipped the per-field enable-toggle (v0.1.14/.15) — the durable fix for the "form submits untouched fields" family. A field marked togglable:true renders with an OFF-by-default switch: while off the control is disabled (excluded from submission) AND the server skips injecting its default, so it is genuinely not sent until the user opts in. Per operator direction, opt fish-s2's `references` (inline-base64 Custom-clone) field in — it already satisfies the togglable-requires- optional validator (optional:true, no default). The advanced clone field now renders dormant and can never silently override the Voice dropdown again. This is a SCHEMA change (new CatalogField property), so: - services.schema.json: add `togglable` (boolean, default false), mirroring the asset_engine Pydantic model that generates this schema. - catalog_version 1 -> 2 (header: bump on schema changes). - CATALOG-CONTRACT.md: consumer pin note -> catalog_version=2. Scoped to `references` only. The chatterbox/dia2 clone fields are the same family but NOT toggled: dia2 deliberately defaults voice_mode=clone + a clone ref as its stable out-of-box voice, and toggling that field would change dia2's default-voice behavior (the earlier 404 fix). Validated: jsonschema accepts togglable; additionalProperties:false guard still rejects unknown props.
2070 lines
72 KiB
YAML
2070 lines
72 KiB
YAML
# services.yaml — canonical catalog of inference services on irv-ml1
|
||
#
|
||
# THIS IS A FIRST-CLASS CONTRACT. External consumers depend on the
|
||
# shape and contents of this file. See CATALOG-CONTRACT.md alongside
|
||
# for: schema reference, change-management policy, sync workflow for
|
||
# downstream consumers, and known consumers list.
|
||
#
|
||
# Drives form generators that auto-render UIs against the inference
|
||
# services. Each entry produces one form (from `fields:`) and one
|
||
# response renderer (dispatched on `response.type`). The field-type
|
||
# vocabulary and response-type vocabulary are closed sets — see the
|
||
# JSON Schema at services.schema.json or the contract doc.
|
||
#
|
||
# `catalog_version`: bump when the SCHEMA changes (a field type added,
|
||
# a required field removed, etc). Per-service `version:` bumps when a
|
||
# specific service's parameter shape changes. Both let downstream
|
||
# consumers detect drift.
|
||
|
||
catalog_version: 2
|
||
|
||
services:
|
||
- id: kokoro
|
||
name: Kokoro 82M TTS
|
||
description: >
|
||
Lowest-latency English TTS (82M params, fp16). ~300ms TTFA, 35–100x realtime,
|
||
60+ built-in voices in 8 languages. Voice mixing via inline weights.
|
||
OpenAI-compatible /v1/audio/speech.
|
||
category: tts
|
||
version: 3
|
||
host: irv-ml1
|
||
lifecycle:
|
||
stack: kokoro
|
||
vram_gb: 2
|
||
gpu_device_id: null
|
||
endpoint: http://10.100.79.3:8193/v1/audio/speech
|
||
method: POST
|
||
content_type: application/json
|
||
model:
|
||
id: hexgrad/Kokoro-82M
|
||
revision: null
|
||
image: ghcr.io/remsky/kokoro-fastapi-gpu:v0.2.4-master
|
||
fields:
|
||
- name: input
|
||
type: textarea
|
||
label: Text
|
||
required: true
|
||
max_length: 5000
|
||
- name: voice
|
||
type: select
|
||
label: Voice
|
||
source_url: http://10.100.79.3:8193/v1/audio/voices
|
||
source_jsonpath: $.voices[*]
|
||
default: af_heart
|
||
description: >
|
||
60+ built-in voices. Default `af_heart` is the only A-rated voice per
|
||
upstream VOICES.md (also the kokoro-fastapi container's own default).
|
||
Custom blends: af_bella(2)+af_aoede(1) syntax for weighted mixing.
|
||
Persistent custom voices via playbooks/blend-kokoro-voice.yaml.
|
||
- name: response_format
|
||
type: select
|
||
options: [wav, mp3, opus, flac, pcm]
|
||
default: wav
|
||
- name: speed
|
||
type: slider
|
||
label: Speed
|
||
required: false
|
||
min: 0.25
|
||
max: 4.0
|
||
step: 0.05
|
||
default: 1.0
|
||
description: Playback speed multiplier. 1.0 is natural.
|
||
- name: volume_multiplier
|
||
type: slider
|
||
label: Volume
|
||
required: false
|
||
min: 0.5
|
||
max: 2.0
|
||
step: 0.05
|
||
default: 1.0
|
||
description: >
|
||
Output gain. Useful for level-matching against music beds.
|
||
Upstream is unbounded; UI bounds (0.5–2.0) are a sensible default —
|
||
override the slider client-side if you need extremes.
|
||
- name: lang_code
|
||
type: text
|
||
label: Language code
|
||
required: false
|
||
description: >
|
||
Optional language hint (e.g. "a" for American English). When unset,
|
||
kokoro infers from the first letter of the voice name. Set when text
|
||
contains code-switching kokoro guesses wrong on.
|
||
- name: stream
|
||
type: bool
|
||
default: false
|
||
description: Phrase-by-phrase streaming via chunked HTTP.
|
||
response:
|
||
type: audio
|
||
mime_from_field: response_format
|
||
reproducibility:
|
||
seedable: false
|
||
deterministic: true
|
||
notes: >
|
||
No seed parameter. Model fully deterministic (no sampling); identical
|
||
params always produce identical bytes. Image tag is mutable; pin to
|
||
digest for v3 reproducibility audit.
|
||
estimated_latency:
|
||
cold_start_s: 2
|
||
warm_per_unit: "~300ms TTFA, 35–100x realtime"
|
||
license: Apache-2.0
|
||
notes: |
|
||
Voice mixing: voice="name1(w1)+name2(w2)+..." normalizes weights.
|
||
Custom voices persist at /worktank/kokoro/user_voices (bind-mounted).
|
||
v2 (2026-05-11): added speed, volume_multiplier, lang_code per
|
||
kokoro's OpenAPI surface.
|
||
|
||
- id: kokoro-captioned
|
||
name: Kokoro Captioned Speech
|
||
description: >
|
||
Kokoro TTS with word-level timestamps returned alongside the audio.
|
||
For subtitle generation and video sync. Same model as `kokoro`;
|
||
separate catalog entry because the wire shape is a JSON envelope
|
||
carrying base64-encoded audio plus a structured timestamps array.
|
||
category: tts
|
||
version: 2
|
||
status: ready
|
||
host: irv-ml1
|
||
endpoint: http://10.100.79.3:8193/dev/captioned_speech
|
||
method: POST
|
||
content_type: application/json
|
||
model:
|
||
id: hexgrad/Kokoro-82M
|
||
revision: null
|
||
image: ghcr.io/remsky/kokoro-fastapi-gpu:v0.2.4-master
|
||
fields:
|
||
- name: input
|
||
type: textarea
|
||
label: Text
|
||
required: true
|
||
max_length: 5000
|
||
- name: voice
|
||
type: select
|
||
label: Voice
|
||
source_url: http://10.100.79.3:8193/v1/audio/voices
|
||
source_jsonpath: $.voices[*]
|
||
default: af_heart
|
||
- name: response_format
|
||
type: select
|
||
options: [wav, mp3, opus, flac, pcm]
|
||
default: wav
|
||
- name: speed
|
||
type: slider
|
||
label: Speed
|
||
required: false
|
||
min: 0.25
|
||
max: 4.0
|
||
step: 0.05
|
||
default: 1.0
|
||
- name: lang_code
|
||
type: text
|
||
label: Language code
|
||
required: false
|
||
response:
|
||
# Stays in the closed type vocabulary: from a renderer-dispatch
|
||
# standpoint this IS audio. The audio_field/audio_format_field/
|
||
# timestamps_field decomposition tells consumers how to extract
|
||
# those parts from the JSON envelope wire shape — added to the
|
||
# catalog schema in 2026-05 specifically to support response
|
||
# shapes like this one without extending the type vocab.
|
||
type: audio
|
||
audio_field: audio
|
||
audio_format_field: audio_format
|
||
timestamps_field: timestamps
|
||
reproducibility:
|
||
seedable: false
|
||
deterministic: true
|
||
notes: >
|
||
Same determinism story as kokoro proper. Verified wire shape
|
||
(2026-05-11 against live API):
|
||
{
|
||
"audio": "<base64-encoded bytes in response_format>",
|
||
"audio_format": "audio/wav" (or matching response_format),
|
||
"timestamps": [{"word": str, "start_time": float, "end_time": float}, ...]
|
||
}
|
||
Consumer base64-decodes `audio` to play; `timestamps` drives
|
||
subtitle/karaoke UI. The response decomposition fields above
|
||
encode this so the renderer doesn't need per-service-id branches.
|
||
estimated_latency:
|
||
cold_start_s: 2
|
||
warm_per_unit: "~same as kokoro proper, plus minor overhead for timestamp emission"
|
||
license: Apache-2.0
|
||
notes: |
|
||
`return_timestamps` and `stream` upstream params deliberately
|
||
omitted from the catalog: timestamps must be on for this endpoint
|
||
to be meaningful, and streaming + JSON-with-base64 don't compose.
|
||
`download_format` / `return_download_link` skipped — same as kokoro
|
||
proper.
|
||
|
||
status: experimental until the consumer's audio-with-timestamps
|
||
renderer ships. Once present, flip to status: ready.
|
||
|
||
- id: chatterbox
|
||
name: Chatterbox TTS
|
||
description: >
|
||
Resemble AI's low-latency English TTS (Chatterbox-Turbo, 350M, ~75ms TTFB,
|
||
6× realtime). 28 built-in predefined voices + zero-shot cloning from a
|
||
5–30s reference. Inline paralinguistic tags, plus Resemble's signature
|
||
exaggeration / cfg_weight emotion + pacing control.
|
||
category: tts
|
||
version: 2
|
||
status: ready
|
||
host: irv-ml1
|
||
lifecycle:
|
||
stack: chatterbox
|
||
vram_gb: 4
|
||
gpu_device_id: 0
|
||
endpoint: http://10.100.79.3:8196/tts
|
||
method: POST
|
||
content_type: application/json
|
||
model:
|
||
id: ResembleAI/chatterbox-turbo
|
||
revision: null
|
||
image: devnen/Chatterbox-TTS-Server:latest
|
||
section_groups:
|
||
- id: basic
|
||
label: Text & voice
|
||
- id: sampling
|
||
label: Expression & sampling
|
||
hint: Resemble's neutral defaults (exaggeration 0.5 / cfg_weight 0.5). Raise exaggeration or lower cfg_weight for drama.
|
||
- id: advanced
|
||
label: Advanced
|
||
fields:
|
||
- name: text
|
||
type: textarea
|
||
label: Text (with optional [tags])
|
||
section: basic
|
||
required: true
|
||
max_length: 5000
|
||
description: >
|
||
Inline paralinguistic tags honored by Turbo: [laugh] [chuckle] [sigh]
|
||
[gasp] [cough] [clear throat] [sniff] [groan] [shush]. Best results
|
||
when a physical tag is paired with surrounding emotional context.
|
||
- name: voice_mode
|
||
type: select
|
||
label: Voice mode
|
||
section: basic
|
||
options: [predefined, clone]
|
||
default: predefined
|
||
description: >
|
||
`predefined` -> a built-in voice (predefined_voice_id below).
|
||
`clone` -> a reference clip (reference_audio_filename). predefined is
|
||
the out-of-box default; the empty/"undefined" case is avoided by
|
||
defaulting the voice below.
|
||
- name: predefined_voice_id
|
||
type: select
|
||
label: Voice (built-in)
|
||
section: basic
|
||
optional: true
|
||
default: "Emily.wav"
|
||
source_url: http://10.100.79.3:8196/get_predefined_voices
|
||
source_jsonpath: $[*].filename
|
||
description: >
|
||
Required when voice_mode=predefined. 28 built-in voices staged in the
|
||
devnen image (Abigail, Adrian, Alexander, Alice, Austin, Axel, Connor,
|
||
Cora, Elena, Eli, Emily, Everett, Gabriel, Gianna, Henry, Ian, Jade,
|
||
Jeremiah, Jordan, Julian, Layla, Leonardo, Michael, Miles, Olivia,
|
||
Ryan, Taylor, Thomas — each <name>.wav). Default Emily.wav is the
|
||
server's own default_voice_id. Verified live via /get_predefined_voices.
|
||
- name: reference_audio_filename
|
||
type: select
|
||
label: Voice (clone reference)
|
||
section: basic
|
||
optional: true
|
||
source_url: http://10.100.79.3:8196/get_reference_files
|
||
source_jsonpath: $[*]
|
||
description: >
|
||
Required when voice_mode=clone. 5–30s clean WAV (16 kHz+ mono) under
|
||
/worktank/chatterbox/reference_audio/; upload via the server's
|
||
/upload_reference. Match the clip's language to `language` to avoid
|
||
accent transfer (or set cfg_weight=0).
|
||
- name: exaggeration
|
||
type: slider
|
||
section: sampling
|
||
min: 0.25
|
||
max: 2.0
|
||
step: 0.05
|
||
default: 0.5
|
||
description: >
|
||
Emotional intensity. Resemble's docs: 0.5 "works well for most prompts
|
||
across all languages"; ~0.7+ for dramatic delivery (which also speeds
|
||
speech up). NOTE: the devnen server *ships* 1.3 (tuned for its
|
||
theatrical demo presets) — 0.5 is the general-use value and the catalog
|
||
default; the shipped 1.3 is the likely cause of over-acted/unstable output.
|
||
- name: cfg_weight
|
||
type: slider
|
||
section: sampling
|
||
min: 0.0
|
||
max: 1.0
|
||
step: 0.05
|
||
default: 0.5
|
||
description: >
|
||
Pacing / prompt adherence (Resemble default 0.5). Lower to ~0.3 to
|
||
slow delivery, for fast/intense reference speakers, or alongside a
|
||
raised exaggeration for drama; 0 effectively disables guidance (useful
|
||
to reduce reference-accent transfer).
|
||
- name: temperature
|
||
type: slider
|
||
section: sampling
|
||
min: 0.05
|
||
max: 2.0
|
||
step: 0.05
|
||
default: 0.8
|
||
description: Sampling temperature; lower = steadier. Server + Resemble default 0.8.
|
||
- name: speed_factor
|
||
type: slider
|
||
section: sampling
|
||
min: 0.5
|
||
max: 2.0
|
||
step: 0.05
|
||
default: 1.0
|
||
description: Post-hoc playback speed. Server default 1.0.
|
||
- name: seed
|
||
type: number
|
||
section: sampling
|
||
required: false
|
||
default: 0
|
||
description: 0 = random; a fixed integer repeats the same take.
|
||
- name: output_format
|
||
type: select
|
||
section: basic
|
||
options: [wav, opus, mp3]
|
||
default: wav
|
||
description: 24 kHz. Live-verified enum (wav/opus/mp3).
|
||
- name: language
|
||
type: text
|
||
section: advanced
|
||
required: false
|
||
default: en
|
||
description: >
|
||
Language override. Base Turbo is English; the multilingual variant
|
||
(23 languages, via the stack .env) honors other codes. Leave `en`.
|
||
- name: split_text
|
||
type: bool
|
||
section: advanced
|
||
default: true
|
||
description: Auto-split long text into chunks.
|
||
- name: chunk_size
|
||
type: slider
|
||
section: advanced
|
||
min: 100
|
||
max: 1000
|
||
step: 10
|
||
default: 120
|
||
description: Target chunk length in chars when splitting (server default 120).
|
||
response:
|
||
type: audio
|
||
mime_from_field: output_format
|
||
reproducibility:
|
||
seedable: true
|
||
deterministic: false
|
||
seed_field: seed
|
||
notes: >
|
||
/tts exposes `seed` (0=random); a fixed seed + identical params repeats a
|
||
take. Temperature-sampled → not guaranteed byte-exact, and Resemble's
|
||
PerTh watermark is applied unconditionally. (Prior catalog claimed no
|
||
seed support — corrected against the live OpenAPI 2026-06-01.)
|
||
estimated_latency:
|
||
cold_start_s: 3
|
||
warm_per_unit: "~75ms TTFB, 6× realtime"
|
||
license: MIT
|
||
notes: |
|
||
Routes to the devnen wrapper's richer /tts (full control surface:
|
||
exaggeration / cfg_weight / temperature / speed_factor / seed / voice_mode)
|
||
instead of the thin OpenAI /v1/audio/speech, which exposes NONE of the
|
||
emotion knobs — that omission was why prior output was poor. Same wrapper
|
||
author as the `dia` stack; identical predefined/clone voice model.
|
||
Defaults sourced from Resemble's README (exaggeration + cfg_weight = 0.5)
|
||
and the server's generation_defaults (temperature 0.8, speed 1.0, seed 0),
|
||
read live 2026-06-01; the server's shipped exaggeration 1.3 is demo-tuned
|
||
and deliberately NOT adopted. Python 3.10 only (wrapper hardcoding);
|
||
multilingual (23-language) variant available via the stack .env.
|
||
|
||
- id: index-tts
|
||
name: IndexTTS-2
|
||
description: >
|
||
Bilibili's emotion-controllable zero-shot TTS. Disentangled emotion control
|
||
(timbre from one reference, emotion from another). 22050 Hz fixed output.
|
||
category: tts
|
||
version: 1
|
||
status: down
|
||
host: irv-ml1
|
||
lifecycle:
|
||
stack: index-tts
|
||
vram_gb: 6
|
||
gpu_device_id: null
|
||
endpoint: http://10.100.79.3:8192/v1/audio/speech
|
||
method: POST
|
||
content_type: application/json
|
||
model:
|
||
id: IndexTeam/IndexTTS-2
|
||
revision: null
|
||
image: local/index-tts:v2
|
||
fields:
|
||
- name: input
|
||
type: textarea
|
||
label: Text
|
||
required: true
|
||
max_length: 5000
|
||
- name: voice
|
||
type: select
|
||
label: Speaker Voice
|
||
description: <name>.wav in /worktank/index-tts/voices/. 5–30s clean clips.
|
||
- name: response_format
|
||
type: select
|
||
options: [wav]
|
||
default: wav
|
||
description: 22050 Hz PCM_16 mono only; no negotiation.
|
||
- name: stream
|
||
type: bool
|
||
default: false
|
||
description: >
|
||
Segment-level streaming (~120 tokens). Streaming WAV uses placeholder
|
||
data-length (0xFFFFFFFF); browsers fine, strict parsers may complain.
|
||
- name: emotion_voice
|
||
type: select
|
||
label: Emotion Reference Voice
|
||
optional: true
|
||
description: <name>.wav in /worktank/index-tts/emotions/.
|
||
- name: emotion_vector
|
||
type: json
|
||
label: Emotion Vector
|
||
optional: true
|
||
description: >
|
||
8 floats [happy, angry, sad, afraid, disgusted, melancholic, surprised, calm],
|
||
each 0.0–1.0.
|
||
- name: emotion_text
|
||
type: textarea
|
||
label: Emotion Description (free text)
|
||
optional: true
|
||
- name: emotion_alpha
|
||
type: slider
|
||
min: 0.0
|
||
max: 1.0
|
||
default: 1.0
|
||
label: Emotion Strength
|
||
response:
|
||
type: audio
|
||
mime: audio/wav
|
||
reproducibility:
|
||
seedable: false
|
||
deterministic: true
|
||
notes: >
|
||
No seed. 22050 Hz hardcoded — resample in caller if 24/48 kHz needed.
|
||
Precedence if multiple emotion sources: emotion_voice > vector > text.
|
||
estimated_latency:
|
||
cold_start_s: 5
|
||
warm_per_unit: "segment-latency streaming"
|
||
license: "Custom Bilibili (free at small scale; commercial tier 100M MAU)"
|
||
notes: |
|
||
Three-way mutual-exclusion among emotion_voice / emotion_vector / emotion_text;
|
||
precedence as above. UI should expose this as a single picker.
|
||
|
||
- id: qwen3-tts
|
||
name: Qwen3-TTS 1.7B
|
||
description: >
|
||
Alibaba's open English-first TTS (Apache 2.0). 10 languages, 97ms TTFB,
|
||
instruction-driven emotion, voice cloning.
|
||
category: tts
|
||
version: 2
|
||
status: down
|
||
host: irv-ml1
|
||
lifecycle:
|
||
stack: qwen3-tts
|
||
vram_gb: 16
|
||
gpu_device_id: null
|
||
endpoint: http://10.100.79.3:8191/v1/audio/speech
|
||
method: POST
|
||
content_type: application/json
|
||
model:
|
||
id: Qwen/Qwen3-TTS-12Hz-1.7B
|
||
revision: null
|
||
image: local/qwen3-tts:v2
|
||
fields:
|
||
- name: model
|
||
type: select
|
||
options: [Qwen/Qwen3-TTS-12Hz-1.7B, Qwen/Qwen3-TTS-12Hz-0.6B-Base]
|
||
default: Qwen/Qwen3-TTS-12Hz-1.7B
|
||
- name: input
|
||
type: textarea
|
||
label: Text
|
||
required: true
|
||
max_length: 5000
|
||
- name: voice
|
||
type: select
|
||
label: Voice
|
||
source_url: http://10.100.79.3:8191/v1/voices
|
||
source_jsonpath: $.voices[*].id
|
||
default: vivian
|
||
options:
|
||
- vivian
|
||
- serena
|
||
- uncle_fu
|
||
- ryan
|
||
- aiden
|
||
- ono_anna
|
||
- sohee
|
||
- eric
|
||
- dylan
|
||
- alloy
|
||
- echo
|
||
- fable
|
||
- nova
|
||
- onyx
|
||
- shimmer
|
||
description: >
|
||
Wrapper ships 9 Qwen presets (vivian/serena/uncle_fu/ryan/aiden/
|
||
ono_anna/sohee/eric/dylan) + 6 OpenAI-compat aliases (alloy/echo/
|
||
fable/nova/onyx/shimmer) — verified live 2026-05-12 against
|
||
/v1/voices. Default `vivian` matches the wrapper's OpenAPI default
|
||
(case-normalized; the Qwen3-TTS blog cites "Vivian" with caps).
|
||
For cloning: clone:<name> where <name> is a profile dir under
|
||
/worktank/qwen3-tts/voices/profiles/. Create via /voice-studio web
|
||
UI or manually (meta.json + reference.wav). The 17-preset list
|
||
cited in the Qwen3-TTS upstream blog (Cherry/Ethan/Chelsie/...)
|
||
differs from what this wrapper exposes — the wrapper is the
|
||
source of truth.
|
||
- name: instructions
|
||
type: textarea
|
||
label: Emotion/Style Instructions
|
||
optional: true
|
||
description: >
|
||
Natural-language directive (e.g. "speak with cold contempt").
|
||
English instructions verified working ~2026-04.
|
||
- name: response_format
|
||
type: select
|
||
options: [wav, mp3, pcm]
|
||
default: wav
|
||
response:
|
||
type: audio
|
||
mime_from_field: response_format
|
||
reproducibility:
|
||
seedable: false
|
||
deterministic: true
|
||
estimated_latency:
|
||
cold_start_s: 5
|
||
warm_per_unit: "~97ms TTFB"
|
||
license: Apache-2.0
|
||
notes: |
|
||
Voice cloning shape differs from CosyVoice: profile-based, not voice-id-based.
|
||
|
||
- id: cosyvoice
|
||
name: CosyVoice 3 (Multilingual)
|
||
description: >
|
||
FunAudioLLM's multilingual expressive TTS. 18+ Chinese dialects + 8 other langs.
|
||
English prosody not ElevenLabs-grade — use Qwen3-TTS for English.
|
||
category: tts
|
||
version: 1
|
||
status: down
|
||
host: irv-ml1
|
||
lifecycle:
|
||
stack: cosyvoice
|
||
vram_gb: 4
|
||
gpu_device_id: null
|
||
endpoint: http://10.100.79.3:8190/v1/audio/speech
|
||
method: POST
|
||
content_type: application/json
|
||
model:
|
||
id: FunAudioLLM/Fun-CosyVoice3-0.5B-2512
|
||
revision: null
|
||
image: neosun/cosyvoice:v1.3.2
|
||
fields:
|
||
- name: model
|
||
type: select
|
||
options: [cosyvoice-v3, cosyvoice-v2]
|
||
default: cosyvoice-v3
|
||
- name: input
|
||
type: textarea
|
||
label: Text (with optional XML emotion tags)
|
||
required: true
|
||
max_length: 5000
|
||
description: >
|
||
For English: use XML tags <angry>, <sad>, <surprised>, <fast>, <whisper>, etc.
|
||
NOT the instruct field — English instruct values get vocalized literally
|
||
(upstream bug).
|
||
- name: voice
|
||
type: select
|
||
label: Voice (cloned only — no presets)
|
||
description: >
|
||
Create via POST /v1/voices/create (multipart with reference audio ≤30s).
|
||
Reference must be 16kHz mono ≤30s; longer = AssertionError.
|
||
- name: response_format
|
||
type: select
|
||
options: [wav]
|
||
default: wav
|
||
- name: speed
|
||
type: slider
|
||
min: 0.5
|
||
max: 2.0
|
||
default: 1.0
|
||
response:
|
||
type: audio
|
||
mime: audio/wav
|
||
reproducibility:
|
||
seedable: false
|
||
deterministic: true
|
||
notes: >
|
||
Reference audio MUST be ≤30s (16kHz mono). instruct field broken for English.
|
||
estimated_latency:
|
||
cold_start_s: 5
|
||
warm_per_unit: "~150ms TTFB streaming"
|
||
license: Apache-2.0
|
||
notes: |
|
||
GOTCHA: instruct field is Chinese-context only — UI should hide it for English
|
||
or surface a strong warning.
|
||
|
||
- id: fish-s2
|
||
name: Fish Audio S2-Pro
|
||
description: >
|
||
Fishaudio's richest-paralinguistic English TTS (15,000+ inline tags).
|
||
Trained 10M+ hours, dual-AR. Released March 2026. Heavy: ~240s compile
|
||
warmup on cold start, ~realtime throughput once warm.
|
||
category: tts
|
||
version: 6
|
||
host: irv-ml1
|
||
lifecycle:
|
||
stack: fish-s2
|
||
vram_gb: 24
|
||
gpu_device_id: 1
|
||
endpoint: http://10.100.79.3:8195/v1/tts
|
||
method: POST
|
||
content_type: application/json
|
||
model:
|
||
id: fishaudio/s2-pro
|
||
revision: null
|
||
image: local/fish-s2:v1
|
||
section_groups:
|
||
- id: basic
|
||
label: Text & output
|
||
- id: sampling
|
||
label: Sampling & latency
|
||
hint: fish-speech ServeTTSRequest defaults. Lower temperature/top_p for steadier reads; latency=balanced for lower latency.
|
||
- id: advanced
|
||
label: Advanced & voice cloning
|
||
fields:
|
||
- name: text
|
||
type: textarea
|
||
label: Text (with optional [tags])
|
||
section: basic
|
||
required: true
|
||
max_length: 5000
|
||
description: >
|
||
Inline tags: [laugh] [whispers] [super happy] [sigh] [excited]
|
||
[heavy breathing] [angry] [sleepy] [crying] [surprise] ... (15,000+).
|
||
Upstream best-practice: physical tags like [whispers] feel flat
|
||
without emotional context — pair with an emotion tag. Example:
|
||
`[excited] Welcome back! [whisper] I have a secret. [laugh]
|
||
Just kidding.`
|
||
- name: format
|
||
type: select
|
||
section: basic
|
||
options: [wav, mp3, opus]
|
||
default: wav
|
||
description: >
|
||
Output container (upstream also accepts raw `pcm`, omitted here).
|
||
wav + mp3 verified live 2026-06-01.
|
||
- name: temperature
|
||
type: slider
|
||
section: sampling
|
||
min: 0.1
|
||
max: 1.0
|
||
step: 0.05
|
||
default: 0.8
|
||
description: Sampling temperature; lower = steadier. fish-speech default 0.8.
|
||
- name: top_p
|
||
type: slider
|
||
section: sampling
|
||
min: 0.1
|
||
max: 1.0
|
||
step: 0.05
|
||
default: 0.8
|
||
description: Nucleus sampling cutoff. fish-speech default 0.8.
|
||
- name: repetition_penalty
|
||
type: slider
|
||
section: sampling
|
||
min: 0.9
|
||
max: 2.0
|
||
step: 0.05
|
||
default: 1.1
|
||
description: >
|
||
Penalizes repeats; raise if you hear stutters/loops. fish-speech
|
||
default 1.1.
|
||
- name: latency
|
||
type: select
|
||
section: sampling
|
||
options: [normal, balanced]
|
||
default: normal
|
||
description: >
|
||
`balanced` trades a little quality for lower latency — useful given
|
||
S2-Pro's ~realtime throughput. fish-speech default `normal`.
|
||
- name: seed
|
||
type: number
|
||
section: sampling
|
||
required: false
|
||
description: Omit for a random seed; a fixed integer repeats a take.
|
||
- name: reference_id
|
||
type: select
|
||
label: Voice
|
||
section: basic
|
||
optional: true
|
||
default: "Emily"
|
||
options:
|
||
- Abigail
|
||
- Adrian
|
||
- Alexander
|
||
- Alice
|
||
- Austin
|
||
- Axel
|
||
- Beatrice
|
||
- Eleanor
|
||
- Imogen
|
||
- Connor
|
||
- Cora
|
||
- Elena
|
||
- Eli
|
||
- Emily
|
||
- Everett
|
||
- Gabriel
|
||
- Gianna
|
||
- glados
|
||
- Henry
|
||
- Ian
|
||
- Jade
|
||
- Jeremiah
|
||
- Jordan
|
||
- Julian
|
||
- Layla
|
||
- Leonardo
|
||
- Michael
|
||
- Miles
|
||
- Olivia
|
||
- Ryan
|
||
- Taylor
|
||
- Thomas
|
||
description: >
|
||
Voice = a staged clone reference picked by name (THE working voice
|
||
path on this build; verified live 2026-06-01). 32 voices staged in
|
||
/worktank/fish-s2/references/: 28 from the dia library + glados + 3
|
||
British-female VCTK voices (Beatrice/Eleanor/Imogen). Default Emily.
|
||
Subtle British (Southern-England) female accents: Imogen (VCTK p225),
|
||
Eleanor (p228), Beatrice (p229) — consenting VCTK volunteers (CC BY
|
||
4.0), NOT modeled on or representing any public figure. Other female:
|
||
Abigail, Alice, Cora, Elena, Emily, Gianna, Jade, Layla, Olivia,
|
||
glados. Resolves against the DIRECTORY references/<name>/ (audio +
|
||
a same-basename <name>.lab transcript inside it) — NOT a flat
|
||
references/<name>.wav, which fish-speech ignores (empty/flat-only
|
||
dirs silently collapse every voice to the model default; root-caused
|
||
+ fixed 2026-06-01). Blank = model default/random speaker. To add:
|
||
create references/<name>/ with <name>.wav (clean 5–15s) + <name>.lab
|
||
(transcript) and add the name here; the deploy playbook's normalize
|
||
step also mirrors any flat <name>.wav into this layout. (No /voices
|
||
API → static list; a list-endpoint is the durable fix — see notes.)
|
||
- name: references
|
||
type: json
|
||
label: Custom clone (inline base64)
|
||
section: advanced
|
||
optional: true
|
||
togglable: true
|
||
description: >
|
||
Power-use: zero-shot clone from a reference NOT in the staged library
|
||
— array of {audio: <base64-encoded WAV bytes>, text: "transcript"}.
|
||
IMPORTANT: `audio` must be base64 bytes, NOT a filesystem path (a path
|
||
returns HTTP 500 on this build). For staged voices use `reference_id`.
|
||
- name: max_new_tokens
|
||
type: number
|
||
section: advanced
|
||
required: false
|
||
default: 1024
|
||
description: Max audio tokens per chunk. fish-speech default 1024.
|
||
- name: chunk_length
|
||
type: slider
|
||
section: advanced
|
||
min: 100
|
||
max: 1000
|
||
step: 10
|
||
default: 200
|
||
description: Target chunk length in chars when splitting. fish-speech default 200.
|
||
- name: normalize
|
||
type: bool
|
||
section: advanced
|
||
default: true
|
||
description: Text normalization (numbers, punctuation). fish-speech default on.
|
||
- name: use_memory_cache
|
||
type: select
|
||
section: advanced
|
||
options: ["off", "on"]
|
||
default: "off"
|
||
description: >
|
||
`on` caches the reference encoding to speed up repeated calls with the
|
||
same voice. fish-speech default off.
|
||
response:
|
||
type: audio
|
||
mime_from_field: format
|
||
reproducibility:
|
||
seedable: true
|
||
deterministic: false
|
||
seed_field: seed
|
||
notes: >
|
||
/v1/tts exposes `seed` (omit = random); a fixed seed repeats a take.
|
||
Temperature/top_p sampled → not guaranteed byte-exact. (Prior catalog
|
||
claimed no seed support — corrected against the upstream ServeTTSRequest
|
||
schema + a live generation 2026-06-01.)
|
||
estimated_latency:
|
||
cold_start_s: 240
|
||
warm_per_unit: "~realtime throughput on the A6000 (heavy). latency=balanced trades quality for lower latency."
|
||
license: "Research-only (Fishaudio terms; non-commercial)"
|
||
license_warning: |
|
||
Research/internal only. Not clear for commercial use. Same flag as
|
||
Voxtral and SAO — UI must surface when output destined for products.
|
||
notes: |
|
||
NOT OpenAI-compatible: only /v1/tts (no /v1/audio/voices, /v1/models, or
|
||
/openapi.json). Voice discovery is manual (host filesystem). Full control
|
||
surface (temperature/top_p/repetition_penalty/latency/seed/format + the
|
||
cloning fields) sourced from fish-speech's ServeTTSRequest schema and
|
||
verified live 2026-06-01; prior catalog exposed only text + references.
|
||
HEAVY: ~240s torch.compile warmup measured on cold start; budget the wait.
|
||
|
||
- id: kyutai-tts
|
||
name: Kyutai TTS 1.6B EN/FR
|
||
description: >
|
||
Kyutai's bilingual streaming TTS (1.6B, 2.5M hours). Heritage from Mimi codec
|
||
+ Moshi dialogue framework. OpenAI-compat HTTP wrapper over Rust streaming core.
|
||
category: tts
|
||
version: 2
|
||
status: down
|
||
host: irv-ml1
|
||
lifecycle:
|
||
stack: kyutai-tts
|
||
vram_gb: 6
|
||
gpu_device_id: 0
|
||
endpoint: http://10.100.79.3:8198/v1/audio/speech
|
||
method: POST
|
||
content_type: application/json
|
||
model:
|
||
id: kyutai/tts-1.6b-en_fr
|
||
revision: null
|
||
image: local/kyutai-tts:v1
|
||
fields:
|
||
- name: model
|
||
type: select
|
||
options: [tts-1.6b-en_fr]
|
||
default: tts-1.6b-en_fr
|
||
- name: input
|
||
type: textarea
|
||
label: Text
|
||
required: true
|
||
max_length: 5000
|
||
- name: voice
|
||
type: text
|
||
label: Voice (HF-relative path)
|
||
default: unmute-prod-website/default_voice.wav
|
||
description: >
|
||
Path relative to the `kyutai/tts-voices` HF repo, cached on
|
||
irv-ml1 at /worktank/kyutai-tts/hf_cache. NillPointer wrapper
|
||
does NOT expose /v1/audio/voices (404; only /health + POST
|
||
/v1/audio/speech are wired) — voices are specified by path.
|
||
Default `unmute-prod-website/default_voice.wav` is upstream's
|
||
named-default. Categories available locally (count):
|
||
vctk/* (212, CC BY 4.0 — commercial-safe)
|
||
ears/* (306)
|
||
voice-donations/* (291, mixed)
|
||
expresso/* (103, CC BY-NC — research-only)
|
||
cml-tts/* (70)
|
||
unmute-prod-website/* (6, incl. default)
|
||
alba-mackenna/* (4)
|
||
For commercial paths, prefer a vctk/* voice (e.g.,
|
||
`vctk/p225_023_mic1.wav`). Full repo:
|
||
https://huggingface.co/kyutai/tts-voices
|
||
- name: response_format
|
||
type: select
|
||
options: [wav, mp3, pcm]
|
||
default: wav
|
||
- name: stream
|
||
type: bool
|
||
default: false
|
||
response:
|
||
type: audio
|
||
mime_from_field: response_format
|
||
reproducibility:
|
||
seedable: false
|
||
deterministic: true
|
||
notes: >
|
||
Wrapper adds Python overhead vs Kyutai's bare 220ms claim.
|
||
Voice list is filesystem-discovered, not API-exposed — the
|
||
NillPointer wrapper only wires /health + /v1/audio/speech.
|
||
estimated_latency:
|
||
cold_start_s: 4
|
||
warm_per_unit: "~220–400ms TTFB (with wrapper)"
|
||
license: "TBD (Kyutai — verify)"
|
||
|
||
- id: vibevoice
|
||
name: VibeVoice 1.5B (Long-form)
|
||
description: >
|
||
Microsoft's diffusion-based long-form multi-speaker TTS. Multi-minute scripts
|
||
with speaker switching. Not for low-latency single-line use.
|
||
category: tts
|
||
version: 3
|
||
host: irv-ml1
|
||
lifecycle:
|
||
stack: vibevoice
|
||
vram_gb: 20
|
||
gpu_device_id: 1
|
||
endpoint: http://10.100.79.3:8194/v1/audio/speech
|
||
method: POST
|
||
content_type: application/json
|
||
model:
|
||
id: microsoft/VibeVoice-1.5B
|
||
revision: null
|
||
image: local/vibevoice:v1
|
||
fields:
|
||
- name: model
|
||
type: select
|
||
options: [tts-1, tts-1-hd, vibevoice]
|
||
default: tts-1
|
||
description: >
|
||
OpenAI-compatibility aliases all map to VibeVoice internally.
|
||
Wire default is tts-1 (verified against /openapi.json).
|
||
- name: input
|
||
type: textarea
|
||
label: "Text (or Speaker N: ... script)"
|
||
required: true
|
||
description: >
|
||
Single-speaker: plain text. Multi-speaker: "Speaker 0: ...\nSpeaker 1: ..."
|
||
via /v1/vibevoice/generate (extended endpoint).
|
||
- name: voice
|
||
type: select
|
||
label: Voice
|
||
default: en-Alice_woman
|
||
description: >
|
||
Default `en-Alice_woman` matches the upstream model card's stated
|
||
default voice. Foot-gun: Alice has been observed to insert
|
||
intro-BGM for openers like "Welcome to ..." — flip to
|
||
en-Maya_woman if BGM artifacts are unwanted.
|
||
OpenAI presets (compat aliases): alloy, echo, fable, onyx, nova, shimmer.
|
||
VibeVoice presets: en-Alice_woman, en-Carter_man, en-Frank_man,
|
||
en-Mary_woman_bgm, en-Maya_woman, in-Samuel_man, zh-Anchen_man_bgm,
|
||
zh-Bowen_man, zh-Xinran_woman. The `_bgm`-suffixed voices were
|
||
trained with background music intentionally — avoid for clean speech.
|
||
Custom: drop WAV/MP3/FLAC/M4A into /worktank/vibevoice/voices/,
|
||
restart container. Voice cloning training NOT released by Microsoft.
|
||
options:
|
||
- alloy
|
||
- echo
|
||
- fable
|
||
- onyx
|
||
- nova
|
||
- shimmer
|
||
- en-Alice_woman
|
||
- en-Carter_man
|
||
- en-Frank_man
|
||
- en-Mary_woman_bgm
|
||
- en-Maya_woman
|
||
- in-Samuel_man
|
||
- zh-Anchen_man_bgm
|
||
- zh-Bowen_man
|
||
- zh-Xinran_woman
|
||
- name: response_format
|
||
type: select
|
||
options: [wav, mp3, opus, flac, pcm]
|
||
default: mp3
|
||
description: >
|
||
Wire default is mp3 (verified /openapi.json). All five values
|
||
confirmed by exercising the endpoint 2026-05-11; aac and m4a
|
||
fail with 500 despite OpenAPI not enforcing an enum, so excluded.
|
||
- name: stream
|
||
type: bool
|
||
default: false
|
||
description: Single-shot endpoint doesn't stream; segment-level on multi-speaker.
|
||
response:
|
||
type: audio
|
||
mime_from_field: response_format
|
||
reproducibility:
|
||
seedable: false
|
||
deterministic: true
|
||
estimated_latency:
|
||
cold_start_s: 8
|
||
warm_per_unit: "30–60s first generation; segment-based after"
|
||
license: MIT
|
||
notes: |
|
||
flash_attention_2 default; sdpa fallback.
|
||
7B variant (rsxdalv/VibeVoice-Large, ~18GB) needs int8 for <10GB VRAM.
|
||
|
||
- id: voxtral
|
||
name: Voxtral 4B TTS
|
||
description: >
|
||
Mistral AI's 4B multilingual streaming TTS (CC BY-NC — research/internal only).
|
||
8 languages, 70ms model latency, 9.7× realtime. Served via vLLM-Omni.
|
||
category: tts
|
||
version: 2
|
||
status: down
|
||
host: irv-ml1
|
||
lifecycle:
|
||
stack: voxtral
|
||
vram_gb: 12
|
||
gpu_device_id: 1
|
||
endpoint: http://10.100.79.3:8197/v1/audio/speech
|
||
method: POST
|
||
content_type: application/json
|
||
model:
|
||
id: mistralai/Voxtral-4B-TTS-2603
|
||
revision: null
|
||
image: vllm/vllm-omni:v0.18.0
|
||
fields:
|
||
- name: model
|
||
type: select
|
||
options: [mistralai/Voxtral-4B-TTS-2603]
|
||
default: mistralai/Voxtral-4B-TTS-2603
|
||
- name: input
|
||
type: textarea
|
||
label: Text
|
||
required: true
|
||
max_length: 5000
|
||
- name: voice
|
||
type: select
|
||
label: Voice
|
||
source_url: http://10.100.79.3:8197/v1/audio/voices
|
||
default: neutral_female
|
||
options:
|
||
- neutral_female
|
||
- neutral_male
|
||
- casual_female
|
||
- casual_male
|
||
- cheerful_female
|
||
- ar_male
|
||
- de_female
|
||
- de_male
|
||
- es_female
|
||
- es_male
|
||
- fr_female
|
||
- fr_male
|
||
- hi_female
|
||
- hi_male
|
||
- it_female
|
||
- it_male
|
||
- nl_female
|
||
- nl_male
|
||
- pt_female
|
||
- pt_male
|
||
description: >
|
||
Native Voxtral presets — vLLM-Omni does NOT translate OpenAI
|
||
aliases (verified 2026-05-12 live against /v1/audio/voices). Naming
|
||
shape is `<register>_<gender>` for English (neutral_*, casual_*,
|
||
cheerful_*) and `<lang>_<gender>` for non-English. Default
|
||
`neutral_female` matches Mistral docs' stated default. The full
|
||
list above was captured live from the running container; uploaded
|
||
user voices appear in /v1/audio/voices under `uploaded_voices`.
|
||
- name: response_format
|
||
type: select
|
||
options: [wav, mp3, pcm]
|
||
default: wav
|
||
- name: stream
|
||
type: bool
|
||
default: false
|
||
response:
|
||
type: audio
|
||
mime_from_field: response_format
|
||
reproducibility:
|
||
seedable: false
|
||
deterministic: true
|
||
notes: vLLM-Omni v0.18.0+ required (first Voxtral-aware release, 2026-03-29).
|
||
estimated_latency:
|
||
cold_start_s: 6
|
||
warm_per_unit: "~70ms model latency, 9.7× realtime"
|
||
license: "CC BY-NC (Mistral) — non-commercial only"
|
||
license_warning: |
|
||
NOT clear for commercial use. UI must surface this when output destined
|
||
for products. Use Kokoro/Chatterbox/Fish/IndexTTS/Qwen3/CosyVoice for
|
||
commercial paths.
|
||
|
||
- id: parakeet
|
||
name: Parakeet TDT (ASR)
|
||
description: >
|
||
NVIDIA Parakeet-TDT 0.6B (int8 ONNX, ~400MB) via sherpa-onnx.
|
||
Transcription only.
|
||
category: asr
|
||
version: 1
|
||
host: irv-ml1
|
||
lifecycle:
|
||
stack: parakeet
|
||
vram_gb: 2
|
||
gpu_device_id: null
|
||
endpoint: http://10.100.79.3:8765/transcribe
|
||
method: POST
|
||
content_type: multipart/form-data
|
||
model:
|
||
id: nvidia/parakeet-tdt-v2-en-int8
|
||
revision: null
|
||
image: local/parakeet:sherpa-onnx-v2
|
||
fields:
|
||
- name: file
|
||
type: file
|
||
label: Audio File
|
||
required: true
|
||
accepted_types: [audio/wav, audio/mp3, audio/flac, audio/ogg]
|
||
response:
|
||
type: text
|
||
output_field: text
|
||
reproducibility:
|
||
seedable: false
|
||
deterministic: true
|
||
estimated_latency:
|
||
cold_start_s: 1
|
||
warm_per_unit: "~realtime"
|
||
license: "Proprietary (NVIDIA model) + Apache-2.0 (sherpa-onnx)"
|
||
notes: |
|
||
Aliased at /v1/audio/transcriptions for OpenAI compat.
|
||
v3 model (25 languages) available via env-only change.
|
||
|
||
- id: stable-audio-open
|
||
name: Stable Audio Open 1.0 (SFX)
|
||
description: >
|
||
Stability AI's text-to-audio diffusion. SFX/foley/ambience only — NOT music.
|
||
Max 47s clips. Seeded, fully deterministic.
|
||
category: sfx
|
||
version: 2
|
||
host: irv-ml1
|
||
lifecycle:
|
||
stack: stable-audio-open
|
||
vram_gb: 6
|
||
gpu_device_id: 1
|
||
endpoint: http://10.100.79.3:8211/v1/audio/sfx
|
||
method: POST
|
||
content_type: application/json
|
||
model:
|
||
id: stabilityai/stable-audio-open-1.0
|
||
revision: null
|
||
image: local/stable-audio-open:v1
|
||
fields:
|
||
- name: prompt
|
||
type: textarea
|
||
label: Prompt
|
||
required: true
|
||
description: >
|
||
Description of the audio to generate. Per diffusers Tips section,
|
||
descriptive multi-element prompts produce better results than terse
|
||
ones — `"melodic techno with a fast beat and synths, 128 BPM"` is
|
||
stronger than `"techno"`. Other canonical examples from the model
|
||
card: `"128 BPM tech house drum loop"`, `"the sound of a hammer
|
||
hitting a wooden surface"`.
|
||
- name: negative_prompt
|
||
type: textarea
|
||
label: Negative Prompt
|
||
default: "low quality, average quality"
|
||
description: >
|
||
Official diffusers-docs recommendation. `"low quality, average
|
||
quality"` (lowercase, comma-separated) per the Stable Audio
|
||
pipeline's Tips section — was `"Low quality."` in v0, fixed in v1.
|
||
- name: duration
|
||
type: slider
|
||
min: 0.5
|
||
max: 47.0
|
||
default: 10.0
|
||
label: Duration (seconds)
|
||
- name: steps
|
||
type: slider
|
||
min: 10
|
||
max: 300
|
||
default: 100
|
||
label: Diffusion Steps
|
||
- name: cfg_scale
|
||
type: slider
|
||
min: 0.0
|
||
max: 20.0
|
||
default: 7.0
|
||
label: CFG Scale
|
||
- name: seed
|
||
type: number
|
||
label: Seed
|
||
optional: true
|
||
response:
|
||
type: audio
|
||
mime: audio/wav
|
||
reproducibility:
|
||
seedable: true
|
||
seed_field: seed
|
||
deterministic: true
|
||
notes: >
|
||
Identical seed+prompt+steps+cfg = bit-identical bytes. Wrapper serializes
|
||
concurrent requests via asyncio.Lock (StableAudioPipeline not reentrant).
|
||
estimated_latency:
|
||
cold_start_s: 3
|
||
warm_per_unit: "~30–60s per 10s clip"
|
||
license: "Stability AI Community (non-commercial)"
|
||
license_warning: |
|
||
Non-commercial only. Same flag as Voxtral for commercial paths.
|
||
|
||
- id: ace-step
|
||
name: ACE-Step 1.5 (Music)
|
||
description: >
|
||
Apache-2.0 hybrid diffusion+LLM music generation. Multi-minute lyric-aware
|
||
songs with vocals + instrumentation.
|
||
category: music
|
||
version: 5
|
||
host: irv-ml1
|
||
lifecycle:
|
||
stack: ace-step
|
||
vram_gb: 16
|
||
gpu_device_id: 1
|
||
endpoint: http://10.100.79.3:8210/generate
|
||
method: POST
|
||
content_type: application/json
|
||
model:
|
||
id: ace-step/ACE-Step
|
||
revision: main
|
||
image: local/ace-step:v1
|
||
section_groups:
|
||
- id: basic
|
||
label: Basic
|
||
hint: "Prompt + lyrics + duration. The 80% case."
|
||
- id: generation
|
||
label: Generation
|
||
hint: "Sampler steps, guidance, scheduler, seed."
|
||
- id: conditioning
|
||
label: Conditioning
|
||
hint: "ERG flags, OSS schedule, guidance shape."
|
||
- id: a2a
|
||
label: "Audio → Audio"
|
||
hint: "Generate from a reference clip."
|
||
- id: lora
|
||
label: LoRA
|
||
hint: "Adapter weights."
|
||
- id: output
|
||
label: Output
|
||
hint: "Format and device."
|
||
fields:
|
||
- name: prompt
|
||
type: textarea
|
||
label: Musical Prompt
|
||
required: true
|
||
section: basic
|
||
description: >
|
||
Style/mood/instrumentation as a comma-separated tag string.
|
||
The upstream Gradio UI ships pre-filled with: `"funk, pop, soul,
|
||
rock, melodic, guitar, drums, bass, keyboard, percussion, 105 BPM,
|
||
energetic, upbeat, groovy, vibrant, dynamic"` — same shape works
|
||
well here. Shorter examples: `"uplifting pop with synth leads"`,
|
||
`"lo-fi hip-hop beat with vinyl crackle"`.
|
||
- name: lyrics
|
||
type: textarea
|
||
label: Lyrics
|
||
required: true
|
||
default: ""
|
||
section: basic
|
||
description: >
|
||
Required by the upstream Pydantic model (`lyrics: str`) but empty
|
||
string is a valid value (instrumental). Default '' so the inference
|
||
client always sends a string.
|
||
- name: audio_duration
|
||
type: slider
|
||
min: 5.0
|
||
max: 240.0
|
||
default: 30.0
|
||
label: Duration (seconds)
|
||
section: basic
|
||
description: >
|
||
Upstream caps at 240s (the model's training horizon). Lower bound
|
||
5s is our choice — upstream uses -1 as a "random duration" sentinel
|
||
which is hostile UX for a slider. Default 30s also kept (upstream
|
||
uses -1; explicit 30 is the better first-time-user experience).
|
||
- name: infer_step
|
||
type: number
|
||
default: 60
|
||
label: Inference Steps
|
||
section: generation
|
||
description: >
|
||
Upstream Gradio default is 60 (matches benchmark numbers in the
|
||
README). Lower values (20-30) are useful for "preview" passes;
|
||
higher (80-100) marginal returns.
|
||
- name: guidance_scale
|
||
type: slider
|
||
min: 0.0
|
||
max: 30.0
|
||
default: 15.0
|
||
section: generation
|
||
- name: scheduler_type
|
||
type: select
|
||
options: [euler, heun, pingpong]
|
||
default: euler
|
||
section: generation
|
||
description: >
|
||
Flow-matching scheduler. `euler` is the canonical default;
|
||
`heun` trades 2x compute for higher-order accuracy; `pingpong`
|
||
is a specialized noise-bouncing variant.
|
||
- name: cfg_type
|
||
type: select
|
||
options: [apg, cfg, cfg_star]
|
||
default: apg
|
||
section: generation
|
||
description: >
|
||
Classifier-free guidance variant. Upstream Gradio default is `apg`
|
||
(adaptive projected guidance); `cfg` is the standard SD-style
|
||
formulation; `cfg_star` is an advanced alternative. See the
|
||
upstream pipeline source for trade-offs.
|
||
- name: omega_scale
|
||
type: slider
|
||
min: -10.0
|
||
max: 30.0
|
||
default: 10.0
|
||
section: generation
|
||
description: >
|
||
Upstream technically allows [-100, 100] but values that wide are
|
||
unusable as a slider. UI-bounded to [-10, 30] which covers the
|
||
typical zone with headroom. Hit the API directly for extremes.
|
||
- name: actual_seeds
|
||
type: json
|
||
label: Seeds (empty = random)
|
||
default: []
|
||
section: generation
|
||
description: >
|
||
Empty list = wrapper sends empty string to pipeline = pipeline
|
||
picks a random seed per batch element. Explicit seeds (e.g. [42]
|
||
or [42, 137, 9999]) for reproducibility.
|
||
|
||
REPRODUCIBILITY GAP (queued for follow-up): the pipeline returns
|
||
the chosen seed in its result dict, but our wrapper currently
|
||
throws it away. Assets generated with the default `[]` cannot
|
||
currently be regenerated. Workaround: set actual_seeds explicitly
|
||
when reproducibility matters. Wrapper enhancement to surface
|
||
random-resolved seeds via X-Actual-Seeds header + a catalog
|
||
schema field for header→accessory capture is the planned fix.
|
||
- name: guidance_interval
|
||
type: slider
|
||
min: 0.0
|
||
max: 1.0
|
||
default: 0.5
|
||
section: conditioning
|
||
- name: guidance_interval_decay
|
||
type: slider
|
||
min: 0.0
|
||
max: 1.0
|
||
default: 0.0
|
||
section: conditioning
|
||
description: >
|
||
Upstream Gradio default is 0.0 (no decay). Catalog v4 had this at
|
||
1.0 (full decay) — wrong; produced under-conditioned outputs.
|
||
- name: min_guidance_scale
|
||
type: slider
|
||
min: 0.0
|
||
max: 20.0
|
||
default: 3.0
|
||
section: conditioning
|
||
description: >
|
||
Upstream technically allows up to 200; UI-bounded to 20 (covers
|
||
the typical zone). Hit the API directly for extremes.
|
||
- name: use_erg_tag
|
||
type: bool
|
||
default: true
|
||
section: conditioning
|
||
- name: use_erg_lyric
|
||
type: bool
|
||
default: false
|
||
section: conditioning
|
||
- name: use_erg_diffusion
|
||
type: bool
|
||
default: true
|
||
section: conditioning
|
||
- name: oss_steps
|
||
type: json
|
||
default: []
|
||
section: conditioning
|
||
- name: guidance_scale_text
|
||
type: slider
|
||
min: 0.0
|
||
max: 10.0
|
||
default: 0.0
|
||
section: conditioning
|
||
- name: guidance_scale_lyric
|
||
type: slider
|
||
min: 0.0
|
||
max: 10.0
|
||
default: 0.0
|
||
section: conditioning
|
||
- name: audio2audio_enable
|
||
type: bool
|
||
default: false
|
||
section: a2a
|
||
- name: ref_audio_strength
|
||
type: slider
|
||
min: 0.0
|
||
max: 1.0
|
||
default: 0.5
|
||
section: a2a
|
||
- name: ref_audio_input
|
||
type: text
|
||
label: Reference Audio Path
|
||
optional: true
|
||
section: a2a
|
||
- name: lora_name_or_path
|
||
type: text
|
||
label: LoRA Repo/Path
|
||
optional: true
|
||
section: lora
|
||
- name: lora_weight
|
||
type: slider
|
||
min: -3.0
|
||
max: 3.0
|
||
default: 1.0
|
||
section: lora
|
||
description: >
|
||
Negative weights are legitimate (apply the LoRA in inverse).
|
||
Upstream Gradio range adopted verbatim.
|
||
- name: audio_format
|
||
type: select
|
||
options: [wav, mp3, flac]
|
||
default: wav
|
||
section: output
|
||
- name: bf16
|
||
type: bool
|
||
default: true
|
||
section: output
|
||
- name: torch_compile
|
||
type: bool
|
||
default: false
|
||
section: output
|
||
- name: device_id
|
||
type: number
|
||
default: 0
|
||
label: GPU Device Index
|
||
section: output
|
||
- name: checkpoint_path
|
||
type: text
|
||
label: Checkpoint Path
|
||
required: true
|
||
default: /app/checkpoints
|
||
section: output
|
||
description: >
|
||
Required by the upstream wrapper (`infer-api.py:29`, no default in
|
||
the Pydantic model). The container always mounts checkpoints at
|
||
/app/checkpoints, so the catalog default works out-of-the-box.
|
||
Only override if you've mounted an alternate checkpoint path.
|
||
Wrapper-side cleanup queued — once the upstream model defaults this,
|
||
the catalog field will become optional or be dropped entirely.
|
||
response:
|
||
# As of wrapper version that ships with image local/ace-step:v1
|
||
# post 2026-05-11, /generate streams audio bytes inline with
|
||
# Content-Type set from the audio_format request field. The
|
||
# in-container output_path is exposed via X-Output-Path header
|
||
# for log correlation but is no longer load-bearing.
|
||
type: audio
|
||
mime_from_field: audio_format
|
||
reproducibility:
|
||
seedable: true
|
||
deterministic: true
|
||
notes: >
|
||
actual_seeds parameter exposed; identical seeds + params = identical audio.
|
||
Local infer-api.py patches upstream's broken 24-arg pipeline signature
|
||
(v2: was 18 in upstream — caused crashes with audio_duration in `format`
|
||
slot) AND inline-streams the generated audio bytes (v4: was returning a
|
||
JSON path reference to a file inside the container, which was
|
||
unreachable from outside).
|
||
|
||
REPRODUCIBILITY GAP (v5): default `actual_seeds: []` triggers random
|
||
seed selection inside the pipeline. The chosen seed IS available in
|
||
the pipeline's return dict (`actual_seeds` key) but our wrapper
|
||
doesn't capture or surface it — so default-defaulted assets cannot be
|
||
regenerated bit-exact. Set actual_seeds explicitly when reproducibility
|
||
is required. Wrapper enhancement to surface chosen seeds via response
|
||
header + a catalog schema for header→accessory capture is queued.
|
||
estimated_latency:
|
||
cold_start_s: 30
|
||
warm_per_unit: "~10–60s depending on audio_duration + infer_step"
|
||
license: Apache-2.0
|
||
notes: |
|
||
27-field surface — UI must do progressive disclosure (basic/advanced).
|
||
Gradio UI fallback: docker exec -it ace-step python3 acestep/gui.py.
|
||
|
||
- id: comfyui
|
||
name: ComfyUI (workflow engine — catalog-deferred)
|
||
description: >
|
||
Node-based diffusion workflow engine. Native API is workflow JSON DAG, not
|
||
form fields. Catalog-deferred until per-asset-type workflow templates are
|
||
defined and a wrapper maps form inputs to template node parameters.
|
||
category: image
|
||
status: catalog-deferred
|
||
version: 1
|
||
host: irv-ml1
|
||
endpoint: http://10.100.79.3:8188
|
||
method: WebSocket + POST
|
||
content_type: application/json
|
||
model:
|
||
id: "various (SD, SDXL, Flux, ControlNet, LoRA, upscalers)"
|
||
revision: null
|
||
image: mmartial/comfyui-nvidia-docker:ubuntu24_cuda12.8-20260312
|
||
response:
|
||
type: image
|
||
mime: image/png
|
||
reproducibility:
|
||
seedable: true
|
||
deterministic: true
|
||
notes: >
|
||
Seed is a workflow node parameter. Reproducibility requires persisting
|
||
full workflow JSON + seed alongside the asset.
|
||
license: GPL-3.0
|
||
notes: |
|
||
To bring into the catalog: define workflow templates per asset-type
|
||
(portrait, landscape, sfx-thumbnail, ...), build a wrapper that does
|
||
form-field-to-node-parameter substitution, submit via POST /prompt, poll
|
||
/history. Until then, expose ComfyUI as an external link in the UI.
|
||
User state at /worktank/comfyui/basedir/.
|
||
|
||
# Dia2 runs as TWO fixed-model instances: the devnen wrapper is
|
||
# single-model and IGNORES the OpenAI `model` field (serves whatever
|
||
# checkpoint is loaded), so the only way to offer both Dia2 models to
|
||
# asset-engine as real per-request choices is one endpoint per model.
|
||
# Both live in the `dia` stack (one compose, two services); `compose up`
|
||
# starts both. The legacy Dia 1.6B entry was retired 2026-05-31 in favor
|
||
# of these — drop the old `dia` tile when re-vendoring.
|
||
- id: dia2-2b
|
||
name: Dia2 2B (High Quality)
|
||
description: >
|
||
Nari Labs' Dia2 dialogue TTS, 2B high-quality checkpoint — multi-speaker
|
||
turn-taking in one pass with [S1]/[S2] speaker tags and nonverbals
|
||
(laughs)/(coughs)/(sighs). 24 kHz. Served via devnen/Dia-TTS-Server.
|
||
category: tts
|
||
version: 2
|
||
status: ready
|
||
host: irv-ml1
|
||
lifecycle:
|
||
stack: dia
|
||
vram_gb: 8
|
||
gpu_device_id: 0
|
||
endpoint: http://10.100.79.3:8200/tts
|
||
method: POST
|
||
content_type: application/json
|
||
model:
|
||
id: nari-labs/Dia2-2B
|
||
revision: null
|
||
image: local/dia:v2
|
||
section_groups:
|
||
- id: basic
|
||
label: Text & voice
|
||
- id: sampling
|
||
label: Sampling
|
||
hint: Wrapper-canonical Dia2 defaults; lower temperature/cfg for steadier output.
|
||
- id: advanced
|
||
label: Advanced
|
||
fields:
|
||
- name: text
|
||
type: textarea
|
||
label: Text ([S1]/[S2] dialogue + nonverbals)
|
||
section: basic
|
||
required: true
|
||
max_length: 5000
|
||
default: "[S1] Hello Dia2!" # canonical: nari-labs/dia2 README usage example
|
||
description: >
|
||
[S1]/[S2] tags mark speaker turns; nonverbals like (laughs),
|
||
(coughs), (sighs), (clears throat) go inline.
|
||
- name: voice_mode
|
||
type: select
|
||
label: Voice mode
|
||
section: basic
|
||
options: [clone, single_s1, single_s2, dialogue]
|
||
default: clone
|
||
description: >
|
||
Defaults to `clone` -> a stable predefined voice (clone_reference_filename
|
||
below, default Abigail.wav). The unconditioned modes (single_s1/s2,
|
||
dialogue) sample a RANDOM speaker each call (gender varies) — pick one
|
||
only if you want that. NOTE: voice_mode=clone REQUIRES a real
|
||
clone_reference_filename; an empty/"undefined" value 404s.
|
||
- name: clone_reference_filename
|
||
type: select
|
||
label: Voice (clone reference)
|
||
section: basic
|
||
optional: true
|
||
default: "Abigail.wav"
|
||
source_url: http://10.100.79.3:8200/get_reference_files
|
||
source_jsonpath: $[*]
|
||
description: >
|
||
Required when voice_mode=clone. Lists the reference_audio library —
|
||
43 curated voices (singles + [S1]/[S2] dialogue pairs like
|
||
Abigail_Taylor.wav) staged there from the image's /app/voices, plus
|
||
any you upload. Pins voice/gender deterministically.
|
||
- name: transcript
|
||
type: textarea
|
||
label: Reference transcript
|
||
section: advanced
|
||
optional: true
|
||
description: >
|
||
Optional transcript of a custom clone reference (overrides its local
|
||
.txt sidecar). Leave blank for predefined voices.
|
||
- name: output_format
|
||
type: select
|
||
section: basic
|
||
options: [opus, wav]
|
||
default: opus
|
||
description: 24 kHz (Dia2).
|
||
- name: cfg_scale
|
||
type: slider
|
||
section: sampling
|
||
min: 1.0
|
||
max: 5.0
|
||
step: 0.1
|
||
default: 3.0
|
||
description: Classifier-free guidance scale (wrapper default 3.0).
|
||
- name: temperature
|
||
type: slider
|
||
section: sampling
|
||
min: 0.1
|
||
max: 1.5
|
||
step: 0.05
|
||
default: 1.3
|
||
description: Sampling temperature; lower = steadier (wrapper default 1.3).
|
||
- name: top_p
|
||
type: slider
|
||
section: sampling
|
||
min: 0.1
|
||
max: 1.0
|
||
step: 0.01
|
||
default: 0.95
|
||
- name: cfg_filter_top_k
|
||
type: number
|
||
section: sampling
|
||
required: false
|
||
default: 35
|
||
description: Top-k filter for CFG guidance (1–100; wrapper default 35).
|
||
- name: speed_factor
|
||
type: slider
|
||
section: sampling
|
||
min: 0.5
|
||
max: 2.0
|
||
step: 0.01
|
||
default: 0.94
|
||
description: Playback speed (wrapper canonical default 0.94).
|
||
- name: seed
|
||
type: number
|
||
section: sampling
|
||
required: false
|
||
default: -1
|
||
description: -1 = random; a fixed integer repeats the same take.
|
||
- name: split_text
|
||
type: bool
|
||
section: advanced
|
||
default: true
|
||
description: Auto-split long text into chunks.
|
||
- name: chunk_size
|
||
type: slider
|
||
section: advanced
|
||
min: 100
|
||
max: 1000
|
||
step: 10
|
||
default: 300
|
||
description: Target chunk length in chars when splitting (wrapper default 300).
|
||
- name: max_tokens
|
||
type: number
|
||
section: advanced
|
||
required: false
|
||
description: Max audio tokens per chunk; omit to use the model's internal default.
|
||
response:
|
||
type: audio
|
||
mime_from_field: output_format
|
||
reproducibility:
|
||
seedable: true
|
||
deterministic: false
|
||
notes: >
|
||
Per the dia2 README, voices vary per generation unless anchored — set
|
||
voice_mode=clone + a clone_reference_filename for a stable voice/gender.
|
||
seed (-1=random) repeats a take but doesn't choose the voice;
|
||
temperature-sampled, not byte-exact; raw bytes -> no seed_field. All
|
||
field defaults are the wrapper's CustomTTSRequest Pydantic blessed values.
|
||
estimated_latency:
|
||
cold_start_s: 30
|
||
warm_per_unit: "dialogue one-pass; ~realtime on the 3090"
|
||
license: "Apache-2.0 (Dia2 weights); MIT (devnen wrapper)"
|
||
notes: |
|
||
Routes to the wrapper's richer /tts endpoint (full control surface:
|
||
cfg_scale/temperature/top_p/cfg_filter_top_k/voice_mode/clone) rather than
|
||
the OpenAI /v1/audio/speech. One of two fixed-model instances in the `dia`
|
||
stack; sibling dia2-1b (:8202). `docker compose up` starts BOTH (~8 GB
|
||
here; budget both if gating the whole stack). Image local/dia:v2 (see
|
||
stacks/dia/dia2-image/). Verified end-to-end 2026-05-31.
|
||
|
||
- id: dia2-1b
|
||
name: Dia2 1B (Streaming)
|
||
description: >
|
||
Nari Labs' Dia2 dialogue TTS, 1B streaming checkpoint — same [S1]/[S2]
|
||
dialogue + nonverbals as dia2-2b, lower latency / lighter weight. 24 kHz.
|
||
Served via devnen/Dia-TTS-Server.
|
||
category: tts
|
||
version: 2
|
||
status: ready
|
||
host: irv-ml1
|
||
lifecycle:
|
||
stack: dia
|
||
vram_gb: 5
|
||
gpu_device_id: 0
|
||
endpoint: http://10.100.79.3:8202/tts
|
||
method: POST
|
||
content_type: application/json
|
||
model:
|
||
id: nari-labs/Dia2-1B
|
||
revision: null
|
||
image: local/dia:v2
|
||
section_groups:
|
||
- id: basic
|
||
label: Text & voice
|
||
- id: sampling
|
||
label: Sampling
|
||
hint: Wrapper-canonical Dia2 defaults; lower temperature/cfg for steadier output.
|
||
- id: advanced
|
||
label: Advanced
|
||
fields:
|
||
- name: text
|
||
type: textarea
|
||
label: Text ([S1]/[S2] dialogue + nonverbals)
|
||
section: basic
|
||
required: true
|
||
max_length: 5000
|
||
default: "[S1] Hello Dia2!" # canonical: nari-labs/dia2 README usage example
|
||
description: >
|
||
[S1]/[S2] tags mark speaker turns; nonverbals like (laughs),
|
||
(coughs), (sighs), (clears throat) go inline.
|
||
- name: voice_mode
|
||
type: select
|
||
label: Voice mode
|
||
section: basic
|
||
options: [clone, single_s1, single_s2, dialogue]
|
||
default: clone
|
||
description: >
|
||
Defaults to `clone` -> a stable predefined voice (clone_reference_filename
|
||
below, default Abigail.wav). The unconditioned modes (single_s1/s2,
|
||
dialogue) sample a RANDOM speaker each call (gender varies) — pick one
|
||
only if you want that. NOTE: voice_mode=clone REQUIRES a real
|
||
clone_reference_filename; an empty/"undefined" value 404s.
|
||
- name: clone_reference_filename
|
||
type: select
|
||
label: Voice (clone reference)
|
||
section: basic
|
||
optional: true
|
||
default: "Abigail.wav"
|
||
source_url: http://10.100.79.3:8202/get_reference_files
|
||
source_jsonpath: $[*]
|
||
description: >
|
||
Required when voice_mode=clone. Lists the reference_audio library —
|
||
43 curated voices (singles + [S1]/[S2] dialogue pairs like
|
||
Abigail_Taylor.wav) staged there from the image's /app/voices, plus
|
||
any you upload. Pins voice/gender deterministically.
|
||
- name: transcript
|
||
type: textarea
|
||
label: Reference transcript
|
||
section: advanced
|
||
optional: true
|
||
description: >
|
||
Optional transcript of a custom clone reference (overrides its local
|
||
.txt sidecar). Leave blank for predefined voices.
|
||
- name: output_format
|
||
type: select
|
||
section: basic
|
||
options: [opus, wav]
|
||
default: opus
|
||
description: 24 kHz (Dia2).
|
||
- name: cfg_scale
|
||
type: slider
|
||
section: sampling
|
||
min: 1.0
|
||
max: 5.0
|
||
step: 0.1
|
||
default: 3.0
|
||
description: Classifier-free guidance scale (wrapper default 3.0).
|
||
- name: temperature
|
||
type: slider
|
||
section: sampling
|
||
min: 0.1
|
||
max: 1.5
|
||
step: 0.05
|
||
default: 1.3
|
||
description: Sampling temperature; lower = steadier (wrapper default 1.3).
|
||
- name: top_p
|
||
type: slider
|
||
section: sampling
|
||
min: 0.1
|
||
max: 1.0
|
||
step: 0.01
|
||
default: 0.95
|
||
- name: cfg_filter_top_k
|
||
type: number
|
||
section: sampling
|
||
required: false
|
||
default: 35
|
||
description: Top-k filter for CFG guidance (1–100; wrapper default 35).
|
||
- name: speed_factor
|
||
type: slider
|
||
section: sampling
|
||
min: 0.5
|
||
max: 2.0
|
||
step: 0.01
|
||
default: 0.94
|
||
description: Playback speed (wrapper canonical default 0.94).
|
||
- name: seed
|
||
type: number
|
||
section: sampling
|
||
required: false
|
||
default: -1
|
||
description: -1 = random; a fixed integer repeats the same take.
|
||
- name: split_text
|
||
type: bool
|
||
section: advanced
|
||
default: true
|
||
description: Auto-split long text into chunks.
|
||
- name: chunk_size
|
||
type: slider
|
||
section: advanced
|
||
min: 100
|
||
max: 1000
|
||
step: 10
|
||
default: 300
|
||
description: Target chunk length in chars when splitting (wrapper default 300).
|
||
- name: max_tokens
|
||
type: number
|
||
section: advanced
|
||
required: false
|
||
description: Max audio tokens per chunk; omit to use the model's internal default.
|
||
response:
|
||
type: audio
|
||
mime_from_field: output_format
|
||
reproducibility:
|
||
seedable: true
|
||
deterministic: false
|
||
notes: >
|
||
Same story as dia2-2b: voices vary per generation unless anchored
|
||
(voice_mode=clone + clone_reference_filename); temperature-sampled,
|
||
not byte-exact; raw bytes -> no seed_field. Defaults are the wrapper's
|
||
CustomTTSRequest Pydantic blessed values.
|
||
estimated_latency:
|
||
cold_start_s: 30
|
||
warm_per_unit: "streaming; lower latency than dia2-2b"
|
||
license: "Apache-2.0 (Dia2 weights); MIT (devnen wrapper)"
|
||
notes: |
|
||
Routes to the wrapper's richer /tts endpoint (same control surface as
|
||
dia2-2b). Sibling of dia2-2b in the same `dia` stack (see its notes for
|
||
the single-model-per-endpoint rationale + both-start-together caveat).
|
||
Image local/dia:v2. Verified end-to-end 2026-05-31.
|
||
|
||
- id: zonos
|
||
name: Zonos-v0.1 TTS
|
||
description: >
|
||
Zyphra's expressive multilingual open-weight TTS (Apache-2.0) — 44 kHz,
|
||
zero-shot voice cloning from a 10–30s clip, and an 8-axis emotion
|
||
vector plus pitch/rate/fmax conditioning. First genuinely seedable TTS
|
||
in the fleet: the adapter returns the seed so regenerate/fork can pin it.
|
||
category: tts
|
||
version: 1
|
||
status: down
|
||
host: irv-ml1
|
||
lifecycle:
|
||
stack: zonos
|
||
# Adapter alone (~6 GB). NOTE: the zonos stack currently ships TWO
|
||
# services (the Gradio eval UI + this adapter); if orchestration does a
|
||
# whole-stack `compose up` it loads the model twice (~12 GB). Target the
|
||
# zonos-api service, or drop the Gradio service at promotion.
|
||
vram_gb: 6
|
||
gpu_device_id: 0
|
||
endpoint: http://10.100.79.3:8203/v1/audio/speech
|
||
method: POST
|
||
content_type: application/json
|
||
model:
|
||
id: Zyphra/Zonos-v0.1-transformer
|
||
revision: null
|
||
image: local/zonos-api:v1
|
||
section_groups:
|
||
- id: text
|
||
label: Text
|
||
- id: voice
|
||
label: Voice
|
||
- id: expression
|
||
label: Expression
|
||
hint: Conditioning knobs; leave emotion blank to keep it unconditional.
|
||
- id: generation
|
||
label: Generation
|
||
fields:
|
||
- name: input
|
||
type: textarea
|
||
label: Text to synthesize
|
||
section: text
|
||
required: true
|
||
max_length: 500
|
||
default: "Zonos uses eSpeak for text to phoneme conversion!" # canonical: upstream gradio_interface.py default
|
||
description: eSpeak-phonemized. Upstream Gradio caps the box at ~500 chars.
|
||
- name: language
|
||
type: select
|
||
label: Language code
|
||
section: text
|
||
default: en-us
|
||
# eSpeak code list is large; these are the documented multilingual
|
||
# set. The adapter accepts any code in zonos.supported_language_codes.
|
||
options: [en-us, ja, cmn, fr-fr, de]
|
||
description: Any eSpeak code Zonos supports; 400 on an unknown code.
|
||
- name: voice
|
||
type: select
|
||
label: Clone voice (optional)
|
||
section: voice
|
||
optional: true
|
||
source_url: http://10.100.79.3:8203/v1/audio/voices
|
||
source_jsonpath: $.voices[*]
|
||
description: >
|
||
Reference clip filename under /worktank/zonos/voices/ (10–30s clean
|
||
WAV). Omit for Zonos's default unconditioned voice.
|
||
- name: response_format
|
||
type: select
|
||
section: generation
|
||
options: [wav, flac]
|
||
default: wav
|
||
description: 44.1 kHz. Both lossless (libsndfile); no mp3/opus in v1.
|
||
- name: emotion
|
||
type: json
|
||
label: Emotion vector (optional)
|
||
section: expression
|
||
optional: true
|
||
description: >
|
||
8 floats 0.0–1.0 [happy, sad, disgust, fear, surprise, anger, other,
|
||
neutral]. Omit to leave emotion unconditional (the Gradio default;
|
||
upstream warns the sliders are finicky and can destabilize output).
|
||
- name: speaking_rate
|
||
type: slider
|
||
section: expression
|
||
min: 5.0
|
||
max: 30.0
|
||
step: 0.5
|
||
default: 15.0
|
||
- name: pitch_std
|
||
type: slider
|
||
label: Pitch std
|
||
section: expression
|
||
min: 0.0
|
||
max: 300.0
|
||
step: 1
|
||
default: 45.0
|
||
- name: fmax
|
||
type: slider
|
||
label: Fmax (Hz)
|
||
section: expression
|
||
min: 0
|
||
max: 24000
|
||
step: 1
|
||
default: 24000
|
||
- name: cfg_scale
|
||
type: slider
|
||
label: CFG scale
|
||
section: generation
|
||
min: 1.0
|
||
max: 5.0
|
||
step: 0.1
|
||
default: 2.0
|
||
- name: seed
|
||
type: number
|
||
section: generation
|
||
optional: true
|
||
description: Omit for a random seed; the seed used is returned in the envelope.
|
||
response:
|
||
# JSON envelope (like kokoro-captioned) so the seed rides back with the
|
||
# audio. Adapter returns: {audio: <base64 in response_format>,
|
||
# audio_format: "audio/wav"|"audio/flac", seed: <int>}.
|
||
type: audio
|
||
audio_field: audio
|
||
audio_format_field: audio_format
|
||
reproducibility:
|
||
seedable: true
|
||
deterministic: true
|
||
seed_field: seed
|
||
notes: >
|
||
torch.manual_seed(seed); the adapter echoes the seed it used in the
|
||
envelope's `seed` key. Same seed + params + GPU → byte-stable in
|
||
practice; cross-GPU (3090 vs A6000) may differ at bf16. Wire shape
|
||
is defined by the adapter (stacks/zonos/adapter/server.py) — verify
|
||
against the live endpoint at deploy per CATALOG-CONTRACT.
|
||
estimated_latency:
|
||
cold_start_s: 30
|
||
warm_per_unit: "~2x realtime on the 3090 (transformer variant)"
|
||
license: Apache-2.0
|
||
notes: |
|
||
Served via a thin OpenAI-ish FastAPI adapter (stacks/zonos/adapter/) in
|
||
front of the Zonos Python SDK — upstream ships only Gradio + SDK, no REST.
|
||
Transformer variant only (mamba-ssm absent → no hybrid). Fields read from
|
||
upstream gradio_interface.py (2026-05-31), the CATALOG-CONTRACT blessed
|
||
source for defaults/ranges. Adapter not yet deployed/verified — flip to
|
||
ready (or experimental) after the first successful generation through 8203.
|
||
|
||
# Reproducibility audit — answers per service: (a) seedable, (b) model
|
||
# deterministic without seed, (c) image tag mutable (security/reproducibility risk).
|
||
reproducibility_audit:
|
||
- service: kokoro
|
||
seedable: false
|
||
model_deterministic: true
|
||
image_tag_mutable: true
|
||
notes: ":v0.2.4-master is mutable; pin to digest for v3."
|
||
- service: kokoro-captioned
|
||
seedable: false
|
||
model_deterministic: true
|
||
image_tag_mutable: true
|
||
notes: "Same image as kokoro proper; same mutability story. Response carries timestamps."
|
||
- service: chatterbox
|
||
seedable: true
|
||
model_deterministic: false
|
||
image_tag_mutable: true
|
||
notes: "/tts exposes seed (0=random); temperature-sampled, not byte-exact. PerTh watermark unconditional (Resemble policy). image :latest is mutable — pin a digest/SHA for true repro."
|
||
- service: index-tts
|
||
seedable: false
|
||
model_deterministic: true
|
||
image_tag_mutable: false
|
||
notes: "22050 Hz hardcoded — caller must resample."
|
||
- service: qwen3-tts
|
||
seedable: false
|
||
model_deterministic: true
|
||
image_tag_mutable: false
|
||
- service: cosyvoice
|
||
seedable: false
|
||
model_deterministic: true
|
||
image_tag_mutable: false
|
||
notes: "instruct field broken for English; XML tags only."
|
||
- service: fish-s2
|
||
seedable: true
|
||
model_deterministic: false
|
||
image_tag_mutable: false
|
||
notes: "/v1/tts exposes seed (omit=random); temperature/top_p sampled, not byte-exact. Research-only license — non-commercial."
|
||
- service: kyutai-tts
|
||
seedable: false
|
||
model_deterministic: true
|
||
image_tag_mutable: false
|
||
- service: vibevoice
|
||
seedable: false
|
||
model_deterministic: true
|
||
image_tag_mutable: false
|
||
notes: "Voice cloning training not released."
|
||
- service: voxtral
|
||
seedable: false
|
||
model_deterministic: true
|
||
image_tag_mutable: false
|
||
notes: "CC BY-NC — non-commercial."
|
||
- service: parakeet
|
||
seedable: false
|
||
model_deterministic: true
|
||
image_tag_mutable: false
|
||
- service: stable-audio-open
|
||
seedable: true
|
||
model_deterministic: true
|
||
image_tag_mutable: false
|
||
notes: "Wrapper serializes concurrent requests (StableAudioPipeline not reentrant)."
|
||
- service: ace-step
|
||
seedable: true
|
||
model_deterministic: true
|
||
image_tag_mutable: false
|
||
notes: "Local infer-api.py patches upstream's broken pipeline signature."
|
||
- service: comfyui
|
||
seedable: true
|
||
model_deterministic: true
|
||
image_tag_mutable: false
|
||
notes: "Reproducibility requires persisting full workflow JSON + seed."
|
||
- service: dia2-2b
|
||
seedable: true
|
||
model_deterministic: false
|
||
image_tag_mutable: false
|
||
notes: "Dia2 2B, temperature-sampled (seed gives consistent prosody, not byte-exact). local/dia:v2 (derived; upstream wrapper SHA not pinned)."
|
||
- service: dia2-1b
|
||
seedable: true
|
||
model_deterministic: false
|
||
image_tag_mutable: false
|
||
notes: "Dia2 1B streaming; same determinism story as dia2-2b. local/dia:v2."
|
||
- service: zonos
|
||
seedable: true
|
||
model_deterministic: true
|
||
image_tag_mutable: false
|
||
notes: "Adapter echoes the seed used (reproducibility.seed_field=seed). Byte-stable same-GPU; bf16 may drift cross-GPU. local/zonos-api:v1 built FROM local/zonos (pin ZONOS_SHA for true repro)."
|