Script assisted by Claude

This commit is contained in:
2026-08-27 12:12:58 +01:00
commit 817cac2ddc
2 changed files with 120 additions and 0 deletions
+118
View File
@@ -0,0 +1,118 @@
"""
gpu_keepalive.py
Tiny AMD GPU keep-alive utility for Windows/WDDM VRAM eviction issues
(e.g. llama.cpp / llama-server on RX 7900 XTX + Adrenalin drivers).
What it does:
- Opens an OpenCL context on the AMD GPU
- Allocates a small buffer resident in GPU memory
- Runs a trivial kernel against it on a timer
- This keeps the GPU context "active" so the driver's idle
power-management / residency-trim path doesn't decide to
evict allocations to system RAM.
This does NOT touch llama.cpp or llama-server directly. It just
keeps the card from ever reaching the idle state that triggers
eviction, so llama-server's own VRAM allocation is less likely
to get trimmed.
Requirements:
pip install pyopencl
Usage:
python gpu_keepalive.py # defaults: 4s interval, 64MB buffer
python gpu_keepalive.py --interval 3 --size-mb 128
python gpu_keepalive.py --list # list available OpenCL devices
Stop with Ctrl+C.
"""
import argparse
import sys
import time
try:
import pyopencl as cl
import numpy as np
except ImportError:
print("Missing dependencies. Install with:\n pip install pyopencl numpy")
sys.exit(1)
KERNEL_SRC = """
__kernel void touch(__global float* buf) {
int i = get_global_id(0);
buf[i] = buf[i] + 1.0f;
}
"""
def find_amd_device():
for platform in cl.get_platforms():
for device in platform.get_devices():
if device.type & cl.device_type.GPU and "amd" in (platform.name + device.name).lower():
return platform, device
# fallback: just grab the first GPU device found
for platform in cl.get_platforms():
for device in platform.get_devices():
if device.type & cl.device_type.GPU:
return platform, device
return None, None
def list_devices():
for platform in cl.get_platforms():
print(f"Platform: {platform.name}")
for device in platform.get_devices():
print(f" Device: {device.name} ({device.type})")
def main():
parser = argparse.ArgumentParser(description="Tiny AMD GPU keep-alive to prevent WDDM VRAM eviction.")
parser.add_argument("--interval", type=float, default=4.0, help="Seconds between GPU touches (default: 4)")
parser.add_argument("--size-mb", type=int, default=64, help="Size of the resident buffer in MB (default: 64)")
parser.add_argument("--list", action="store_true", help="List OpenCL platforms/devices and exit")
args = parser.parse_args()
if args.list:
list_devices()
return
platform, device = find_amd_device()
if device is None:
print("No OpenCL GPU device found. Is the AMD OpenCL runtime installed (it ships with Adrenalin)?")
sys.exit(1)
print(f"Using platform: {platform.name}")
print(f"Using device: {device.name}")
ctx = cl.Context([device])
queue = cl.CommandQueue(ctx)
program = cl.Program(ctx, KERNEL_SRC).build()
kernel = cl.Kernel(program, "touch")
n_floats = (args.size_mb * 1024 * 1024) // 4
host_buf = np.zeros(n_floats, dtype=np.float32)
mf = cl.mem_flags
gpu_buf = cl.Buffer(ctx, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=host_buf)
print(f"Resident buffer: {args.size_mb} MB")
print(f"Touch interval: {args.interval}s")
print("Running. Ctrl+C to stop.\n")
try:
tick = 0
while True:
kernel.set_args(gpu_buf)
cl.enqueue_nd_range_kernel(queue, kernel, (n_floats,), None)
queue.finish()
tick += 1
print(f"\r[keep-alive] touched GPU buffer #{tick}", end="", flush=True)
time.sleep(args.interval)
except KeyboardInterrupt:
print("\nStopped.")
if __name__ == "__main__":
main()
+2
View File
@@ -0,0 +1,2 @@
pyopencl
numpy