Skip to content

Commit d19d4a5

Browse files
committed
Merge branch 'master' into qwen_image
2 parents 94f4f29 + 02af48a commit d19d4a5

10 files changed

Lines changed: 166 additions & 38 deletions

File tree

.github/workflows/build.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ jobs:
149149
runs-on: windows-2025
150150

151151
env:
152-
VULKAN_VERSION: 1.3.261.1
152+
VULKAN_VERSION: 1.4.328.1
153153

154154
strategy:
155155
matrix:
@@ -199,9 +199,9 @@ jobs:
199199
version: 1.11.1
200200
- name: Install Vulkan SDK
201201
id: get_vulkan
202-
if: ${{ matrix.build == 'vulkan' }}
202+
if: ${{ matrix.build == 'vulkan' }} https://sdk.lunarg.com/sdk/download/1.4.328.1/windows/vulkansdk-windows-X64-1.4.328.1.exe
203203
run: |
204-
curl.exe -o $env:RUNNER_TEMP/VulkanSDK-Installer.exe -L "https://sdk.lunarg.com/sdk/download/${env:VULKAN_VERSION}/windows/VulkanSDK-${env:VULKAN_VERSION}-Installer.exe"
204+
curl.exe -o $env:RUNNER_TEMP/VulkanSDK-Installer.exe -L "https://sdk.lunarg.com/sdk/download/${env:VULKAN_VERSION}/windows/vulkansdk-windows-X64-${env:VULKAN_VERSION}.exe"
205205
& "$env:RUNNER_TEMP\VulkanSDK-Installer.exe" --accept-licenses --default-answer --confirm-command install
206206
Add-Content $env:GITHUB_ENV "VULKAN_SDK=C:\VulkanSDK\${env:VULKAN_VERSION}"
207207
Add-Content $env:GITHUB_PATH "C:\VulkanSDK\${env:VULKAN_VERSION}\bin"

Dockerfile

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
ARG UBUNTU_VERSION=22.04
22

3-
FROM ubuntu:$UBUNTU_VERSION as build
3+
FROM ubuntu:$UBUNTU_VERSION AS build
44

5-
RUN apt-get update && apt-get install -y build-essential git cmake
5+
RUN apt-get update && apt-get install -y --no-install-recommends build-essential git cmake
66

77
WORKDIR /sd.cpp
88

99
COPY . .
1010

11-
RUN mkdir build && cd build && cmake .. && cmake --build . --config Release
11+
RUN cmake . -B ./build
12+
RUN cmake --build ./build --config Release --parallel
1213

13-
FROM ubuntu:$UBUNTU_VERSION as runtime
14+
FROM ubuntu:$UBUNTU_VERSION AS runtime
15+
16+
RUN apt-get update && \
17+
apt-get install --yes --no-install-recommends libgomp1 && \
18+
apt-get clean
1419

