Skip to main content

gpu-quiescence

Python Dependencies CI Ollama License PyPI

In plain English: this checks a GPU really has enough free memory and has settled before you launch a big job, so it does not crash halfway through.

Train on the box you serve from: a VRAM readiness preflight for machines that serve and train on one GPU.

More tools · Working rules

Provenance: this came out of one body of production LLM work, extracted and generalised into a standalone package. First published 2026-08-31.

One machine, two jobs: an inference server holding models warm, and a training run that needs the memory back. Start the trainer cold and it OOMs, thrashes, or silently degrades serving. gpu-quiescence runs a preflight first, and records precisely what was tested - including which resource each stage actually touched. Every observation carries the resource it measured, and the envelope names the tool and version that produced it, so an archived --json record identifies itself.

evict → settle → probe → headroom → launch (reduced priority) → restore
  • Evict: ask the inference server to release its models, then check that the memory actually came back. Ships an Ollama evictor; anything with evict / settled / restore plugs in. settled() is a predicate and the stage owns the only deadline, so the report states the time it really waited and counts every question it asked. /api/ps says how much VRAM each model holds, so the reclaim is certified in bytes: free memory must rise by at least 90% of what the server said it was holding (--reclaim-fraction, 0 to switch the check off). "The server says it unloaded" is a claim; the delta is a measurement.
  • Settle: free memory (VRAM in GPU mode, via nvidia-smi) must sit inside a variation band before any reading is trusted. A reclaim still in progress shows up as a wide band and keeps the stage waiting. A timeout too short to ever succeed is rejected at construction.
  • Probe: allocate, touch, and release one representative buffer. Honesty first: the default allocator is host memory (bytearray). In GPU mode the VRAM readiness signal comes from settle and headroom reading real VRAM numbers; the probe proves the host side, and the report names its allocator so the record says exactly what was tested. To probe VRAM itself, pass --probe-vram (library: ProbeStage(..., allocator=torch_cuda_allocator())), which allocates and fills a uint8 tensor on the CUDA device and needs the torch extra. Probe outcomes are three-valued: succeeded, refused (the allocator said no - the expected failure), or errored (the allocator broke). A CUDA OOM counts as a refusal even though torch.cuda.OutOfMemoryError is not a MemoryError; refusal_exceptions= teaches the stage about any other allocator. Both failures gate the launch; the report never disguises one as the other. And success claims only itself: not "memory is contiguous", not "training cannot OOM".
  • Headroom: free >= required * 1.10 + 512 MiB, both knobs configurable. The numbers go in the report either way.
  • Launch + restore: the job runs as a reduced-priority child, and the inference model is re-warmed after it exits, success or not. The box goes back to serving either way.

Every stage produces a report entry with its observations; a failed stage gates the job instead of raising, and an empty handshake fails because nothing was tested. --json emits the whole readiness report.

Install

pip install gpu-quiescence

# gate a fine-tune on 8 GiB of GPU memory, evicting Ollama first
gpu-quiescence --require-mib 8192 --gpu \
  --ollama http://127.0.0.1:11434 --restore-model llama3 \
  -- python train.py

Also installable from a pinned git tag: pip install "git+https://github.com/m-sanchez/gpu-quiescence@v3.0.0". CI proves the built wheel installs, imports, and exposes the command; releases are built and published from a tag by GitHub Actions using PyPI trusted publishing, with PEP 740 attestations, so the wheel can be verified rather than trusted. No required runtime dependencies; psutil and torch are optional extras.

Exit codes: 0 ready (and the job succeeded, if one was given) · 1 not ready, or the job failed · 2 usage error. A usage error is anything that stopped the handshake from running at all - no nvidia-smi, a driver that will not answer, a MIG or vGPU device that reports [N/A] for free memory, an unreachable --ollama URL, a command that does not exist - and it never shares an exit code with a verdict. Every row of that contract has a test against main().

Python 3.10+, zero runtime dependencies. System-RAM mode (--system) reads /proc/meminfo on Linux and GlobalMemoryStatusEx on Windows, and CI runs the suite on both; other platforms need the optional extra (pip install "gpu-quiescence[fallback]", which brings psutil). GPU mode parses nvidia-smi; --probe-vram needs pip install "gpu-quiescence[torch]". Develop with pip install -e . pytest and pytest.

Library use

from gpu_quiescence import Handshake, SettleStage, ProbeStage, HeadroomStage, NvidiaSmiProbe

probe = NvidiaSmiProbe()
report = Handshake([
    SettleStage(probe),
    ProbeStage(probe, required_mib=8192),
    HeadroomStage(probe, required_mib=8192),
]).run()

report.ok           # gate decision
report.to_dict()    # envelope + what was tested, stage by stage

EvictStage(evictor, probe=probe) certifies the reclaim in bytes; ProbeStage(probe, required_mib, allocator=torch_cuda_allocator()) probes VRAM instead of host memory.

The tests are the point

Every externally checkable claim on this page is mapped to the test that enforces it in CLAIMS.md.

Test Claim
settle waits through a moving reclaim, times out on drift a wide band means "not yet", not "fail fast"
a CUDA-shaped OOM is refused, an allocator bug is errored the report never disguises a bug as an OOM, on the allocator that touches VRAM
the probe names its allocator, every stage names its resource the record says which resource was actually tested
a reclaim short of the bytes the server held gates the job "it says it unloaded" is not "the memory came back"
the evict report states the time it actually waited a diagnostic with the wrong number is worse than none
an empty handshake fails nothing tested is not ready
an impossible settle timeout is rejected at construction a stage that can only fail is a lie
the evict stage owns the only deadline eviction is asynchronous, and one wait has one owner
probe success text never says "contiguous" the claim is exactly what the probe established
probe failure is a gated report, not an exception the handshake is a gate; it reports, it does not crash
a driver error, a MIG [N/A], a bad URL and a missing binary all exit 2 a usage error is never a "not ready" verdict
headroom failure carries the numbers a refusal you can act on
restoration runs even when the job fails the box always goes back to serving

Metadata

Release files for gpu-quiescence 3.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gpu-quiescence 3.0.0
File Size Uploaded
gpu_quiescence-3.0.0.tar.gz 26.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gpu-quiescence 3.0.0
File Interpreter ABI Platform
gpu_quiescence-3.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 47.1 kB

Release files / gpu_quiescence-3.0.0.tar.gz

Download URL gpu_quiescence-3.0.0.tar.gz
Size 26.8 kB
Tags Source
SHA-256 checksum
How to use checksums
508685a0a50f29a460e5902bb09b6c8191a366c3ce237ad9e5e60e9ed5fb5bf6
BLAKE2b-256 checksum
How to use checksums
b31dff778d4428b21454b8d1ea69e17032cfc45a43c2ef3596b4179b33295369
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 1, 2026.

Transparency log

Release files / gpu_quiescence-3.0.0-py3-none-any.whl

Download URL gpu_quiescence-3.0.0-py3-none-any.whl
Size 20.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fc70b8b46cac332f92913387f1b78c039dbd762d5aefdbb11d98a44de2fecf94
BLAKE2b-256 checksum
How to use checksums
c331a1ad840fb9136535b12d2ab8e10ab6c4368eb5c955f230ad09fe7f354866
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 1, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

3.0.0 This release

2 release files

2.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page