Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
ce95c09
fix: halve VAE decode tile size on OOM retry instead of clamping to 2…
losewayy Oct 10, 2026
0e1d733
docs: restrict README UI listings to open-source projects
leejet Oct 10, 2026
05845fd
ci: fix ROCm ccache build caching and update to ROCm 10.1.0 (#1890)
superm1 Oct 10, 2026
b7a74e6
fix: demote resident params to disk residency when memory reclamation…
losewayy Oct 10, 2026
1b0ba10
feat: run conditional and unconditional CFG in one batched UNet forwa…
daniandtheweb Oct 10, 2026
2988060
feat: add TAEQI2.1 support for Qwen Image 2.1 (#2123)
leejet Oct 10, 2026
792bcd3
feat: add MoSR upscaler support (#2128)
GabrieleLozupone Oct 12, 2026
d637cfb
feat: add Qwen Image 2.1 Turbo sigma preset (#2130)
leejet Oct 12, 2026
7e3e20a
ci: add ROCm Dockerfile (#2094)
robertosw Oct 13, 2026
60423ab
fix: reclaim before accepting wrapped Vulkan iGPU memory estimates (#…
losewayy Oct 13, 2026
d763dae
feat: add per-module automatic flash attention selection (#2132)
leejet Oct 13, 2026
46362fc
feat: add automatic direct convolution selection (#2134)
leejet Oct 13, 2026
1d0a58a
chore: move parameter and tokenizer diagnostics to debug (#2135)
leejet Oct 13, 2026
120e3e8
docs: add Kokon to UIs (#2136)
GabrieleLozupone Oct 14, 2026
2891378
fix: prevent core dump in CPU backend if using FP8 (e4m3) tensors (#2…
akleine Oct 15, 2026
e47426c
fix: benchmark Vulkan direct convolution in auto mode (#2141)
leejet Oct 15, 2026
8cd731e
feat: add FLUX.3 Image Klein and Klein Base support (#2143)
leejet Oct 15, 2026
359125c
Merge upstream master (FLUX.3 Image Klein) into the fork
danielhanchen Oct 16, 2026
ca7d7af
Keep --diffusion-fa covering the MiniMax-H3 video VAE under per-modul…
danielhanchen Oct 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ jobs:
runs-on: windows-2022

env:
ROCM_VERSION: "7.14.0"
ROCM_VERSION: "10.1.0"
GPU_TARGETS: "gfx1010;gfx1011;gfx1012;gfx1030;gfx1031;gfx1032;gfx1033;gfx1034;gfx1035;gfx1036;gfx1100;gfx1101;gfx1102;gfx1103;gfx1150;gfx1151;gfx1152;gfx1153;gfx1200;gfx1201"
# rocm-sdk re-expands clang from the wheel every run, so its mtime always
# differs and the default compiler_check=mtime misses every object.
Expand Down Expand Up @@ -502,7 +502,7 @@ jobs:

write-host "Installing ROCm wheels for multi-arch support"
# Install ROCm wheels for multi-arch support (this may take several minutes)
python -m pip install --index-url https://repo.amd.com/rocm/whl-multi-arch/ "rocm[libraries,devel]==${{env.ROCM_VERSION}}"
python -m pip install --index-url https://stable.repo.amd.com/rocm/whl-next/ "rocm[libraries,devel]==${{env.ROCM_VERSION}}"

# Pre-expand the devel tree so it is included in the cache
write-host "Initializing ROCm devel tree"
Expand Down Expand Up @@ -599,9 +599,9 @@ jobs:
strategy:
matrix:
include:
- ROCM_VERSION: "7.14.0"
- ROCM_VERSION: "10.1.0"
gpu_targets: "gfx900;gfx906;gfx908;gfx90a;gfx90c;gfx942;gfx950;gfx1010;gfx1011;gfx1012;gfx1030;gfx1031;gfx1032;gfx1033;gfx1034;gfx1035;gfx1036;gfx1100;gfx1101;gfx1102;gfx1103;gfx1150;gfx1151;gfx1152;gfx1153;gfx1200;gfx1201"
build: x64
build: 'x64'

steps:
- name: Clone
Expand All @@ -618,6 +618,15 @@ jobs:
# Plateaus at the 500M default (88.19% full, 142 misses/run).
max-size: 2G

- name: Tune ccache for reinstalled ROCm toolchain
run: |
# ROCm is pip-installed fresh each run, so the clang binary's mtime
# changes every time. With the default compiler_check=mtime that
# invalidates the cache; hash compiler contents instead so warm
# builds hit.
ccache --set-config=compiler_check=content
ccache --set-config=sloppiness=time_macros,include_file_mtime,include_file_ctime

- name: Dependencies
id: depends
run: |
Expand Down Expand Up @@ -653,7 +662,7 @@ jobs:
# libraries = HIP runtime and CMake configs needed for linking
# devel = compilers, headers, static libs
python -m pip install --upgrade pip
python -m pip install --index-url https://repo.amd.com/rocm/whl-multi-arch/ "rocm[libraries,devel]==${{matrix.ROCM_VERSION}}"
python -m pip install --index-url https://stable.repo.amd.com/rocm/whl-next/ "rocm[libraries,devel]==${{matrix.ROCM_VERSION}}"

# Get ROCm installation paths using the rocm-sdk CLI tool
ROCM_PATH=$(rocm-sdk path --root)
Expand Down
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ file(GLOB SD_LIB_SOURCES CONFIGURE_DEPENDS
"src/core/*.h"
"src/core/*.cpp"
"src/core/*.hpp"
"src/core/probe/*.h"
"src/core/probe/*.cpp"
"src/extensions/*.h"
"src/extensions/*.cpp"
"src/extensions/*.hpp"
Expand Down Expand Up @@ -342,6 +344,14 @@ if (SD_CUDA)
target_link_libraries(${SD_LIB} PUBLIC CUDA::cuda_driver)
set_property(SOURCE src/core/ggml_extend_backend.cpp APPEND PROPERTY COMPILE_DEFINITIONS SD_USE_CUDA)
endif()
if (SD_HIPBLAS)
find_package(hip REQUIRED CONFIG HINTS "$ENV{ROCM_PATH}" /opt/rocm)
target_link_libraries(${SD_LIB} PRIVATE hip::host)
set_property(SOURCE src/core/ggml_extend_backend.cpp APPEND PROPERTY COMPILE_DEFINITIONS SD_USE_HIP)
if (GGML_HIP_MMQ_MFMA)
set_property(SOURCE src/core/ggml_extend_backend.cpp APPEND PROPERTY COMPILE_DEFINITIONS SD_HIP_MFMA)
endif()
endif()
target_include_directories(${SD_LIB} PUBLIC . src include)
target_include_directories(${SD_LIB} PRIVATE src/core)
target_include_directories(${SD_LIB} PUBLIC . thirdparty)
Expand Down
4 changes: 4 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ PRs should include:
- Linked issue/PR context when applicable.
- Screenshots or sample outputs for UI/visual behavior changes.

## README UI Listings

The [UIs list in the README](README.md#uis) only includes open-source projects that use `stable-diffusion.cpp` as a backend. Do not submit PRs to add closed-source UIs.

## Code Style

Format code according to the repository style before submitting changes.
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ API and command-line option may change frequently.***

## 🔥Important News

* **2026/10/16** 🚀 stable-diffusion.cpp adds **Day-0 support for FLUX.3 Image Klein / Klein Base**
* **2026/09/20** 🚀 stable-diffusion.cpp adds **Day-0 support for Qwen-Image-2.1**
* **2026/08/20** 🚀 stable-diffusion.cpp now supports **LTX-2.5**
* **2026/08/04** 🚀 stable-diffusion.cpp adds **Day-1 support for MiniMax-H3**
Expand Down Expand Up @@ -44,6 +45,7 @@ API and command-line option may change frequently.***
- [SD3/SD3.5](./docs/sd3.md)
- [FLUX.1-dev/FLUX.1-schnell](./docs/flux.md)
- [FLUX.2-dev/FLUX.2-klein](./docs/flux2.md)
- [FLUX.3 Image Klein / Klein Base](./docs/flux3.md)
- [Lens](./docs/lens.md)
- [Chroma](./docs/chroma.md)
- [Chroma1-Radiance](./docs/chroma_radiance.md)
Expand Down Expand Up @@ -183,14 +185,14 @@ These projects wrap `stable-diffusion.cpp` for easier use in other languages/fra
These projects use `stable-diffusion.cpp` as a backend for their image generation.

- [GIMP Plugins](https://github.com/themanyone/gimp-plugins)
- [Jellybox](https://jellybox.com)
- [Stable Diffusion GUI](https://github.com/fszontagh/sd.cpp.gui.wx)
- [Stable Diffusion CLI-GUI](https://github.com/piallai/stable-diffusion.cpp)
- [Local Diffusion](https://github.com/rmatif/Local-Diffusion)
- [sd.cpp-webui](https://github.com/daniandtheweb/sd.cpp-webui)
- [LocalAI](https://github.com/mudler/LocalAI)
- [Neural-Pixel](https://github.com/Luiz-Alcantara/Neural-Pixel)
- [KoboldCpp](https://github.com/LostRuins/koboldcpp)
- [Kokon](https://github.com/GabrieleLozupone/kokon)

## Contributors

Expand Down
Binary file added assets/flux3/flux3-image-klein-base.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/flux3/flux3-image-klein-edit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/flux3/flux3-image-klein.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions docker/Dockerfile.rocm
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
FROM rocm/dev-ubuntu-24.04 AS build

# sd-server embeds the web UI at build time, so the build image needs Node/pnpm.
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential git cmake ninja-build ccache ca-certificates curl gnupg && \
mkdir -p /etc/apt/keyrings && \
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key -o /tmp/nodesource-repo.gpg.key && \
gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg /tmp/nodesource-repo.gpg.key && \
rm /tmp/nodesource-repo.gpg.key && \
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" > /etc/apt/sources.list.d/nodesource.list && \
apt-get update && apt-get install -y --no-install-recommends nodejs && \
npm install -g pnpm@10.15.1 && \
apt-get clean && rm -rf /var/lib/apt/lists/*

WORKDIR /sd.cpp

# ROCm's clang is not on PATH in Docker RUN shells (profile scripts are not loaded).
ENV PATH="/opt/rocm/llvm/bin:$PATH"

COPY . .

ARG AMDGPU_TARGETS=""

RUN cmake . -B ./build -G Ninja \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DSD_HIPBLAS=ON \
-DGGML_NATIVE=OFF \
-DAMDGPU_TARGETS="${AMDGPU_TARGETS}" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
RUN cmake --build ./build --config Release --parallel

FROM rocm/dev-ubuntu-24.04 AS runtime

# ROCm clang links against its own OpenMP runtime in /opt/rocm/llvm/lib,
# and the ROCm runtime libs (hipblas, rocblas, amdhip64) live in /opt/rocm/lib.
ENV LD_LIBRARY_PATH="/opt/rocm/llvm/lib:/opt/rocm/lib:$LD_LIBRARY_PATH"

RUN apt-get update && \
apt-get install --yes --no-install-recommends libgomp1 && \
apt-get clean && rm -rf /var/lib/apt/lists/*

COPY --from=build /sd.cpp/build/bin /sd.cpp/bin
RUN printf '#!/bin/sh\nexec /sd.cpp/bin/sd-cli "$@"\n' > /sd-cli && \
printf '#!/bin/sh\nexec /sd.cpp/bin/sd-server "$@"\n' > /sd-server && \
chmod +x /sd-cli /sd-server

ENTRYPOINT [ "/sd-cli" ]
2 changes: 1 addition & 1 deletion docs/anima.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
## Examples

```sh
.\bin\Release\sd-cli.exe --diffusion-model ..\models\diffusion_models\anima-preview.safetensors --vae ..\models\vae\qwen_image_vae.safetensors --llm ..\models\text_encoders\qwen_3_06b_base.safetensors -p "a lovely cat holding a sign says 'anima.cpp'" --cfg-scale 6.0 --sampling-method euler -v --offload-to-cpu --diffusion-fa
.\bin\Release\sd-cli.exe --diffusion-model ..\models\diffusion_models\anima-preview.safetensors --vae ..\models\vae\qwen_image_vae.safetensors --llm ..\models\text_encoders\qwen_3_06b_base.safetensors -p "a lovely cat holding a sign says 'anima.cpp'" --cfg-scale 6.0 --sampling-method euler -v --offload-to-cpu
```

<img alt="anima image example" src="../assets/anima/example.png" />
6 changes: 3 additions & 3 deletions docs/animatediff.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ SD 1.5 defaults (euler_a, low CFG) produces noise-like output.
.\bin\Release\sd-cli.exe -M vid_gen \
--model ..\models\checkpoints\realisticVisionV60B1.safetensors \
--motion-module ..\models\animatediff\mm_sd15_v3.safetensors \
--offload-to-cpu --diffusion-fa \
--offload-to-cpu \
-p "a red apple on a wooden table" \
--cfg-scale 8.0 --sampling-method euler --scheduler discrete \
-H 512 -W 512 --video-frames 8 --fps 8 --steps 20 -s 42 \
Expand All @@ -66,7 +66,7 @@ use layer streaming:
.\bin\Release\sd-cli.exe -M vid_gen \
--model ..\models\checkpoints\realisticVisionV60B1.safetensors \
--motion-module ..\models\animatediff\mm_sd15_v3.safetensors \
--offload-to-cpu --diffusion-fa \
--offload-to-cpu \
-p "photo of coastline, rocks, storm weather, wind, waves, lightning" \
--cfg-scale 8.0 --sampling-method euler --scheduler discrete \
-H 384 -W 384 --video-frames 16 --fps 8 --steps 20 -s 42 \
Expand All @@ -79,7 +79,7 @@ Low-VRAM streaming (verified with a 2 GiB cap on RTX 3060):
.\bin\Release\sd-cli.exe -M vid_gen \
--model ..\models\checkpoints\realisticVisionV60B1.safetensors \
--motion-module ..\models\animatediff\mm_sd15_v3.safetensors \
--max-vram 2.0 --diffusion-fa \
--max-vram 2.0 \
-p "photo of coastline, rocks, storm weather, wind, waves, lightning" \
--cfg-scale 8.0 --sampling-method euler --scheduler discrete \
-H 384 -W 384 --video-frames 8 --fps 8 --steps 20 -s 42 \
Expand Down
117 changes: 117 additions & 0 deletions docs/backend.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,123 @@ If a VAE decode fails, decoding retries with spatial tiling even when `--auto-fi
is off; supported video decoders try temporal tiling first and can then add
spatial tiling. Spatial retries use half-size tiles along each latent dimension.

## Direct convolution (`--conv-direct on|off|auto`)

`--conv-direct` defaults to `auto` and accepts module assignments for
`diffusion`, `vae` (including preview VAE), and `controlnet`, using the same
aliases and precedence rules as `--flash-attn`:

```shell
sd-cli -m model.safetensors -p "a cat" --conv-direct auto,vae=off
sd-cli -m model.safetensors -p "a cat" --conv-direct off,diffusion=on
```

- `on` requests direct 2D and 3D convolution.
- `off` uses the existing im2col-based convolution paths.
- `auto` first checks support for a representative F16-weight/F32-input direct
convolution graph. Vulkan then benchmarks direct convolution against im2col
using two small shapes per dimension, with warmup, output validation, and five
interleaved measurements per shape. Direct convolution must improve the sum of
median times by at least 5%; a failed probe defaults to `off`.
Other backends retain their implicit GEMM checks without benchmarking:
CUDA 2D requires a compiled Turing-or-newer MMA architecture; HIP 2D requires
the supported CDNA MFMA or RDNA WMMA architectures described below for flash
attention. MUSA 2D has a SIMT implementation. CUDA, HIP, and MUSA 3D also have
a SIMT implementation, so they do not require MMA. Other backends default to
`off`. Results and decision logs are cached per compute backend and dimension
in the context, as with flash attention. Each dimension is selected independently,
and all compute devices in a module must qualify. Parameter-storage devices do
not affect this choice.

These are backend-level defaults. GGML still chooses the actual kernel based on
weight type, shape, and hardware; enabling direct convolution does not guarantee
that every operation uses implicit GEMM. The CUDA-family implicit GEMM paths
require F16 weights and can use ordinary direct kernels for other cases.
This option does not change the separately created image upscaler context.

Repeating `--conv-direct` replaces the previous assignment string. Existing
`--diffusion-conv-direct` (diffusion and ControlNet) and `--vae-conv-direct`
flags are deprecated and emit a warning, but remain supported when
`--conv-direct` is omitted. Use `--conv-direct auto,diffusion=on,controlnet=on`
and `--conv-direct auto,vae=on`, respectively. An explicit
`--conv-direct` takes precedence over both legacy flags regardless of order.
Library callers can set the appended `sd_ctx_params_t::conv_direct_mode` field
to the same string; null or empty selects `auto` while honoring legacy true
flags. The context copies the string.

## Flash attention (`--flash-attn on|off|auto`)

`--flash-attn` defaults to `auto`. Selection happens while creating the model
context, before inference, and is cached once per compute backend in that context.
Parameter-storage backends are not benchmarked.

The option also accepts module assignments, using the same module aliases as
`--backend`:

```shell
sd-cli -m model.safetensors -p "a cat" --flash-attn auto,te=off,vae=on
sd-cli -m model.safetensors -p "a cat" --flash-attn off,diffusion=auto
```

Supported modules are `diffusion`, `te`, `clip_vision`, `vae`, `controlnet`, and
`audio_encoder`. Modules without an assignment use the default (`auto` if no
default is supplied). A bare mode or `all=`, `default=`, or `*=` sets the default;
module-specific settings take precedence regardless of their position. Within
one assignment string, the last setting for the same module or default wins.
Repeating `--flash-attn` replaces the entire previous string.

Only modules set to `auto` need backend probing. An explicit `on` or `off` for
one module does not change another module's decision, even when they share a
backend. Modules without configurable attention are rejected instead of silently
ignoring their settings.

- `on` requests flash attention for all models. Unsupported attention operations
still fall back to ordinary attention.
- `off` disables flash attention, including the flash-attention fallback from
SageAttention. SageAttention itself remains controlled by `--sage-attn`.
- `auto` enables CPU and supported CUDA MMA configurations without timing a
benchmark. CUDA uses both the device's capability and the compiled GGML
architectures. HIP also skips timing on known CDNA MFMA architectures
(`gfx908`, `gfx90a`, `gfx940`/`gfx941`/`gfx942`, `gfx950`) and RDNA 3/3.5/4
WMMA architectures (`gfx11xx`/`gfx12xx`). The CDNA shortcut requires
`GGML_HIP_MMQ_MFMA` to be enabled at build time. All shortcuts still check
support for the FA probe graph. Vulkan devices whose description identifies
NVIDIA RTX hardware (GeForce RTX, TITAN RTX, Quadro RTX and professional RTX)
also skip timing. This is a device-name heuristic and needs no CUDA runtime.
Unsupported graphs are disabled; other configurations, including older or
unknown HIP architectures and other Vulkan devices, are benchmarked.

The probe compares ordinary and flash attention through the same attention
builder used by models, including layout conversion and F16 conversion. It uses
two small self-attention graphs (512 tokens with head size 64, and 1024 tokens
with head size 128, both with four heads), checks their outputs, warms up each
path, then alternates five synchronized measurements. Flash attention is enabled
when the sum of its median times is at least 5% lower. These representative
shapes are a startup heuristic, not a guarantee for every model or resolution.
Allocation/execution failures and inconclusive probes select `off`. Timing stops
starting new measurement pairs after one second of measured computation;
backend initialization, warmup and an in-flight pair can take longer.

Different modules can select different results. A multi-device model enables
flash attention only if all of its compute devices select `on`, preserving the
model's existing single boolean setting. This conservative rule also covers
row-split configurations, which can fall back to layer split during initialization.

`--fa` and `--diffusion-fa` are deprecated and emit a warning when used.
Use `--flash-attn on` and `--flash-attn off,diffusion=on`, respectively.
Both aliases write the same mode string as `--flash-attn`; the last occurrence
of any of these options wins. Library callers
can set `sd_ctx_params_t::flash_attn_mode` to the same string, including
`"on"`, `"off"`, `"auto"`, or `"auto,te=off,vae=on"`.
A null or empty string uses automatic selection unless a
legacy `flash_attn` or `diffusion_flash_attn` boolean is set. The context copies
the string; no new enum is required.

```shell
sd-cli -m model.safetensors -p "a cat" --flash-attn auto
sd-cli -m model.safetensors -p "a cat" --flash-attn off
```

## Modules

| Module | Purpose | Accepted names |
Expand Down
Loading