hiyouga/LlamaFactory · error · ValueError
dim must be specified.
Error message
dim must be specified.
What it means
`DistributedInterface.get_device_mesh(dim)` requires an explicit `Dim` argument; passing `None` (or omitting it) raises this ValueError immediately, before the distributed check. The mesh is a per-dimension lookup (data dims vs model dims), so there is no meaningful default dimension.
Source
Thrown at src/llamafactory/v1/accelerator/interface.py:192
)
else:
self.model_device_mesh = None
self.data_device_mesh = None
self._initialized = True
logger.info_rank0(f"DistributedInterface initialized: {self}.")
def __str__(self) -> str:
return (
f"DistributedInterface(strategy={self.strategy}), is_distributed={self._is_distributed}, "
f"current_device={self.current_device}, rank={self._rank}, world_size={self._world_size}, "
f"model_device_mesh={self.model_device_mesh}, data_device_mesh={self.data_device_mesh}"
)
def get_device_mesh(self, dim: Dim | None = None) -> DeviceMesh | None:
"""Get device mesh for specified dimension."""
if dim is None:
raise ValueError("dim must be specified.")
elif not self._is_distributed:
return None
elif dim in self.strategy.data_mesh_dim_names:
return self.data_device_mesh[dim.value]
else:
return self.model_device_mesh[dim.value]
def get_group(self, dim: Dim | None = None) -> Optional[ProcessGroup]:
"""Get process group for specified dimension."""
if not self._is_distributed or dim is None:
return None
else:
return self.get_device_mesh(dim).get_group()
def get_rank(self, dim: Dim | None = None) -> int:
"""Get parallel rank for specified dimension."""
if not self._is_distributed:
return 0View on GitHub (pinned to f28afaf635)
Solutions
- Pass an explicit `Dim` member, e.g. `get_device_mesh(Dim.DP)` or `get_device_mesh(Dim.MP)`
- Guard optional dims at the call site: only call when the value is not None
- Check the `Dim` enum definition in the accelerator interface for the exact member names
Example fix
# before mesh = interface.get_device_mesh() # ValueError: dim must be specified. # after from llamafactory.v1.accelerator.interface import Dim mesh = interface.get_device_mesh(Dim.DP)
Defensive patterns
Strategy: type-guard
Validate before calling
from llamafactory.v1.accelerator.interface import Dim, DistributedInterface
def mesh_for(interface: DistributedInterface, dim: Dim | None):
if dim is None:
return None # caller decides; never call get_device_mesh(None)
return interface.get_device_mesh(dim) Type guard
from typing import TypeGuard
from llamafactory.v1.accelerator.interface import Dim
def is_dim(value: object) -> TypeGuard[Dim]:
return isinstance(value, Dim) Prevention
- Type optional dims as `Dim | None` and guard before the call
- Never copy the `dim: Dim | None = None` default into public wrappers
- Keep an enum reference next to mesh code so valid members are visible
When it happens
Trigger: Calling `interface.get_device_mesh()` with no arguments, or passing a variable that is `None` (e.g. an optional dim parameter threaded through from a config that was never set).
Common situations: Writing a custom plugin/trainer that mirrors a signature with `dim: Dim | None = None` and forwards the default; refactoring code that previously used a hardcoded dimension enum member.
Related errors
- world_size ({helper.get_world_size()}) must be divisible by
- mp_replicate_size * mp_shard_size must equal to world_size,
- world_size ({helper.get_world_size()}) must be divisible by
- dp_size * cp_size must equal to world_size, got {self.dp_siz
- Streaming dataset does not support index access.
AI-assisted analysis of hiyouga/LlamaFactory@f28afaf635 (2026-08-14).
Data as JSON: /api/errors/41f6ee51fbc98f36.
Report an issue: GitHub.