JAX 501: systems topics#
Everything so far assumed one Python process driving some devices. These pages are about running JAX as part of a larger system: many processes and hosts, long-lived and restartable jobs, artifacts that outlive the process that created them, and the machinery that keeps it all fast and safe.
Introduction to multi-controller JAX (aka multi-process/multi-host JAX) — multi-controller JAX: running one process per host, process-spanning meshes and arrays, runtime-level pipeline parallelism with
jax.device_put, and building global arrays from per-process data.Distributed data loading — distributed data loading: getting each batch’s shards onto the right hosts, for data-parallel and model-parallel workloads.
Fault Tolerant Distributed JAX — fault-tolerant distributed JAX: surviving machine failures with
jax.live_devices, barrier semantics, and recovery, with worked training examples.Security considerations — securing JAX’s network services: mTLS for the coordination service and the TPU runtime’s internal services, and which connections remain unprotected.
Exporting and serializing staged-out computations — exporting and serializing staged-out computations for later or cross-platform execution, and Shape polymorphism — exporting with symbolic shapes so one artifact serves many input sizes.
Persistent compilation cache — the persistent compilation cache: skipping recompilation across process restarts and sharing compiled artifacts across nodes.
Transfer guard — logging or disallowing unintended host-device transfers.
Smaller notes#
A few systems topics are small enough to cover right here.
Concurrency and threads. JAX has limited support for Python concurrency:
it’s fine to call JAX APIs like jax.jit() or jax.grad() from
multiple Python threads, but you must not use threads to manipulate JAX
trace values inside a traced function — the likely outcome is a mysterious
error. In multi-controller JAX (Introduction to multi-controller JAX (aka multi-process/multi-host JAX)) threading has a further
hazard: every process must enqueue the same operations in the same order on
a given device, and threads can schedule work in different orders in
different processes, causing non-deterministic crashes. The
jax.thread_guard() context manager helps detect this: once set, an
error is raised if a JAX operation is issued from a thread other than the
one where the guard was set.
Multi-process coordination helpers. The
jax.experimental.multihost_utils module collects small utilities for
multi-controller programs: sync_global_devices (a named cross-process
barrier), broadcast_one_to_all (make process 0’s value everyone’s
value), process_allgather (gather a value from every process),
assert_equal (check that a value agrees across processes), and
host_local_array_to_global_array / global_array_to_host_local_array
(convert between per-host and global views of arrays).
Compatibility policies for long-lived artifacts. Serialized artifacts outlive the process that made them, so here is what’s promised: exported modules have explicit compatibility windows (see the compatibility guarantees in Exporting and serializing staged-out computations); persistent compilation cache entries make no cross-version promises, but their keys include the jaxlib version, so version changes cause cache misses rather than misbehavior; and JAX’s general API stability rules are described in the API compatibility policy.