hiyouga/LlamaFactory · error · ValueError

DeepSpeed config_file is required.

Error message

DeepSpeed config_file is required.

What it means

ValueError from DeepSpeedParams.__post_init__ (interface.py:69) requiring a non-empty config_file. The v1 DeepSpeed plugin deliberately does not accept inline parameters or auto-generated configs; the path to a DeepSpeed JSON config is mandatory at construction time.

Source

Thrown at src/llamafactory/v1/plugins/trainer_plugins/distributed/interface.py:69

    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):
    @staticmethod
    def shard_model(model: HFModel, dist_config: PluginConfig | FSDP2Params, **kwargs) -> HFModel:
        dist_config = DistributedPlugin.parse_params(dist_config, FSDP2Params)
        from .fsdp2 import FSDP2Engine

        return FSDP2Engine(asdict(dist_config), bf16=bool(kwargs.get("bf16"))).shard_model(model)

    @staticmethod
    def save_model(model, output_dir, processor) -> None:
        from .fsdp2 import save_model

View on GitHub (pinned to f28afaf635)

Solutions

  1. Provide a DeepSpeed JSON config path: DeepSpeedParams(config_file='ds_configs/zero2.json').
  2. If migrating from v0, copy the ds_config previously used (examples/deepspeed/ in the repo has reference configs).
  3. Verify the path exists and is readable before launch, since an invalid path fails later with a different error.

Example fix

# before
dist_config:
  name: deepspeed

# after
dist_config:
  name: deepspeed
  config_file: examples/deepspeed/ds_z2_config.json
Defensive patterns

Strategy: validation

Validate before calling

cfg = dist_cfg.get("config_file", "") if isinstance(dist_cfg, dict) else ""
if not cfg or not Path(cfg).is_file():
    raise SystemExit("deepspeed dist_config needs an existing config_file path")

Type guard

def is_valid_deepspeed_params(p) -> bool:
    return isinstance(p, DeepSpeedParams) and bool(p.config_file)

Prevention

When it happens

Trigger: Instantiating DeepSpeedParams() with no arguments, or passing dist_config: {name: deepspeed} without a config_file key; also when config_file is set to an empty string in YAML.

Common situations: Users migrating from v0/HuggingFace Trainer, where DeepSpeed can auto-derive a config from training args, expect the same here; or a YAML variable for the config path resolves to empty.

Related errors


AI-assisted analysis of hiyouga/LlamaFactory@f28afaf635 (2026-08-14). Data as JSON: /api/errors/18445f0c6f97e9dd. Report an issue: GitHub.