hiyouga/LlamaFactory · error · ValueError
ep_size must be positive, got {self.ep_size}.
Error message
ep_size must be positive, got {self.ep_size}. What it means
ValueError from FSDP2Params.__post_init__ (interface.py:59) validating that ep_size is at least 1. It fires at config-parse time, before any distributed setup, when a non-positive expert-parallel size is supplied. This is a strict guard against typo'd or computed-to-zero ep_size values.
Source
Thrown at src/llamafactory/v1/plugins/trainer_plugins/distributed/interface.py:59
dcp_path: str | None = None
@dataclass
class FSDPTurboParams:
name: Literal["fsdpturbo"] = "fsdpturbo"
reshard_after_forward: bool = True
offload_params: bool = False
pin_memory: bool = True
dcp_path: str | None = None
ep_size: int = 1
ep_dispatcher: str = "eager"
fsdp_ignored_modules: list[str] = field(default_factory=list)
hook_modules: list[str] = field(default_factory=list)
fsdp_implementation: str = "native"
def __post_init__(self) -> None:
if self.ep_size < 1:
raise ValueError(f"ep_size must be positive, got {self.ep_size}.")
@dataclass
class DeepSpeedParams:
name: Literal["deepspeed"] = "deepspeed"
config_file: str = ""
def __post_init__(self) -> None:
if not self.config_file:
raise ValueError("DeepSpeed config_file is required.")
class DistributedPlugin(BasePlugin):
"""Plugin family for distributed training backends."""
@DistributedPlugin("fsdp2").register()
class FSDP2Distributed(BaseDistributed):View on GitHub (pinned to f28afaf635)
Solutions
- Set ep_size to 1 (no expert parallelism) or a positive divisor of world size.
- If the value is computed, validate it before constructing FSDP2Params and fall back to 1 when the computation yields <= 0.
- Re-check the YAML/JSON config for a mistyped ep_size key value.
Example fix
# before FSDP2Params(ep_size=world_size // 16) # 0 when world_size < 16 # after FSDP2Params(ep_size=max(1, world_size // 16))
Defensive patterns
Strategy: validation
Validate before calling
assert isinstance(ep_size, int) and ep_size >= 1, f"ep_size must be >= 1, got {ep_size}" Type guard
def is_valid_ep_size(v) -> bool:
return isinstance(v, int) and not isinstance(v, bool) and v >= 1 Prevention
- Validate computed config values before building params dataclasses.
- Use max(1, computed) for derived sizes.
When it happens
Trigger: Passing ep_size: 0 or a negative value in the dist_config mapping for the fsdp2/fsdpturbo plugin; or computing ep_size programmatically (e.g. world_size // num_nodes) and passing 0 when the division underflows.
Common situations: YAML typo (ep_size: 0), templated configs where a variable evaluates to 0, or scripts that derive ep_size from environment variables defaulting to 0.
Related errors
- Total Megatron Bridge parallel size ({parallel_size}) exceed
- Total Megatron Bridge parallel size ({parallel_size}) must d
- Megatron Bridge cannot be used together with MCA or HyperPar
- DeepSpeed config_file is required.
- Unknown mixing strategy: {data_args.mix_strategy}.
AI-assisted analysis of hiyouga/LlamaFactory@f28afaf635 (2026-08-14).
Data as JSON: /api/errors/72fddbabcd5b1067.
Report an issue: GitHub.