{"record":{"id":"79f74781a24933bd","repo":"microsoft/VibeVoice","slug":"unsupported-decoder-model-type-decoder-config-ge-79f747","errorCode":null,"errorMessage":"Unsupported decoder model type: {decoder_config.get('model_type', '')}","messagePattern":"Unsupported decoder model type: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"vibevoice/modular/configuration_vibevoice_streaming.py","lineNumber":63,"sourceCode":"\n        if acoustic_tokenizer_config is None:\n            self.acoustic_tokenizer_config = self.sub_configs[\"acoustic_tokenizer_config\"]()\n        elif isinstance(acoustic_tokenizer_config, dict):\n            acoustic_tokenizer_config[\"model_type\"] = \"vibevoice_acoustic_tokenizer\"\n            self.acoustic_tokenizer_config = self.sub_configs[\"acoustic_tokenizer_config\"](**acoustic_tokenizer_config)\n        elif isinstance(acoustic_tokenizer_config, VibeVoiceAcousticTokenizerConfig):\n            # If an instance of the config class is provided\n            self.acoustic_tokenizer_config = acoustic_tokenizer_config\n\n        if decoder_config is None:\n            self.decoder_config = self.sub_configs[\"decoder_config\"]()\n        elif isinstance(decoder_config, dict):\n            # If a dictionary is provided, instantiate the config class with it\n            # self.decoder_config = self.sub_configs[\"decoder_config\"](**decoder_config)\n            if decoder_config.get(\"model_type\", '') == \"qwen2\":\n                self.decoder_config = Qwen2Config(**decoder_config)\n            else:\n                raise ValueError(f\"Unsupported decoder model type: {decoder_config.get('model_type', '')}\")\n        elif isinstance(decoder_config, (Qwen2Config,)):\n            # If an instance of the config class is provided\n            self.decoder_config = decoder_config\n\n        if diffusion_head_config is None:\n            self.diffusion_head_config = self.sub_configs[\"diffusion_head_config\"]()\n        elif isinstance(diffusion_head_config, dict):\n            diffusion_head_config[\"model_type\"] = \"vibevoice_diffusion_head\"\n            self.diffusion_head_config = self.sub_configs[\"diffusion_head_config\"](**diffusion_head_config)\n        elif isinstance(diffusion_head_config, VibeVoiceDiffusionHeadConfig):\n            # If an instance of the config class is provided\n            self.diffusion_head_config = diffusion_head_config\n\n        # other parameters\n        self.acoustic_vae_dim = getattr(self.acoustic_tokenizer_config, 'vae_dim', 64)\n        # The decoder of the model is divided into two components. The lower Transformer layers are only used for encoding text, while the upper Transformer layers are used for encoding text and generating speech. `tts_backbone_num_hidden_layers` indicates the number of upper layers used for TTS.\n        self.tts_backbone_num_hidden_layers = tts_backbone_num_hidden_layers\n","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/microsoft/VibeVoice/blob/94da20d98b2fa7688e9cbfaf7692ddb4954f7600/vibevoice/modular/configuration_vibevoice_streaming.py#L45-L81","documentation":"The streaming variant (VibeVoiceStreamingConfig, configuration_vibevoice_streaming.py:63) of the same decoder guard: a dict decoder_config must have model_type == 'qwen2' or construction fails. All three config classes intentionally restrict the decoder backbone to Qwen2, so this is a supported-architecture boundary, not a bug.","triggerScenarios":"Building VibeVoiceStreamingConfig(decoder_config={...}) without model_type='qwen2', or loading a streaming checkpoint whose config.json decoder block names another architecture.","commonSituations":"Porting the streaming config from the non-streaming one with edits; converter scripts that emit 'qwen2_5' or similar; user-supplied YAML/JSON config piped into the constructor.","solutions":["Set model_type='qwen2' in the decoder_config dict for the streaming model.","Validate incoming config dicts before constructing: assert cfg['decoder_config'].get('model_type') == 'qwen2'.","Diff a known-good streaming checkpoint's config.json against yours and align the decoder block.","Do not attempt to substitute decoder architectures — weights would not load anyway."],"exampleFix":"# before\nVibeVoiceStreamingConfig(decoder_config={\"model_type\": \"qwen3\", ...})\n\n# after\nVibeVoiceStreamingConfig(decoder_config={\"model_type\": \"qwen2\", ...})","handlingStrategy":"validation","validationCode":"if isinstance(decoder_config, dict):\n    decoder_config = {**decoder_config, \"model_type\": \"qwen2\"}  # force the only supported decoder\nVibeVoiceStreamingConfig(decoder_config=decoder_config)","typeGuard":"def is_valid_streaming_decoder(cfg: dict) -> bool:\n    return cfg.get(\"model_type\") == \"qwen2\"","tryCatchPattern":"try:\n    VibeVoiceStreamingConfig(decoder_config=decoder_config)\nexcept ValueError as e:\n    raise SystemExit(f\"Bad streaming config: {e}; decoder must be qwen2\") from e","preventionTips":["Use repo-shipped streaming configs unmodified","Normalize decoder model_type to 'qwen2' before construction","Add CI checks validating config schema for streaming checkpoints"],"tags":["configuration","streaming","decoder","qwen2","valueerror"],"backgroundTag":null,"analyzedSha":"94da20d98b2fa7688e9cbfaf7692ddb4954f7600","analyzedAt":"2026-08-15T04:12:07.418Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}