Skip to content

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 09 Jun 11:57
ade49b3

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. 0 disables, -1 auto-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_SPECTRUM mode + spectrum tuning fields on SDCacheParams.
  • 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-generation FlowShift / 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_video now returns bool and 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_ctx gained backend / params_backend args, surfaced via UpscalerParams.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.txtmaster-685-19bdfe2.
  • Forces SD_WEBP=OFF / SD_WEBM=OFF: upstream now vendors libwebp/libwebm as submodules that clone-upstream.sh initialises 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-685 libs (e.g. with StreamLayers: 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