FluidCR: Heterogeneous GPU Migration framework for deep learning (PyTorch today, TensorFlow-ready)
Project description
FluidCR: Transparent AI/ML Workload Migration Across Heterogeneous GPU Environments
FluidCR lets you live-migrate long-running deep learning jobs between GPUs
using CRIU (Checkpoint/Restore in Userspace), without requiring any code
changes in your training script. Your existing for step, batch in enumerate(dataloader) loop works as-is -- FluidCR transparently resumes from
the correct batch and step number after migration.
It targets PyTorch today and is structured to support additional backends (e.g. TensorFlow) in the future.
Installation
Install the Python package
The FluidCR Python package (launcher + runtime hooks) is published on PyPI as
fluidcr.
On any machine/container where you run training:
python -m pip install --upgrade pip
pip install fluidcr
This installs:
- the
fluidcrpackage (transparentenumerate()patching, hooks, backends) - a
sitecustomize.pymodule in site-packages that automatically loads FluidCR - the
fluidcr-launcherCLI
You can then start training under FluidCR with:
fluidcr-launcher python -u train.py
In Kubernetes Pods, your command block typically becomes:
fluidcr-launcher python -u /workspace/train.py
Runtime prerequisites (cluster)
FluidCR relies on a CRIU and CRI-O build that understand GPU checkpoint/restore
and the /checkpoint/*/lock convention. Install these first on your nodes:
-
CRIU (GPU migration fork)
leehun-criubranch2026-01-26/gpu-migration-support
See the upstream README for build/install instructions: -
CRI-O (restore-from-file fork)
leehun-cri-obranch2026-02-03/support-restore-from-file
Install and configure it as your Kubernetes container runtime:
In addition you need:
- A Kubernetes cluster with GPU nodes and the NVIDIA drivers/runtime configured.
kubectlaccess to the cluster.
Deploying FluidCR example
From this repository:
- Create the demo namespace and storage (if not already present):
examples/dra/ns.yamlexamples/dra/storage.yaml
- Create the ConfigMaps:
examples/dra/fluidcr-scripts.yaml(Launcher + FluidCR payload)examples/dra/training-script.yaml(yourtrain.py)
- Create the resource claim(s):
examples/dra/resource-claim.yaml(orresource-claim-restore.yaml)
- Launch a training pod:
- Single worker:
examples/dra/training-pod.yaml - Two workers in one Pod (for PID-isolation testing):
examples/dra/multiple-training-pod.yaml
- Single worker:
- Trigger checkpoint from outside the pod:
- Prefer using the
fluidcr-ctrlCLI, which also exposes a REST API inside the Pod:- All workers using the GPU:
kubectl exec ... -- fluidcr-ctrl checkpoint --all - Specific PID(s):
kubectl exec ... -- fluidcr-ctrl checkpoint --pid <pid1> <pid2> ...
- All workers using the GPU:
- Under the hood this sends
SIGUSR1to the worker PID(s) and waits until the corresponding/checkpoint/<PPID>/lockfile(s) appear, indicating that the checkpoint is ready for CRIU/CRI-O to snapshot.
- Prefer using the
Control API (CLI + REST)
When at least one fluidcr-launcher is active, FluidCR starts a small HTTP server
inside the container (default 0.0.0.0:8298, configurable via
FLUIDCR_CTRL_PORT). It is implemented by the fluidcr-ctrl module.
-
CLI (inside the Pod):
-
Trigger checkpoint for all GPU-using or worker processes:
fluidcr-ctrl checkpoint --all
-
Trigger checkpoint for specific worker PID(s):
fluidcr-ctrl checkpoint --pid 1234 5678
-
Resume from checkpoints:
# All pending checkpoints (all /checkpoint/*/lock) fluidcr-ctrl resume --all # Specific parent PID(s) fluidcr-ctrl resume --ppid 1 2 3
checkpointwaits until the corresponding lock file(s)/checkpoint/<PPID>/lockappear (or timeout), so when the command returns the checkpoint is ready for CRIU/CRI-O. -
-
REST API (from outside the Pod):
Assuming
FLUIDCR_CTRL_PORT=8298and using the Pod IP:-
POST /checkpoint// Signal specific worker PIDs { "pids": [1234, 5678] } // Or auto-detect GPU/worker PIDs { "all": true }
Response:
{ "results": { "1234": "checkpoint-ready", "5678": "signalled (timeout-waiting-lock)" } }
-
POST /resume// Resume specific parent PIDs { "ppids": [1, 2, 3] } // Or resume all pending checkpoints { "all": true }
Response:
{ "results": { "1": "lock-removed", "2": "no-lock" } }
-
- Use your CRI-O / CRIU integration to checkpoint and restore the container,
pointing CRI-O at the CRIU checkpoint tarball and re-using the same
fluidcr-scriptsandtrain-scriptConfigMaps (seeexamples/dra/restore-pod.yaml).
High-level architecture
FluidCR is split into two main pieces:
-
Launcher (
launcher.py/fluidcr-launcher): a small supervisor process that:- spawns your training script as a child process (the Worker)
- injects
sitecustomize.pyviaPYTHONPATH - watches the Worker's exit code:
0→ training finished, exit normally99→ Worker saved a checkpoint and exited for migration
- buffers the checkpoint file into RAM so CRIU can carry it across nodes
- creates a per-process lock file so an external controller knows when it is safe to snapshot
- starts a lightweight in-container REST API (via the
fluidcr-ctrlmodule) so external controllers can trigger checkpoint/resume over HTTP
-
Payload (
sitecustomize.py+fluidcr/package): automatically loaded into the Worker by Python. It:- installs a PEP‑451 import hook for
torch - monkey-patches
torch.nn.Moduleandtorch.optim.Optimizerto track models and optimizers - patches
builtins.enumeratesoenumerate(DataLoader)transparently resumes from the correct batch after a checkpoint restore - tracks global training steps and RNG state
- handles
SIGUSR1by saving a checkpoint and exiting with code99
- installs a PEP‑451 import hook for
All of this is delivered to your Pods via a ConfigMap (examples/dra/fluidcr-scripts.yaml).
Key files
-
launcher.py- Entry point you run instead of
python train.py. - For each Launcher process, checkpoints and lock files are isolated by
PID:
/checkpoint/<PID>/latest.pt/checkpoint/<PID>/lock
- The external controller can discover all ready instances via
/checkpoint/*/lock.
- Entry point you run instead of
-
sitecustomize.py- Thin bootstrap that simply does
import fluidcr. - Needs to stay at the top level of your
PYTHONPATHso Python’ssitecustomizemechanism can find it.
- Thin bootstrap that simply does
-
fluidcr/__init__.py: patchesenumerate()for transparent DataLoader resume, public API (fluidcr.global_step()), SIGUSR1 handler, import hooks._config.py: env‑driven configuration and lightweight logging._hook.py: generic PEP‑451 import hook logic.backends/__init__.py:AbstractBackendinterface and registry.backends/pytorch.py: PyTorch backend (tracking, checkpointing, RNG, GPU teardown).ctrl.py: external control helpers (fluidcr-ctrlCLI and REST API).
Why launcher.py and sitecustomize.py live at the top level
The package code lives under fluidcr/, but we intentionally keep:
sitecustomize.pyat the top level so that Python’s automaticsitecustomizeimport works as soon as/opt/fluidcris onPYTHONPATH.launcher.pyat the top level so Kubernetes manifests can invoke it as/opt/fluidcr/launcher.pywithout needing to worry about Python module import paths.
Internally, both of these files are very thin:
sitecustomize.pyjust imports thefluidcrpackage.launcher.pyis a small script that wires the environment and hands off most logic to the shared configuration/checkpointing scheme.
In other words, the reusable logic already lives in fluidcr/; the two
top‑level scripts are just ergonomic entry points for Python and Kubernetes.
We can still add more entry points later (e.g. fluidcr.launcher console
script) without changing this layout.
Examples
Working DRA examples live under examples/dra/:
training-pod.yaml– single training job.multiple-training-pod.yaml– twolauncher.pyprocesses in one Pod, useful for testing PID‑isolated checkpoints and locks.restore-pod.yaml– example restore workflow using CRIU.
See docs/FluidCR_Architecture.md for a more detailed architectural walk‑through.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fluidcr-0.3.3.tar.gz.
File metadata
- Download URL: fluidcr-0.3.3.tar.gz
- Upload date:
- Size: 42.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e05e9aab53a649aea88787e040abe42b93147b2c56983d9de155f9513f53d93a
|
|
| MD5 |
d4450d3332c3587d210c7488655534ca
|
|
| BLAKE2b-256 |
6a5d80e341f36a4276465018a07d92a947efcafa88b02d3470250256952de51c
|
File details
Details for the file fluidcr-0.3.3-py3-none-any.whl.
File metadata
- Download URL: fluidcr-0.3.3-py3-none-any.whl
- Upload date:
- Size: 43.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e60d9c393ce8683476d4b36ed06bebde42a4c8f6e509b2252ed06a8800b6b80f
|
|
| MD5 |
9d1b3d543e813e8e24d476b9a96f24a8
|
|
| BLAKE2b-256 |
1d579e3f26b0ce67b367a961064592d1c78e1876a5e617fdae8884cd7443fdd8
|