Files
transcriber/PLAN.md
T
2026-06-09 10:55:47 +00:00

193 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Linux Port Plan for Local AI Image Generator
> **Plan location**: This plan will be copied to the project root as `PLAN.md` upon 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:
1. **Entry Point**: `start.bat` double-click launcher.
2. **Setup**: `scripts/setup.ps1` auto-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 into `app/dist/`.
3. **Runtime**: `scripts/serve.cjs` (a Node.js HTTP server) serves the static frontend on `localhost:1420`, manages the backend process lifecycle, proxies generation requests, handles model downloads/imports, tracks telemetry, and manages the gallery.
4. **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](https://github.com/leejet/stable-diffusion.cpp/issues/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 `tar` and run `bin/node` / `bin/npm` directly.
### 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**: `0x8086`
This 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 with `tar` (universally available on Linux).
- Backend `.zip` files → extracted using Node.js after bootstrapping (e.g., via `adm-zip` or a small inline script), or fall back to `python3 -m zipfile` if needed.
- NVIDIA CUDA redist `.tar.xz` → extracted with `tar`.
## 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
1. **`start.sh`** — Bash entry point equivalent to `start.bat`.
- Checks for portable Node.js and frontend build.
- Runs `scripts/setup.sh` if anything is missing.
- Starts `scripts/serve.cjs` with the portable Node.js binary.
- Opens browser (`xdg-open`) or prints URL.
- Handles graceful shutdown (traps SIGINT/SIGTERM to kill backend).
2. **`scripts/setup.sh`** — Bash setup equivalent to `setup.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 install` and `npm run build` using portable npm.
3. **`scripts/reset.sh`** — Bash reset equivalent to `reset.ps1`.
- Deletes `app/tools/`, `app/backend/`, `app/dist/`, `app/frontend/node_modules/` while preserving `app/models/` and `app/outputs/`.
### Modified Files
4. **`scripts/serve.cjs`** — Enhance Linux support.
- **Add Linux backend paths**:
```js
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, return `cpu`, `vulkan`, `rocm` (if binary exists), and `cuda` (if binary + libraries exist).
- **Update `selectBackendPath()`**: Choose Linux backend based on resolved type; set `LD_LIBRARY_PATH` for CUDA/ROCm subprocesses so they find bundled `.so` files.
- **Update `getHealth()` / `getSetupPaths()`**: Include Linux backend checks.
- **Update `getGpuInfo()` / `hasNvidiaGpu()`**: Add Linux sysfs parsing.
- **CUDA VRAM polling**: Keep existing `nvidia-smi` approach; on Linux it works if drivers are installed.
5. **`README.md`** — Add Linux section with compatibility matrix, `./start.sh` usage, 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:
1. **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.
2. **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-perf` or `./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
1. **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.
2. **Large ROCm download**: The official ROCm backend ZIP is ~1.2 GB, which is a significant one-time download.
3. **Large cuBLAS download**: NVIDIA's redistributable cuBLAS package is ~400–500 MB.
4. **NVIDIA driver requirement for CUDA**: `libcuda.so.1` must be present on the host (provided by the NVIDIA proprietary driver). If missing, CUDA mode falls back to Vulkan.
5. **ROCm host driver requirement**: ROCm requires a compatible AMD GPU and ROCm kernel driver. If unavailable, ROCm falls back to Vulkan.
6. **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
1. Create `start.sh`, `scripts/setup.sh`, and `scripts/reset.sh` with CPU + Vulkan support first.
2. Update `scripts/serve.cjs` with Linux paths, sysfs GPU detection, and backend selection.
3. Add ROCm download path (behind `--max-perf` flag).
4. Add CUDA download path using leaxer binary + NVIDIA redist libraries (behind `--max-perf` flag).
5. Add fallback logic so that if ROCm/CUDA fails to initialize, the app automatically switches to Vulkan.
6. Update `README.md` with Linux instructions and performance notes.
7. Test on Linux machines with NVIDIA (CUDA/Vulkan), AMD (ROCm/Vulkan), Intel (Vulkan), and CPU-only configurations.