Skip to content

Commit afd305e

Browse files
committed
add progress and warning/error display
- add management of shared library - update glove
1 parent 43a1f89 commit afd305e

File tree

12 files changed

+7882
-7253
lines changed

12 files changed

+7882
-7253
lines changed

CMakeLists.txt

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ option(SD_FLASH_ATTN "sd: use flash attention for x4 less memory
3333
option(SD_FAST_SOFTMAX "sd: x1.5 faster softmax, indeterministic (sometimes, same seed don't generate same image), cuda only" OFF)
3434
option(SD_BUILD_SHARED_LIBS "sd: build shared libs" OFF)
3535
#option(SD_BUILD_SERVER "sd: build server example" ON)
36-
option(SD_EXAMPLES_GLOVE_GUI "sd: use glove gui in examples" OFF)
36+
option(SD_EXAMPLES_GLOVE_GUI "sd: use glove gui for examples" OFF)
37+
option(SD_EXAMPLES_GLOVE_GUI_DESKTOP "sd: if SD_EXAMPLES_GLOVE_GUI, gui is configured as autonomous desktop application" ON)
3738
set(QT_VERSION "6" CACHE STRING "Qt version")
3839
set_property(CACHE QT_VERSION PROPERTY STRINGS 5 6)
3940

@@ -77,11 +78,20 @@ file(GLOB SD_LIB_SOURCES
7778
"*.hpp"
7879
)
7980

81+
if(SD_BUILD_EXAMPLES AND SD_EXAMPLES_GLOVE_GUI)
82+
set(CMAKE_INCLUDE_CURRENT_DIR ON)
83+
set(CMAKE_AUTOMOC ON)
84+
find_package(Qt${QT_VERSION} COMPONENTS Widgets REQUIRED)
85+
endif()
86+
8087
# we can get only one share lib
8188
if(SD_BUILD_SHARED_LIBS)
8289
message("-- Build shared library")
8390
message(${SD_LIB_SOURCES})
8491
set(BUILD_SHARED_LIBS OFF)
92+
if(SD_EXAMPLES_GLOVE_GUI)
93+
set(SD_LIB_SOURCES ${SD_LIB_SOURCES} ${CMAKE_SOURCE_DIR}/thirdparty/glove.h)
94+
endif()
8595
add_library(${SD_LIB} SHARED ${SD_LIB_SOURCES})
8696
add_definitions(-DSD_BUILD_SHARED_LIB)
8797
target_compile_definitions(${SD_LIB} PRIVATE -DSD_BUILD_DLL)
@@ -92,6 +102,12 @@ else()
92102
add_library(${SD_LIB} STATIC ${SD_LIB_SOURCES})
93103
endif()
94104

105+
if(SD_EXAMPLES_GLOVE_GUI)
106+
target_link_libraries(${SD_LIB} PRIVATE Qt${QT_VERSION}::Widgets)
107+
target_compile_definitions(${SD_LIB} PUBLIC -D SD_EXAMPLES_GLOVE_GUI)
108+
qt_disable_unicode_defines(stable-diffusion)
109+
endif()
110+
95111
if(SD_SYCL)
96112
message("-- Use SYCL as backend stable-diffusion")
97113
set(GGML_SYCL ON)
@@ -107,12 +123,6 @@ if(SD_SYCL)
107123
target_compile_options(${SD_LIB} PRIVATE ${SYCL_COMPILE_OPTIONS})
108124
endif()
109125

110-
if(SD_BUILD_EXAMPLES AND SD_EXAMPLES_GLOVE_GUI)
111-
set(CMAKE_INCLUDE_CURRENT_DIR ON)
112-
set(CMAKE_AUTOMOC ON)
113-
find_package(Qt${QT_VERSION} COMPONENTS Widgets REQUIRED)
114-
endif()
115-
116126
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
117127

118128
# see https://github.com/ggerganov/ggml/pull/682

README.md

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# stable-diffusion.cpp : GUI of command line interface
22

3-
This repository is a fork of [stable-diffusion.cpp](https://github.com/leejet/stable-diffusion.cpp). It only adds a GUI interface to the executable generating examples. It will be updated according to the master repository developments (evolution of the parameters).
3+
This repository is a fork of [stable-diffusion.cpp](https://github.com/leejet/stable-diffusion.cpp). It adds a GUI interface to the executable generating examples. It will be updated according to the master repository developments (evolution of the parameters).
44

55
<p align="center">
66
<img src="./assets/sd-example.png" width="360x">
@@ -13,12 +13,8 @@ This repository is a fork of [stable-diffusion.cpp](https://github.com/leejet/st
1313
```cmake
1414
-DSD_BUILD_EXAMPLES=ON -DSD_EXAMPLES_GLOVE_GUI=ON
1515
```
16-
17-
then instead of CLI arguments use:
18-
19-
```sh
20-
sd -glove
21-
```
16+
17+
## Features
2218

2319
- Parameters saving as *json*, upon acceptance (*Ok* button):
2420

@@ -31,8 +27,33 @@ This repository is a fork of [stable-diffusion.cpp](https://github.com/leejet/st
3127
- Parameters can be loaded
3228
- by using the *Load* button
3329
- or: <code>sd -glove 'path-to-parameters-file'</code>
30+
31+
- Progress :
32+
33+
- Monitoring of progression
34+
- Possibility to cancel
35+
36+
<p align="center">
37+
<img src="./assets/sd-example-progress.png" width="200x">
38+
</p>
39+
40+
- Warning/error messages display
41+
42+
## Misc
43+
44+
- By default, the setup is configured for a desktop application (i.e. : launch using executable icon on desktop).
45+
One can disable this default behaviour by additionaly setting the following CMake command:
46+
```cmake
47+
-DSD_EXAMPLES_GLOVE_GUI_DESKTOP=OFF
48+
```
49+
In this case, the GUI will be accessible using the following CLI argument:
50+
```sh
51+
sd -glove
52+
```
53+
and the terminal will be visible.
54+
3455

35-
- On Windows, if DLLs are missing, go to the <code>sd</code> executable directory and do:
56+
- On Windows, if DLLs are missing, go to the <code>sd</code> executable directory and apply the command:
3657

3758
```sh
3859
windeployqt.exe sd.exe

assets/sd-example-progress.png

6.67 KB
Loading

assets/sd-example.png

3.87 KB
Loading

denoiser.hpp

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
#include "ggml_extend.hpp"
55
#include "gits_noise.inl"
66

7+
#ifdef SD_EXAMPLES_GLOVE_GUI
8+
#include "glove.h"
9+
#endif
10+
711
/*================================================= CompVisDenoiser ==================================================*/
812

913
// Ref: https://github.com/crowsonkb/k-diffusion/blob/master/k_diffusion/external.py
@@ -482,7 +486,9 @@ static void sample_k_diffusion(sample_method_t method,
482486
struct ggml_tensor* noise = ggml_dup_tensor(work_ctx, x);
483487
struct ggml_tensor* d = ggml_dup_tensor(work_ctx, x);
484488

485-
for (int i = 0; i < steps; i++) {
489+
SlvProgressionQt& p = *GlvApp::get_progression("Generating image");
490+
for (p = 0; p << steps; p++) {
491+
int i = p;
486492
float sigma = sigmas[i];
487493

488494
// denoise
@@ -535,7 +541,9 @@ static void sample_k_diffusion(sample_method_t method,
535541
{
536542
struct ggml_tensor* d = ggml_dup_tensor(work_ctx, x);
537543

538-
for (int i = 0; i < steps; i++) {
544+
SlvProgressionQt& p = *GlvApp::get_progression("Generating image");
545+
for (p = 0; p << steps; p++) {
546+
int i = p;
539547
float sigma = sigmas[i];
540548

541549
// denoise
@@ -568,7 +576,9 @@ static void sample_k_diffusion(sample_method_t method,
568576
struct ggml_tensor* d = ggml_dup_tensor(work_ctx, x);
569577
struct ggml_tensor* x2 = ggml_dup_tensor(work_ctx, x);
570578

571-
for (int i = 0; i < steps; i++) {
579+
SlvProgressionQt& p = *GlvApp::get_progression("Generating image");
580+
for (p = 0; p << steps; p++) {
581+
int i = p;
572582
// denoise
573583
ggml_tensor* denoised = model(x, sigmas[i], -(i + 1));
574584

@@ -618,7 +628,9 @@ static void sample_k_diffusion(sample_method_t method,
618628
struct ggml_tensor* d = ggml_dup_tensor(work_ctx, x);
619629
struct ggml_tensor* x2 = ggml_dup_tensor(work_ctx, x);
620630

621-
for (int i = 0; i < steps; i++) {
631+
SlvProgressionQt& p = *GlvApp::get_progression("Generating image");
632+
for (p = 0; p << steps; p++) {
633+
int i = p;
622634
// denoise
623635
ggml_tensor* denoised = model(x, sigmas[i], i + 1);
624636

@@ -671,7 +683,9 @@ static void sample_k_diffusion(sample_method_t method,
671683
struct ggml_tensor* d = ggml_dup_tensor(work_ctx, x);
672684
struct ggml_tensor* x2 = ggml_dup_tensor(work_ctx, x);
673685

674-
for (int i = 0; i < steps; i++) {
686+
SlvProgressionQt& p = *GlvApp::get_progression("Generating image");
687+
for (p = 0; p << steps; p++) {
688+
int i = p;
675689
// denoise
676690
ggml_tensor* denoised = model(x, sigmas[i], i + 1);
677691

@@ -745,7 +759,9 @@ static void sample_k_diffusion(sample_method_t method,
745759

746760
auto t_fn = [](float sigma) -> float { return -log(sigma); };
747761

748-
for (int i = 0; i < steps; i++) {
762+
SlvProgressionQt& p = *GlvApp::get_progression("Generating image");
763+
for (p = 0; p << steps; p++) {
764+
int i = p;
749765
// denoise
750766
ggml_tensor* denoised = model(x, sigmas[i], i + 1);
751767

@@ -784,7 +800,9 @@ static void sample_k_diffusion(sample_method_t method,
784800

785801
auto t_fn = [](float sigma) -> float { return -log(sigma); };
786802

787-
for (int i = 0; i < steps; i++) {
803+
SlvProgressionQt& p = *GlvApp::get_progression("Generating image");
804+
for (p = 0; p << steps; p++) {
805+
int i = p;
788806
// denoise
789807
ggml_tensor* denoised = model(x, sigmas[i], i + 1);
790808

@@ -827,7 +845,9 @@ static void sample_k_diffusion(sample_method_t method,
827845
ggml_tensor* x_next = x;
828846
std::vector<ggml_tensor*> buffer_model;
829847

830-
for (int i = 0; i < steps; i++) {
848+
SlvProgressionQt& p = *GlvApp::get_progression("Generating image");
849+
for (p = 0; p << steps; p++) {
850+
int i = p;
831851
float sigma = sigmas[i];
832852
float sigma_next = sigmas[i + 1];
833853

@@ -905,7 +925,9 @@ static void sample_k_diffusion(sample_method_t method,
905925
std::vector<ggml_tensor*> buffer_model;
906926
ggml_tensor* x_next = x;
907927

908-
for (int i = 0; i < steps; i++) {
928+
SlvProgressionQt& p = *GlvApp::get_progression("Generating image");
929+
for (p = 0; p << steps; p++) {
930+
int i = p;
909931
float sigma = sigmas[i];
910932
float t_next = sigmas[i + 1];
911933

@@ -978,7 +1000,9 @@ static void sample_k_diffusion(sample_method_t method,
9781000
struct ggml_tensor* noise = ggml_dup_tensor(work_ctx, x);
9791001
struct ggml_tensor* d = ggml_dup_tensor(work_ctx, x);
9801002

981-
for (int i = 0; i < steps; i++) {
1003+
SlvProgressionQt& p = *GlvApp::get_progression("Generating image");
1004+
for (p = 0; p << steps; p++) {
1005+
int i = p;
9821006
float sigma = sigmas[i];
9831007

9841008
// denoise

examples/cli/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ set(TARGET sd)
33
if(SD_EXAMPLES_GLOVE_GUI)
44
add_executable(${TARGET} main.cpp main_glove.h ${CMAKE_SOURCE_DIR}/thirdparty/glove.h)
55
target_compile_definitions(${TARGET} PUBLIC -D SD_EXAMPLES_GLOVE_GUI)
6+
if(SD_EXAMPLES_GLOVE_GUI_DESKTOP)
7+
target_compile_definitions(${TARGET} PUBLIC -D SD_EXAMPLES_GLOVE_GUI_DESKTOP)
8+
endif()
69
target_link_libraries(${TARGET} PRIVATE stable-diffusion ${CMAKE_THREAD_LIBS_INIT} Qt${QT_VERSION}::Widgets)
710
if(MSVC)
811
target_compile_options(${TARGET} PUBLIC /bigobj)

examples/cli/main.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -543,18 +543,27 @@ void parse_args(int argc, const char** argv, SDParams& params) {
543543

544544
if (params.mode != CONVERT && params.mode != IMG2VID && params.prompt.length() == 0) {
545545
fprintf(stderr, "error: the following arguments are required: prompt\n");
546+
#ifdef SD_EXAMPLES_GLOVE_GUI
547+
GlvApp::show(SlvStatus(SlvStatus::statusType::warning, "error: the following arguments are required: prompt\n"), true);
548+
#endif
546549
print_usage(argc, argv);
547550
exit(1);
548551
}
549552

550553
if (params.model_path.length() == 0 && params.diffusion_model_path.length() == 0) {
551554
fprintf(stderr, "error: the following arguments are required: model_path/diffusion_model\n");
555+
#ifdef SD_EXAMPLES_GLOVE_GUI
556+
GlvApp::show(SlvStatus(SlvStatus::statusType::warning, "error: the following arguments are required: model_path/diffusion_model\n"), true);
557+
#endif
552558
print_usage(argc, argv);
553559
exit(1);
554560
}
555561

556562
if ((params.mode == IMG2IMG || params.mode == IMG2VID) && params.input_path.length() == 0) {
557563
fprintf(stderr, "error: when using the img2img mode, the following arguments are required: init-img\n");
564+
#ifdef SD_EXAMPLES_GLOVE_GUI
565+
GlvApp::show(SlvStatus(SlvStatus::statusType::warning, "error: when using the img2img mode, the following arguments are required: init-img\n"), true);
566+
#endif
558567
print_usage(argc, argv);
559568
exit(1);
560569
}
@@ -675,12 +684,30 @@ void sd_log_cb(enum sd_log_level_t level, const char* log, void* data) {
675684

676685
#ifdef SD_EXAMPLES_GLOVE_GUI
677686
#include "main_glove.h"
687+
#ifdef SD_EXAMPLES_GLOVE_GUI_DESKTOP
688+
#pragma GLOVE_APP_MSVC_NO_CONSOLE
689+
#endif
678690
#endif
679691

680692
int main(int argc, char* argv[]) {
681693

682694
#ifdef SD_EXAMPLES_GLOVE_GUI
683-
GLOVE_CLI(GlvSDParams);
695+
GlvApp::get_progression("Model");
696+
GlvApp::get_progression("clip_l");
697+
GlvApp::get_progression("t5xxl");
698+
GlvApp::get_progression("diffusion-model");
699+
GlvApp::get_progression("VAE");
700+
GlvApp::get_progression("LoRA");
701+
GlvApp::get_progression("Batch");
702+
GlvApp::get_progression("Generating image")->set_recurrent(true);
703+
GlvApp::get_progression("Decoding");
704+
GlvApp::get_progression("Result");
705+
706+
#ifdef SD_EXAMPLES_GLOVE_GUI_DESKTOP
707+
GLOVE_APP_PARAM_AUTO(GlvSDParams);
708+
#else
709+
GLOVE_APP_PARAM(GlvSDParams);
710+
#endif
684711
#endif
685712

686713
SDParams params;
@@ -943,7 +970,10 @@ int main(int argc, char* argv[]) {
943970

944971
size_t last = params.output_path.find_last_of(".");
945972
std::string dummy_name = last != std::string::npos ? params.output_path.substr(0, last) : params.output_path;
946-
for (int i = 0; i < params.batch_count; i++) {
973+
GlvApp::get_progression("Result")->set_message("Saving images");
974+
SlvProgressionQt& p = *GlvApp::get_progression("Result");
975+
for (p = 0; p << params.batch_count; p++) {
976+
int i = p;
947977
if (results[i].data == NULL) {
948978
continue;
949979
}

examples/cli/main_glove.h

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11

2+
#pragma once
3+
24
#define GLOVE_ENABLE_JSON
35
#include "glove.h"
46

@@ -31,31 +33,34 @@ glvm_parametrization(GlvSDParamsAdvanced, "Advanced params",
3133
color, bool, "--color", "colors the logging tags according to level", false,
3234
verbose, bool, "--verbose", "print extra info", false);
3335

36+
glvm_parametrization(GlvSDModelAddons, "SD model addons",
37+
clip_l, SlvFile, "--clip_l", "path to the clip-l text encoder", SlvFile(SlvFile::IO::Read),
38+
t5xxl, SlvFile, "--t5xxl", "path to the the t5xxl text encoder", SlvFile(SlvFile::IO::Read),
39+
vae, SlvFile, "--vae", "path to vae", SlvFile("", SlvFileExtensions({".safetensors", ".sft"}), SlvFile::IO::Read),
40+
lora_model_dir, SlvDirectory, "--lora-model-dir", "lora model directory", SlvDirectory())
41+
3442
glvm_parametrization(GlvSDParams, "SD params",
35-
mode, ProcessingMode, "--mode", "run mode (txt2img or img2img or convert, default: txt2img)", ProcessingMode::text_to_image,
36-
model, SlvFile, "--model", "path to full model", SlvFile("./", SlvFileExtensions({".safetensors", ".ckpt"}), SlvFile::IO::Read),
37-
diffusion_model, SlvFile, "--diffusion-model", "path to the standalone diffusion model", SlvFile(SlvFileExtensions({".gguf"}), SlvFile::IO::Read),
38-
clip_l, SlvFile, "--clip_l", "path to the clip-l text encoder", SlvFile(SlvFile::IO::Read),
39-
t5xxl, SlvFile, "--t5xxl", "path to the the t5xxl text encoder", SlvFile(SlvFile::IO::Read),
40-
vae, SlvFile, "--vae", "path to vae", SlvFile("", SlvFileExtensions({".safetensors", ".sft"}), SlvFile::IO::Read),
41-
photomaker_params, GlvSDParamsPhotomaker, "Photomaker", "", GlvSDParamsPhotomaker(),
42-
lora_model_dir, SlvDirectory, "--lora-model-dir", "lora model directory", SlvDirectory(),
43-
init_img, SlvFile, "--init-img", "path to the input image, required by img2img", SlvFile(SlvFile::IO::Read),
44-
control_img, SlvFile, "--control-image", "path to image condition, control net", SlvFile(SlvFile::IO::Read),
45-
output, SlvFile, "--output", "path to write result image to (default: ./output.png)", SlvFile("./output.png", SlvFileExtensions({".png"}), SlvFile::IO::Write),
46-
prompt, std::string, "--prompt", "the prompt to render", "",
47-
negative_prompt, std::string, "--negative-prompt", "the negative prompt (default: '')", "",
48-
cfg_scale, float, "--cfg-scale", "unconditional guidance scale: (default: 7.0)", 7.0f,
49-
strength, float, "--strength", "strength for noising/unnoising (default: 0.75)", 0.75f,
50-
style_ratio, SlvProportion, "--style-ratio", "strength for keeping input identity (default: 20%)", 0.2f,
51-
control_strength, SlvProportion, "--control-strength", "strength to apply Control Net (default: 0.9) \n1.0 corresponds to full destruction of information in init", 0.9f,
52-
height, unsigned int, "--height", "image height, in pixel space (default: 512)", 512,
53-
width, unsigned int, "--width", "image width, in pixel space (default: 512)", 512,
54-
sampling_method, SamplingMethod, "--sampling-method", "{euler, euler_a, heun, dpm2, dpm++2s_a, dpm++2m, dpm++2mv2, ipndm, ipndm_v, lcm} \nsampling method (default: 'euler_a')", SamplingMethod::euler_a,
55-
steps, unsigned int, "--steps", "number of sample steps (default: 20)", 20,
56-
rng, Rng, "--rng", "RNG (default: cuda)", Rng::cuda,
57-
seed, int, "--seed", "RNG seed (default: 42, use random seed for < 0)", 42,
58-
batch_count, unsigned int, "--batch-count", "number of images to generate.", 1,
59-
advanced_params, GlvSDParamsAdvanced, "Advanced", "", GlvSDParamsAdvanced())
60-
61-
GLOVE_CLI_PARAMETRIZATION_OUTPUT_DIRECTORY(GlvSDParams, "--output")
43+
mode, ProcessingMode, "--mode", "run mode (txt2img or img2img or convert, default: txt2img)", ProcessingMode::text_to_image,
44+
model, SlvFile, "--model", "path to full model", SlvFile("./", SlvFileExtensions({".safetensors", ".ckpt"}), SlvFile::IO::Read),
45+
diffusion_model, SlvFile, "--diffusion-model", "path to the standalone diffusion model", SlvFile(SlvFileExtensions({".gguf"}), SlvFile::IO::Read),
46+
model_addons, GlvSDModelAddons, "Model addons", "", GlvSDModelAddons(),
47+
photomaker_params, GlvSDParamsPhotomaker, "Photomaker", "", GlvSDParamsPhotomaker(),
48+
init_img, SlvFile, "--init-img", "path to the input image, required by img2img", SlvFile(SlvFile::IO::Read),
49+
control_img, SlvFile, "--control-image", "path to image condition, control net", SlvFile(SlvFile::IO::Read),
50+
output, SlvFile, "--output", "path to write result image to (default: ./output.png)", SlvFile("./output.png", SlvFileExtensions({".png"}), SlvFile::IO::Write),
51+
prompt, std::string, "--prompt", "the prompt to render", "",
52+
negative_prompt, std::string, "--negative-prompt", "the negative prompt (default: '')", "",
53+
cfg_scale, float, "--cfg-scale", "unconditional guidance scale: (default: 7.0)", 7.0f,
54+
strength, float, "--strength", "strength for noising/unnoising (default: 0.75)", 0.75f,
55+
style_ratio, SlvProportion, "--style-ratio", "strength for keeping input identity (default: 20%)", 0.2f,
56+
control_strength, SlvProportion, "--control-strength", "strength to apply Control Net (default: 0.9) \n1.0 corresponds to full destruction of information in init", 0.9f,
57+
height, unsigned int, "--height", "image height, in pixel space (default: 512)", 512,
58+
width, unsigned int, "--width", "image width, in pixel space (default: 512)", 512,
59+
sampling_method, SamplingMethod, "--sampling-method", "{euler, euler_a, heun, dpm2, dpm++2s_a, dpm++2m, dpm++2mv2, ipndm, ipndm_v, lcm} \nsampling method (default: 'euler_a')", SamplingMethod::euler_a,
60+
steps, unsigned int, "--steps", "number of sample steps (default: 20)", 20,
61+
rng, Rng, "--rng", "RNG (default: cuda)", Rng::cuda,
62+
seed, int, "--seed", "RNG seed (default: 42, use random seed for < 0)", 42,
63+
batch_count, unsigned int, "--batch-count", "number of images to generate.", 1,
64+
advanced_params, GlvSDParamsAdvanced, "Advanced", "", GlvSDParamsAdvanced())
65+
66+
GLOVE_APP_CLI_PARAMETRIZATION_OUTPUT_DIRECTORY(GlvSDParams, "--output")

0 commit comments

Comments
 (0)