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 0

View on GitHub (pinned to f28afaf635)

Solutions

  1. Pass an explicit `Dim` member, e.g. `get_device_mesh(Dim.DP)` or `get_device_mesh(Dim.MP)`
  2. Guard optional dims at the call site: only call when the value is not None
  3. 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

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


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