diff --git a/examples/common/common.hpp b/examples/common/common.hpp index e508aba34..558817eea 100644 --- a/examples/common/common.hpp +++ b/examples/common/common.hpp @@ -1749,4 +1749,4 @@ uint8_t* load_image_from_memory(const char* image_bytes, int expected_height = 0, int expected_channel = 3) { return load_image_common(true, image_bytes, len, width, height, expected_width, expected_height, expected_channel); -} +} \ No newline at end of file diff --git a/examples/server/README.md b/examples/server/README.md index 533081af6..6393d841d 100644 --- a/examples/server/README.md +++ b/examples/server/README.md @@ -60,4 +60,63 @@ Context Options: --vae-tile-size tile size for vae tiling, format [X]x[Y] (default: 32x32) --vae-relative-tile-size relative tile size for vae tiling, format [X]x[Y], in fraction of image size if < 1, in number of tiles per dim if >=1 (overrides --vae-tile-size) + +Default Generation Options: + -p, --prompt the prompt to render + -n, --negative-prompt the negative prompt (default: "") + -i, --init-img path to the init image + --end-img path to the end image, required by flf2v + --mask path to the mask image + --control-image path to control image, control net + --control-video path to control video frames, It must be a directory path. The video frames inside should be stored as images in + lexicographical (character) order. For example, if the control video path is + `frames`, the directory contain images such as 00.png, 01.png, ... etc. + --pm-id-images-dir path to PHOTOMAKER input id images dir + --pm-id-embed-path path to PHOTOMAKER v2 id embed + -H, --height image height, in pixel space (default: 512) + -W, --width image width, in pixel space (default: 512) + --steps number of sample steps (default: 20) + --high-noise-steps (high noise) number of sample steps (default: -1 = auto) + --clip-skip ignore last layers of CLIP network; 1 ignores none, 2 ignores one layer (default: -1). <= 0 represents unspecified, + will be 1 for SD1.x, 2 for SD2.x + -b, --batch-count batch count + --video-frames video frames (default: 1) + --fps fps (default: 24) + --timestep-shift shift timestep for NitroFusion models (default: 0). recommended N for NitroSD-Realism around 250 and 500 for + NitroSD-Vibrant + --upscale-repeats Run the ESRGAN upscaler this many times (default: 1) + --upscale-tile-size tile size for ESRGAN upscaling (default: 128) + --cfg-scale unconditional guidance scale: (default: 7.0) + --img-cfg-scale image guidance scale for inpaint or instruct-pix2pix models: (default: same as --cfg-scale) + --guidance distilled guidance scale for models with guidance input (default: 3.5) + --slg-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 + --skip-layer-start SLG enabling point (default: 0.01) + --skip-layer-end SLG disabling point (default: 0.2) + --eta eta in DDIM, only for DDIM and TCD (default: 0) + --high-noise-cfg-scale (high noise) unconditional guidance scale: (default: 7.0) + --high-noise-img-cfg-scale (high noise) image guidance scale for inpaint or instruct-pix2pix models (default: same as --cfg-scale) + --high-noise-guidance (high noise) distilled guidance scale for models with guidance input (default: 3.5) + --high-noise-slg-scale (high noise) skip layer guidance (SLG) scale, only for DiT models: (default: 0) + --high-noise-skip-layer-start (high noise) SLG enabling point (default: 0.01) + --high-noise-skip-layer-end (high noise) SLG disabling point (default: 0.2) + --high-noise-eta (high noise) eta in DDIM, only for DDIM and TCD (default: 0) + --strength strength for noising/unnoising (default: 0.75) + --pm-style-strength + --control-strength strength to apply Control Net (default: 0.9). 1.0 corresponds to full destruction of information in init image + --moe-boundary timestep boundary for Wan2.2 MoE model. (default: 0.875). Only enabled if `--high-noise-steps` is set to -1 + --vace-strength wan vace strength + --increase-ref-index automatically increase the indices of references images based on the order they are listed (starting with 1). + --disable-auto-resize-ref-image disable auto resize of ref images + -s, --seed RNG seed (default: 42, use random seed for < 0) + --sampling-method sampling method, one of [euler, euler_a, heun, dpm2, dpm++2s_a, dpm++2m, dpm++2mv2, ipndm, ipndm_v, lcm, ddim_trailing, + tcd] (default: euler for Flux/SD3/Wan, euler_a otherwise) + --high-noise-sampling-method (high noise) sampling method, one of [euler, euler_a, heun, dpm2, dpm++2s_a, dpm++2m, dpm++2mv2, ipndm, ipndm_v, lcm, + ddim_trailing, tcd] default: euler for Flux/SD3/Wan, euler_a otherwise + --scheduler denoiser sigma scheduler, one of [discrete, karras, exponential, ays, gits, smoothstep, sgm_uniform, simple, lcm], + default: discrete + --skip-layers layers to skip for SLG steps (default: [7,8,9]) + --high-noise-skip-layers (high noise) layers to skip for SLG steps (default: [7,8,9]) + -r, --ref-image reference image for Flux Kontext models (can be used multiple times) + --easycache enable EasyCache for DiT models with optional "threshold,start_percent,end_percent" (default: 0.2,0.15,0.95) ``` \ No newline at end of file diff --git a/examples/server/main.cpp b/examples/server/main.cpp index 3bfaa36d4..90cf484b9 100644 --- a/examples/server/main.cpp +++ b/examples/server/main.cpp @@ -179,17 +179,21 @@ void print_usage(int argc, const char* argv[], const std::vector& op options_list[0].print(); std::cout << "\nContext Options:\n"; options_list[1].print(); + std::cout << "\nDefault Generation Options:\n"; + options_list[2].print(); } -void parse_args(int argc, const char** argv, SDSvrParams& svr_params, SDContextParams& ctx_params) { - std::vector options_vec = {svr_params.get_options(), ctx_params.get_options()}; +void parse_args(int argc, const char** argv, SDSvrParams& svr_params, SDContextParams& ctx_params, SDGenerationParams& default_gen_params) { + std::vector options_vec = {svr_params.get_options(), ctx_params.get_options(), default_gen_params.get_options()}; if (!parse_options(argc, argv, options_vec)) { print_usage(argc, argv, options_vec); exit(svr_params.normal_exit ? 0 : 1); } - if (!svr_params.process_and_check() || !ctx_params.process_and_check(IMG_GEN)) { + if (!svr_params.process_and_check() || + !ctx_params.process_and_check(IMG_GEN) || + !default_gen_params.process_and_check(IMG_GEN, ctx_params.lora_model_dir)) { print_usage(argc, argv, options_vec); exit(1); } @@ -298,7 +302,8 @@ void sd_log_cb(enum sd_log_level_t level, const char* log, void* data) { int main(int argc, const char** argv) { SDSvrParams svr_params; SDContextParams ctx_params; - parse_args(argc, argv, svr_params, ctx_params); + SDGenerationParams default_gen_params; + parse_args(argc, argv, svr_params, ctx_params, default_gen_params); sd_set_log_callback(sd_log_cb, (void*)&svr_params); @@ -306,6 +311,7 @@ int main(int argc, const char** argv) { printf("%s", sd_get_system_info()); printf("%s\n", svr_params.to_string().c_str()); printf("%s\n", ctx_params.to_string().c_str()); + printf("%s\n", default_gen_params.to_string().c_str()); } sd_ctx_params_t sd_ctx_params = ctx_params.to_sd_ctx_params_t(false, false, false); @@ -320,6 +326,23 @@ int main(int argc, const char** argv) { httplib::Server svr; + svr.set_pre_routing_handler([](const httplib::Request& req, httplib::Response& res) { + std::string origin = req.get_header_value("Origin"); + if (origin.empty()) { + origin = "*"; + } + res.set_header("Access-Control-Allow-Origin", origin); + res.set_header("Access-Control-Allow-Credentials", "true"); + res.set_header("Access-Control-Allow-Methods", "*"); + res.set_header("Access-Control-Allow-Headers", "*"); + + if (req.method == "OPTIONS") { + res.status = 204; + return httplib::Server::HandlerResponse::Handled; + } + return httplib::Server::HandlerResponse::Unhandled; + }); + // health svr.Get("/", [&](const httplib::Request&, httplib::Response& res) { res.set_content(R"({"ok":true,"service":"sd-cpp-http"})", "application/json"); @@ -390,11 +413,11 @@ int main(int argc, const char** argv) { out["data"] = json::array(); out["output_format"] = output_format; - SDGenerationParams gen_params; - gen_params.prompt = prompt; - gen_params.width = width; - gen_params.height = height; - gen_params.batch_count = n; + SDGenerationParams gen_params = default_gen_params; + gen_params.prompt = prompt; + gen_params.width = width; + gen_params.height = height; + gen_params.batch_count = n; if (!sd_cpp_extra_args_str.empty() && !gen_params.from_json_str(sd_cpp_extra_args_str)) { res.status = 400; @@ -570,11 +593,11 @@ int main(int argc, const char** argv) { output_compression = 0; } - SDGenerationParams gen_params; - gen_params.prompt = prompt; - gen_params.width = width; - gen_params.height = height; - gen_params.batch_count = n; + SDGenerationParams gen_params = default_gen_params; + gen_params.prompt = prompt; + gen_params.width = width; + gen_params.height = height; + gen_params.batch_count = n; if (!sd_cpp_extra_args_str.empty() && !gen_params.from_json_str(sd_cpp_extra_args_str)) { res.status = 400; @@ -582,6 +605,12 @@ int main(int argc, const char** argv) { return; } + if (!gen_params.process_and_check(IMG_GEN, ctx_params.lora_model_dir)) { + res.status = 400; + res.set_content(R"({"error":"invalid params"})", "application/json"); + return; + } + if (svr_params.verbose) { printf("%s\n", gen_params.to_string().c_str()); }