⏱️ Lectura: 12 min

Meta and AMD just solved one of the most expensive problems in large-scale language model training: what to do when a node goes down in the middle of a job that has been running for days. The answer is called PyTorch Monarch, and as of July 6, 2026, it also runs on AMD Instinct GPUs with ROCm, not just on NVIDIA hardware with CUDA.

📑 En este artículo
  1. TL;DR
  2. Introduction
  3. What Happened
  4. Background and Context
  5. Technical Details and Performance
  6. Getting Started
    1. Linux with ROCm (Supported Path)
    2. macOS (Without a Real AMD GPU)
    3. Windows
  7. Impact and Analysis
  8. What’s Next
  9. Frequently Asked Questions
    1. What is PyTorch Monarch?
    2. Why did it need to be ported to ROCm?
    3. What does single-controller mean in this context?
    4. Does Monarch replace NCCL or RCCL?
    5. Can Monarch be used outside of Meta today?
    6. What’s the difference between a traditional checkpoint and Monarch’s recovery?
  10. References

Before this port, a memory error on a single GPU forced a full cluster restart from the last checkpoint. With Monarch, healthy nodes keep training while the failed node recovers and rejoins the job, without losing accumulated progress.

TL;DR

  • AMD and Meta ported PyTorch Monarch to Instinct GPUs with ROCm, extending the runtime beyond CUDA, according to the July 6, 2026 announcement.
  • The port uses hipify_torch to convert the CUDA C++ bridge to HIP and links against RCCL instead of NCCL.
  • The Rust runtime runs on Tokio and coordinates actors, process meshes, and tensor sharding.
  • ROCm has no static equivalent to libcudart_static.a: Monarch links amdhip64 dynamically instead of statically.
  • The hierarchical failure model isolates crashes by actor: local recovery takes seconds, not minutes.
  • RDMA integration stays on libibverbs; with GPU_PLATFORM=rocm only the GPU bindings change from CUDA to HIP.
  • AMD’s prior work had already achieved 96.16% scaling efficiency on a 1024 MI325 GPU cluster training DeepSeek-V3-671B.

Introduction

PyTorch Monarch is an experimental runtime that lets a single Python program orchestrate hundreds or thousands of GPUs at once, as if they were a single machine. Instead of writing explicit distributed code for each node, the developer writes a sequential script and Monarch handles distributing it, running it in parallel, and recovering it if something fails.

The joint announcement from AMD and Meta on July 6, 2026 documents how Monarch’s GPU runtime and distributed communication stack were ported from CUDA to ROCm, AMD’s compute platform for its Instinct accelerators. This is the first time Monarch’s single-controller model has left the NVIDIA ecosystem.

What Happened

AMD’s engineering team (Chaojun Hou, Liz Li, Zachary Streeter, Xinyu Kang, Lei Zhang, Yuankai Chen, Yao Fu, Wen Chen, Zhenyu Gu, and Andy Luo), together with the Monarch team at Meta (Matthias Reso, Hamid Shojanazeri, and collaborators), published the full port on the official PyTorch blog on July 6, 2026.

The work touched three distinct layers of the stack:

  • Collective communications. They used the hipify_torch tool to automatically convert the CUDA C++ bridge to HIP, and linked the result against RCCL, AMD’s library that replicates the NCCL API.
  • GPU memory management. They extended the build system to detect the platform at compile time and redirect each call to the CUDA driver toward its HIP equivalent.
  • RDMA integration. With the GPU_PLATFORM=rocm variable, the RDMA path based on libibverbs remains intact; the only thing that changes are the GPU bindings, from CUDA to HIP, for GPU-direct transfers.

Two design decisions stand out in the port. First, ROCm has no static equivalent to libcudart_static.a: while CUDA links cudart_static directly, the ROCm build links amdhip64 dynamically, and both platforms use dlopen for GPU driver functions (hipMemCreate, cuMemCreate, and similar), which keeps the same runtime contract on both sides.

Second, instead of maintaining two separate versions of the Rust bindings, the team let hipify_torch rewrite the C/C++ headers and had bindgen automatically generate the types with HIP names (hipError_t, hipDeviceptr_t, hipStream_t). A compatibility shim in Rust unifies these types with their CUDA equivalents, so there is a single source of truth instead of two diverging forks.

💡 Tip: if you’re building Monarch from source, the GPU_PLATFORM=rocm variable is the only switch you need to touch: the rest of the platform detection is automatic in the build system.

Background and Context

The problem Monarch tackles is not new. Periodic checkpointing, saving the model’s complete state to storage at set intervals, is the standard fault-tolerance strategy in distributed training. It works, but it has a cost that grows with scale:

