12 KiB
Linux Port Plan for Local AI Image Generator
Plan location: This plan will be copied to the project root as
PLAN.mdupon approval, per user request.
Implementation Update (post-verification)
During end-to-end testing, the third-party Linux CUDA binary (
leaxer-ai/leaxer-stable-diffusion) was found to segfault during generation after successfully loading the model. As a result, Linux CUDA support was removed from the implementation. Linux NVIDIA GPUs now use the Vulkan backend. The setup script also gained a glibc version check, because the official leejet Linux binaries require glibc 2.38+ (Ubuntu 24.04). The frontend's misleading "mock SVG" fallback was replaced with a real error message when the backend crashes. See the updated README for build-from-source instructions.
1. What This Project Does
Local AI Image Generator is a zero-configuration, portable desktop environment for running Stable Diffusion (Safetensors / GGUF / CKPT) completely offline. The Windows flow is:
- Entry Point:
start.batdouble-click launcher. - Setup:
scripts/setup.ps1auto-downloads portable Node.js for Windows, detects the GPU vendor, downloads the matching stable-diffusion.cpp backend (CUDA for NVIDIA, Vulkan for AMD/Intel), installs npm dependencies, and builds the Vite+React frontend intoapp/dist/. - Runtime:
scripts/serve.cjs(a Node.js HTTP server) serves the static frontend onlocalhost:1420, manages the backend process lifecycle, proxies generation requests, handles model downloads/imports, tracks telemetry, and manages the gallery. - All sandboxed: Everything lives under the project folder (
app/tools/,app/backend/,app/models/,app/outputs/). No global PATH changes, no system installers.
2. Research Findings
2.1 stable-diffusion.cpp Linux Binaries
We researched the upstream project (leejet/stable-diffusion.cpp) and third-party builders. The following Linux x86_64 binaries are available:
| Backend | Source | Availability | Approx. Size | Notes |
|---|---|---|---|---|
| CPU | leejet official releases | ✅ Available | ~20–30 MB | Generic x86_64 CPU binary |
| Vulkan | leejet official releases | ✅ Available | ~100 MB | Cross-vendor GPU (AMD, Intel, NVIDIA) |
| ROCm | leejet official releases | ✅ Available | ~1.2 GB | AMD GPU; requires host ROCm kernel driver |
| CUDA | leejet official releases | ❌ Not published | N/A | See section 2.2 |
| CUDA | leaxer-ai/leaxer-stable-diffusion (third-party) | ❌ Rejected | ~115 MB | Loads models but segfaults during generation; removed from setup. |
Critical Finding: Upstream does not publish Linux CUDA binaries. There is an open feature request (leejet/stable-diffusion.cpp#1291) but no official support yet.
2.2 Linux CUDA Feasibility Analysis
We evaluated the third-party leaxer-ai/leaxer-stable-diffusion Linux CUDA binary:
- The binary downloads successfully and is a valid ELF executable.
- It loads models and initializes CUDA without errors.
- However, it segfaults as soon as image generation starts (reproduced on NVIDIA L4 with
TXT2IMG). - Because the binary is non-functional for its intended purpose, the project does not download or use it.
Decision: Linux CUDA support is disabled until a reliable prebuilt binary becomes available (either from upstream leejet or a verified third-party builder). Linux NVIDIA systems fall back to the Vulkan backend, which uses the same GPU via the NVIDIA Vulkan driver.
Users who need native CUDA performance on Linux can build stable-diffusion.cpp from source with -DSD_CUDA=ON and copy the resulting binary into app/backend/linux/cuda/; see README for instructions.
2.3 Portable Node.js for Linux
- Node.js distributes
node-v22.12.0-linux-x64.tar.xz(matching the Windows LTS version already used). - Fully portable: extract with
tarand runbin/node/bin/npmdirectly.
2.4 Zero-Dependency GPU Detection on Linux
To avoid requiring lspci, lshw, or other host packages, we can parse PCI vendor IDs directly from sysfs:
- Read
/sys/bus/pci/devices/*/vendor - NVIDIA:
0x10de - AMD:
0x1002 - Intel:
0x8086This is pure file I/O and works in any Linux environment with sysfs.
2.5 Extraction Strategy (No Host unzip Required)
- Node.js
.tar.xz→ extracted withtar(universally available on Linux). - Backend
.zipfiles → extracted using Node.js after bootstrapping (e.g., viaadm-zipor a small inline script), or fall back topython3 -m zipfileif needed. - NVIDIA CUDA redist
.tar.xz→ extracted withtar.
3. Implementation Approach: Maximum Performance (All Four Backends)
Based on your feedback, the recommended approach is to support CPU + Vulkan + ROCm + CUDA on Linux.
3.1 Backend Selection Matrix
| Vendor | Primary Backend | Fallback Backend | Source |
|---|---|---|---|
| NVIDIA | CUDA (best perf) | Vulkan | CUDA = leaxer third-party; Vulkan = leejet official |
| AMD | ROCm (best perf) | Vulkan | ROCm = leejet official; Vulkan = leejet official |
| Intel | Vulkan | CPU | Vulkan = leejet official |
| No GPU / Unknown | CPU | — | CPU = leejet official |
3.2 Backend Directory Layout (Linux)
app/backend/
├── win/
│ ├── cuda/sd-cuda.exe
│ └── vulkan/sd-vulkan.exe
└── linux/
├── cpu/sd-cpu
├── vulkan/sd-vulkan
├── rocm/sd-rocm + libstable-diffusion.so
└── cuda/sd-cuda + libstable-diffusion.so + libcudart.so.12 + libcublas.so.12 + libcublasLt.so.12
4. Files to Create / Modify
New Files
-
start.sh— Bash entry point equivalent tostart.bat.- Checks for portable Node.js and frontend build.
- Runs
scripts/setup.shif anything is missing. - Starts
scripts/serve.cjswith the portable Node.js binary. - Opens browser (
xdg-open) or prints URL. - Handles graceful shutdown (traps SIGINT/SIGTERM to kill backend).
-
scripts/setup.sh— Bash setup equivalent tosetup.ps1.- Downloads portable Node.js Linux tarball with
curl+ progress bar. - Extracts with
tar. - Detects GPU via sysfs PCI vendor IDs.
- Downloads appropriate backends:
- CPU + Vulkan for everyone (baseline).
- ROCm if AMD GPU detected.
- CUDA if NVIDIA GPU detected (optional, due to large download).
- Downloads NVIDIA CUDA redist libraries if CUDA is selected.
- Extracts all archives using
tar/ Node.js / Python fallback. - Renames binaries to predictable names.
- Runs
npm installandnpm run buildusing portable npm.
- Downloads portable Node.js Linux tarball with
-
scripts/reset.sh— Bash reset equivalent toreset.ps1.- Deletes
app/tools/,app/backend/,app/dist/,app/frontend/node_modules/while preservingapp/models/andapp/outputs/.
- Deletes
Modified Files
-
scripts/serve.cjs— Enhance Linux support.- Add Linux backend paths:
linuxCpu: path.join(ROOT, "app", "backend", "linux", "cpu", "sd-cpu"), linuxVulkan: path.join(ROOT, "app", "backend", "linux", "vulkan", "sd-vulkan"), linuxRocm: path.join(ROOT, "app", "backend", "linux", "rocm", "sd-rocm"), linuxCuda: path.join(ROOT, "app", "backend", "linux", "cuda", "sd-cuda"), - Add Linux GPU detection via sysfs (
/sys/bus/pci/devices/*/vendor). - Update
getBackendOptions(): For Linux, returncpu,vulkan,rocm(if binary exists), andcuda(if binary + libraries exist). - Update
selectBackendPath(): Choose Linux backend based on resolved type; setLD_LIBRARY_PATHfor CUDA/ROCm subprocesses so they find bundled.sofiles. - Update
getHealth()/getSetupPaths(): Include Linux backend checks. - Update
getGpuInfo()/hasNvidiaGpu(): Add Linux sysfs parsing. - CUDA VRAM polling: Keep existing
nvidia-smiapproach; on Linux it works if drivers are installed.
- Add Linux backend paths:
-
README.md— Add Linux section with compatibility matrix,./start.shusage, and known limitations.
5. Download Sources
| Component | URL Pattern |
|---|---|
| Portable Node.js | https://nodejs.org/dist/v22.12.0/node-v22.12.0-linux-x64.tar.xz |
| CPU Backend | https://github.com/leejet/stable-diffusion.cpp/releases/download/master-XXX/sd-master-XXX-bin-Linux-Ubuntu-24.04-x86_64.zip |
| Vulkan Backend | https://github.com/leejet/stable-diffusion.cpp/releases/download/master-XXX/sd-master-XXX-bin-Linux-Ubuntu-24.04-x86_64-vulkan.zip |
| ROCm Backend | https://github.com/leejet/stable-diffusion.cpp/releases/download/master-XXX/sd-master-XXX-bin-Linux-Ubuntu-24.04-x86_64-rocm-7.13.0.zip |
| CUDA Binary (third-party) | https://github.com/leaxer-ai/leaxer-stable-diffusion/releases/download/v0.1.0/sd-x86_64-unknown-linux-gnu-cuda |
| CUDA Server (third-party) | https://github.com/leaxer-ai/leaxer-stable-diffusion/releases/download/v0.1.0/sd-server-x86_64-unknown-linux-gnu-cuda |
| CUDA Runtime (NVIDIA redist) | https://developer.download.nvidia.com/compute/cuda/redist/cuda_cudart/linux-x86_64/cuda_cudart-linux-x86_64-12.X.YZ-archive.tar.xz |
| cuBLAS (NVIDIA redist) | https://developer.download.nvidia.com/compute/cuda/redist/libcublas/linux-x86_64/libcublas-linux-x86_64-12.X.YZ-archive.tar.xz |
6. Setup Modes
To respect users with limited bandwidth or no NVIDIA hardware, setup.sh should support two modes:
-
Quick Setup (default) — Downloads CPU + Vulkan only.
- Works on all Linux systems.
- NVIDIA users get Vulkan acceleration (good, but not best).
- ~120–150 MB total download.
-
Maximum Performance Setup — Downloads CPU + Vulkan + ROCm + CUDA.
- Best performance for each vendor.
- ~1.5 GB total download (mostly ROCm + cuBLAS).
- User can opt-in via
./start.sh --max-perfor./scripts/setup.sh --max-perf.
7. Self-Contained Checklist
| Host Dependency | How We Eliminate It |
|---|---|
| Node.js installed globally | Download portable node-v22.12.0-linux-x64.tar.xz into app/tools/node-linux/ |
| npm installed globally | Use portable npm from the tarball |
unzip command |
Extract ZIPs using Node.js or Python zipfile |
lspci / lshw |
Parse /sys/bus/pci/devices/*/vendor directly |
| C++ compiler / CUDA toolkit | Use pre-built binaries only |
| System package manager (apt/yum) | Never used |
| CUDA runtime libs | Bundle NVIDIA redistributable .so files |
One unavoidable host dependency remains: the NVIDIA kernel driver (libcuda.so.1) for CUDA mode. Without it, CUDA cannot run. The app will detect this and automatically fall back to Vulkan for NVIDIA.
8. Known Limitations
- Third-party CUDA binary: The Linux CUDA build comes from
leaxer-ai/leaxer-stable-diffusion, which has only one release (v0.1.0) and may become stale. We should pin to a specific version and periodically evaluate alternatives. - Large ROCm download: The official ROCm backend ZIP is ~1.2 GB, which is a significant one-time download.
- Large cuBLAS download: NVIDIA's redistributable cuBLAS package is ~400–500 MB.
- NVIDIA driver requirement for CUDA:
libcuda.so.1must be present on the host (provided by the NVIDIA proprietary driver). If missing, CUDA mode falls back to Vulkan. - ROCm host driver requirement: ROCm requires a compatible AMD GPU and ROCm kernel driver. If unavailable, ROCm falls back to Vulkan.
- glibc compatibility: Official Linux binaries are built on Ubuntu 24.04. They may fail on very old distributions (e.g., CentOS 7, Ubuntu 18.04) due to glibc version mismatches.
9. Recommended Implementation Order
- Create
start.sh,scripts/setup.sh, andscripts/reset.shwith CPU + Vulkan support first. - Update
scripts/serve.cjswith Linux paths, sysfs GPU detection, and backend selection. - Add ROCm download path (behind
--max-perfflag). - Add CUDA download path using leaxer binary + NVIDIA redist libraries (behind
--max-perfflag). - Add fallback logic so that if ROCm/CUDA fails to initialize, the app automatically switches to Vulkan.
- Update
README.mdwith Linux instructions and performance notes. - Test on Linux machines with NVIDIA (CUDA/Vulkan), AMD (ROCm/Vulkan), Intel (Vulkan), and CPU-only configurations.