Skip to content

Commit 371dbba

Browse files
committed
apg: add experimental threshold smoothing parameter
1 parent 9fb432d commit 371dbba

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
lines changed

examples/cli/main.cpp

+16-2
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ struct SDParams {
130130
float apg_eta = 1.0f;
131131
float apg_momentum = 0.0f;
132132
float apg_norm_threshold = 0.0f;
133+
float apg_norm_smoothing = 0.0f;
133134
};
134135

135136
void print_params(SDParams params) {
@@ -214,6 +215,8 @@ void print_usage(int argc, const char* argv[]) {
214215
printf(" --apg-eta VALUE parallel projected guidance scale for APG (default: 1.0, recommended: between 0 and 1)\n");
215216
printf(" --apg-momentum VALUE CFG update direction momentum for APG (default: 0, recommended: around -0.5)\n");
216217
printf(" --apg-nt, --apg-rescale VALUE CFG update direction norm threshold for APG (default: 0 = disabled, recommended: 4-15)\n");
218+
printf(" --apg-nt-smoothing VALUE EXPERIMENTAL! Norm threshold smoothing for APG (default: 0 = disabled)\n");
219+
printf(" (replaces saturation with a smooth approximation)\n");
217220
printf(" --slg-scale SCALE skip layer guidance (SLG) scale, only for DiT models: (default: 0)\n");
218221
printf(" 0 means disabled, a value of 2.5 is nice for sd3.5 medium\n");
219222
printf(" --skip-layers LAYERS Layers to skip for SLG steps: (default: [7,8,9])\n");
@@ -641,6 +644,12 @@ void parse_args(int argc, const char** argv, SDParams& params) {
641644
break;
642645
}
643646
params.apg_norm_threshold = std::stof(argv[i]);
647+
} else if (arg == "--apg-nt-smoothing") {
648+
if (++i >= argc) {
649+
invalid_arg = true;
650+
break;
651+
}
652+
params.apg_norm_smoothing = std::stof(argv[i]);
644653
} else {
645654
fprintf(stderr, "error: unknown argument: %s\n", arg.c_str());
646655
print_usage(argc, argv);
@@ -739,6 +748,9 @@ std::string get_image_params(SDParams params, int64_t seed) {
739748
}
740749
if (params.apg_norm_threshold != 0) {
741750
parameter_string += "CFG normalization threshold: " + std::to_string(params.apg_norm_threshold) + ", ";
751+
if (params.apg_norm_smoothing != 0) {
752+
parameter_string += "CFG normalization threshold: " + std::to_string(params.apg_norm_smoothing) + ", ";
753+
}
742754
}
743755
if (params.slg_scale != 0 && params.skip_layers.size() != 0) {
744756
parameter_string += "SLG scale: " + std::to_string(params.cfg_scale) + ", ";
@@ -989,7 +1001,8 @@ int main(int argc, const char* argv[]) {
9891001
params.skip_layer_end},
9901002
sd_apg_params_t{params.apg_eta,
9911003
params.apg_momentum,
992-
params.apg_norm_threshold});
1004+
params.apg_norm_threshold,
1005+
params.apg_norm_smoothing});
9931006
} else {
9941007
sd_image_t input_image = {(uint32_t)params.width,
9951008
(uint32_t)params.height,
@@ -1060,7 +1073,8 @@ int main(int argc, const char* argv[]) {
10601073
params.skip_layer_end},
10611074
sd_apg_params_t{params.apg_eta,
10621075
params.apg_momentum,
1063-
params.apg_norm_threshold});
1076+
params.apg_norm_threshold,
1077+
params.apg_norm_smoothing});
10641078
}
10651079
}
10661080

stable-diffusion.cpp

+9-3
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ class StableDiffusionGGML {
797797
int start_merge_step,
798798
SDCondition id_cond,
799799
sd_slg_params_t slg_params = {NULL, 0, 0, 0, 0},
800-
sd_apg_params_t apg_params = {1, 0, 0},
800+
sd_apg_params_t apg_params = {1, 0, 0, 0},
801801
ggml_tensor* noise_mask = nullptr) {
802802
std::vector<int> skip_layers(slg_params.skip_layers, slg_params.skip_layers + slg_params.skip_layers_count);
803803

@@ -976,8 +976,14 @@ class StableDiffusionGGML {
976976
deltas[i] = delta;
977977
}
978978
if (apg_params.norm_treshold > 0) {
979-
diff_norm = sqrtf(diff_norm);
980-
apg_scale_factor = std::min(1.0f, apg_params.norm_treshold / diff_norm);
979+
diff_norm = sqrtf(diff_norm);
980+
if (apg_params.norm_treshold_smoothing <= 0) {
981+
apg_scale_factor = std::min(1.0f, apg_params.norm_treshold / diff_norm);
982+
} else {
983+
// Experimental: smooth saturate
984+
float x = apg_params.norm_treshold / diff_norm;
985+
apg_scale_factor = x / std::pow(1 + std::pow(x, 1.0 / apg_params.norm_treshold_smoothing), apg_params.norm_treshold_smoothing);
986+
}
981987
}
982988
if (apg_params.eta != 1.0f) {
983989
dot *= apg_scale_factor;

stable-diffusion.h

+1
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ typedef struct {
126126
float eta;
127127
float momentum;
128128
float norm_treshold;
129+
float norm_treshold_smoothing;
129130
} sd_apg_params_t;
130131

131132
typedef struct {

0 commit comments

Comments
 (0)