Skip to content

Add shared cuda→mps→cpu device-selection helper (#166) - #254

Open
MarcBarnaba wants to merge 2 commits into
lightningpixel:devfrom
MarcBarnaba:macos-mps-support
Open

Add shared cuda→mps→cpu device-selection helper (#166)#254
MarcBarnaba wants to merge 2 commits into
lightningpixel:devfrom
MarcBarnaba:macos-mps-support

Conversation

@MarcBarnaba

Copy link
Copy Markdown

Part of #166 (FEATURE 5 — macOS support for all models).

BaseGenerator subclasses currently hardcode torch.cuda.is_available(),
so model extensions only run on Windows/Linux with an NVIDIA GPU. This adds
two small helpers to api/services/generators/base.py:

  • select_device() — picks cudamps (Apple Silicon) → cpu.
  • select_dtype(device)float16 on CUDA, float32 on MPS/CPU (MPS has
    incomplete fp16 kernel coverage for attention/layer-norm/interpolation).

BaseGenerator.unload() now also releases MPS memory via
torch.mps.empty_cache() (it already did this for CUDA).

Extensions import these from services.generators.base the same way they
already import smooth_progress/GenerationCancelled, so device logic
lives in one place instead of being duplicated per extension, per the
ticket's implementation notes.

Companion extension PR: lightningpixel/modly-triposg-extension uses
these helpers — see that PR for the per-model changes.

Status of the other three models in the ticket, for visibility:

  • Hunyuan3D 2 Mini / Mini Turbo already have working MPS support merged on
    main (PR feat(update): add update available modal with version check  #11 on modly-hunyuan3d-mini-extension, and an equivalent commit
    on modly-hunyuan3d-mini-turbo-extension) — no changes needed there.
  • Trellis2 GGUF depends on spconv for its sparse convolutions, which has
    no CPU or Metal/MPS backend at all (only an unsupported Linux-only debug
    CPU build) — full MPS support isn't achievable without replacing that
    dependency, so it's out of scope for this pass.

No frontend/store/API surface changes. Windows/CUDA behavior is
unchanged (torch.cuda.is_available() is still checked first everywhere).

BaseGenerator subclasses currently hardcode torch.cuda.is_available(),
so the four bundled models only run on Windows/Linux with an NVIDIA
GPU. Add select_device()/select_dtype() to base.py so extensions can
detect Apple Silicon (MPS) and fall back to CPU in one shared place
instead of duplicating the check per extension. unload() now also
releases MPS memory via torch.mps.empty_cache().

Windows/CUDA behavior is unchanged.

Ref: lightningpixel#166
torch.backends.mps hard-crashes with NotImplementedError on ops that
have no Metal kernel yet (e.g. 3D pooling), instead of transparently
falling back to CPU like on other backends. The opt-in env var that
enables the fallback must be set before the process's first `import
torch` — setting it inside select_device() is too late for extensions
that import torch before calling it (confirmed by testing TripoSG end
to end). Set it once, for every extension subprocess, in
ExtensionProcess._build_env() on macOS.

Ref: lightningpixel#166
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant