Skip to content

Commit bc79fb6

Browse files
committed
apg: add experimental threshold smoothing parameter
1 parent 950b326 commit bc79fb6

File tree

3 files changed

+27
-7
lines changed

3 files changed

+27
-7
lines changed

examples/cli/main.cpp

+17-4
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ struct SDParams {
140140
float apg_eta = 1.0f;
141141
float apg_momentum = 0.0f;
142142
float apg_norm_threshold = 0.0f;
143+
float apg_norm_smoothing = 0.0f;
143144

144145
sd_preview_t preview_method = SD_PREVIEW_NONE;
145146
int preview_interval = 1;
@@ -233,8 +234,9 @@ void print_usage(int argc, const char* argv[]) {
233234
printf(" --apg-eta VALUE parallel projected guidance scale for APG (default: 1.0, recommended: between 0 and 1)\n");
234235
printf(" --apg-momentum VALUE CFG update direction momentum for APG (default: 0, recommended: around -0.5)\n");
235236
printf(" --apg-nt, --apg-rescale VALUE CFG update direction norm threshold for APG (default: 0 = disabled, recommended: 4-15)\n");
236-
printf(" --slg-scale SCALE skip layer guidance (SLG) scale, only for DiT models: (default: 0)\n");
237-
printf(" 0 means disabled, a value of 2.5 is nice for sd3.5 medium\n");
237+
printf(" --apg-nt-smoothing VALUE EXPERIMENTAL! Norm threshold smoothing for APG (default: 0 = disabled)\n");
238+
printf(" (replaces saturation with a smooth approximation)\n");
239+
printf(" --slg-scale SCALE skip layer guidance (SLG) scale, only for DiT models: (default: 0)0 means disabled, a value of 2.5 is nice for sd3.5 medium\n");
238240
printf(" --eta SCALE eta in DDIM, only for DDIM and TCD: (default: 0)\n");
239241
printf(" --skip-layers LAYERS Layers to skip for SLG steps: (default: [7,8,9])\n");
240242
printf(" --skip-layer-start START SLG enabling point: (default: 0.01)\n");
@@ -673,6 +675,12 @@ void parse_args(int argc, const char** argv, SDParams& params) {
673675
break;
674676
}
675677
params.apg_norm_threshold = std::stof(argv[i]);
678+
} else if (arg == "--apg-nt-smoothing") {
679+
if (++i >= argc) {
680+
invalid_arg = true;
681+
break;
682+
}
683+
params.apg_norm_smoothing = std::stof(argv[i]);
676684
} else if (arg == "--preview") {
677685
if (++i >= argc) {
678686
invalid_arg = true;
@@ -800,6 +808,9 @@ std::string get_image_params(SDParams params, int64_t seed) {
800808
}
801809
if (params.apg_norm_threshold != 0) {
802810
parameter_string += "CFG normalization threshold: " + std::to_string(params.apg_norm_threshold) + ", ";
811+
if (params.apg_norm_smoothing != 0) {
812+
parameter_string += "CFG normalization threshold: " + std::to_string(params.apg_norm_smoothing) + ", ";
813+
}
803814
}
804815
if (params.slg_scale != 0 && params.skip_layers.size() != 0) {
805816
parameter_string += "SLG scale: " + std::to_string(params.cfg_scale) + ", ";
@@ -1061,7 +1072,8 @@ int main(int argc, const char* argv[]) {
10611072
params.skip_layer_end},
10621073
sd_apg_params_t{params.apg_eta,
10631074
params.apg_momentum,
1064-
params.apg_norm_threshold});
1075+
params.apg_norm_threshold,
1076+
params.apg_norm_smoothing});
10651077
} else {
10661078
sd_image_t input_image = {(uint32_t)params.width,
10671079
(uint32_t)params.height,
@@ -1133,7 +1145,8 @@ int main(int argc, const char* argv[]) {
11331145
params.skip_layer_end},
11341146
sd_apg_params_t{params.apg_eta,
11351147
params.apg_momentum,
1136-
params.apg_norm_threshold});
1148+
params.apg_norm_threshold,
1149+
params.apg_norm_smoothing});
11371150
}
11381151
}
11391152

stable-diffusion.cpp

+9-3
Original file line numberDiff line numberDiff line change
@@ -923,7 +923,7 @@ class StableDiffusionGGML {
923923
int start_merge_step,
924924
SDCondition id_cond,
925925
sd_slg_params_t slg_params = {NULL, 0, 0, 0, 0},
926-
sd_apg_params_t apg_params = {1, 0, 0},
926+
sd_apg_params_t apg_params = {1, 0, 0, 0},
927927
ggml_tensor* noise_mask = nullptr) {
928928
std::vector<int> skip_layers(slg_params.skip_layers, slg_params.skip_layers + slg_params.skip_layers_count);
929929
size_t steps = sigmas.size() - 1;
@@ -1099,8 +1099,14 @@ class StableDiffusionGGML {
10991099
deltas[i] = delta;
11001100
}
11011101
if (apg_params.norm_treshold > 0) {
1102-
diff_norm = sqrtf(diff_norm);
1103-
apg_scale_factor = std::min(1.0f, apg_params.norm_treshold / diff_norm);
1102+
diff_norm = sqrtf(diff_norm);
1103+
if (apg_params.norm_treshold_smoothing <= 0) {
1104+
apg_scale_factor = std::min(1.0f, apg_params.norm_treshold / diff_norm);
1105+
} else {
1106+
// Experimental: smooth saturate
1107+
float x = apg_params.norm_treshold / diff_norm;
1108+
apg_scale_factor = x / std::pow(1 + std::pow(x, 1.0 / apg_params.norm_treshold_smoothing), apg_params.norm_treshold_smoothing);
1109+
}
11041110
}
11051111
if (apg_params.eta != 1.0f) {
11061112
dot *= apg_scale_factor;

stable-diffusion.h

+1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ typedef struct {
131131
float eta;
132132
float momentum;
133133
float norm_treshold;
134+
float norm_treshold_smoothing;
134135
} sd_apg_params_t;
135136

136137
typedef struct {

0 commit comments

Comments
 (0)