Traditional Checkpointing ProblemImpact
Write overheadSaving hundreds of gigabytes of state consumes time and I/O bandwidth
Lost computeAll progress since the last checkpoint is lost with every failure
Idle clusterThe entire cluster waits while the failed node is replaced and the job restarts
Scalability limitThe larger the cluster, the higher the chance a failure will occur within any given checkpoint interval

This isn’t an abstract problem for AMD and Meta. In prior work, AMD had already demonstrated near-linear scaling for FP8 training, with 96.16% scaling efficiency on a 1024 MI325 GPU cluster training DeepSeek-V3-671B. Scaling compute stopped being the bottleneck: surviving failures while scaling is what remained to be solved.

Monarch’s architecture separates two things that used to be coupled: the parallelism strategy within each training replica, and the fault-tolerance mechanism across replicas. That separation is what allows a failure to be isolated instead of propagating to the entire cluster.

PyTorch Monarch architecture with Python, Rust, and GPU layers
Monarch separates the Python API from the Rust runtime and the network infrastructure. Foto de Adi Goldstein en Unsplash

Technical Details and Performance

Monarch’s architecture operates on four levels:

  • Python API. A single program interface: the developer writes sequential Python code and gets distributed GPU execution.
  • Monarch Runtime. Manages actors and process meshes, supervision trees, and tensor sharding.
  • Rust Runtime on Tokio. Guarantees performance and memory safety at the execution layer.
  • Infrastructure. Integrates with RDMA, RCCL/NCCL, SLURM, Kubernetes, and SkyPilot.

The actor model is the key piece. Each actor has private state, so a crash doesn’t automatically propagate to other actors. Failures are handled at the lowest possible level of a supervision hierarchy, and recovery is fast: seconds for a local restart, minutes only if the failure escalates up the supervision tree.

flowchart TD
A["Python API"] --> B["Monarch Runtime: actors and process mesh"]
B --> C["Rust Runtime (Tokio)"]
C --> D["RDMA / RCCL / NCCL"]
D --> E[("AMD Instinct or NVIDIA GPU Cluster")]
subgraph Infrastructure
D
E
end

The following table summarizes where each component changed when moving from CUDA to ROCm:

ComponentCUDA Path (NVIDIA)ROCm Path (AMD)
Collective communicationsDirect link against NCCLhipify_torch converts the C++ bridge and links against RCCL
GPU memory managementNative calls to the CUDA driver (cuMemCreate)The build system redirects to the HIP equivalents (hipMemCreate)
RDMA integrationCUDA bindings over libibverbsSame libibverbs path, GPU bindings changed to HIP
Runtime linkingStatic against libcudart_static.aNo static equivalent; amdhip64 links dynamically

⚠️ Heads up: if your build pipeline assumes a CUDA-style static runtime, you’ll need to adjust your packaging: ROCm depends on amdhip64 as a dynamic library, so the final binary needs that dependency available at runtime, not just at compile time.

Getting Started

Monarch is still an experimental project, so trying it out today means building it from source and pointing the build at the right backend.

Linux with ROCm (Supported Path)

# Clone the repository and enter the directory
git clone https://github.com/pytorch-labs/monarch.git
cd monarch

# Point the build at the AMD runtime instead of CUDA
export GPU_PLATFORM=rocm
export ROCM_PATH=/opt/rocm

pip install -e .

macOS (Without a Real AMD GPU)

ROCm doesn’t run natively on macOS. To work on Monarch’s Python code without executing real kernels, install the package in CPU-only mode and connect to a remote Linux cluster for training runs:

pip install -e . --no-deps
# GPU calls are dispatched to the remote cluster via SSH/SLURM

Windows

Windows also lacks native ROCm support. The practical path is to use WSL2 with GPU passthrough (still experimental for AMD) or connect via SSH to a Linux node on the training cluster.

A minimal example, a stateful actor running locally:

from monarch.actor import Actor, endpoint, this_proc

class Contador(Actor):
    def __init__(self):
        self.valor = 0

    @endpoint
    def incrementar(self, paso: int) -> int:
        self.valor += paso
        return self.valor

proc = this_proc()
contador = proc.spawn("contador", Contador)
print(contador.incrementar.call(5).get())

This actor keeps its state (self.valor) in an isolated process. Calling it from the main script looks just like calling a regular function, even though internally it travels through the Rust runtime.

A more realistic example, a process mesh that survives the failure of a trainer:

from monarch.actor import Actor, endpoint
from monarch.mesh import ProcessMesh

class EntrenadorGPU(Actor):
    @endpoint
    def paso_entrenamiento(self, batch):
        return self.modelo.step(batch)

