v0.2.0
stable-diffusion-go v0.2.0 — 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.0 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/cuda12) subdir tree the binding selects from.
Highlights
Re-syncs the binding to leejet/stable-diffusion.cpp master-685 (from master-453 — 232 upstream commits) and surfaces the new image-generation capabilities, most notably CPU→GPU weight streaming for running models that don't fit in VRAM.
This is a minor release (
v0.2.0): it adds significant features and contains one breaking API change (see below).
✨ VRAM weight streaming — run models larger than your GPU
ContextParams.StreamLayers bool— stream model weights from CPU during generation (residency + prefetch).ContextParams.MaxVRAM float32— GiB budget for graph-cut segmented parameter offload.0disables,-1auto-detects (free VRAM minus 1 GiB).ContextParams.Backend/ParamsBackend string— runtime backend selection (upstream switched to runtime backend discovery).
StreamLayers has no effect unless MaxVRAM is also set. This is weight streaming for memory-constrained inference — not token/output streaming.
🔍 Hi-res fix (second high-resolution pass)
New ImgGenParams fields: HiresEnabled, HiresUpscaler (latent / model / lanczos / latent_bicubic / …), HiresModelPath, HiresScale, HiresTargetWidth, HiresTargetHeight, HiresSteps, HiresDenoisingStrength, HiresUpscaleTileSize, HiresCustomSigmas. Disabled by default; unset numeric fields keep the library's defaults.
🎛️ New samplers, schedulers, caches, quant types
- Samplers:
res_multistep,res_2s,er_sde,euler_cfg_pp,euler_a_cfg_pp,euler_ge. - Schedulers:
bong_tangent,ltx2. - Cache:
SD_CACHE_SPECTRUMmode + spectrum tuning fields onSDCacheParams. - Quant types:
nvfp4,q1_0. - Other context options:
VAEFormat(auto/flux/sd3/flux2),FlashAttn(whole-model flash attention), new model/loader paths (UncondDiffusionModelPath,EmbeddingsConnectorsPath,AudioVAEPath), and per-generationFlowShift/ExtraSampleArgs.
The upstream commit range also adds support for many new models that the prebuilt libs in this release now carry — Flux.2 Klein, HiDream, Anima, ERNIE-image, Longcat, Ideogram4, SDXS, Z-Image, Chroma Radiance, plus Qwen-image fixes and assorted performance work.
⚠️ Breaking change
ContextParams.FlowShift has been removed. Upstream moved flow_shift from a context-level setting to a per-generation sampler parameter. Migrate by setting it on the generation params instead:
// before
sd.NewStableDiffusion(&ContextParams{ /* ... */ FlowShift: 3.0 })
// after — set it per generation
sd.GenerateImage(&ImgGenParams{ /* ... */ FlowShift: 3.0 }, out) // images
// (VidGenParams.FlowShift / HighNoiseFlowShift for video)When left unset (0), the binding now passes the upstream "auto" sentinel so each model uses its own appropriate shift — preserving the old "library default" behaviour rather than silently forcing shift = 0 (which would degrade flow models like Flux/SD3).
🧱 ABI resync (why this PR touches so much)
The Go structs are a hand-maintained mirror of the C structs and are populated by the native *_init functions through a pointer, so they must match the new C layout exactly or memory corrupts. Several C structs gained fields mid-struct (e.g. temporal_tiling is now field #2 of sd_tiling_params_t), and two native signatures changed:
generate_videonow returnsbooland yields frames and an audio buffer. The audio buffer is freed (this binding is image-focused); the public Go(*SDContext).GenerateVideo→([]SDImage, int)signature is unchanged, so video callers are unaffected.new_upscaler_ctxgainedbackend/params_backendargs, surfaced viaUpscalerParams.Backend/ParamsBackend.
Six new native symbols are bound: sd_ctx_supports_image_generation, sd_ctx_supports_video_generation, sd_hires_upscaler_name, str_to_sd_hires_upscaler, sd_hires_params_init, free_sd_audio.
Scope: image generation only. Video is kept compiling and correct (full ABI resync + signature fix, audio discarded) but gains no new features; no LTX2 audio pipeline.
🛠️ Build
lib/version.txt→master-685-19bdfe2.- Forces
SD_WEBP=OFF/SD_WEBM=OFF: upstream now vendors libwebp/libwebm as submodules thatclone-upstream.shinitialises recursively (which would otherwise default them ON). The binding does its own image I/O (PNG via the Go stdlib), so this keeps the build lean and identical in scope to before. - Single self-contained shared-lib model is preserved (
SD_BUILD_SHARED_LIBS=ON, static ggml, hidden visibility), so packaging and the symbol gate are unchanged.
✅ Verification
gofmt -l . clean · go vet ./... · go test ./... · cross-builds for windows/amd64, darwin/arm64, linux/amd64 — all pass with no native library present. The CI symbol gate (lib/expected-symbols.txt, now 47 symbols) and the enum-ABI table (pkg/sd/enums_test.go) guard that the resync stayed faithful to the C ABI; a new maps_test.go covers the added string→enum map entries.
The native libs are built and symbol-verified by this release pipeline. An end-to-end generation against the freshly built
master-685libs (e.g. withStreamLayers: true) is the remaining manual smoke test — CI has no GPU/lib.
🤖 Generated with Claude Code
What's Changed
- feat: upgrade stable-diffusion.cpp to master-685 (VRAM weight streaming + image features) by @tomcrawf90 in #19
Full Changelog: v0.1.15...v0.2.0