huggingface/transformers · error · ValueError
Can only set a dictionary as `tp_plan`
Error message
Can only set a dictionary as `tp_plan`
What it means
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.
Source
Thrown at src/transformers/distributed/mixin.py:115
)
return self._ep_plan
return self._tp_plan
@property
def fsdp_plan(self) -> dict[str, str]:
return self._fsdp_plan
@property
def pp_plan(self) -> dict[str, tuple[str, str]]:
return self._pp_plan
@tp_plan.setter
def tp_plan(self, plan: dict[str, str] | None):
if plan is None:
self._tp_plan = {}
return
if not isinstance(plan, dict):
raise ValueError("Can only set a dictionary as `tp_plan`")
for layer_pattern, parallel_style in plan.items():
if parallel_style not in ALL_PARALLEL_STYLES:
raise ValueError(
f"Unsupported tensor parallel style '{parallel_style}' for layer '{layer_pattern}'. "
f"Supported styles are {list(ALL_PARALLEL_STYLES.keys())}"
)
model_param_names = [name for name, _ in self.named_parameters()]
for layer_pattern in plan.keys():
regex_pattern = layer_pattern.replace("*", r"\d+")
pattern_matched = False
for param_name in model_param_names:
if re.match(regex_pattern, param_name):
pattern_matched = True
break
if not pattern_matched:
warnings.warn(View on GitHub (pinned to a597f97485)
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.
Example fix
# before
model.tp_plan = "colwise" # raises ValueError
# after
model.tp_plan = {"model.layers.*": "colwise", "lm_head": "rowwise"} Defensive patterns
Strategy: type-guard
Validate before calling
if plan is not None and not isinstance(plan, dict):
raise TypeError(f"tp_plan must be a dict, got {type(plan).__name__}") Type guard
def is_valid_tp_plan(plan) -> bool:
from transformers.distributed import ALL_PARALLEL_STYLES
return plan is None or (
isinstance(plan, dict)
and all(isinstance(k, str) for k in plan)
and all(v in ALL_PARALLEL_STYLES for v in plan.values())
) Try / catch
try:
model.tp_plan = plan
except ValueError as e:
if "dictionary" in str(e) or "Unsupported tensor parallel style" in str(e):
raise TypeError(f"invalid tp_plan {plan!r}: {e}") from e
raise Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- FSDP+TP is not supported yet. Use DistributedConfig(fsdp_siz
- Expert parallelism was requested (`enable_expert_parallel=Tr
- Cannot assign to field {name}, you should create a new insta
- Framework '{return_tensors}' not recognized!
- return_tensors should be `'pt'` or `None`
AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14).
Data as JSON: /api/errors/b8be8e52ae5aca87.
Report an issue: GitHub.