| 143 | } |
| 144 | |
| 145 | int64_t require_acoustic_vae_dim(const engine::io::json::Value & root) { |
| 146 | // VibeVoice-7B's config.json spells this key "acostic_vae_dim". |
| 147 | for (const char * key : {"acoustic_vae_dim", "acostic_vae_dim"}) { |
| 148 | if (const auto * value = root.find(key); value != nullptr) { |
| 149 | return value->as_i64(); |
| 150 | } |
| 151 | } |
| 152 | throw std::runtime_error("VibeVoice config is missing acoustic_vae_dim"); |
| 153 | } |
| 154 | |
| 155 | VibeVoiceConfig parse_config(const assets::ResourceBundle & resources) { |
| 156 | const auto root = resources.parse_json("config"); |
| 157 | VibeVoiceConfig config; |
| 158 | config.model_type = json::optional_string(root, "model_type", ""); |
| 159 | if (config.model_type != "vibevoice") { |
| 160 | throw std::runtime_error("VibeVoice config model_type mismatch"); |
| 161 | } |
| 162 | config.torch_dtype = json::optional_string(root, "torch_dtype", config.torch_dtype); |
| 163 | config.acoustic_vae_dim = require_acoustic_vae_dim(root); |
| 164 | config.semantic_vae_dim = json::require_i64(root, "semantic_vae_dim"); |
| 165 | config.acoustic_tokenizer = parse_tokenizer_config(root.require("acoustic_tokenizer_config"), "acoustic tokenizer"); |
| 166 | config.semantic_tokenizer = parse_tokenizer_config(root.require("semantic_tokenizer_config"), "semantic tokenizer"); |
| 167 | config.decoder = parse_decoder_config(root.require("decoder_config")); |
| 168 | // VibeVoice-7B carries tie_word_embeddings at the top level, unlike the 1.5B decoder config. |
| 169 | config.decoder.tie_word_embeddings = |
| 170 | json::optional_bool(root, "tie_word_embeddings", config.decoder.tie_word_embeddings); |
| 171 | config.diffusion_head = parse_diffusion_head_config(root.require("diffusion_head_config")); |
| 172 | engine::io::require_positive(config.acoustic_vae_dim, "acoustic_vae_dim"); |
| 173 | engine::io::require_positive(config.semantic_vae_dim, "semantic_vae_dim"); |
| 174 | if (config.acoustic_vae_dim != config.acoustic_tokenizer.vae_dim) { |
| 175 | throw std::runtime_error("VibeVoice acoustic_vae_dim does not match acoustic tokenizer vae_dim"); |
| 176 | } |
| 177 | if (config.semantic_vae_dim != config.semantic_tokenizer.vae_dim) { |
no test coverage detected