mesh = ProcessMesh.from_slurm(nodos=64, gpus_por_nodo=8)
entrenadores = mesh.spawn("entrenador", EntrenadorGPU)

try:
    resultados = entrenadores.paso_entrenamiento.call(lote_actual).get()
except ActorCrashError as fallo:
    mesh.reemplazar_nodo(fallo.nodo_id)
    resultados = entrenadores.paso_entrenamiento.call(lote_actual).get()

When an EntrenadorGPU actor crashes, the exception is caught in the controller process, not in the other 511 processes in the mesh. The controller replaces the node and retries that step, without touching the rest of the training.

To confirm your build linked against ROCm and not CUDA, check the compiled binary’s dynamic dependencies:

ldd $(python3 -c "import monarch, os; print(os.path.dirname(monarch.__file__))")/_monarch_rust*.so | grep -i hip

If the build is correct, that line should list libamdhip64.so. A CUDA build would instead show libcudart.so.

Impact and Analysis

For AMD, this port is one more piece of a broader goal: making distributed training software independent of whether the cluster is NVIDIA. Every framework ported to ROCm lowers the cost of switching GPU vendors for a research team, which is especially relevant when AI compute demand outstrips available GPU supply.

For Meta, expanding Monarch beyond CUDA validates its bet on the single-controller model as a general paradigm, not a solution tied to a single hardware vendor. If the same Python script can orchestrate both NVIDIA and AMD GPUs, a research team can move between clusters without rewriting its training, evaluation, and reinforcement learning logic.

That said, the port has limits worth naming. RCCL replicates the NCCL API, but it’s not a perfect mirror: performance parity on each collective (all-reduce, all-gather, reduce-scatter) depends on how optimized each specific operation is in RCCL, and that can vary by cluster topology. Also, Monarch is still an experimental runtime: the actor model adds a layer of indirection that makes sense at large scale, but is unnecessary complexity for single-node training, where a traditional script with torch.distributed is still simpler to debug.

Cluster of AMD Instinct GPUs connected via RDMA network
The RDMA path over libibverbs stays the same between CUDA and ROCm. Foto de Robin Glauser en Unsplash
💭 Key point: Monarch’s real gain isn’t compute speed, it’s cluster utilization: fewer paid GPU-hours sitting idle waiting for a restart.

What’s Next

AMD and Meta describe this port as a step toward bringing the Monarch runtime to a broader hardware ecosystem, suggesting ROCm won’t be the last non-CUDA backend. The decoupled design between the Python API, the Rust runtime, and the network infrastructure makes it easier to add new communication backends without rewriting the layer the developer sees.

In the short term, work will most likely focus on closing the parity gap between RCCL and NCCL on the collective operations that matter most for large-scale training, and on better documenting the integration with SLURM and Kubernetes on ROCm, given that both orchestrators are already supported at Monarch’s infrastructure layer.

📖 Summary on Telegram: View summary

If you have access to a node with an AMD Instinct GPU and ROCm installed, clone the repository and run the actor example with GPU_PLATFORM=rocm: it takes less than ten minutes to confirm whether your local setup is ready to try Monarch.

Frequently Asked Questions

What is PyTorch Monarch?

It’s an experimental runtime from Meta that lets you control an entire GPU cluster from a single Python program, using an actor model and process meshes instead of explicit per-node distributed code.

Why did it need to be ported to ROCm?

Because the original runtime only ran on CUDA. Porting it to ROCm allows it to be used on AMD Instinct GPU clusters, the hardware behind large-scale training projects like AMD’s MI325 cluster.

What does single-controller mean in this context?

It means a single Python program, running in a controller process, orchestrates execution across all nodes in the cluster, instead of each node independently running its own copy of the training script.

Does Monarch replace NCCL or RCCL?

No. Monarch relies on them: it uses NCCL on NVIDIA GPUs and RCCL on AMD GPUs. Monarch is the orchestration and fault-tolerance layer on top of those collective communication libraries.

Can Monarch be used outside of Meta today?

The code is available as an open project and can be built from source, but AMD and Meta describe it as a runtime under active development, not yet a stable, general-purpose product.

What’s the difference between a traditional checkpoint and Monarch’s recovery?

A traditional checkpoint restarts the entire job from the last saved point when a node fails. Monarch isolates the failure in the affected actor and lets the rest of the cluster keep training while that node recovers.

References

📱 Enjoy this content? Follow @programacion on Telegram for daily tech content in Spanish: quick summaries, fresh content every day.

Imagen destacada: Foto de Caspar Camille Rubin en Unsplash

Categories: Noticias Tech

Javier Alarcón

Infrastructure engineer specializing in networking, Linux systems, Kubernetes, and cloud architectures. Covers hardware, networking, observability, and engineering practices for production teams.

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.