1use std::collections::BTreeMap;
7
8use serde::{Deserialize, Deserializer, Serialize, Serializer};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
15pub enum TaskKind {
16 Vad,
18 Asr,
20 Diar,
22 SourceSeparation,
24 AudioGeneration,
26 Tts,
28 VoiceCloning,
30 VoiceConversion,
32 SpeechToSpeech,
34 Alignment,
36 VoiceDesign,
38 SpeakerRecognition,
40 Svc,
42 Midi,
44 TurnDetection,
46 WakeWord,
48 AudioClassification,
51}
52
53impl TaskKind {
54 pub fn as_str(self) -> &'static str {
56 match self {
57 TaskKind::Vad => "vad",
58 TaskKind::Asr => "asr",
59 TaskKind::Diar => "diar",
60 TaskKind::SourceSeparation => "sep",
61 TaskKind::AudioGeneration => "gen",
62 TaskKind::Tts => "tts",
63 TaskKind::VoiceCloning => "clon",
64 TaskKind::VoiceConversion => "vc",
65 TaskKind::SpeechToSpeech => "s2s",
66 TaskKind::Alignment => "align",
67 TaskKind::VoiceDesign => "vdes",
68 TaskKind::SpeakerRecognition => "spk",
69 TaskKind::Svc => "svc",
70 TaskKind::Midi => "midi",
71 TaskKind::TurnDetection => "turn",
72 TaskKind::WakeWord => "wake",
73 TaskKind::AudioClassification => "cls",
74 }
75 }
76}
77
78impl Serialize for TaskKind {
79 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
80 serializer.serialize_str(self.as_str())
81 }
82}
83
84impl<'de> Deserialize<'de> for TaskKind {
85 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
86 let s = String::deserialize(deserializer)?;
87 match s.as_str() {
88 "vad" => Ok(TaskKind::Vad),
89 "asr" => Ok(TaskKind::Asr),
90 "diar" => Ok(TaskKind::Diar),
91 "sep" => Ok(TaskKind::SourceSeparation),
92 "gen" => Ok(TaskKind::AudioGeneration),
93 "tts" => Ok(TaskKind::Tts),
94 "clon" => Ok(TaskKind::VoiceCloning),
95 "vc" => Ok(TaskKind::VoiceConversion),
96 "s2s" => Ok(TaskKind::SpeechToSpeech),
97 "align" => Ok(TaskKind::Alignment),
98 "vdes" => Ok(TaskKind::VoiceDesign),
99 "spk" => Ok(TaskKind::SpeakerRecognition),
100 "svc" => Ok(TaskKind::Svc),
101 "midi" => Ok(TaskKind::Midi),
102 "turn" => Ok(TaskKind::TurnDetection),
103 "wake" | "wake_word" => Ok(TaskKind::WakeWord),
106 "cls" | "classify" => Ok(TaskKind::AudioClassification),
107 other => Err(serde::de::Error::unknown_variant(
108 other,
109 &[
110 "vad", "asr", "diar", "sep", "gen", "tts", "clon", "vc", "s2s", "align",
111 "vdes", "spk", "svc", "midi", "turn", "wake", "cls",
112 ],
113 )),
114 }
115 }
116}
117
118#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
120#[serde(rename_all = "lowercase")]
121pub enum RunMode {
122 Offline,
124 Streaming,
126}
127
128impl RunMode {
129 pub fn as_str(self) -> &'static str {
131 match self {
132 RunMode::Offline => "offline",
133 RunMode::Streaming => "streaming",
134 }
135 }
136}
137
138#[derive(Debug, Clone, PartialEq, Eq, Hash)]
148pub enum ModelFamily {
149 SileroVad,
152 MarblenetVad,
154 Pulsevad,
157 FireredVad,
160 EarshotVad,
167
168 Qwen3Asr,
171 CitrinetAsr,
173 SenseAsr,
175 FunAsrNano,
177 HiggsAudioStt,
179 HviskeAsr,
181 HviskeAsrV6,
184 KrokoAsr,
186 NemotronAsr,
188 Nemotron3Diar,
192 NemotronTranscribe,
199 ParakeetTdt,
201 VibevoiceAsr,
203 VibevoiceAsrStreaming,
206 FireredAudio,
208 Granite5Asr,
210 Audio8Asr,
212 Audio8Tts,
214 Vibeasr,
216 MoonshineAsr,
218 NiagaraAsr,
220 CanaryAsr,
223 CohereAsr,
226 MossTranscribeDiarize,
229 Confucius4R2t2,
231 AudioFlamingo,
233 Crisperwhisper,
235 GigaamAsr,
237 IndexEcho,
239 Lfm2Audio,
241 Lfm3Audio,
247 LfmD1Omni,
252 Owsm,
254 OwsmCtc,
256 Samsone,
259 WhistleAsr,
261 Phonon2Asr,
266 UnderdogBark3,
270 HaasAsr,
274
275 Qwen3Tts,
278 Confucius4Tts,
280 DotsTts,
282 FishAudio,
284 FishDrama3,
289 GlmTts,
291 HiggsAudioTts,
293 IndexTts2,
295 IrodoriTts,
297 MossTtsLocal,
299 MossTtsNano,
301 MossTtsV15,
305 MossVoicegen,
307 Neutts,
309 Outetts,
311 PocketTts,
313 GradiumPhonon,
317 PocketTtsSmall,
322 VieneuV3Turbo,
326 Fireredtts3,
328 F5Tts,
330 MagpieTts,
332 Personaplex,
334 MinimaxH3,
336 Sanotts,
338 SoproTts,
340 MiraTts,
342 Cosyvoice3,
344 BreezeTts,
346 SopranoTts,
348 EchoTts,
350 Voxcpm1,
352 KokoroTts,
354 Zipvoice,
357 Auk,
360 PiperTts,
363 KittenTts,
366 KittenTts2,
369 Plapre,
373 Kugelaudio,
375 Maya1,
378 MossTtsd,
381 Ming3Tts,
385 XttsV2,
389
390 SortformerDiar,
393 SortformerDiarV2,
396 SeedVc,
398 Rvc,
400 Meanvc2,
402 ToneColorVc,
404 Chatterbox,
406 ChatterboxTurbo,
408 Vevo2,
410 Voxcpm2,
412 AceStep,
414
415 Htdemucs,
418 Htdemucs6Stems,
421 Mossformer2,
423 TfGridnet,
425 MelBandRoformer,
427 BsRoformer,
429 Muscriptor,
431 Omnivoice,
433 StableAudio,
435 MinimaxMusic3,
437 Supertonic,
439 Yue2,
442 MagentaRealtime2,
448 Sheetsage2,
451 VoxtralRealtime,
453 VoxtralTts,
456 Audiosr,
458 Apollo,
460 Universr,
464 BuiltinAudioUtils,
469 ControlFoley,
471 MidashEnglmGen,
473 Liveavatar,
476 Latentsync,
480 SoulxFlashhead,
487 Reuse,
489 RealtimeReuse,
493 SamAudio,
495 Sidon,
497 SmartTurn,
501
502 MicroWakeWord,
507 SherpaKws,
511 OpenWakeWord,
515 Ced,
519 AstAudioset,
523
524 Miocodec,
527 Miotts,
529 Vibevoice,
531 Dramabox,
533 Heartmula,
535 InflectV2,
537 Qwen3ForcedAligner,
539 MmsForcedAligner,
541 Ming3Audio,
545
546 Custom(String),
548}
549
550impl ModelFamily {
551 pub fn from_path(path: &str) -> Option<ModelFamily> {
579 let lower = path.to_ascii_lowercase();
580 if let Some((_, f)) = lower.rsplit_once("#family=") {
582 return Some(ModelFamily::from(f.trim()));
583 }
584 const KEYWORDS: &[(&str, ModelFamily)] = &[
586 ("silero_vad", ModelFamily::SileroVad),
587 ("silero-vad", ModelFamily::SileroVad),
588 ("marblenet_vad", ModelFamily::MarblenetVad),
589 ("marblenet-vad", ModelFamily::MarblenetVad),
590 ("marblenet", ModelFamily::MarblenetVad),
591 ("pulsevad", ModelFamily::Pulsevad),
592 ("pulse-vad", ModelFamily::Pulsevad),
593 ("pulse", ModelFamily::Pulsevad),
594 ("firered_vad", ModelFamily::FireredVad),
595 ("firered-vad", ModelFamily::FireredVad),
596 ("fireredvad", ModelFamily::FireredVad),
597 ("earshot_vad", ModelFamily::EarshotVad),
598 ("earshot-vad", ModelFamily::EarshotVad),
599 ("earshot", ModelFamily::EarshotVad),
600 ("qwen3_asr", ModelFamily::Qwen3Asr),
601 ("qwen3-asr", ModelFamily::Qwen3Asr),
602 ("qwen3_tts", ModelFamily::Qwen3Tts),
603 ("qwen3-tts", ModelFamily::Qwen3Tts),
604 ("qwen3_forced_aligner", ModelFamily::Qwen3ForcedAligner),
605 ("qwen3-forced-aligner", ModelFamily::Qwen3ForcedAligner),
606 ("qwen3", ModelFamily::Qwen3Asr),
607 ("citrinet", ModelFamily::CitrinetAsr),
608 ("sense_asr", ModelFamily::SenseAsr),
609 ("sense-asr", ModelFamily::SenseAsr),
610 ("sensevoice", ModelFamily::SenseAsr),
611 ("fun-asr-nano", ModelFamily::FunAsrNano),
612 ("fun_asr_nano", ModelFamily::FunAsrNano),
613 ("funasr", ModelFamily::FunAsrNano),
614 ("higgs_audio_stt", ModelFamily::HiggsAudioStt),
615 ("higgs_audio_tts", ModelFamily::HiggsAudioTts),
616 ("higgs", ModelFamily::HiggsAudioStt),
617 ("hviske_asr_v6", ModelFamily::HviskeAsrV6),
619 ("hviske-asr-v6", ModelFamily::HviskeAsrV6),
620 ("hviske-v6", ModelFamily::HviskeAsrV6),
621 ("hviskev6", ModelFamily::HviskeAsrV6),
622 ("hviske", ModelFamily::HviskeAsr),
623 ("whistle_asr", ModelFamily::WhistleAsr),
624 ("whistle-asr", ModelFamily::WhistleAsr),
625 ("whistle", ModelFamily::WhistleAsr),
626 ("kroko", ModelFamily::KrokoAsr),
627 ("nemotron_transcribe", ModelFamily::NemotronTranscribe),
631 ("nemotron-transcribe", ModelFamily::NemotronTranscribe),
632 ("nemotron_3.5_transcribe", ModelFamily::NemotronTranscribe),
633 ("nemotron-3.5-transcribe", ModelFamily::NemotronTranscribe),
634 ("nemotron-3.5", ModelFamily::NemotronTranscribe),
635 ("nemotron_3.5", ModelFamily::NemotronTranscribe),
636 ("nemotron_3_diar", ModelFamily::Nemotron3Diar),
637 ("nemotron-3-diar", ModelFamily::Nemotron3Diar),
638 ("nemotron_3", ModelFamily::Nemotron3Diar),
639 ("nemotron-3", ModelFamily::Nemotron3Diar),
640 ("nemotron", ModelFamily::NemotronAsr),
641 ("parakeet", ModelFamily::ParakeetTdt),
642 ("phonon2_asr", ModelFamily::Phonon2Asr),
648 ("phonon2-asr", ModelFamily::Phonon2Asr),
649 ("phonon-2", ModelFamily::Phonon2Asr),
650 ("phonon2", ModelFamily::Phonon2Asr),
651 ("phonon_2", ModelFamily::Phonon2Asr),
652 ("underdog_bark3", ModelFamily::UnderdogBark3),
653 ("underdog-bark3", ModelFamily::UnderdogBark3),
654 ("underdog-bark-3", ModelFamily::UnderdogBark3),
655 ("underdog", ModelFamily::UnderdogBark3),
656 ("bark3", ModelFamily::UnderdogBark3),
657 ("bark-3", ModelFamily::UnderdogBark3),
658 ("haas_asr", ModelFamily::HaasAsr),
659 ("haas-asr", ModelFamily::HaasAsr),
660 ("haas-ja", ModelFamily::HaasAsr),
661 ("haas", ModelFamily::HaasAsr),
662 (
663 "vibevoice_asr_streaming",
664 ModelFamily::VibevoiceAsrStreaming,
665 ),
666 (
667 "vibevoice-asr-streaming",
668 ModelFamily::VibevoiceAsrStreaming,
669 ),
670 ("vibevoice_asr", ModelFamily::VibevoiceAsr),
671 ("firered_audio", ModelFamily::FireredAudio),
672 ("firered-audio", ModelFamily::FireredAudio),
673 ("granite5asr", ModelFamily::Granite5Asr),
674 ("granite-speech", ModelFamily::Granite5Asr),
675 ("granite_speech", ModelFamily::Granite5Asr),
676 ("granite", ModelFamily::Granite5Asr),
677 ("audio8_asr", ModelFamily::Audio8Asr),
678 ("audio8-asr", ModelFamily::Audio8Asr),
679 ("audio8asr", ModelFamily::Audio8Asr),
680 ("arkasr", ModelFamily::Audio8Asr),
681 ("audio8_tts", ModelFamily::Audio8Tts),
682 ("audio8-tts", ModelFamily::Audio8Tts),
683 ("audio8tts", ModelFamily::Audio8Tts),
684 ("fireredtts3", ModelFamily::Fireredtts3),
685 ("firered_tts3", ModelFamily::Fireredtts3),
686 ("firered-tts3", ModelFamily::Fireredtts3),
687 ("vibevoice", ModelFamily::Vibevoice),
688 ("confucius4_r2t2", ModelFamily::Confucius4R2t2),
690 ("confucius4-r2t2", ModelFamily::Confucius4R2t2),
691 ("r2t2", ModelFamily::Confucius4R2t2),
692 ("confucius", ModelFamily::Confucius4Tts),
693 ("dots_tts", ModelFamily::DotsTts),
694 ("dots-tts", ModelFamily::DotsTts),
695 ("fish_drama3", ModelFamily::FishDrama3),
697 ("fish-drama3", ModelFamily::FishDrama3),
698 ("fish_audio", ModelFamily::FishAudio),
699 ("fish-audio", ModelFamily::FishAudio),
700 ("glm_tts", ModelFamily::GlmTts),
701 ("glm-tts", ModelFamily::GlmTts),
702 ("index_tts2", ModelFamily::IndexTts2),
703 ("index-tts2", ModelFamily::IndexTts2),
704 ("irodori", ModelFamily::IrodoriTts),
705 (
707 "moss_transcribe_diarize",
708 ModelFamily::MossTranscribeDiarize,
709 ),
710 (
711 "moss-transcribe-diarize",
712 ModelFamily::MossTranscribeDiarize,
713 ),
714 ("mossformer2", ModelFamily::Mossformer2),
716 ("mossformer-2", ModelFamily::Mossformer2),
717 ("mossformer", ModelFamily::Mossformer2),
718 ("moss-tts-nano", ModelFamily::MossTtsNano),
719 ("moss_tts_nano", ModelFamily::MossTtsNano),
720 ("moss-tts-local", ModelFamily::MossTtsLocal),
721 ("moss_tts_local", ModelFamily::MossTtsLocal),
722 ("moss-tts-v15", ModelFamily::MossTtsV15),
724 ("moss_tts_v15", ModelFamily::MossTtsV15),
725 ("moss_ttsd", ModelFamily::MossTtsd),
726 ("moss-ttsd", ModelFamily::MossTtsd),
727 ("mossttsd", ModelFamily::MossTtsd),
728 ("moss_voicegen", ModelFamily::MossVoicegen),
729 ("moss-voicegen", ModelFamily::MossVoicegen),
730 ("moss", ModelFamily::MossTtsNano),
731 ("neutts", ModelFamily::Neutts),
732 ("outetts", ModelFamily::Outetts),
733 ("gradium_phonon", ModelFamily::GradiumPhonon),
734 ("gradium-phonon", ModelFamily::GradiumPhonon),
735 ("gradium", ModelFamily::GradiumPhonon),
736 ("phonon-31m", ModelFamily::GradiumPhonon),
740 ("phonon_31m", ModelFamily::GradiumPhonon),
741 ("phonon-40m", ModelFamily::GradiumPhonon),
742 ("phonon_40m", ModelFamily::GradiumPhonon),
743 ("pocket_tts_small", ModelFamily::PocketTtsSmall),
747 ("pocket-tts-small", ModelFamily::PocketTtsSmall),
748 ("pockettts-small", ModelFamily::PocketTtsSmall),
749 ("pocket_tts", ModelFamily::PocketTts),
750 ("pocket-tts", ModelFamily::PocketTts),
751 ("vietneu", ModelFamily::VieneuV3Turbo),
752 ("vieneu", ModelFamily::VieneuV3Turbo),
753 ("f5_tts", ModelFamily::F5Tts),
754 ("f5-tts", ModelFamily::F5Tts),
755 ("magpie", ModelFamily::MagpieTts),
756 ("personaplex", ModelFamily::Personaplex),
757 ("soprano_tts", ModelFamily::SopranoTts),
758 ("soprano-tts", ModelFamily::SopranoTts),
759 ("soprano", ModelFamily::SopranoTts),
760 ("index_echo", ModelFamily::IndexEcho),
762 ("index-echo", ModelFamily::IndexEcho),
763 ("indexecho", ModelFamily::IndexEcho),
764 ("echo_tts", ModelFamily::EchoTts),
765 ("echo-tts", ModelFamily::EchoTts),
766 ("echo", ModelFamily::EchoTts),
767 ("kokoro_tts", ModelFamily::KokoroTts),
768 ("kokoro-tts", ModelFamily::KokoroTts),
769 ("kokoro", ModelFamily::KokoroTts),
770 ("piper_tts", ModelFamily::PiperTts),
771 ("piper-tts", ModelFamily::PiperTts),
772 ("piper", ModelFamily::PiperTts),
773 ("kitten_tts2", ModelFamily::KittenTts2),
775 ("kitten-tts2", ModelFamily::KittenTts2),
776 ("kitten_tts_2", ModelFamily::KittenTts2),
777 ("kittentts2", ModelFamily::KittenTts2),
778 ("kitten_tts", ModelFamily::KittenTts),
779 ("kitten-tts", ModelFamily::KittenTts),
780 ("kitten", ModelFamily::KittenTts),
781 ("plapre_3", ModelFamily::Plapre),
783 ("plapre-3", ModelFamily::Plapre),
784 ("plapre", ModelFamily::Plapre),
785 ("kugelaudio", ModelFamily::Kugelaudio),
786 ("kugel-audio", ModelFamily::Kugelaudio),
787 ("kugel_audio", ModelFamily::Kugelaudio),
788 ("kugel", ModelFamily::Kugelaudio),
789 ("maya1", ModelFamily::Maya1),
790 ("maya-1", ModelFamily::Maya1),
791 ("maya_1", ModelFamily::Maya1),
792 ("maya", ModelFamily::Maya1),
793 ("ming3_audio", ModelFamily::Ming3Audio),
795 ("ming3-audio", ModelFamily::Ming3Audio),
796 ("ming-3.0-audio", ModelFamily::Ming3Audio),
797 ("ming_3.0_audio", ModelFamily::Ming3Audio),
798 ("ming3_tts", ModelFamily::Ming3Tts),
799 ("ming3-tts", ModelFamily::Ming3Tts),
800 ("ming-3.0-tts", ModelFamily::Ming3Tts),
801 ("ming_3.0_tts", ModelFamily::Ming3Tts),
802 ("ming3", ModelFamily::Ming3Tts),
803 ("xtts_v2", ModelFamily::XttsV2),
804 ("xtts-v2", ModelFamily::XttsV2),
805 ("xtts", ModelFamily::XttsV2),
806 ("voxcpm1", ModelFamily::Voxcpm1),
807 ("voxcpm-1", ModelFamily::Voxcpm1),
808 ("sanotts", ModelFamily::Sanotts),
809 ("sano-tts", ModelFamily::Sanotts),
810 ("sano_tts", ModelFamily::Sanotts),
811 ("sopro_tts", ModelFamily::SoproTts),
812 ("sopro-tts", ModelFamily::SoproTts),
813 ("sopro", ModelFamily::SoproTts),
814 ("mira_tts", ModelFamily::MiraTts),
815 ("mira-tts", ModelFamily::MiraTts),
816 ("miratts", ModelFamily::MiraTts),
817 ("mira", ModelFamily::MiraTts),
818 ("cosyvoice3", ModelFamily::Cosyvoice3),
819 ("cosyvoice-3", ModelFamily::Cosyvoice3),
820 ("cosyvoice", ModelFamily::Cosyvoice3),
821 ("breeze_tts", ModelFamily::BreezeTts),
822 ("breeze-tts", ModelFamily::BreezeTts),
823 ("breeze", ModelFamily::BreezeTts),
824 ("vibeasr", ModelFamily::Vibeasr),
825 ("vibe-asr", ModelFamily::Vibeasr),
826 ("moonshine_asr", ModelFamily::MoonshineAsr),
827 ("moonshine-asr", ModelFamily::MoonshineAsr),
828 ("moonshine", ModelFamily::MoonshineAsr),
829 ("niagara_asr", ModelFamily::NiagaraAsr),
830 ("niagara-asr", ModelFamily::NiagaraAsr),
831 ("niagara", ModelFamily::NiagaraAsr),
832 ("canary_asr", ModelFamily::CanaryAsr),
833 ("canary-asr", ModelFamily::CanaryAsr),
834 ("canary", ModelFamily::CanaryAsr),
835 ("cohere_asr", ModelFamily::CohereAsr),
836 ("cohere-asr", ModelFamily::CohereAsr),
837 ("cohere", ModelFamily::CohereAsr),
838 ("audio_flamingo", ModelFamily::AudioFlamingo),
839 ("audio-flamingo", ModelFamily::AudioFlamingo),
840 ("audioflamingo", ModelFamily::AudioFlamingo),
841 ("crisperwhisper", ModelFamily::Crisperwhisper),
842 ("crisper-whisper", ModelFamily::Crisperwhisper),
843 ("crisper_whisper", ModelFamily::Crisperwhisper),
844 ("gigaam_asr", ModelFamily::GigaamAsr),
845 ("gigaam-asr", ModelFamily::GigaamAsr),
846 ("gigaam", ModelFamily::GigaamAsr),
847 ("lfm_d1_omni", ModelFamily::LfmD1Omni),
850 ("lfm-d1-omni", ModelFamily::LfmD1Omni),
851 ("d1_omni", ModelFamily::LfmD1Omni),
852 ("d1-omni", ModelFamily::LfmD1Omni),
853 ("lfm2_audio", ModelFamily::Lfm2Audio),
854 ("lfm2-audio", ModelFamily::Lfm2Audio),
855 ("lfm2", ModelFamily::Lfm2Audio),
856 ("lfm3_audio", ModelFamily::Lfm3Audio),
857 ("lfm3-audio", ModelFamily::Lfm3Audio),
858 ("lfm3", ModelFamily::Lfm3Audio),
859 ("owsm_ctc", ModelFamily::OwsmCtc),
861 ("owsm-ctc", ModelFamily::OwsmCtc),
862 ("owsmctc", ModelFamily::OwsmCtc),
863 ("owsm", ModelFamily::Owsm),
864 ("samsone", ModelFamily::Samsone),
865 ("sam-sone", ModelFamily::Samsone),
866 ("zipvoice", ModelFamily::Zipvoice),
867 ("zip-voice", ModelFamily::Zipvoice),
868 ("liveavatar", ModelFamily::Liveavatar),
869 ("live-avatar", ModelFamily::Liveavatar),
870 ("latentsync", ModelFamily::Latentsync),
871 ("latent-sync", ModelFamily::Latentsync),
872 ("latent_sync", ModelFamily::Latentsync),
873 ("soulx_flashhead", ModelFamily::SoulxFlashhead),
874 ("soulx-flashhead", ModelFamily::SoulxFlashhead),
875 ("soulx", ModelFamily::SoulxFlashhead),
876 ("flashhead", ModelFamily::SoulxFlashhead),
877 ("realtime_reuse", ModelFamily::RealtimeReuse),
881 ("realtime-reuse", ModelFamily::RealtimeReuse),
882 ("real-time-reuse", ModelFamily::RealtimeReuse),
883 ("realtimereuse", ModelFamily::RealtimeReuse),
884 ("reuse", ModelFamily::Reuse),
885 ("re-use", ModelFamily::Reuse),
886 ("sam_audio", ModelFamily::SamAudio),
887 ("sam-audio", ModelFamily::SamAudio),
888 ("samaudio", ModelFamily::SamAudio),
889 ("sidon", ModelFamily::Sidon),
890 ("smart_turn", ModelFamily::SmartTurn),
891 ("smart-turn", ModelFamily::SmartTurn),
892 ("smartturn", ModelFamily::SmartTurn),
893 ("auk", ModelFamily::Auk),
894 ("minimax_h3", ModelFamily::MinimaxH3),
895 ("minimax-h3", ModelFamily::MinimaxH3),
896 ("sortformer_diar_v2", ModelFamily::SortformerDiarV2),
897 ("sortformer-diar-v2", ModelFamily::SortformerDiarV2),
898 ("sortformer_diar", ModelFamily::SortformerDiar),
899 ("sortformer-diar", ModelFamily::SortformerDiar),
900 ("sortformer", ModelFamily::SortformerDiar),
901 ("seed_vc", ModelFamily::SeedVc),
902 ("seed-vc", ModelFamily::SeedVc),
903 ("seedvc", ModelFamily::SeedVc),
904 ("rvc", ModelFamily::Rvc),
905 ("meanvc2", ModelFamily::Meanvc2),
906 ("mean-vc2", ModelFamily::Meanvc2),
907 ("tone_color_vc", ModelFamily::ToneColorVc),
908 ("tone-color-vc", ModelFamily::ToneColorVc),
909 ("tone_color", ModelFamily::ToneColorVc),
910 ("tonecolor", ModelFamily::ToneColorVc),
911 ("chatterbox_turbo", ModelFamily::ChatterboxTurbo),
912 ("chatterbox-turbo", ModelFamily::ChatterboxTurbo),
913 ("chatterbox", ModelFamily::Chatterbox),
914 ("vevo2", ModelFamily::Vevo2),
915 ("voxcpm2", ModelFamily::Voxcpm2),
916 ("ace_step", ModelFamily::AceStep),
917 ("ace-step", ModelFamily::AceStep),
918 ("htdemucs_6stems", ModelFamily::Htdemucs6Stems),
920 ("htdemucs-6stems", ModelFamily::Htdemucs6Stems),
921 ("htdemucs_6s", ModelFamily::Htdemucs6Stems),
922 ("htdemucs-6s", ModelFamily::Htdemucs6Stems),
923 ("htdemucs", ModelFamily::Htdemucs),
924 ("demucs", ModelFamily::Htdemucs),
925 ("tf_gridnet", ModelFamily::TfGridnet),
926 ("tf-gridnet", ModelFamily::TfGridnet),
927 ("tfgridnet", ModelFamily::TfGridnet),
928 ("gridnet", ModelFamily::TfGridnet),
929 ("mel-band-roformer", ModelFamily::MelBandRoformer),
930 ("mel_band_roformer", ModelFamily::MelBandRoformer),
931 ("bs-roformer", ModelFamily::BsRoformer),
932 ("bs_roformer", ModelFamily::BsRoformer),
933 ("muscriptor", ModelFamily::Muscriptor),
934 ("omnivoice", ModelFamily::Omnivoice),
935 ("stable_audio", ModelFamily::StableAudio),
936 ("stable-audio", ModelFamily::StableAudio),
937 ("minimax_music3", ModelFamily::MinimaxMusic3),
938 ("minimax-music3", ModelFamily::MinimaxMusic3),
939 ("supertonic", ModelFamily::Supertonic),
940 ("yue2", ModelFamily::Yue2),
941 ("magenta_realtime_2", ModelFamily::MagentaRealtime2),
942 ("magenta-realtime-2", ModelFamily::MagentaRealtime2),
943 ("magenta_rt2", ModelFamily::MagentaRealtime2),
944 ("magenta-rt2", ModelFamily::MagentaRealtime2),
945 ("magenta", ModelFamily::MagentaRealtime2),
946 ("yue-2", ModelFamily::Yue2),
947 ("sheetsage2", ModelFamily::Sheetsage2),
948 ("sheetsage-2", ModelFamily::Sheetsage2),
949 ("sheetsage", ModelFamily::Sheetsage2),
950 ("voxtral_tts", ModelFamily::VoxtralTts),
952 ("voxtral-tts", ModelFamily::VoxtralTts),
953 ("voxtral-realtime", ModelFamily::VoxtralRealtime),
954 ("voxtral", ModelFamily::VoxtralRealtime),
955 ("audiosr", ModelFamily::Audiosr),
956 ("audio-sr", ModelFamily::Audiosr),
957 ("apollo", ModelFamily::Apollo),
958 ("universr", ModelFamily::Universr),
959 ("univer-sr", ModelFamily::Universr),
960 ("controlfoley", ModelFamily::ControlFoley),
961 ("control-foley", ModelFamily::ControlFoley),
962 ("midashenglm_gen", ModelFamily::MidashEnglmGen),
963 ("midashenglm-gen", ModelFamily::MidashEnglmGen),
964 ("midashen", ModelFamily::MidashEnglmGen),
965 ("builtin_audio_utils", ModelFamily::BuiltinAudioUtils),
966 ("builtin-audio-utils", ModelFamily::BuiltinAudioUtils),
967 ("deepfilternet", ModelFamily::BuiltinAudioUtils),
968 ("rnnoise", ModelFamily::BuiltinAudioUtils),
969 ("zipenhancer", ModelFamily::BuiltinAudioUtils),
970 ("gtcrn", ModelFamily::BuiltinAudioUtils),
971 ("flashsr", ModelFamily::BuiltinAudioUtils),
972 ("miocodec", ModelFamily::Miocodec),
973 ("miotts", ModelFamily::Miotts),
974 ("dramabox", ModelFamily::Dramabox),
975 ("heartmula", ModelFamily::Heartmula),
976 ("inflect", ModelFamily::InflectV2),
977 ("mms_forced_aligner", ModelFamily::MmsForcedAligner),
978 ("mms", ModelFamily::MmsForcedAligner),
979 ("forced-aligner", ModelFamily::Qwen3ForcedAligner),
980 ("micro_wake_word", ModelFamily::MicroWakeWord),
983 ("micro-wake-word", ModelFamily::MicroWakeWord),
984 ("micro_wake", ModelFamily::MicroWakeWord),
985 ("micro-wake", ModelFamily::MicroWakeWord),
986 ("microwake", ModelFamily::MicroWakeWord),
987 ("sherpa_kws", ModelFamily::SherpaKws),
988 ("sherpa-kws", ModelFamily::SherpaKws),
989 ("sherpa", ModelFamily::SherpaKws),
990 ("open_wake_word", ModelFamily::OpenWakeWord),
992 ("open-wake-word", ModelFamily::OpenWakeWord),
993 ("openwake", ModelFamily::OpenWakeWord),
994 ("ced", ModelFamily::Ced),
995 ("ast_audioset", ModelFamily::AstAudioset),
996 ("ast-audioset", ModelFamily::AstAudioset),
997 ("audioset", ModelFamily::AstAudioset),
998 ];
999 KEYWORDS
1000 .iter()
1001 .find(|(k, _)| lower.contains(k))
1002 .map(|(_, family)| family.clone())
1003 }
1004
1005 pub fn as_str(&self) -> &str {
1007 match self {
1008 ModelFamily::SileroVad => "silero_vad",
1009 ModelFamily::MarblenetVad => "marblenet_vad",
1010 ModelFamily::Pulsevad => "pulsevad",
1011 ModelFamily::FireredVad => "firered_vad",
1012 ModelFamily::EarshotVad => "earshot_vad",
1013 ModelFamily::Qwen3Asr => "qwen3_asr",
1014 ModelFamily::CitrinetAsr => "citrinet_asr",
1015 ModelFamily::SenseAsr => "sense_asr",
1016 ModelFamily::FunAsrNano => "fun_asr_nano",
1017 ModelFamily::HiggsAudioStt => "higgs_audio_stt",
1018 ModelFamily::HviskeAsr => "hviske_asr",
1019 ModelFamily::HviskeAsrV6 => "hviske_asr_v6",
1020 ModelFamily::KrokoAsr => "kroko_asr",
1021 ModelFamily::NemotronAsr => "nemotron_asr",
1022 ModelFamily::Nemotron3Diar => "nemotron_3_diar",
1023 ModelFamily::NemotronTranscribe => "nemotron_transcribe",
1024 ModelFamily::ParakeetTdt => "parakeet_tdt",
1025 ModelFamily::VibevoiceAsr => "vibevoice_asr",
1026 ModelFamily::VibevoiceAsrStreaming => "vibevoice_asr_streaming",
1027 ModelFamily::FireredAudio => "firered_audio",
1028 ModelFamily::Granite5Asr => "granite5asr",
1029 ModelFamily::Audio8Asr => "audio8_asr",
1030 ModelFamily::Audio8Tts => "audio8_tts",
1031 ModelFamily::Vibeasr => "vibeasr",
1032 ModelFamily::MoonshineAsr => "moonshine_asr",
1033 ModelFamily::NiagaraAsr => "niagara_asr",
1034 ModelFamily::CanaryAsr => "canary_asr",
1035 ModelFamily::CohereAsr => "cohere_asr",
1036 ModelFamily::MossTranscribeDiarize => "moss_transcribe_diarize",
1037 ModelFamily::Confucius4R2t2 => "confucius4_r2t2",
1038 ModelFamily::AudioFlamingo => "audio_flamingo",
1039 ModelFamily::Crisperwhisper => "crisperwhisper",
1040 ModelFamily::GigaamAsr => "gigaam_asr",
1041 ModelFamily::IndexEcho => "index_echo",
1042 ModelFamily::Lfm2Audio => "lfm2_audio",
1043 ModelFamily::Lfm3Audio => "lfm3_audio",
1044 ModelFamily::LfmD1Omni => "lfm_d1_omni",
1045 ModelFamily::Owsm => "owsm",
1046 ModelFamily::OwsmCtc => "owsm_ctc",
1047 ModelFamily::Samsone => "samsone",
1048 ModelFamily::WhistleAsr => "whistle_asr",
1049 ModelFamily::Phonon2Asr => "phonon2_asr",
1050 ModelFamily::UnderdogBark3 => "underdog_bark3",
1051 ModelFamily::HaasAsr => "haas_asr",
1052 ModelFamily::Qwen3Tts => "qwen3_tts",
1053 ModelFamily::Confucius4Tts => "confucius4_tts",
1054 ModelFamily::DotsTts => "dots_tts",
1055 ModelFamily::FishAudio => "fish_audio",
1056 ModelFamily::FishDrama3 => "fish_drama3",
1057 ModelFamily::GlmTts => "glm_tts",
1058 ModelFamily::HiggsAudioTts => "higgs_audio_tts",
1059 ModelFamily::IndexTts2 => "index_tts2",
1060 ModelFamily::IrodoriTts => "irodori_tts",
1061 ModelFamily::MossTtsLocal => "moss_tts_local",
1062 ModelFamily::MossTtsNano => "moss_tts_nano",
1063 ModelFamily::MossTtsV15 => "moss_tts_v15",
1064 ModelFamily::MossVoicegen => "moss_voicegen",
1065 ModelFamily::Neutts => "neutts",
1066 ModelFamily::Outetts => "outetts",
1067 ModelFamily::PocketTts => "pocket_tts",
1068 ModelFamily::GradiumPhonon => "gradium_phonon",
1069 ModelFamily::PocketTtsSmall => "pocket_tts_small",
1070 ModelFamily::VieneuV3Turbo => "vieneu_v3_turbo",
1071 ModelFamily::Fireredtts3 => "fireredtts3",
1072 ModelFamily::F5Tts => "f5_tts",
1073 ModelFamily::MagpieTts => "magpie_tts",
1074 ModelFamily::Personaplex => "personaplex",
1075 ModelFamily::SopranoTts => "soprano_tts",
1076 ModelFamily::EchoTts => "echo_tts",
1077 ModelFamily::Voxcpm1 => "voxcpm1",
1078 ModelFamily::KokoroTts => "kokoro_tts",
1079 ModelFamily::Zipvoice => "zipvoice",
1080 ModelFamily::Auk => "auk",
1081 ModelFamily::PiperTts => "piper_tts",
1082 ModelFamily::KittenTts => "kitten_tts",
1083 ModelFamily::KittenTts2 => "kitten_tts2",
1084 ModelFamily::Plapre => "plapre",
1085 ModelFamily::Kugelaudio => "kugelaudio",
1086 ModelFamily::Maya1 => "maya1",
1087 ModelFamily::MossTtsd => "moss_ttsd",
1088 ModelFamily::Ming3Tts => "ming3_tts",
1089 ModelFamily::XttsV2 => "xtts_v2",
1090 ModelFamily::MinimaxH3 => "minimax_h3",
1091 ModelFamily::Sanotts => "sanotts",
1092 ModelFamily::SoproTts => "sopro_tts",
1093 ModelFamily::MiraTts => "mira_tts",
1094 ModelFamily::Cosyvoice3 => "cosyvoice3",
1095 ModelFamily::BreezeTts => "breeze_tts",
1096 ModelFamily::SortformerDiar => "sortformer_diar",
1097 ModelFamily::SortformerDiarV2 => "sortformer_diar_v2",
1098 ModelFamily::SeedVc => "seed_vc",
1099 ModelFamily::Rvc => "rvc",
1100 ModelFamily::Meanvc2 => "meanvc2",
1101 ModelFamily::ToneColorVc => "tone_color_vc",
1102 ModelFamily::Chatterbox => "chatterbox",
1103 ModelFamily::ChatterboxTurbo => "chatterbox_turbo",
1104 ModelFamily::Vevo2 => "vevo2",
1105 ModelFamily::Voxcpm2 => "voxcpm2",
1106 ModelFamily::AceStep => "ace_step",
1107 ModelFamily::Htdemucs => "htdemucs",
1108 ModelFamily::Htdemucs6Stems => "htdemucs_6stems",
1109 ModelFamily::Mossformer2 => "mossformer2",
1110 ModelFamily::TfGridnet => "tf_gridnet",
1111 ModelFamily::MelBandRoformer => "mel_band_roformer",
1112 ModelFamily::BsRoformer => "bs_roformer",
1113 ModelFamily::Muscriptor => "muscriptor",
1114 ModelFamily::Omnivoice => "omnivoice",
1115 ModelFamily::StableAudio => "stable_audio",
1116 ModelFamily::MinimaxMusic3 => "minimax_music3",
1117 ModelFamily::Supertonic => "supertonic",
1118 ModelFamily::Yue2 => "yue2",
1119 ModelFamily::MagentaRealtime2 => "magenta_realtime_2",
1120 ModelFamily::Sheetsage2 => "sheetsage2",
1121 ModelFamily::VoxtralRealtime => "voxtral_realtime",
1122 ModelFamily::VoxtralTts => "voxtral_tts",
1123 ModelFamily::Audiosr => "audiosr",
1124 ModelFamily::Apollo => "apollo",
1125 ModelFamily::Universr => "universr",
1126 ModelFamily::BuiltinAudioUtils => "builtin_audio_utils",
1127 ModelFamily::ControlFoley => "controlfoley",
1128 ModelFamily::MidashEnglmGen => "midashenglm_gen",
1129 ModelFamily::Liveavatar => "liveavatar",
1130 ModelFamily::Latentsync => "latentsync",
1131 ModelFamily::SoulxFlashhead => "soulx_flashhead",
1132 ModelFamily::Reuse => "reuse",
1133 ModelFamily::RealtimeReuse => "realtime_reuse",
1134 ModelFamily::SamAudio => "sam_audio",
1135 ModelFamily::Sidon => "sidon",
1136 ModelFamily::SmartTurn => "smart_turn",
1137 ModelFamily::MicroWakeWord => "micro_wake_word",
1138 ModelFamily::SherpaKws => "sherpa_kws",
1139 ModelFamily::OpenWakeWord => "open_wake_word",
1140 ModelFamily::Ced => "ced",
1141 ModelFamily::AstAudioset => "ast_audioset",
1142 ModelFamily::Miocodec => "miocodec",
1143 ModelFamily::Miotts => "miotts",
1144 ModelFamily::Vibevoice => "vibevoice",
1145 ModelFamily::Dramabox => "dramabox",
1146 ModelFamily::Heartmula => "heartmula",
1147 ModelFamily::InflectV2 => "inflect_v2",
1148 ModelFamily::Qwen3ForcedAligner => "qwen3_forced_aligner",
1149 ModelFamily::MmsForcedAligner => "mms_forced_aligner",
1150 ModelFamily::Ming3Audio => "ming3_audio",
1151 ModelFamily::Custom(s) => s,
1152 }
1153 }
1154}
1155
1156impl From<&str> for ModelFamily {
1157 fn from(s: &str) -> Self {
1159 match s {
1160 "silero_vad" => ModelFamily::SileroVad,
1161 "marblenet_vad" => ModelFamily::MarblenetVad,
1162 "pulsevad" => ModelFamily::Pulsevad,
1163 "firered_vad" => ModelFamily::FireredVad,
1164 "firered-vad" => ModelFamily::FireredVad,
1165 "earshot_vad" => ModelFamily::EarshotVad,
1166 "earshot-vad" => ModelFamily::EarshotVad,
1167 "earshot" => ModelFamily::EarshotVad,
1169 "qwen3_asr" => ModelFamily::Qwen3Asr,
1170 "citrinet_asr" => ModelFamily::CitrinetAsr,
1171 "sense_asr" => ModelFamily::SenseAsr,
1172 "fun_asr_nano" => ModelFamily::FunAsrNano,
1173 "higgs_audio_stt" => ModelFamily::HiggsAudioStt,
1174 "hviske_asr" => ModelFamily::HviskeAsr,
1175 "hviske_asr_v6" => ModelFamily::HviskeAsrV6,
1176 "hviske-asr-v6" => ModelFamily::HviskeAsrV6,
1177 "kroko_asr" => ModelFamily::KrokoAsr,
1178 "nemotron_asr" => ModelFamily::NemotronAsr,
1179 "nemotron_3_diar" => ModelFamily::Nemotron3Diar,
1180 "nemotron_transcribe" => ModelFamily::NemotronTranscribe,
1181 "nemotron-transcribe" => ModelFamily::NemotronTranscribe,
1182 "parakeet_tdt" => ModelFamily::ParakeetTdt,
1183 "vibevoice_asr" => ModelFamily::VibevoiceAsr,
1184 "vibevoice_asr_streaming" => ModelFamily::VibevoiceAsrStreaming,
1185 "firered_audio" => ModelFamily::FireredAudio,
1186 "granite5asr" => ModelFamily::Granite5Asr,
1187 "granite_speech5_asr" => ModelFamily::Granite5Asr,
1188 "granite_speech" => ModelFamily::Granite5Asr,
1189 "granite_speech5_ctc" => ModelFamily::Granite5Asr,
1190 "audio8_asr" => ModelFamily::Audio8Asr,
1191 "arkasr" => ModelFamily::Audio8Asr,
1192 "audio8_tts" => ModelFamily::Audio8Tts,
1193 "vibeasr" => ModelFamily::Vibeasr,
1194 "moonshine_asr" => ModelFamily::MoonshineAsr,
1195 "niagara_asr" => ModelFamily::NiagaraAsr,
1196 "canary_asr" => ModelFamily::CanaryAsr,
1197 "cohere_asr" => ModelFamily::CohereAsr,
1198 "moss_transcribe_diarize" => ModelFamily::MossTranscribeDiarize,
1199 "confucius4_r2t2" => ModelFamily::Confucius4R2t2,
1200 "audio_flamingo" => ModelFamily::AudioFlamingo,
1201 "crisperwhisper" => ModelFamily::Crisperwhisper,
1202 "gigaam_asr" => ModelFamily::GigaamAsr,
1203 "index_echo" => ModelFamily::IndexEcho,
1204 "lfm2_audio" => ModelFamily::Lfm2Audio,
1205 "lfm3_audio" => ModelFamily::Lfm3Audio,
1206 "lfm3-audio" => ModelFamily::Lfm3Audio,
1207 "lfm_d1_omni" => ModelFamily::LfmD1Omni,
1208 "lfm-d1-omni" => ModelFamily::LfmD1Omni,
1209 "owsm" => ModelFamily::Owsm,
1210 "owsm_ctc" => ModelFamily::OwsmCtc,
1211 "samsone" => ModelFamily::Samsone,
1212 "whistle_asr" => ModelFamily::WhistleAsr,
1213 "whistle-asr" => ModelFamily::WhistleAsr,
1214 "phonon2_asr" => ModelFamily::Phonon2Asr,
1215 "phonon2-asr" => ModelFamily::Phonon2Asr,
1216 "underdog_bark3" => ModelFamily::UnderdogBark3,
1217 "underdog-bark3" => ModelFamily::UnderdogBark3,
1218 "haas_asr" => ModelFamily::HaasAsr,
1219 "haas-asr" => ModelFamily::HaasAsr,
1220 "qwen3_tts" => ModelFamily::Qwen3Tts,
1221 "confucius4_tts" => ModelFamily::Confucius4Tts,
1222 "dots_tts" => ModelFamily::DotsTts,
1223 "fish_audio" => ModelFamily::FishAudio,
1224 "fish_drama3" => ModelFamily::FishDrama3,
1225 "fish-drama3" => ModelFamily::FishDrama3,
1226 "glm_tts" => ModelFamily::GlmTts,
1227 "higgs_audio_tts" => ModelFamily::HiggsAudioTts,
1228 "index_tts2" => ModelFamily::IndexTts2,
1229 "irodori_tts" => ModelFamily::IrodoriTts,
1230 "moss_tts_local" => ModelFamily::MossTtsLocal,
1231 "moss_tts_nano" => ModelFamily::MossTtsNano,
1232 "moss_tts_v15" => ModelFamily::MossTtsV15,
1233 "moss_voicegen" => ModelFamily::MossVoicegen,
1234 "neutts" => ModelFamily::Neutts,
1235 "outetts" => ModelFamily::Outetts,
1236 "pocket_tts" => ModelFamily::PocketTts,
1237 "pocket_tts_small" => ModelFamily::PocketTtsSmall,
1238 "pocket-tts-small" => ModelFamily::PocketTtsSmall,
1239 "gradium_phonon" => ModelFamily::GradiumPhonon,
1240 "gradium-phonon" => ModelFamily::GradiumPhonon,
1241 "gradium" => ModelFamily::GradiumPhonon,
1242 "vietneu_tts" => ModelFamily::VieneuV3Turbo,
1243 "vieneu_v3_turbo" => ModelFamily::VieneuV3Turbo,
1244 "fireredtts3" => ModelFamily::Fireredtts3,
1245 "f5_tts" => ModelFamily::F5Tts,
1246 "magpie_tts" => ModelFamily::MagpieTts,
1247 "personaplex" => ModelFamily::Personaplex,
1248 "soprano_tts" => ModelFamily::SopranoTts,
1249 "echo_tts" => ModelFamily::EchoTts,
1250 "voxcpm1" => ModelFamily::Voxcpm1,
1251 "kokoro_tts" => ModelFamily::KokoroTts,
1252 "zipvoice" => ModelFamily::Zipvoice,
1253 "auk" => ModelFamily::Auk,
1254 "piper_tts" => ModelFamily::PiperTts,
1255 "kitten_tts" => ModelFamily::KittenTts,
1256 "kitten_tts2" => ModelFamily::KittenTts2,
1257 "plapre" => ModelFamily::Plapre,
1258 "plapre_3" | "plapre-3" => ModelFamily::Plapre,
1259 "kugelaudio" => ModelFamily::Kugelaudio,
1260 "maya1" => ModelFamily::Maya1,
1261 "moss_ttsd" => ModelFamily::MossTtsd,
1262 "ming3_tts" => ModelFamily::Ming3Tts,
1263 "ming3-tts" => ModelFamily::Ming3Tts,
1264 "ming3_audio" => ModelFamily::Ming3Audio,
1265 "ming3-audio" => ModelFamily::Ming3Audio,
1266 "xtts_v2" => ModelFamily::XttsV2,
1267 "xtts-v2" => ModelFamily::XttsV2,
1268 "xtts" => ModelFamily::XttsV2,
1269 "minimax_h3" => ModelFamily::MinimaxH3,
1270 "sanotts" => ModelFamily::Sanotts,
1271 "sopro_tts" => ModelFamily::SoproTts,
1272 "sopro" => ModelFamily::SoproTts,
1273 "sopro_v2" => ModelFamily::SoproTts,
1274 "sopro_v2_turbo" => ModelFamily::SoproTts,
1275 "mira_tts" => ModelFamily::MiraTts,
1276 "miratts" => ModelFamily::MiraTts,
1277 "mira" => ModelFamily::MiraTts,
1278 "MiraTTS" => ModelFamily::MiraTts,
1279 "cosyvoice3" => ModelFamily::Cosyvoice3,
1280 "breeze_tts" => ModelFamily::BreezeTts,
1281 "sortformer_diar" => ModelFamily::SortformerDiar,
1282 "sortformer_diar_v2" => ModelFamily::SortformerDiarV2,
1283 "seed_vc" => ModelFamily::SeedVc,
1284 "rvc" => ModelFamily::Rvc,
1285 "meanvc2" => ModelFamily::Meanvc2,
1286 "tone_color_vc" => ModelFamily::ToneColorVc,
1287 "chatterbox" => ModelFamily::Chatterbox,
1288 "chatterbox_turbo" => ModelFamily::ChatterboxTurbo,
1289 "vevo2" => ModelFamily::Vevo2,
1290 "voxcpm2" => ModelFamily::Voxcpm2,
1291 "ace_step" => ModelFamily::AceStep,
1292 "htdemucs" => ModelFamily::Htdemucs,
1293 "htdemucs_6stems" => ModelFamily::Htdemucs6Stems,
1294 "htdemucs_6s" => ModelFamily::Htdemucs6Stems,
1295 "mossformer2" => ModelFamily::Mossformer2,
1296 "tf_gridnet" => ModelFamily::TfGridnet,
1297 "tf-gridnet" => ModelFamily::TfGridnet,
1298 "mel_band_roformer" => ModelFamily::MelBandRoformer,
1299 "bs_roformer" => ModelFamily::BsRoformer,
1300 "muscriptor" => ModelFamily::Muscriptor,
1301 "omnivoice" => ModelFamily::Omnivoice,
1302 "stable_audio" => ModelFamily::StableAudio,
1303 "minimax_music3" => ModelFamily::MinimaxMusic3,
1304 "supertonic" => ModelFamily::Supertonic,
1305 "yue2" => ModelFamily::Yue2,
1306 "magenta_realtime_2" => ModelFamily::MagentaRealtime2,
1307 "magenta-realtime-2" => ModelFamily::MagentaRealtime2,
1308 "sheetsage2" => ModelFamily::Sheetsage2,
1309 "voxtral_realtime" => ModelFamily::VoxtralRealtime,
1310 "voxtral_tts" => ModelFamily::VoxtralTts,
1311 "voxtral-tts" => ModelFamily::VoxtralTts,
1312 "audiosr" => ModelFamily::Audiosr,
1313 "apollo" => ModelFamily::Apollo,
1314 "universr" => ModelFamily::Universr,
1315 "builtin_audio_utils" => ModelFamily::BuiltinAudioUtils,
1316 "controlfoley" => ModelFamily::ControlFoley,
1317 "midashenglm_gen" => ModelFamily::MidashEnglmGen,
1318 "liveavatar" => ModelFamily::Liveavatar,
1319 "latentsync" => ModelFamily::Latentsync,
1320 "latent-sync" => ModelFamily::Latentsync,
1321 "soulx_flashhead" => ModelFamily::SoulxFlashhead,
1322 "soulx-flashhead" => ModelFamily::SoulxFlashhead,
1323 "reuse" => ModelFamily::Reuse,
1324 "realtime_reuse" => ModelFamily::RealtimeReuse,
1325 "realtime-reuse" => ModelFamily::RealtimeReuse,
1326 "sam_audio" => ModelFamily::SamAudio,
1327 "sidon" => ModelFamily::Sidon,
1328 "smart_turn" => ModelFamily::SmartTurn,
1329 "micro_wake_word" => ModelFamily::MicroWakeWord,
1330 "micro-wake-word" => ModelFamily::MicroWakeWord,
1331 "sherpa_kws" => ModelFamily::SherpaKws,
1332 "sherpa-kws" => ModelFamily::SherpaKws,
1333 "open_wake_word" => ModelFamily::OpenWakeWord,
1334 "open-wake-word" => ModelFamily::OpenWakeWord,
1335 "ced" => ModelFamily::Ced,
1336 "ast_audioset" => ModelFamily::AstAudioset,
1337 "ast-audioset" => ModelFamily::AstAudioset,
1338 "miocodec" => ModelFamily::Miocodec,
1339 "miotts" => ModelFamily::Miotts,
1340 "vibevoice" => ModelFamily::Vibevoice,
1341 "dramabox" => ModelFamily::Dramabox,
1342 "heartmula" => ModelFamily::Heartmula,
1343 "inflect_v2" => ModelFamily::InflectV2,
1344 "qwen3_forced_aligner" => ModelFamily::Qwen3ForcedAligner,
1345 "mms_forced_aligner" => ModelFamily::MmsForcedAligner,
1346 other => ModelFamily::Custom(other.to_owned()),
1347 }
1348 }
1349}
1350
1351impl From<String> for ModelFamily {
1352 fn from(s: String) -> Self {
1353 ModelFamily::from(s.as_str())
1354 }
1355}
1356
1357impl AsRef<str> for ModelFamily {
1358 fn as_ref(&self) -> &str {
1359 self.as_str()
1360 }
1361}
1362
1363impl std::fmt::Display for ModelFamily {
1364 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1365 f.write_str(self.as_str())
1366 }
1367}
1368
1369#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
1371#[serde(rename_all = "lowercase")]
1372pub enum Backend {
1373 Cpu,
1375 Cuda,
1377 Hip,
1379 Vulkan,
1381 Metal,
1383 Best,
1385}
1386
1387impl Backend {
1388 pub fn as_str(self) -> &'static str {
1390 match self {
1391 Backend::Cpu => "cpu",
1392 Backend::Cuda => "cuda",
1393 Backend::Hip => "hip",
1394 Backend::Vulkan => "vulkan",
1395 Backend::Metal => "metal",
1396 Backend::Best => "best",
1397 }
1398 }
1399}
1400
1401#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1403pub struct Device {
1404 pub backend: String,
1406 pub index: i32,
1408 pub name: String,
1410 #[serde(rename = "type")]
1412 pub kind: String,
1413}
1414
1415#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1417pub struct LoaderInfo {
1418 pub family: String,
1420 pub capabilities: Capabilities,
1422 pub instructions_policy: String,
1424 pub api_endpoints: Vec<String>,
1426}
1427
1428#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1430pub struct Capabilities {
1431 pub supported_tasks: Vec<SupportedTask>,
1433 pub languages: Vec<String>,
1435 pub supports_speaker_reference: bool,
1437 pub supports_style_condition: bool,
1439 pub supports_timestamps: bool,
1441}
1442
1443#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1445pub struct SupportedTask {
1446 pub task: String,
1448 pub modes: Vec<String>,
1450}
1451
1452#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1454pub struct ModelMetadata {
1455 pub family: String,
1457 pub variant: String,
1459 pub description: String,
1461 pub config_candidates: Vec<String>,
1463 pub weight_candidates: Vec<String>,
1465}
1466
1467#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
1469pub struct TimeSpan {
1470 pub start_sample: i64,
1472 pub end_sample: i64,
1474}
1475
1476#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1478pub struct SpeechSegment {
1479 pub span: TimeSpan,
1481 pub confidence: f32,
1483 pub text: String,
1485}
1486
1487#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1489pub struct SpeakerTurn {
1490 pub speaker_id: String,
1492 pub span: TimeSpan,
1494 pub confidence: f32,
1496 #[serde(default)]
1498 pub text: String,
1499}
1500
1501#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1503pub struct WordTimestamp {
1504 pub span: TimeSpan,
1506 pub word: String,
1508 pub confidence: f32,
1510}
1511
1512#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1514pub struct VoiceArtifact {
1515 pub kind: String,
1517 pub id: String,
1519 #[serde(default)]
1521 pub payload_base64: String,
1522 #[serde(default)]
1524 pub meta: BTreeMap<String, String>,
1525}
1526
1527#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1529pub struct CliOption {
1530 pub name: String,
1532 pub value_name: String,
1534 pub description: String,
1536 pub required: bool,
1538 #[serde(default, skip_serializing_if = "Option::is_none")]
1540 pub default_value: Option<String>,
1541 #[serde(default, skip_serializing_if = "Option::is_none")]
1543 pub min_value: Option<String>,
1544 #[serde(default, skip_serializing_if = "Option::is_none")]
1546 pub max_value: Option<String>,
1547}
1548
1549#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1551pub struct NamedAsset {
1552 pub id: String,
1554 pub path: String,
1556}
1557
1558#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1560pub struct CliInterface {
1561 #[serde(default)]
1563 pub request_options: Vec<CliOption>,
1564 #[serde(default)]
1566 pub session_options: Vec<CliOption>,
1567 #[serde(default)]
1569 pub load_options: Vec<CliOption>,
1570}
1571
1572#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1574pub struct ModelInspection {
1575 pub metadata: ModelMetadata,
1577 pub capabilities: Capabilities,
1579 pub cli: CliInterface,
1581 #[serde(default)]
1583 pub discovered_configs: Vec<NamedAsset>,
1584 #[serde(default)]
1586 pub discovered_weights: Vec<NamedAsset>,
1587 #[serde(default)]
1589 pub model_root: String,
1590}
1591
1592#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1594pub struct TextOutput {
1595 pub text: String,
1597 pub language: String,
1599}
1600
1601#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1603pub struct AudioBufferInfo {
1604 pub sample_rate: i32,
1606 pub channels: i32,
1608 pub sample_count: usize,
1610 #[serde(default)]
1613 pub samples: Option<Vec<f32>>,
1614}
1615
1616#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1618pub struct NamedAudioOutput {
1619 pub id: String,
1621 pub audio: AudioBufferInfo,
1623 pub meta: BTreeMap<String, String>,
1625}
1626
1627#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1636pub struct CustomSchemaOutput {
1637 pub schema: String,
1639 pub data: serde_json::Value,
1641}
1642
1643#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1645pub struct TaskResult {
1646 pub speech_segments: Vec<SpeechSegment>,
1648 pub speaker_turns: Vec<SpeakerTurn>,
1650 pub text_output: Option<TextOutput>,
1652 pub audio_output: Option<AudioBufferInfo>,
1654 pub named_audio_outputs: Vec<NamedAudioOutput>,
1656 #[serde(default)]
1667 pub word_timestamps: Vec<WordTimestamp>,
1668 #[serde(default)]
1670 pub custom_schema_output: Option<CustomSchemaOutput>,
1671 #[serde(default)]
1673 pub artifact_output: Option<VoiceArtifact>,
1674 #[serde(default)]
1676 pub output_artifacts: Vec<VoiceArtifact>,
1677}
1678
1679#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1681pub struct StreamEvent {
1682 pub voice_activity: Vec<VoiceActivityEvent>,
1684 pub partial_text: Option<TextOutput>,
1686 #[serde(default)]
1690 pub partial_text_snapshot: Option<TextOutput>,
1691 pub audio_output: Option<AudioBufferInfo>,
1693 #[serde(default)]
1695 pub named_audio_outputs: Vec<NamedAudioOutput>,
1696 #[serde(default)]
1698 pub speaker_turns: Vec<SpeakerTurn>,
1699 #[serde(default)]
1702 pub word_timestamps: Vec<WordTimestamp>,
1703 #[serde(default)]
1705 pub output_artifacts: Vec<VoiceArtifact>,
1706 pub is_final: bool,
1708}
1709
1710#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1712pub struct VoiceActivityEvent {
1713 pub kind: String,
1715 pub sample: i64,
1717 pub probability: f32,
1719 pub segment: Option<SpeechSegment>,
1721}
1722
1723#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1725pub struct StreamingPolicy {
1726 pub input: String,
1728 pub output: String,
1730 pub preferred_audio_chunk_samples: usize,
1732 pub preferred_audio_chunk_seconds: f64,
1734}
1735
1736#[cfg(test)]
1737mod tests {
1738 #![allow(clippy::unwrap_used, clippy::expect_used)]
1740 use super::*;
1741
1742 #[test]
1746 fn model_family_roundtrip() {
1747 let mut variants: Vec<ModelFamily> = Vec::new();
1748 macro_rules! push {
1749 ($($v:ident),* $(,)?) => {
1750 $(variants.push(ModelFamily::$v);)*
1751 };
1752 }
1753 push![
1754 SileroVad,
1756 MarblenetVad,
1757 Pulsevad,
1758 FireredVad,
1759 EarshotVad,
1760 Qwen3Asr,
1762 CitrinetAsr,
1763 SenseAsr,
1764 FunAsrNano,
1765 HiggsAudioStt,
1766 HviskeAsr,
1767 HviskeAsrV6,
1768 KrokoAsr,
1769 NemotronAsr,
1770 Nemotron3Diar,
1771 NemotronTranscribe,
1772 ParakeetTdt,
1773 VibevoiceAsr,
1774 VibevoiceAsrStreaming,
1775 FireredAudio,
1776 Granite5Asr,
1777 Audio8Asr,
1778 Audio8Tts,
1779 Vibeasr,
1780 MoonshineAsr,
1781 NiagaraAsr,
1782 CanaryAsr,
1783 CohereAsr,
1784 MossTranscribeDiarize,
1785 Confucius4R2t2,
1786 AudioFlamingo,
1787 Crisperwhisper,
1788 GigaamAsr,
1789 IndexEcho,
1790 Lfm2Audio,
1791 Lfm3Audio,
1792 LfmD1Omni,
1793 Owsm,
1794 OwsmCtc,
1795 Samsone,
1796 WhistleAsr,
1797 Phonon2Asr,
1798 UnderdogBark3,
1799 HaasAsr,
1800 Qwen3Tts,
1802 Confucius4Tts,
1803 DotsTts,
1804 FishAudio,
1805 FishDrama3,
1806 GlmTts,
1807 HiggsAudioTts,
1808 IndexTts2,
1809 IrodoriTts,
1810 MossTtsLocal,
1811 MossTtsNano,
1812 MossTtsV15,
1813 MossVoicegen,
1814 Neutts,
1815 Outetts,
1816 PocketTts,
1817 PocketTtsSmall,
1818 GradiumPhonon,
1819 VieneuV3Turbo,
1820 Fireredtts3,
1821 F5Tts,
1822 MagpieTts,
1823 Personaplex,
1824 SopranoTts,
1825 EchoTts,
1826 Voxcpm1,
1827 KokoroTts,
1828 Zipvoice,
1829 Auk,
1830 PiperTts,
1831 KittenTts,
1832 KittenTts2,
1833 Plapre,
1834 Kugelaudio,
1835 Maya1,
1836 MossTtsd,
1837 Ming3Tts,
1838 XttsV2,
1839 MinimaxH3,
1840 Sanotts,
1841 SoproTts,
1842 MiraTts,
1843 Cosyvoice3,
1844 BreezeTts,
1845 SortformerDiar,
1847 SortformerDiarV2,
1848 SeedVc,
1849 Rvc,
1850 Meanvc2,
1851 ToneColorVc,
1852 Chatterbox,
1853 ChatterboxTurbo,
1854 Vevo2,
1855 Voxcpm2,
1856 AceStep,
1857 Htdemucs,
1858 Htdemucs6Stems,
1859 Mossformer2,
1860 TfGridnet,
1861 MelBandRoformer,
1862 BsRoformer,
1863 Muscriptor,
1864 Omnivoice,
1865 StableAudio,
1866 MinimaxMusic3,
1867 Supertonic,
1868 Yue2,
1869 MagentaRealtime2,
1870 Sheetsage2,
1871 VoxtralRealtime,
1872 VoxtralTts,
1873 Audiosr,
1874 Apollo,
1875 Universr,
1876 BuiltinAudioUtils,
1877 ControlFoley,
1878 MidashEnglmGen,
1879 Liveavatar,
1880 Latentsync,
1881 SoulxFlashhead,
1882 Reuse,
1883 RealtimeReuse,
1884 SamAudio,
1885 Sidon,
1886 SmartTurn,
1887 MicroWakeWord,
1889 SherpaKws,
1890 OpenWakeWord,
1891 Ced,
1892 AstAudioset,
1893 Miocodec,
1895 Miotts,
1896 Vibevoice,
1897 Dramabox,
1898 Heartmula,
1899 InflectV2,
1900 Qwen3ForcedAligner,
1901 MmsForcedAligner,
1902 Ming3Audio,
1903 ];
1904 assert!(
1905 variants.len() >= 40,
1906 "ModelFamily 应至少覆盖上游全部 40+ loader 族,当前 {}",
1907 variants.len()
1908 );
1909 for v in variants {
1910 let name = v.as_str();
1911 assert_eq!(
1912 ModelFamily::from(name),
1913 v,
1914 "as_str() 与 From<&str> 不一致:{}",
1915 name
1916 );
1917 assert_eq!(format!("{v}"), name);
1919 assert_eq!(v.as_ref(), name);
1920 }
1921 }
1922
1923 #[test]
1924 fn model_family_custom_fallback() {
1925 let m = ModelFamily::from("brand_new_family");
1927 match &m {
1928 ModelFamily::Custom(s) => assert_eq!(s, "brand_new_family"),
1929 other => panic!("未收录名字应落入 Custom,得到 {other:?}"),
1930 }
1931 assert_eq!(m.as_str(), "brand_new_family");
1932 assert_eq!(
1934 ModelFamily::from("brand_new_family"),
1935 ModelFamily::Custom("brand_new_family".to_owned())
1936 );
1937 assert_eq!(
1939 ModelFamily::from("qwen3_asr".to_owned()),
1940 ModelFamily::Qwen3Asr
1941 );
1942 }
1943
1944 #[test]
1945 fn model_family_from_path() {
1946 assert_eq!(
1948 ModelFamily::from_path("models/qwen3-asr-0.6b-q8_0.gguf"),
1949 Some(ModelFamily::Qwen3Asr)
1950 );
1951 assert_eq!(
1952 ModelFamily::from_path("sortformer-diar-4spk-v1-q8_0.gguf"),
1953 Some(ModelFamily::SortformerDiar)
1954 );
1955 assert_eq!(
1956 ModelFamily::from_path("citrinet-asr-q8_0.gguf"),
1957 Some(ModelFamily::CitrinetAsr)
1958 );
1959 assert_eq!(
1960 ModelFamily::from_path("moss-tts-nano-q8_0.gguf"),
1961 Some(ModelFamily::MossTtsNano)
1962 );
1963 assert_eq!(
1965 ModelFamily::from_path("fish-drama3-q8_0.gguf"),
1966 Some(ModelFamily::FishDrama3)
1967 );
1968 assert_eq!(
1969 ModelFamily::from_path("fish_audio-f16.gguf"),
1970 Some(ModelFamily::FishAudio)
1971 );
1972 assert_eq!(
1974 ModelFamily::from_path("moss-tts-v15-q8_0.gguf"),
1975 Some(ModelFamily::MossTtsV15)
1976 );
1977 assert_eq!(
1979 ModelFamily::from_path("nemotron-3-diarization-bf16.gguf"),
1980 Some(ModelFamily::Nemotron3Diar)
1981 );
1982 assert_eq!(
1984 ModelFamily::from_path("vieneu-v3-turbo-q8_0.gguf"),
1985 Some(ModelFamily::VieneuV3Turbo)
1986 );
1987 assert_eq!(ModelFamily::from("vietneu_tts"), ModelFamily::VieneuV3Turbo);
1988 assert_eq!(
1990 ModelFamily::from_path("qwen3-tts-12hz-0.6b-base-q8_0.gguf"),
1991 Some(ModelFamily::Qwen3Tts)
1992 );
1993 assert_eq!(
1994 ModelFamily::from_path("qwen3-forced-aligner-q8_0.gguf"),
1995 Some(ModelFamily::Qwen3ForcedAligner)
1996 );
1997 assert_eq!(
1998 ModelFamily::from_path("mira-tts-q8_0.gguf"),
1999 Some(ModelFamily::MiraTts)
2000 );
2001 assert_eq!(
2002 ModelFamily::from_path("htdemucs-6s-q8_0.gguf"),
2003 Some(ModelFamily::Htdemucs6Stems)
2004 );
2005 assert_eq!(
2007 ModelFamily::from_path("htdemucs-q8_0.gguf"),
2008 Some(ModelFamily::Htdemucs)
2009 );
2010 assert_eq!(
2012 ModelFamily::from_path("kitten-tts2-q8_0.gguf"),
2013 Some(ModelFamily::KittenTts2)
2014 );
2015 assert_eq!(
2016 ModelFamily::from_path("kitten-tts-q8_0.gguf"),
2017 Some(ModelFamily::KittenTts)
2018 );
2019 assert_eq!(
2021 ModelFamily::from_path("plapre-3-bf16.gguf"),
2022 Some(ModelFamily::Plapre)
2023 );
2024 assert_eq!(
2026 ModelFamily::from_path("open-wake-word-alexa-f32.gguf"),
2027 Some(ModelFamily::OpenWakeWord)
2028 );
2029 assert_eq!(
2030 ModelFamily::from_path("microwake-mixednet-q8_0.gguf"),
2031 Some(ModelFamily::MicroWakeWord)
2032 );
2033 assert_eq!(
2035 ModelFamily::from_path("index-echo-q8_0.gguf"),
2036 Some(ModelFamily::IndexEcho)
2037 );
2038 assert_eq!(
2039 ModelFamily::from_path("echo-tts-q8_0.gguf"),
2040 Some(ModelFamily::EchoTts)
2041 );
2042 assert_eq!(
2044 ModelFamily::from_path("owsm-ctc-q8_0.gguf"),
2045 Some(ModelFamily::OwsmCtc)
2046 );
2047 assert_eq!(
2048 ModelFamily::from_path("owsm-q8_0.gguf"),
2049 Some(ModelFamily::Owsm)
2050 );
2051 assert_eq!(
2053 ModelFamily::from_path("moss-ttsd-q8_0.gguf"),
2054 Some(ModelFamily::MossTtsd)
2055 );
2056 assert_eq!(
2058 ModelFamily::from_path("smart-turn-q8_0.gguf"),
2059 Some(ModelFamily::SmartTurn)
2060 );
2061 assert_eq!(
2063 ModelFamily::from_path("firered-vad-q8_0.gguf"),
2064 Some(ModelFamily::FireredVad)
2065 );
2066 assert_eq!(
2068 ModelFamily::from_path("hviske-asr-v6-q8_0.gguf"),
2069 Some(ModelFamily::HviskeAsrV6)
2070 );
2071 assert_eq!(
2072 ModelFamily::from_path("hviske-asr-q8_0.gguf"),
2073 Some(ModelFamily::HviskeAsr)
2074 );
2075 assert_eq!(
2076 ModelFamily::from_path("whistle-asr-q8_0.gguf"),
2077 Some(ModelFamily::WhistleAsr)
2078 );
2079 assert_eq!(
2081 ModelFamily::from_path("mossformer2-ss-16k-f32.gguf"),
2082 Some(ModelFamily::Mossformer2)
2083 );
2084 assert_eq!(
2085 ModelFamily::from_path("tf-gridnet-q8_0.gguf"),
2086 Some(ModelFamily::TfGridnet)
2087 );
2088 assert_eq!(
2090 ModelFamily::from_path("micro-wake-word-hey-jarvis-q8_0.gguf"),
2091 Some(ModelFamily::MicroWakeWord)
2092 );
2093 assert_eq!(
2094 ModelFamily::from_path("sherpa-kws-keywords-q8_0.gguf"),
2095 Some(ModelFamily::SherpaKws)
2096 );
2097 assert_eq!(
2099 ModelFamily::from_path("ced-base-16k-q8_0.gguf"),
2100 Some(ModelFamily::Ced)
2101 );
2102 assert_eq!(
2103 ModelFamily::from_path("qwen3-forced-aligner-q8_0.gguf"),
2104 Some(ModelFamily::Qwen3ForcedAligner)
2105 );
2106 assert_eq!(
2107 ModelFamily::from_path("ast-audioset-q8_0.gguf"),
2108 Some(ModelFamily::AstAudioset)
2109 );
2110 assert_eq!(
2111 ModelFamily::from_path("tone-color-vc-q8_0.gguf"),
2112 Some(ModelFamily::ToneColorVc)
2113 );
2114 assert_eq!(
2115 ModelFamily::from("htdemucs_6s"),
2116 ModelFamily::Htdemucs6Stems
2117 );
2118 assert_eq!(
2120 ModelFamily::from_path("vibevoice-asr-streaming-7b-q8_0.gguf"),
2121 Some(ModelFamily::VibevoiceAsrStreaming)
2122 );
2123 assert_eq!(
2124 ModelFamily::from_path("sortformer-diar-v2-q8_0.gguf"),
2125 Some(ModelFamily::SortformerDiarV2)
2126 );
2127 assert_eq!(
2128 ModelFamily::from_path("kokoro-tts-82m-q8_0.gguf"),
2129 Some(ModelFamily::KokoroTts)
2130 );
2131 assert_eq!(
2132 ModelFamily::from_path("moonshine-tiny-q8_0.gguf"),
2133 Some(ModelFamily::MoonshineAsr)
2134 );
2135 assert_eq!(
2136 ModelFamily::from_path("niagara-asr-q8_0.gguf"),
2137 Some(ModelFamily::NiagaraAsr)
2138 );
2139 assert_eq!(
2140 ModelFamily::from_path("yue2-music-q8_0.gguf"),
2141 Some(ModelFamily::Yue2)
2142 );
2143 assert_eq!(
2144 ModelFamily::from_path("sheetsage2-q8_0.gguf"),
2145 Some(ModelFamily::Sheetsage2)
2146 );
2147 assert_eq!(
2149 ModelFamily::from_path("voxtral-tts-4b-q8_0.gguf"),
2150 Some(ModelFamily::VoxtralTts)
2151 );
2152 assert_eq!(
2153 ModelFamily::from_path("voxtral-realtime-q8_0.gguf"),
2154 Some(ModelFamily::VoxtralRealtime)
2155 );
2156 assert_eq!(
2157 ModelFamily::from_path("pulsevad-2.1k-f32.gguf"),
2158 Some(ModelFamily::Pulsevad)
2159 );
2160 assert_eq!(
2161 ModelFamily::from_path("canary-180m-flash-q8_0.gguf"),
2162 Some(ModelFamily::CanaryAsr)
2163 );
2164 assert_eq!(
2165 ModelFamily::from_path("cohere-transcribe-03-2026-q8_0.gguf"),
2166 Some(ModelFamily::CohereAsr)
2167 );
2168 assert_eq!(
2170 ModelFamily::from_path("moss-transcribe-diarize-q8_0.gguf"),
2171 Some(ModelFamily::MossTranscribeDiarize)
2172 );
2173 assert_eq!(
2174 ModelFamily::from_path("apollo-orig.gguf"),
2175 Some(ModelFamily::Apollo)
2176 );
2177 assert_eq!(
2178 ModelFamily::from_path("universr-audio-orig.gguf"),
2179 Some(ModelFamily::Universr)
2180 );
2181 assert_eq!(
2182 ModelFamily::from_path("zipvoice-distill-q8_0.gguf"),
2183 Some(ModelFamily::Zipvoice)
2184 );
2185 assert_eq!(
2186 ModelFamily::from_path("auk-flash-q8_0.gguf"),
2187 Some(ModelFamily::Auk)
2188 );
2189 assert_eq!(
2190 ModelFamily::from_path("liveavatar-nvfp4.gguf"),
2191 Some(ModelFamily::Liveavatar)
2192 );
2193 assert_eq!(
2194 ModelFamily::from_path("piper-en-us-lessac-medium-orig.gguf"),
2195 Some(ModelFamily::PiperTts)
2196 );
2197 assert_eq!(
2198 ModelFamily::from_path("kitten-tts-mini-0.8-orig.gguf"),
2199 Some(ModelFamily::KittenTts)
2200 );
2201 assert_eq!(
2203 ModelFamily::from_path("confucius4-r2t2-q8_0.gguf"),
2204 Some(ModelFamily::Confucius4R2t2)
2205 );
2206 assert_eq!(
2207 ModelFamily::from_path("confucius4-tts-q8_0.gguf"),
2208 Some(ModelFamily::Confucius4Tts)
2209 );
2210 assert_eq!(
2212 ModelFamily::from_path("deepfilternet2"),
2213 Some(ModelFamily::BuiltinAudioUtils)
2214 );
2215 assert_eq!(
2218 ModelFamily::from_path("phonon-2-mixed-q8.gguf"),
2219 Some(ModelFamily::Phonon2Asr)
2220 );
2221 assert_eq!(
2222 ModelFamily::from_path("Phonon-2-GGUF/phonon-2-mixed-q8.gguf"),
2223 Some(ModelFamily::Phonon2Asr)
2224 );
2225 assert_eq!(
2226 ModelFamily::from_path("phonon-31m-en-q8_0.gguf"),
2227 Some(ModelFamily::GradiumPhonon)
2228 );
2229 assert_eq!(
2230 ModelFamily::from_path("gradium-phonon-31m-en-q8_0.gguf"),
2231 Some(ModelFamily::GradiumPhonon)
2232 );
2233 assert_eq!(
2234 ModelFamily::from_path("pocket-tts-q8_0.gguf"),
2235 Some(ModelFamily::PocketTts)
2236 );
2237 assert_eq!(
2240 ModelFamily::from_path(
2241 "PocketTTS-Small-GGUF/english-18m-refl/english-18m-refl-f32.gguf"
2242 ),
2243 Some(ModelFamily::PocketTtsSmall)
2244 );
2245 assert_eq!(
2248 ModelFamily::from_path("RE-USE-GGUF/realtime-reuse-f32.gguf"),
2249 Some(ModelFamily::RealtimeReuse)
2250 );
2251 assert_eq!(
2252 ModelFamily::from_path("Haas-ja-v1.0-GGUF/haas-ja-v1.0-q8_0.gguf"),
2253 Some(ModelFamily::HaasAsr)
2254 );
2255 assert_eq!(
2256 ModelFamily::from_path("Underdog-Bark-3.0-GGUF/underdog-bark-3.0-mixed-f16.gguf"),
2257 Some(ModelFamily::UnderdogBark3)
2258 );
2259 assert_eq!(
2260 ModelFamily::from_path("d1-Omni-2B-GGUF/d1-Omni-2B-Q8_0.gguf"),
2261 Some(ModelFamily::LfmD1Omni)
2262 );
2263 assert_eq!(
2264 ModelFamily::from_path("d1-Omni-2B-GGUF/mmproj-d1-Omni-2B-F16.gguf"),
2265 Some(ModelFamily::LfmD1Omni)
2266 );
2267 assert_eq!(
2269 ModelFamily::from_path("ming-3.0-audio-tiny-bf16.gguf"),
2270 Some(ModelFamily::Ming3Audio)
2271 );
2272 assert_eq!(
2273 ModelFamily::from_path("ming-3.0-tts-0.5b-bf16.gguf"),
2274 Some(ModelFamily::Ming3Tts)
2275 );
2276 assert_eq!(
2277 ModelFamily::from_path("xtts-v2-gpt-q8_0.gguf"),
2278 Some(ModelFamily::XttsV2)
2279 );
2280 assert_eq!(
2281 ModelFamily::from_path("latentsync-1.6-q8_0-f16.gguf"),
2282 Some(ModelFamily::Latentsync)
2283 );
2284 assert_eq!(
2286 ModelFamily::from_path("Qwen3-ASR.Q8_0.GGUF"),
2287 Some(ModelFamily::Qwen3Asr)
2288 );
2289 assert_eq!(
2291 ModelFamily::from_path("model.gguf#family=citrinet_asr"),
2292 Some(ModelFamily::CitrinetAsr)
2293 );
2294 assert_eq!(
2295 ModelFamily::from_path("model.gguf#family=MiraTTS"),
2296 Some(ModelFamily::MiraTts)
2297 );
2298 assert_eq!(
2299 ModelFamily::from_path("model.gguf#family=qwen3_tts"),
2300 Some(ModelFamily::Qwen3Tts)
2301 );
2302 assert_eq!(
2304 ModelFamily::from_path("earshot_vad.safetensors"),
2305 Some(ModelFamily::EarshotVad)
2306 );
2307 assert_eq!(
2308 ModelFamily::from_path("nemotron-transcribe-30b-a4b-experts-iq4_nl.gguf"),
2309 Some(ModelFamily::NemotronTranscribe)
2310 );
2311 assert_eq!(
2314 ModelFamily::from_path(
2315 "mmproj-NVIDIA-Nemotron-3.5-Transcribe-30B-A4B-Encoder-F16.gguf"
2316 ),
2317 Some(ModelFamily::NemotronTranscribe)
2318 );
2319 assert_eq!(
2320 ModelFamily::from_path("NVIDIA-Nemotron-3.5-Transcribe-30B-A4B-GGUF"),
2321 Some(ModelFamily::NemotronTranscribe)
2322 );
2323 assert_eq!(
2325 ModelFamily::from_path("nemotron-3-diarization-bf16.gguf"),
2326 Some(ModelFamily::Nemotron3Diar)
2327 );
2328 assert_eq!(
2329 ModelFamily::from_path("LFM3-Audio-2B-Q8_0.gguf"),
2330 Some(ModelFamily::Lfm3Audio)
2331 );
2332 assert_eq!(
2333 ModelFamily::from_path("mmproj-LFM3-Audio-2B-F16.gguf"),
2334 Some(ModelFamily::Lfm3Audio)
2335 );
2336 assert_eq!(
2338 ModelFamily::from_path("lfm2.5-audio-1.5b-q8_0.gguf"),
2339 Some(ModelFamily::Lfm2Audio)
2340 );
2341 assert_eq!(
2342 ModelFamily::from_path("magenta-rt2-small-f16.gguf"),
2343 Some(ModelFamily::MagentaRealtime2)
2344 );
2345 assert_eq!(
2346 ModelFamily::from_path("Magenta-RealTime-2-GGUF/magenta-rt2-base-q8_0.gguf"),
2347 Some(ModelFamily::MagentaRealtime2)
2348 );
2349 assert_eq!(
2350 ModelFamily::from_path("SoulX-FlashHead-Lite-Q8_0.gguf"),
2351 Some(ModelFamily::SoulxFlashhead)
2352 );
2353 assert_eq!(
2354 ModelFamily::from_path("SoulX-FlashHead-GGUF"),
2355 Some(ModelFamily::SoulxFlashhead)
2356 );
2357 assert_eq!(ModelFamily::from_path("my-weights.gguf"), None);
2359 assert_eq!(ModelFamily::from_path(""), None);
2360 }
2361
2362 #[test]
2363 fn task_kind_as_str() {
2364 let cases = [
2365 (TaskKind::Vad, "vad"),
2366 (TaskKind::Asr, "asr"),
2367 (TaskKind::Diar, "diar"),
2368 (TaskKind::SourceSeparation, "sep"),
2369 (TaskKind::AudioGeneration, "gen"),
2370 (TaskKind::Tts, "tts"),
2371 (TaskKind::VoiceCloning, "clon"),
2372 (TaskKind::VoiceConversion, "vc"),
2373 (TaskKind::SpeechToSpeech, "s2s"),
2374 (TaskKind::Alignment, "align"),
2375 (TaskKind::VoiceDesign, "vdes"),
2376 (TaskKind::SpeakerRecognition, "spk"),
2377 (TaskKind::Svc, "svc"),
2378 (TaskKind::Midi, "midi"),
2379 (TaskKind::TurnDetection, "turn"),
2380 (TaskKind::WakeWord, "wake"),
2381 (TaskKind::AudioClassification, "cls"),
2382 ];
2383 for (k, want) in cases {
2384 assert_eq!(k.as_str(), want);
2385 }
2386 }
2387
2388 #[test]
2389 fn task_kind_aliases() {
2390 assert_eq!(
2392 serde_json::from_str::<TaskKind>("\"wake_word\"").unwrap(),
2393 TaskKind::WakeWord
2394 );
2395 assert_eq!(
2396 serde_json::from_str::<TaskKind>("\"classify\"").unwrap(),
2397 TaskKind::AudioClassification
2398 );
2399 }
2400
2401 #[test]
2402 fn task_kind_serde_roundtrip() {
2403 let all = [
2406 TaskKind::Vad,
2407 TaskKind::Asr,
2408 TaskKind::Diar,
2409 TaskKind::SourceSeparation,
2410 TaskKind::AudioGeneration,
2411 TaskKind::Tts,
2412 TaskKind::VoiceCloning,
2413 TaskKind::VoiceConversion,
2414 TaskKind::SpeechToSpeech,
2415 TaskKind::Alignment,
2416 TaskKind::VoiceDesign,
2417 TaskKind::SpeakerRecognition,
2418 TaskKind::Svc,
2419 TaskKind::Midi,
2420 TaskKind::TurnDetection,
2421 TaskKind::WakeWord,
2422 TaskKind::AudioClassification,
2423 ];
2424 for k in all {
2425 let s = serde_json::to_string(&k).unwrap();
2426 assert_eq!(s, format!("\"{}\"", k.as_str()));
2427 assert_eq!(serde_json::from_str::<TaskKind>(&s).unwrap(), k);
2428 }
2429 assert!(serde_json::from_str::<TaskKind>("\"sourceseparation\"").is_err());
2430 }
2431
2432 #[test]
2433 fn run_mode_as_str() {
2434 assert_eq!(RunMode::Offline.as_str(), "offline");
2435 assert_eq!(RunMode::Streaming.as_str(), "streaming");
2436 }
2437
2438 #[test]
2439 fn backend_as_str() {
2440 let cases = [
2441 (Backend::Cpu, "cpu"),
2442 (Backend::Cuda, "cuda"),
2443 (Backend::Hip, "hip"),
2444 (Backend::Vulkan, "vulkan"),
2445 (Backend::Metal, "metal"),
2446 (Backend::Best, "best"),
2447 ];
2448 for (b, want) in cases {
2449 assert_eq!(b.as_str(), want);
2450 }
2451 }
2452
2453 #[test]
2455 fn structured_types_deserialize() {
2456 let result: TaskResult = serde_json::from_str(
2457 r#"{
2458 "speech_segments": [
2459 {"span": {"start_sample": 0, "end_sample": 1600}, "confidence": 0.95, "text": ""}
2460 ],
2461 "text_output": {"text": "hi", "language": "en"},
2462 "audio_output": {"sample_rate": 24000, "channels": 1, "sample_count": 0, "samples": []},
2463 "named_audio_outputs": [],
2464 "speaker_turns": [
2465 {"speaker_id": "speaker_0", "span": {"start_sample": 0, "end_sample": 1600}, "confidence": 0.9, "text": "hello"}
2466 ],
2467 "word_timestamps": [
2468 {"span": {"start_sample": 0, "end_sample": 320}, "word": "hello", "confidence": 0.99}
2469 ],
2470 "artifact_output": {"kind": "speaker_embedding", "id": "spk1", "payload_base64": "", "meta": {}},
2471 "output_artifacts": [
2472 {"kind": "custom", "id": "a", "payload_base64": "AQID", "meta": {"k": "v"}}
2473 ]
2474 }"#,
2475 )
2476 .unwrap();
2477 assert_eq!(result.speech_segments.len(), 1);
2478 assert_eq!(result.speech_segments[0].span.start_sample, 0);
2479 assert_eq!(result.speech_segments[0].confidence, 0.95);
2480 assert_eq!(result.text_output.as_ref().unwrap().text, "hi");
2481 assert_eq!(result.audio_output.unwrap().sample_rate, 24000);
2482 assert_eq!(result.speaker_turns[0].text, "hello");
2483 assert_eq!(result.word_timestamps[0].word, "hello");
2484 assert_eq!(
2485 result.artifact_output.as_ref().unwrap().kind,
2486 "speaker_embedding"
2487 );
2488 assert_eq!(result.output_artifacts[0].payload_base64, "AQID");
2489
2490 let ev: StreamEvent = serde_json::from_str(
2491 r#"{
2492 "voice_activity": [
2493 {"kind": "speech_start", "sample": 100, "probability": 0.8, "segment": null}
2494 ],
2495 "partial_text": null,
2496 "partial_text_snapshot": {"text": "hel", "language": "en"},
2497 "audio_output": null,
2498 "named_audio_outputs": [{"id": "chunk_0", "audio": {"sample_rate": 48000, "channels": 2, "sample_count": 320, "samples": []}, "meta": {}}],
2499 "speaker_turns": [],
2500 "word_timestamps": [],
2501 "output_artifacts": [],
2502 "is_final": true
2503 }"#,
2504 )
2505 .unwrap();
2506 assert_eq!(ev.voice_activity[0].kind, "speech_start");
2507 assert_eq!(ev.named_audio_outputs[0].id, "chunk_0");
2508 assert_eq!(ev.partial_text_snapshot.as_ref().unwrap().text, "hel");
2509 assert!(ev.is_final);
2510 }
2511
2512 #[test]
2513 fn model_inspection_deserialize() {
2514 let info: ModelInspection = serde_json::from_str(
2517 r#"{
2518 "metadata": {
2519 "family": "qwen3_asr",
2520 "variant": "q8_0",
2521 "description": "Qwen3 ASR",
2522 "config_candidates": ["config.json"],
2523 "weight_candidates": ["qwen3-asr-q8_0.gguf"]
2524 },
2525 "capabilities": {
2526 "supported_tasks": [{"task": "asr", "modes": ["offline", "streaming"]}],
2527 "languages": ["zh", "en"],
2528 "supports_speaker_reference": false,
2529 "supports_style_condition": false,
2530 "supports_timestamps": true
2531 },
2532 "discovered_weights": [
2533 {"id": "model", "path": "/models/qwen3-asr-q8_0.gguf"}
2534 ],
2535 "cli": {
2536 "request_options": [
2537 {"name": "language", "value_name": "CODE", "description": "语言", "required": false, "default_value": "auto"}
2538 ],
2539 "session_options": [],
2540 "load_options": []
2541 }
2542 }"#,
2543 )
2544 .unwrap();
2545 assert_eq!(info.metadata.family, "qwen3_asr");
2546 assert!(
2547 info.capabilities
2548 .supported_tasks
2549 .iter()
2550 .any(|t| t.task == "asr" && t.modes.contains(&"streaming".to_string()))
2551 );
2552 assert_eq!(info.discovered_weights[0].id, "model");
2553 assert_eq!(info.cli.request_options[0].name, "language");
2554 assert_eq!(
2555 info.cli.request_options[0].default_value.as_deref(),
2556 Some("auto")
2557 );
2558 }
2559}