Skip to main content

Run CUDA-hardcoded PyTorch repos on Apple Silicon (MPS) with zero source edits.

Project description

mpsify

PyPI Python License: MIT

Run CUDA-hardcoded PyTorch repos on Apple Silicon (MPS) — with zero source edits.

You inherit someone's training script. It's full of .cuda(), device='cuda', torch.cuda.amp, map_location='cuda'. PyTorch-MPS could run the actual math fine on your Mac — but the code dies before it gets the chance. mpsify patches torch at import time so all of that transparently retargets to MPS.

pip install mpsify

Usage

Point it at any script — no edits to their code:

python -m mpsify train.py --epochs 10 --lr 1e-3
# or, after install, the console script:
mpsify train.py --epochs 10 --lr 1e-3

Or drop one line at the top of your entry file:

import mpsify  # patches torch on import

The wrapper (python -m mpsify) is preferred: it sets PYTORCH_ENABLE_MPS_FALLBACK=1 before torch loads, which the import form can't always guarantee.

What it does

CUDA thing Retargeted to
torch.cuda.is_available() True
.cuda(), .to('cuda'), device='cuda' mps
torch.device('cuda') mps
torch.load(map_location='cuda') mps
DataLoader(pin_memory=True) pin_memory=False (no pinned memory on MPS)
torch.cuda.amp autocast / GradScaler no-op, fp32 (see knobs)
nn.DataParallel identity (single device)
nccl backend gloo

Ops with no Metal kernel fall back to CPU automatically. mpsify catches those fallbacks, warns once per op live, and prints a summary at exit — so you can see exactly which ops are your latency hot spots.

Libraries with no Metal backend at all (bitsandbytes, apex, deepspeed, flash_attn, triton) are detected and reported loudly instead of crashing cryptically.

Pre-flight check

See what mpsify will do to a script without running it:

python -m mpsify doctor train.py

Reports every CUDA call it will remap and any library it can't fix (flash-attention, bitsandbytes, ...). Exit code is non-zero if something is unshimmable — handy in CI.

Loading a CUDA-trained checkpoint

Weights are just numbers — a model trained on CUDA runs on MPS unchanged. The only snag is torch.load restoring tensors to their saved cuda device. mpsify.load handles that (and upcasts fp16 → fp32, since MPS half-precision has rough edges):

import mpsify
state = mpsify.load("model_trained_on_a100.pth")   # lands on MPS
model.load_state_dict(state)

Diagnosing slow ops

python -m mpsify --profile train.py

Runs a dispatch-level profiler that counts calls and times ops. This adds per-op overhead — use it for a diagnostic pass, not production.

Knobs

Env var Effect
MPSIFY_AMP=1 Re-enable AMP/autocast (default off = fp32, correct but slower). AMP on MPS is where correctness gets dicey.
MPSIFY_QUIET=1 Suppress live fallback warnings; keep the exit summary.

Tested on

Real pretrained models, output verified numerically identical to CPU (max abs diff ~1e-6) on macOS + torch 2.5.1:

  • torchvision resnet18, efficientnet_b0, vit_b_16
  • timm mobilenetv3_small_100
  • HuggingFace transformers — DistilBERT sentiment: .to('cuda'), forward, and pipeline(device=0) all run on MPS
  • A 3-step fine-tuning loop (loss decreases, params on mps:0)
  • Loading fp16/CUDA checkpoints via mpsify.load

Note: transformers 5.x refuses to torch.load a .bin checkpoint unless torch ≥ 2.6 (a CVE guard). Use models that ship safetensors (use_safetensors=True) — unrelated to mpsify.

Scope

Handles pure-PyTorch repos (torchvision / timm models — ResNet, EfficientNet, ViT, etc.). It does not translate custom .cu/Triton kernels or make CUDA-only libraries (flash-attention, DeepSpeed, apex) actually work — those are detected and reported, not fixed.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mpsify-0.2.0.tar.gz (12.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mpsify-0.2.0-py3-none-any.whl (10.7 kB view details)

Uploaded Python 3

File details

Details for the file mpsify-0.2.0.tar.gz.

File metadata

  • Download URL: mpsify-0.2.0.tar.gz
  • Upload date:
  • Size: 12.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for mpsify-0.2.0.tar.gz
Algorithm Hash digest
SHA256 7ee0d7c1088249073f2467f89035cabbaebc393298abff26f3d8e92ed73c4b73
MD5 13f5cd1564581e1966a9c96dde1d90b5
BLAKE2b-256 dbe14801f64f0203704a4fa50de7e2821be0faee6d2addff390dce034be69652

See more details on using hashes here.

File details

Details for the file mpsify-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: mpsify-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 10.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for mpsify-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0eac782accfbb8b26431315cd369e4f9f93e89b03b764d740e9615f8abaa0bda
MD5 f378f8b17137f661b6ff153639c55528
BLAKE2b-256 e640813c70e2f057deacba701b905c3cb4a4cf210bedcd224c954cb3d410e9d9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page