Skip to content

PyTorch backend: crash on Apple MPS with float64 targets — device move precedes the float64->float32 guard #68

Description

@phas02

Environment: tabfm 1.0.1 (d8678b6), PyTorch backend, torch 2.13.0, Python 3.13, macOS on Apple Silicon (device="mps").

Repro

import numpy as np
from tabfm import TabFMRegressor, tabfm_v1_0_0_pytorch

model = tabfm_v1_0_0_pytorch.load("regression", device="mps")
rng = np.random.default_rng(0)
X = rng.random((100, 5), dtype=np.float32)
y = rng.random(100)          # float64 — numpy's default float dtype
reg = TabFMRegressor(model=model)
reg.fit(X[:80], y[:80])
reg.predict(X[80:])
# TypeError: Cannot convert a MPS Tensor to float64 dtype as the MPS framework
# doesn't support float64. Please use float32 instead.

Cause_predict_step_pytorch in src/classifier_and_regressor.py (~L1801):

y_t = torch.from_numpy(y_batch).to(device)   # raises on MPS when y_batch is float64
if y_t.dtype == torch.float64:
    y_t = y_t.to(torch.float32)              # guard never reached

The float64→float32 guard sits after the .to(device), but MPS rejects float64 tensors at transfer time — so any float64 y (numpy's default) crashes before the guard runs. CUDA/CPU are unaffected, which is presumably why it hasn't surfaced.

Suggested fix — convert before moving:

y_t = torch.from_numpy(y_batch)
if y_t.dtype == torch.float64:
    y_t = y_t.to(torch.float32)
y_t = y_t.to(device)

Notes

  • Workaround: pass y.astype(np.float32) to fit().
  • With that workaround, both TabFMClassifier and TabFMRegressor run end-to-end on MPS with the default bfloat16 weights — this guard ordering appears to be the only blocker for Apple Silicon.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions