Skip to content

v0.2.3

Choose a tag to compare

@github-actions github-actions released this 30 Jun 16:27
ff3f626

stable-diffusion-go v0.2.3 — pure-Go binding + prebuilt native libraries.

Built from leejet/stable-diffusion.cpp @ 19bdfe2 (upstream pin: master-685-19bdfe2).

go get github.com/Pendra-Cloud/stable-diffusion-go@v0.2.3 for the
binding; the lib archives attached here match this exact tag. Each archive
contains a self-contained libstable-diffusion (ggml statically linked,
hidden visibility — exports only the sd_* symbols pkg/sd/load.go registers).

CUDA archives require a matching host CUDA runtime; Vulkan archives require
a Vulkan loader/ICD on the host. The Windows archive carries the per-CPU/GPU
(avx2/avx512/avx/noavx/vulkan/cuda13) subdir tree the binding selects from.

Problem

On a Windows GPU host, image generation runs entirely on CPU even though a working GPU build is bundled. Confirmed live on a GCP NVIDIA L4 / Windows Server 2022 worker (Pendra v3.40.2): SDXL loaded with VRAM 0.00MB / RAM 4590MB, pegging the CPU for 5+ minutes with zero nvidia-smi activity.

Root cause

windowsLibCandidates builds the wrong candidate order:

if SD_VK_DEVICE == "true" { ...vulkan only if vulkaninfo detects a GPU... }
else if GetGPUName() == "NVIDIA" { candidates += "cuda13/..." }   // ← our host
candidates += GetCpuAVX()                                          // avx2 fallback
  • The Pendra Windows installer bundles no cuda13 SD build (only avx*/noavx + vulkan), so the NVIDIA branch dead-ends and falls through to avx2 (CPU).
  • The working vulkan build is gated behind SD_VK_DEVICE=true and GetVulkanGPU(), which shells out to vulkaninfo — a Vulkan-SDK tool that GPU drivers don't install. So the GPU path is effectively unreachable by default.

Fix

Select the Vulkan build for any detected GPU when the Vulkan loader is present:

  • Order candidates vendor-optimal (cuda13/rocm) → vulkan → CPU. Load() already opens the first candidate whose file exists and skips the rest, so listing an unbundled variant (e.g. cuda13) is free — the NVIDIA host now lands on vulkan.
  • Detect the loader via vulkan-1.dll in %SystemRoot%\System32 (installed by every vendor's Windows driver) instead of the vulkaninfo CLI.
  • Keep SD_VK_DEVICE=true as an explicit force override.

Verified

  • End-to-end on hardware: routing the L4 to the bundled vulkan build drove the GPU at 91–99% SM utilisation and finished generations in seconds (vs 5+ min on CPU).
  • Unit tests (no GPU / no native lib needed — detection injected via package vars): NVIDIA & AMD prefer Vulkan-before-CPU; no Vulkan loader ⇒ no Vulkan offered; no GPU ⇒ CPU-only; SD_VK_DEVICE=true forces Vulkan.
  • go build ./..., go test ./..., and GOOS=windows/GOOS=darwin cross-builds all pass.

Downstream

After this is tagged (e.g. v0.2.3), bump the dependency in Pendra-Cloud/pendra (packages/worker/go.mod) so the worker picks up GPU image generation on Windows.

What's Changed

  • fix(windows): prefer the bundled Vulkan GPU build on a GPU host by @tomcrawf90 in #26

Full Changelog: v0.2.2...v0.2.3