Run any workload on every GPU (and CPU) you can reach.
Install ·
Quickstart ·
AI agents ·
Why GPUlayer ·
Performance ·
Architecture ·
Docs ·
Examples ·
Changelog
GPUlayer sends a command, a Python function or a distributed job to machines that can run it (this one, remote servers, clusters, data centers, cloud VMs, or several at once), starts it there and brings back logs, outputs and results. PyTorch gets a deeper integration on top. Documentation: gpulayer.dev/docs.
v0.6.0. Tested on CPU, Apple Silicon (PyTorch MPS and MLX) and an NVIDIA Tesla T4, on machines with several GPUs (4× RTX 3070, 2× A100 with NVLink: NCCL across all GPUs of a machine), and on up to 30 machines on Google Cloud. NCCL across machines is implemented but not validated yet; cloud provisioning covers Google Cloud. See Status and roadmap.
Install
pip install gpulayer
That's it. Check what this machine can run:
gpulayer resources detect
To train with PyTorch, install it too: pip install "gpulayer[torch]".
Other ways to install
| Method | Command |
|---|---|
| As a standalone CLI with uv | uv tool install gpulayer |
| Install script (own virtual environment, no sudo) | curl -fsSL https://raw.githubusercontent.com/antonellof/gpulayer/main/install.sh | sh |
| Docker | docker pull ghcr.io/antonellof/gpulayer:0.6.0 (also :0.6.0-torch; see deploy/docker) |
| Kubernetes (Helm) | helm install gpulayer deploy/kubernetes/helm/gpulayer -n gpulayer --create-namespace (see Kubernetes) |
| From source, to run the examples | git clone https://github.com/antonellof/gpulayer && cd gpulayer && pip install -e ".[dev,examples]" |
More in Installation.
Quickstart
# Any command as a job: code and inputs shipped, outputs returned
gpulayer submit --accelerator cuda --source ./app -- ./render.sh
# PyTorch: the same script in this process, as 2-process DDP, or on 2 nodes
python examples/trainer_regression/train.py
python examples/trainer_regression/train.py --accelerator cpu --devices 2
python examples/trainer_regression/train.py --accelerator cpu --nodes 2 --devices 2
# More machines: run this on the server, then paste the printed `gpulayer join` line elsewhere
gpulayer up
# See what ran
gpulayer dashboard
import gpulayer as gl
@gl.remote(accelerator="mps", frameworks={"mlx": ">=0.10"}) # any library, any GPU
def benchmark(n: int) -> dict: ...
benchmark.map([1024, 2048, 4096]) # in parallel
The full quickstart walks through each step with its output.
For AI and coding agents
gpulayer mcp is an MCP server, so Claude Code, Claude Desktop, Cursor, Codex and VS Code
agents can list GPUs, submit jobs, wait, read logs and download outputs. An
Agent Skill covers agents that use the CLI.
claude mcp add gpulayer -- gpulayer mcp
See AI and coding agents.
Why GPUlayer
Most GPU code assumes the GPU is on the machine where you run it. With GPUlayer you describe what a workload needs (an accelerator, GPU memory, frameworks) and it runs on a machine that has it, wherever that machine is.
| Situation | Without GPUlayer | With GPUlayer |
|---|---|---|
| Code on a laptop, GPU elsewhere | ssh, copy code, rebuild the environment, tmux, copy results back | gpulayer submit --target remote -- <cmd> |
| Several GPU machines | track free machines by hand; jobs crash on the wrong GPU or library | one queue; each job lands where it can run, or is rejected with the reason |
| NVIDIA servers and Apple Silicon Macs | separate scripts and setup per machine | ask for cuda or mps; one interface |
| Many independent tasks | loops and ad hoc scripts | fn.map([...]) across free GPUs |
| Multi-node training | torchrun on every node with matching ranks and addresses |
Trainer(num_nodes=2, devices=4); the machines are kept in one zone or rack when possible |
On one machine with one GPU, running your code directly is simpler. GPUlayer runs services without a load balancer in front of them, and is not a sandbox for untrusted code. More in Why GPUlayer.
Performance and comparison
Measured on NVIDIA GPUs against PyTorch Lightning, with the same model, data and optimizer and each trainer's defaults:
- One Tesla T4: GPUlayer's Trainer is 1.25 to 1.39x faster per step on small models and 1.14x on a compute-bound CNN, and starts 0.1 to 0.7 s sooner.
- 1, 2 and 4 RTX 3070s (DDP over NCCL): GPUlayer is faster in 5 of 6 cases, by 1.11 to 1.76x, with the lead growing with the number of GPUs; the 1-GPU CNN was 1.14x faster with Lightning on that host.
- NCCL across 4 GPUs and over NVLink (2x A100), and the best-connected GPU choice, validated on rented machines.
- One training job across machines on CPUs (gloo): GPUlayer trains 11.9% faster than
Lightning under torchrun on 8 machines (50.5 s vs 57.3 s; 5.3% on 4, 1.6% on 2), and it
starts every machine from one
Trainer(num_nodes=N)call. - A distributed job split across two GCP regions ran 16 to 24% slower than in one region; GPUlayer keeps a group in one zone or region when it can.
- Distributed jobs start 1.1 to 2.3 s faster than through torchrun; tested on up to 16 machines (32 processes) and 30 workers across two GCP regions.
- Across two machines: a distributed job spanning both, fail-fast in 2.7 s, and 55.6 small jobs per second.
Method, all charts and raw logs:
Performance and comparison. Reproduce them
with benchmarks/.
Architecture
GPUlayer has three parts:
- Clients submit work: the
gpulayerCLI, the Python SDK (@gl.remote,gl.Client), the PyTorchTrainerandlaunch(), and the MCP server for AI agents. A job states what it needs (accelerator, GPU count and memory, frameworks), not which machine to use. - The control plane keeps the job queue, picks a worker for each job and records the
reason when no worker fits. Distributed groups stay in one network group, zone or region
when possible, and multi-GPU jobs get the best-connected GPUs on a machine. It stores code bundles, inputs, outputs and logs, and checks
tokens. For work on one machine it runs inside your process; for several machines it runs
as a server (
gpulayer up). - Workers, one per machine, report their GPUs and installed frameworks, ask the control
plane for tasks, run them as normal processes (one per rank for distributed jobs),
stream logs back and upload outputs. Workers open every connection themselves, so they can
sit behind NAT. A cloud VM is a worker that joined with
gpulayer join.
A job goes from queued to scheduled when a worker fits, then running, and ends as
succeeded, failed, cancelled or timed_out. Frameworks such as PyTorch, JAX, MLX and
CuPy still decide how the computation uses the GPU; GPUlayer decides which GPU runs it. More in
Architecture overview.
Development
uv pip install -e '.[dev,examples]'
.venv/bin/pytest && .venv/bin/ruff check src tests && .venv/bin/mypy src
See Contributing.
License
Apache License 2.0, see LICENSE.
Metadata
Release files for gpulayer 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| gpulayer-0.6.0.tar.gz | 2.3 MB | With provenance | Details for gpulayer-0.6.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| gpulayer-0.6.0-py3-none-any.whl | Python 3 | none | any | Details for gpulayer-0.6.0-py3-none-any.whl |
Total release size: 2.5 MB
Release files / gpulayer-0.6.0.tar.gz
| Download URL | gpulayer-0.6.0.tar.gz |
|---|---|
| Size | 2.3 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3f41a45a3ec74081b22fd7f49c0d43c8008748d5598e9ec78416d63b1e0e136f
|
|
BLAKE2b-256 checksum How to use checksums |
b639bfcc74558b317fd67ba1b36a843130edac3b4e674cdbc75c92eb66a8d50b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.
Transparency logRelease files / gpulayer-0.6.0-py3-none-any.whl
| Download URL | gpulayer-0.6.0-py3-none-any.whl |
|---|---|
| Size | 176.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e39194b3070f0e23d9e2552b9ee4495f441c8bc1ee901f9d21689387242fd336
|
|
BLAKE2b-256 checksum How to use checksums |
833d8d9199bf6f5289d3d622a442c436d4e43328e1e75b9158c3c612b1047173
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.
Transparency logSecurity for gpulayer 0.6.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for gpulayer-0.6.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.