Get the most out of your CPUs and GPUs without leaving Python: streaming multiprocessing pipelines
Project description
gpupipe
Get the most out of your CPUs and GPUs without leaving Python: streaming pipelines of multi-worker stages — parallel downloads feeding GPU inference feeding DB writes — with backpressure, batching, and graceful shutdown handled for you.
Installation
# With uv
uv add git+https://github.com/mogwai/gpupipe.git
# Or pip
pip install git+https://github.com/mogwai/gpupipe.git
The distribution is gpupipe; the module you import is pipe (sklearn-style):
from pipe import Pipe
Quick Start
from pipe import Pipe
class Generator:
def __call__(self):
# Generator pattern - yield items, exhaustion signals completion
for i in range(100):
yield {"id": i}
class Worker:
def load(self):
# Called after process spawn - initialize heavy resources here
pass
def __call__(self, item):
item["processed"] = True
return item
pipe = Pipe()
pipe.add(Generator(), outqn=20)
pipe.add(Worker(), workers=4, outqn=20)
for result in pipe:
print(result)
Autoscaling (queue-pressure-based worker scaling) is a planned feature — designed and implemented, but not currently wired into
Pipe. SeePLANNED.mdfor the design and re-integration steps.
Capability Tour
GPU pools
pipe.add(GPUWorker(), pergpu=True, outqn=None) # one worker per GPU
pipe.add(GPUWorker(), gpus=[5, 6], workers=2) # 2 workers on each of GPUs 5,6
pipe.add(GPUWorker(), gpu_id=0) # pin every worker to GPU 0
Each process worker is isolated to its GPU via CUDA_VISIBLE_DEVICES; requesting a
GPU that doesn't exist fails loudly instead of silently running on CPU.
CPU affinity
# 16 cores chunked across 4 workers (4 dedicated cores each), BLAS threads sized to match
pipe.add(MelSpectrogram(), workers=4, cpus=range(16))
pipe.add(HeavyCPU(), workers=2, cpu_threads=8) # just lift the 2-thread BLAS cap
Threaded workers (I/O-bound)
pipe.add(IOWorker(), workers=8, thread=True, outqn=20) # one process, 8 threads
Streaming async IO (downloads)
from pipe import AsyncPoolWorker
class Downloader(AsyncPoolWorker):
async def process(self, item): # N in flight continuously,
item["data"] = await fetch(item["url"]) # each result emitted the
return item # moment it lands - no batch barrier
pipe.add(Downloader(max_concurrent=256), workers=1, outqn=200)
Framework batching
class GPUInference:
def __call__(self, batch): # batch = list of up to 16 items,
return run_model(batch) # partial batches included
pipe.add(GPUInference(), pergpu=True, batch=16)
Send items back for retry: push()
class QualityGate:
def __call__(self, item):
if ok(item):
return item
if item.setdefault("tries", 0) < 2:
item["tries"] += 1
self.push("Renderer", item, timeout=5) # back to the Renderer stage
return None
return item # give up, pass through
One pipeline feeding N DDP ranks
pipe = Pipe(expected_consumers=world_size) # rank 0 runs the pipe
pipe.start()
# every rank:
for batch in PipeIterator(shared_queue): # items distributed across ranks,
train_step(batch) # each rank gets its own End
Live stats without log clobbering
pipe = Pipe(stats_interval=3) # pinned one-line display on a TTY
pipe.print("checkpoint saved") # prints ABOVE the stats line
Profiling
pipe = Pipe(profile=True) # per-worker cProfile + peak RSS, summary on stop
Testing
# Run all tests
pytest tests/
# Run a specific test
pytest tests/test_basic.py -v
Key Classes
Pipe- Main pipeline orchestratorEnd- Sentinel a root worker returns to signal completionAsyncPoolWorker- Streaming async IO stage: subclass, implementasync def process(item)Batcher- Batch items togetherBufferAndShuffle- Buffer and shuffle itemsPipeIterator- Read a pipe's output queue from another process (DDP shared mode)
Features
- Multi-worker stages connected by queues, with backpressure
- Threaded workers (
thread=True) for I/O-bound stages - Streaming async IO stages (
AsyncPoolWorker: N requests in flight, no batch barrier) - Framework batching (
batch=N: worker receives a list, partial batches included) - GPU pools:
pergpu=True,gpu_id=N, or explicitgpus=[...]with per-worker isolation - CPU affinity:
cpus=[...]chunked across workers,cpu_threads=for BLAS sizing - Chunked queue transport (
chunk=/chunk_ms=) for small-item edges worker.push(stage, item)- send an item back to an earlier stage (retry/quality gates)- DDP shared mode: one pipeline feeds N training ranks (
expected_consumers+PipeIterator) - Live stats: pinned one-line display on a TTY (
pipe.print()/print_above()write above it), rich mode, or pollget_stats()externally - Health monitoring with worker restart; graceful shutdown with flush semantics
- Per-worker profiling (
profile=True: cProfile + peak RSS summary) - Sequential mode (
sequential=True) for single-process debugging - HTTP serving (
pipe.web) for cross-machine pipelines
Documentation
PIPE_REFERENCE.md- the full reference: worker types, return-value semantics, completion signaling, tensor handling, DDP, env vars, pitfallsdocs/examples/- runnable examples and job templatesPLANNED.md- designed-but-unwired features (autoscaling)
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 gpupipe-0.1.0.tar.gz.
File metadata
- Download URL: gpupipe-0.1.0.tar.gz
- Upload date:
- Size: 113.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.24 {"installer":{"name":"uv","version":"0.9.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"KDE neon","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b86478b4a0f4c6053e3475ad88ef737cb04298e9ad3f150887c59c15f03d10b
|
|
| MD5 |
3b8a3c70779eeb59740b7c33620ede6d
|
|
| BLAKE2b-256 |
6a7632dfdbbbd729f9141fa54c42b78a4a39151f0bbca9a3c82ea9c7e5565e84
|
File details
Details for the file gpupipe-0.1.0-py3-none-any.whl.
File metadata
- Download URL: gpupipe-0.1.0-py3-none-any.whl
- Upload date:
- Size: 46.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.24 {"installer":{"name":"uv","version":"0.9.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"KDE neon","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
af1468ac5ea9272e968063bc0672df8e6c9ebcf4c751ec31051ed4676919488c
|
|
| MD5 |
e1a6addaae6d4cd57eea4cc5668b4398
|
|
| BLAKE2b-256 |
9d7cba8ce2ed27bb2c55caf2eab1dd3bc932a9a90e05f5fa33754591d7c84b83
|