51c77370b3
Six default + description tightenings from upstream-source research:
- **Kokoro voice**: af_bella → af_heart. Per upstream VOICES.md, af_heart
is the only A-rated voice; also the kokoro-fastapi container's own
default. Applied to both kokoro (v2 → v3) and kokoro-captioned (v1 → v2).
- **SAO negative_prompt**: "Low quality." → "low quality, average quality".
Per diffusers official docs Tips section — the lowercase comma-separated
shape is the explicit recommendation; the period form was a code-example
string, never a documented default. SAO bumped v1 → v2.
- **SAO prompt description**: added the model card's canonical examples
("128 BPM tech house drum loop", "the sound of a hammer hitting a wooden
surface") plus the Tips advice on descriptive prompts.
- **VibeVoice voice**: en-Carter_man → en-Alice_woman. Per upstream model
card, Alice is the documented default. Description now flags the
Alice-injects-BGM-for-intros foot-gun + the `_bgm`-suffix meaning.
VibeVoice bumped v2 → v3.
- **Fish-s2 text description**: added multi-tag placeholder example
combining emotion + physical tags, per upstream best-practice docs
(physical tags "feel flat without emotional context").
- **ace-step prompt description**: added the upstream Gradio UI's
pre-filled tag string as the canonical prompt-shape example.
Surfaced separately to lkraven (NOT applied here, need decisions):
- Voxtral voice "alloy" may need to become a native preset like
"neutral_female" — depends on whether vLLM-Omni translates OpenAI
aliases.
- Qwen3-TTS — research found 17 presets (Cherry, Ethan, ...) that the
catalog currently says don't exist. Catalog says clone-only; needs
wrapper-level verification before adding.
- Kyutai-TTS — service down, can't probe /v1/audio/voices. Default
remains undefaulted.
1232 lines
41 KiB
YAML
1232 lines
41 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: 1
|
||
|
||
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 Turbo TTS
|
||
description: >
|
||
Resemble AI's low-latency English TTS (350M, ~75ms TTFB, 6× realtime).
|
||
Zero-shot voice cloning from ~5s reference. 9 paralinguistic tags.
|
||
category: tts
|
||
version: 1
|
||
status: down
|
||
host: irv-ml1
|
||
lifecycle:
|
||
stack: chatterbox
|
||
vram_gb: 4
|
||
gpu_device_id: 0
|
||
endpoint: http://10.100.79.3:8196/v1/audio/speech
|
||
method: POST
|
||
content_type: application/json
|
||
model:
|
||
id: ResembleAI/chatterbox-turbo
|
||
revision: null
|
||
image: devnen/Chatterbox-TTS-Server:latest
|
||
fields:
|
||
- name: input
|
||
type: textarea
|
||
label: Text (with optional [tags])
|
||
required: true
|
||
max_length: 5000
|
||
description: >
|
||
Inline tags: [laugh] [chuckle] [sigh] [gasp] [cough] [clear throat]
|
||
[sniff] [groan] [shush]. Turbo loses base-Chatterbox's exaggeration knob.
|
||
- name: model
|
||
type: select
|
||
options: [chatterbox-turbo]
|
||
default: chatterbox-turbo
|
||
- name: voice
|
||
type: select
|
||
label: Voice
|
||
default: alloy
|
||
description: >
|
||
Built-in OpenAI-compat aliases (alloy, echo, fable, onyx, nova, shimmer).
|
||
Cloned: 5–15s WAV files in /worktank/chatterbox/reference_audio/.
|
||
- name: response_format
|
||
type: select
|
||
options: [wav, opus, aac, flac, pcm_s16]
|
||
default: wav
|
||
- name: stream
|
||
type: bool
|
||
default: false
|
||
response:
|
||
type: audio
|
||
mime_from_field: response_format
|
||
reproducibility:
|
||
seedable: false
|
||
deterministic: true
|
||
notes: >
|
||
No seed. Wrapper repo updates ~weekly; pin SHA in .env. PerTh watermark
|
||
unconditionally applied (Resemble policy).
|
||
estimated_latency:
|
||
cold_start_s: 3
|
||
warm_per_unit: "~75ms TTFB, 6× realtime"
|
||
license: MIT
|
||
notes: |
|
||
Python 3.10 only (wrapper hardcoding).
|
||
Multilingual variant (23 languages) also available via .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: 1
|
||
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
|
||
description: >
|
||
Built-in or cloned. 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).
|
||
- 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, ~150ms streaming TTFB. Released March 2026.
|
||
category: tts
|
||
version: 1
|
||
host: irv-ml1
|
||
lifecycle:
|
||
stack: fish-s2
|
||
vram_gb: 4
|
||
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
|
||
fields:
|
||
- name: text
|
||
type: textarea
|
||
label: Text (with optional [tags])
|
||
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: references
|
||
type: json
|
||
label: Voice References
|
||
optional: true
|
||
description: >
|
||
Array of {audio: "/app/references/<file>.wav", text: "transcript"}.
|
||
Files under /worktank/fish-s2/references/ on host.
|
||
response:
|
||
type: audio
|
||
mime: audio/wav
|
||
reproducibility:
|
||
seedable: false
|
||
deterministic: true
|
||
estimated_latency:
|
||
cold_start_s: 8
|
||
warm_per_unit: "~150ms TTFB"
|
||
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, no /v1/models.
|
||
Voice discovery is manual (host filesystem).
|
||
|
||
- 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: 1
|
||
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: select
|
||
label: Voice
|
||
source_url: http://10.100.79.3:8198/v1/audio/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.
|
||
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: 1
|
||
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: alloy
|
||
- 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/.
|
||
|
||
# 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: false
|
||
model_deterministic: true
|
||
image_tag_mutable: false
|
||
notes: "PerTh watermark unconditional (Resemble policy)."
|
||
- 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: false
|
||
model_deterministic: true
|
||
image_tag_mutable: false
|
||
notes: "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."
|