{"record":{"id":"b8be8e52ae5aca87","repo":"huggingface/transformers","slug":"can-only-set-a-dictionary-as-tp-plan","errorCode":null,"errorMessage":"Can only set a dictionary as `tp_plan`","messagePattern":"Can only set a dictionary as `tp_plan`","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/transformers/distributed/mixin.py","lineNumber":115,"sourceCode":"                )\n            return self._ep_plan\n        return self._tp_plan\n\n    @property\n    def fsdp_plan(self) -> dict[str, str]:\n        return self._fsdp_plan\n\n    @property\n    def pp_plan(self) -> dict[str, tuple[str, str]]:\n        return self._pp_plan\n\n    @tp_plan.setter\n    def tp_plan(self, plan: dict[str, str] | None):\n        if plan is None:\n            self._tp_plan = {}\n            return\n        if not isinstance(plan, dict):\n            raise ValueError(\"Can only set a dictionary as `tp_plan`\")\n\n        for layer_pattern, parallel_style in plan.items():\n            if parallel_style not in ALL_PARALLEL_STYLES:\n                raise ValueError(\n                    f\"Unsupported tensor parallel style '{parallel_style}' for layer '{layer_pattern}'. \"\n                    f\"Supported styles are {list(ALL_PARALLEL_STYLES.keys())}\"\n                )\n\n        model_param_names = [name for name, _ in self.named_parameters()]\n        for layer_pattern in plan.keys():\n            regex_pattern = layer_pattern.replace(\"*\", r\"\\d+\")\n            pattern_matched = False\n            for param_name in model_param_names:\n                if re.match(regex_pattern, param_name):\n                    pattern_matched = True\n                    break\n            if not pattern_matched:\n                warnings.warn(","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/distributed/mixin.py#L97-L133","documentation":"The tp_plan setter on distributed model mixins only accepts a dict mapping module-name patterns (with '*' wildcards for repeated layers) to parallel styles, or None to clear the plan. Passing a string, list, or any other object raises immediately; each value is subsequently validated against ALL_PARALLEL_STYLES as well.","triggerScenarios":"Assigning model.tp_plan = 'colwise' (string) or a list of patterns instead of a dict; deserializing a plan from YAML/JSON that parsed into a list; passing a plan built by string concatenation instead of a literal dict.","commonSituations":"Config-driven setups loading tp plans from files whose schema drifted; users assuming tp_plan takes a single style string applied globally; copy-paste between APIs with different plan formats.","solutions":["Pass a dict: model.tp_plan = {'layers.*': 'colwise'} with keys as module patterns and values from ALL_PARALLEL_STYLES.","Pass None to clear the plan instead of an empty string/list.","Validate externally loaded plans: isinstance(plan, dict) and all values in the supported style set before assigning."],"exampleFix":"# before\nmodel.tp_plan = \"colwise\"  # raises ValueError\n\n# after\nmodel.tp_plan = {\"model.layers.*\": \"colwise\", \"lm_head\": \"rowwise\"}","handlingStrategy":"type-guard","validationCode":"if plan is not None and not isinstance(plan, dict):\n    raise TypeError(f\"tp_plan must be a dict, got {type(plan).__name__}\")","typeGuard":"def is_valid_tp_plan(plan) -> bool:\n    from transformers.distributed import ALL_PARALLEL_STYLES\n    return plan is None or (\n        isinstance(plan, dict)\n        and all(isinstance(k, str) for k in plan)\n        and all(v in ALL_PARALLEL_STYLES for v in plan.values())\n    )","tryCatchPattern":"try:\n    model.tp_plan = plan\nexcept ValueError as e:\n    if \"dictionary\" in str(e) or \"Unsupported tensor parallel style\" in str(e):\n        raise TypeError(f\"invalid tp_plan {plan!r}: {e}\") from e\n    raise","preventionTips":["Always pass tp_plan as a dict literal keyed by module patterns.","Schema-validate config-loaded plans (dict with values in ALL_PARALLEL_STYLES).","Use None to clear a plan rather than an empty string or list."],"tags":["distributed","tensor-parallelism","type-validation","api-misuse"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}