d3faeb0314
asset_engine consumer needed to render kokoro-captioned, whose wire
shape is a JSON envelope carrying base64-encoded audio plus a
structured timestamps array. Modeling it as response.type=json
would force either a per-service-id renderer (forbidden by
brief §1.7) or extending the closed response-type vocabulary
(forbidden by brief §2.2 without a coordinated bump).
Resolution (per althing thread 01KRCF4W66X3): keep response.type
closed at the existing six values and decompose at the response
*field* level instead — the same flexibility seam already used by
mime / mime_from_field / output_field. Adds three optional keys:
- audio_field: JSON key holding base64-encoded audio bytes
- audio_format_field: JSON key holding the decoded audio MIME
- timestamps_field: JSON key holding a structured timestamps array
(independent of type, declared by any service emitting time-
aligned markers)
Validators in CatalogResponse enforce sane combinations:
- audio_field requires response.type=audio
- audio_field forbids mime_from_field
- audio_format_field requires audio_field
This is additive and backward-compatible — no catalog_version bump,
existing services parse unchanged. CATALOG-CONTRACT.md updated with
the new rows in the response-field table and a versioning-policy
row codifying that adding optional keys to response: doesn't bump.
kokoro-captioned re-shaped to use the new schema:
response:
type: audio
audio_field: audio
audio_format_field: audio_format
timestamps_field: timestamps
And marked status: experimental until the asset_engine consumer's
audio-with-timestamps renderer ships.
JSON Schema regenerated to reflect the new Pydantic shape.
Pydantic-model side of this change lives in the asset_engine repo
at src/asset_engine/catalog.py — committed there separately.
1001 lines
31 KiB
YAML
1001 lines
31 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: 2
|
||
host: irv-ml1
|
||
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_bella
|
||
description: >
|
||
60+ built-in voices. 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: 1
|
||
status: experimental
|
||
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_bella
|
||
- 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
|
||
host: irv-ml1
|
||
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
|
||
host: irv-ml1
|
||
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
|
||
host: irv-ml1
|
||
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
|
||
host: irv-ml1
|
||
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
|
||
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+).
|
||
- 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
|
||
host: irv-ml1
|
||
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: 1
|
||
host: irv-ml1
|
||
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: [vibevoice]
|
||
default: vibevoice
|
||
- 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: Carter
|
||
description: >
|
||
Built-in: Carter, Davis, Emma, Frank, Grace, Mike, Samuel.
|
||
Custom: drop WAV/MP3/FLAC/M4A into /worktank/vibevoice/voices/, restart container.
|
||
Voice cloning training NOT released by Microsoft.
|
||
- name: response_format
|
||
type: select
|
||
options: [wav, mp3]
|
||
default: wav
|
||
- 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
|
||
host: irv-ml1
|
||
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
|
||
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: 1
|
||
host: irv-ml1
|
||
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
|
||
- name: negative_prompt
|
||
type: textarea
|
||
label: Negative Prompt
|
||
default: "Low quality."
|
||
- 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
|
||
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: 1
|
||
host: irv-ml1
|
||
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
|
||
fields:
|
||
- name: prompt
|
||
type: textarea
|
||
label: Musical Prompt
|
||
required: true
|
||
description: Style/mood/instrumentation, e.g. "uplifting pop with synth leads".
|
||
- name: lyrics
|
||
type: textarea
|
||
label: Lyrics
|
||
optional: true
|
||
- name: audio_duration
|
||
type: slider
|
||
min: 5.0
|
||
max: 600.0
|
||
default: 30.0
|
||
label: Duration (seconds)
|
||
- name: audio_format
|
||
type: select
|
||
options: [wav, mp3, flac]
|
||
default: wav
|
||
- name: infer_step
|
||
type: number
|
||
default: 20
|
||
label: Inference Steps
|
||
- name: guidance_scale
|
||
type: slider
|
||
min: 1.0
|
||
max: 15.0
|
||
default: 7.5
|
||
- name: scheduler_type
|
||
type: select
|
||
options: [linear, squared, sqrt]
|
||
default: linear
|
||
- name: cfg_type
|
||
type: select
|
||
options: [none, cfg, cfg_rw]
|
||
default: cfg
|
||
- name: omega_scale
|
||
type: slider
|
||
min: 0.0
|
||
max: 1.0
|
||
default: 0.5
|
||
- name: actual_seeds
|
||
type: json
|
||
label: Seeds
|
||
default: [42]
|
||
- name: guidance_interval
|
||
type: slider
|
||
min: 0.0
|
||
max: 1.0
|
||
default: 0.0
|
||
- name: guidance_interval_decay
|
||
type: slider
|
||
min: 0.0
|
||
max: 1.0
|
||
default: 1.0
|
||
- name: min_guidance_scale
|
||
type: slider
|
||
min: 0.0
|
||
max: 10.0
|
||
default: 1.0
|
||
- name: use_erg_tag
|
||
type: bool
|
||
default: false
|
||
- name: use_erg_lyric
|
||
type: bool
|
||
default: false
|
||
- name: use_erg_diffusion
|
||
type: bool
|
||
default: false
|
||
- name: oss_steps
|
||
type: json
|
||
default: []
|
||
- name: guidance_scale_text
|
||
type: slider
|
||
min: 0.0
|
||
max: 15.0
|
||
default: 0.0
|
||
- name: guidance_scale_lyric
|
||
type: slider
|
||
min: 0.0
|
||
max: 15.0
|
||
default: 0.0
|
||
- name: audio2audio_enable
|
||
type: bool
|
||
default: false
|
||
- name: ref_audio_strength
|
||
type: slider
|
||
min: 0.0
|
||
max: 1.0
|
||
default: 0.5
|
||
- name: ref_audio_input
|
||
type: text
|
||
label: Reference Audio Path
|
||
optional: true
|
||
- name: lora_name_or_path
|
||
type: text
|
||
label: LoRA Repo/Path
|
||
optional: true
|
||
- name: lora_weight
|
||
type: slider
|
||
min: 0.0
|
||
max: 2.0
|
||
default: 1.0
|
||
- name: bf16
|
||
type: bool
|
||
default: true
|
||
- name: torch_compile
|
||
type: bool
|
||
default: false
|
||
- name: device_id
|
||
type: number
|
||
default: 0
|
||
label: GPU Device Index
|
||
response:
|
||
type: audio
|
||
mime_from_field: audio_format
|
||
output_field: output_path
|
||
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
|
||
(was 18 in upstream — caused crashes with audio_duration in `format` slot).
|
||
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."
|