Skip to content

Add AMD ROCm support (Linux + Windows) - #267

Open
lionrayonnant wants to merge 1 commit into
lightningpixel:mainfrom
lionrayonnant:feat/amd-rocm-support
Open

Add AMD ROCm support (Linux + Windows)#267
lionrayonnant wants to merge 1 commit into
lightningpixel:mainfrom
lionrayonnant:feat/amd-rocm-support

Conversation

@lionrayonnant

@lionrayonnant lionrayonnant commented Aug 17, 2026

Copy link
Copy Markdown

Summary

Adds AMD GPU support alongside the existing NVIDIA/MPS/CPU paths. Modly never
installs PyTorch itself — each extension's setup.py does, from an index it
hardcodes — so this is really two pieces: detecting AMD hardware, and
redirecting extension installs to the right ROCm wheels.

  • electron/main/gpu-detect.ts (new) — detects AMD GPUs via KFD topology
    on Linux and Win32_VideoController on Windows, resolves the ROCm pip index
    and requirements per platform. NVIDIA keeps detection priority, so nothing
    changes for existing CUDA/MPS users. Escape hatches (MODLY_TORCH_FLAVOR,
    MODLY_ROCM_GFX, MODLY_ROCM_INDEX, MODLY_ROCM_TORCH_SPEC) are available
    for machines the auto-detection gets wrong, or to roll back to an older
    ROCm/torch pairing.
  • electron/main/setup-launcher.ts (extracted from ipc-handlers.ts) —
    adds a compatibility shim that rewrites an extension's pip torch install to
    ROCm wheels. This is needed because most extension setup.py scripts
    predate AMD support and hardcode a CUDA index; the official
    hunyuan3d-mini extension already accepts a torch_flavor argument, but
    Modly never sent it, and other extensions don't know the argument exists
    at all.
  • api/routers/extensions.py — the FastAPI-side GPU detection no longer
    mistakes a ROCm build's device capability for a CUDA one (both answer
    torch.cuda.get_device_capability() the same way under PyTorch's HIP
    build), and reads the AMD compute target from KFD topology directly (no
    torch dependency in this process).
  • electron/main/copy-runtime.ts (new) — fixes an unrelated but blocking
    bug found while verifying this end-to-end on Linux: fs.cp rewrites the
    bundled Python runtime's relative symlinks into absolute paths pointing at
    the source tree. On AppImage, the source is the ephemeral
    /tmp/.mount_Modly-XXXXXX/ mount, so the "stable" runtime copy silently
    wasn't stable — every extension venv recorded that path and died on the
    next launch. verbatimSymlinks: true keeps the links relative.
  • docs/running-on-amd-rocm.md, arch/decisions/AMD-ROCM-SUPPORT.md
    usage, the verified configuration, escape hatches, and known limitations.

Verified on real hardware

Radeon RX 9060 XT (Navi 44, gfx1200), Linux:

  • Detection reports accelerator=rocm gfx=gfx1200 correctly.
  • hunyuan3d-mini extension setup installs torch 2.13.0+rocm7.2 and loads
    on the GPU (torch.cuda.is_available() is True, gcnArchName is
    gfx1200).
  • A full image-to-3D generation through the normal ExtensionProcess
    subprocess path completes successfully (18s load, 221s generation, valid
    GLB output).
  • rocBLAS (fp16 matmul) and MIOpen (conv2d) kernels both execute correctly.
  • 14 GB of the card's 16 GB allocates and reads back cleanly —
    ROCm/ROCm#6295, which reports
    this exact card capped near 8GB, did not reproduce on this stack.

Windows is implemented (wheel URLs and cp311 availability were checked
against the AMD and PyTorch package indexes) but not run end-to-end — no
Windows/AMD machine was available for this PR.

Extensions tried beyond hunyuan3d-mini

Two other official extensions were tried while verifying this, both without success:

  • modly-trellis2-extension — not attempted. Its build_vendor.py ships
    precompiled CUDA binaries (nvdiffrast, cumesh, spconv) in vendor/,
    built against nvcc. Independent of anything in this PR, those .so files
    cannot run under ROCm/HIP — there's no ROCm build shipped, and nothing here
    can redirect a vendored binary the way it redirects a pip install.
  • modly-triposplat-extension — attempted and failed. It's pure Python +
    PyTorch (no compiled extensions), so the ROCm redirect in this PR applies
    cleanly and the diffusion stage runs correctly on the GPU. Generation
    consistently fails afterwards, during mesh reconstruction
    (splat_mesh.py's Gaussian-to-mesh step): comparing CPU vs GPU on the same
    captured real output showed the accumulated density values diverge
    significantly (~13x) between devices, though I could not isolate this to
    a single faulty op — _inverse_covariance and index_add_ each checked
    out correctly in isolation with the same data. This looks like a
    ROCm-specific numerical issue somewhere in that extension's reconstruction
    pipeline (torch 2.13.0+rocm7.2), not something this PR's detection/redirect
    layer can fix. Flagging it here rather than silently leaving it unverified.

Extensions with vendored CUDA-compiled native code (e.g. nvdiffrast,
spconv binaries built against nvcc) cannot work under ROCm regardless of
this change — there's no ROCm equivalent shipped. Pure-PyTorch extensions
are the ones this PR actually helps; hunyuan3d-mini is confirmed working
end-to-end, triposplat is not (see above).

Test plan

  • npm run lint
  • ./node_modules/.bin/tsc --noEmit -p tsconfig.node.json (no new errors)
  • npm test (23 Python + 77 Node tests, including 25 new tests for the
    detection/redirect logic added here)
  • End-to-end on real AMD hardware (see above)

Adds AMD GPU detection and a PyTorch/ROCm redirect for extension setup, on
top of the existing NVIDIA/MPS/CPU paths.

- electron/main/gpu-detect.ts: detects AMD GPUs (KFD topology on Linux,
  Win32_VideoController on Windows), resolves the ROCm pip index and
  requirements. NVIDIA keeps detection priority; explicit overrides
  (MODLY_TORCH_FLAVOR, MODLY_ROCM_GFX, MODLY_ROCM_INDEX,
  MODLY_ROCM_TORCH_SPEC) are available for machines the auto-detection
  gets wrong.
- electron/main/setup-launcher.ts: extracted from ipc-handlers.ts, adds a
  compatibility shim that redirects an extension's pip torch install to
  ROCm wheels — needed because most third-party extension setup.py
  scripts predate AMD support and hardcode a CUDA index.
- api/routers/extensions.py: the FastAPI-side GPU detection no longer
  mistakes a ROCm build's device capability for CUDA compute capability
  (both answer torch.cuda.get_device_capability the same way), and reads
  the AMD compute target from the same KFD topology as the Electron side.
- electron/main/copy-runtime.ts: fixes an unrelated but blocking AppImage
  bug found while verifying this end-to-end — fs.cp rewrote the bundled
  Python runtime's relative symlinks into absolute paths pointing at the
  ephemeral AppImage mount, so every extension venv died on the next
  launch. verbatimSymlinks keeps them relative.
- docs/running-on-amd-rocm.md, arch/decisions/AMD-ROCM-SUPPORT.md: usage,
  verified configuration, and known limitations.

Verified end-to-end on a Radeon RX 9060 XT (gfx1200): detection, ROCm
wheel install (torch 2.13.0+rocm7.2), and a full image-to-3D generation
through hunyuan3d-mini all complete successfully on the GPU.
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