{"record":{"id":"18445f0c6f97e9dd","repo":"hiyouga/LlamaFactory","slug":"deepspeed-config-file-is-required","errorCode":null,"errorMessage":"DeepSpeed config_file is required.","messagePattern":"DeepSpeed config_file is required\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/llamafactory/v1/plugins/trainer_plugins/distributed/interface.py","lineNumber":69,"sourceCode":"    ep_size: int = 1\n    ep_dispatcher: str = \"eager\"\n    fsdp_ignored_modules: list[str] = field(default_factory=list)\n    hook_modules: list[str] = field(default_factory=list)\n    fsdp_implementation: str = \"native\"\n\n    def __post_init__(self) -> None:\n        if self.ep_size < 1:\n            raise ValueError(f\"ep_size must be positive, got {self.ep_size}.\")\n\n\n@dataclass\nclass DeepSpeedParams:\n    name: Literal[\"deepspeed\"] = \"deepspeed\"\n    config_file: str = \"\"\n\n    def __post_init__(self) -> None:\n        if not self.config_file:\n            raise ValueError(\"DeepSpeed config_file is required.\")\n\n\nclass DistributedPlugin(BasePlugin):\n    \"\"\"Plugin family for distributed training backends.\"\"\"\n\n\n@DistributedPlugin(\"fsdp2\").register()\nclass FSDP2Distributed(BaseDistributed):\n    @staticmethod\n    def shard_model(model: HFModel, dist_config: PluginConfig | FSDP2Params, **kwargs) -> HFModel:\n        dist_config = DistributedPlugin.parse_params(dist_config, FSDP2Params)\n        from .fsdp2 import FSDP2Engine\n\n        return FSDP2Engine(asdict(dist_config), bf16=bool(kwargs.get(\"bf16\"))).shard_model(model)\n\n    @staticmethod\n    def save_model(model, output_dir, processor) -> None:\n        from .fsdp2 import save_model","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/hiyouga/LlamaFactory/blob/f28afaf6355af515454dfb16c97d728307c93897/src/llamafactory/v1/plugins/trainer_plugins/distributed/interface.py#L51-L87","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Provide a DeepSpeed JSON config path: DeepSpeedParams(config_file='ds_configs/zero2.json').","If migrating from v0, copy the ds_config previously used (examples/deepspeed/ in the repo has reference configs).","Verify the path exists and is readable before launch, since an invalid path fails later with a different error."],"exampleFix":"# before\ndist_config:\n  name: deepspeed\n\n# after\ndist_config:\n  name: deepspeed\n  config_file: examples/deepspeed/ds_z2_config.json","handlingStrategy":"validation","validationCode":"cfg = dist_cfg.get(\"config_file\", \"\") if isinstance(dist_cfg, dict) else \"\"\nif not cfg or not Path(cfg).is_file():\n    raise SystemExit(\"deepspeed dist_config needs an existing config_file path\")","typeGuard":"def is_valid_deepspeed_params(p) -> bool:\n    return isinstance(p, DeepSpeedParams) and bool(p.config_file)","tryCatchPattern":null,"preventionTips":["Treat config_file as required in config templates.","Resolve and stat() the path at config-load time, not at train start."],"tags":["config","deepspeed","distributed","validation"],"backgroundTag":null,"analyzedSha":"f28afaf6355af515454dfb16c97d728307c93897","analyzedAt":"2026-08-14T21:57:28.298Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}