diff --git a/model_specs/dramabox.json b/model_specs/dramabox.json index ed494c8d3..3ecbe701b 100644 --- a/model_specs/dramabox.json +++ b/model_specs/dramabox.json @@ -57,7 +57,7 @@ { "name": "num_inference_steps", "type": "int", - "description": "Diffusion sampling step count; default comes from config.json, 30 in the current package.", + "description": "Diffusion sampling step count; default 30.", "required": false, "min": 1, "default": 30 @@ -65,7 +65,7 @@ { "name": "guidance_scale", "type": "float", - "description": "Classifier-free guidance scale; default comes from config.json, 2.5 in the current package. Values greater than 1 enable CFG.", + "description": "Classifier-free guidance scale; default 2.5. Values greater than 1 enable CFG.", "required": false, "min": 0.0, "default": 2.5 @@ -73,7 +73,7 @@ { "name": "spatio_temporal_guidance_scale", "type": "float", - "description": "Spatio-temporal guidance scale; default comes from config.json, 1.5 in the current package. Values greater than 0 enable STG.", + "description": "Spatio-temporal guidance scale; default 1.5. Values greater than 0 enable STG.", "required": false, "min": 0.0, "default": 1.5 @@ -81,7 +81,7 @@ { "name": "duration_scale", "type": "float", - "description": "Multiplier applied to the estimated prompt duration when duration_sec is 0; default comes from config.json, 1.1 in the current package.", + "description": "Multiplier applied to the estimated prompt duration when duration_sec is 0; default 1.1.", "required": false, "min": 0.0, "default": 1.1 @@ -89,7 +89,7 @@ { "name": "reference_duration_sec", "type": "float", - "description": "Reference voice crop/repeat duration in seconds; default comes from config.json, 10.0 in the current package.", + "description": "Reference voice crop/repeat duration in seconds; default 10.0.", "required": false, "min": 0.0, "default": 10.0 diff --git a/model_specs/firered_audio.json b/model_specs/firered_audio.json index 7e54daf4b..32f05f856 100644 --- a/model_specs/firered_audio.json +++ b/model_specs/firered_audio.json @@ -182,14 +182,6 @@ "min": 1, "default": 1024 }, - { - "name": "helper_graph_arena_mb", - "type": "int", - "description": "Helper graph arena size in MiB; default 256.", - "required": false, - "min": 1, - "default": 256 - }, { "name": "weight_context_mb", "type": "int", diff --git a/model_specs/fish_audio.json b/model_specs/fish_audio.json index 9a15337c7..8530e14d2 100644 --- a/model_specs/fish_audio.json +++ b/model_specs/fish_audio.json @@ -29,7 +29,7 @@ { "name": "reference_text", "type": "string", - "description": "Reference transcript used with speaker reference audio.", + "description": "Reference transcript used with speaker reference audio. Required whenever the request carries inline reference audio; the model rejects the request without it.", "required": false }, { @@ -57,10 +57,15 @@ { "name": "text_chunk_mode", "type": "enum", - "description": "Framework text chunking mode; default word_budget.", - "preset": "text_chunk_mode_full", + "description": "Framework text chunking mode; default default.", + "values": [ + "default", + "tag_aware", + "japanese", + "endline" + ], "required": false, - "default": "word_budget" + "default": "default" }, { "name": "top_p", diff --git a/model_specs/granite5asr.json b/model_specs/granite5asr.json index f576999fb..ae85c315d 100644 --- a/model_specs/granite5asr.json +++ b/model_specs/granite5asr.json @@ -22,13 +22,6 @@ }, "options": { "request": [ - { - "name": "language", - "type": "string", - "description": "Recognition language (currently English).", - "required": false, - "default": "en" - }, { "name": "audio_chunk_mode", "type": "enum", diff --git a/model_specs/heartmula.json b/model_specs/heartmula.json index 0392f868e..d6f87fdec 100644 --- a/model_specs/heartmula.json +++ b/model_specs/heartmula.json @@ -26,13 +26,13 @@ "name": "lyrics", "type": "string", "description": "Lyrics text.", - "required": false + "required": true }, { "name": "tags", "type": "string", "description": "Comma-separated music tags.", - "required": false + "required": true }, { "name": "duration_sec", diff --git a/model_specs/irodori_tts.json b/model_specs/irodori_tts.json index 4da584fe6..ccebb6390 100644 --- a/model_specs/irodori_tts.json +++ b/model_specs/irodori_tts.json @@ -74,6 +74,8 @@ "type": "enum", "description": "Text chunking mode; default endline.", "values": [ + "default", + "tag_aware", "japanese", "endline" ], diff --git a/model_specs/midashenglm_gen.json b/model_specs/midashenglm_gen.json index 5704bf86f..0f92dbec0 100644 --- a/model_specs/midashenglm_gen.json +++ b/model_specs/midashenglm_gen.json @@ -67,9 +67,9 @@ { "name": "seed", "type": "int", - "description": "Generation seed; -1 selects a random seed.", + "description": "Generation seed; parsed as an unsigned 32-bit value, so negative seeds are rejected.", "required": false, - "min": -1, + "min": 0, "max": 2147483647, "default": 0 } diff --git a/model_specs/minimax_h3.json b/model_specs/minimax_h3.json index 9ac47500a..d4a38a686 100644 --- a/model_specs/minimax_h3.json +++ b/model_specs/minimax_h3.json @@ -192,6 +192,24 @@ "min": 0.0, "default": 0.1 }, + { + "name": "first_block_cache_start_percent", + "type": "float", + "description": "Start of the denoise window where the first-block cache may be used, as a fraction of the schedule.", + "required": false, + "min": 0.0, + "max": 1.0, + "default": 0.1 + }, + { + "name": "first_block_cache_end_percent", + "type": "float", + "description": "End of the denoise window where the first-block cache may be used, as a fraction of the schedule; must be greater than first_block_cache_start_percent.", + "required": false, + "min": 0.0, + "max": 1.0, + "default": 0.95 + }, { "name": "first_block_cache_start_sigma", "type": "float", diff --git a/model_specs/minimax_music3.json b/model_specs/minimax_music3.json index 97c165638..4da4d6aae 100644 --- a/model_specs/minimax_music3.json +++ b/model_specs/minimax_music3.json @@ -80,6 +80,47 @@ "required": false, "min": 0, "default": 0 + }, + { + "name": "flow_uncond_interval", + "type": "int", + "description": "Evaluate the flow unconditional CFG branch only every N-th step and reuse the cached guidance delta in between; 1 keeps the exact reference trajectory.", + "required": false, + "min": 1, + "default": 1 + }, + { + "name": "flow_uncond_warmup", + "type": "int", + "description": "Number of initial flow steps that always evaluate both CFG branches when delta reuse is enabled.", + "required": false, + "min": 0, + "default": 2 + }, + { + "name": "ensemble_takes", + "type": "int", + "description": "Decode N independent takes of the same prompt in one batched AR pass (seeds seed..seed+N-1); outputs are returned as named audio take_01..take_NN.", + "required": false, + "min": 1, + "max": 16, + "default": 1 + }, + { + "name": "ensemble_prefix_frames", + "type": "int", + "description": "Intro-lock for ensembles: decode the first N AR frames once as a shared master trajectory (~25 frames per second), then fork the takes; 0 disables.", + "required": false, + "min": 0, + "default": 0 + }, + { + "name": "flow_chunk_hop_frames", + "type": "int", + "description": "Flow chunk hop in AR frames (~25/sec); 0 keeps the model config (100, 50% chunk overlap).", + "required": false, + "min": 0, + "default": 0 } ], "session": [ @@ -141,6 +182,13 @@ "description": "Load large generation stages only while they are needed to reduce peak VRAM.", "required": false, "default": true + }, + { + "name": "pipeline_overlap", + "type": "bool", + "description": "Overlap AR decoding with per-chunk condition/flow/vocoder work on a second backend stream. Requires mem_saver=false; falls back to the sequential pipeline otherwise.", + "required": false, + "default": false } ], "load": [] diff --git a/model_specs/miocodec.json b/model_specs/miocodec.json index 8cb71e543..c94907a99 100644 --- a/model_specs/miocodec.json +++ b/model_specs/miocodec.json @@ -26,6 +26,60 @@ "speaker_reference" ] }, + "options": { + "request": [], + "session": [ + { + "name": "weight_type", + "type": "enum", + "description": "Codec weight storage type; default f32.", + "preset": "weight_type_full", + "required": false, + "default": "f32" + }, + { + "name": "weight_context_mb", + "type": "int", + "description": "Codec weight descriptor context size in MiB; default 256.", + "required": false, + "min": 1, + "default": 256 + }, + { + "name": "constant_context_mb", + "type": "int", + "description": "Reusable constant context size in MiB; default 256.", + "required": false, + "min": 1, + "default": 256 + }, + { + "name": "content_graph_arena_mb", + "type": "int", + "description": "Content encoder graph arena size in MiB; default 512.", + "required": false, + "min": 1, + "default": 512 + }, + { + "name": "global_graph_arena_mb", + "type": "int", + "description": "Global encoder graph arena size in MiB; default 256.", + "required": false, + "min": 1, + "default": 256 + }, + { + "name": "wave_graph_arena_mb", + "type": "int", + "description": "Wave decoder graph arena size in MiB; default 512.", + "required": false, + "min": 1, + "default": 512 + } + ], + "load": [] + }, "runtime": { "tags": [ "gguf" diff --git a/model_specs/mms_forced_aligner.json b/model_specs/mms_forced_aligner.json index 9862dee61..793ad37b7 100644 --- a/model_specs/mms_forced_aligner.json +++ b/model_specs/mms_forced_aligner.json @@ -61,7 +61,7 @@ { "name": "return_timestamps", "type": "bool", - "description": "Request word timestamps in the result; set automatically by --words-out.", + "description": "Accepted for cross-model compatibility (--words-out sets it) and ignored: the forced aligner always returns word timestamps.", "required": false, "default": true } diff --git a/model_specs/outetts.json b/model_specs/outetts.json index fc8e7dedc..4eae1b8bc 100644 --- a/model_specs/outetts.json +++ b/model_specs/outetts.json @@ -107,7 +107,7 @@ { "name": "reference_text", "type": "string", - "description": "Transcript matching the reference voice audio for voice cloning.", + "description": "Transcript matching the reference voice audio for voice cloning. Required whenever reference audio is supplied; the model rejects voice cloning without it.", "required": false }, { @@ -128,10 +128,15 @@ { "name": "text_chunk_mode", "type": "enum", - "description": "Framework long-form text chunking mode; default word_budget.", - "preset": "text_chunk_mode_full", + "description": "Framework long-form text chunking mode; default default.", + "values": [ + "default", + "tag_aware", + "japanese", + "endline" + ], "required": false, - "default": "word_budget" + "default": "default" } ], "session": [ diff --git a/model_specs/parakeet_tdt.json b/model_specs/parakeet_tdt.json index 7d9910dd8..96be20dfa 100644 --- a/model_specs/parakeet_tdt.json +++ b/model_specs/parakeet_tdt.json @@ -54,6 +54,12 @@ }, "options": { "request": [ + { + "name": "language", + "type": "string", + "description": "Transcription language from the OpenAI-compatible request field. Accepted for API compatibility; Parakeet TDT detects the language itself and does not use this value (see keep_language_tags).", + "required": false + }, { "name": "max_tokens", "type": "int", diff --git a/model_specs/qwen3_forced_aligner.json b/model_specs/qwen3_forced_aligner.json index 060d45db8..a5083531e 100644 --- a/model_specs/qwen3_forced_aligner.json +++ b/model_specs/qwen3_forced_aligner.json @@ -37,6 +37,63 @@ "required": false, "default": false } + ], + "session": [ + { + "name": "weight_type", + "type": "enum", + "description": "Fallback weight storage type for the thinker; default native.", + "preset": "weight_type_full", + "required": false, + "default": "native" + }, + { + "name": "thinker_weight_type", + "type": "enum", + "description": "Thinker matmul weight storage type; defaults to weight_type when set, otherwise native.", + "preset": "weight_type_full", + "required": false + }, + { + "name": "audio_encoder_weight_type", + "type": "enum", + "description": "Audio encoder weight storage type; default native.", + "preset": "weight_type_conv", + "required": false, + "default": "native" + }, + { + "name": "audio_encoder_graph_arena_mb", + "type": "int", + "description": "Audio encoder graph arena size in MiB; default 128.", + "required": false, + "min": 1, + "default": 128 + }, + { + "name": "thinker_prefill_graph_arena_mb", + "type": "int", + "description": "Thinker prefill graph arena size in MiB; default 256.", + "required": false, + "min": 1, + "default": 256 + }, + { + "name": "thinker_decode_graph_arena_mb", + "type": "int", + "description": "Thinker decode graph arena size in MiB; default 256.", + "required": false, + "min": 1, + "default": 256 + }, + { + "name": "thinker_weight_context_mb", + "type": "int", + "description": "Thinker weight descriptor context size in MiB; default 64.", + "required": false, + "min": 1, + "default": 64 + } ] }, "runtime": { diff --git a/model_specs/sense_asr.json b/model_specs/sense_asr.json index 868b896a3..2cc6102e2 100644 --- a/model_specs/sense_asr.json +++ b/model_specs/sense_asr.json @@ -69,10 +69,11 @@ { "name": "audio_chunk_mode", "type": "enum", - "description": "Audio chunking mode: auto, fixed, or none.", + "description": "Audio chunking mode: auto, fixed, vad, or none.", "values": [ "auto", "fixed", + "vad", "none" ], "required": false, diff --git a/model_specs/voxcpm1.json b/model_specs/voxcpm1.json index 66376a33c..423545b32 100644 --- a/model_specs/voxcpm1.json +++ b/model_specs/voxcpm1.json @@ -46,21 +46,21 @@ "type": "int", "description": "Maximum MiniCPM output tokens.", "required": false, - "default": 1024 + "default": 4096 }, { "name": "min_tokens", "type": "int", "description": "Minimum MiniCPM output tokens before an EOS stop is honored.", "required": false, - "default": 0 + "default": 2 }, { "name": "num_inference_steps", "type": "int", "description": "CFM diffusion sampling steps.", "required": false, - "default": 50 + "default": 10 }, { "name": "guidance_scale", @@ -81,7 +81,7 @@ "type": "int", "description": "Maximum bad-case retry count.", "required": false, - "default": 2 + "default": 3 }, { "name": "retry_badcase_ratio_threshold", diff --git a/webui/configs/model_params.json b/webui/configs/model_params.json index 68890fdfa..33b69d601 100644 --- a/webui/configs/model_params.json +++ b/webui/configs/model_params.json @@ -1,48 +1,59 @@ { "echo_tts": [ - {"name": "num_inference_steps", "type": "slider", "label": "num_inference_steps", "label_en": "Sampling steps", "default": 40, "minimum": 8, "maximum": 40, "step": 1, "precision": 0, "info": "Euler sampler steps."}, + {"name": "num_inference_steps", "type": "slider", "label": "num_inference_steps", "label_en": "Sampling steps", "default": 40, "minimum": 8, "maximum": 120, "step": 1, "precision": 0, "info": "Euler sampler steps.", "info_en": "Euler sampler steps. No upper bound in the model; higher is slower and steadier."}, {"name": "text_guidance_scale", "type": "slider", "label": "text_guidance_scale", "label_en": "Text guidance", "default": 3.0, "minimum": 0.0, "maximum": 10.0, "step": 0.1}, {"name": "speaker_guidance_scale", "type": "slider", "label": "speaker_guidance_scale", "label_en": "Speaker guidance", "default": 8.0, "minimum": 0.0, "maximum": 15.0, "step": 0.1}, {"name": "truncation_factor", "type": "slider", "label": "truncation_factor", "label_en": "Noise truncation", "default": 0.8, "minimum": 0.0, "maximum": 1.0, "step": 0.05}, {"name": "guidance_interval", "type": "slider", "label": "guidance_interval", "label_en": "Guidance interval", "default": 1, "minimum": 1, "maximum": 3, "step": 1, "precision": 0, "info": "Refresh the unconditional CFG lanes every Nth guided step. Higher is faster and works best with more steps; 1 is highest fidelity."}, - {"name": "reference_duration_sec", "type": "slider", "label": "reference_duration_sec", "label_en": "Reference trim (s)", "default": 15.0, "minimum": 1.0, "maximum": 60.0, "step": 1.0, "info": "Trim the speaker reference before encoding. Around 10 s usually clones best."}, - {"name": "seed", "type": "number", "label": "seed", "label_en": "Seed", "default": 0, "minimum": 0, "step": 1, "precision": 0} + {"name": "reference_duration_sec", "type": "slider", "label": "reference_duration_sec", "label_en": "Reference trim (s)", "default": 15.0, "minimum": 1.0, "maximum": 60.0, "step": 1.0, "info": "Trim the speaker reference before encoding. Around 10 s usually clones best."} ], - "_comment": "WebUI TTS 高级参数控件配置:按模型 family 动态生成控件(gr.render)。每项字段:name=选项键(随请求 options 透传给模型);type=slider|number|bool|text|choice;label/info=显示文案;default=默认值(应等于模型默认,已按 src/models//*.cpp 校对);minimum/maximum/step=数值范围;precision=0 表示整数;choices=下拉候选。规则:只有被用户改动过的控件值才会随请求发送;seed/max_tokens 已有专用输入框,勿在此重复;参考文本用『参考文本』框(reference_text);文件路径/parity 类参数(如 *_noise_file)未纳入,可用『其它参数(JSON)』兜底框传。", + + "_comment": "WebUI 模型参数控件配置:按 catalog 条目 id 或 family 生成控件。每项字段:name=选项键(随请求 options 透传给模型);type=slider|number|bool|text|choice;label/label_en、info/info_en、placeholder/placeholder_en=显示文案;default=默认值;minimum/maximum/step=数值范围;precision=0 表示整数;choices=下拉候选。 BEHAVIOUR: the native UI seeds every control from its `default` and sends the whole set with every request (webui/native/src/routes/+page.svelte resetParams/requestOptions), so a `default` here is an UNCONDITIONAL OVERRIDE of the model's own default, never a fallback. Every default must therefore be read from the C++ (src/models//, src/community_models//) or from the packaged config the C++ derives it from. To let the model or its checkpoint decide, OMIT `default`: the control then sends \"\", and runtime::find_option_match (src/framework/runtime/options.cpp:151) ignores empty values, so the option counts as unset. Use type=number/text for those so the widget renders blank. `minimum` must not sit below the C++ guard - a slider that can reach an illegal value produces a 500. KEYS: ~27 families call runtime::validate_spec_backed_request_options (include/engine/framework/runtime/spec_backed_model.h:59) and hard-reject any key absent from model_specs/.json options.request - the KEY is checked even when the value is empty. Spec min/max are documentation only and are never enforced. L10N: catalog.ts discards any label/info/placeholder containing Han characters, so every entry needs the _en variant or it renders as raw snake_case. 勿在此重复:seed/max_tokens 已有专用输入框(服务端用顶层 seed 覆盖 options[\"seed\"],app/server/runtime.cpp:1876);参考文本用『参考文本』框(reference_text);语种用顶层 language 框。文件路径/说话人向量/parity 类参数(如 *_noise_file、speaker_embedding、multi_reference_cond)未纳入,可用『其它参数(JSON)』兜底框传。", "qwen3_tts": [ - {"name": "temperature", "type": "slider", "label": "temperature", "default": 0.9, "minimum": 0.0, "maximum": 2.0, "step": 0.05}, + {"name": "temperature", "type": "slider", "label": "temperature", "default": 0.9, "minimum": 0.05, "maximum": 2.0, "step": 0.05, "info_en": "Must be above 0 while do_sample is on."}, {"name": "top_k", "type": "number", "label": "top_k", "default": 50, "minimum": 0, "step": 1, "precision": 0}, {"name": "top_p", "type": "slider", "label": "top_p", "default": 1.0, "minimum": 0.0, "maximum": 1.0, "step": 0.01}, {"name": "repetition_penalty", "type": "slider", "label": "repetition_penalty", "default": 1.05, "minimum": 1.0, "maximum": 2.0, "step": 0.01}, {"name": "do_sample", "type": "bool", "label": "do_sample", "default": true}, - {"name": "instruct", "type": "text", "label": "instruct(仅 VoiceDesign/CustomVoice)", "default": "", "placeholder": "风格/音色指令,Base 版忽略"}, - {"name": "speaker", "type": "text", "label": "speaker(仅 CustomVoice)", "default": "", "placeholder": "内置音色名,其它版忽略"} + {"name": "subtalker_do_sample", "type": "bool", "label": "subtalker_do_sample", "label_en": "Sub-talker: sample", "default": true}, + {"name": "subtalker_temperature", "type": "slider", "label": "subtalker_temperature", "label_en": "Sub-talker: temperature", "default": 0.9, "minimum": 0.05, "maximum": 2.0, "step": 0.05, "info_en": "Must be above 0 while subtalker_do_sample is on."}, + {"name": "subtalker_top_k", "type": "number", "label": "subtalker_top_k", "label_en": "Sub-talker: top-k", "default": 50, "minimum": 0, "step": 1, "precision": 0}, + {"name": "subtalker_top_p", "type": "slider", "label": "subtalker_top_p", "label_en": "Sub-talker: top-p", "default": 1.0, "minimum": 0.0, "maximum": 1.0, "step": 0.01}, + {"name": "x_vector_only_mode", "type": "bool", "label": "x_vector_only_mode(仅 VoiceClone)", "label_en": "x_vector_only_mode (VoiceClone only)", "default": false, "info_en": "Condition on the speaker embedding alone instead of in-context reference audio. Ignored by other variants."}, + {"name": "instruct", "type": "text", "label": "instruct(仅 VoiceDesign/CustomVoice)", "label_en": "instruct (VoiceDesign / CustomVoice only)", "default": "", "placeholder": "风格/音色指令,Base 版忽略", "placeholder_en": "Style or timbre instruction; ignored by Base models"}, + {"name": "speaker", "type": "text", "label": "speaker(仅 CustomVoice)", "label_en": "speaker (CustomVoice only)", "default": "", "placeholder": "内置音色名,其它版忽略", "placeholder_en": "Built-in voice name; ignored by other variants"} ], "vibevoice": [ - {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 10, "minimum": 1, "step": 1, "precision": 0, "info": "扩散步数(官方默认 10),越大越慢越稳"}, - {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 1.3, "minimum": 0.0, "maximum": 5.0, "step": 0.1, "info": "CFG 引导强度"}, - {"name": "max_length_times", "type": "number", "label": "max_length_times", "default": 2.0, "minimum": 0.1, "step": 0.1, "info": "最大输出长度倍数"}, + {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "minimum": 1, "step": 1, "precision": 0, "info": "留空=用模型自带的 ddpm_num_inference_steps(随包,7B 为 20)", "info_en": "Blank uses the packaged model's own ddpm_num_inference_steps (20 in the shipped 7B). Setting a value overrides it for every request."}, + {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 1.3, "minimum": 0.0, "maximum": 5.0, "step": 0.1, "info": "CFG 引导强度", "info_en": "Classifier-free guidance strength."}, + {"name": "max_length_times", "type": "number", "label": "max_length_times", "default": 2.0, "minimum": 0.1, "step": 0.1, "info": "最大输出长度倍数", "info_en": "Cap on output length as a multiple of the estimated token count."}, {"name": "temperature", "type": "slider", "label": "temperature", "default": 1.0, "minimum": 0.05, "maximum": 2.0, "step": 0.05}, {"name": "top_p", "type": "slider", "label": "top_p", "default": 1.0, "minimum": 0.05, "maximum": 1.0, "step": 0.01}, + {"name": "top_k", "type": "number", "label": "top_k", "label_en": "Top-k", "default": 50, "minimum": 0, "step": 1, "precision": 0, "info_en": "Must be non-negative; 0 disables top-k."}, {"name": "do_sample", "type": "bool", "label": "do_sample", "default": false}, - {"name": "voice_samples", "type": "text", "label": "voice_samples(多说话人,逗号分隔 wav,≤4)", "default": "", "placeholder": "D:/a.wav,D:/b.wav — 用此项时勿再上传参考音色"} + {"name": "voice_samples", "type": "text", "label": "voice_samples(多说话人,逗号分隔 wav,≤4)", "label_en": "voice_samples (multi-speaker: comma-separated WAVs, max 4)", "default": "", "placeholder": "D:/a.wav,D:/b.wav — 用此项时勿再上传参考音色", "placeholder_en": "/a.wav,/b.wav - do not also upload a reference voice when using this"} ], "voxcpm2": [ - {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 10, "minimum": 1, "step": 1, "precision": 0, "info": "CFM/DiT 步数"}, + {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 10, "minimum": 1, "step": 1, "precision": 0, "info": "CFM/DiT 步数", "info_en": "CFM/DiT sampling steps."}, {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 2.0, "minimum": 0.0, "maximum": 5.0, "step": 0.1}, {"name": "text_chunk_mode", "type": "choice", "label": "text_chunk_mode", "default": "tag_aware", "choices": ["default", "tag_aware", "japanese", "endline"]}, {"name": "min_tokens", "type": "number", "label": "min_tokens", "default": 2, "minimum": 0, "step": 1, "precision": 0}, - {"name": "retry_badcase", "type": "bool", "label": "retry_badcase(自动重试异常输出)", "default": true} + {"name": "retry_badcase", "type": "bool", "label": "retry_badcase(自动重试异常输出)", "label_en": "retry_badcase (auto-retry bad generations)", "default": true}, + {"name": "retry_badcase_max_times", "type": "number", "label": "retry_badcase_max_times(最大重试次数)", "label_en": "Retry attempts", "default": 3, "minimum": 1, "step": 1, "precision": 0, "info_en": "Must be positive."}, + {"name": "retry_badcase_ratio_threshold", "type": "number", "label": "retry_badcase_ratio_threshold(时长/字数比阈值)", "label_en": "Retry length-ratio threshold", "default": 6.0, "minimum": 0.1, "step": 0.5, "info_en": "Audio-seconds-per-character ratio above which a take is treated as a bad case. Must be positive."} ], "voxcpm1": [ - {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 10, "minimum": 1, "step": 1, "precision": 0, "info": "CFM/DiT 步数"}, + {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 10, "minimum": 1, "step": 1, "precision": 0, "info": "CFM/DiT 步数", "info_en": "CFM/DiT sampling steps."}, {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 2.0, "minimum": 0.0, "maximum": 5.0, "step": 0.1}, + {"name": "text_chunk_mode", "type": "choice", "label": "text_chunk_mode", "label_en": "Text chunk mode", "default": "tag_aware", "choices": ["default", "tag_aware", "japanese", "endline"]}, {"name": "min_tokens", "type": "number", "label": "min_tokens", "default": 2, "minimum": 0, "step": 1, "precision": 0}, - {"name": "retry_badcase", "type": "bool", "label": "retry_badcase(自动重试异常输出)", "default": true} + {"name": "retry_badcase", "type": "bool", "label": "retry_badcase(自动重试异常输出)", "label_en": "retry_badcase (auto-retry bad generations)", "default": true}, + {"name": "retry_badcase_max_times", "type": "number", "label": "retry_badcase_max_times(最大重试次数)", "label_en": "Retry attempts", "default": 3, "minimum": 1, "step": 1, "precision": 0, "info_en": "Must be positive."}, + {"name": "retry_badcase_ratio_threshold", "type": "number", "label": "retry_badcase_ratio_threshold(时长/字数比阈值)", "label_en": "Retry length-ratio threshold", "default": 6.0, "minimum": 0.1, "step": 0.5, "info_en": "Audio-seconds-per-character ratio above which a take is treated as a bad case. Must be positive."} ], "miotts": [ @@ -50,14 +61,17 @@ {"name": "top_k", "type": "number", "label": "top_k", "default": 50, "minimum": 0, "step": 1, "precision": 0}, {"name": "top_p", "type": "slider", "label": "top_p", "default": 1.0, "minimum": 0.0, "maximum": 1.0, "step": 0.01}, {"name": "repetition_penalty", "type": "slider", "label": "repetition_penalty", "default": 1.0, "minimum": 1.0, "maximum": 1.5, "step": 0.01}, - {"name": "best_of_n", "type": "number", "label": "best_of_n(候选数,>1 自动开启)", "default": 1, "minimum": 1, "maximum": 8, "step": 1, "precision": 0} + {"name": "miotts.best_of_n", "type": "number", "label": "miotts.best_of_n(候选数,>1 自动开启)", "label_en": "best_of_n (candidate count; >1 enables best-of-N selection)", "default": 1, "minimum": 1, "maximum": 8, "step": 1, "precision": 0} ], "chatterbox": [ - {"name": "exaggeration", "type": "slider", "label": "exaggeration", "default": 0.5, "minimum": 0.0, "maximum": 2.0, "step": 0.05, "info": "改动后需重新『加载模型』才生效"}, - {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 0.5, "minimum": 0.0, "maximum": 1.0, "step": 0.05, "info": "改动后需重新『加载模型』才生效"}, + {"name": "exaggeration", "type": "slider", "label": "exaggeration", "default": 0.5, "minimum": 0.0, "maximum": 2.0, "step": 0.05, "info_en": "Applied at model load; reload the model after changing it."}, + {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 0.5, "minimum": 0.0, "maximum": 1.0, "step": 0.05, "info_en": "Applied at model load; reload the model after changing it."}, {"name": "temperature", "type": "slider", "label": "temperature", "default": 0.8, "minimum": 0.0, "maximum": 2.0, "step": 0.05}, - {"name": "repetition_penalty", "type": "slider", "label": "repetition_penalty", "default": 1.2, "minimum": 1.0, "maximum": 2.0, "step": 0.01} + {"name": "repetition_penalty", "type": "slider", "label": "repetition_penalty", "default": 1.2, "minimum": 1.0, "maximum": 2.0, "step": 0.01}, + {"name": "min_p", "type": "slider", "label": "min_p", "label_en": "Min-p", "default": 0.05, "minimum": 0.0, "maximum": 1.0, "step": 0.01, "info_en": "Chatterbox's real truncation filter: tokens below max_prob * min_p are masked. top_p defaults to 1.0 and is a deliberate no-op."}, + {"name": "top_p", "type": "slider", "label": "top_p", "label_en": "Top-p", "default": 1.0, "minimum": 0.0, "maximum": 1.0, "step": 0.01, "info_en": "Inert at 1.0 by design; lower it only if you also raise min_p out of the way."}, + {"name": "s3gen_cfg_rate", "type": "slider", "label": "s3gen_cfg_rate", "label_en": "S3Gen guidance", "default": 0.7, "minimum": 0.0, "maximum": 2.0, "step": 0.05} ], "chatterbox-vc": [ @@ -69,23 +83,38 @@ {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 32, "minimum": 1, "step": 1, "precision": 0}, {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 2.0, "minimum": 0.0, "maximum": 5.0, "step": 0.1}, {"name": "speed", "type": "slider", "label": "speed", "default": 1.0, "minimum": 0.5, "maximum": 2.0, "step": 0.05}, - {"name": "instruct", "type": "text", "label": "instruct(风格/音色指令)", "default": "", "placeholder": "如:以轻快的语气朗读"} + {"name": "instruct", "type": "text", "label": "instruct(风格/音色指令)", "label_en": "instruct (style / voice instruction)", "default": "", "placeholder": "如:以轻快的语气朗读", "placeholder_en": "e.g. read this in a bright, upbeat tone"}, + {"name": "reference_max_seconds", "type": "number", "label": "reference_max_seconds(参考音频最长秒数)", "label_en": "Reference cap (s)", "default": 15.0, "minimum": 0.0, "step": 1.0, "info": "参考超过约 15 s 后音色克隆明显劣化;0=不限制", "info_en": "Cloning quality collapses past roughly 15 s of reference speech; the clip is cut back to the last pause inside this window. 0 disables the limit."}, + {"name": "reference_pad_ms", "type": "number", "label": "reference_pad_ms", "label_en": "Reference silence pad (ms)", "default": 150, "minimum": 0, "step": 10, "precision": 0, "info_en": "Digital silence written onto both ends of a trimmed reference. Must be non-negative."}, + {"name": "t_shift", "type": "slider", "label": "t_shift", "label_en": "Timestep shift", "default": 0.1, "minimum": 0.0, "maximum": 1.0, "step": 0.01}, + {"name": "class_temperature", "type": "slider", "label": "class_temperature", "label_en": "Class temperature", "default": 0.0, "minimum": 0.0, "maximum": 2.0, "step": 0.05, "info_en": "0 picks the argmax token; above 0 samples the codebook class."}, + {"name": "position_temperature", "type": "slider", "label": "position_temperature", "label_en": "Position temperature", "default": 5.0, "minimum": 0.0, "maximum": 20.0, "step": 0.5, "info_en": "0 disables Gumbel sampling of the unmasking order."}, + {"name": "layer_penalty_factor", "type": "slider", "label": "layer_penalty_factor", "label_en": "Layer penalty", "default": 5.0, "minimum": 0.0, "maximum": 20.0, "step": 0.5, "info_en": "Score penalty per codebook layer when choosing which position to unmask next."}, + {"name": "denoise", "type": "bool", "label": "denoise", "label_en": "Denoise reference", "default": true}, + {"name": "preprocess_prompt", "type": "bool", "label": "preprocess_prompt", "label_en": "Preprocess reference", "default": true}, + {"name": "postprocess_output", "type": "bool", "label": "postprocess_output", "label_en": "Postprocess output", "default": true}, + {"name": "audio_chunk_threshold", "type": "number", "label": "audio_chunk_threshold", "label_en": "Long-form chunk threshold (s)", "default": 30.0, "minimum": 0.0, "step": 1.0}, + {"name": "audio_chunk_duration", "type": "number", "label": "audio_chunk_duration", "label_en": "Long-form chunk length (s)", "default": 15.0, "minimum": 0.0, "step": 1.0}, + {"name": "text_chunk_mode", "type": "choice", "label": "text_chunk_mode", "label_en": "Text chunk mode", "default": "tag_aware", "choices": ["default", "tag_aware", "japanese", "endline"]} ], "sense_asr": [ {"name": "enable_itn", "type": "bool", "label": "enable_itn(逆文本规范化)", "label_en": "enable_itn", "default": true}, {"name": "keep_tags", "type": "bool", "label": "keep_tags(保留语言/情绪/事件标签)", "label_en": "keep_tags", "default": false}, - {"name": "audio_chunk_mode", "type": "choice", "label": "audio_chunk_mode", "default": "auto", "choices": ["auto", "fixed", "none"]}, - {"name": "audio_chunk_duration_sec", "type": "number", "label": "audio_chunk_duration_sec", "default": 30, "minimum": 0.001, "step": 1} + {"name": "audio_chunk_mode", "type": "choice", "label": "audio_chunk_mode", "label_en": "Audio chunk mode", "default": "auto", "choices": ["auto", "fixed", "vad", "none"], "info_en": "vad segments on detected speech; auto and vad share the same code path."}, + {"name": "audio_chunk_duration_sec", "type": "number", "label": "audio_chunk_duration_sec", "label_en": "Audio chunk length (s)", "default": 30, "minimum": 0.001, "step": 1} ], "pocket_tts": [ - {"name": "frames_after_eos", "type": "number", "label": "frames_after_eos(-1=自动)", "default": -1, "minimum": -1, "step": 1, "precision": 0} + {"name": "frames_after_eos", "type": "number", "label": "frames_after_eos(-1=自动)", "label_en": "frames_after_eos (-1 = automatic)", "default": -1, "minimum": -1, "step": 1, "precision": 0} ], "neutts": [ {"name": "voice_id", "type": "choice", "label": "voice_id(内置音色)", "label_en": "voice_id (built-in voice)", "default": "emily", "choices": ["dave", "emily", "greta", "jo", "juliette", "mateo", "paul", "sophie", "steven"]}, - {"name": "emotion", "type": "choice", "label": "emotion(情绪)", "label_en": "emotion", "default": "neutral", "choices": ["angry", "disgusted", "sad", "happy", "fearful", "neutral", "surprised"]} + {"name": "emotion", "type": "choice", "label": "emotion(情绪)", "label_en": "emotion", "default": "neutral", "choices": ["angry", "disgusted", "sad", "happy", "fearful", "neutral", "surprised"]}, + {"name": "temperature", "type": "slider", "label": "temperature", "label_en": "Temperature", "default": 1.0, "minimum": 0.05, "maximum": 2.0, "step": 0.05, "info_en": "Must be positive."}, + {"name": "top_k", "type": "number", "label": "top_k", "label_en": "Top-k", "default": 50, "minimum": 1, "step": 1, "precision": 0, "info_en": "Must be positive."}, + {"name": "min_tokens", "type": "number", "label": "min_tokens", "label_en": "Min speech tokens", "default": 50, "minimum": 0, "step": 1, "precision": 0, "info_en": "Minimum tokens generated before an end-of-speech token may stop decoding."} ], "magpie_tts": [ @@ -111,16 +140,16 @@ {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 2.5, "minimum": 0.0, "maximum": 8.0, "step": 0.1}, {"name": "spatio_temporal_guidance_scale", "type": "slider", "label": "spatio_temporal_guidance_scale", "default": 1.5, "minimum": 0.0, "maximum": 5.0, "step": 0.1}, {"name": "duration_scale", "type": "slider", "label": "duration_scale(自动估时倍率)", "label_en": "duration_scale", "default": 1.1, "minimum": 0.5, "maximum": 2.0, "step": 0.05}, - {"name": "reference_duration_sec", "type": "number", "label": "reference_duration_sec(参考音频裁剪/重复秒数)", "label_en": "reference_duration_sec", "default": 10.0, "minimum": 0.0, "step": 0.5}, - {"name": "guidance_rescale", "type": "text", "label": "guidance_rescale", "default": "auto", "placeholder": "auto 或数值"}, - {"name": "audio_chunk_threshold_sec", "type": "number", "label": "audio_chunk_threshold_sec(长文本阈值)", "label_en": "audio_chunk_threshold_sec", "default": 45.0, "minimum": 0.0, "step": 1.0}, - {"name": "audio_chunk_duration_sec", "type": "number", "label": "audio_chunk_duration_sec(长文本分段目标时长)", "label_en": "audio_chunk_duration_sec", "default": 37.0, "minimum": 0.0, "step": 1.0}, + {"name": "reference_duration_sec", "type": "number", "label": "reference_duration_sec(参考音频裁剪/重复秒数)", "label_en": "reference_duration_sec", "default": 10.0, "minimum": 0.5, "step": 0.5, "info_en": "Must be positive."}, + {"name": "guidance_rescale", "type": "text", "label": "guidance_rescale", "default": "auto", "placeholder": "auto 或数值", "placeholder_en": "auto, or a number"}, + {"name": "audio_chunk_threshold_sec", "type": "number", "label": "audio_chunk_threshold_sec(长文本阈值)", "label_en": "audio_chunk_threshold_sec", "default": 45.0, "minimum": 1.0, "step": 1.0, "info_en": "Must be positive."}, + {"name": "audio_chunk_duration_sec", "type": "number", "label": "audio_chunk_duration_sec(长文本分段目标时长)", "label_en": "audio_chunk_duration_sec", "default": 37.0, "minimum": 1.0, "step": 1.0, "info_en": "Must be positive."}, {"name": "cross_fade_duration_sec", "type": "number", "label": "cross_fade_duration_sec(分段交叉淡化)", "label_en": "cross_fade_duration_sec", "default": 0.05, "minimum": 0.0, "step": 0.01} ], "confucius4_tts": [ - {"name": "temperature", "type": "slider", "label": "temperature", "default": 0.8, "minimum": 0.0, "maximum": 2.0, "step": 0.05}, - {"name": "top_p", "type": "slider", "label": "top_p", "default": 0.8, "minimum": 0.0, "maximum": 1.0, "step": 0.01}, + {"name": "temperature", "type": "slider", "label": "temperature", "default": 0.8, "minimum": 0.05, "maximum": 2.0, "step": 0.05, "info_en": "Must be positive."}, + {"name": "top_p", "type": "slider", "label": "top_p", "default": 0.8, "minimum": 0.01, "maximum": 1.0, "step": 0.01, "info_en": "Must be within (0, 1]."}, {"name": "top_k", "type": "number", "label": "top_k", "default": 30, "minimum": 1, "step": 1, "precision": 0}, {"name": "num_beams", "type": "number", "label": "num_beams", "default": 3, "minimum": 1, "step": 1, "precision": 0}, {"name": "repetition_penalty", "type": "slider", "label": "repetition_penalty", "default": 10.0, "minimum": 0.0, "maximum": 20.0, "step": 0.1}, @@ -134,27 +163,28 @@ ], "ace_step": [ - {"name": "route", "type": "choice", "label": "route(操作类型)", "default": "text2music", "choices": ["text2music", "complete", "lego", "extract", "cover", "cover-nofsq", "repaint", "remix"], "info": "cover/remix=换词翻唱,非 text2music 需上传源音频;详见 webui/README.md"}, - {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 8, "minimum": 1, "maximum": 20, "step": 1, "precision": 0, "info": "扩散步数(turbo 上限 20);remix 路由不填时默认 16,其他路由默认 8"}, - {"name": "shift", "type": "slider", "label": "shift(时间步弯曲)", "default": 3.0, "minimum": 1.0, "maximum": 5.0, "step": 0.5, "info": "原版 turbo 默认 3.0;1.0 会明显劣化 remix 换词咬字"}, - {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 1.0, "minimum": 0.0, "maximum": 5.0, "step": 0.1}, - {"name": "audio_cover_strength", "type": "slider", "label": "【cover】audio_cover_strength", "default": 1.0, "minimum": 0.0, "maximum": 1.0, "step": 0.05, "info": "1=贴近原曲,0=自由发挥;建议 0.5"}, - {"name": "cover_noise_strength", "type": "slider", "label": "【cover】cover_noise_strength", "default": 0.0, "minimum": 0.0, "maximum": 1.0, "step": 0.05, "info": "保旋律强度;推荐 0.1~0.25"}, - {"name": "source_caption", "type": "text", "label": "【remix】source_caption", "default": "", "placeholder": "源歌曲描述;『🔍 分析』自动填"}, - {"name": "source_lyrics", "type": "text", "lines": 4, "label": "【remix】source_lyrics", "default": "", "placeholder": "源歌曲原歌词;『🔍 分析』自动填"}, - {"name": "flow_edit_n_min", "type": "slider", "label": "【remix】flow_edit_n_min", "default": 0.0, "minimum": 0.0, "maximum": 1.0, "step": 0.05, "info": "调大更保源曲、换词更弱"}, - {"name": "flow_edit_n_max", "type": "slider", "label": "【remix】flow_edit_n_max", "default": 1.0, "minimum": 0.0, "maximum": 1.0, "step": 0.05, "info": "唱不出新歌词时降到 0.7~0.9"}, - {"name": "flow_edit_n_avg", "type": "number", "label": "【remix】flow_edit_n_avg", "default": 2, "minimum": 1, "maximum": 4, "step": 1, "precision": 0, "info": "每步多次采样取平均(remix 默认 2);1=最快"}, - {"name": "bpm", "type": "number", "label": "【曲谱】BPM", "default": 0, "minimum": 0, "step": 1, "precision": 0, "info": "0=不指定"}, - {"name": "keyscale", "type": "text", "label": "【曲谱】keyscale", "default": "", "placeholder": "如 F major"}, - {"name": "timesignature", "type": "text", "label": "【曲谱】timesignature", "default": "", "placeholder": "如 4"} + {"name": "route", "type": "choice", "label": "route(操作类型)", "label_en": "route (task)", "default": "text2music", "choices": ["text2music", "complete", "lego", "extract", "cover", "cover-nofsq", "repaint"], "info": "cover/cover-nofsq=换词翻唱;非 text2music 需上传源音频;详见 webui/README.md", "info_en": "cover and cover-nofsq re-sing new lyrics. Every route except text2music needs a source audio upload; see webui/README.md."}, + {"name": "negative_prompt", "type": "text", "label": "negative_prompt", "label_en": "Negative prompt", "default": "", "placeholder_en": "Blank uses the model's \"NO USER INPUT\" placeholder"}, + {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 8, "minimum": 1, "maximum": 20, "step": 1, "precision": 0, "info": "扩散步数;turbo 权重会被静默限制为 8", "info_en": "Diffusion steps. Turbo checkpoints are silently clamped to 8; only base checkpoints use more."}, + {"name": "shift", "type": "slider", "label": "shift(时间步弯曲)", "label_en": "shift (timestep curve)", "default": 1.0, "minimum": 1.0, "maximum": 5.0, "step": 0.5, "info": "官方默认 1.0;extract 路由由模型自动改用 3.0", "info_en": "Model default is 1.0. The extract route sets 3.0 itself, so leaving this at 1.0 no longer overrides it."}, + {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "label_en": "Guidance scale", "default": 1.0, "minimum": 0.0, "maximum": 5.0, "step": 0.1}, + {"name": "audio_cover_strength", "type": "slider", "label": "【cover】audio_cover_strength", "label_en": "audio_cover_strength (cover routes)", "default": 1.0, "minimum": 0.0, "maximum": 1.0, "step": 0.05, "info": "1=贴近原曲,0=自由发挥;建议 0.5", "info_en": "1 hugs the source track, 0 improvises. Around 0.5 works well."}, + {"name": "cover_noise_strength", "type": "slider", "label": "【cover】cover_noise_strength", "label_en": "cover_noise_strength (cover routes)", "default": 0.0, "minimum": 0.0, "maximum": 1.0, "step": 0.05, "info": "保旋律强度;推荐 0.1~0.25", "info_en": "Melody retention. 0.1 to 0.25 is the usual range."}, + {"name": "bpm", "type": "number", "label": "【曲谱】BPM", "label_en": "BPM", "default": 0, "minimum": 0, "step": 1, "precision": 0, "info": "0=不指定", "info_en": "0 leaves the tempo unspecified."}, + {"name": "keyscale", "type": "text", "label": "【曲谱】keyscale", "label_en": "Key / scale", "default": "", "placeholder": "如 F major", "placeholder_en": "e.g. F major"}, + {"name": "timesignature", "type": "text", "label": "【曲谱】timesignature", "label_en": "Time signature", "default": "", "placeholder": "如 4", "placeholder_en": "e.g. 4"} ], "minimax_music3": [ {"name": "num_inference_steps", "type": "number", "label": "Flow steps per window", "default": 30, "minimum": 1, "maximum": 200, "step": 1, "precision": 0, "info": "Flow-matching Euler steps per 200-frame denoising window."}, {"name": "guidance_scale", "type": "slider", "label": "Flow guidance scale", "default": 1.7, "minimum": 0.0, "maximum": 10.0, "step": 0.1}, {"name": "ar_guidance_scale", "type": "slider", "label": "AR guidance scale", "default": 1.5, "minimum": 0.0, "maximum": 10.0, "step": 0.1, "info": "Classifier-free guidance of the semantic and residual code sampling."}, - {"name": "top_k", "type": "number", "label": "top_k", "default": 50, "minimum": 1, "maximum": 1024, "step": 1, "precision": 0} + {"name": "top_k", "type": "number", "label": "top_k", "default": 50, "minimum": 1, "maximum": 1024, "step": 1, "precision": 0}, + {"name": "ensemble_takes", "type": "number", "label": "ensemble_takes", "label_en": "Ensemble takes", "default": 1, "minimum": 1, "maximum": 16, "step": 1, "precision": 0, "info_en": "Decode N independent takes in one batched pass (seeds seed, seed+1, ...). Extra takes are returned as take_01...take_NN."}, + {"name": "ensemble_prefix_frames", "type": "number", "label": "ensemble_prefix_frames", "label_en": "Ensemble intro lock (frames)", "default": 0, "minimum": 0, "step": 10, "precision": 0, "info_en": "Decode the first N frames once and share them across takes before they diverge. 0 disables the fork."}, + {"name": "flow_uncond_interval", "type": "number", "label": "flow_uncond_interval", "label_en": "Flow CFG reuse interval", "default": 1, "minimum": 1, "step": 1, "precision": 0, "info_en": "Above 1 reuses the cached guidance delta on intermediate steps: faster, slightly off the exact reference trajectory. 1 is exact."}, + {"name": "flow_uncond_warmup", "type": "number", "label": "flow_uncond_warmup", "label_en": "Flow CFG warmup steps", "default": 2, "minimum": 0, "step": 1, "precision": 0, "info_en": "Leading steps that always evaluate the unconditional branch when reuse is on."}, + {"name": "flow_chunk_hop_frames", "type": "number", "label": "flow_chunk_hop_frames", "label_en": "Flow chunk hop (frames)", "default": 0, "minimum": 0, "step": 10, "precision": 0, "info_en": "0 uses the model config's hop of 100. A larger hop means fewer chunks and less double-denoising."} ], "minimax_h3": [ @@ -163,29 +193,35 @@ {"name": "guidance_scale", "type": "slider", "label": "Guidance scale", "default": 1.0, "minimum": 0.0, "maximum": 5.0, "step": 0.1}, {"name": "sampler", "type": "choice", "label": "Sampler", "default": "euler", "choices": ["euler", "res_multistep", "dpmpp_2m", "unipc"]}, {"name": "dit_acceleration", "type": "choice", "label": "DiT acceleration", "default": "none", "choices": ["none", "spectrum", "first_block_cache"], "info": "None uses the quality-first full-DiT path. Acceleration modes are experimental and may distort some outputs."}, - {"name": "return_video", "type": "bool", "label": "Decode video", "default": false, "info": "Disabled by default to reduce memory use and return audio only."} + {"name": "return_video", "type": "bool", "label": "Decode video", "default": false, "info": "Disabled by default to reduce memory use and return audio only."}, + {"name": "negative_prompt", "type": "text", "label": "negative_prompt", "label_en": "Negative prompt", "default": "", "placeholder_en": "Blank uses the model default"} ], "stable_audio": [ - {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 8, "minimum": 1, "step": 1, "precision": 0, "info": "RF 扩散步数"}, + {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 8, "minimum": 1, "step": 1, "precision": 0, "info": "RF 扩散步数", "info_en": "Rectified-flow sampling steps."}, {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 1.0, "minimum": 0.0, "maximum": 5.0, "step": 0.1}, - {"name": "audio_input_kind", "type": "choice", "label": "audio_input_kind(仅上传源音频时生效)", "default": "init_audio", "choices": ["init_audio", "inpaint_audio"]}, - {"name": "init_noise_level", "type": "slider", "label": "init_noise_level(init_audio 强度)", "default": 1.0, "minimum": 0.0, "maximum": 1.0, "step": 0.05} + {"name": "audio_input_kind", "type": "choice", "label": "audio_input_kind(仅上传源音频时生效)", "label_en": "audio_input_kind (only used when a source audio file is uploaded)", "default": "init_audio", "choices": ["init_audio", "inpaint_audio"]}, + {"name": "init_noise_level", "type": "slider", "label": "init_noise_level(init_audio 强度)", "label_en": "init_noise_level (init_audio strength)", "default": 1.0, "minimum": 0.0, "maximum": 1.0, "step": 0.05}, + {"name": "negative_prompt", "type": "text", "label": "negative_prompt", "label_en": "Negative prompt", "default": "", "placeholder_en": "Blank applies no negative conditioning"}, + {"name": "sampler", "type": "choice", "label": "sampler", "label_en": "Sampler", "default": "pingpong", "choices": ["pingpong", "euler"], "info_en": "Only pingpong and euler are accepted; the dpmpp entries in the CLI help text are rejected by the parser."} ], "seed_vc": [ - {"name": "route", "type": "choice", "label": "route(转换路径)", "default": "", "choices": ["", "v2_vc", "v1_whisper_bigvgan_vc", "v1_xlsr_hift_vc", "v1_svc"], "info": "留空=按任务默认"}, - {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 30, "minimum": 1, "step": 1, "precision": 0, "info": "CFM 扩散步数"}, - {"name": "length_adjust", "type": "slider", "label": "length_adjust(时长伸缩)", "default": 1.0, "minimum": 0.5, "maximum": 2.0, "step": 0.05}, - {"name": "intelligibility_cfg_rate", "type": "slider", "label": "intelligibility_cfg_rate(仅 v2_vc)", "default": 0.7, "minimum": 0.0, "maximum": 1.0, "step": 0.05}, - {"name": "similarity_cfg_rate", "type": "slider", "label": "similarity_cfg_rate(仅 v2_vc)", "default": 0.7, "minimum": 0.0, "maximum": 1.0, "step": 0.05}, - {"name": "inference_cfg_rate", "type": "slider", "label": "inference_cfg_rate(仅 v1 路径)", "default": 0.7, "minimum": 0.0, "maximum": 1.0, "step": 0.05} + {"name": "route", "type": "choice", "label": "route(转换路径)", "label_en": "route (conversion path)", "default": "", "choices": ["", "v2_vc", "v1_whisper_bigvgan_vc", "v1_xlsr_hift_vc", "v1_svc"], "info": "留空=按任务默认", "info_en": "Blank = pick the default path for the selected task."}, + {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 30, "minimum": 1, "step": 1, "precision": 0, "info": "CFM 扩散步数", "info_en": "CFM diffusion steps."}, + {"name": "length_adjust", "type": "slider", "label": "length_adjust(时长伸缩)", "label_en": "length_adjust (duration stretch)", "default": 1.0, "minimum": 0.5, "maximum": 2.0, "step": 0.05}, + {"name": "intelligibility_guidance_scale", "type": "slider", "label": "intelligibility_guidance_scale(仅 v2_vc)", "label_en": "Intelligibility guidance (v2_vc only)", "default": 0.7, "minimum": 0.0, "maximum": 1.0, "step": 0.05}, + {"name": "similarity_guidance_scale", "type": "slider", "label": "similarity_guidance_scale(仅 v2_vc)", "label_en": "Similarity guidance (v2_vc only)", "default": 0.7, "minimum": 0.0, "maximum": 1.0, "step": 0.05}, + {"name": "inference_guidance_scale", "type": "slider", "label": "inference_guidance_scale(仅 v1 路径)", "label_en": "Inference guidance (v1 paths only)", "default": 0.7, "minimum": 0.0, "maximum": 1.0, "step": 0.05}, + {"name": "f0_condition", "type": "bool", "label": "f0_condition(仅 v1 路径)", "label_en": "f0_condition (v1 routes only)", "default": false, "info_en": "Enable F0 conditioning. Required for singing voice conversion on the v1_svc route."}, + {"name": "auto_f0_adjust", "type": "bool", "label": "auto_f0_adjust(仅 v1 路径)", "label_en": "auto_f0_adjust (v1 routes only)", "default": false, "info_en": "Shift the source pitch toward the target speaker's pitch level."}, + {"name": "semitone_shift", "type": "number", "label": "semitone_shift(仅 v1 路径)", "label_en": "semitone_shift (v1 routes only)", "default": 0, "minimum": -24, "maximum": 24, "step": 1, "precision": 0} ], "rvc": [ {"name": "voice_id", "type": "choice", "label": "voice_id(打包音色)", "label_en": "voice_id", "default": "default", "choices": ["default", "manthos", "chocola", "fraise"]}, - {"name": "voice_model_path", "type": "text", "label": "voice_model_path(自定义 RVC .pth/.pt)", "label_en": "voice_model_path", "default": "", "placeholder": "留空=使用打包音色"}, - {"name": "retrieval_index_path", "type": "text", "label": "retrieval_index_path(FAISS index)", "label_en": "retrieval_index_path", "default": "", "placeholder": "可选 .index 路径"}, + {"name": "voice_model_path", "type": "text", "label": "voice_model_path(自定义 RVC .pth/.pt)", "label_en": "voice_model_path", "default": "", "placeholder": "留空=使用打包音色", "placeholder_en": "Blank = use the packaged voice"}, + {"name": "retrieval_index_path", "type": "text", "label": "retrieval_index_path(FAISS index)", "label_en": "retrieval_index_path", "default": "", "placeholder": "可选 .index 路径", "placeholder_en": "Optional .index path"}, {"name": "retrieval_blend", "type": "slider", "label": "retrieval_blend", "default": 0.0, "minimum": 0.0, "maximum": 1.0, "step": 0.05}, {"name": "semitone_shift", "type": "number", "label": "semitone_shift(半音变调)", "label_en": "semitone_shift", "default": 0, "step": 1, "precision": 0}, {"name": "pitch_filter_radius", "type": "number", "label": "pitch_filter_radius", "default": 3, "minimum": 0, "step": 1, "precision": 0}, @@ -199,53 +235,70 @@ {"name": "split_threshold_sec", "type": "number", "label": "split_threshold_sec", "default": 32, "minimum": 1, "step": 1, "precision": 0} ], - "meanvc2": [ - {"name": "seed", "type": "number", "label": "seed", "default": 42, "minimum": 0, "step": 1, "precision": 0} - ], - "personaplex": [ {"name": "voice_id", "type": "choice", "label": "voice_id(打包音色)", "label_en": "voice_id (packaged voice)", "default": "NATF2", "choices": ["NATF0", "NATF1", "NATF2", "NATF3", "NATM0", "NATM1", "NATM2", "NATM3", "VARF0", "VARF1", "VARF2", "VARF3", "VARF4", "VARM0", "VARM1", "VARM2", "VARM3", "VARM4"]}, {"name": "system_prompt", "type": "text", "label": "system_prompt", "default": "", "placeholder": "Leave blank to use the text box as the system prompt."}, - {"name": "temperature", "type": "slider", "label": "temperature", "default": 0.8, "minimum": 0.0, "maximum": 2.0, "step": 0.05}, - {"name": "text_temperature", "type": "slider", "label": "text_temperature", "default": 0.8, "minimum": 0.0, "maximum": 2.0, "step": 0.05}, + {"name": "temperature", "type": "slider", "label": "temperature", "default": 0.8, "minimum": 0.05, "maximum": 2.0, "step": 0.05, "info_en": "Must be above 0 while do_sample is on."}, + {"name": "text_temperature", "type": "number", "label": "text_temperature", "label_en": "text_temperature (blank follows temperature)", "minimum": 0.05, "maximum": 2.0, "step": 0.05, "info_en": "Blank makes the text head follow temperature. Must be above 0 while do_sample is on."}, {"name": "top_k", "type": "number", "label": "top_k", "default": 250, "minimum": 0, "step": 1, "precision": 0}, - {"name": "text_top_k", "type": "number", "label": "text_top_k", "default": 250, "minimum": 0, "step": 1, "precision": 0}, + {"name": "text_top_k", "type": "number", "label": "text_top_k", "label_en": "text_top_k (blank follows top_k)", "minimum": 0, "step": 1, "precision": 0, "info_en": "Blank makes the text head follow top_k."}, {"name": "do_sample", "type": "bool", "label": "do_sample", "default": true} ], "vevo2": [ - {"name": "route", "type": "choice", "label": "route(任务路线)", "default": "", "choices": ["", "style_preserved_vc", "style_converted_vc", "style_preserved_svc", "style_converted_svc", "singing_style_conversion", "editing"], "info": "留空=按任务默认;详见 webui/README.md"}, - {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 32, "minimum": 1, "step": 1, "precision": 0, "info": "流匹配步数"}, - {"name": "use_pitch_shift", "type": "choice", "label": "use_pitch_shift(自动音高对齐)", "default": "", "choices": ["", "true", "false"], "info": "留空=按路线默认"}, - {"name": "temperature", "type": "slider", "label": "temperature(AR 路线用)", "default": 0.7, "minimum": 0.0, "maximum": 2.0, "step": 0.05, "info": "默认取自模型 generation_config.json"}, - {"name": "top_k", "type": "number", "label": "top_k(AR 路线用)", "default": 20, "minimum": 0, "step": 1, "precision": 0, "info": "默认取自模型 generation_config.json"}, - {"name": "top_p", "type": "slider", "label": "top_p(AR 路线用)", "default": 0.8, "minimum": 0.0, "maximum": 1.0, "step": 0.01} + {"name": "route", "type": "choice", "label": "route(任务路线)", "label_en": "route (task path)", "default": "", "choices": ["", "style_preserved_vc", "style_converted_vc", "style_preserved_svc", "style_converted_svc", "singing_style_conversion", "editing"], "info": "留空=按任务默认;详见 webui/README.md", "info_en": "Blank = pick the default path for the selected task; see webui/README.md."}, + {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 32, "minimum": 1, "step": 1, "precision": 0, "info": "流匹配步数", "info_en": "Flow-matching steps."}, + {"name": "use_pitch_shift", "type": "choice", "label": "use_pitch_shift(自动音高对齐)", "label_en": "use_pitch_shift (automatic pitch alignment)", "default": "", "choices": ["", "true", "false"], "info": "留空=按路线默认", "info_en": "Blank = use the path's own default."}, + {"name": "temperature", "type": "number", "label": "temperature(AR 路线用)", "label_en": "temperature (AR paths)", "minimum": 0.05, "maximum": 2.0, "step": 0.05, "info": "留空=取自模型 generation_config.json(回退 1.0)", "info_en": "Blank uses the checkpoint's generation_config.json (C++ fallback 1.0). Must be above 0."}, + {"name": "top_k", "type": "number", "label": "top_k(AR 路线用)", "label_en": "top_k (AR paths)", "minimum": 0, "step": 1, "precision": 0, "info": "留空=取自模型 generation_config.json(回退 25)", "info_en": "Blank uses the checkpoint's generation_config.json (C++ fallback 25)."}, + {"name": "top_p", "type": "number", "label": "top_p(AR 路线用)", "label_en": "top_p (AR paths)", "minimum": 0.0, "maximum": 1.0, "step": 0.01, "info": "留空=取自模型 generation_config.json(回退 0.8)", "info_en": "Blank uses the checkpoint's generation_config.json (C++ fallback 0.8)."} ], "heartmula": [ - {"name": "tags", "type": "text", "label": "tags(必填,逗号分隔)", "default": "", "placeholder": "pop,bright,drums,female vocals", "info": "风格/情绪/乐器/人声标签,模型必需"}, + {"name": "tags", "type": "text", "label": "tags(必填,逗号分隔)", "label_en": "tags (required, comma-separated)", "default": "", "info": "风格/情绪/乐器/人声标签,模型必需", "info_en": "Required. Style, mood, instrument and vocal tags; HeartMuLa throws on an empty value.", "placeholder": "pop,bright,drums,female vocals"}, {"name": "temperature", "type": "slider", "label": "temperature", "default": 1.0, "minimum": 0.0, "maximum": 2.0, "step": 0.05}, {"name": "top_k", "type": "number", "label": "top_k", "default": 50, "minimum": 0, "step": 1, "precision": 0}, - {"name": "guidance_scale", "type": "slider", "label": "guidance_scale(MuLa CFG)", "default": 1.5, "minimum": 0.0, "maximum": 5.0, "step": 0.1}, - {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps(codec 步数)", "default": 10, "minimum": 1, "step": 1, "precision": 0}, - {"name": "infinite_mode", "type": "bool", "label": "infinite_mode(长输出分段生成)", "default": false}, - {"name": "codec_guidance_scale", "type": "slider", "label": "codec_guidance_scale", "default": 1.25, "minimum": 0.0, "maximum": 5.0, "step": 0.05} + {"name": "guidance_scale", "type": "slider", "label": "guidance_scale(MuLa CFG)", "label_en": "guidance_scale (MuLa CFG)", "default": 1.5, "minimum": 0.0, "maximum": 5.0, "step": 0.1}, + {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps(codec 步数)", "label_en": "num_inference_steps (codec steps)", "default": 10, "minimum": 1, "step": 1, "precision": 0}, + {"name": "infinite_mode", "type": "bool", "label": "infinite_mode(长输出分段生成)", "label_en": "infinite_mode (chunked long-form generation)", "default": false}, + {"name": "codec_guidance_scale", "type": "slider", "label": "codec_guidance_scale", "default": 1.25, "minimum": 0.0, "maximum": 5.0, "step": 0.05}, + {"name": "text_chunk_size", "type": "number", "label": "text_chunk_size", "label_en": "Text chunk size (infinite mode)", "default": 4096, "minimum": 1, "step": 64, "precision": 0}, + {"name": "infinite_chunk_audio_duration_ms", "type": "number", "label": "infinite_chunk_audio_duration_ms", "label_en": "Infinite-mode chunk audio (ms)", "default": 240000, "minimum": 1, "step": 10000, "precision": 0, "info_en": "Maximum audio generated per infinite-mode chunk. Must be positive."} ], "index_tts2": [ - {"name": "lang", "type": "choice", "label": "lang(语种提示, 仅 IndexTTS2.5 模型)", "label_en": "lang (language hint, IndexTTS2.5 models only)", "default": "auto", "choices": ["auto", "zh", "en", "ja", "es", "ar"], "info": "仅对 IndexTTS2.5(多语种)模型生效:auto 含汉字按中文,否则按英文;日/西/阿建议显式选择", "info_en": "Only applies to IndexTTS2.5 (multilingual) models: auto picks zh when the text contains Han characters, otherwise en; set ja/es/ar explicitly"}, - {"name": "emotion_text", "type": "text", "label": "emotion_text(情绪参考文本)", "label_en": "emotion_text (emotion reference text)", "default": "", "placeholder": "例:你吓死我了!你是鬼吗?", "placeholder_en": "e.g. You scared me to death!", "info": "填写后自动开启情感条件(use_emotion_text)", "info_en": "Setting this enables emotion conditioning."}, + {"name": "language", "type": "choice", "label": "language(语种提示, 仅 IndexTTS2.5 模型)", "label_en": "language (language hint, IndexTTS2.5 models only)", "default": "auto", "choices": ["auto", "zh", "en", "ja", "es", "ar"], "info": "仅对 IndexTTS2.5(多语种)模型生效:auto 含汉字按中文,否则按英文;日/西/阿建议显式选择", "info_en": "Only applies to IndexTTS2.5 (multilingual) models: auto picks zh when the text contains Han characters, otherwise en; set ja/es/ar explicitly"}, + {"name": "emotion_text", "type": "text", "label": "emotion_text(情绪参考文本)", "label_en": "emotion_text (emotion reference text)", "default": "", "info": "填写后自动开启情感条件(use_emotion_text)", "info_en": "Setting this enables emotion conditioning.", "placeholder": "例:你吓死我了!你是鬼吗?", "placeholder_en": "e.g. You scared me to death!"}, {"name": "emotion_alpha", "type": "slider", "label": "emotion_alpha(情感强度)", "label_en": "emotion_alpha", "default": 1.0, "minimum": 0.0, "maximum": 1.0, "step": 0.05}, {"name": "use_emotion_text", "type": "bool", "label": "use_emotion_text(从朗读文本推断情感)", "label_en": "use_emotion_text (infer from text)", "default": false}, {"name": "use_random_emotion", "type": "bool", "label": "use_random_emotion(随机情感)", "label_en": "use_random_emotion", "default": false}, {"name": "interval_silence_ms", "type": "number", "label": "interval_silence_ms(分段间静音)", "label_en": "interval_silence_ms", "default": 200, "minimum": 0, "step": 50, "precision": 0}, - {"name": "duration_factor", "type": "slider", "label": "duration_factor(语速/时长倍率,>1 更慢,<1 更快)", "label_en": "duration_factor (duration multiplier; >1 slower, <1 faster)", "default": 1.0, "minimum": 0.5, "maximum": 2.0, "step": 0.05, "info": "对齐官方 IndexTTS2.5 的 duration_factor:缩放输出时长,不改变音色/内容", "info_en": "Matches official IndexTTS2.5 duration_factor: scales output duration without changing timbre or content"} + {"name": "duration_factor", "type": "slider", "label": "duration_factor(语速/时长倍率,>1 更慢,<1 更快)", "label_en": "duration_factor (duration multiplier; >1 slower, <1 faster)", "default": 1.0, "minimum": 0.5, "maximum": 2.0, "step": 0.05, "info": "对齐官方 IndexTTS2.5 的 duration_factor:缩放输出时长,不改变音色/内容", "info_en": "Matches official IndexTTS2.5 duration_factor: scales output duration without changing timbre or content"}, + {"name": "do_sample", "type": "bool", "label": "do_sample", "label_en": "Sample", "default": true}, + {"name": "temperature", "type": "slider", "label": "temperature", "label_en": "Temperature", "default": 0.8, "minimum": 0.05, "maximum": 2.0, "step": 0.05, "info_en": "Must be positive."}, + {"name": "top_p", "type": "slider", "label": "top_p", "label_en": "Top-p", "default": 0.8, "minimum": 0.01, "maximum": 1.0, "step": 0.01, "info_en": "Must be within (0, 1]."}, + {"name": "top_k", "type": "number", "label": "top_k", "label_en": "Top-k", "default": 30, "minimum": 1, "step": 1, "precision": 0, "info_en": "Must be positive."}, + {"name": "repetition_penalty", "type": "slider", "label": "repetition_penalty", "label_en": "Repetition penalty", "default": 10.0, "minimum": 0.0, "maximum": 20.0, "step": 0.1}, + {"name": "num_beams", "type": "number", "label": "num_beams", "label_en": "Beam count", "default": 3, "minimum": 1, "step": 1, "precision": 0, "info_en": "Must be positive."}, + {"name": "length_penalty", "type": "slider", "label": "length_penalty", "label_en": "Length penalty", "default": 0.0, "minimum": -2.0, "maximum": 2.0, "step": 0.1} ], "irodori_tts": [ {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps(RF 扩散步数)", "label_en": "num_inference_steps", "default": 40, "minimum": 1, "step": 1, "precision": 0}, {"name": "duration_sec", "type": "number", "label": "duration_sec(0=模型自动预测时长)", "label_en": "duration_sec (0 = auto)", "default": 0, "minimum": 0, "step": 0.5}, - {"name": "duration_scale", "type": "slider", "label": "duration_scale(语速倒数,越大越慢)", "label_en": "duration_scale", "default": 1.0, "minimum": 0.5, "maximum": 2.0, "step": 0.05} + {"name": "duration_scale", "type": "slider", "label": "duration_scale(语速倒数,越大越慢)", "label_en": "duration_scale", "default": 1.0, "minimum": 0.5, "maximum": 2.0, "step": 0.05}, + {"name": "text_guidance_scale", "type": "slider", "label": "text_guidance_scale", "label_en": "Text guidance", "default": 3.0, "minimum": 0.0, "maximum": 10.0, "step": 0.1}, + {"name": "speaker_guidance_scale", "type": "slider", "label": "speaker_guidance_scale", "label_en": "Speaker guidance", "default": 5.0, "minimum": 0.0, "maximum": 15.0, "step": 0.1}, + {"name": "caption_guidance_scale", "type": "slider", "label": "caption_guidance_scale", "label_en": "Caption guidance", "default": 3.0, "minimum": 0.0, "maximum": 10.0, "step": 0.1}, + {"name": "guidance_mode", "type": "choice", "label": "guidance_mode", "label_en": "Guidance mode", "default": "independent", "choices": ["independent", "joint", "alternating"]}, + {"name": "guidance_min_t", "type": "slider", "label": "guidance_min_t", "label_en": "Guidance start timestep", "default": 0.5, "minimum": 0.0, "maximum": 1.0, "step": 0.05, "info_en": "Must not exceed the guidance end timestep."}, + {"name": "guidance_max_t", "type": "slider", "label": "guidance_max_t", "label_en": "Guidance end timestep", "default": 1.0, "minimum": 0.0, "maximum": 1.0, "step": 0.05}, + {"name": "min_duration_sec", "type": "number", "label": "min_duration_sec", "label_en": "Min duration (s)", "default": 0.5, "minimum": 0.05, "step": 0.5, "info_en": "Must be positive and no greater than the maximum."}, + {"name": "max_duration_sec", "type": "number", "label": "max_duration_sec", "label_en": "Max duration (s)", "default": 30.0, "minimum": 0.05, "step": 0.5}, + {"name": "no_ref", "type": "bool", "label": "no_ref", "label_en": "No-reference generation", "default": true, "info_en": "Forced off automatically whenever a speaker reference is supplied."}, + {"name": "trim_tail", "type": "bool", "label": "trim_tail", "label_en": "Trim trailing silence", "default": true}, + {"name": "text_chunk_mode", "type": "choice", "label": "text_chunk_mode", "label_en": "Text chunk mode", "default": "endline", "choices": ["japanese", "endline"]}, + {"name": "instruction", "type": "text", "label": "instruction", "label_en": "instruction (caption-conditioned checkpoints)", "default": "", "placeholder_en": "Voice or style description; ignored by checkpoints without caption conditioning"} ], "moss_tts_local": [ @@ -273,9 +326,9 @@ ], "controlfoley": [ - {"name": "duration_sec", "type": "number", "label": "duration_sec", "default": 8.0, "minimum": 0.1, "step": 0.5}, + {"name": "duration_sec", "type": "number", "label": "duration_sec", "default": 8.0, "minimum": 0.64, "maximum": 60.0, "step": 0.1, "info_en": "Shorter than 0.64 s produces an empty sync sequence and fails."}, {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 25, "minimum": 1, "step": 1, "precision": 0}, - {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 4.5, "minimum": 0.0, "maximum": 10.0, "step": 0.1}, + {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 4.5, "minimum": 0.1, "maximum": 10.0, "step": 0.1, "info_en": "Must be positive."}, {"name": "negative_prompt", "type": "text", "label": "negative_prompt", "default": "", "placeholder": "optional negative prompt"}, {"name": "mask_away_clip", "type": "bool", "label": "mask_away_clip", "default": false} ], @@ -284,7 +337,7 @@ {"name": "duration_sec", "type": "number", "label": "duration_sec", "default": 20.0, "minimum": 0.1, "step": 0.5}, {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 2.0, "minimum": 0.0, "maximum": 10.0, "step": 0.1}, {"name": "stop_threshold", "type": "slider", "label": "stop_threshold", "default": 0.5, "minimum": 0.0, "maximum": 1.0, "step": 0.05}, - {"name": "min_stop_step", "type": "number", "label": "min_stop_step", "default": 5, "minimum": 0, "step": 1, "precision": 0} + {"name": "min_stop_step", "type": "number", "label": "min_stop_step", "default": 5, "minimum": 1, "step": 1, "precision": 0, "info_en": "Must be positive."} ], "fireredtts3-base": [ @@ -308,7 +361,7 @@ {"name": "template_name", "type": "choice", "label": "template_name", "default": "voice_design", "choices": ["voice_design"]}, {"name": "language", "type": "choice", "label": "language", "default": "Chinese", "choices": ["Chinese", "English", "Cantonese", "Japanese", "Korean", "Spanish", "French", "Russian", "Arabic", "Turkish", "Indonesian", "Portuguese", "Italian", "Dutch", "Vietnamese", "German", "Ukrainian", "Thai", "Polish", "Romanian", "Greek", "Czech", "Finnish", "Hindi", "ZH_Anhui", "ZH_Fujian", "ZH_Gansu", "ZH_Guizhou", "ZH_Hebei", "ZH_Henan", "ZH_Hubei", "ZH_Hunan", "ZH_Jiangxi", "ZH_Liaoning", "ZH_Minnan", "ZH_Ningxia", "ZH_Shaanxi", "ZH_Shandong", "ZH_Shanghai", "ZH_Shanxi", "ZH_Tianjin", "ZH_Wenzhou", "ZH_Wu", "ZH_Yunnan"]}, {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 10, "minimum": 1, "step": 1, "precision": 0}, - {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 2.0, "minimum": 0.0, "maximum": 10.0, "step": 0.1}, + {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 1.2, "minimum": 0.0, "maximum": 10.0, "step": 0.1, "info_en": "FireRedTTS3 voice design is tuned for 1.2; 2.0 is the instruct_tts value."}, {"name": "stop_threshold", "type": "slider", "label": "stop_threshold", "default": 0.5, "minimum": 0.0, "maximum": 1.0, "step": 0.05} ], @@ -318,9 +371,7 @@ {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 10, "minimum": 1, "step": 1, "precision": 0}, {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 2.0, "minimum": 0.0, "maximum": 10.0, "step": 0.1}, {"name": "max_new_audio_steps", "type": "number", "label": "max_new_audio_steps", "default": 750, "minimum": 1, "step": 1, "precision": 0}, - {"name": "top_k", "type": "number", "label": "top_k", "default": 20, "minimum": 0, "step": 1, "precision": 0}, - {"name": "top_p", "type": "slider", "label": "top_p", "default": 0.8, "minimum": 0.0, "maximum": 1.0, "step": 0.01}, - {"name": "temperature", "type": "slider", "label": "temperature", "default": 0.7, "minimum": 0.0, "maximum": 2.0, "step": 0.05} + {"name": "min_new_audio_steps", "type": "number", "label": "min_new_audio_steps", "label_en": "Min audio steps", "default": 6, "minimum": 0, "step": 1, "precision": 0, "info_en": "Floor on generated audio steps; suppresses truncated outputs. Must be non-negative."} ], "firered-audio-vdesign": [ @@ -328,16 +379,18 @@ {"name": "language", "type": "choice", "label": "language", "default": "zh", "choices": ["zh", "en"]}, {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 10, "minimum": 1, "step": 1, "precision": 0}, {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 2.0, "minimum": 0.0, "maximum": 10.0, "step": 0.1}, - {"name": "max_new_audio_steps", "type": "number", "label": "max_new_audio_steps", "default": 750, "minimum": 1, "step": 1, "precision": 0} + {"name": "max_new_audio_steps", "type": "number", "label": "max_new_audio_steps", "default": 750, "minimum": 1, "step": 1, "precision": 0}, + {"name": "min_new_audio_steps", "type": "number", "label": "min_new_audio_steps", "label_en": "Min audio steps", "default": 6, "minimum": 0, "step": 1, "precision": 0, "info_en": "Floor on generated audio steps; suppresses truncated outputs. Must be non-negative."} ], "firered-audio-semantic-edit": [ {"name": "template_name", "type": "choice", "label": "template_name", "default": "semantic_edit", "choices": ["semantic_edit"]}, {"name": "language", "type": "choice", "label": "language", "default": "zh", "choices": ["zh", "en"]}, - {"name": "instruction", "type": "text", "label": "instruction", "default": "", "placeholder": "delete '比普通的茶叶要'"}, + {"name": "instruction", "type": "text", "label": "instruction", "default": "", "placeholder": "delete '比普通的茶叶要'", "placeholder_en": "delete 'the phrase to remove'"}, {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 10, "minimum": 1, "step": 1, "precision": 0}, {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 2.0, "minimum": 0.0, "maximum": 10.0, "step": 0.1}, {"name": "max_new_audio_steps", "type": "number", "label": "max_new_audio_steps", "default": 750, "minimum": 1, "step": 1, "precision": 0}, + {"name": "min_new_audio_steps", "type": "number", "label": "min_new_audio_steps", "label_en": "Min audio steps", "default": 6, "minimum": 0, "step": 1, "precision": 0, "info_en": "Floor on generated audio steps; suppresses truncated outputs. Must be non-negative."}, {"name": "max_new_text_tokens", "type": "number", "label": "max_new_text_tokens", "default": 512, "minimum": 1, "step": 1, "precision": 0} ], @@ -347,22 +400,207 @@ {"name": "instruction", "type": "text", "label": "instruction", "default": "shift the pitch by 3 steps", "placeholder": "shift the pitch by 3 steps"}, {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "default": 10, "minimum": 1, "step": 1, "precision": 0}, {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "default": 2.0, "minimum": 0.0, "maximum": 10.0, "step": 0.1}, - {"name": "max_new_audio_steps", "type": "number", "label": "max_new_audio_steps", "default": 750, "minimum": 1, "step": 1, "precision": 0} + {"name": "max_new_audio_steps", "type": "number", "label": "max_new_audio_steps", "default": 750, "minimum": 1, "step": 1, "precision": 0}, + {"name": "min_new_audio_steps", "type": "number", "label": "min_new_audio_steps", "label_en": "Min audio steps", "default": 6, "minimum": 0, "step": 1, "precision": 0, "info_en": "Floor on generated audio steps; suppresses truncated outputs. Must be non-negative."} ], "firered-audio-asr": [ {"name": "template_name", "type": "choice", "label": "template_name", "default": "asr", "choices": ["asr", "understand"]}, {"name": "language", "type": "choice", "label": "language", "default": "zh", "choices": ["zh", "en"]}, - {"name": "enable_thinking", "type": "bool", "label": "enable_thinking", "default": false}, - {"name": "max_new_tokens", "type": "number", "label": "max_new_tokens", "default": 512, "minimum": 1, "step": 1, "precision": 0}, - {"name": "top_k", "type": "number", "label": "top_k", "default": 20, "minimum": 0, "step": 1, "precision": 0}, - {"name": "top_p", "type": "slider", "label": "top_p", "default": 0.8, "minimum": 0.0, "maximum": 1.0, "step": 0.01}, - {"name": "temperature", "type": "slider", "label": "temperature", "default": 0.7, "minimum": 0.0, "maximum": 2.0, "step": 0.05} + {"name": "enable_thinking", "type": "bool", "label": "enable_thinking", "default": false, "info_en": "Rejected by the asr template; use template_name=understand."}, + {"name": "max_new_tokens", "type": "number", "label": "max_new_tokens", "label_en": "max_new_tokens", "minimum": 1, "step": 1, "precision": 0, "info_en": "Blank uses 300, or 1024 when enable_thinking is on. Setting a value here defeats the automatic thinking-mode bump."}, + {"name": "top_k", "type": "number", "label": "top_k", "default": 20, "minimum": 0, "step": 1, "precision": 0, "info_en": "Sampling options apply to template_name=understand only; asr decodes greedily."}, + {"name": "top_p", "type": "slider", "label": "top_p", "default": 0.8, "minimum": 0.0, "maximum": 1.0, "step": 0.01, "info_en": "Sampling options apply to template_name=understand only; asr decodes greedily."}, + {"name": "temperature", "type": "slider", "label": "temperature", "default": 0.7, "minimum": 0.0, "maximum": 2.0, "step": 0.05, "info_en": "Sampling options apply to template_name=understand only; asr decodes greedily."} ], "supertonic": [ {"name": "voice", "type": "choice", "label": "voice(预置音色:M 男声 / F 女声)", "label_en": "voice (M = male, F = female presets)", "default": "M1", "choices": ["M1", "M2", "M3", "M4", "M5", "F1", "F2", "F3", "F4", "F5"]}, {"name": "speaking_rate", "type": "slider", "label": "speaking_rate(语速倍率)", "label_en": "speaking_rate", "default": 1.05, "minimum": 0.5, "maximum": 2.0, "step": 0.05}, {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps(流匹配步数)", "label_en": "num_inference_steps", "default": 8, "minimum": 1, "step": 1, "precision": 0} + ], + + "dots_tts": [ + {"name": "template_name", "type": "choice", "label": "template_name", "label_en": "Template", "default": "tts", "choices": ["tts", "instruction_tts", "text_to_audio", "tts_interleave", "edit"], "info_en": "Generation template. instruction_tts and edit need an instruction; edit also needs source audio plus source_text and target_text."}, + {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "label_en": "Sampling steps", "default": 10, "minimum": 1, "step": 1, "precision": 0}, + {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "label_en": "Guidance scale", "default": 1.2, "minimum": 0.0, "maximum": 5.0, "step": 0.1}, + {"name": "speaker_scale", "type": "slider", "label": "speaker_scale", "label_en": "Speaker scale", "default": 1.5, "minimum": 0.0, "maximum": 5.0, "step": 0.1, "info_en": "Classifier-free guidance weight on the speaker reference."}, + {"name": "sampler_mode", "type": "choice", "label": "sampler_mode", "label_en": "ODE sampler", "default": "euler", "choices": ["euler", "midpoint", "rk4"]}, + {"name": "vocoder_merge_steps", "type": "number", "label": "vocoder_merge_steps", "label_en": "Vocoder merge steps", "default": 4, "minimum": 1, "step": 1, "precision": 0}, + {"name": "use_xvector", "type": "choice", "label": "use_xvector", "label_en": "Speaker x-vector", "default": "auto", "choices": ["auto", "on", "off"]}, + {"name": "reference_duration_sec", "type": "number", "label": "reference_duration_sec", "label_en": "Reference trim (s)", "minimum": 0.0, "step": 0.5, "info_en": "Blank uses the whole reference clip."}, + {"name": "text_chunk_size", "type": "number", "label": "text_chunk_size", "label_en": "Text chunk size", "default": 320, "minimum": 1, "step": 1, "precision": 0}, + {"name": "text_chunk_mode", "type": "choice", "label": "text_chunk_mode", "label_en": "Text chunk mode", "default": "tag_aware", "choices": ["default", "tag_aware", "japanese", "endline"]}, + {"name": "instruction", "type": "text", "label": "instruction", "label_en": "instruction (instruction_tts / edit)", "default": "", "placeholder_en": "Style or edit instruction"}, + {"name": "source_text", "type": "text", "label": "source_text", "label_en": "source_text (edit template)", "default": "", "placeholder_en": "Transcript of the source audio"}, + {"name": "target_text", "type": "text", "label": "target_text", "label_en": "target_text (edit template)", "default": "", "placeholder_en": "Transcript the edit should produce"} + ], + + "outetts": [ + {"name": "temperature", "type": "number", "label": "temperature", "label_en": "Temperature", "minimum": 0.0, "step": 0.05, "info_en": "Blank uses the packaged checkpoint's value (C++ fallback 0.4)."}, + {"name": "top_k", "type": "number", "label": "top_k", "label_en": "Top-k", "minimum": 0, "step": 1, "precision": 0, "info_en": "Blank uses the packaged checkpoint's value (C++ fallback 40)."}, + {"name": "top_p", "type": "number", "label": "top_p", "label_en": "Top-p", "minimum": 0.01, "maximum": 1.0, "step": 0.01, "info_en": "Blank uses the packaged checkpoint's value (C++ fallback 0.9). Must be above 0."}, + {"name": "min_p", "type": "number", "label": "min_p", "label_en": "Min-p", "minimum": 0.0, "maximum": 1.0, "step": 0.01, "info_en": "Blank uses the packaged checkpoint's value (C++ fallback 0.05)."}, + {"name": "repetition_penalty", "type": "number", "label": "repetition_penalty", "label_en": "Repetition penalty", "minimum": 0.01, "step": 0.01, "info_en": "Blank uses the packaged checkpoint's value (C++ fallback 1.1). Must be above 0."}, + {"name": "repetition_window", "type": "number", "label": "repetition_window", "label_en": "Repetition window", "default": 64, "minimum": 0, "step": 1, "precision": 0}, + {"name": "reference_language", "type": "text", "label": "reference_language", "label_en": "Reference language", "default": "", "placeholder_en": "Blank follows the request language, else en"}, + {"name": "text_chunk_size", "type": "number", "label": "text_chunk_size", "label_en": "Text chunk size", "default": 256, "minimum": 1, "step": 1, "precision": 0}, + {"name": "text_chunk_mode", "type": "choice", "label": "text_chunk_mode", "label_en": "Text chunk mode", "default": "default", "choices": ["default", "tag_aware", "japanese", "endline"]} + ], + + "glm_tts": [ + {"name": "temperature", "type": "slider", "label": "temperature", "label_en": "Temperature", "default": 1.0, "minimum": 0.05, "maximum": 2.0, "step": 0.05}, + {"name": "top_k", "type": "number", "label": "top_k", "label_en": "Top-k", "default": 25, "minimum": 0, "step": 1, "precision": 0}, + {"name": "top_p", "type": "slider", "label": "top_p", "label_en": "Top-p", "default": 0.8, "minimum": 0.0, "maximum": 1.0, "step": 0.01}, + {"name": "num_inference_steps", "type": "number", "label": "num_inference_steps", "label_en": "Flow steps", "minimum": 1, "step": 1, "precision": 0, "info_en": "Blank uses the packaged checkpoint's value (C++ fallback 10)."}, + {"name": "flow_guidance_scale", "type": "number", "label": "flow_guidance_scale", "label_en": "Flow guidance scale", "minimum": 0.0, "step": 0.05, "info_en": "Blank uses the packaged checkpoint's value (C++ fallback 0.7)."} + ], + + "fish_audio": [ + {"name": "temperature", "type": "slider", "label": "temperature", "label_en": "Temperature", "default": 0.8, "minimum": 0.05, "maximum": 1.95, "step": 0.05, "info_en": "Must stay strictly between 0 and 2."}, + {"name": "top_p", "type": "slider", "label": "top_p", "label_en": "Top-p", "default": 0.8, "minimum": 0.01, "maximum": 1.0, "step": 0.01}, + {"name": "top_k", "type": "number", "label": "top_k", "label_en": "Top-k", "default": 30, "minimum": 1, "step": 1, "precision": 0}, + {"name": "text_chunk_size", "type": "number", "label": "text_chunk_size", "label_en": "Text chunk size", "default": 200, "minimum": 1, "step": 1, "precision": 0}, + {"name": "text_chunk_mode", "type": "choice", "label": "text_chunk_mode", "label_en": "Text chunk mode", "default": "default", "choices": ["default", "tag_aware", "japanese", "endline"]} + ], + + "higgs_audio_tts": [ + {"name": "temperature", "type": "slider", "label": "temperature", "label_en": "Temperature", "default": 0.8, "minimum": 0.05, "maximum": 2.0, "step": 0.05}, + {"name": "top_p", "type": "slider", "label": "top_p", "label_en": "Top-p", "default": 0.8, "minimum": 0.01, "maximum": 1.0, "step": 0.01}, + {"name": "top_k", "type": "number", "label": "top_k", "label_en": "Top-k", "default": 30, "minimum": 0, "step": 1, "precision": 0}, + {"name": "text_chunk_size", "type": "number", "label": "text_chunk_size", "label_en": "Text chunk size", "default": 1024, "minimum": 1, "step": 1, "precision": 0}, + {"name": "text_chunk_mode", "type": "choice", "label": "text_chunk_mode", "label_en": "Text chunk mode", "default": "default", "choices": ["default", "tag_aware", "japanese", "endline"]} + ], + + "vietneu_tts": [ + {"name": "do_sample", "type": "bool", "label": "do_sample", "label_en": "Sample", "default": true}, + {"name": "temperature", "type": "slider", "label": "temperature", "label_en": "Temperature", "default": 0.9, "minimum": 0.0, "maximum": 2.0, "step": 0.05}, + {"name": "top_k", "type": "number", "label": "top_k", "label_en": "Top-k", "default": 50, "minimum": 0, "step": 1, "precision": 0}, + {"name": "top_p", "type": "slider", "label": "top_p", "label_en": "Top-p", "default": 1.0, "minimum": 0.0, "maximum": 1.0, "step": 0.01}, + {"name": "repetition_penalty", "type": "slider", "label": "repetition_penalty", "label_en": "Repetition penalty", "default": 1.05, "minimum": 1.0, "maximum": 2.0, "step": 0.01}, + {"name": "subtalker_do_sample", "type": "bool", "label": "subtalker_do_sample", "label_en": "Sub-talker: sample", "default": true}, + {"name": "subtalker_temperature", "type": "slider", "label": "subtalker_temperature", "label_en": "Sub-talker: temperature", "default": 0.9, "minimum": 0.0, "maximum": 2.0, "step": 0.05}, + {"name": "subtalker_top_k", "type": "number", "label": "subtalker_top_k", "label_en": "Sub-talker: top-k", "default": 50, "minimum": 0, "step": 1, "precision": 0}, + {"name": "subtalker_top_p", "type": "slider", "label": "subtalker_top_p", "label_en": "Sub-talker: top-p", "default": 1.0, "minimum": 0.0, "maximum": 1.0, "step": 0.01}, + {"name": "x_vector_only_mode", "type": "bool", "label": "x_vector_only_mode", "label_en": "Speaker-embedding-only mode", "default": false, "info_en": "Condition on the speaker embedding alone instead of in-context reference audio."}, + {"name": "text_chunk_size", "type": "number", "label": "text_chunk_size", "label_en": "Text chunk size", "default": 200, "minimum": 1, "step": 1, "precision": 0}, + {"name": "text_chunk_mode", "type": "choice", "label": "text_chunk_mode", "label_en": "Text chunk mode", "default": "default", "choices": ["default", "tag_aware", "japanese", "endline"]} + ], + + "soprano_tts": [ + {"name": "temperature", "type": "slider", "label": "temperature", "label_en": "Temperature", "default": 0.3, "minimum": 0.05, "maximum": 2.0, "step": 0.05, "info_en": "Must be above 0."}, + {"name": "top_p", "type": "slider", "label": "top_p", "label_en": "Top-p", "default": 0.95, "minimum": 0.0, "maximum": 1.0, "step": 0.01}, + {"name": "repetition_penalty", "type": "slider", "label": "repetition_penalty", "label_en": "Repetition penalty", "default": 1.2, "minimum": 1.0, "maximum": 2.0, "step": 0.01}, + {"name": "eos_bias", "type": "slider", "label": "eos_bias", "label_en": "End-of-speech bias", "default": 0.0, "minimum": -5.0, "maximum": 5.0, "step": 0.1, "info_en": "Positive values stop generation sooner."} + ], + + "muscriptor": [ + {"name": "output_format", "type": "choice", "label": "output_format", "label_en": "Output format", "default": "midi", "choices": ["midi", "json"]}, + {"name": "instruments", "type": "text", "label": "instruments", "label_en": "Instruments", "default": "", "placeholder_en": "Comma-separated instrument names; blank transcribes all"}, + {"name": "do_sample", "type": "bool", "label": "do_sample", "label_en": "Sample", "default": false}, + {"name": "temperature", "type": "slider", "label": "temperature", "label_en": "Temperature", "default": 1.0, "minimum": 0.0, "maximum": 2.0, "step": 0.05}, + {"name": "guidance_scale", "type": "slider", "label": "guidance_scale", "label_en": "Guidance scale", "default": 1.0, "minimum": 0.0, "maximum": 5.0, "step": 0.1, "info_en": "Exactly 1.0 disables classifier-free guidance; other values double the conditioning batch."}, + {"name": "num_beams", "type": "number", "label": "num_beams", "label_en": "Beam count", "default": 1, "minimum": 1, "step": 1, "precision": 0}, + {"name": "batch_size", "type": "number", "label": "batch_size", "label_en": "Batch size", "default": 1, "minimum": 1, "step": 1, "precision": 0, "info_en": "Values above 1 require prelude_forcing to be off."}, + {"name": "prelude_forcing", "type": "bool", "label": "prelude_forcing", "label_en": "Prelude forcing", "default": true} + ], + + "hviske_asr": [ + {"name": "punctuation", "type": "bool", "label": "punctuation", "label_en": "Punctuation", "default": true}, + {"name": "num_beams", "type": "number", "label": "num_beams", "label_en": "Beam count", "default": 1, "minimum": 1, "step": 1, "precision": 0}, + {"name": "length_penalty", "type": "slider", "label": "length_penalty", "label_en": "Length penalty", "default": 1.0, "minimum": 0.05, "maximum": 3.0, "step": 0.05, "info_en": "Must be above 0."}, + {"name": "do_sample", "type": "bool", "label": "do_sample", "label_en": "Sample", "default": false}, + {"name": "temperature", "type": "slider", "label": "temperature", "label_en": "Temperature", "default": 1.0, "minimum": 0.05, "maximum": 2.0, "step": 0.05, "info_en": "Must be above 0."}, + {"name": "top_k", "type": "number", "label": "top_k", "label_en": "Top-k", "default": 50, "minimum": 0, "step": 1, "precision": 0, "info_en": "0 disables top-k filtering."}, + {"name": "top_p", "type": "slider", "label": "top_p", "label_en": "Top-p", "default": 1.0, "minimum": 0.01, "maximum": 1.0, "step": 0.01}, + {"name": "audio_chunk_mode", "type": "choice", "label": "audio_chunk_mode", "label_en": "Audio chunk mode", "default": "auto", "choices": ["auto", "fixed", "quiet_energy", "none"]}, + {"name": "audio_chunk_duration_sec", "type": "number", "label": "audio_chunk_duration_sec", "label_en": "Audio chunk length (s)", "minimum": 0.001, "step": 1.0, "info_en": "Blank uses the packaged model's max_audio_clip_s."} + ], + + "kroko_asr": [ + {"name": "decoding_method", "type": "choice", "label": "decoding_method", "label_en": "Decoding method", "default": "greedy_search", "choices": ["greedy_search", "modified_beam_search"]}, + {"name": "num_beams", "type": "number", "label": "num_beams", "label_en": "Beam count", "default": 4, "minimum": 1, "maximum": 64, "step": 1, "precision": 0, "info_en": "Only used by modified_beam_search."}, + {"name": "blank_penalty", "type": "slider", "label": "blank_penalty", "label_en": "Blank penalty", "default": 0.0, "minimum": 0.0, "maximum": 5.0, "step": 0.1}, + {"name": "hotwords", "type": "text", "label": "hotwords", "label_en": "Hotwords", "default": "", "placeholder_en": "Phrases separated by / or newline; needs modified_beam_search"}, + {"name": "hotwords_score", "type": "slider", "label": "hotwords_score", "label_en": "Hotword boost", "default": 1.5, "minimum": 0.0, "maximum": 10.0, "step": 0.1}, + {"name": "enable_endpoint", "type": "bool", "label": "enable_endpoint", "label_en": "Endpoint detection", "default": false}, + {"name": "rule1_min_trailing_silence_sec", "type": "number", "label": "rule1_min_trailing_silence_sec", "label_en": "Endpoint rule 1: trailing silence (s)", "default": 2.4, "minimum": 0.0, "step": 0.1}, + {"name": "rule2_min_trailing_silence_sec", "type": "number", "label": "rule2_min_trailing_silence_sec", "label_en": "Endpoint rule 2: trailing silence (s)", "default": 1.2, "minimum": 0.0, "step": 0.1}, + {"name": "rule3_min_utterance_length_sec", "type": "number", "label": "rule3_min_utterance_length_sec", "label_en": "Endpoint rule 3: utterance length (s)", "default": 20.0, "minimum": 0.0, "step": 1.0} + ], + + "qwen3_asr": [ + {"name": "return_timestamps", "type": "bool", "label": "return_timestamps", "label_en": "Return timestamps", "default": false, "info_en": "Also shortens the automatic chunk length from 30 s to 15 s."}, + {"name": "clamp_timestamps_to_audio", "type": "bool", "label": "clamp_timestamps_to_audio", "label_en": "Clamp timestamps to audio length", "default": false}, + {"name": "audio_chunk_mode", "type": "choice", "label": "audio_chunk_mode", "label_en": "Audio chunk mode", "default": "auto", "choices": ["auto", "fixed", "vad", "none"]}, + {"name": "audio_chunk_duration_sec", "type": "number", "label": "audio_chunk_duration_sec", "label_en": "Audio chunk length (s)", "minimum": 0.001, "step": 1.0, "info_en": "Blank uses 30 s, or 15 s when timestamps or VAD chunking are on."} + ], + + "nemotron_asr": [ + {"name": "keep_language_tags", "type": "bool", "label": "keep_language_tags", "label_en": "Keep language tags", "default": false} + ], + + "vibevoice_asr": [ + {"name": "temperature", "type": "slider", "label": "temperature", "label_en": "Temperature", "default": 0.0, "minimum": 0.0, "maximum": 2.0, "step": 0.05, "info_en": "0 decodes deterministically."}, + {"name": "top_p", "type": "slider", "label": "top_p", "label_en": "Top-p", "default": 1.0, "minimum": 0.01, "maximum": 1.0, "step": 0.01}, + {"name": "top_k", "type": "number", "label": "top_k", "label_en": "Top-k", "default": 50, "minimum": 0, "step": 1, "precision": 0}, + {"name": "repetition_penalty", "type": "slider", "label": "repetition_penalty", "label_en": "Repetition penalty", "default": 1.0, "minimum": 0.05, "maximum": 2.0, "step": 0.01, "info_en": "Must be above 0."}, + {"name": "num_beams", "type": "number", "label": "num_beams", "label_en": "Beam count", "default": 1, "minimum": 1, "step": 1, "precision": 0}, + {"name": "audio_chunk_mode", "type": "choice", "label": "audio_chunk_mode", "label_en": "Audio chunk mode", "default": "auto", "choices": ["auto", "fixed", "vad", "none"]}, + {"name": "audio_chunk_seconds", "type": "number", "label": "audio_chunk_seconds", "label_en": "Audio chunk length (s)", "default": 1200.0, "minimum": 0.001, "step": 10.0} + ], + + "voxtral_realtime": [ + {"name": "do_sample", "type": "bool", "label": "do_sample", "label_en": "Sample", "default": false}, + {"name": "temperature", "type": "slider", "label": "temperature", "label_en": "Temperature", "default": 1.0, "minimum": 0.05, "maximum": 2.0, "step": 0.05, "info_en": "Must be above 0."}, + {"name": "top_p", "type": "slider", "label": "top_p", "label_en": "Top-p", "default": 1.0, "minimum": 0.01, "maximum": 1.0, "step": 0.01}, + {"name": "top_k", "type": "number", "label": "top_k", "label_en": "Top-k", "default": 50, "minimum": 0, "step": 1, "precision": 0}, + {"name": "max_new_tokens", "type": "number", "label": "max_new_tokens", "label_en": "Max new tokens", "minimum": 1, "step": 1, "precision": 0, "info_en": "Blank lets the model use the remaining audio-token budget. Voxtral-Realtime reads max_new_tokens, not max_tokens."} + ], + + "higgs_audio_stt": [ + {"name": "enable_thinking", "type": "bool", "label": "enable_thinking", "label_en": "Thinking mode", "default": true}, + {"name": "audio_chunk_mode", "type": "choice", "label": "audio_chunk_mode", "label_en": "Audio chunk mode", "default": "auto", "choices": ["auto", "fixed", "none"]}, + {"name": "audio_chunk_duration_sec", "type": "number", "label": "audio_chunk_duration_sec", "label_en": "Audio chunk length (s)", "default": 4.0, "minimum": 0.001, "step": 1.0} + ], + + "fun_asr_nano": [ + {"name": "enable_itn", "type": "bool", "label": "enable_itn", "label_en": "Inverse text normalization", "default": true}, + {"name": "audio_chunk_mode", "type": "choice", "label": "audio_chunk_mode", "label_en": "Audio chunk mode", "default": "auto", "choices": ["auto", "fixed", "none"]}, + {"name": "audio_chunk_seconds", "type": "number", "label": "audio_chunk_seconds", "label_en": "Audio chunk length (s)", "default": 30.0, "minimum": 0.001, "step": 1.0, "info_en": "Fun-ASR-Nano accepts only audio_chunk_seconds; the canonical audio_chunk_duration_sec is rejected."} + ], + + "parakeet_tdt": [ + {"name": "keep_language_tags", "type": "bool", "label": "keep_language_tags", "label_en": "Keep language tags", "default": false}, + {"name": "audio_chunk_mode", "type": "choice", "label": "audio_chunk_mode", "label_en": "Audio chunk mode", "default": "auto", "choices": ["auto", "fixed", "vad", "none"]}, + {"name": "audio_chunk_duration_sec", "type": "number", "label": "audio_chunk_duration_sec", "label_en": "Audio chunk length (s)", "minimum": 0.001, "step": 0.5, "info_en": "Blank uses the session's centre-window length (2.0 s by default)."} + ], + + "granite5asr": [ + {"name": "audio_chunk_mode", "type": "choice", "label": "audio_chunk_mode", "label_en": "Audio chunk mode", "default": "auto", "choices": ["auto", "fixed", "vad", "none"]}, + {"name": "audio_chunk_duration_sec", "type": "number", "label": "audio_chunk_duration_sec", "label_en": "Audio chunk length (s)", "default": 30.0, "minimum": 0.001, "step": 1.0} + ], + + "silero_vad": [ + {"name": "threshold", "type": "slider", "label": "threshold", "label_en": "Speech probability threshold", "default": 0.5, "minimum": 0.0, "maximum": 1.0, "step": 0.01, "info_en": "These options apply to offline runs. Streaming VAD uses the session configuration and ignores per-request values."}, + {"name": "min_speech_duration_ms", "type": "number", "label": "min_speech_duration_ms", "label_en": "Min speech duration (ms)", "default": 250, "minimum": 0, "step": 10, "precision": 0}, + {"name": "min_silence_duration_ms", "type": "number", "label": "min_silence_duration_ms", "label_en": "Min silence duration (ms)", "default": 100, "minimum": 0, "step": 10, "precision": 0}, + {"name": "speech_pad_ms", "type": "number", "label": "speech_pad_ms", "label_en": "Speech padding (ms)", "default": 30, "minimum": 0, "step": 10, "precision": 0}, + {"name": "min_silence_at_max_speech_ms", "type": "number", "label": "min_silence_at_max_speech_ms", "label_en": "Min silence at max speech (ms)", "default": 98, "minimum": 0, "step": 10, "precision": 0}, + {"name": "use_max_poss_sil_at_max_speech", "type": "bool", "label": "use_max_poss_sil_at_max_speech", "label_en": "Split at the longest silence when max speech is reached", "default": true} + ], + + "marblenet_vad": [ + {"name": "threshold", "type": "slider", "label": "threshold", "label_en": "Speech probability threshold", "default": 0.5, "minimum": 0.0, "maximum": 1.0, "step": 0.01} + ], + + "sortformer_diar": [ + {"name": "speaker_threshold", "type": "slider", "label": "speaker_threshold", "label_en": "Speaker probability threshold", "default": 0.5, "minimum": 0.0, "maximum": 1.0, "step": 0.01}, + {"name": "speaker_min_frames", "type": "number", "label": "speaker_min_frames", "label_en": "Min speaker frames", "default": 0, "minimum": 0, "step": 1, "precision": 0, "info_en": "0 disables the minimum-length filter."}, + {"name": "speaker_pad_frames", "type": "number", "label": "speaker_pad_frames", "label_en": "Speaker pad frames", "default": 0, "minimum": 0, "step": 1, "precision": 0} + ], + + "qwen3_forced_aligner": [ + {"name": "clamp_timestamps_to_audio", "type": "bool", "label": "clamp_timestamps_to_audio", "label_en": "Clamp timestamps to audio length", "default": false} ] } diff --git a/webui/configs/models_catalog.json b/webui/configs/models_catalog.json index 924c2fd99..27dccaf58 100644 --- a/webui/configs/models_catalog.json +++ b/webui/configs/models_catalog.json @@ -3,34 +3,42 @@ "port": 8088, "device": 0, "threads": 1, - "_comment": "Native WebUI catalog for model families enabled in registry.cpp. The embedded server loads one selected model or precision at a time and resolves paths relative to the configured models root. Missing packages appear as not installed; the Models page invokes the repository-level model_manager_v2.py through the server to install spec-backed GGUF packages in the background. 'task' must be one of: tts, asr, vad, diar, sep, gen, clon, vc, s2s, align, vdes, spk, svc. 'download_id' is a model_specs package id and is omitted for bundled assets such as silero_vad. Optional per-entry keys include input_hint, default_options, session_options, and min_vram_gb. min_vram_gb is an estimated minimum CUDA VRAM value used only for UI guidance.", + "_comment": "Native WebUI catalog for model families enabled in registry.cpp. The embedded server loads one selected model or precision at a time and resolves paths relative to the configured models root. Missing packages appear as not installed; the Models page invokes the repository-level model_manager_v2.py through the server to install spec-backed GGUF packages in the background. 'task' must be one of: tts, asr, vad, diar, sep, gen, clon, vc, s2s, align, vdes, spk, svc, midi. 'download_id' must be the exact model_specs packages[].id this entry installs and loads -- not a family name or a legacy alias -- and 'path' must be that package's install location (models//). Both are omitted for bundled assets such as silero_vad and marblenet_vad. Optional per-entry keys include input_hint, default_options, session_options, and min_vram_gb. min_vram_gb is an estimated minimum CUDA VRAM value used only for UI guidance.", "models": [ - { "id": "omnivoice", "display_name": "OmniVoice (tts)", "family": "omnivoice", "path": "models/OmniVoice", "task": "tts", "mode": "offline", "download_id": "omnivoice", "min_vram_gb": 10 }, - { "id": "pocket-tts", "display_name": "Pocket TTS (tts)", "family": "pocket_tts", "path": "models/pocket-tts", "task": "tts", "mode": "offline", "download_id": "pocket_tts", "min_vram_gb": 2 }, - { "id": "dots-tts-soar", "display_name": "DotTTS SOAR (tts + clone)", "family": "dots_tts", "path": "models/DotTTS-SOAR-GGUF", "task": "tts", "mode": "offline", "download_id": "dots_tts_soar_q8_0", "min_vram_gb": 8 }, - { "id": "dots-tts-meanflow", "display_name": "DotTTS MeanFlow (tts + clone)", "family": "dots_tts", "path": "models/DotTTS-MF-GGUF", "task": "tts", "mode": "offline", "download_id": "dots_tts_mf_q8_0", "min_vram_gb": 8 }, - { "id": "neutts-2e", "display_name": "NeuTTS 2E (tts, preset voices)", "family": "neutts", "path": "models/NeuTTS-2E-GGUF", "task": "tts", "mode": "offline", "download_id": "neutts_2e_orig", "min_vram_gb": 4 }, - { "id": "qwen3-tts", "display_name": "Qwen3-TTS 0.6B (tts)", "family": "qwen3_tts", "path": "models/Qwen3-TTS-12Hz-0.6B-Base", "task": "tts", "mode": "offline", "download_id": "qwen3_tts_0_6b_base", "min_vram_gb": 5 }, - { "id": "qwen3-tts-1.7b", "display_name": "Qwen3-TTS 1.7B Base (tts)", "family": "qwen3_tts", "path": "models/Qwen3-TTS-12Hz-1.7B-Base", "task": "tts", "mode": "offline", "download_id": "qwen3_tts_1_7b_base", "min_vram_gb": 8 }, - { "id": "qwen3-tts-1.7b-custom", "display_name": "Qwen3-TTS 1.7B CustomVoice (tts)", "family": "qwen3_tts", "path": "models/Qwen3-TTS-12Hz-1.7B-CustomVoice", "task": "tts", "mode": "offline", "download_id": "qwen3_tts_1_7b_custom_voice", "min_vram_gb": 8 }, - { "id": "miotts", "display_name": "MioTTS 1.7B (tts; needs MioCodec)", "family": "miotts", "path": "models/MioTTS-1.7B", "task": "tts", "mode": "offline", "download_id": "miotts_1_7b", "min_vram_gb": 8 }, - { "id": "soprano-tts", "display_name": "Soprano TTS (tts)", "family": "soprano_tts", "path": "models/Soprano-1.1-80M-GGUF", "task": "tts", "mode": "offline", "download_id": "soprano_1_1_80m_q8_0", "min_vram_gb": 1 }, - { "id": "voxcpm2", "display_name": "VoxCPM2 (tts)", "family": "voxcpm2", "path": "models/VoxCPM2", "task": "tts", "mode": "offline", "download_id": "voxcpm2", "session_options": { "voxcpm2.weight_type": "q8_0" }, "min_vram_gb": 6 }, - { "id": "voxcpm1", "display_name": "VoxCPM1 0.5B (tts + clone)", "family": "voxcpm1", "path": "models/VoxCPM1-GGUF", "task": "tts", "mode": "offline", "download_id": "voxcpm1_0.5b_q8_0", "min_vram_gb": 4 }, - { "id": "vibevoice", "display_name": "VibeVoice 1.5B/7B (tts, long-form/multi-speaker)", "family": "vibevoice", "path": "models/VibeVoice-1.5B", "task": "tts", "mode": "offline", "download_id": "vibevoice_1_5b", "min_vram_gb": 7 }, - { "id": "vibevoice-7b", "display_name": "VibeVoice 7B (tts, long-form/multi-speaker)", "family": "vibevoice", "path": "models/VibeVoice-7B-GGUF", "task": "tts", "mode": "offline", "download_id": "vibevoice_7b_q8_0", "min_vram_gb": 16 }, - { "id": "index-tts2", "display_name": "IndexTTS2 (tts 中英克隆+情感)", "display_name_en": "IndexTTS2 (tts, zh/en clone + emotion)", "family": "index_tts2", "path": "models/IndexTTS-2", "task": "tts", "mode": "offline", "download_id": "index_tts2", "min_vram_gb": 8 }, - { "id": "index-tts2.5", "display_name": "IndexTTS2.5 (tts 多语种克隆+情感, GGUF Q8)", "display_name_en": "IndexTTS2.5 (tts, zh/en/ja/es/ar clone + emotion, GGUF Q8)", "family": "index_tts2", "path": "models/IndexTTS2.5-GGUF", "task": "tts", "mode": "offline", "download_id": "index_tts2_5_q8_0", "min_vram_gb": 8, + { "id": "omnivoice", "display_name": "OmniVoice (tts)", "family": "omnivoice", "path": "models/OmniVoice-GGUF/omnivoice-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "omnivoice_q8_0", "min_vram_gb": 10 }, + { "id": "pocket-tts", "display_name": "Pocket TTS (tts)", "family": "pocket_tts", "path": "models/PocketTTS-GGUF/english/pocket-tts-english-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "pocket_tts_english_q8_0", "min_vram_gb": 2 }, + { "id": "pocket-tts-german", "display_name": "Pocket TTS German (voice clone)", "family": "pocket_tts", "path": "models/PocketTTS-GGUF/german/pocket-tts-german-q8_0.gguf", "task": "clon", "mode": "offline", "download_id": "pocket_tts_german_q8_0", "min_vram_gb": 2, + "input_hint_en": "**Pocket TTS German**: German offline speech. Unlike the English package this checkpoint ships no packaged voice embedding, so a reference voice upload is required." }, + { "id": "pocket-tts-italian", "display_name": "Pocket TTS Italian (voice clone)", "family": "pocket_tts", "path": "models/PocketTTS-GGUF/italian/pocket-tts-italian-q8_0.gguf", "task": "clon", "mode": "offline", "download_id": "pocket_tts_italian_q8_0", "min_vram_gb": 2, + "input_hint_en": "**Pocket TTS Italian**: Italian offline speech. Unlike the English package this checkpoint ships no packaged voice embedding, so a reference voice upload is required." }, + { "id": "pocket-tts-portuguese", "display_name": "Pocket TTS Portuguese (voice clone)", "family": "pocket_tts", "path": "models/PocketTTS-GGUF/portuguese/pocket-tts-portuguese-q8_0.gguf", "task": "clon", "mode": "offline", "download_id": "pocket_tts_portuguese_q8_0", "min_vram_gb": 2, + "input_hint_en": "**Pocket TTS Portuguese**: Portuguese offline speech. Unlike the English package this checkpoint ships no packaged voice embedding, so a reference voice upload is required." }, + { "id": "pocket-tts-spanish", "display_name": "Pocket TTS Spanish (voice clone)", "family": "pocket_tts", "path": "models/PocketTTS-GGUF/spanish/pocket-tts-spanish-q8_0.gguf", "task": "clon", "mode": "offline", "download_id": "pocket_tts_spanish_q8_0", "min_vram_gb": 2, + "input_hint_en": "**Pocket TTS Spanish**: Spanish offline speech. Unlike the English package this checkpoint ships no packaged voice embedding, so a reference voice upload is required." }, + { "id": "dots-tts-soar", "display_name": "DotTTS SOAR (tts + clone)", "family": "dots_tts", "path": "models/DotTTS-SOAR-GGUF/dots-tts-soar-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "dots_tts_soar_q8_0", "min_vram_gb": 8 }, + { "id": "dots-tts-meanflow", "display_name": "DotTTS MeanFlow (tts + clone)", "family": "dots_tts", "path": "models/DotTTS-MF-GGUF/dots-tts-mf-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "dots_tts_mf_q8_0", "min_vram_gb": 8 }, + { "id": "neutts-2e", "display_name": "NeuTTS 2E (tts, preset voices)", "family": "neutts", "path": "models/NeuTTS-2E-GGUF/neutts-2e-orig.gguf", "task": "tts", "mode": "offline", "download_id": "neutts_2e_orig", "min_vram_gb": 4 }, + { "id": "qwen3-tts", "display_name": "Qwen3-TTS 0.6B (tts)", "family": "qwen3_tts", "path": "models/Qwen3-TTS-12Hz-0.6B-Base-GGUF/qwen3-tts-12hz-0.6b-base-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "qwen3_tts_0_6b_base_q8_0", "min_vram_gb": 5 }, + { "id": "qwen3-tts-1.7b", "display_name": "Qwen3-TTS 1.7B Base (tts)", "family": "qwen3_tts", "path": "models/Qwen3-TTS-12Hz-1.7B-Base-GGUF/qwen3-tts-12hz-1.7b-base-q8_0_v2.gguf", "task": "tts", "mode": "offline", "download_id": "qwen3_tts_1_7b_base_q8_0", "min_vram_gb": 8 }, + { "id": "qwen3-tts-1.7b-custom", "display_name": "Qwen3-TTS 1.7B CustomVoice (tts)", "family": "qwen3_tts", "path": "models/Qwen3-TTS-12Hz-1.7B-CustomVoice-GGUF/qwen3-tts-12hz-1.7b-customvoice-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "qwen3_tts_1_7b_customvoice_q8_0", "min_vram_gb": 8 }, + { "id": "miotts", "display_name": "MioTTS 1.7B (tts; needs MioCodec)", "family": "miotts", "path": "models/MioTTS-1.7B-GGUF/miotts-1.7b-q8_0.gguf", "task": "clon", "mode": "offline", "download_id": "miotts_1_7b_q8_0", "min_vram_gb": 8 }, + { "id": "soprano-tts", "display_name": "Soprano TTS (tts)", "family": "soprano_tts", "path": "models/Soprano-1.1-80M-GGUF/soprano-1.1-80m-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "soprano_1_1_80m_q8_0", "min_vram_gb": 1 }, + { "id": "voxcpm2", "display_name": "VoxCPM2 (tts)", "family": "voxcpm2", "path": "models/VoxCPM2-GGUF/voxcpm2-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "voxcpm2_q8_0", "session_options": { "voxcpm2.weight_type": "q8_0" }, "min_vram_gb": 6 }, + { "id": "voxcpm1", "display_name": "VoxCPM1 0.5B (tts + clone)", "family": "voxcpm1", "path": "models/VoxCPM1-GGUF/voxcpm-0.5b-q8_0-audiovae-f16.gguf", "task": "tts", "mode": "offline", "download_id": "voxcpm1_0.5b_q8_0", "min_vram_gb": 4 }, + { "id": "vibevoice", "display_name": "VibeVoice 1.5B/7B (tts, long-form/multi-speaker)", "family": "vibevoice", "path": "models/VibeVoice-1.5B-GGUF/vibevoice-1.5b-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "vibevoice_1_5b_q8_0", "min_vram_gb": 7 }, + { "id": "vibevoice-7b", "display_name": "VibeVoice 7B (tts, long-form/multi-speaker)", "family": "vibevoice", "path": "models/VibeVoice-7B-GGUF/vibevoice-7b-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "vibevoice_7b_q8_0", "min_vram_gb": 16 }, + { "id": "index-tts2", "display_name": "IndexTTS2 (tts 中英克隆+情感)", "display_name_en": "IndexTTS2 (tts, zh/en clone + emotion)", "family": "index_tts2", "path": "models/IndexTTS2-GGUF/index-tts2-q8_0.gguf", "task": "clon", "mode": "offline", "download_id": "index_tts2_q8_0", "min_vram_gb": 8 }, + { "id": "index-tts2.5", "display_name": "IndexTTS2.5 (tts 多语种克隆+情感, GGUF Q8)", "display_name_en": "IndexTTS2.5 (tts, zh/en/ja/es/ar clone + emotion, GGUF Q8)", "family": "index_tts2", "path": "models/IndexTTS2.5-GGUF/index-tts2_5-q8_0.gguf", "task": "clon", "mode": "offline", "download_id": "index_tts2_5_q8_0", "min_vram_gb": 8, "input_hint": "**IndexTTS2.5**:中/英/日/西/阿零样本克隆;上传参考音色即克隆;可在『其它参数(JSON)』里传 `lang`(默认 auto:含汉字按中文,否则按英文)与情感选项。许可证为 bilibili Model Use License(非 OSI),商用前请确认条款。", "input_hint_en": "**IndexTTS2.5**: zero-shot cloning in zh/en/ja/es/ar. Upload a reference voice to clone; pass `lang` (default auto: zh when the text contains Han characters, otherwise en) and emotion options through the JSON box. Weights are under the bilibili Model Use License (not OSI-approved) — check terms before commercial use." }, - { "id": "irodori-tts", "display_name": "Irodori-TTS v4 Small (tts 日语, GGUF Q8)", "display_name_en": "Irodori-TTS v4 Small (ja tts, GGUF Q8)", "family": "irodori_tts", "path": "models/Irodori-TTS-v4-Small-GGUF", "task": "tts", "mode": "offline", "download_id": "irodori_tts_v4_small_q8_0", "min_vram_gb": 4, + { "id": "irodori-tts", "display_name": "Irodori-TTS v4 Small (tts 日语, GGUF Q8)", "display_name_en": "Irodori-TTS v4 Small (ja tts, GGUF Q8)", "family": "irodori_tts", "path": "models/Irodori-TTS-v4-Small-GGUF/irodori-tts-v4-small-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "irodori_tts_v4_small_q8_0", "min_vram_gb": 4, "input_hint": "**Irodori-TTS v4 Small**:日语 TTS;可不上传参考音色直接生成,也可上传参考音色进行克隆;可在声音设计页用日语 caption 描述音色。", "input_hint_en": "**Irodori-TTS v4 Small**: Japanese TTS. Generate without a reference voice, clone from an uploaded reference, or use the voice-design page with a Japanese voice caption." }, - { "id": "irodori-tts-v3-500m", "display_name": "Irodori-TTS 500M v3 (tts 日语)", "display_name_en": "Irodori-TTS 500M v3 (ja tts)", "family": "irodori_tts", "path": "models/Irodori-TTS-500M-v3-GGUF", "task": "tts", "mode": "offline", "download_id": "irodori_tts_500m_v3_q8_0", "min_vram_gb": 4 }, - { "id": "moss-tts-local", "display_name": "MOSS-TTS-Local v1.5 (tts)", "family": "moss_tts_local", "path": "models/MOSS-TTS-Local-Transformer-v1.5", "task": "tts", "mode": "offline", "download_id": "moss_tts_local_v1_5", "min_vram_gb": 8 }, - { "id": "moss-tts-nano", "display_name": "MOSS-TTS-Nano 100M (tts)", "family": "moss_tts_nano", "path": "models/MOSS-TTS-Nano-100M", "task": "tts", "mode": "offline", "download_id": "moss_tts_nano_100m", "min_vram_gb": 2 }, - { "id": "magpie-tts", "display_name": "MagpieTTS Multilingual 357M v2607 (tts, preset voices)", "display_name_en": "MagpieTTS Multilingual 357M v2607 (tts, preset voices)", "family": "magpie_tts", "path": "models/MagpieTTS-Multilingual-357M-GGUF", "task": "tts", "mode": "offline", "download_id": "magpie_tts_q8_0", "min_vram_gb": 4, + { "id": "irodori-tts-v3-500m", "display_name": "Irodori-TTS 500M v3 (tts 日语)", "display_name_en": "Irodori-TTS 500M v3 (ja tts)", "family": "irodori_tts", "path": "models/Irodori-TTS-500M-v3-GGUF/irodori-tts-500m-v3-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "irodori_tts_500m_v3_q8_0", "min_vram_gb": 4 }, + { "id": "moss-tts-local", "display_name": "MOSS-TTS-Local v1.5 (tts)", "family": "moss_tts_local", "path": "models/MOSS-TTS-Local-v1.5-GGUF/moss-tts-local-v1.5-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "moss_tts_local_v1_5_q8_0", "min_vram_gb": 8 }, + { "id": "moss-tts-nano", "display_name": "MOSS-TTS-Nano 100M (tts)", "family": "moss_tts_nano", "path": "models/MOSS-TTS-Nano-100M-GGUF/moss-tts-nano-100m-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "moss_tts_nano_100m_q8_0", "min_vram_gb": 2 }, + { "id": "magpie-tts", "display_name": "MagpieTTS Multilingual 357M v2607 (tts, preset voices)", "display_name_en": "MagpieTTS Multilingual 357M v2607 (tts, preset voices)", "family": "magpie_tts", "path": "models/MagpieTTS-Multilingual-357M-GGUF/magpie-tts-multilingual-357m-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "magpie_tts_q8_0", "min_vram_gb": 4, "input_hint": "**MagpieTTS**:多语种离线 TTS;使用打包 speaker map 里的 `voice_id`,不需要上传参考音频。当前 GGUF 包不包含日语 phoneme 表,因此日语路径不可用。", "input_hint_en": "**MagpieTTS**: multilingual offline TTS with packaged speaker prompts selected by `voice_id`; no reference upload is needed. The current GGUF package does not include the Japanese phoneme table, so Japanese is not available." }, { "id": "fireredtts3-instruct", "display_name": "FireRedTTS3 Instruct Clone", "family": "fireredtts3", "path": "models/FireRedTTS3-Instruct-GGUF/fireredtts3-instruct-q8_0.gguf", "task": "clon", "mode": "offline", "download_id": "fireredtts3_instruct_q8_0", "min_vram_gb": 8, @@ -39,44 +47,60 @@ "input_hint_en": "**FireRedTTS3 Base**: zero-shot voice cloning. Upload a reference voice and provide the matching reference transcript." }, { "id": "firered-audio-tts", "display_name": "FireRedAudio Clone", "family": "firered_audio", "path": "models/FireRedAudio-GGUF/firered-audio-q8_0.gguf", "task": "clon", "mode": "offline", "download_id": "firered_audio_q8_0", "min_vram_gb": 10, "input_hint_en": "**FireRedAudio Clone**: upload a reference voice and provide the matching reference transcript. For no-reference voice design, use the VoiceDesign entry." }, - { "id": "supertonic", "display_name": "Supertonic 3 (tts 预置音色/多语种)", "display_name_en": "Supertonic 3 (tts, preset voices)", "family": "supertonic", "path": "models/supertonic-3", "task": "tts", "mode": "offline", "download_id": "supertonic_3", "min_vram_gb": 2 }, - { "id": "higgs-audio-tts", "display_name": "Higgs Audio v3 TTS 4B (tts 克隆, GGUF Q8)", "display_name_en": "Higgs Audio v3 TTS 4B (tts + clone, GGUF Q8)", "family": "higgs_audio_tts", "path": "models/Higgs-Audio-v3-TTS-4B-GGUF", "task": "tts", "mode": "offline", "download_id": "higgs_audio_v3_tts_4b", "min_vram_gb": 6, + { "id": "supertonic", "display_name": "Supertonic 3 (tts 预置音色/多语种)", "display_name_en": "Supertonic 3 (tts, preset voices)", "family": "supertonic", "path": "models/Supertonic-3-GGUF/supertonic-3-orig.gguf", "task": "tts", "mode": "offline", "download_id": "supertonic_3_orig", "min_vram_gb": 2 }, + { "id": "higgs-audio-tts", "display_name": "Higgs Audio v3 TTS 4B (tts 克隆, GGUF Q8)", "display_name_en": "Higgs Audio v3 TTS 4B (tts + clone, GGUF Q8)", "family": "higgs_audio_tts", "path": "models/Higgs-Audio-v3-TTS-4B-GGUF/higgs-audio-v3-tts-4b-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "higgs_audio_tts_4b_q8_0", "min_vram_gb": 6, "input_hint": "**Higgs Audio v3 TTS**:Q8_0 GGUF 包(权重已量化,不用再设 weight_type);上传参考音色即声音克隆,留空用默认音色;长文本自动分段。", "input_hint_en": "**Higgs Audio v3 TTS**: Q8_0 GGUF package (already quantized — no weight_type needed). Upload a reference voice to clone, or leave it empty for the default voice; long text is chunked automatically." }, - { "id": "fish-audio-s2-pro", "display_name": "Fish Audio S2 Pro (tts 克隆/控制标记, GGUF Q8)", "display_name_en": "Fish Audio S2 Pro (tts + clone/control tags, GGUF Q8)", "family": "fish_audio", "path": "models/Fish-Audio-S2-Pro-GGUF", "task": "tts", "mode": "offline", "download_id": "fish_audio_s2_pro", "min_vram_gb": 8, + { "id": "fish-audio-s2-pro", "display_name": "Fish Audio S2 Pro (tts 克隆/控制标记, GGUF Q8)", "display_name_en": "Fish Audio S2 Pro (tts + clone/control tags, GGUF Q8)", "family": "fish_audio", "path": "models/Fish-Audio-S2-Pro-GGUF/fish-audio-s2-pro-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "fish_audio_s2_pro_q8_0", "min_vram_gb": 8, "input_hint": "**Fish Audio S2 Pro**:Q8_0 GGUF 包;中英+自动语种;上传参考音色即克隆;正文里可写行内控制标记(如 (laugh))。", "input_hint_en": "**Fish Audio S2 Pro**: Q8_0 GGUF package; English/Chinese plus auto language. Upload a reference voice to clone; inline control tags such as (laugh) can be written in the text." }, - { "id": "glm-tts", "display_name": "GLM-TTS (tts 克隆, 社区)", "display_name_en": "GLM-TTS (tts + clone, community)", "family": "glm_tts", "path": "models/GLM-TTS", "task": "tts", "mode": "offline", "download_id": "glm_tts", "min_vram_gb": 8, + { "id": "glm-tts", "display_name": "GLM-TTS (tts 克隆, 社区)", "display_name_en": "GLM-TTS (tts + clone, community)", "family": "glm_tts", "path": "models/GLM-TTS-Q8/Text to audio (TTS)/GLM-TTS_Q8.gguf", "task": "clon", "mode": "offline", "download_id": "glm_tts_q8_0", "min_vram_gb": 8, "input_hint": "**GLM-TTS**(社区模型):中英 TTS / voice clone;上传参考音色即克隆。", "input_hint_en": "**GLM-TTS** (community): Chinese/English TTS and voice clone. Upload a reference voice to clone." }, - { "id": "outetts", "display_name": "Llama-OuteTTS 1.0 1B (tts 克隆, 社区)", "display_name_en": "Llama-OuteTTS 1.0 1B (tts + clone, community)", "family": "outetts", "path": "models/Llama-OuteTTS-1.0-1B", "task": "tts", "mode": "offline", "download_id": "outetts_1_0_1b", "min_vram_gb": 4, + { "id": "outetts", "display_name": "Llama-OuteTTS 1.0 1B (tts 克隆, 社区)", "display_name_en": "Llama-OuteTTS 1.0 1B (tts + clone, community)", "family": "outetts", "path": "models/Llama-OuteTTS-1.0-1B_Q8/Text to audio (TTS)/Llama-OuteTTS-1.0-1B_Q8.gguf", "task": "tts", "mode": "offline", "download_id": "outetts_1_0_1b_q8_0", "min_vram_gb": 4, "input_hint": "**OuteTTS 1.0 1B**(社区模型):23 种语言,DAC 编解码;上传参考音色即克隆。", "input_hint_en": "**OuteTTS 1.0 1B** (community): 23 languages, IBM DAC codec. Upload a reference voice to clone." }, - { "id": "vietneu-tts", "display_name": "VieNeu-TTS v3 Turbo (tts 越南语, 社区)", "display_name_en": "VieNeu-TTS v3 Turbo (vi tts, community)", "family": "vietneu_tts", "path": "models/VieNeu-TTS-v3-Turbo", "task": "tts", "mode": "offline", "download_id": "vietneu_tts_v3_turbo", "min_vram_gb": 4, + { "id": "vietneu-tts", "display_name": "VieNeu-TTS v3 Turbo (tts 越南语, 社区)", "display_name_en": "VieNeu-TTS v3 Turbo (vi tts, community)", "family": "vietneu_tts", "path": "models/VieNeu-TTS-v3-Turbo-GGUF/model.gguf", "task": "clon", "mode": "offline", "download_id": "vietneu_tts_v3_turbo_q8_0", "min_vram_gb": 4, "input_hint": "**VieNeu-TTS v3 Turbo**(社区模型):越南语 / 英语;上传参考音色即克隆。", "input_hint_en": "**VieNeu-TTS v3 Turbo** (community): Vietnamese and English. Upload a reference voice to clone." }, - { "id": "inflect-v2", "display_name": "Inflect Micro v2 (tts 英语, 社区)", "display_name_en": "Inflect Micro v2 (en tts, community)", "family": "inflect_v2", "path": "models/Inflect-Micro-v2", "task": "tts", "mode": "offline", "download_id": "inflect_micro_v2", "min_vram_gb": 2, + { "id": "inflect-v2", "display_name": "Inflect Micro v2 (tts 英语, 社区)", "display_name_en": "Inflect Micro v2 (en tts, community)", "family": "inflect_v2", "path": "models/Inflect-Micro-v2-GGUF/inflect-micro-v2-orig.gguf", "task": "tts", "mode": "offline", "download_id": "inflect_micro_v2_orig", "min_vram_gb": 2, "input_hint": "**Inflect Micro v2**(社区模型):英语离线 TTS;Micro 是默认包,Nano 可通过模型管理器另装后手动选择路径。", "input_hint_en": "**Inflect Micro v2** (community): English offline TTS. Micro is the default package; Nano can be installed separately and selected manually." }, - { "id": "dramabox", "display_name": "DramaBox (tts 克隆, GGUF Q8)", "display_name_en": "DramaBox (tts + clone, GGUF Q8)", "family": "dramabox", "path": "models/DramaBox-GGUF", "task": "tts", "mode": "offline", "download_id": "dramabox_q8_0", "min_vram_gb": 16, + { "id": "dramabox", "display_name": "DramaBox (tts 克隆, GGUF Q8)", "display_name_en": "DramaBox (tts + clone, GGUF Q8)", "family": "dramabox", "path": "models/DramaBox-GGUF/dramabox-q8_0.gguf", "task": "tts", "mode": "offline", "download_id": "dramabox_q8_0", "min_vram_gb": 16, "input_hint": "**DramaBox**:英语 TTS / voice clone;上传参考音色可克隆,长文本建议写清楚说话人描述。", "input_hint_en": "**DramaBox**: English TTS and voice clone. Upload a reference voice to clone; for long text, keep speaker wording explicit." }, - { "id": "confucius4-tts", "display_name": "Confucius4-TTS (voice clone, GGUF)", "display_name_en": "Confucius4-TTS (voice clone, GGUF)", "family": "confucius4_tts", "path": "models/Confucius4-TTS-GGUF", "task": "clon", "mode": "offline", "download_id": "confucius4_tts_orig", "min_vram_gb": 8, + { "id": "confucius4-tts", "display_name": "Confucius4-TTS (voice clone, GGUF)", "display_name_en": "Confucius4-TTS (voice clone, GGUF)", "family": "confucius4_tts", "path": "models/Confucius4-TTS-GGUF/confucius4-tts-orig.gguf", "task": "clon", "mode": "offline", "download_id": "confucius4_tts_orig", "min_vram_gb": 8, "input_hint": "**Confucius4-TTS**:需要参考音色;当前中文/英语路径更可靠,非中英语种仍在验证中。", "input_hint_en": "**Confucius4-TTS**: requires a reference voice. Chinese/English are the most reliable paths; other languages are still being validated." }, - { "id": "echo-tts", "display_name": "Echo-TTS (voice clone)", "family": "echo_tts", "path": "models/Echo-TTS-GGUF", "task": "clon", "mode": "offline", "download_id": "echo_tts_q8_0", "min_vram_gb": 8, + { "id": "echo-tts", "display_name": "Echo-TTS (voice clone)", "family": "echo_tts", "path": "models/Echo-TTS-GGUF/echo-tts-q8_0.gguf", "task": "clon", "mode": "offline", "download_id": "echo_tts_q8_0", "min_vram_gb": 8, "input_hint_en": "**Echo-TTS**: English zero-shot cloning at 44.1 kHz. Upload a reference voice -- no transcript needed. Output is CC-BY-NC-SA and may not be used commercially." }, - { "id": "chatterbox", "display_name": "Chatterbox (voice clone)", "family": "chatterbox", "path": "models/chatterbox", "task": "clon", "mode": "offline", "download_id": "chatterbox", "min_vram_gb": 12 }, + { "id": "chatterbox", "display_name": "Chatterbox (voice clone)", "family": "chatterbox", "path": "models/Chatterbox-GGUF/chatterbox-q8_0.gguf", "task": "clon", "mode": "offline", "download_id": "chatterbox_q8_0", "min_vram_gb": 12 }, + { "id": "f5-tts-habibi", "display_name": "F5-TTS Habibi Unified (voice clone, ar)", "family": "f5_tts", "path": "models/Habibi-TTS/Unified/habibi-unified-orig.gguf", "task": "clon", "mode": "offline", "download_id": "habibi_unified", "min_vram_gb": 4, + "input_hint_en": "**F5-TTS Habibi Unified**: Arabic zero-shot cloning across dialects. Upload a reference voice and provide the matching reference transcript; select a dialect with `dialect` (MSA, SAU, UAE, ALG, IRQ, EGY, MAR, ...) in the JSON box. Weights are cc-by-nc-sa-4.0 (F5-TTS Base is cc-by-nc-4.0) -- non-commercial use only." }, + { "id": "f5-tts-habibi-alg", "display_name": "F5-TTS Habibi Algerian (voice clone, ar-ALG)", "family": "f5_tts", "path": "models/Habibi-TTS/Specialized/ALG/habibi-alg-orig.gguf", "task": "clon", "mode": "offline", "download_id": "habibi_alg", "min_vram_gb": 4, + "input_hint_en": "**F5-TTS Habibi Algerian**: Arabic zero-shot cloning specialised for the Algerian checkpoint. Upload a reference voice and provide the matching reference transcript. Weights are cc-by-nc-sa-4.0 (F5-TTS Base is cc-by-nc-4.0) -- non-commercial use only." }, + { "id": "f5-tts-habibi-egy", "display_name": "F5-TTS Habibi Egyptian (voice clone, ar-EGY)", "family": "f5_tts", "path": "models/Habibi-TTS/Specialized/EGY/habibi-egy-orig.gguf", "task": "clon", "mode": "offline", "download_id": "habibi_egy", "min_vram_gb": 4, + "input_hint_en": "**F5-TTS Habibi Egyptian**: Arabic zero-shot cloning specialised for the Egyptian checkpoint. Upload a reference voice and provide the matching reference transcript. Weights are cc-by-nc-sa-4.0 (F5-TTS Base is cc-by-nc-4.0) -- non-commercial use only." }, + { "id": "f5-tts-habibi-irq", "display_name": "F5-TTS Habibi Iraqi (voice clone, ar-IRQ)", "family": "f5_tts", "path": "models/Habibi-TTS/Specialized/IRQ/habibi-irq-orig.gguf", "task": "clon", "mode": "offline", "download_id": "habibi_irq", "min_vram_gb": 4, + "input_hint_en": "**F5-TTS Habibi Iraqi**: Arabic zero-shot cloning specialised for the Iraqi checkpoint. Upload a reference voice and provide the matching reference transcript. Weights are cc-by-nc-sa-4.0 (F5-TTS Base is cc-by-nc-4.0) -- non-commercial use only." }, + { "id": "f5-tts-habibi-mar", "display_name": "F5-TTS Habibi Moroccan (voice clone, ar-MAR)", "family": "f5_tts", "path": "models/Habibi-TTS/Specialized/MAR/habibi-mar-orig.gguf", "task": "clon", "mode": "offline", "download_id": "habibi_mar", "min_vram_gb": 4, + "input_hint_en": "**F5-TTS Habibi Moroccan**: Arabic zero-shot cloning specialised for the Moroccan checkpoint. Upload a reference voice and provide the matching reference transcript. Weights are cc-by-nc-sa-4.0 (F5-TTS Base is cc-by-nc-4.0) -- non-commercial use only." }, + { "id": "f5-tts-habibi-msa", "display_name": "F5-TTS Habibi Modern Standard Arabic (voice clone, ar-MSA)", "family": "f5_tts", "path": "models/Habibi-TTS/Specialized/MSA/habibi-msa-orig.gguf", "task": "clon", "mode": "offline", "download_id": "habibi_msa", "min_vram_gb": 4, + "input_hint_en": "**F5-TTS Habibi Modern Standard Arabic**: Arabic zero-shot cloning specialised for the Modern Standard Arabic checkpoint. Upload a reference voice and provide the matching reference transcript. Weights are cc-by-nc-sa-4.0 (F5-TTS Base is cc-by-nc-4.0) -- non-commercial use only." }, + { "id": "f5-tts-habibi-sau", "display_name": "F5-TTS Habibi Saudi (voice clone, ar-SAU)", "family": "f5_tts", "path": "models/Habibi-TTS/Specialized/SAU/habibi-sau-orig.gguf", "task": "clon", "mode": "offline", "download_id": "habibi_sau", "min_vram_gb": 4, + "input_hint_en": "**F5-TTS Habibi Saudi**: Arabic zero-shot cloning specialised for the Saudi checkpoint. Upload a reference voice and provide the matching reference transcript. Weights are cc-by-nc-sa-4.0 (F5-TTS Base is cc-by-nc-4.0) -- non-commercial use only." }, + { "id": "f5-tts-habibi-uae", "display_name": "F5-TTS Habibi Emirati (voice clone, ar-UAE)", "family": "f5_tts", "path": "models/Habibi-TTS/Specialized/UAE/habibi-uae-orig.gguf", "task": "clon", "mode": "offline", "download_id": "habibi_uae", "min_vram_gb": 4, + "input_hint_en": "**F5-TTS Habibi Emirati**: Arabic zero-shot cloning specialised for the Emirati checkpoint. Upload a reference voice and provide the matching reference transcript. Weights are cc-by-nc-sa-4.0 (F5-TTS Base is cc-by-nc-4.0) -- non-commercial use only." }, - { "id": "ace-step", "display_name": "ACE-Step 1.5 (music gen)", "family": "ace_step", "path": "models/Ace-Step1.5", "task": "gen", "mode": "offline", "download_id": "ace_step", "session_options": { "ace_step.mem_saver": "true", "ace_step.dit_weight_type": "q8_0", "ace_step.text_encoder_weight_type": "q8_0", "ace_step.planner_weight_type": "q8_0" }, "min_vram_gb": 8 }, - { "id": "minimax-music3", "display_name": "MiniMax-Music3 (song gen)", "family": "minimax_music3", "path": "models/MiniMax-Music3-GGUF", "task": "gen", "mode": "offline", "download_id": "minimax_music3_q4_0", "min_vram_gb": 12 }, - { "id": "stable-audio-small-music","display_name": "Stable Audio 3 Small Music (gen)", "family": "stable_audio", "path": "models/stable-audio-3-small-music", "task": "gen", "mode": "offline", "download_id": "stable_audio_3_small_music", "min_vram_gb": 4 }, - { "id": "stable-audio-small-sfx", "display_name": "Stable Audio 3 Small SFX (gen)", "family": "stable_audio", "path": "models/stable-audio-3-small-sfx", "task": "gen", "mode": "offline", "download_id": "stable_audio_3_small_sfx", "min_vram_gb": 4 }, - { "id": "stable-audio-medium", "display_name": "Stable Audio 3 Medium (gen)", "family": "stable_audio", "path": "models/stable-audio-3-medium", "task": "gen", "mode": "offline", "download_id": "stable_audio_3_medium", "session_options": { "stable_audio.mem_saver": "true" }, "min_vram_gb": 10 }, - { "id": "heartmula", "display_name": "HeartMuLa 3B (music gen)", "family": "heartmula", "path": "models/HeartMuLa", "task": "gen", "mode": "offline", "download_id": "heartmula", "session_options": { "heartmula.mem_saver": "true" }, "min_vram_gb": 24 }, - { "id": "minimax-h3", "display_name": "MiniMax-H3 Q4 (sound generation)", "family": "minimax_h3", "path": "models/MiniMax-H3-Q4-GGUF/dit.gguf", "task": "gen", "mode": "offline", "download_id": "minimax_h3", "min_vram_gb": 20, + { "id": "ace-step", "display_name": "ACE-Step 1.5 (music gen)", "family": "ace_step", "path": "models/ACE-Step1.5-GGUF/turbo/ace-step-1.5-turbo-bf16.gguf", "task": "gen", "mode": "offline", "download_id": "ace_step_turbo_bf16", "session_options": { "ace_step.mem_saver": "true", "ace_step.dit_weight_type": "q8_0", "ace_step.text_encoder_weight_type": "q8_0", "ace_step.planner_weight_type": "q8_0" }, "min_vram_gb": 8 }, + { "id": "minimax-music3", "display_name": "MiniMax-Music3 (song gen)", "family": "minimax_music3", "path": "models/MiniMax-Music3-GGUF", "task": "gen", "mode": "offline", "download_id": "minimax_music3_q4_0", "min_vram_gb": 12 }, + { "id": "stable-audio-small-music","display_name": "Stable Audio 3 Small Music (gen)", "family": "stable_audio", "path": "models/Stable-Audio-3-Small-Music-GGUF/stable-audio-3-small-music-q8_0.gguf", "task": "gen", "mode": "offline", "download_id": "stable_audio_3_small_music_q8_0", "min_vram_gb": 4 }, + { "id": "stable-audio-small-sfx", "display_name": "Stable Audio 3 Small SFX (gen)", "family": "stable_audio", "path": "models/Stable-Audio-3-Small-SFX-GGUF/stable-audio-3-small-sfx-q8_0.gguf", "task": "gen", "mode": "offline", "download_id": "stable_audio_3_small_sfx_q8_0", "min_vram_gb": 4 }, + { "id": "stable-audio-medium", "display_name": "Stable Audio 3 Medium (gen)", "family": "stable_audio", "path": "models/Stable-Audio-3-Medium-GGUF/stable-audio-3-medium-q8_0.gguf", "task": "gen", "mode": "offline", "download_id": "stable_audio_3_medium_q8_0", "session_options": { "stable_audio.mem_saver": "true" }, "min_vram_gb": 10 }, + { "id": "heartmula", "display_name": "HeartMuLa 3B (music gen)", "family": "heartmula", "path": "models/HeartMuLa-GGUF/heartmula-q8_0.gguf", "task": "gen", "mode": "offline", "download_id": "heartmula_q8_0", "session_options": { "heartmula.mem_saver": "true" }, "min_vram_gb": 24 }, + { "id": "minimax-h3", "display_name": "MiniMax-H3 Q4 (sound generation)", "family": "minimax_h3", "path": "models/MiniMax-H3-Q4-GGUF/dit.gguf", "task": "gen", "mode": "offline", "download_id": "minimax_h3_q4_k", "min_vram_gb": 20, "default_options": { "num_inference_steps": 12, "height": 32, "width": 32, "num_frames": 241, "guidance_scale": 1.0, "dit_acceleration": "none", "return_video": false }, "input_hint_en": "MiniMax-H3 uses a joint audio/video DiT. The default Q4 DiT is the quality-first choice; the optional CUDA-only INT8 ConvRot DiT trades slightly more VRAM for higher speed. Native Studio uses 12 denoising steps, a 32x32 latent canvas, quality-first full-DiT execution, and disables video decoding for practical audio-only generation on a 24 GB GPU." }, { "id": "midashenglm-gen", "display_name": "MiDashengLM-Gen (audio generation)", "family": "midashenglm_gen", "path": "models/MiDashengLM-Gen-GGUF/midashenglm-gen-q8_0.gguf", "task": "gen", "mode": "offline", "download_id": "midashenglm_gen_q8_0", "min_vram_gb": 8, @@ -89,81 +113,85 @@ { "id": "firered-audio-acoustic-edit", "display_name": "FireRedAudio Acoustic Edit", "family": "firered_audio", "path": "models/FireRedAudio-GGUF/firered-audio-q8_0.gguf", "task": "gen", "mode": "offline", "download_id": "firered_audio_q8_0", "min_vram_gb": 10, "input_hint_en": "**FireRedAudio Acoustic Edit**: upload source audio and use a trained acoustic instruction such as `shift the pitch by 3 steps`." }, - { "id": "qwen3-asr", "display_name": "Qwen3-ASR 0.6B (asr)", "family": "qwen3_asr", "path": "models/Qwen3-ASR-0.6B", "task": "asr", "mode": "offline", "download_id": "qwen3_asr_0_6b", "min_vram_gb": 3 }, - { "id": "qwen3-asr-1.7b", "display_name": "Qwen3-ASR 1.7B HF (asr)", "family": "qwen3_asr", "path": "models/Qwen3-ASR-1.7B-hf", "task": "asr", "mode": "offline", "download_id": "qwen3_asr_1_7b_hf", "min_vram_gb": 6, + { "id": "qwen3-asr", "display_name": "Qwen3-ASR 0.6B (asr)", "family": "qwen3_asr", "path": "models/Qwen3-ASR-0.6B-GGUF/qwen3-asr-0.6b-q8_0.gguf", "task": "asr", "mode": "offline", "download_id": "qwen3_asr_0_6b_q8_0", "min_vram_gb": 3 }, + { "id": "qwen3-asr-1.7b", "display_name": "Qwen3-ASR 1.7B HF (asr)", "family": "qwen3_asr", "path": "models/Qwen3-ASR-1.7B-GGUF/qwen3-asr-1.7b-q8_0.gguf", "task": "asr", "mode": "offline", "download_id": "qwen3_asr_1_7b_q8_0", "min_vram_gb": 6, "input_hint": "**Qwen3-ASR 1.7B**(HF 原生权重,免转换):精度高于 0.6B;长音频自动分段转写;8G 卡显存偏紧,长音频建议先短段试跑。", "input_hint_en": "**Qwen3-ASR 1.7B**: native Hugging Face weights with no conversion required. It is more accurate than the 0.6B model and automatically chunks long audio; test short clips first on an 8 GB GPU." }, - { "id": "citrinet-asr", "display_name": "Citrinet ASR (asr)", "family": "citrinet_asr", "path": "models/citrinet", "task": "asr", "mode": "offline", "download_id": "citrinet_asr", "min_vram_gb": 2 }, - { "id": "nemotron-asr", "display_name": "Nemotron 3.5 ASR 0.6B (asr, 100+语种)", "display_name_en": "Nemotron 3.5 ASR 0.6B (asr, 100+ languages)", "family": "nemotron_asr", "path": "models/nemotron-3.5-asr-streaming-0.6b", "task": "asr", "mode": "offline", "download_id": "nemotron_asr", "min_vram_gb": 4, + { "id": "citrinet-asr", "display_name": "Citrinet ASR (asr)", "family": "citrinet_asr", "path": "models/Citrinet-ASR-GGUF/citrinet-asr-q8_0.gguf", "task": "asr", "mode": "offline", "download_id": "citrinet_asr_q8_0", "min_vram_gb": 2 }, + { "id": "nemotron-asr", "display_name": "Nemotron 3.5 ASR 0.6B (asr, 100+语种)", "display_name_en": "Nemotron 3.5 ASR 0.6B (asr, 100+ languages)", "family": "nemotron_asr", "path": "models/Nemotron-3.5-ASR-Streaming-0.6B-GGUF/nemotron-3.5-asr-streaming-0.6b-q8_0.gguf", "task": "asr", "mode": "offline", "download_id": "nemotron_asr_q8_0", "min_vram_gb": 4, "input_hint": "**Nemotron ASR**:100+ 语种,语种码为 BCP-47(如 en-US / zh-CN),留空=auto;模型自带长音频处理。", "input_hint_en": "**Nemotron ASR**: supports more than 100 languages using BCP-47 codes such as en-US or zh-CN. Leave language blank for automatic detection; long audio is handled by the model." }, - { "id": "higgs-audio-stt", "display_name": "Higgs Audio v3 STT (asr, 英语)", "display_name_en": "Higgs Audio v3 STT (asr, English)", "family": "higgs_audio_stt", "path": "models/higgs-audio-v3-stt", "task": "asr", "mode": "offline", "download_id": "higgs_audio_stt", "min_vram_gb": 8, + { "id": "higgs-audio-stt", "display_name": "Higgs Audio v3 STT (asr, 英语)", "display_name_en": "Higgs Audio v3 STT (asr, English)", "family": "higgs_audio_stt", "path": "models/Higgs-Audio-v3-STT-GGUF/higgs-audio-v3-stt-q8_0.gguf", "task": "asr", "mode": "offline", "download_id": "higgs_audio_stt_q8_0", "min_vram_gb": 8, "input_hint": "**Higgs Audio STT**:英语转写;可在文本框填指令(默认相当于 Transcribe the speech.);离线模式自动切分长音频。", "input_hint_en": "**Higgs Audio STT**: English transcription. The text box accepts an instruction; offline mode automatically chunks long audio." }, - { "id": "hviske-asr", "display_name": "Hviske v5.3 (asr, 丹麦语)", "display_name_en": "Hviske v5.3 (asr, Danish)", "family": "hviske_asr", "path": "models/hviske-v5.3", "task": "asr", "mode": "offline", "download_id": "hviske_asr", "min_vram_gb": 6, + { "id": "hviske-asr", "display_name": "Hviske v5.3 (asr, 丹麦语)", "display_name_en": "Hviske v5.3 (asr, Danish)", "family": "hviske_asr", "path": "models/Hviske-v5.3-GGUF/hviske-v5.3_Q8.gguf", "task": "asr", "mode": "offline", "download_id": "hviske_asr_q8_0", "min_vram_gb": 6, "input_hint": "**Hviske ASR**:丹麦语专用;模型侧自动分段。", "input_hint_en": "**Hviske ASR**: dedicated Danish transcription with automatic model-side segmentation." }, - { "id": "vibevoice-asr", "display_name": "VibeVoice ASR (asr, 多语种+说话人分段)", "display_name_en": "VibeVoice ASR (asr, multilingual + speaker turns)", "family": "vibevoice_asr", "path": "models/VibeVoice-ASR", "task": "asr", "mode": "offline", "download_id": "vibevoice_asr", "min_vram_gb": 20, + { "id": "vibevoice-asr", "display_name": "VibeVoice ASR (asr, 多语种+说话人分段)", "display_name_en": "VibeVoice ASR (asr, multilingual + speaker turns)", "family": "vibevoice_asr", "path": "models/VibeVoice-ASR-GGUF/vibevoice-asr-q8_0.gguf", "task": "asr", "mode": "offline", "download_id": "vibevoice_asr_q8_0", "min_vram_gb": 20, "input_hint": "**VibeVoice ASR**:自动语种,可输出分段/说话人轮次;文本框可填上下文提示(如 The recording is a meeting conversation.)。权重 17.3G,8G 卡跑不动。", "input_hint_en": "**VibeVoice ASR**: automatic language detection with segment and speaker-turn output. The text box accepts a context prompt. Its 17.3 GB weights require substantially more than 8 GB VRAM." }, - { "id": "voxtral-realtime", "display_name": "Voxtral Mini 4B Realtime (asr, 自动语种+流式)", "display_name_en": "Voxtral Mini 4B Realtime (asr, auto + streaming)", "family": "voxtral_realtime", "path": "models/Voxtral-Mini-4B-Realtime-2602-GGUF", "task": "asr", "mode": "offline", "download_id": "voxtral_realtime", "min_vram_gb": 8 }, - { "id": "fun-asr-nano", "display_name": "Fun-ASR-Nano 2512 (asr, GGUF Q8)", "display_name_en": "Fun-ASR-Nano 2512 (asr, GGUF Q8)", "family": "fun_asr_nano", "path": "models/Fun-ASR-Nano-2512-GGUF", "task": "asr", "mode": "offline", "download_id": "fun_asr_nano_2512_q8_0", "min_vram_gb": 4, + { "id": "voxtral-realtime", "display_name": "Voxtral Mini 4B Realtime (asr, 自动语种+流式)", "display_name_en": "Voxtral Mini 4B Realtime (asr, auto + streaming)", "family": "voxtral_realtime", "path": "models/Voxtral-Mini-4B-Realtime-2602-GGUF/voxtral-mini-4b-realtime-2602-q8_0.gguf", "task": "asr", "mode": "offline", "download_id": "voxtral_realtime_q8_0", "min_vram_gb": 8 }, + { "id": "fun-asr-nano", "display_name": "Fun-ASR-Nano 2512 (asr, GGUF Q8)", "display_name_en": "Fun-ASR-Nano 2512 (asr, GGUF Q8)", "family": "fun_asr_nano", "path": "models/Fun-ASR-Nano-2512-GGUF/fun-asr-nano-2512-q8_0.gguf", "task": "asr", "mode": "offline", "download_id": "fun_asr_nano_2512_q8_0", "min_vram_gb": 4, "input_hint": "**Fun-ASR-Nano**:轻量离线 ASR;支持 auto/中文/英语/日语。", "input_hint_en": "**Fun-ASR-Nano**: lightweight offline ASR; supports auto, Chinese, English and Japanese." }, - { "id": "parakeet-tdt", "display_name": "Parakeet-TDT 0.6B v3 (asr, 流式)", "display_name_en": "Parakeet-TDT 0.6B v3 (asr + streaming)", "family": "parakeet_tdt", "path": "models/parakeet-tdt-0.6b-v3", "task": "asr", "mode": "offline", "download_id": "parakeet_tdt", "min_vram_gb": 4, + { "id": "parakeet-tdt", "display_name": "Parakeet-TDT 0.6B v3 (asr, 流式)", "display_name_en": "Parakeet-TDT 0.6B v3 (asr + streaming)", "family": "parakeet_tdt", "path": "models/Parakeet-TDT-0.6B-v3-GGUF/parakeet-tdt-0.6b-v3-q8_0.gguf", "task": "asr", "mode": "offline", "download_id": "parakeet_tdt_q8_0", "min_vram_gb": 4, "input_hint": "**Parakeet-TDT**:离线/长音频/流式 ASR;支持多种欧洲语言,留空=自动。", "input_hint_en": "**Parakeet-TDT**: offline, long-form and streaming ASR for many European languages; leave language empty for auto." }, - { "id": "kroko-asr", "display_name": "Kroko Community ASR (asr, GGUF Q8)", "display_name_en": "Kroko Community ASR (asr, GGUF Q8)", "family": "kroko_asr", "path": "models/Kroko-ASR-GGUF", "task": "asr", "mode": "offline", "download_id": "kroko_asr_community_q8_0", "min_vram_gb": 4, + { "id": "kroko-asr", "display_name": "Kroko Community ASR (asr, GGUF Q8)", "display_name_en": "Kroko Community ASR (asr, GGUF Q8)", "family": "kroko_asr", "path": "models/Kroko-ASR-GGUF/kroko-en-community-64-l-q8_0.gguf", "task": "asr", "mode": "offline", "download_id": "kroko_asr_community_q8_0", "min_vram_gb": 4, "input_hint": "**Kroko Community ASR**:GGUF Q8 包;离线转写,支持时间戳。", "input_hint_en": "**Kroko Community ASR**: GGUF Q8 package for offline transcription with timestamps." }, - { "id": "granite5asr", "display_name": "Granite Speech 5.0 470M TurboCTC (asr)", "display_name_en": "Granite Speech 5.0 470M TurboCTC (asr)", "family": "granite5asr", "path": "granite5asr", "task": "asr", "mode": "offline", "download_id": "granite5asr_q8_0", "min_vram_gb": 4, + { "id": "granite5asr", "display_name": "Granite Speech 5.0 470M TurboCTC (asr)", "display_name_en": "Granite Speech 5.0 470M TurboCTC (asr)", "family": "granite5asr", "path": "models/Granite-Speech-5.0-470M-TurboCTC-GGUF/granite-speech-5.0-470m-turboctc-q8_0.gguf", "task": "asr", "mode": "offline", "download_id": "granite5asr_q8_0", "min_vram_gb": 4, "input_hint": "**Granite Speech 5.0 TurboCTC**:IBM 470M 英语 ASR;超快 Conformer CTC 转写;支持长音频自动分段与流式模式。", "input_hint_en": "**Granite Speech 5.0 TurboCTC**: IBM 470M English ASR with ultra-fast Conformer CTC architecture, supporting long-form audio segmentation and streaming mode." }, - { "id": "sense-asr", "display_name": "SenseVoice-Small (asr, 流式, 社区)", "display_name_en": "SenseVoice-Small (asr + streaming, community)", "family": "sense_asr", "path": "models/SenseVoice-Small-GGUF", "task": "asr", "mode": "offline", "download_id": "sensevoice_small_q8", "min_vram_gb": 4, + { "id": "sense-asr", "display_name": "SenseVoice-Small (asr, 流式, 社区)", "display_name_en": "SenseVoice-Small (asr + streaming, community)", "family": "sense_asr", "path": "models/SenseVoice-Small-GGUF/sensevoice-small-q8-audiocpp-v1.gguf", "task": "asr", "mode": "offline", "download_id": "sensevoice_small_q8", "min_vram_gb": 4, "input_hint": "**SenseVoice-Small**(社区模型):多语种 ASR,事件/情感/语言标签,ITN 可开关;离线与流式模式。", "input_hint_en": "**SenseVoice-Small** (community): multilingual ASR with event/emotion/language tags, optional ITN; offline and streaming modes." }, { "id": "firered-audio-asr", "display_name": "FireRedAudio (ASR / audio QA)", "family": "firered_audio", "path": "models/FireRedAudio-GGUF/firered-audio-q8_0.gguf", "task": "asr", "mode": "offline", "download_id": "firered_audio_q8_0", "min_vram_gb": 10, "input_hint_en": "**FireRedAudio ASR**: upload audio, then use the text box as the transcription or audio-understanding instruction." }, - { "id": "chatterbox-vc", "display_name": "Chatterbox (vc 声音转换)", "display_name_en": "Chatterbox (voice conversion)", "family": "chatterbox", "path": "models/chatterbox", "task": "vc", "mode": "offline", "download_id": "chatterbox", "min_vram_gb": 12, + { "id": "chatterbox-vc", "display_name": "Chatterbox (vc 声音转换)", "display_name_en": "Chatterbox (voice conversion)", "family": "chatterbox", "path": "models/Chatterbox-GGUF/chatterbox-q8_0.gguf", "task": "vc", "mode": "offline", "download_id": "chatterbox_q8_0", "min_vram_gb": 12, "input_hint": "**Chatterbox VC**:上传源语音和目标音色参考;模型保留源语音内容,将说话人音色转换为目标音色,输出 24kHz 单声道。", "input_hint_en": "**Chatterbox VC**: upload source speech and a target-voice reference. It preserves the source content and converts the speaker identity; output is 24 kHz mono." }, - { "id": "meanvc2", "display_name": "MeanVC2 (voice conversion)", "display_name_en": "MeanVC2 (voice conversion)", "family": "meanvc2", "path": "models/MeanVC2-GGUF/meanvc2-120ms-40ms-fp32.gguf", "task": "vc", "mode": "offline", "download_id": "meanvc2_120ms_40ms_f32", "min_vram_gb": 6, + { "id": "meanvc2", "display_name": "MeanVC2 (voice conversion)", "display_name_en": "MeanVC2 (voice conversion)", "family": "meanvc2", "path": "models/MeanVC2-GGUF/meanvc2-120ms-40ms-fp32.gguf", "task": "vc", "mode": "offline", "download_id": "meanvc2_120ms_40ms_f32", "min_vram_gb": 6, "input_hint": "**MeanVC2**:上传源语音和目标音色参考;默认 120 ms / 40 ms checkpoint 使用 F32 GGUF。", "input_hint_en": "**MeanVC2**: upload source speech and a target-voice reference. The default 120 ms / 40 ms checkpoint uses F32 GGUF." }, - { "id": "vevo2", "display_name": "Vevo2 (vc 语音转换, GGUF Q8)", "display_name_en": "Vevo2 (voice conversion, GGUF Q8)", "family": "vevo2", "path": "models/Vevo2-GGUF", "task": "vc", "mode": "offline", "download_id": "vevo2_gguf", "min_vram_gb": 6 }, - { "id": "vevo2-svc", "display_name": "Vevo2 (svc 歌声转换, GGUF Q8)", "display_name_en": "Vevo2 (singing voice conversion, GGUF Q8)", "family": "vevo2", "path": "models/Vevo2-GGUF", "task": "svc", "mode": "offline", "download_id": "vevo2_gguf", "min_vram_gb": 6, + { "id": "vevo2", "display_name": "Vevo2 (vc 语音转换, GGUF Q8)", "display_name_en": "Vevo2 (voice conversion, GGUF Q8)", "family": "vevo2", "path": "models/Vevo2-GGUF/vevo2-q8_0.gguf", "task": "vc", "mode": "offline", "download_id": "vevo2_q8_0", "min_vram_gb": 6 }, + { "id": "vevo2-svc", "display_name": "Vevo2 (svc 歌声转换, GGUF Q8)", "display_name_en": "Vevo2 (singing voice conversion, GGUF Q8)", "family": "vevo2", "path": "models/Vevo2-GGUF/vevo2-q8_0.gguf", "task": "svc", "mode": "offline", "download_id": "vevo2_q8_0", "min_vram_gb": 6, "input_hint": "**Vevo2 歌声转换 (svc)**:上传源歌声 + 目标歌手参考音色,默认 route=style_preserved_svc。style_converted_svc / singing_style_conversion 等风格转换 route 需在『其它参数(JSON)』里补 `style_ref`(服务器本地 wav 路径)/ `style_ref_text` / `target_text`。", "input_hint_en": "**Vevo2 singing conversion**: upload source singing and a target-singer reference. The default route is style_preserved_svc; style-conversion routes also accept style_ref, style_ref_text and target_text in Additional options." }, - { "id": "vevo2-s2s", "display_name": "Vevo2 (s2s 语音编辑, GGUF Q8)", "display_name_en": "Vevo2 (speech editing, GGUF Q8)", "family": "vevo2", "path": "models/Vevo2-GGUF", "task": "s2s", "mode": "offline", "download_id": "vevo2_gguf", "min_vram_gb": 6, + { "id": "vevo2-s2s", "display_name": "Vevo2 (s2s 语音编辑, GGUF Q8)", "display_name_en": "Vevo2 (speech editing, GGUF Q8)", "family": "vevo2", "path": "models/Vevo2-GGUF/vevo2-q8_0.gguf", "task": "s2s", "mode": "offline", "download_id": "vevo2_q8_0", "min_vram_gb": 6, "input_hint": "**Vevo2 语音编辑 (s2s)**:上传要编辑的源语音,并在『其它参数(JSON)』里填 `{\"target_text\": \"替换后的完整句子\"}`(编辑保持原说话人音色,可不上传目标音色)。", "input_hint_en": "**Vevo2 speech editing**: upload source speech and set target_text to the complete replacement sentence in Additional options. Editing preserves the original speaker and does not require a target-voice reference." }, - { "id": "seed-vc", "display_name": "Seed-VC (vc 语音转换)", "display_name_en": "Seed-VC (voice conversion)", "family": "seed_vc", "path": "models/SeedVC-MLX", "task": "vc", "mode": "offline", "download_id": "seed_vc", "min_vram_gb": 4 }, - { "id": "seed-vc-svc", "display_name": "Seed-VC (svc 歌声转换)", "display_name_en": "Seed-VC (singing voice conversion)", "family": "seed_vc", "path": "models/SeedVC-MLX", "task": "svc", "mode": "offline", "download_id": "seed_vc", "min_vram_gb": 4, + { "id": "dots-tts-edit", "display_name": "DotTTS Edit (speech editing)", "family": "dots_tts", "path": "models/DotTTS-Edit-GGUF/dots-tts-edit-q8_0.gguf", "task": "s2s", "mode": "offline", "download_id": "dots_tts_edit_q8_0", "min_vram_gb": 8, "default_options": { "template_name": "edit" }, + "input_hint_en": "**DotTTS Edit**: upload the source speech and describe the edit in the text box. Optional `instruction`, `source_text`, `target_text` and `use_xvector` overrides can be passed through the JSON box." }, + { "id": "seed-vc", "display_name": "Seed-VC (vc 语音转换)", "display_name_en": "Seed-VC (voice conversion)", "family": "seed_vc", "path": "models/SeedVC-MLX-GGUF/seed-vc-mlx-q8_0.gguf", "task": "vc", "mode": "offline", "download_id": "seed_vc_mlx_q8_0", "min_vram_gb": 4 }, + { "id": "seed-vc-svc", "display_name": "Seed-VC (svc 歌声转换)", "display_name_en": "Seed-VC (singing voice conversion)", "family": "seed_vc", "path": "models/SeedVC-MLX-GGUF/seed-vc-mlx-q8_0.gguf", "task": "svc", "mode": "offline", "download_id": "seed_vc_mlx_q8_0", "min_vram_gb": 4, "input_hint": "**Seed-VC 歌声转换 (svc)**:上传源歌声 + 目标歌手参考音色,默认 route=v1_svc(带 F0 条件)。可在『其它参数(JSON)』里调 `auto_f0_adjust` / `semi_tone_shift` / `f0_condition`。", "input_hint_en": "**Seed-VC singing conversion**: upload source singing and a target-singer reference. The default route is v1_svc with F0 conditioning." }, - { "id": "rvc", "display_name": "RVC (vc, GGUF F16)", "display_name_en": "RVC (voice conversion, GGUF F16)", "family": "rvc", "path": "models/RVC-GGUF", "task": "vc", "mode": "offline", "download_id": "rvc_f16", "min_vram_gb": 4, + { "id": "rvc", "display_name": "RVC (vc, GGUF F16)", "display_name_en": "RVC (voice conversion, GGUF F16)", "family": "rvc", "path": "models/RVC-GGUF/rvc-f16.gguf", "task": "vc", "mode": "offline", "download_id": "rvc_f16", "min_vram_gb": 4, "input_hint": "**RVC**:所选 GGUF 即目标音色;上传源语音即可转换;索引/音高等选项可用 JSON 传。", "input_hint_en": "**RVC**: the selected GGUF is the target voice; upload source speech to convert. Index and pitch options can be passed through the JSON box." }, - { "id": "miocodec", "display_name": "MioCodec (vc; codec dependency)", "family": "miocodec", "path": "models/MioCodec-25Hz-44.1kHz-v2", "task": "vc", "mode": "offline", "download_id": "miocodec_25hz_44k_v2", "min_vram_gb": 3 }, - { "id": "personaplex", "display_name": "PersonaPlex 7B v1 (speech conversation)", "display_name_en": "PersonaPlex 7B v1 (speech conversation)", "family": "personaplex", "path": "models/PersonaPlex-GGUF", "task": "s2s", "mode": "offline", "download_id": "personaplex_7b_v1_q4_k", "min_vram_gb": 8, + { "id": "miocodec", "display_name": "MioCodec (vc; codec dependency)", "family": "miocodec", "path": "models/MioCodec-25Hz-44.1kHz-v2-GGUF/miocodec-25hz-44khz-v2-q8_0.gguf", "task": "vc", "mode": "offline", "download_id": "miocodec_q8_0", "min_vram_gb": 3 }, + { "id": "personaplex", "display_name": "PersonaPlex 7B v1 (speech conversation)", "display_name_en": "PersonaPlex 7B v1 (speech conversation)", "family": "personaplex", "path": "models/PersonaPlex-GGUF/personaplex-7b-v1-q8_0.gguf", "task": "s2s", "mode": "offline", "download_id": "personaplex_7b_v1_q8_0", "min_vram_gb": 8, "request_options": ["voice_id", "system_prompt", "temperature", "text_temperature", "top_k", "text_top_k", "do_sample", "seed"], "input_hint": "**PersonaPlex**:上传用户语音,模型返回语音回复;文本框可填写 assistant system/persona prompt;`voice_id` 选择打包音色,也可上传参考音色覆盖。", "input_hint_en": "**PersonaPlex**: upload user speech and receive a spoken response. The text box provides the assistant system/persona prompt; `voice_id` selects a packaged voice, and an uploaded reference voice overrides it." }, { "id": "audiosr", "display_name": "AudioSR (audio super-resolution)", "family": "audiosr", "path": "models/AudioSR-GGUF/audiosr-basic-f32.gguf", "task": "s2s", "mode": "offline", "download_id": "audiosr_basic_f32", "min_vram_gb": 8, "input_hint_en": "**AudioSR**: upload a source audio file to generate a super-resolved output." }, - { "id": "htdemucs", "display_name": "HTDemucs (sep 音源分离)", "display_name_en": "HTDemucs (source separation)", "family": "htdemucs", "path": "models/htdemucs", "task": "sep", "mode": "offline", "download_id": "htdemucs", "min_vram_gb": 3 }, - { "id": "bs-roformer", "display_name": "BS-RoFormer (sep 人声分离)", "display_name_en": "BS-RoFormer (vocal separation)", "family": "bs_roformer", "path": "models/BS-RoFormer-ep368-GGUF/bs-roformer-ep368-q8_0.gguf", "task": "sep", "mode": "offline", "download_id": "bs_roformer_q8_0", "min_vram_gb": 3 }, - { "id": "mel-band-roformer", "display_name": "Mel-Band RoFormer (sep 人声分离)", "display_name_en": "Mel-Band RoFormer (vocal separation)", "family": "mel_band_roformer", "path": "models/mel-roformer-mlx", "task": "sep", "mode": "offline", "download_id": "mel_band_roformer", "min_vram_gb": 3 }, + { "id": "htdemucs", "display_name": "HTDemucs (sep 音源分离)", "display_name_en": "HTDemucs (source separation)", "family": "htdemucs", "path": "models/HTDemucs-GGUF/htdemucs-q8_0.gguf", "task": "sep", "mode": "offline", "download_id": "htdemucs_q8_0", "min_vram_gb": 3 }, + { "id": "bs-roformer", "display_name": "BS-RoFormer (sep 人声分离)", "display_name_en": "BS-RoFormer (vocal separation)", "family": "bs_roformer", "path": "models/BS-RoFormer-ep368-GGUF/bs-roformer-ep368-q8_0.gguf", "task": "sep", "mode": "offline", "download_id": "bs_roformer_q8_0", "min_vram_gb": 3 }, + { "id": "mel-band-roformer", "display_name": "Mel-Band RoFormer (sep 人声分离)", "display_name_en": "Mel-Band RoFormer (vocal separation)", "family": "mel_band_roformer", "path": "models/Mel-Band-RoFormer-GGUF/mel-band-roformer-q8_0.gguf", "task": "sep", "mode": "offline", "download_id": "mel_band_roformer_q8_0", "min_vram_gb": 3 }, - { "id": "silero-vad", "display_name": "Silero VAD (vad, bundled)", "family": "silero_vad", "path": "assets/framework/models/silero_vad", "task": "vad", "mode": "offline", "min_vram_gb": 1 }, - { "id": "marblenet-vad", "display_name": "MarbleNet VAD (vad, bundled)", "family": "marblenet_vad", "path": "assets/framework/models/marblenet_vad", "task": "vad", "mode": "offline", "min_vram_gb": 1 }, - { "id": "sortformer-diar", "display_name": "Sortformer Diarization 4spk (diar)", "family": "sortformer_diar", "path": "models/diar_sortformer_4spk-v1", "task": "diar", "mode": "offline", "download_id": "sortformer_diar_4spk_v1", "min_vram_gb": 2 }, - { "id": "qwen3-forced-aligner", "display_name": "Qwen3 Forced Aligner (align)", "family": "qwen3_forced_aligner", "path": "models/Qwen3-ForcedAligner-0.6B", "task": "align", "mode": "offline", "download_id": "qwen3_forced_aligner_0_6b", "min_vram_gb": 3 }, - { "id": "muscriptor-small", "display_name": "MuScriptor Small (audio to MIDI)", "family": "muscriptor", "path": "models/MuScriptor-Small-GGUF", "task": "midi", "mode": "offline", "download_id": "muscriptor_small_f32", "min_vram_gb": 4 }, + { "id": "silero-vad", "display_name": "Silero VAD (vad, bundled)", "family": "silero_vad", "path": "assets/framework/models/silero_vad", "task": "vad", "mode": "offline", "min_vram_gb": 1 }, + { "id": "marblenet-vad", "display_name": "MarbleNet VAD (vad, bundled)", "family": "marblenet_vad", "path": "assets/framework/models/marblenet_vad", "task": "vad", "mode": "offline", "min_vram_gb": 1 }, + { "id": "sortformer-diar", "display_name": "Sortformer Diarization 4spk (diar)", "family": "sortformer_diar", "path": "models/Sortformer-Diar-4spk-v1-GGUF/sortformer-diar-4spk-v1-q8_0.gguf", "task": "diar", "mode": "offline", "download_id": "sortformer_diar_4spk_v1_q8_0", "min_vram_gb": 2 }, + { "id": "qwen3-forced-aligner", "display_name": "Qwen3 Forced Aligner (align)", "family": "qwen3_forced_aligner", "path": "models/Qwen3-ForcedAligner-0.6B-GGUF/qwen3-forced-aligner-0.6b-q8_0.gguf", "task": "align", "mode": "offline", "download_id": "qwen3_forced_aligner_0_6b_q8_0", "min_vram_gb": 3 }, + { "id": "muscriptor-small", "display_name": "MuScriptor Small (audio to MIDI)", "family": "muscriptor", "path": "models/MuScriptor-Small-GGUF/muscriptor-small-f32.gguf", "task": "midi", "mode": "offline", "download_id": "muscriptor_small_f32", "min_vram_gb": 4 }, - { "id": "qwen3-tts-1.7b-vdesign", "display_name": "Qwen3-TTS 1.7B VoiceDesign (vdes)", "family": "qwen3_tts", "path": "models/Qwen3-TTS-12Hz-1.7B-VoiceDesign", "task": "vdes", "mode": "offline", "download_id": "qwen3_tts_1_7b_voice_design", "min_vram_gb": 8, + { "id": "qwen3-tts-1.7b-vdesign", "display_name": "Qwen3-TTS 1.7B VoiceDesign (vdes)", "family": "qwen3_tts", "path": "models/Qwen3-TTS-12Hz-1.7B-VoiceDesign-GGUF/qwen3-tts-12hz-1.7b-voicedesign-q8_0.gguf", "task": "vdes", "mode": "offline", "download_id": "qwen3_tts_1_7b_voicedesign_q8_0", "min_vram_gb": 8, "input_hint": "**Qwen3-TTS VoiceDesign**:在『音色描述』里用文字描述想要的声音(如“低沉磁性的中年男声,语速偏慢”),配上要念的文本即可,无需参考音频。", "input_hint_en": "**Qwen3-TTS VoiceDesign**: describe the desired voice, then enter the text to synthesize. No reference recording is required." }, { "id": "fireredtts3-instruct-vdesign", "display_name": "FireRedTTS3 Instruct VoiceDesign", "family": "fireredtts3", "path": "models/FireRedTTS3-Instruct-GGUF/fireredtts3-instruct-q8_0.gguf", "task": "vdes", "mode": "offline", "download_id": "fireredtts3_instruct_q8_0", "min_vram_gb": 8, "input_hint_en": "**FireRedTTS3 VoiceDesign**: describe the target voice in Voice description, then enter the text to synthesize." }, { "id": "firered-audio-vdesign", "display_name": "FireRedAudio VoiceDesign", "family": "firered_audio", "path": "models/FireRedAudio-GGUF/firered-audio-q8_0.gguf", "task": "vdes", "mode": "offline", "download_id": "firered_audio_q8_0", "min_vram_gb": 10, "input_hint_en": "**FireRedAudio VoiceDesign**: describe the target voice in Voice description, then enter the text to synthesize." }, - { "id": "irodori-tts-vdesign", "display_name": "Irodori-TTS v4 Small VoiceDesign (vdes 日语, GGUF Q8)", "display_name_en": "Irodori-TTS v4 Small VoiceDesign (ja vdes, GGUF Q8)", "family": "irodori_tts", "path": "models/Irodori-TTS-v4-Small-GGUF", "task": "vdes", "mode": "offline", "download_id": "irodori_tts_v4_small_q8_0", "min_vram_gb": 4, + { "id": "irodori-tts-vdesign", "display_name": "Irodori-TTS v4 Small VoiceDesign (vdes 日语, GGUF Q8)", "display_name_en": "Irodori-TTS v4 Small VoiceDesign (ja vdes, GGUF Q8)", "family": "irodori_tts", "path": "models/Irodori-TTS-v4-Small-GGUF/irodori-tts-v4-small-q8_0.gguf", "task": "vdes", "mode": "offline", "download_id": "irodori_tts_v4_small_q8_0", "min_vram_gb": 4, "input_hint": "**Irodori-TTS v4 VoiceDesign**(日语):『音色描述』用日语 caption 描述音色(如「落ち着いた大人の男性。深く響く声。」),文本填要念的日语内容,无需参考音频。", "input_hint_en": "**Irodori-TTS v4 VoiceDesign**: provide a Japanese voice caption and Japanese synthesis text. No reference recording is required." }, - { "id": "irodori-tts-v3-vdesign", "display_name": "Irodori-TTS 600M v3 VoiceDesign (vdes 日语)", "display_name_en": "Irodori-TTS 600M v3 VoiceDesign (ja vdes)", "family": "irodori_tts", "path": "models/Irodori-TTS-600M-v3-VoiceDesign-GGUF", "task": "vdes", "mode": "offline", "download_id": "irodori_tts_600m_v3_voicedesign_q8_0", "min_vram_gb": 4, - "input_hint": "**Irodori-TTS v3 VoiceDesign**(日语):『音色描述』用日语 caption 描述音色(如「落ち着いた大人の男性。深く響く声。」),文本填要念的日语内容,无需参考音频。", "input_hint_en": "**Irodori-TTS v3 VoiceDesign**: provide a Japanese voice caption and Japanese synthesis text. No reference recording is required." } + { "id": "irodori-tts-v3-vdesign", "display_name": "Irodori-TTS 600M v3 VoiceDesign (vdes 日语)", "display_name_en": "Irodori-TTS 600M v3 VoiceDesign (ja vdes)", "family": "irodori_tts", "path": "models/Irodori-TTS-600M-v3-VoiceDesign-GGUF/irodori-tts-600m-v3-voicedesign-q8_0.gguf", "task": "vdes", "mode": "offline", "download_id": "irodori_tts_600m_v3_voicedesign_q8_0", "min_vram_gb": 4, + "input_hint": "**Irodori-TTS v3 VoiceDesign**(日语):『音色描述』用日语 caption 描述音色(如「落ち着いた大人の男性。深く響く声。」),文本填要念的日语内容,无需参考音频。", "input_hint_en": "**Irodori-TTS v3 VoiceDesign**: provide a Japanese voice caption and Japanese synthesis text. No reference recording is required." }, + { "id": "moss-voicegen", "display_name": "MOSS-VoiceGenerator (voice design)", "family": "moss_voicegen", "path": "models/MOSS-VoiceGenerator-GGUF/moss_voicegen_bf16_codec_f16_decode.gguf", "task": "vdes", "mode": "offline", "download_id": "moss_voicegen_bf16_codec_f16_decode", "min_vram_gb": 8, + "input_hint_en": "**MOSS-VoiceGenerator**: Apache-2.0 voice design -- the speaker comes from a written description instead of a reference recording. The model reads the description from the `instruct` option, so pass it in the JSON box (for example {\"instruct\": \"A warm male radio voice in his fifties, calm.\"}); it also expects full language names such as English or Chinese rather than en/zh." } ] } diff --git a/webui/native/dist/index.html b/webui/native/dist/index.html index c30ce5757..39979e809 100644 --- a/webui/native/dist/index.html +++ b/webui/native/dist/index.html @@ -24,27 +24,35 @@ })(); -
diff --git a/webui/native/lang/lang_it.json b/webui/native/lang/lang_it.json index d64880980..d8f744a32 100644 --- a/webui/native/lang/lang_it.json +++ b/webui/native/lang/lang_it.json @@ -134,7 +134,6 @@ "models.hfAccess": "Accesso HF richiesto", "models.model": "modello", "models.queued": "in coda", - "models.reinstall": "Reinstalla", "models.selected": "Selezionato", "models.sharedPackage": "Usa il pacchetto condiviso {name} mostrato sopra.", "models.sizeUnavailable": "dimensione non disponibile", @@ -150,7 +149,6 @@ "arena.title.tts": "Confronto TTS", "arena.title.vc": "Confronto conversione vocale", "arena.title.asr": "Confronto ASR", - "arena.subtitle": "Esegue lo stesso input sui modelli installati e sui pacchetti scelti, uno dopo l'altro.", "arena.subtitle.tts": "Esegue lo stesso testo sui modelli TTS e sui pacchetti scelti.", "arena.subtitle.vc": "Esegue lo stesso audio sorgente sui modelli di conversione vocale scelti.", "arena.subtitle.asr": "Esegue lo stesso audio sorgente sui modelli ASR scelti e confronta le trascrizioni.", @@ -256,6 +254,47 @@ "voice.recommendedClone": "consigliata per la clonazione", "voice.recording": "Registrazione voce di riferimento", "voice.requiredClone": "obbligatoria per questa clonazione vocale", - "voice.transcriptPlaceholder": "Digita le parole esatte dell'audio di riferimento oppure carica il file .txt corrispondente." + "voice.transcriptPlaceholder": "Digita le parole esatte dell'audio di riferimento oppure carica il file .txt corrispondente.", + "file.clear": "Cancella file", + "file.preview": "Anteprima", + "param.chatterbox.s3gen_cfg_rate.label": "s3gen_cfg_rate (guida della voce)", + "param.controlfoley.negative_prompt.placeholder": "prompt negativo opzionale", + "param.dramabox.duration_sec.label": "duration_sec (0 = automatico)", + "param.echo_tts.guidance_interval.info": "Aggiorna le corsie CFG non condizionate ogni N passaggi guidati. Valori più alti sono più veloci e funzionano meglio con molti passaggi; 1 offre la fedeltà massima.", + "param.echo_tts.guidance_interval.label": "Intervallo di guida", + "param.echo_tts.num_inference_steps.info": "Passaggi del campionatore Euler.", + "param.echo_tts.num_inference_steps.label": "Passaggi di campionamento", + "param.echo_tts.reference_duration_sec.info": "Taglia il riferimento del parlante prima della codifica. Circa 10 s di solito danno la clonazione migliore.", + "param.echo_tts.reference_duration_sec.label": "Taglio del riferimento (s)", + "param.echo_tts.seed.label": "Seed", + "param.echo_tts.speaker_guidance_scale.label": "Guida del parlante", + "param.echo_tts.text_guidance_scale.label": "Guida del testo", + "param.echo_tts.truncation_factor.label": "Troncamento del rumore", + "param.index_tts2.duration_factor.info": "Corrisponde al duration_factor ufficiale di IndexTTS2.5: scala la durata dell'output senza modificare timbro o contenuto", + "param.index_tts2.duration_factor.label": "duration_factor (moltiplicatore di durata; >1 più lento, <1 più veloce)", + "param.index_tts2.emotion_text.info": "Impostandolo si attiva il condizionamento emotivo.", + "param.index_tts2.emotion_text.label": "emotion_text (testo di riferimento dell'emozione)", + "param.index_tts2.lang.info": "Vale solo per i modelli IndexTTS2.5 (multilingua): auto sceglie zh quando il testo contiene caratteri Han, altrimenti en; imposta ja/es/ar esplicitamente", + "param.index_tts2.lang.label": "lang (suggerimento di lingua, solo modelli IndexTTS2.5)", + "param.index_tts2.use_emotion_text.label": "use_emotion_text (deduci dal testo)", + "param.irodori_tts.duration_sec.label": "duration_sec (0 = automatico)", + "param.magpie_tts.voice_id.label": "voice_id (voce inclusa nel pacchetto)", + "param.minimax_music3.ar_guidance_scale.info": "Guida senza classificatore del campionamento dei codici semantici e residui.", + "param.minimax_music3.ar_guidance_scale.label": "Scala di guida AR", + "param.minimax_music3.guidance_scale.label": "Scala di guida del flow", + "param.minimax_music3.num_inference_steps.info": "Passaggi Euler di flow matching per ogni finestra di denoising da 200 fotogrammi.", + "param.minimax_music3.num_inference_steps.label": "Passaggi di flow per finestra", + "param.neutts.voice_id.label": "voice_id (voce integrata)", + "param.personaplex.system_prompt.placeholder": "Lascia vuoto per usare la casella di testo come system prompt.", + "param.personaplex.voice_id.label": "voice_id (voce inclusa nel pacchetto)", + "param.rvc.output_sample_rate.label": "output_sample_rate (0 = predefinito della voce)", + "param.supertonic.voice.label": "voice (preset M = maschile, F = femminile)", + "request.autoDuration": "-1 = automatico", + "request.rewriteCaption": "Riscrivi descrizione", + "request.rewritingCaption": "Riscrittura descrizione...", + "studio.subtitle.conversion": "Trasforma una registrazione in un'altra voce conservando l'interpretazione parlata o cantata.", + "studio.subtitle.separation": "Separa una registrazione in voce, strumenti o altre tracce audio disponibili.", + "task.midi": "Da audio a MIDI", + "voice.configured": "Voci configurate" } } diff --git a/webui/native/lang/lang_pl.json b/webui/native/lang/lang_pl.json index e4aff0311..e2433136b 100644 --- a/webui/native/lang/lang_pl.json +++ b/webui/native/lang/lang_pl.json @@ -134,7 +134,6 @@ "models.hfAccess": "Wymagany dostęp do HF", "models.model": "model", "models.queued": "w kolejce", - "models.reinstall": "Zainstaluj ponownie", "models.selected": "Wybrano", "models.sharedPackage": "Używa wspólnego pakietu {name} pokazanego powyżej.", "models.sizeUnavailable": "rozmiar niedostępny", @@ -150,7 +149,6 @@ "arena.title.tts": "Porównanie TTS", "arena.title.vc": "Porównanie konwersji głosu", "arena.title.asr": "Porównanie ASR", - "arena.subtitle": "Uruchamia ten sam input na wybranych zainstalowanych modelach i wariantach pakietów, jeden po drugim.", "arena.subtitle.tts": "Uruchamia ten sam tekst na wybranych modelach TTS i wariantach pakietów.", "arena.subtitle.vc": "Uruchamia to samo audio źródłowe na wybranych modelach konwersji głosu.", "arena.subtitle.asr": "Uruchamia to samo audio źródłowe na wybranych modelach ASR i porównuje transkrypcje.", @@ -256,6 +254,47 @@ "voice.recommendedClone": "zalecana do klonowania", "voice.recording": "Nagrywanie głosu referencyjnego", "voice.requiredClone": "wymagana dla tego klonowania głosu", - "voice.transcriptPlaceholder": "Wpisz dokładne słowa z audio referencyjnego lub wczytaj pasujący plik .txt powyżej." + "voice.transcriptPlaceholder": "Wpisz dokładne słowa z audio referencyjnego lub wczytaj pasujący plik .txt powyżej.", + "file.clear": "Wyczyść plik", + "file.preview": "Podgląd", + "param.chatterbox.s3gen_cfg_rate.label": "s3gen_cfg_rate (naprowadzanie głosem)", + "param.controlfoley.negative_prompt.placeholder": "opcjonalne polecenie negatywne", + "param.dramabox.duration_sec.label": "duration_sec (0 = automatycznie)", + "param.echo_tts.guidance_interval.info": "Odświeża bezwarunkowe ścieżki CFG co N-ty krok naprowadzany. Większe wartości są szybsze i działają najlepiej przy większej liczbie kroków; 1 daje najwyższą wierność.", + "param.echo_tts.guidance_interval.label": "Interwał naprowadzania", + "param.echo_tts.num_inference_steps.info": "Kroki próbnika Eulera.", + "param.echo_tts.num_inference_steps.label": "Kroki próbkowania", + "param.echo_tts.reference_duration_sec.info": "Przytnij referencję mówcy przed kodowaniem. Około 10 s zwykle daje najlepsze klonowanie.", + "param.echo_tts.reference_duration_sec.label": "Przycięcie referencji (s)", + "param.echo_tts.seed.label": "Ziarno", + "param.echo_tts.speaker_guidance_scale.label": "Naprowadzanie mówcą", + "param.echo_tts.text_guidance_scale.label": "Naprowadzanie tekstem", + "param.echo_tts.truncation_factor.label": "Obcinanie szumu", + "param.index_tts2.duration_factor.info": "Odpowiada oficjalnemu duration_factor z IndexTTS2.5: skaluje czas trwania wyjścia bez zmiany barwy ani treści", + "param.index_tts2.duration_factor.label": "duration_factor (mnożnik czasu trwania; >1 wolniej, <1 szybciej)", + "param.index_tts2.emotion_text.info": "Ustawienie tego pola włącza warunkowanie emocjami.", + "param.index_tts2.emotion_text.label": "emotion_text (tekst referencyjny emocji)", + "param.index_tts2.lang.info": "Działa tylko w modelach IndexTTS2.5 (wielojęzycznych): auto wybiera zh, gdy tekst zawiera znaki Han, w przeciwnym razie en; ja/es/ar ustaw wprost", + "param.index_tts2.lang.label": "lang (podpowiedź języka, tylko modele IndexTTS2.5)", + "param.index_tts2.use_emotion_text.label": "use_emotion_text (wywnioskuj z tekstu)", + "param.irodori_tts.duration_sec.label": "duration_sec (0 = automatycznie)", + "param.magpie_tts.voice_id.label": "voice_id (głos z pakietu)", + "param.minimax_music3.ar_guidance_scale.info": "Naprowadzanie bez klasyfikatora przy próbkowaniu kodów semantycznych i rezydualnych.", + "param.minimax_music3.ar_guidance_scale.label": "Skala naprowadzania AR", + "param.minimax_music3.guidance_scale.label": "Skala naprowadzania flow", + "param.minimax_music3.num_inference_steps.info": "Kroki Eulera flow matching na każde 200-klatkowe okno odszumiania.", + "param.minimax_music3.num_inference_steps.label": "Kroki flow na okno", + "param.neutts.voice_id.label": "voice_id (głos wbudowany)", + "param.personaplex.system_prompt.placeholder": "Zostaw puste, aby użyć pola tekstowego jako system prompt.", + "param.personaplex.voice_id.label": "voice_id (głos z pakietu)", + "param.rvc.output_sample_rate.label": "output_sample_rate (0 = domyślna dla głosu)", + "param.supertonic.voice.label": "voice (M = głos męski, F = żeński)", + "request.autoDuration": "-1 = automatycznie", + "request.rewriteCaption": "Przepisz opis", + "request.rewritingCaption": "Przepisywanie opisu...", + "studio.subtitle.conversion": "Przekształcaj nagranie w inny głos, zachowując sposób mówienia lub śpiewania.", + "studio.subtitle.separation": "Rozdzielaj nagranie na wokal, instrumenty lub inne dostępne ścieżki.", + "task.midi": "Audio na MIDI", + "voice.configured": "Skonfigurowane głosy" } } diff --git a/webui/native/lang/lang_ru.json b/webui/native/lang/lang_ru.json index 7070c35c6..42032f5c3 100644 --- a/webui/native/lang/lang_ru.json +++ b/webui/native/lang/lang_ru.json @@ -134,7 +134,6 @@ "models.hfAccess": "Требуется доступ HF", "models.model": "модель", "models.queued": "в очереди", - "models.reinstall": "Переустановить", "models.selected": "Выбрано", "models.sharedPackage": "Использует общий пакет {name}, показанный выше.", "models.sizeUnavailable": "размер недоступен", @@ -150,7 +149,6 @@ "arena.title.tts": "Сравнение TTS", "arena.title.vc": "Сравнение преобразования голоса", "arena.title.asr": "Сравнение ASR", - "arena.subtitle": "Запускает один и тот же ввод через выбранные установленные модели и варианты пакетов по очереди.", "arena.subtitle.tts": "Запускает один и тот же текст через выбранные модели TTS и варианты пакетов.", "arena.subtitle.vc": "Запускает одно и то же исходное аудио через выбранные модели преобразования голоса.", "arena.subtitle.asr": "Запускает одно и то же исходное аудио через выбранные модели ASR и сравнивает расшифровки.", @@ -256,6 +254,47 @@ "voice.recommendedClone": "рекомендуется для клонирования", "voice.recording": "Запись эталонного голоса", "voice.requiredClone": "требуется для этого клонирования", - "voice.transcriptPlaceholder": "Введите точные слова из эталонного аудио или загрузите соответствующий файл .txt выше." + "voice.transcriptPlaceholder": "Введите точные слова из эталонного аудио или загрузите соответствующий файл .txt выше.", + "file.clear": "Очистить файл", + "file.preview": "Предпросмотр", + "param.chatterbox.s3gen_cfg_rate.label": "s3gen_cfg_rate (управление голосом)", + "param.controlfoley.negative_prompt.placeholder": "необязательный негативный запрос", + "param.dramabox.duration_sec.label": "duration_sec (0 = автоматически)", + "param.echo_tts.guidance_interval.info": "Обновляет безусловные линии CFG на каждом N-м управляемом шаге. Больше — быстрее и лучше работает при большем числе шагов; 1 даёт максимальную точность.", + "param.echo_tts.guidance_interval.label": "Интервал управления", + "param.echo_tts.num_inference_steps.info": "Шаги сэмплера Эйлера.", + "param.echo_tts.num_inference_steps.label": "Шаги сэмплирования", + "param.echo_tts.reference_duration_sec.info": "Обрезает эталон голоса перед кодированием. Около 10 с обычно дают лучшее клонирование.", + "param.echo_tts.reference_duration_sec.label": "Обрезка эталона (с)", + "param.echo_tts.seed.label": "Seed", + "param.echo_tts.speaker_guidance_scale.label": "Управление по голосу", + "param.echo_tts.text_guidance_scale.label": "Управление по тексту", + "param.echo_tts.truncation_factor.label": "Усечение шума", + "param.index_tts2.duration_factor.info": "Соответствует официальному duration_factor из IndexTTS2.5: масштабирует длительность вывода, не меняя тембр и содержание", + "param.index_tts2.duration_factor.label": "duration_factor (множитель длительности; >1 медленнее, <1 быстрее)", + "param.index_tts2.emotion_text.info": "Заполнение этого поля включает управление эмоцией.", + "param.index_tts2.emotion_text.label": "emotion_text (эталонный текст эмоции)", + "param.index_tts2.lang.info": "Действует только для моделей IndexTTS2.5 (многоязычных): auto выбирает zh, если в тексте есть иероглифы, иначе en; ja/es/ar задавайте явно", + "param.index_tts2.lang.label": "lang (подсказка языка, только модели IndexTTS2.5)", + "param.index_tts2.use_emotion_text.label": "use_emotion_text (определять по тексту)", + "param.irodori_tts.duration_sec.label": "duration_sec (0 = автоматически)", + "param.magpie_tts.voice_id.label": "voice_id (голос из пакета)", + "param.minimax_music3.ar_guidance_scale.info": "Управление без классификатора при сэмплировании семантических и остаточных кодов.", + "param.minimax_music3.ar_guidance_scale.label": "Масштаб управления AR", + "param.minimax_music3.guidance_scale.label": "Масштаб управления flow", + "param.minimax_music3.num_inference_steps.info": "Шаги Эйлера flow matching на каждое окно шумоподавления в 200 кадров.", + "param.minimax_music3.num_inference_steps.label": "Шаги flow на окно", + "param.neutts.voice_id.label": "voice_id (встроенный голос)", + "param.personaplex.system_prompt.placeholder": "Оставьте пустым, чтобы использовать текстовое поле как system prompt.", + "param.personaplex.voice_id.label": "voice_id (голос из пакета)", + "param.rvc.output_sample_rate.label": "output_sample_rate (0 = по умолчанию для голоса)", + "param.supertonic.voice.label": "voice (M = мужской, F = женский пресет)", + "request.autoDuration": "-1 = автоматически", + "request.rewriteCaption": "Переписать описание", + "request.rewritingCaption": "Переписывание описания...", + "studio.subtitle.conversion": "Преобразуйте запись в другой голос, сохраняя манеру речи или пения.", + "studio.subtitle.separation": "Разделяйте запись на вокал, инструменты и другие доступные аудиодорожки.", + "task.midi": "Аудио в MIDI", + "voice.configured": "Настроенные голоса" } } diff --git a/webui/native/lang/lang_zh.json b/webui/native/lang/lang_zh.json index 1c9ca0207..56e4cae1b 100644 --- a/webui/native/lang/lang_zh.json +++ b/webui/native/lang/lang_zh.json @@ -134,7 +134,6 @@ "models.hfAccess": "需要 HF 访问权限", "models.model": "模型", "models.queued": "排队中", - "models.reinstall": "重新安装", "models.selected": "已选择", "models.sharedPackage": "使用上方显示的共享 {name} 软件包。", "models.sizeUnavailable": "大小不可用", @@ -150,7 +149,6 @@ "arena.title.tts": "TTS 对比", "arena.title.vc": "语音转换对比", "arena.title.asr": "ASR 对比", - "arena.subtitle": "用同一输入依次运行已选择的已安装模型和精度包,方便比较输出。", "arena.subtitle.tts": "用同一文本依次运行已选择的 TTS 模型和精度包。", "arena.subtitle.vc": "用同一源音频依次运行已选择的语音转换模型。", "arena.subtitle.asr": "用同一源音频依次运行已选择的 ASR 模型并比较转录结果。", @@ -256,6 +254,119 @@ "voice.recommendedClone": "建议用于克隆", "voice.recording": "正在录制参考音色", "voice.requiredClone": "此声音克隆必需", - "voice.transcriptPlaceholder": "输入参考音频中的准确文字,或加载上方匹配的 .txt 文件。" + "voice.transcriptPlaceholder": "输入参考音频中的准确文字,或加载上方匹配的 .txt 文件。", + "file.clear": "清除文件", + "file.preview": "预览", + "param.ace_step.audio_cover_strength.info": "1=贴近原曲,0=自由发挥;建议 0.5", + "param.ace_step.bpm.info": "0=不指定", + "param.ace_step.bpm.label": "【曲谱】BPM", + "param.ace_step.cover_noise_strength.info": "保旋律强度;推荐 0.1~0.25", + "param.ace_step.flow_edit_n_avg.info": "每步多次采样取平均(remix 默认 2);1=最快", + "param.ace_step.flow_edit_n_max.info": "唱不出新歌词时降到 0.7~0.9", + "param.ace_step.flow_edit_n_min.info": "调大更保源曲、换词更弱", + "param.ace_step.keyscale.label": "【曲谱】keyscale", + "param.ace_step.keyscale.placeholder": "如 F major", + "param.ace_step.num_inference_steps.info": "扩散步数(turbo 上限 20);remix 路由不填时默认 16,其他路由默认 8", + "param.ace_step.route.info": "cover/remix=换词翻唱,非 text2music 需上传源音频;详见 webui/README.md", + "param.ace_step.route.label": "route(操作类型)", + "param.ace_step.shift.info": "原版 turbo 默认 3.0;1.0 会明显劣化 remix 换词咬字", + "param.ace_step.shift.label": "shift(时间步弯曲)", + "param.ace_step.source_caption.placeholder": "源歌曲描述;『🔍 分析』自动填", + "param.ace_step.source_lyrics.placeholder": "源歌曲原歌词;『🔍 分析』自动填", + "param.ace_step.timesignature.label": "【曲谱】timesignature", + "param.ace_step.timesignature.placeholder": "如 4", + "param.chatterbox.exaggeration.info": "改动后需重新『加载模型』才生效", + "param.chatterbox.guidance_scale.info": "改动后需重新『加载模型』才生效", + "param.chatterbox.num_inference_steps.label": "num_inference_steps(生成步数)", + "param.chatterbox.s3gen_cfg_rate.label": "s3gen_cfg_rate(音色引导强度)", + "param.dramabox.audio_chunk_duration_sec.label": "audio_chunk_duration_sec(长文本分段目标时长)", + "param.dramabox.audio_chunk_threshold_sec.label": "audio_chunk_threshold_sec(长文本阈值)", + "param.dramabox.cross_fade_duration_sec.label": "cross_fade_duration_sec(分段交叉淡化)", + "param.dramabox.duration_scale.label": "duration_scale(自动估时倍率)", + "param.dramabox.duration_sec.label": "duration_sec(0=自动估时)", + "param.dramabox.guidance_rescale.placeholder": "auto 或数值", + "param.dramabox.negative_prompt.label": "negative_prompt(负向提示)", + "param.dramabox.negative_prompt.placeholder": "留空=模型内置质量提示", + "param.dramabox.reference_duration_sec.label": "reference_duration_sec(参考音频裁剪/重复秒数)", + "param.heartmula.infinite_mode.label": "infinite_mode(长输出分段生成)", + "param.heartmula.num_inference_steps.label": "num_inference_steps(codec 步数)", + "param.heartmula.tags.info": "风格/情绪/乐器/人声标签,模型必需", + "param.heartmula.tags.label": "tags(必填,逗号分隔)", + "param.index_tts2.duration_factor.info": "对齐官方 IndexTTS2.5 的 duration_factor:缩放输出时长,不改变音色/内容", + "param.index_tts2.duration_factor.label": "duration_factor(语速/时长倍率,>1 更慢,<1 更快)", + "param.index_tts2.emotion_alpha.label": "emotion_alpha(情感强度)", + "param.index_tts2.emotion_text.info": "填写后自动开启情感条件(use_emotion_text)", + "param.index_tts2.emotion_text.label": "emotion_text(情绪参考文本)", + "param.index_tts2.emotion_text.placeholder": "例:你吓死我了!你是鬼吗?", + "param.index_tts2.interval_silence_ms.label": "interval_silence_ms(分段间静音)", + "param.index_tts2.lang.info": "仅对 IndexTTS2.5(多语种)模型生效:auto 含汉字按中文,否则按英文;日/西/阿建议显式选择", + "param.index_tts2.lang.label": "lang(语种提示, 仅 IndexTTS2.5 模型)", + "param.index_tts2.use_emotion_text.label": "use_emotion_text(从朗读文本推断情感)", + "param.index_tts2.use_random_emotion.label": "use_random_emotion(随机情感)", + "param.inflect_v2.speaking_rate.label": "speaking_rate(语速倍率)", + "param.inflect_v2.text_chunk_size.label": "text_chunk_size(长文本分段字符数)", + "param.inflect_v2.variation.label": "variation(音色变化)", + "param.irodori_tts.duration_scale.label": "duration_scale(语速倒数,越大越慢)", + "param.irodori_tts.duration_sec.label": "duration_sec(0=模型自动预测时长)", + "param.irodori_tts.num_inference_steps.label": "num_inference_steps(RF 扩散步数)", + "param.magpie_tts.voice_id.label": "voice_id(打包音色)", + "param.miotts.best_of_n.label": "best_of_n(候选数,>1 自动开启)", + "param.neutts.emotion.label": "emotion(情绪)", + "param.neutts.voice_id.label": "voice_id(内置音色)", + "param.omnivoice.instruct.label": "instruct(风格/音色指令)", + "param.omnivoice.instruct.placeholder": "如:以轻快的语气朗读", + "param.personaplex.voice_id.label": "voice_id(打包音色)", + "param.pocket_tts.frames_after_eos.label": "frames_after_eos(-1=自动)", + "param.qwen3_tts.instruct.label": "instruct(仅 VoiceDesign/CustomVoice)", + "param.qwen3_tts.instruct.placeholder": "风格/音色指令,Base 版忽略", + "param.qwen3_tts.speaker.label": "speaker(仅 CustomVoice)", + "param.qwen3_tts.speaker.placeholder": "内置音色名,其它版忽略", + "param.rvc.output_sample_rate.label": "output_sample_rate(0=跟随音色)", + "param.rvc.retrieval_index_path.placeholder": "可选 .index 路径", + "param.rvc.semitone_shift.label": "semitone_shift(半音变调)", + "param.rvc.voice_id.label": "voice_id(打包音色)", + "param.rvc.voice_model_path.label": "voice_model_path(自定义 RVC .pth/.pt)", + "param.rvc.voice_model_path.placeholder": "留空=使用打包音色", + "param.seed_vc.inference_cfg_rate.label": "inference_cfg_rate(仅 v1 路径)", + "param.seed_vc.intelligibility_cfg_rate.label": "intelligibility_cfg_rate(仅 v2_vc)", + "param.seed_vc.length_adjust.label": "length_adjust(时长伸缩)", + "param.seed_vc.num_inference_steps.info": "CFM 扩散步数", + "param.seed_vc.route.info": "留空=按任务默认", + "param.seed_vc.route.label": "route(转换路径)", + "param.seed_vc.similarity_cfg_rate.label": "similarity_cfg_rate(仅 v2_vc)", + "param.sense_asr.enable_itn.label": "enable_itn(逆文本规范化)", + "param.sense_asr.keep_tags.label": "keep_tags(保留语言/情绪/事件标签)", + "param.stable_audio.audio_input_kind.label": "audio_input_kind(仅上传源音频时生效)", + "param.stable_audio.init_noise_level.label": "init_noise_level(init_audio 强度)", + "param.stable_audio.num_inference_steps.info": "RF 扩散步数", + "param.supertonic.num_inference_steps.label": "num_inference_steps(流匹配步数)", + "param.supertonic.speaking_rate.label": "speaking_rate(语速倍率)", + "param.supertonic.voice.label": "voice(预置音色:M 男声 / F 女声)", + "param.vevo2.num_inference_steps.info": "流匹配步数", + "param.vevo2.route.info": "留空=按任务默认;详见 webui/README.md", + "param.vevo2.route.label": "route(任务路线)", + "param.vevo2.temperature.info": "默认取自模型 generation_config.json", + "param.vevo2.temperature.label": "temperature(AR 路线用)", + "param.vevo2.top_k.info": "默认取自模型 generation_config.json", + "param.vevo2.top_k.label": "top_k(AR 路线用)", + "param.vevo2.top_p.label": "top_p(AR 路线用)", + "param.vevo2.use_pitch_shift.info": "留空=按路线默认", + "param.vevo2.use_pitch_shift.label": "use_pitch_shift(自动音高对齐)", + "param.vibevoice.guidance_scale.info": "CFG 引导强度", + "param.vibevoice.max_length_times.info": "最大输出长度倍数", + "param.vibevoice.num_inference_steps.info": "扩散步数(官方默认 10),越大越慢越稳", + "param.vibevoice.voice_samples.label": "voice_samples(多说话人,逗号分隔 wav,≤4)", + "param.vibevoice.voice_samples.placeholder": "D:/a.wav,D:/b.wav — 用此项时勿再上传参考音色", + "param.voxcpm1.num_inference_steps.info": "CFM/DiT 步数", + "param.voxcpm1.retry_badcase.label": "retry_badcase(自动重试异常输出)", + "param.voxcpm2.num_inference_steps.info": "CFM/DiT 步数", + "param.voxcpm2.retry_badcase.label": "retry_badcase(自动重试异常输出)", + "request.autoDuration": "-1 = 自动", + "request.rewriteCaption": "重写描述", + "request.rewritingCaption": "正在重写描述...", + "studio.subtitle.conversion": "将录音转换为另一种声音,同时保留原有的说话或演唱表现。", + "studio.subtitle.separation": "将录音分离为人声、乐器或其他可用音轨。", + "task.midi": "音频转 MIDI", + "voice.configured": "已配置音色" } } diff --git a/webui/native/src/app.css b/webui/native/src/app.css index df994638a..c685a3bd7 100644 --- a/webui/native/src/app.css +++ b/webui/native/src/app.css @@ -156,7 +156,7 @@ button:disabled { opacity: .45; cursor: not-allowed; } button.primary, button.run { color: var(--text-invert); background: linear-gradient(135deg, var(--cyan), #5ac7ff); border: 0; font-weight: 800; } .button-row button { flex: 1; } .studio-package-buttons { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 5px; margin-top: 11px; } -.studio-package-buttons button, .single-model-toggle { position: relative; min-width: 0; min-height: 38px; padding: 6px 4px; font-size: 9px; line-height: 1.15; } +.studio-package-buttons button, .single-model-toggle { position: relative; min-width: 0; min-height: 38px; padding: 6px 4px; overflow: hidden; font-size: 9px; line-height: 1.15; overflow-wrap: anywhere; } .studio-package-buttons button.selected-package:not(:disabled) { border-color: var(--active-border); color: var(--cyan); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--cyan) 10%, transparent); } .studio-package-buttons button:disabled { color: var(--control-disabled); background: var(--panel-2); opacity: .48; } .studio-package-buttons button.resident, .single-model-toggle.resident { padding-right: 12px; border-color: var(--active-border); color: var(--text-strong); background: var(--active-bg); opacity: 1; } @@ -215,6 +215,13 @@ kbd { font: 9px ui-monospace, monospace; padding: 2px 4px; border: 1px solid rgb .audio-list a { color: var(--cyan); text-decoration: none; } audio { width: 100%; height: 38px; } .transcript { margin-top: 14px; } +.timed-rows { margin-top: 14px; } +.timed-rows-scroll { max-height: 250px; overflow: auto; border: 1px solid var(--line); border-radius: 8px; margin-top: 6px; } +.timed-rows table { width: 100%; border-collapse: collapse; font-size: 12px; } +.timed-rows th, .timed-rows td { padding: 6px 9px; text-align: left; border-bottom: 1px solid var(--line); } +.timed-rows th { position: sticky; top: 0; background: var(--card-bg); color: var(--muted); font-weight: 500; } +.timed-rows td:first-child, .timed-rows td:nth-child(2) { white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--text-subtle); } +.timed-rows tr:last-child td { border-bottom: none; } pre { background: var(--code-bg); border: 1px solid var(--line); border-radius: 8px; padding: 10px; overflow: auto; max-height: 250px; color: var(--text-subtle); white-space: pre-wrap; overflow-wrap: anywhere; } .arena-hero { align-items: end; } @@ -268,16 +275,22 @@ pre { background: var(--code-bg); border: 1px solid var(--line); border-radius: .model-actions { display: grid; gap: 6px; width: clamp(280px, 17vw, 324px); min-width: 0; }.model-actions small { text-align: right; } .model-actions button { padding: 7px; font-size: 11px; } .package-buttons { display: grid; grid-template-columns: repeat(3, minmax(76px, 1fr)); gap: 5px; } -.package-buttons.wide-package-set { grid-template-columns: repeat(2, minmax(0, 1fr)); } -.package-buttons.wide-package-set .package-size { line-height: 1.15; } +/* Labels are the build only ('Turbo BF16'), so even a six-package set stays on + the three-column grid instead of widening to two half-width columns. */ +.package-buttons.wide-package-set { grid-template-columns: repeat(3, minmax(0, 1fr)); } .package-buttons:has(> .package-choice:only-child) { grid-template-columns: minmax(0, 1fr); } .package-buttons:has(> .package-choice:nth-child(2):last-child) { grid-template-columns: repeat(2, minmax(0, 1fr)); } -.package-choice { position: relative; height: 48px; min-width: 0; } -.package-install { display: flex; width: 100%; height: 48px; min-width: 0; min-height: 0; padding-top: 4px; padding-bottom: 4px; flex-direction: column; align-items: center; justify-content: center; gap: 2px; white-space: nowrap; } -.package-install > span:first-child { line-height: 1.1; } +.package-choice { position: relative; height: 56px; min-width: 0; } +.package-install { display: flex; width: 100%; height: 56px; min-width: 0; min-height: 0; padding: 4px 6px; flex-direction: column; align-items: center; justify-content: center; gap: 2px; overflow: hidden; text-align: center; } +/* Both lines clamp instead of overflowing: the package label falls back to the + full model name when the short build name would be ambiguous, and the size + line carries a status as well as the byte count. */ +.package-install > span { display: -webkit-box; max-width: 100%; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow-wrap: anywhere; } +.package-install > span:first-child { line-height: 1.15; } .package-install.preferred { border-color: var(--active-border); color: var(--cyan); box-shadow: inset 0 0 0 1px rgba(66,232,213,.1); } -.package-install.downloaded { padding-right: 23px; border-color: var(--button-hover-border); background: color-mix(in srgb, var(--button-bg) 80%, white 20%); color: var(--blue); white-space: normal; } -.package-install.downloaded > span:first-child { white-space: nowrap; } +.package-install.downloaded { padding-right: 23px; border-color: var(--button-hover-border); background: color-mix(in srgb, var(--button-bg) 80%, white 20%); color: var(--blue); } +/* Keep the label clear of the corner badges that overlay the button. */ +.package-choice:has(.package-update) .package-install { padding-left: 26px; } .package-install.downloaded:hover:not(:disabled) { border-color: var(--button-hover-border); background: color-mix(in srgb, var(--button-hover-bg) 76%, white 24%); } .package-install.downloaded.preferred { border-color: var(--active-border); color: var(--cyan); box-shadow: inset 0 0 0 1px rgba(66,232,213,.16); } .model-actions .package-delete { position: absolute; top: 3px; right: 3px; z-index: 1; display: grid; width: 18px; height: 18px; min-height: 0; padding: 2px; place-items: center; border-color: transparent; background: transparent; color: var(--muted); } @@ -285,7 +298,10 @@ pre { background: var(--code-bg); border: 1px solid var(--line); border-radius: .package-delete svg { width: 12px; height: 12px; fill: currentColor; } .model-actions .package-update { position: absolute; top: 3px; left: 3px; z-index: 1; width: auto; min-height: 18px; padding: 2px 4px; border-color: rgba(66,232,213,.3); background: var(--active-bg); color: var(--cyan); font-size: 7px; } .shared-package-note { padding: 7px 9px; border: 1px dashed var(--line); border-radius: 7px; color: var(--muted); font-size: 9px; text-align: center; } -.package-size { color: var(--muted); font-size: 8px; font-weight: 500; letter-spacing: 0; text-transform: none; } +.package-size { color: var(--muted); font-size: 8px; font-weight: 500; line-height: 1.2; letter-spacing: 0; text-transform: none; } +/* The size line carries a status word as well as the byte count, so it gets a + line more than the label above it. */ +.package-install > span.package-size { -webkit-line-clamp: 3; line-clamp: 3; } .install-progress { grid-column: 1/-1; width: 100%; min-width: 0; max-width: 100%; } .install-progress-head { display: flex; justify-content: space-between; gap: 8px; color: var(--muted); font-size: 9px; } .install-progress-head strong { color: var(--blue); text-transform: uppercase; }.install-progress.complete .install-progress-head strong, .install-progress.cleaned .install-progress-head strong { color: var(--cyan); }.install-progress.failed .install-progress-head strong, .install-progress.cancelled .install-progress-head strong { color: var(--danger); } diff --git a/webui/native/src/lib/catalog.ts b/webui/native/src/lib/catalog.ts index baaf51af4..2fbb8a11e 100644 --- a/webui/native/src/lib/catalog.ts +++ b/webui/native/src/lib/catalog.ts @@ -1,6 +1,11 @@ import rawCatalog from '../../../configs/models_catalog.json'; import rawParams from '../../../configs/model_params.json'; -import type { CatalogEntry, InstallPackageChoice, ParamSpec } from './types'; +import type { + CatalogEntry, + InstallPackageChoice, + InstallPackageSlot, + ParamSpec +} from './types'; interface PackageEntry { family: string; @@ -23,6 +28,7 @@ interface PackageSpec { ui?: { builtin_voices?: string[]; default_voice?: string; + recommended_package?: string; }; } @@ -39,14 +45,15 @@ const packages: PackageEntry[] = Object.values(specModules).flatMap((spec) => ); const specsByFamily = new Map(Object.values(specModules).map((spec) => [spec.family, spec])); -const exposeAllGgufPackageFamilies = new Set([ - 'audiosr', - 'controlfoley', - 'firered_audio', - 'fireredtts3', - 'meanvc2', - 'midashenglm_gen' -]); + +// Package ids carry a trailing format/precision tag. Stripping it yields the +// "stem" that identifies the model itself, so a catalog download id written +// before (or after) a requantisation can still be matched to its package. Keep +// longer tags ahead of their prefixes (`q8_0` before `q8`, `q4_0` before `q4`) +// so the alternation strips the whole tag. This list is the single source of +// truth for suffix stripping anywhere in this module. +const packageIdSuffix = + /_(?:q2_k|q3_k|q4_0|q4_k|q4|q5_0|q5_k|q6_k|q8_0|q8|f16|fp16|bf16|f32|safetensors|orig)$/i; const hanCharacters = /[\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff]/u; @@ -70,81 +77,103 @@ const cleanPath = (value: string) => value const cleanId = (value: string) => value.toLowerCase().replace(/[^a-z0-9]/g, ''); -function preferredPackage(entries: PackageEntry[]): PackageEntry | undefined { - return entries.find((entry) => entry.default) || +// The id that identifies the model behind a package, independent of how that +// package was quantised. +const packageIdStem = (value: string) => cleanId(value.replace(packageIdSuffix, '')); + +const isGguf = (entry: PackageEntry) => entry.format === 'gguf'; + +const familyPackages = (family: string) => + packages.filter((candidate) => candidate.family === family); + +const recommendedPackageId = (family: string) => + specsByFamily.get(family)?.ui?.recommended_package; + +// Picks one package out of a candidate set. `ui.recommended_package` is the +// spec's own answer to "which build should a new user get", so it outranks the +// structural fallbacks; `default` and q8_0 remain for candidate sets that do +// not contain the recommendation (a second model in the same family). +function preferredPackage(entries: PackageEntry[], recommended?: string): PackageEntry | undefined { + return (recommended ? entries.find((entry) => entry.id === recommended) : undefined) || + entries.find((entry) => entry.default) || entries.find((entry) => entry.precision === 'q8_0') || entries[0]; } -function relatedPackages(entry: CatalogEntry): PackageEntry[] { - const family = packages.filter((candidate) => candidate.family === entry.family); - if (!family.length) return []; - if (entry.family === 'ace_step' || entry.family === 'minimax_music3') return family; - if (!entry.download_id) return family; - const exact = family.find((candidate) => candidate.id === entry.download_id); - if (exact) { - const stem = exact.id.replace(/_(?:q8_0|q8|f16|fp16|bf16|safetensors|orig)$/i, ''); - const matches = family.filter((candidate) => - candidate.id.replace(/_(?:q8_0|q8|f16|fp16|bf16|safetensors|orig)$/i, '') === stem); - return matches.length ? matches : [exact]; - } +// Resolves the single package a catalog entry points at. Precedence, most +// specific first: +// 1. an exact package id — the catalog names the package outright; +// 2. the same id stem — the catalog names the model but a stale (or absent) +// precision tag, e.g. `omnivoice` -> `omnivoice_q8_0`. Stems are compared +// for equality rather than by prefix on purpose: a prefix test makes +// `index_tts2` swallow the separate `index_tts2_5_*` model; +// 3. a GGUF package installing into the catalog `path`. Restricted to GGUF +// because a legacy path such as models/pocket-tts names the upstream +// Safetensors drop, not the GGUF build the entry actually wants; +// 4. the family's `ui.recommended_package`, for entries whose download id is +// a bare family name that never matched a package; +// 5. anything GGUF in the family, so a not-yet-migrated entry still resolves. +// Steps 3-5 exist only for catalog entries that have not been migrated to real +// package ids; steps 1-2 cover every migrated entry. +function resolvedPackage(entry: CatalogEntry): PackageEntry | undefined { + const family = familyPackages(entry.family); + if (!family.length) return undefined; + const recommended = recommendedPackageId(entry.family); + if (entry.download_id) { + const exact = family.find((candidate) => candidate.id === entry.download_id); + if (exact) return exact; - // Resolve a legacy family/variant id before considering its old target - // directory. A directory such as models/pocket-tts may identify the gated - // upstream safetensors package, while the family default is the public GGUF - // package intended by the catalog's generic `pocket_tts` download id. - const legacyId = cleanId(entry.download_id); - const legacyMatches = family.filter((candidate) => { - const currentId = cleanId(candidate.id); - return currentId.startsWith(legacyId) || legacyId.startsWith(currentId); - }); - if (legacyMatches.length) return legacyMatches; - - const target = cleanPath(entry.path); - const targetMatches = family.filter((candidate) => cleanPath(candidate.target_directory) === target); - if (targetMatches.length) { - const stems = new Set(targetMatches.map((candidate) => - candidate.id.replace(/_(?:q8_0|q8|f16|fp16|bf16|safetensors|orig)$/i, ''))); - const matches = family.filter((candidate) => stems.has( - candidate.id.replace(/_(?:q8_0|q8|f16|fp16|bf16|safetensors|orig)$/i, ''))); - return matches.length ? matches : targetMatches; + const stem = packageIdStem(entry.download_id); + const stemMatches = family.filter((candidate) => packageIdStem(candidate.id) === stem); + if (stemMatches.length) { + return preferredPackage(stemMatches.filter(isGguf), recommended) || + preferredPackage(stemMatches, recommended); + } + + const target = cleanPath(entry.path); + const targetMatches = family.filter((candidate) => + isGguf(candidate) && cleanPath(candidate.target_directory) === target); + if (targetMatches.length) return preferredPackage(targetMatches, recommended); } - return family; + const recommendedMatch = recommended + ? family.find((candidate) => candidate.id === recommended) + : undefined; + if (recommendedMatch) return recommendedMatch; + return preferredPackage(family.filter(isGguf), recommended) || + preferredPackage(family, recommended); } -function relatedExposeAllGgufPackages(entry: CatalogEntry): PackageEntry[] { - const family = packages.filter((candidate) => - candidate.family === entry.family && candidate.format === 'gguf'); - if (!family.length) return []; - if (!entry.download_id) return family; - const exact = family.find((candidate) => candidate.id === entry.download_id); - if (!exact) return relatedPackages(entry); - const matches = family.filter((candidate) => candidate.target_directory === exact.target_directory); - return matches.length ? matches : [exact]; +// Packages that are precision variants of one model share a target directory; +// packages that are different models install into different ones. Grouping on +// that field is what the old hand-maintained family allowlist was approximating. +function relatedPackages(entry: CatalogEntry): PackageEntry[] { + const resolved = resolvedPackage(entry); + if (!resolved) return []; + return familyPackages(entry.family).filter((candidate) => + candidate.target_directory === resolved.target_directory); } +// Every quantised precision, kept in step with the tags in `packageIdSuffix` so +// a newly published quantisation sorts with its peers instead of falling +// through to the unknown bucket behind `orig`. +const quantisedPrecisions = [ + 'q2_k', 'q3_k', 'q4', 'q4_0', 'q4_k', 'q5_0', 'q5_k', 'q6_k', 'q8_0', 'q8' +]; + function exposedPackageRank(entry: PackageEntry, selectedId?: string): number { if (selectedId && entry.id === selectedId) return 0; if (entry.default) return 1; - if (['q4_k', 'q4_0', 'q8_0', 'q8'].includes(entry.precision)) return 2; + if (quantisedPrecisions.includes(entry.precision)) return 2; if (['f16', 'fp16', 'bf16'].includes(entry.precision)) return 3; if (entry.precision === 'f32') return 4; if (entry.precision === 'orig') return 5; return 6; } -function packageLabel(entry: PackageEntry): string { - if (entry.family === 'ace_step') { - const precision = entry.precision === 'bf16' - ? 'BF16' - : ['q8_0', 'q8'].includes(entry.precision) - ? 'Q8' - : entry.precision.toUpperCase(); - if (entry.id.includes('_xl_turbo_')) return `GGUF Turbo XL ${precision}`; - if (entry.id.includes('_xl_sft_')) return `GGUF Turbo XL SFT ${precision}`; - if (entry.id.includes('_turbo_')) return `GGUF Turbo ${precision}`; - return `GGUF ${precision}`; - } +// Derived label, used only when a package has no display_name. It describes the +// build, not the model, so it cannot tell two models in one target directory +// apart — see packageLabel. +function derivedPackageLabel(entry: PackageEntry): string { if (entry.format === 'safetensors') return 'Safetensors'; if (entry.id.includes('int8_dit')) return 'GGUF Q4 ConvRot'; if (entry.precision === 'q4_k' || entry.precision === 'q4_0') return 'GGUF Q4'; @@ -154,6 +183,14 @@ function packageLabel(entry: PackageEntry): string { return `GGUF ${entry.precision.toUpperCase()}`; } +// display_name is unique per package and already distinguishes both the model +// and its precision ("ACE-Step 1.5 XL Turbo BF16 GGUF"), which the derived +// label cannot: a target directory may hold several distinct models, and those +// would otherwise all render as "GGUF Q8". +function packageLabel(entry: PackageEntry): string { + return englishUiText(entry.display_name) || derivedPackageLabel(entry); +} + function packageModelPath(entry: PackageEntry): string { let modelFile: string | undefined; if (entry.format === 'gguf' && entry.family === 'minimax_h3') { @@ -199,60 +236,97 @@ function packageSessionOptions(entry: PackageEntry): Record | un return undefined; } +// The build alone, without the model name or the "GGUF" every exposed package +// shares. Install buttons are around 90px wide, so the full display_name +// overflowed them; the precision is what actually distinguishes the buttons. +function shortPackageLabel(entry: PackageEntry): string { + if (entry.format !== 'gguf') return derivedPackageLabel(entry); + const precision = entry.precision === 'orig' ? 'Original' : entry.precision.toUpperCase(); + return entry.id.includes('int8_dit') ? `${precision} ConvRot` : precision; +} + +const installChoice = (candidate: PackageEntry, shortLabel: string): InstallPackageChoice => ({ + id: candidate.id, + label: packageLabel(candidate), + short_label: shortLabel, + path: packageModelPath(candidate), + format: candidate.format, + precision: candidate.precision, + session_options: packageSessionOptions(candidate) +}); + function installChoices(entry: CatalogEntry): InstallPackageChoice[] { - const exposesAllGguf = exposeAllGgufPackageFamilies.has(entry.family); - const related = exposesAllGguf ? relatedExposeAllGgufPackages(entry) : relatedPackages(entry); - if (entry.family === 'ace_step' || entry.family === 'minimax_music3' || - exposesAllGguf) { - return related - .filter((candidate) => candidate.format === 'gguf') - .sort((left, right) => exposesAllGguf - ? exposedPackageRank(left, entry.download_id) - exposedPackageRank(right, entry.download_id) - : Number(right.default === true) - Number(left.default === true)) - .map((candidate) => ({ - id: candidate.id, - label: packageLabel(candidate), - path: packageModelPath(candidate), - format: candidate.format, - precision: candidate.precision, - session_options: packageSessionOptions(candidate) - })); - } - const q8 = preferredPackage(related.filter((candidate) => - candidate.format === 'gguf' && ['q8_0', 'q8'].includes(candidate.precision))); - const fp16 = preferredPackage(related.filter((candidate) => - candidate.format === 'gguf' && ['f16', 'fp16'].includes(candidate.precision))) || - preferredPackage(related.filter((candidate) => - candidate.format === 'gguf' && candidate.precision === 'bf16')); - const otherGguf = !q8 && !fp16 - ? related.filter((candidate) => candidate.format === 'gguf') - : []; // The native model manager intentionally exposes complete GGUF packages // only. Safetensors packages frequently depend on source-tree sidecars and - // are not yet reliable as one-click UI installs. - return [q8, fp16, ...otherGguf] - .filter((candidate): candidate is PackageEntry => candidate !== undefined) - .map((candidate) => ({ - id: candidate.id, - label: packageLabel(candidate), - path: packageModelPath(candidate), - format: candidate.format, - precision: candidate.precision, - session_options: packageSessionOptions(candidate) - })); + // are not yet reliable as one-click UI installs. Every other build of the + // resolved model is offered: they share a target directory, so switching + // between them is a requantisation rather than a different model. + const exposed = relatedPackages(entry).filter(isGguf); + if (!exposed.length) return []; + // An entry that names a package explicitly gets that package, even when the + // family recommends another build of it: the catalog id is the per-entry + // decision (a deliberate low-VRAM pick, say) and the recommendation is only + // the family-wide default for entries that express no preference. + const explicit = exposed.find((candidate) => candidate.id === entry.download_id); + const selected = explicit || preferredPackage(exposed, recommendedPackageId(entry.family)); + const ordered = exposed + .slice() + .sort((left, right) => + exposedPackageRank(left, selected?.id) - exposedPackageRank(right, selected?.id)); + // Two distinct models can share a target directory, and the short label + // describes the build only, so it cannot tell those apart. Keep the full + // display_name on every button of such a set rather than render one + // ambiguous button. + const labels = distinctLabels(ordered.map(shortPackageLabel)) || + distinctLabels(trimmedPackageLabels(ordered.map(packageLabel))) || + ordered.map(packageLabel); + return ordered.map((candidate, index) => installChoice(candidate, labels[index])); +} + +function distinctLabels(labels: string[]): string[] | undefined { + const seen = new Set(labels.map((value) => value.toLowerCase())); + return seen.size === labels.length && labels.every(Boolean) ? labels : undefined; +} + +// Second try when precisions alone collide, which happens when one target +// directory holds several models ("ACE-Step 1.5 Turbo BF16 GGUF" beside +// "ACE-Step 1.5 XL SFT BF16 GGUF"). Drop the leading words every package of the +// set shares and the trailing format word, leaving what actually differs. +function trimmedPackageLabels(labels: string[]): string[] { + if (labels.length < 2) return labels; + const words = labels.map((label) => label.split(' ').filter(Boolean)); + let shared = 0; + while (words.every((entry) => shared < entry.length - 1 && entry[shared] === words[0][shared])) { + shared++; + } + return words.map((entry) => { + const rest = entry.slice(shared); + if (rest.length > 1 && rest[rest.length - 1].toLowerCase() === 'gguf') rest.pop(); + return rest.join(' '); + }); +} + +// Why a managed entry ended up with no installable package. Returned as display +// text so the entry can stay listed instead of vanishing from the whole UI. +function unavailableReason(entry: CatalogEntry): string { + const family = familyPackages(entry.family); + if (!family.length) { + return `No model_specs package definition for family "${entry.family}".`; + } + return 'Only Safetensors packages are published for this model. The native ' + + 'model manager installs GGUF packages only.'; } -export const catalog = (rawCatalog.models as CatalogEntry[]).flatMap((entry) => { +export const catalog = (rawCatalog.models as CatalogEntry[]).map((entry) => { const choices = installChoices(entry); // A managed catalog entry with no remaining GGUF choice is Safetensors-only - // (or otherwise not installable by the native manager). Do not expose it as - // an apparently available Studio model after Safetensors UI support is - // disabled. Entries without a download id are bundled or locally managed - // and must remain visible. - if (entry.download_id && choices.length === 0) return []; + // (or has no spec yet). Keep it listed and flag it: dropping it here made a + // packaging gap look like the model had never existed. Entries without a + // download id are bundled or locally managed and are never flagged. + const unavailable = Boolean(entry.download_id) && choices.length === 0; const installPackage = choices[0]; const spec = specsByFamily.get(entry.family); - return [{ + return { ...entry, display_name: englishUiText(entry.display_name_en, entry.display_name) || entry.id, input_hint: englishUiText(entry.input_hint_en, entry.input_hint), @@ -264,10 +338,24 @@ export const catalog = (rawCatalog.models as CatalogEntry[]).flatMap((entry) => ?.filter((option) => option.required === true) .map((option) => option.name), builtin_voices: spec?.ui?.builtin_voices, - default_voice: spec?.ui?.default_voice - }]; + default_voice: spec?.ui?.default_voice, + unavailable: unavailable || undefined, + unavailable_reason: unavailable ? unavailableReason(entry) : undefined + }; }); +// The install buttons an entry renders. Every exposed package gets its own +// slot: catalog.ts already decided which packages belong together, so the UI +// must not re-derive that from family names or collapse the list to fixed +// q8/fp16 slots. +export function installPackageSlots(entry: CatalogEntry): InstallPackageSlot[] { + return (entry.install_packages || []).map((choice) => ({ + key: choice.id, + label: choice.short_label, + choice + })); +} + export const parameterCatalog = Object.fromEntries( Object.entries(rawParams as unknown as Record) .filter((entry): entry is [string, ParamSpec[]] => Array.isArray(entry[1])) diff --git a/webui/native/src/lib/i18n.ts b/webui/native/src/lib/i18n.ts index 5a37eef69..f2da739ff 100644 --- a/webui/native/src/lib/i18n.ts +++ b/webui/native/src/lib/i18n.ts @@ -122,6 +122,11 @@ const english: Record = { 'studio.subtitle.music': 'Create music and sound from a prompt, lyrics, or reference audio when supported.', 'studio.subtitle.vc': 'Transform a recording into another voice while preserving the spoken or sung performance.', 'studio.subtitle.sep': 'Split a recording into vocals, instruments, or other available audio stems.', + // The workflow tabs are keyed 'conversion' and 'separation' while the task + // labels above use 'vc' and 'sep'. Both spellings resolve so the hero subtitle + // renders text rather than the lookup key itself. + 'studio.subtitle.conversion': 'Transform a recording into another voice while preserving the spoken or sung performance.', + 'studio.subtitle.separation': 'Split a recording into vocals, instruments, or other available audio stems.', 'studio.subtitle.analysis': 'Analyze audio for speech activity, speakers, timing, and alignment.', 'studio.subtitle.design': 'Create or refine a voice from a written description and supported reference controls.', 'studio.model': 'Model', @@ -227,6 +232,15 @@ const english: Record = { 'result.tracks': 'tracks', 'result.saveWav': 'Save WAV', 'result.empty': 'Generated audio and structured results appear here.', + 'result.rows.segments': 'Segments', + 'result.rows.words': 'Word timings', + 'result.rows.speaker_turns': 'Speaker turns', + 'result.saveSrt': 'Save SRT', + 'result.saveVtt': 'Save VTT', + 'result.start': 'Start', + 'result.end': 'End', + 'result.speaker': 'Speaker', + 'result.content': 'Content', 'models.eyebrow': 'MODEL LIBRARY', 'models.title': 'Local packages', 'models.subtitle': 'Download and manage model packages without leaving the native interface.', diff --git a/webui/native/src/lib/types.ts b/webui/native/src/lib/types.ts index 061ef0977..799965ae4 100644 --- a/webui/native/src/lib/types.ts +++ b/webui/native/src/lib/types.ts @@ -3,12 +3,26 @@ export type StringMap = Record; export interface InstallPackageChoice { id: string; label: string; + // Button text. `label` names the model as well as the build ("IndexTTS2.5 + // Original-Dtype GGUF"), which is wider than an install button; the model + // name is already printed beside the buttons, so the short form keeps the + // build only. It falls back to `label` when that would not be unique. + short_label: string; path: string; format: string; precision: string; session_options?: StringMap; } +// One rendered install button. The catalog decides which packages an entry +// exposes, so the UI renders every slot it is given rather than re-deriving the +// set from family names. +export interface InstallPackageSlot { + key: string; + label: string; + choice: InstallPackageChoice; +} + export interface CatalogEntry { id: string; display_name: string; @@ -29,6 +43,11 @@ export interface CatalogEntry { required_request_options?: string[]; builtin_voices?: string[]; default_voice?: string; + // Set when a managed entry resolves to no installable package. The entry is + // still listed so the gap is visible instead of the model disappearing from + // the UI; `unavailable_reason` explains why it cannot be installed. + unavailable?: boolean; + unavailable_reason?: string; } export interface ParamSpec { diff --git a/webui/native/src/routes/+page.svelte b/webui/native/src/routes/+page.svelte index 777984830..ec0a47ca5 100644 --- a/webui/native/src/routes/+page.svelte +++ b/webui/native/src/routes/+page.svelte @@ -29,7 +29,7 @@ type ModelPackageSize, type DirectoryBrowserResponse } from '$lib/api'; - import { catalog, parameterCatalog, taskLabels } from '$lib/catalog'; + import { catalog, installPackageSlots, parameterCatalog, taskLabels } from '$lib/catalog'; import { createTranslator, resolveUiLanguage, uiLanguages } from '$lib/i18n'; import MediaPreview from '$lib/MediaPreview.svelte'; import { defaultChunkBudget, splitTtsChunks } from '$lib/text'; @@ -72,8 +72,12 @@ let instructions = ''; let lyrics = ''; let duration = 30; - let seed = 1234; - let maxTokens = 1024; + // -1 means "let the engine pick", matching the field label. A fixed default + // here would silently pin every model whose own default is a random seed. + let seed = -1; + // Blank means "use the model's own limit". A shared constant here overrode + // per-model ceilings ranging from 300 to 4096, halving some and doubling others. + let maxTokens: number | '' = ''; let sourceFile: File | null = null; let videoFile: File | null = null; let voiceFile: File | null = null; @@ -91,6 +95,11 @@ let outputArtifacts: Array<{ id: string; url: string; extension: string }> = []; let outputText = ''; let outputJson = ''; + // Timed detail rows returned by ASR, diarization, VAD and forced alignment. + // Spans arrive as sample offsets alongside the rate they were counted in. + type TimedRow = { start: number; end: number; label: string; text: string; confidence: number }; + let outputRows: TimedRow[] = []; + let outputRowKind = ''; let logs: string[] = []; let aborter: AbortController | null = null; let longText = true; @@ -142,14 +151,6 @@ demo_3_woman: 'demo_3_woman', demo_4_woman: 'demo_4_woman' }; - const exposeAllStudioPackageFamilies = new Set([ - 'audiosr', - 'controlfoley', - 'firered_audio', - 'fireredtts3', - 'meanvc2', - 'midashenglm_gen' - ]); function chooseUiLanguage(code: string) { uiLanguage = resolveUiLanguage([code]); @@ -402,18 +403,30 @@ $: usesVibeVoiceSpeakerFiles = selected?.family === 'vibevoice'; $: isQwenBase = selected?.task === 'tts' && selected?.family === 'qwen3_tts' && !selected?.id.includes('custom'); - $: allowsQuickStartVoice = ['tts', 'clon'].includes(selected?.task); + // Voice design also picks a named voice, and any model shipping built-in + // voices should offer them whatever its task. + $: allowsQuickStartVoice = ['tts', 'clon', 'vdes'].includes(selected?.task) || + (selected?.builtin_voices || []).length > 0; $: referenceVoiceRequired = !(allowsQuickStartVoice && quickStartVoice) && ( (['clon', 'vc', 'svc'].includes(selected?.task) && selected?.family !== 'rvc') || isQwenBase); $: lyricsRequired = requiresRequestOption(selected, 'lyrics'); $: referenceTextRequired = requiresRequestOption(selected, 'reference_text') || (Boolean(voiceFile) && isQwenBase); - $: quickStartVoices = server && !server.ui_management - ? configuredVoices + // Voices come from three places: the spec's built-in list, whatever the server + // reports for this model, and the bundled demo clips. The demo clips only make + // sense for models that take an arbitrary reference. + $: demoQuickStartVoices = server && !server.ui_management + ? [] : Object.entries(demoVoiceSources) .filter(([, source]) => bundledVoices.includes(source)) .map(([voice]) => voice); - $: quickStartVoicePreview = quickStartVoice && server?.ui_management !== false + $: quickStartVoices = Array.from(new Set([ + ...(selected?.builtin_voices || []), + ...configuredVoices, + ...demoQuickStartVoices + ])); + $: quickStartVoicePreview = quickStartVoice && server?.ui_management !== false && + demoQuickStartVoices.includes(quickStartVoice) ? voicePreviewUrl(demoVoiceSources[quickStartVoice] || quickStartVoice) : ''; $: showsText = ['tts', 'clon', 'gen', 's2s', 'align', 'vdes'].includes(selected?.task); @@ -518,32 +531,7 @@ return packageIsResident(entry, choice, models) || sizes[choice.id]?.installed === true; } - function studioPackageSlots(entry: CatalogEntry) { - const choices = entry.install_packages || []; - if (entry.family === 'ace_step' || entry.family === 'minimax_music3' || - exposeAllStudioPackageFamilies.has(entry.family)) { - return choices.map((choice) => ({ key: choice.id, label: choice.label, choice })); - } - const q8 = choices.find((choice) => choice.format === 'gguf' && - ['q8', 'q8_0'].includes(choice.precision)); - const fp16 = choices.find((choice) => choice.format === 'gguf' && - ['f16', 'fp16', 'bf16'].includes(choice.precision)); - if (!q8 && !fp16) { - return choices.map((choice) => ({ key: choice.id, label: choice.label, choice })); - } - return [ - { - key: 'q8', - label: q8?.label || 'GGUF Q8', - choice: q8 - }, - { - key: 'fp16', - label: fp16?.label || 'GGUF FP16', - choice: fp16 - }, - ]; - } + const studioPackageSlots = installPackageSlots; function resolveRequestSeed(value: number) { if (!Number.isInteger(value) || value < -1 || value > 0xffffffff) { @@ -705,6 +693,62 @@ return ['tts', 'clon', 'gen', 's2s', 'vdes'].includes(entry.task); } + // Seed has a dedicated input rather than a parameter widget, so the tasks + // that never declared it could not be made reproducible at all. Trust the + // spec where one exists; fall back to the historical task list otherwise. + function timedRowsFromResult(result: Record): { rows: TimedRow[]; kind: string } { + const rate = Number(result.sample_rate) || 0; + const toSeconds = (samples: unknown) => (rate > 0 ? Number(samples) / rate : Number.NaN); + const read = (value: unknown, label: (entry: Record) => string) => + (Array.isArray(value) ? value : []).map((entry: Record) => ({ + start: toSeconds(entry.start_sample), + end: toSeconds(entry.end_sample), + label: label(entry), + text: typeof entry.text === 'string' ? entry.text : '', + confidence: Number(entry.confidence) || 0 + })); + const turns = read(result.speaker_turns, (entry) => String(entry.speaker_id ?? '')); + if (turns.length) return { rows: turns, kind: 'speaker_turns' }; + const words = read(result.words, (entry) => String(entry.word ?? '')); + if (words.length) return { rows: words, kind: 'words' }; + return { rows: read(result.segments, () => ''), kind: 'segments' }; + } + + function formatTimecode(seconds: number, millisecondSeparator: string) { + if (!Number.isFinite(seconds) || seconds < 0) seconds = 0; + const whole = Math.floor(seconds); + const milliseconds = Math.round((seconds - whole) * 1000); + const pad = (value: number, width = 2) => String(value).padStart(width, '0'); + return `${pad(Math.floor(whole / 3600))}:${pad(Math.floor(whole / 60) % 60)}:${pad(whole % 60)}` + + `${millisecondSeparator}${pad(milliseconds, 3)}`; + } + + function subtitleText(rows: TimedRow[], format: 'srt' | 'vtt') { + const separator = format === 'srt' ? ',' : '.'; + const cues = rows.map((row, index) => { + const caption = [row.label, row.text].filter(Boolean).join(': ') || `#${index + 1}`; + const timing = + `${formatTimecode(row.start, separator)} --> ${formatTimecode(row.end, separator)}`; + return format === 'srt' ? `${index + 1}\n${timing}\n${caption}\n` : `${timing}\n${caption}\n`; + }); + return (format === 'vtt' ? 'WEBVTT\n\n' : '') + cues.join('\n'); + } + + function downloadSubtitles(format: 'srt' | 'vtt') { + if (!outputRows.length || !selected) return; + const blob = new Blob([subtitleText(outputRows, format)], { type: 'text/plain;charset=utf-8' }); + const url = URL.createObjectURL(blob); + const anchor = document.createElement('a'); + anchor.href = url; + anchor.download = `${selected.id}-transcript.${format}`; + anchor.click(); + URL.revokeObjectURL(url); + } + + function supportsSeed(entry: CatalogEntry) { + return entry.request_options?.includes('seed') === true; + } + function supportsRequestOption(entry: CatalogEntry, option: string) { // Specs that publish request metadata are authoritative. Older specs // without that metadata keep the legacy UI behavior until migrated. @@ -735,10 +779,13 @@ job: ModelInstallJob | undefined, translate = tr ) { - if (job?.state === 'running') return `${choice.label}…`; - if (job?.state === 'queued') return `${choice.label} ${translate('models.queued')}`; - if (job?.state === 'cancelling') return `${choice.label} ${translate('models.stopping')}`; - return choice.label; + // short_label, not label: the model name is already printed beside the + // buttons and would not fit inside one. The full name stays on the title + // and aria-label. + if (job?.state === 'running') return `${choice.short_label}…`; + if (job?.state === 'queued') return `${choice.short_label} ${translate('models.queued')}`; + if (job?.state === 'cancelling') return `${choice.short_label} ${translate('models.stopping')}`; + return choice.short_label; } function packageSizeLabel( @@ -751,8 +798,10 @@ ? formatBytes(size.size_bytes) : ''; if (size?.installed) { - const version = packageVersionLabel(size, translate); - return `${selected ? translate('models.selected') : translate('models.downloaded')}${version ? ` · ${version}` : ''}${bytes ? ` · ${bytes}` : ''}`; + // The version state lives on the button title now: an update has its own + // corner badge, the other states are not actionable, and the three-part + // line did not fit the button. + return `${selected ? translate('models.selected') : translate('models.downloaded')}${bytes ? ` · ${bytes}` : ''}`; } if (bytes) return bytes; if (size?.state === 'pending') return translate('models.checkingSize'); @@ -922,7 +971,7 @@ applyingModelsFolder = true; warningStatus = ''; errorStatus = ''; - status = useDefault ? 'Restoring the default models folder…' : 'Changing models folder…'; + status = useDefault ? 'Restoring the default models folder…' : 'Changing models folder…'; try { const root = await setModelsRoot(useDefault ? '' : modelsFolderInput.trim()); acceptModelsRoot(root); @@ -1297,6 +1346,8 @@ outputArtifacts = []; outputText = ''; outputJson = ''; + outputRows = []; + outputRowKind = ''; } async function ensureLoaded() { @@ -1405,10 +1456,13 @@ } async function refreshConfiguredVoices() { - if (!selectedId || server?.ui_management !== false) { + if (!selectedId) { configuredVoices = []; return; } + // Ask for this model's own voices regardless of management mode. The server + // returns its configured presets plus any embeddings shipped beside the + // weights, and skipping the call in managed mode made both unreachable. try { configuredVoices = await availableVoices(selectedId); if (quickStartVoice && !configuredVoices.includes(quickStartVoice)) quickStartVoice = ''; @@ -1569,6 +1623,22 @@ if (lyricsRequired && !lyrics.trim()) { throw new StatusWarning(`${selected.display_name_en || selected.display_name} requires lyrics.`); } + if (selected.task === 'vdes' && !instructions.trim()) { + throw new StatusWarning( + `${selected.display_name_en || selected.display_name} requires a voice description.`); + } + if (selected.task === 'align') { + // Forced aligners need both halves; the engine throws for either, and a + // form message is a better place to learn that than a raw engine error. + if (!text.trim()) { + throw new StatusWarning( + `${selected.display_name_en || selected.display_name} requires the transcript to align.`); + } + if (!language.trim()) { + throw new StatusWarning( + `${selected.display_name_en || selected.display_name} requires a transcript language.`); + } + } await ensureLoaded(); const options = requestOptions(); if (usesVibeVoiceSpeakerFiles) { @@ -1601,7 +1671,7 @@ seed: chunkSeed(resolvedSeed, index), options }; - if (supportsMaxTokens(selected)) body.max_tokens = maxTokens; + if (supportsMaxTokens(selected) && maxTokens !== '') body.max_tokens = maxTokens; if (voiceRef) body.voice_ref = voiceRef; else if (quickStartVoice) body.voice = demoVoiceSources[quickStartVoice] || quickStartVoice; else if (selected.default_voice) body.voice = selected.default_voice; @@ -1637,6 +1707,7 @@ options }, aborter.signal); outputText = String(result.text || ''); + ({ rows: outputRows, kind: outputRowKind } = timedRowsFromResult(result)); outputJson = JSON.stringify(result, null, 2); } else { if (needsSource && !audio) throw new StatusWarning('Choose a source audio file.'); @@ -1650,10 +1721,15 @@ else request.duration_seconds = duration; } request.seed = resolvedSeed; - if (supportsMaxTokens(selected)) request.max_tokens = maxTokens; + if (supportsMaxTokens(selected) && maxTokens !== '') request.max_tokens = maxTokens; } else if (selected.task === 's2s') { request.seed = resolvedSeed; - if (supportsMaxTokens(selected)) request.max_tokens = maxTokens; + if (supportsMaxTokens(selected) && maxTokens !== '') request.max_tokens = maxTokens; + } else if (supportsSeed(selected)) { + // Voice conversion and the analysis tasks declare a seed but were never + // sent one, so their engines fell back to a fresh random value on every + // run and identical inputs could not be reproduced. + request.seed = resolvedSeed; } if (audio) request.audio = audio; if (voiceRef) request.voice_ref = voiceRef; @@ -1681,6 +1757,7 @@ })); } outputText = typeof result.text === 'string' ? result.text : ''; + ({ rows: outputRows, kind: outputRowKind } = timedRowsFromResult(result)); outputJson = JSON.stringify(result, (key, value) => (key === 'audio' || key === 'payload') && typeof value === 'string' ? `` : value, 2); @@ -2134,8 +2211,9 @@ disabled={loadingModel || !available} title={resident ? `Unload ${choice?.label}` : available ? `Load ${choice?.label}` : `${choice?.label || slot.label} is not downloaded`} + aria-label={choice?.label || slot.label} on:click={() => choice && toggleStudioPackage(choice)}> - {choice?.label || slot.label} + {choice?.short_label || slot.label} {/each} @@ -2181,7 +2259,7 @@ {/if} - {#if selected.task === 'gen'} + {#if selected.task === 'gen' && supportsRequestOption(selected, 'lyrics') && !isFireRedAudioEdit} @@ -2213,7 +2291,7 @@ {/if} - {#if ['tts', 'clon', 'gen', 's2s', 'vdes'].includes(selected.task)} + {#if ['tts', 'clon', 'gen', 's2s', 'vdes'].includes(selected.task) || supportsSeed(selected)}
@@ -2225,7 +2303,7 @@
{/if} - {#if selected.task === 'gen'} + {#if selected.task === 'gen' && !isFireRedAudioEdit}

{tr('result.empty')}

{/if} {#if outputText}{/if} + {#if outputRows.length} +
+
+ {tr(`result.rows.${outputRowKind}`)} + + +
+
+ + + + + + + + + + {#each outputRows as row} + + + + + + {/each} + +
{tr('result.start')}{tr('result.end')}{outputRowKind === 'speaker_turns' ? tr('result.speaker') : tr('result.content')}
{formatTimecode(row.start, '.')}{formatTimecode(row.end, '.')}{[row.label, row.text].filter(Boolean).join(': ')}
+
+
+ {/if} {#if outputJson}
{outputJson}
{/if} @@ -2570,7 +2677,10 @@ aria-pressed={packageIsSelected(entry, choice)} disabled={groupInstallBusy(group, installJobs) || (packageSizeState === 'running' && Object.keys(packageSizes).length === 0)} - title={`${choice.format.toUpperCase()} ${choice.precision}: ${resolveCatalogPath(choice.path)}`} + title={`${choice.label} — ${choice.format.toUpperCase()} ${choice.precision}${ + packageVersionLabel(packageSizes[choice.id]) ? ` · ${packageVersionLabel(packageSizes[choice.id])}` : '' + }: ${resolveCatalogPath(choice.path)}`} + aria-label={choice.label} on:click={() => useOrInstallPackage(entry, choice)}> {installButtonLabel(choice, installJobs[choice.id], tr)} {#if packageSizeLabel(packageSizes[choice.id], packageSizeState, diff --git a/webui/native/src/routes/Arena.svelte b/webui/native/src/routes/Arena.svelte index 4a7a930d4..c29e409f0 100644 --- a/webui/native/src/routes/Arena.svelte +++ b/webui/native/src/routes/Arena.svelte @@ -20,7 +20,7 @@ export let loadedModels: LoadedModel[] = []; export let server: ServerHealth | null = null; export let modelsFolder = ''; - export let maxTokens = 1024; + export let maxTokens: number | '' = ''; export let entrySelectable: (entry: CatalogEntry) => boolean = () => true; export let studioPackageSlots: (entry: CatalogEntry) => Array<{ key: string; label: string; choice?: InstallPackageChoice }> = () => []; @@ -483,7 +483,7 @@ seed: resolveRequestSeed(arenaSeed), options }; - if (supportsMaxTokens(entry)) body.max_tokens = maxTokens; + if (supportsMaxTokens(entry) && maxTokens !== '') body.max_tokens = maxTokens; if (voiceRef) body.voice_ref = voiceRef; else if (builtinVoice) body.voice = builtinVoice; else if (entry.default_voice) body.voice = entry.default_voice;