feat: add GPU/CUDA acceleration support (:cuda Docker tag)

Add a :cuda Docker image tag that auto-detects NVIDIA GPU at runtime
and falls back gracefully to CPU. Same pattern as Immich.

- New gpu.py shared utility for cached CUDA detection
- Background removal (rembg): pass CUDAExecutionProvider to ONNX Runtime
- Upscaling (Real-ESRGAN): use CUDA device + FP16 when GPU available
- OCR (PaddleOCR): enable use_gpu when CUDA detected
- Dispatcher reports GPU status at startup via readiness signal
- Admin health endpoint exposes GPU availability
- Dockerfile uses ARG GPU=false with conditional NVIDIA CUDA base image
- docker-compose.gpu.yml override for GPU users
- CI/CD workflows build and publish :cuda tag (amd64 only)

Three tags: :latest (CPU), :lite (no AI), :cuda (GPU with CPU fallback)
This commit is contained in:
Siddharth Kumar Sah
2026-04-05 19:12:45 +08:00
parent d0c69d6a46
commit 29a382e9e0
13 changed files with 182 additions and 33 deletions
+10
View File
@@ -54,6 +54,8 @@ interface PendingRequest {
let dispatcher: ChildProcess | null = null;
let dispatcherReady = false;
let dispatcherFailed = false;
// biome-ignore lint/style/useConst: reassigned on dispatcher readiness signal
let dispatcherGpuAvailable = false;
const pendingRequests = new Map<string, PendingRequest>();
let stdoutBuffer = "";
@@ -82,6 +84,7 @@ function startDispatcher(): ChildProcess | null {
// Readiness signal
if (parsed.ready === true) {
dispatcherReady = true;
dispatcherGpuAvailable = parsed.gpu === true;
continue;
}
@@ -221,6 +224,13 @@ function dispatcherRun(
});
}
/**
* Whether the Python dispatcher detected a CUDA GPU at startup.
*/
export function isGpuAvailable(): boolean {
return dispatcherGpuAvailable;
}
/**
* Shut down the persistent dispatcher process.
*/
+1 -1
View File
@@ -1,5 +1,5 @@
export { removeBackground } from "./background-removal.js";
export { shutdownDispatcher } from "./bridge.js";
export { isGpuAvailable, shutdownDispatcher } from "./bridge.js";
export { blurFaces } from "./face-detection.js";
export { inpaint } from "./inpainting.js";
export { extractText } from "./ocr.js";