sgl-project/sglang · error · ValueError

MLX float64 arrays cannot be exported to a Torch MPS tensor;

Error message

MLX float64 arrays cannot be exported to a Torch MPS tensor; use float32/bfloat16 or request device='cpu'

What it means

Metal (MPS) does not support float64, so exporting an MLX float64 array to an MPS torch tensor is rejected with guidance to downcast or target CPU. The check is in _prepare_mlx_export, before any evaluation boundary.

Source

Thrown at python/sglang/srt/utils/tensor_bridge.py:266

def _prepare_mlx_export(
    array: mx.array,
    target_device: torch.device,
    mx: Any,
) -> mx.array:
    """Prepare one lazy MLX result for the requested Torch target.

    This intentionally does not evaluate the result.  Callers which export
    several results should prepare every result first and then issue one
    shared ``mx.eval`` boundary.
    """
    if target_device.type not in {"cpu", "mps"}:
        raise ValueError(
            f"The MLX tensor bridge supports CPU and MPS targets, got {target_device}"
        )

    if target_device.type == "mps" and array.dtype == mx.float64:
        raise ValueError(
            "MLX float64 arrays cannot be exported to a Torch MPS tensor; "
            "use float32/bfloat16 or request device='cpu'"
        )

    return array


def _has_negative_stride(array: mx.array) -> bool:
    """Return whether an evaluated MLX array has a DLPack-incompatible view."""
    # PyTorch's DLPack importer aborts the process for negative strides.  MLX
    # exposes the evaluated layout through the buffer protocol, so inspect it
    # before handing the capsule to PyTorch.
    with memoryview(array) as view:
        return any(stride < 0 for stride in (view.strides or ()))


def _export_evaluated_mlx(
    array: mx.array,

View on GitHub (pinned to 0132848349)

Solutions

  1. Cast the MLX array to float32/bfloat16 before export: arr.astype(mx.float32)
  2. Export with device='cpu' to keep float64 on CPU

Example fix

# before
t = mlx_to_torch(arr, device='mps')  # arr is float64
# after
t = mlx_to_torch(arr.astype(mx.float32), device='mps')
# or: t = mlx_to_torch(arr, device='cpu')
Defensive patterns

Strategy: type-guard

Validate before calling

if target == "mps" and arr.dtype == mx.float64:
    arr = arr.astype(mx.float32)  # or target cpu

Type guard

def exportable(arr, target: str) -> bool:
    return not (target == "mps" and arr.dtype == mx.float64)

Prevention

When it happens

Trigger: An MLX op producing float64 (e.g. from a CPU float64 input) exported with target device mps.

Common situations: Numeric/spectral workloads keeping float64 precision on the CPU stream, then trying to land the result back on Metal.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/27fc66b21c1c9760. Report an issue: GitHub.