1520
COPY --from=build /sd.cpp/build/bin/sd /sd
1621

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,7 @@ These projects use `stable-diffusion.cpp` as a backend for their image generatio
449449
- [Local Diffusion](https://github.com/rmatif/Local-Diffusion)
450450
- [sd.cpp-webui](https://github.com/daniandtheweb/sd.cpp-webui)
451451
- [LocalAI](https://github.com/mudler/LocalAI)
452+
- [Neural-Pixel](https://github.com/Luiz-Alcantara/Neural-Pixel)
452453
453454
## Contributors
454455
@@ -473,4 +474,4 @@ Thank you to all the people who have already contributed to stable-diffusion.cpp
473474
- [generative-models](https://github.com/Stability-AI/generative-models/)
474475
- [PhotoMaker](https://github.com/TencentARC/PhotoMaker)
475476
- [Wan2.1](https://github.com/Wan-Video/Wan2.1)
476-
- [Wan2.2](https://github.com/Wan-Video/Wan2.2)
477+
- [Wan2.2](https://github.com/Wan-Video/Wan2.2)

examples/cli/main.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,10 +1107,19 @@ bool load_images_from_dir(const std::string dir,
11071107
return false;
11081108
}
11091109

1110+
std::vector<fs::directory_entry> entries;
11101111
for (const auto& entry : fs::directory_iterator(dir)) {
1111-
if (!entry.is_regular_file())
1112-
continue;
1112+
if (entry.is_regular_file()) {
1113+
entries.push_back(entry);
1114+
}
1115+
}
1116+
1117+
std::sort(entries.begin(), entries.end(),
1118+
[](const fs::directory_entry& a, const fs::directory_entry& b) {
1119+
return a.path().filename().string() < b.path().filename().string();
1120+
});
11131121

1122+
for (const auto& entry : entries) {
11141123
std::string path = entry.path().string();
11151124
std::string ext = entry.path().extension().string();
11161125
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
@@ -1250,7 +1259,7 @@ int main(int argc, const char* argv[]) {
12501259
}
12511260
}
12521261

1253-
if (params.control_net_path.size() > 0 && params.control_image_path.size() > 0) {
1262+
if (params.control_image_path.size() > 0) {
12541263
int width = 0;
12551264
int height = 0;
12561265
control_image.data = load_image(params.control_image_path.c_str(), width, height, params.width, params.height);

flux.hpp

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,7 @@ namespace Flux {
616616
bool guidance_embed = true;
617617
bool flash_attn = true;
618618
bool is_chroma = false;
619+
SDVersion version = VERSION_FLUX;
619620
};
620621

621622
struct Flux : public GGMLBlock {
@@ -850,14 +851,36 @@ namespace Flux {
850851
auto img = process_img(ctx, x);
851852
uint64_t img_tokens = img->ne[1];
852853

853-
if (c_concat != NULL) {
854+
if (params.version == VERSION_FLUX_FILL) {
855+
GGML_ASSERT(c_concat != NULL);
854856
ggml_tensor* masked = ggml_view_4d(ctx, c_concat, c_concat->ne[0], c_concat->ne[1], C, 1, c_concat->nb[1], c_concat->nb[2], c_concat->nb[3], 0);
855857
ggml_tensor* mask = ggml_view_4d(ctx, c_concat, c_concat->ne[0], c_concat->ne[1], 8 * 8, 1, c_concat->nb[1], c_concat->nb[2], c_concat->nb[3], c_concat->nb[2] * C);
856858

857859
masked = process_img(ctx, masked);
858860
mask = process_img(ctx, mask);
859861

860862
img = ggml_concat(ctx, img, ggml_concat(ctx, masked, mask, 0), 0);
863+
} else if (params.version == VERSION_FLEX_2) {
864+
GGML_ASSERT(c_concat != NULL);
865+
ggml_tensor* masked = ggml_view_4d(ctx, c_concat, c_concat->ne[0], c_concat->ne[1], C, 1, c_concat->nb[1], c_concat->nb[2], c_concat->nb[3], 0);
866+
ggml_tensor* mask = ggml_view_4d(ctx, c_concat, c_concat->ne[0], c_concat->ne[1], 1, 1, c_concat->nb[1], c_concat->nb[2], c_concat->nb[3], c_concat->nb[2] * C);
867+
ggml_tensor* control = ggml_view_4d(ctx, c_concat, c_concat->ne[0], c_concat->ne[1], C, 1, c_concat->nb[1], c_concat->nb[2], c_concat->nb[3], c_concat->nb[2] * (C + 1));
868+
869+
masked = ggml_pad(ctx, masked, pad_w, pad_h, 0, 0);
870+
mask = ggml_pad(ctx, mask, pad_w, pad_h, 0, 0);
871+
control = ggml_pad(ctx, control, pad_w, pad_h, 0, 0);
872+
873+
masked = patchify(ctx, masked, patch_size);
874+
mask = patchify(ctx, mask, patch_size);
875+
control = patchify(ctx, control, patch_size);
876+
877+
img = ggml_concat(ctx, img, ggml_concat(ctx, ggml_concat(ctx, masked, mask, 0), control, 0), 0);
878+
} else if (params.version == VERSION_FLUX_CONTROLS) {
879+
GGML_ASSERT(c_concat != NULL);
880+
881+
ggml_tensor* control = ggml_pad(ctx, c_concat, pad_w, pad_h, 0, 0);
882+
control = patchify(ctx, control, patch_size);
883+
img = ggml_concat(ctx, img, control, 0);
861884
}
862885

863886
if (ref_latents.size() > 0) {
@@ -868,6 +891,7 @@ namespace Flux {
868891
}
869892

870893
auto out = forward_orig(ctx, backend, img, context, timestep, y, guidance, pe, mod_index_arange, skip_layers); // [N, num_tokens, C * patch_size * patch_size]
894+
871895
if (out->ne[1] > img_tokens) {
872896
out = ggml_cont(ctx, ggml_permute(ctx, out, 0, 2, 1, 3)); // [num_tokens, N, C * patch_size * patch_size]
873897
out = ggml_view_3d(ctx, out, out->ne[0], out->ne[1], img_tokens, out->nb[1], out->nb[2], 0);
@@ -897,13 +921,18 @@ namespace Flux {
897921
SDVersion version = VERSION_FLUX,
898922
bool flash_attn = false,
899923
bool use_mask = false)
900-
: GGMLRunner(backend, offload_params_to_cpu), use_mask(use_mask) {
924+
: GGMLRunner(backend, offload_params_to_cpu), version(version), use_mask(use_mask) {
925+
flux_params.version = version;
901926
flux_params.flash_attn = flash_attn;
902927
flux_params.guidance_embed = false;
903928
flux_params.depth = 0;
904929
flux_params.depth_single_blocks = 0;
905930
if (version == VERSION_FLUX_FILL) {
906931
flux_params.in_channels = 384;
932+
} else if (version == VERSION_FLUX_CONTROLS) {
933+
flux_params.in_channels = 128;
934+
} else if (version == VERSION_FLEX_2) {
935+
flux_params.in_channels = 196;
907936
}
908937
for (auto pair : tensor_types) {
909938
std::string tensor_name = pair.first;

ggml_extend.hpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -428,18 +428,24 @@ __STATIC_INLINE__ void sd_image_to_tensor(sd_image_t image,
428428

429429
__STATIC_INLINE__ void sd_apply_mask(struct ggml_tensor* image_data,
430430
struct ggml_tensor* mask,
431-
struct ggml_tensor* output) {
431+
struct ggml_tensor* output,
432+
float masked_value = 0.5f) {
432433
int64_t width = output->ne[0];
433434
int64_t height = output->ne[1];
434435
int64_t channels = output->ne[2];
436+
float rescale_mx = mask->ne[0] / output->ne[0];
437+
float rescale_my = mask->ne[1] / output->ne[1];
435438
GGML_ASSERT(output->type == GGML_TYPE_F32);
436439
for (int ix = 0; ix < width; ix++) {
437440
for (int iy = 0; iy < height; iy++) {
438-
float m = ggml_tensor_get_f32(mask, ix, iy);
441+
int mx = (int)(ix * rescale_mx);
442+
int my = (int)(iy * rescale_my);
443+
float m = ggml_tensor_get_f32(mask, mx, my);
439444
m = round(m); // inpaint models need binary masks
440-
ggml_tensor_set_f32(mask, m, ix, iy);
445+
ggml_tensor_set_f32(mask, m, mx, my);
441446
for (int k = 0; k < channels; k++) {
442-
float value = (1 - m) * (ggml_tensor_get_f32(image_data, ix, iy, k) - .5) + .5;
447+
float value = ggml_tensor_get_f32(image_data, ix, iy, k);
448+
value = (1 - m) * (value - masked_value) + masked_value;
443449
ggml_tensor_set_f32(output, value, ix, iy, k);
444450
}
445451
}

model.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,10 +1837,15 @@ SDVersion ModelLoader::get_sd_version() {
18371837
}
18381838

18391839
if (is_flux) {
1840-
is_inpaint = input_block_weight.ne[0] == 384;
1841-
if (is_inpaint) {
1840+
if (input_block_weight.ne[0] == 384) {
18421841
return VERSION_FLUX_FILL;
18431842
}
1843+
if (input_block_weight.ne[0] == 128) {
1844+
return VERSION_FLUX_CONTROLS;
1845+
}
1846+
if (input_block_weight.ne[0] == 196) {
1847+
return VERSION_FLEX_2;
1848+
}
18441849
return VERSION_FLUX;
18451850
}
18461851

model.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ enum SDVersion {
3131
VERSION_SD3,
3232
VERSION_FLUX,
3333
VERSION_FLUX_FILL,
34+
VERSION_FLUX_CONTROLS,
35+
VERSION_FLEX_2,
3436
VERSION_WAN2,
3537
VERSION_WAN2_2_I2V,
3638
VERSION_WAN2_2_TI2V,
@@ -67,7 +69,7 @@ static inline bool sd_version_is_sd3(SDVersion version) {
6769
}
6870

6971
static inline bool sd_version_is_flux(SDVersion version) {
70-
if (version == VERSION_FLUX || version == VERSION_FLUX_FILL) {
72+
if (version == VERSION_FLUX || version == VERSION_FLUX_FILL || version == VERSION_FLUX_CONTROLS || version == VERSION_FLEX_2) {
7173
return true;
7274
}
7375
return false;
@@ -88,7 +90,7 @@ static inline bool sd_version_is_qwen_image(SDVersion version) {
8890
}
8991

9092
static inline bool sd_version_is_inpaint(SDVersion version) {
91-
if (version == VERSION_SD1_INPAINT || version == VERSION_SD2_INPAINT || version == VERSION_SDXL_INPAINT || version == VERSION_FLUX_FILL) {
93+
if (version == VERSION_SD1_INPAINT || version == VERSION_SD2_INPAINT || version == VERSION_SDXL_INPAINT || version == VERSION_FLUX_FILL || version == VERSION_FLEX_2) {
9294
return true;
9395
}
9496
return false;
@@ -108,8 +110,12 @@ static inline bool sd_version_is_unet_edit(SDVersion version) {
108110
return version == VERSION_SD1_PIX2PIX || version == VERSION_SDXL_PIX2PIX;
109111
}
110112

113+
static inline bool sd_version_is_control(SDVersion version) {
114+
return version == VERSION_FLUX_CONTROLS || version == VERSION_FLEX_2;
115+
}
116+
111117
static bool sd_version_is_inpaint_or_unet_edit(SDVersion version) {
112-
return sd_version_is_unet_edit(version) || sd_version_is_inpaint(version);
118+
return sd_version_is_unet_edit(version) || sd_version_is_inpaint(version) || sd_version_is_control(version);
113119
}
114120

115121
enum PMVersion {

0 commit comments

Comments
 (0)