{"record":{"id":"ca879b6582ad9f71","repo":"huggingface/transformers","slug":"calling-get-mtp-config-on-a-config-without-num","errorCode":null,"errorMessage":"Calling `get_mtp_config` on a config without `num_mtp_layers`","messagePattern":"Calling `get_mtp_config` on a config without `num_mtp_layers`","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/transformers/configuration_utils.py","lineNumber":1391,"sourceCode":"                    value = getattr(config_to_return, key)\n                    delattr(config_to_return, key)\n                    setattr(config_to_return, new_key, value)\n\n        return config_to_return\n\n    def get_mtp_config(self) -> \"PreTrainedConfig\":\n        \"\"\"\n        Returns the mtp text config to be used to create the MTP model. Since the MTP layers are created by instantiating\n        the same classes as the main model, we need to overwrite index-specific properties of the config such as `layer_types`\n        or `mtp_layer_types` to create the correct mtp layers and avoid indexing issues in the layers (because MTP layers restart\n        the indexing of layers at 0).\n        \"\"\"\n        # Start from the text config\n        text_config = copy.deepcopy(self.get_text_config(decoder=True))\n        num_mtp_layers = getattr(text_config, \"num_mtp_layers\", None)\n        # In this case, raise\n        if num_mtp_layers is None:\n            raise ValueError(\"Calling `get_mtp_config` on a config without `num_mtp_layers`\")\n\n        layer_types = getattr(text_config, \"layer_types\", None)\n        mtp_layer_types = getattr(text_config, \"mtp_layer_types\", None)\n        mlp_layer_types = getattr(text_config, \"mlp_layer_types\", None)\n        mtp_mlp_layer_types = getattr(text_config, \"mtp_mlp_layer_types\", None)\n\n        # Replace the index-based fields so that we can call `XXXDecoderLayer(config, layer_idx)` with the mtp config, and create\n        # the correct layers\n        if layer_types is not None:\n            if mtp_layer_types is None:\n                raise ValueError(\n                    \"Calling `get_mtp_config` on a config containing `layer_types` without `mtp_layer_types` is ambiguous\"\n                )\n            text_config.layer_types = mtp_layer_types\n        if mlp_layer_types is not None:\n            if mtp_mlp_layer_types is None:\n                raise ValueError(\n                    \"Calling `get_mtp_config` on a config containing `mlp_layer_types` without `mtp_mlp_layer_types` is ambiguous\"","sourceCodeStart":1373,"sourceCodeEnd":1409,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/configuration_utils.py#L1373-L1409","documentation":"ValueError from PreTrainedConfig.get_mtp_config: it deep-copies the decoder text config and builds the MTP (multi-token prediction) config, which requires num_mtp_layers to be defined. If the text config has no num_mtp_layers attribute (getattr returns None), MTP layers were never configured and building an MTP model is meaningless.","triggerScenarios":"Calling config.get_mtp_config() (directly or via MTP model construction) on a model whose config lacks num_mtp_layers, e.g. a checkpoint not trained with MTP (most standard LLMs).","commonSituations":"Generic code paths that unconditionally build MTP heads for models like DeepSeek-MTP/GLM-style architectures; loading a non-MTP checkpoint into MTP-aware code.","solutions":["Guard the call: only invoke get_mtp_config() when getattr(config, 'num_mtp_layers', None) is not None.","If MTP is intended, set num_mtp_layers (and the corresponding mtp layer-type fields) on the config.","Use the non-MTP model class for checkpoints without MTP weights."],"exampleFix":"// before\nmtp_cfg = config.get_mtp_config()  # ValueError on non-MTP checkpoint\n\n// after\nmtp_cfg = config.get_mtp_config() if getattr(config, \"num_mtp_layers\", None) else None","handlingStrategy":"type-guard","validationCode":"if getattr(config.get_text_config(decoder=True), \"num_mtp_layers\", None) is None:\n    skip_mtp = True  # do not call get_mtp_config / build MTP model","typeGuard":"def has_mtp_layers(config) -> bool:\n    return getattr(config.get_text_config(decoder=True), \"num_mtp_layers\", None) is not None","tryCatchPattern":"try:\n    mtp_config = config.get_mtp_config()\nexcept ValueError as e:\n    if \"without `num_mtp_layers`\" in str(e):\n        mtp_config = None  # checkpoint has no MTP","preventionTips":["Treat MTP as opt-in: branch on num_mtp_layers before constructing MTP modules.","Validate configs with a schema check at load time for MTP-capable pipelines."],"tags":["config","mtp","architecture"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}