From 845646b034a12ed844966c84bd7585c8fcb37b7f Mon Sep 17 00:00:00 2001 From: losewayy <1134285612@qq.com> Date: Wed, 21 Oct 2026 23:11:36 +0800 Subject: [PATCH 1/5] feat(server): add ADetailer support to image generation (#2164) --- docs/adetailer.md | 39 +++++- examples/common/common.cpp | 2 +- examples/server/async_jobs.cpp | 4 + examples/server/routes_openai.cpp | 36 ++--- examples/server/routes_sdapi.cpp | 225 +++++++++++++++++++++++++++++- examples/server/routes_sdcpp.cpp | 6 +- examples/server/runtime.cpp | 152 ++++++++++++++++++++ examples/server/runtime.h | 24 ++++ src/detailer.cpp | 38 +++-- src/detailer.h | 50 +++---- 10 files changed, 515 insertions(+), 61 deletions(-) diff --git a/docs/adetailer.md b/docs/adetailer.md index 2bc64df2c0..f42831823c 100644 --- a/docs/adetailer.md +++ b/docs/adetailer.md @@ -1,9 +1,10 @@ # ADetailer `sd-cli` can run a YOLOv8 object detector on an existing or newly generated -image and perform a cropped inpaint pass for every detected object. The first -implementation supports YOLOv8 detection checkpoints. YOLOv8 segmentation and -MediaPipe models are not supported yet. +image, and `sd-server` can run it after image generation. Both perform a cropped +inpaint pass for every detected object. The implementation supports YOLOv8 +detection checkpoints. YOLOv8 segmentation and MediaPipe models are not +supported yet. ## Convert a detector @@ -68,6 +69,36 @@ ADetailer can also run automatically after normal image generation: --extra-ad-args "confidence=0.3,denoising_strength=0.4,inpaint_width=512,inpaint_height=512" ``` +The same options can be supplied when starting `sd-server`. When `--ad-model` is set, its detector runs after OpenAI-compatible and native asynchronous image generation. SDAPI requests enable ADetailer through `alwayson_scripts`, as described below. If no object is detected, the original image is returned unchanged. RGBA output keeps its original alpha channel, including when detected regions are repaired. Detector initialization or detail-pass failures are reported as request failures. + +Server image-generation requests limit base, hires, and detail-pass dimensions to 4096 pixels per side. ADetailer step overrides are limited to 1–100; `steps=0` in `extra_ad_args` keeps inheriting the main generation steps. These limits also apply to inherited dimensions and `extra_ad_args` overrides. Requests exceeding the limits return a parameter error before generation. CLI limits are unchanged. + +### SDAPI requests + +`/sdapi/v1/txt2img` and `/sdapi/v1/img2img` accept the WebUI ADetailer argument format: + +```json +{ + "prompt": "portrait photo", + "alwayson_scripts": { + "ADetailer": { + "args": [true, false, { + "ad_model": "face_yolov8n.pt", + "ad_prompt": "[PROMPT], detailed face", + "ad_use_steps": true, + "ad_steps": 20 + }] + } + } +} +``` + +The detector must be configured at server startup with `--ad-model`. `ad_model` must match that file's basename; the original `.pt` basename is also accepted for a converted detector. Requests cannot load arbitrary detector paths. Omitting the script, setting its first argument to `false`, selecting `"None"`, or setting `ad_tab_enable` to `false` disables detailing. Dictionary-only argument arrays are also accepted. Multiple enabled dictionaries run in order using the configured detector. + +Supported settings include prompts, confidence, mask filtering by area or confidence, mask count and area ratios, dilation/erosion, offsets, mask merging/inversion, blur, denoising strength, masked or full-image inpainting, padding, and optional overrides for inpaint dimensions, steps, CFG, sampler/scheduler, and CLIP skip. The corresponding `ad_use_*` flags control whether overrides apply. Otherwise dimensions, steps, CFG, sampler, scheduler, and CLIP skip inherit the main request. Denoising strength defaults to `0.4`. Pixel mask settings are limited to the larger output dimension, with a minimum limit of 32 and a maximum of 16384 pixels. + +Model/VAE switching, non-default noise multipliers, face restoration, ControlNet, and skipping the initial img2img pass are not supported; active requests for these features return an error. Unknown settings and invalid active values also return errors. During detailing, `/sdapi/v1/progress` remains active with an `adetailer` job; its percentage and preview stay fixed until detailing finishes. + An empty ADetailer prompt inherits the main prompt. `[PROMPT]` inserts the main prompt, `[SEP]` assigns different prompts to consecutive masks, and `[SKIP]` skips the corresponding mask. @@ -82,6 +113,7 @@ All settings other than the detector path and prompts are passed through | `nms` | `0.45` | NMS IoU threshold | | `max_detections` | `100` | Maximum detections retained after NMS | | `mask_k_largest` | `0` | Keep only the largest K masks; zero keeps all | +| `mask_filter_method` | `area` | Rank retained masks by `area` or `confidence` | | `mask_min_ratio` | `0` | Minimum bbox area relative to the image | | `mask_max_ratio` | `1` | Maximum bbox area relative to the image | | `dilate_erode` | `4` | Positive values dilate; negative values erode | @@ -90,6 +122,7 @@ All settings other than the detector path and prompts are passed through | `merge_masks`, `invert_mask` | `false` | Boolean alternatives to `mask_mode` | | `mask_blur` | `4` | Final composite feather radius | | `inpaint_padding` | `32` | Padding around the detected region | +| `inpaint_only_masked` | `true` | Crop to the detected region; `false` uses the full image with the detection mask | | `inpaint_width`, `inpaint_height` | mode-specific | `512x512` after generation; input/output size in `adetailer` mode | | `denoising_strength` | mode-specific | `0.4` after generation; inherits `--strength` in `adetailer` mode | | `steps` | `0` | Detail steps; zero inherits the main generation | diff --git a/examples/common/common.cpp b/examples/common/common.cpp index 9e7851fef1..8a90673960 100644 --- a/examples/common/common.cpp +++ b/examples/common/common.cpp @@ -2219,7 +2219,7 @@ bool SDGenerationParams::from_json_str( if (target_custom_sigmas != nullptr && sample_json.contains("custom_sigmas") && sample_json["custom_sigmas"].is_array() && - !sample_json["custom_sigmas"].empty()) { // empty [] = "not specified", keep server/CLI default + !sample_json["custom_sigmas"].empty()) { // empty [] = "not specified", keep server/CLI default *target_custom_sigmas = sample_json["custom_sigmas"].get>(); } if (sample_json.contains("sample_method") && sample_json["sample_method"].is_string()) { diff --git a/examples/server/async_jobs.cpp b/examples/server/async_jobs.cpp index 7f3c8a1bfc..edd93593c2 100644 --- a/examples/server/async_jobs.cpp +++ b/examples/server/async_jobs.cpp @@ -244,6 +244,10 @@ bool execute_img_gen_job(ServerRuntime& runtime, } clear_preview_callback(); results.adopt(raw_results, num_results); + if (!results.empty() && !apply_server_adetailer(runtime, job.img_gen, params, results)) { + error_message = "ADetailer failed"; + return false; + } } const int num_results = results.count(); diff --git a/examples/server/routes_openai.cpp b/examples/server/routes_openai.cpp index 29dfe313a7..27a7e18f90 100644 --- a/examples/server/routes_openai.cpp +++ b/examples/server/routes_openai.cpp @@ -75,7 +75,7 @@ static bool build_openai_generation_request(const httplib::Request& req, error_message = "invalid params"; return false; } - return true; + return validate_server_img_gen_request(runtime, request, error_message); } static bool build_openai_edit_request(const httplib::Request& req, @@ -158,22 +158,22 @@ static bool build_openai_edit_request(const httplib::Request& req, request.gen_params.height = height; request.gen_params.batch_count = n; - std::string sd_cpp_extra_args_str = extract_and_remove_sd_cpp_extra_args(request.gen_params.prompt); - const json extra_args = sd_cpp_extra_args_str.empty() - ? json::object() - : json::parse(sd_cpp_extra_args_str, nullptr, false); - const bool has_extra_init_image_override = extra_args.is_object() && extra_args.contains("init_image"); - const bool has_extra_ref_images_override = extra_args.is_object() && extra_args.contains("ref_images"); - const bool has_extra_strength_override = extra_args.is_object() && - extra_args.contains("strength") && - extra_args["strength"].is_number(); - const bool has_extra_mask_image = extra_args.is_object() && - extra_args.contains("mask_image") && - !extra_args["mask_image"].is_null(); + std::string sd_cpp_extra_args_str = extract_and_remove_sd_cpp_extra_args(request.gen_params.prompt); + const json extra_args = sd_cpp_extra_args_str.empty() + ? json::object() + : json::parse(sd_cpp_extra_args_str, nullptr, false); + const bool has_extra_init_image_override = extra_args.is_object() && extra_args.contains("init_image"); + const bool has_extra_ref_images_override = extra_args.is_object() && extra_args.contains("ref_images"); + const bool has_extra_strength_override = extra_args.is_object() && + extra_args.contains("strength") && + extra_args["strength"].is_number(); + const bool has_extra_mask_image = extra_args.is_object() && + extra_args.contains("mask_image") && + !extra_args["mask_image"].is_null(); const bool supports_ref_image_conditioning = sd_ctx_supports_ref_image_conditioning(runtime.sd_ctx); const bool may_need_uploaded_init_image = !has_extra_init_image_override && - (!supports_ref_image_conditioning || !mask_bytes.empty() || - has_extra_mask_image || has_extra_strength_override || has_extra_ref_images_override); + (!supports_ref_image_conditioning || !mask_bytes.empty() || + has_extra_mask_image || has_extra_strength_override || has_extra_ref_images_override); SDImageOwner uploaded_image_for_init; bool uploaded_image_was_first_reference = false; for (auto& bytes : images_bytes) { @@ -252,7 +252,7 @@ static bool build_openai_edit_request(const httplib::Request& req, return false; } - return true; + return validate_server_img_gen_request(runtime, request, error_message); } static bool execute_sync_img_gen_request(ServerRuntime& runtime, @@ -270,6 +270,10 @@ static bool execute_sync_img_gen_request(ServerRuntime& runtime, num_results = 0; } results.adopt(raw_results, num_results); + if (!results.empty() && !apply_server_adetailer(runtime, request, img_gen_params, results)) { + error_message = "ADetailer failed"; + return false; + } } if (results.empty()) { diff --git a/examples/server/routes_sdapi.cpp b/examples/server/routes_sdapi.cpp index 4b8e7a5b1e..014b0b5f89 100644 --- a/examples/server/routes_sdapi.cpp +++ b/examples/server/routes_sdapi.cpp @@ -3,9 +3,12 @@ #include #include #include +#include #include +#include #include #include +#include #include "common/common.h" #include "common/media_io.h" @@ -81,6 +84,202 @@ static enum sample_method_t get_sdapi_sample_method(std::string name) { return it != hardcoded.end() ? it->second : SAMPLE_METHOD_COUNT; } +static bool parse_sdapi_adetailer(const json& body, + ServerRuntime& runtime, + bool img2img, + ImgGenJobRequest& request, + std::string& error_message) { + request.adetailer_enabled = false; + request.adetailer_passes.clear(); + if (!body.contains("alwayson_scripts")) { + return true; + } + try { + const auto& scripts = body.at("alwayson_scripts"); + if (!scripts.is_object()) { + throw std::invalid_argument("alwayson_scripts must be an object"); + } + if (!scripts.contains("ADetailer")) { + return true; + } + const auto& args = scripts.at("ADetailer").at("args"); + if (!args.is_array()) { + throw std::invalid_argument("ADetailer.args must be an array"); + } + if (args.empty() || (args[0].is_boolean() && !args[0].get())) { + return true; + } + static const std::unordered_set keys = { + "ad_model", "ad_model_classes", "ad_tab_enable", "ad_prompt", "ad_negative_prompt", + "ad_confidence", "ad_mask_filter_method", "ad_mask_k", "ad_mask_min_ratio", "ad_mask_max_ratio", + "ad_dilate_erode", "ad_x_offset", "ad_y_offset", "ad_mask_merge_invert", "ad_mask_blur", + "ad_denoising_strength", "ad_inpaint_only_masked", "ad_inpaint_only_masked_padding", + "ad_use_inpaint_width_height", "ad_inpaint_width", "ad_inpaint_height", "ad_use_steps", "ad_steps", + "ad_use_cfg_scale", "ad_cfg_scale", "ad_use_sampler", "ad_sampler", "ad_scheduler", + "ad_use_checkpoint", "ad_checkpoint", "ad_use_vae", "ad_vae", "ad_use_noise_multiplier", + "ad_noise_multiplier", "ad_use_clip_skip", "ad_clip_skip", "ad_restore_face", "ad_controlnet_model", + "ad_controlnet_module", "ad_controlnet_weight", "ad_controlnet_guidance_start", "ad_controlnet_guidance_end", "is_api"}; + for (const auto& config : args) { + if (!config.is_object()) { + continue; + } + auto boolean = [&](const char* key, bool fallback) { + if (!config.contains(key)) + return fallback; + if (!config.at(key).is_boolean()) + throw std::invalid_argument(std::string(key) + " must be boolean"); + return config.at(key).get(); + }; + auto text = [&](const char* key, const char* fallback) { + if (!config.contains(key)) + return std::string(fallback); + if (!config.at(key).is_string()) + throw std::invalid_argument(std::string(key) + " must be a string"); + return config.at(key).get(); + }; + auto number = [&](const char* key, double fallback, double minimum, double maximum) { + double value = fallback; + if (config.contains(key)) { + if (!config.at(key).is_number()) + throw std::invalid_argument(std::string(key) + " must be numeric"); + value = config.at(key).get(); + } + if (!std::isfinite(value) || value < minimum || value > maximum) + throw std::invalid_argument(std::string(key) + " is out of range"); + return value; + }; + auto integer = [&](const char* key, int fallback, int minimum, int maximum = std::numeric_limits::max()) { + if (config.contains(key) && !config.at(key).is_number_integer()) + throw std::invalid_argument(std::string(key) + " must be an integer"); + return static_cast(number(key, fallback, minimum, maximum)); + }; + const std::string model = text("ad_model", "None"); + if (model == "None" || !boolean("ad_tab_enable", true)) { + continue; + } + for (const auto& item : config.items()) { + if (keys.count(item.key()) == 0) + throw std::invalid_argument("unsupported ADetailer setting: " + item.key()); + } + const auto& configured = runtime.default_gen_params->ad_model_path; + if (configured.empty()) + throw std::invalid_argument("ADetailer requires a server-configured --ad-model"); + const auto path = fs::u8path(configured); + if (model.find_first_of("/\\") != std::string::npos || + (lower_ascii(model) != lower_ascii(path.filename().u8string()) && lower_ascii(model) != lower_ascii(path.stem().u8string() + ".pt"))) { + throw std::invalid_argument("ADetailer model must match the server-configured detector"); + } + if (!text("ad_model_classes", "").empty()) + throw std::invalid_argument("ad_model_classes is not supported"); + if (boolean("ad_use_checkpoint", false)) { + const auto checkpoint = config.contains("ad_checkpoint") && config.at("ad_checkpoint").is_null() ? "" : text("ad_checkpoint", "Use same checkpoint"); + if (!checkpoint.empty() && checkpoint != "None" && checkpoint != "Use same checkpoint") + throw std::invalid_argument("ADetailer checkpoint switching is not supported"); + } + if (boolean("ad_use_vae", false)) { + const auto vae = config.contains("ad_vae") && config.at("ad_vae").is_null() ? "" : text("ad_vae", "Use same VAE"); + if (!vae.empty() && vae != "None" && vae != "Use same VAE") + throw std::invalid_argument("ADetailer VAE switching is not supported"); + } + if (boolean("ad_use_noise_multiplier", false) && number("ad_noise_multiplier", 1, 0.5, 1.5) != 1) + throw std::invalid_argument("ADetailer noise multiplier is not supported"); + if (boolean("ad_restore_face", false)) + throw std::invalid_argument("ADetailer face restoration is not supported"); + if (text("ad_controlnet_model", "None") != "None") + throw std::invalid_argument("ADetailer ControlNet is not supported"); + + ServerADetailerPass pass; + pass.prompt = text("ad_prompt", ""); + pass.negative_prompt = text("ad_negative_prompt", ""); + pass.width = request.gen_params.get_resolved_width(); + pass.height = request.gen_params.get_resolved_height(); + pass.strength = static_cast(number("ad_denoising_strength", 0.4, 0, 1)); + auto append = [&](const char* key, const std::string& value) { + if (!pass.extra_args.empty()) + pass.extra_args += ","; + pass.extra_args += std::string(key) + "=" + value; + }; + auto append_number = [&](const char* target, const char* key, double fallback, double minimum, double maximum) { + append(target, json(number(key, fallback, minimum, maximum)).dump()); + }; + auto append_integer = [&](const char* target, const char* key, int fallback, int minimum, int maximum = std::numeric_limits::max()) { + append(target, std::to_string(integer(key, fallback, minimum, maximum))); + }; + append_number("confidence", "ad_confidence", 0.3, 0, 1); + append_integer("mask_k_largest", "ad_mask_k", 0, 0); + const auto filter = text("ad_mask_filter_method", "Area"); + if (filter != "Area" && filter != "Confidence") + throw std::invalid_argument("invalid ad_mask_filter_method"); + append("mask_filter_method", lower_ascii(filter)); + const auto min_ratio = number("ad_mask_min_ratio", 0, 0, 1); + const auto max_ratio = number("ad_mask_max_ratio", 1, 0, 1); + if (min_ratio > max_ratio) + throw std::invalid_argument("ad_mask_min_ratio exceeds ad_mask_max_ratio"); + append("mask_min_ratio", json(min_ratio).dump()); + append("mask_max_ratio", json(max_ratio).dump()); + // Bound pixel operations before converting them to the native mask parameters. + const int mask_limit = std::clamp(std::max(pass.width, pass.height), 32, 16384); + append_integer("dilate_erode", "ad_dilate_erode", 4, -mask_limit, mask_limit); + append_integer("x_offset", "ad_x_offset", 0, -mask_limit, mask_limit); + append_integer("y_offset", "ad_y_offset", 0, -mask_limit, mask_limit); + append_integer("mask_blur", "ad_mask_blur", 4, 0, mask_limit); + append_integer("inpaint_padding", "ad_inpaint_only_masked_padding", 32, 0, mask_limit); + append("inpaint_only_masked", boolean("ad_inpaint_only_masked", true) ? "true" : "false"); + const auto merge = text("ad_mask_merge_invert", "None"); + if (merge != "None" && merge != "Merge" && merge != "Merge and Invert") + throw std::invalid_argument("invalid ad_mask_merge_invert"); + append("mask_mode", merge == "None" ? "none" : merge == "Merge" ? "merge" + : "merge_invert"); + if (boolean("ad_use_inpaint_width_height", false)) { + pass.width = integer("ad_inpaint_width", 512, 1, k_max_generation_dimension); + pass.height = integer("ad_inpaint_height", 512, 1, k_max_generation_dimension); + } + if (boolean("ad_use_steps", false)) + append_integer("steps", "ad_steps", 28, 1, k_max_adetailer_steps); + if (boolean("ad_use_cfg_scale", false)) + append_number("cfg_scale", "ad_cfg_scale", 7, 0, std::numeric_limits::max()); + if (boolean("ad_use_clip_skip", false)) { + pass.clip_skip = integer("ad_clip_skip", 1, 1); + if (pass.clip_skip > 12) + throw std::invalid_argument("ad_clip_skip is out of range"); + } + if (boolean("ad_use_sampler", false)) { + std::string sampler = text("ad_sampler", "DPM++ 2M Karras"); + if (sampler != "Use same sampler") { + const std::string suffix = " karras"; + const bool legacy_karras = sampler.size() > suffix.size() && lower_ascii(sampler.substr(sampler.size() - suffix.size())) == suffix; + if (legacy_karras) + sampler.resize(sampler.size() - suffix.size()); + const auto method = get_sdapi_sample_method(sampler); + if (method == SAMPLE_METHOD_COUNT) + throw std::invalid_argument("unsupported ADetailer sampler"); + append("sample_method", sd_sample_method_name(method)); + if (legacy_karras && text("ad_scheduler", "Use same scheduler") == "Use same scheduler") + append("scheduler", sd_scheduler_name(KARRAS_SCHEDULER)); + } + const auto scheduler = text("ad_scheduler", "Use same scheduler"); + if (scheduler == "Automatic") { + pass.automatic_scheduler = true; + } else if (scheduler != "Use same scheduler") { + const auto value = str_to_scheduler(scheduler.c_str()); + if (value == SCHEDULER_COUNT) + throw std::invalid_argument("unsupported ADetailer scheduler"); + append("scheduler", sd_scheduler_name(value)); + } + } + request.adetailer_passes.push_back(std::move(pass)); + } + if (!request.adetailer_passes.empty() && img2img && args.size() > 1 && args[1].is_boolean() && args[1].get()) { + throw std::invalid_argument("ADetailer skip img2img is not supported"); + } + request.adetailer_enabled = !request.adetailer_passes.empty(); + return true; + } catch (const std::exception& error) { + error_message = std::string("invalid ADetailer args: ") + error.what(); + return false; + } +} + static bool build_sdapi_img_gen_request(const json& j, ServerRuntime& runtime, bool img2img, @@ -259,7 +458,8 @@ static bool build_sdapi_img_gen_request(const json& j, return false; } - return true; + return parse_sdapi_adetailer(j, runtime, img2img, request, error_message) && + validate_server_img_gen_request(runtime, request, error_message); } static nlohmann::json prepare_info_field(const SDContextParams& ctx_params, @@ -349,7 +549,7 @@ static void preview_callback(int step, int frame_count, sd_image_t* frames, bool } struct SDAPIPreviewGuard { - SDAPIPreviewGuard(const std::string& id_task, const sd_img_gen_params_t& params, const std::string& job_type) { + SDAPIPreviewGuard(const std::string& id_task, const sd_img_gen_params_t& params, const std::string& job_type, bool detailing = false) { std::lock_guard lock(g_preview.mutex); g_preview.id_task = id_task; g_preview.total = 0; @@ -358,11 +558,20 @@ struct SDAPIPreviewGuard { g_preview.step = 0; g_preview.active = true; // Each batch item has a base pass and, when enabled, a hires pass. - g_preview.job_count = static_cast(std::max(1, params.batch_count)) * (params.hires.enabled ? 2 : 1); + g_preview.job_count = static_cast(std::max(1, params.batch_count)) * (params.hires.enabled ? 2 : 1) + (detailing ? 1 : 0); g_preview.job_no = 0; sd_set_preview_callback(preview_callback, PREVIEW_PROJ, 1, true, false, nullptr); } + void begin_detailing() { + sd_set_preview_callback(nullptr, PREVIEW_NONE, 1, false, false, nullptr); + std::lock_guard lock(g_preview.mutex); + g_preview.job_type = "adetailer"; + g_preview.job_no = static_cast(g_preview.job_count - 1); + g_preview.step = 0; + g_preview.total = 0; + } + ~SDAPIPreviewGuard() { sd_set_preview_callback(nullptr, PREVIEW_NONE, 1, false, false, nullptr); std::lock_guard lock(g_preview.mutex); @@ -410,13 +619,21 @@ void register_sdapi_endpoints(httplib::Server& svr, ServerRuntime& rt) { { std::lock_guard lock(*runtime->sd_ctx_mutex); - SDAPIPreviewGuard preview_guard(id_task, img_gen_params, img2img ? "img2img" : "txt2img"); + const bool detailing = request.adetailer_enabled && !runtime->default_gen_params->ad_model_path.empty(); + SDAPIPreviewGuard preview_guard(id_task, img_gen_params, img2img ? "img2img" : "txt2img", detailing); sd_image_t* raw_results = nullptr; if (!generate_image(runtime->sd_ctx, &img_gen_params, &raw_results, &num_results)) { raw_results = nullptr; num_results = 0; } results.adopt(raw_results, num_results); + if (detailing && !results.empty()) + preview_guard.begin_detailing(); + if (!results.empty() && !apply_server_adetailer(*runtime, request, img_gen_params, results)) { + res.status = 500; + res.set_content(R"({"error":"ADetailer failed"})", "application/json"); + return; + } } if (results.empty()) { diff --git a/examples/server/routes_sdcpp.cpp b/examples/server/routes_sdcpp.cpp index 7e93e5edbf..8eb9c9ab3b 100644 --- a/examples/server/routes_sdcpp.cpp +++ b/examples/server/routes_sdcpp.cpp @@ -410,9 +410,9 @@ static json make_capabilities_json(ServerRuntime& runtime) { result["defaults_by_mode"] = defaults_by_mode; result["limits"] = { {"min_width", 64}, - {"max_width", 4096}, + {"max_width", k_max_generation_dimension}, {"min_height", 64}, - {"max_height", 4096}, + {"max_height", k_max_generation_dimension}, {"max_batch_count", 8}, {"max_queue_size", manager.max_pending_jobs}, {"max_upscale_width", k_max_upscale_dimension}, @@ -457,7 +457,7 @@ static bool parse_img_gen_request(const json& body, error_message = "invalid generation parameters"; return false; } - return true; + return validate_server_img_gen_request(runtime, request, error_message); } static bool parse_vid_gen_request(const json& body, diff --git a/examples/server/runtime.cpp b/examples/server/runtime.cpp index 34140ea353..5b33b338a5 100644 --- a/examples/server/runtime.cpp +++ b/examples/server/runtime.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -18,6 +19,157 @@ namespace fs = std::filesystem; +bool validate_server_img_gen_request(const ServerRuntime& runtime, + const ImgGenJobRequest& request, + std::string& error_message) { + auto dimensions_valid = [&](double width, double height) { + if (!std::isfinite(width) || !std::isfinite(height) || + width < 1 || height < 1 || width > k_max_generation_dimension || height > k_max_generation_dimension) { + error_message = "generation width and height must be between 1 and " + std::to_string(k_max_generation_dimension); + return false; + } + return true; + }; + const auto& params = request.gen_params; + const int width = params.get_resolved_width(); + const int height = params.get_resolved_height(); + if (!dimensions_valid(width, height)) { + return false; + } + if (params.hires_enabled) { + const double hires_width = params.hires_width > 0 ? params.hires_width : params.hires_height > 0 ? params.hires_height + : std::round(width * params.hires_scale); + const double hires_height = params.hires_height > 0 ? params.hires_height : params.hires_width > 0 ? params.hires_width + : std::round(height * params.hires_scale); + if (!dimensions_valid(hires_width, hires_height)) { + return false; + } + } + if (!request.adetailer_enabled || runtime.default_gen_params->ad_model_path.empty()) { + return true; + } + auto pass_valid = [&](const ServerADetailerPass& pass) { + if (!dimensions_valid(pass.width, pass.height)) { + return false; + } + // Match the native key normalization, but leave full option parsing to ADetailer. + auto trim = [](const std::string& text) { + const auto first = text.find_first_not_of(" \t\r\n"); + return first == std::string::npos ? std::string() : text.substr(first, text.find_last_not_of(" \t\r\n") - first + 1); + }; + std::stringstream stream(pass.extra_args); + std::string item; + while (std::getline(stream, item, ',')) { + const auto equals = item.find('='); + if (equals == std::string::npos) { + continue; + } + auto key = trim(item.substr(0, equals)); + std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { return static_cast(std::tolower(c)); }); + if (key != "inpaint_width" && key != "inpaint_height" && key != "steps") { + continue; + } + const auto value = trim(item.substr(equals + 1)); + const int minimum = key == "steps" ? 0 : 1; + const int maximum = key == "steps" ? k_max_adetailer_steps : k_max_generation_dimension; + try { + size_t used = 0; + const int parsed = std::stoi(value, &used); + if (used == value.size() && parsed >= minimum && parsed <= maximum) { + continue; + } + } catch (const std::exception&) { + } + error_message = "ADetailer " + key + " must be between " + std::to_string(minimum) + " and " + std::to_string(maximum); + return false; + } + return true; + }; + if (request.adetailer_passes.empty()) { + ServerADetailerPass pass; + pass.extra_args = params.extra_ad_args; + return pass_valid(pass); + } + return std::all_of(request.adetailer_passes.begin(), request.adetailer_passes.end(), pass_valid); +} + +bool apply_server_adetailer(ServerRuntime& runtime, + const ImgGenJobRequest& request, + const sd_img_gen_params_t& params, + SDImageVec& results) { + const auto& gen_params = request.gen_params; + const auto& ad_model_path = runtime.default_gen_params->ad_model_path; + if (!request.adetailer_enabled || ad_model_path.empty()) { + return true; + } + std::string error_message; + if (!validate_server_img_gen_request(runtime, request, error_message)) { + LOG_ERROR("%s", error_message.c_str()); + return false; + } + + std::vector passes = request.adetailer_passes; + if (passes.empty()) { + ServerADetailerPass pass; + pass.prompt = gen_params.ad_prompt; + pass.negative_prompt = gen_params.ad_negative_prompt; + pass.extra_args = gen_params.extra_ad_args; + passes.push_back(std::move(pass)); + } + + ADetailerCtxPtr ad_ctx(new_adetailer_ctx(ad_model_path.c_str(), + runtime.ctx_params->n_threads, + runtime.ctx_params->effective_backend.c_str(), + runtime.ctx_params->effective_params_backend.c_str())); + if (ad_ctx == nullptr) { + LOG_ERROR("new_adetailer_ctx failed"); + return false; + } + + for (const auto& pass : passes) { + sd_adetailer_params_t ad_params{}; + ad_params.prompt = pass.prompt.empty() ? nullptr : pass.prompt.c_str(); + ad_params.negative_prompt = pass.negative_prompt.empty() ? nullptr : pass.negative_prompt.c_str(); + ad_params.extra_ad_args = pass.extra_args.c_str(); + for (int i = 0; i < results.count(); ++i) { + if (results[i].data == nullptr) { + continue; + } + sd_img_gen_params_t ad_generation_params = params; + ad_generation_params.seed = params.seed + i; + ad_generation_params.width = pass.width; + ad_generation_params.height = pass.height; + ad_generation_params.strength = pass.strength; + if (pass.clip_skip > 0) { + ad_generation_params.clip_skip = pass.clip_skip; + } + if (pass.automatic_scheduler) { + ad_generation_params.sample_params.scheduler = SCHEDULER_COUNT; + } + + sd_image_t* detailed_images = nullptr; + int detailed_count = 0; + if (!adetail_image(ad_ctx.get(), + runtime.sd_ctx, + results[i], + &ad_params, + &ad_generation_params, + &detailed_images, + &detailed_count) || + detailed_count <= 0 || detailed_images == nullptr || detailed_images[0].data == nullptr) { + free_sd_images(detailed_images, detailed_count); + LOG_ERROR("ADetailer failed for image %d", i + 1); + return false; + } + free(results[i].data); + results[i] = detailed_images[0]; + detailed_images[0] = {0, 0, 0, nullptr}; + free_sd_images(detailed_images, detailed_count); + } + } + return true; +} + static std::string lower_ascii(std::string value) { std::transform(value.begin(), value.end(), value.begin(), [](unsigned char c) { return static_cast(std::tolower(c)); diff --git a/examples/server/runtime.h b/examples/server/runtime.h index d9272f6c24..8986f38270 100644 --- a/examples/server/runtime.h +++ b/examples/server/runtime.h @@ -67,18 +67,38 @@ struct ServerRuntime { ServerModels* models; }; +struct ServerADetailerPass { + std::string prompt; + std::string negative_prompt; + std::string extra_args; + int width = 512; + int height = 512; + float strength = 0.4f; + int clip_skip = -1; + bool automatic_scheduler = false; +}; + struct ImgGenJobRequest { SDGenerationParams gen_params; std::string output_format = "png"; int output_compression = 100; std::string preview_mode = "none"; int preview_interval = 1; + bool adetailer_enabled = true; + std::vector adetailer_passes; sd_img_gen_params_t to_sd_img_gen_params_t() { return gen_params.to_sd_img_gen_params_t(); } }; +constexpr int k_max_generation_dimension = 4096; +constexpr int k_max_adetailer_steps = 100; + +bool validate_server_img_gen_request(const ServerRuntime& runtime, + const ImgGenJobRequest& request, + std::string& error_message); + struct VidGenJobRequest { SDGenerationParams gen_params; std::string output_format = "webm"; @@ -111,3 +131,7 @@ void refresh_lora_cache(ServerRuntime& rt); std::string get_lora_full_path(ServerRuntime& rt, const std::string& path); void refresh_upscaler_cache(ServerRuntime& rt); int64_t unix_timestamp_now_ms(); +bool apply_server_adetailer(ServerRuntime& runtime, + const ImgGenJobRequest& request, + const sd_img_gen_params_t& params, + SDImageVec& results); diff --git a/src/detailer.cpp b/src/detailer.cpp index 72d01dc6f0..ec4d6065a3 100644 --- a/src/detailer.cpp +++ b/src/detailer.cpp @@ -291,7 +291,9 @@ static void filter_and_sort_detections(std::vector* detectio std::partial_sort(detections->begin(), detections->begin() + params.mask_k_largest, detections->end(), - [](const auto& a, const auto& b) { return detection_area(a) > detection_area(b); }); + [&](const auto& a, const auto& b) { + return params.mask_filter_by_confidence ? a.confidence > b.confidence : detection_area(a) > detection_area(b); + }); detections->resize(params.mask_k_largest); } @@ -545,7 +547,16 @@ static sd_image_t resize_crop_mask(const Mask& source, const CropRegion& crop, i return output; } -static sd_image_t copy_as_rgb(const sd_image_t& source) { +static sd_image_t copy_for_detailing(const sd_image_t& source) { + if (source.channel == 4) { + sd_image_t output = source; + size_t bytes = static_cast(source.width) * source.height * source.channel; + output.data = static_cast(malloc(bytes)); + if (output.data != nullptr) { + memcpy(output.data, source.data, bytes); + } + return output; + } CropRegion full{0, 0, static_cast(source.width), static_cast(source.height)}; return resize_crop_image(source, full, source.width, source.height); } @@ -566,7 +577,7 @@ static void composite_crop(sd_image_t* destination, continue; } float source_x = (x - crop.x1 + 0.5f) * scale_x - 0.5f; - size_t destination_index = (static_cast(y) * destination->width + x) * 3; + size_t destination_index = (static_cast(y) * destination->width + x) * destination->channel; for (int c = 0; c < 3; ++c) { float generated_value = bilinear_channel(generated, source_x, source_y, c) * 255.f; float original_value = destination->data[destination_index + c]; @@ -787,6 +798,10 @@ static bool parse_adetailer_params(const sd_adetailer_params_t& public_params, ok = parse_int(value, ¶ms->max_detections); } else if (key == "mask_k_largest") { ok = parse_int(value, ¶ms->mask_k_largest); + } else if (key == "mask_filter_method") { + const std::string method = lower_copy(value); + ok = method == "area" || method == "confidence"; + params->mask_filter_by_confidence = method == "confidence"; } else if (key == "mask_min_ratio") { ok = parse_float(value, ¶ms->mask_min_ratio); } else if (key == "mask_max_ratio") { @@ -805,6 +820,8 @@ static bool parse_adetailer_params(const sd_adetailer_params_t& public_params, ok = parse_int(value, ¶ms->mask_blur); } else if (key == "inpaint_padding") { ok = parse_int(value, ¶ms->inpaint_padding); + } else if (key == "inpaint_only_masked") { + ok = parse_bool(value, ¶ms->inpaint_only_masked); } else if (key == "inpaint_width") { ok = parse_int(value, ¶ms->inpaint_width); } else if (key == "inpaint_height") { @@ -920,7 +937,7 @@ bool adetail_image(adetailer_ctx_t* context, filter_and_sort_detections(&detections, input_image.width, input_image.height, params); auto masks = make_masks(detections, input_image.width, input_image.height, params); - sd_image_t current = copy_as_rgb(input_image); + sd_image_t current = copy_for_detailing(input_image); if (current.data == nullptr) { return false; } @@ -939,12 +956,13 @@ bool adetail_image(adetailer_ctx_t* context, if (!mask_bbox(masks[i], &crop)) { continue; } - crop = expand_crop(crop, - current.width, - current.height, - params.inpaint_padding, - params.inpaint_width, - params.inpaint_height); + crop = params.inpaint_only_masked ? expand_crop(crop, + current.width, + current.height, + params.inpaint_padding, + params.inpaint_width, + params.inpaint_height) + : CropRegion{0, 0, static_cast(current.width), static_cast(current.height)}; sd_image_t local_image = resize_crop_image(current, crop, params.inpaint_width, params.inpaint_height); sd_image_t local_mask = resize_crop_mask(masks[i], crop, params.inpaint_width, params.inpaint_height); if (local_image.data == nullptr || local_mask.data == nullptr) { diff --git a/src/detailer.h b/src/detailer.h index 17a81a1dde..0e3ae50f5a 100644 --- a/src/detailer.h +++ b/src/detailer.h @@ -27,30 +27,32 @@ enum ADetailerSort { }; struct ADetailerParams { - const char* prompt = nullptr; - const char* negative_prompt = nullptr; - int input_size = 640; - float confidence = 0.3f; - float nms_threshold = 0.45f; - int max_detections = 100; - int mask_k_largest = 0; - float mask_min_ratio = 0.f; - float mask_max_ratio = 1.f; - int dilate_erode = 4; - int x_offset = 0; - int y_offset = 0; - bool merge_masks = false; - bool invert_mask = false; - int mask_blur = 4; - int inpaint_padding = 32; - int inpaint_width = 512; - int inpaint_height = 512; - float denoising_strength = 0.4f; - int steps = 0; - float cfg_scale = -1.f; - sample_method_t sample_method = SAMPLE_METHOD_COUNT; - scheduler_t scheduler = SCHEDULER_COUNT; - ADetailerSort sort_by = ADETAILER_SORT_NONE; + const char* prompt = nullptr; + const char* negative_prompt = nullptr; + int input_size = 640; + float confidence = 0.3f; + float nms_threshold = 0.45f; + int max_detections = 100; + int mask_k_largest = 0; + bool mask_filter_by_confidence = false; + float mask_min_ratio = 0.f; + float mask_max_ratio = 1.f; + int dilate_erode = 4; + int x_offset = 0; + int y_offset = 0; + bool merge_masks = false; + bool invert_mask = false; + int mask_blur = 4; + int inpaint_padding = 32; + bool inpaint_only_masked = true; + int inpaint_width = 512; + int inpaint_height = 512; + float denoising_strength = 0.4f; + int steps = 0; + float cfg_scale = -1.f; + sample_method_t sample_method = SAMPLE_METHOD_COUNT; + scheduler_t scheduler = SCHEDULER_COUNT; + ADetailerSort sort_by = ADETAILER_SORT_NONE; }; struct ADetailerGGML { From 939895f00ecd733e8e9e751b63c39b57d0615123 Mon Sep 17 00:00:00 2001 From: vmobilis <75476228+vmobilis@users.noreply.github.com> Date: Wed, 21 Oct 2026 18:29:05 +0300 Subject: [PATCH 2/5] feat: display remaining time (#2076) --- src/core/util.cpp | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/core/util.cpp b/src/core/util.cpp index c1d463e4da..7bd5c0bd11 100644 --- a/src/core/util.cpp +++ b/src/core/util.cpp @@ -568,50 +568,59 @@ bool parse_strict_bool(const std::string& text, bool& value) { } static std::string build_progress_bar(int step, int steps, char progress_char = '=', bool show_head = true) { - std::string progress = " |"; - int max_progress = 50; - int32_t current = 0; + std::string progress = " |"; + constexpr int max_progress = 50; + int32_t current = 0; if (steps > 0) { - current = (int32_t)(step * 1.f * max_progress / steps); + current = (int32_t)(std::clamp(step, 0, steps) * 1.f * max_progress / steps); } - for (int i = 0; i < 50; i++) { - if (i > current) { - progress += " "; - } else if (show_head && i == current && i != max_progress - 1) { - progress += ">"; - } else { - progress += progress_char; - } - } - progress += "|"; + int head_length = (current == max_progress) ? 0 : 1; + progress += std::string(current, progress_char) + std::string(head_length, show_head ? '>' : progress_char) + std::string(max_progress - current - head_length, ' ') + "|"; return progress; } -static void print_progress_line(int step, int steps, const std::string& speed_text, char progress_char = '=', bool show_head = true) { +static void print_progress_line(int step, int steps, const std::string& speed_text, char progress_char = '=', bool show_head = true, const std::string& eta_text = "") { if (step == 0) { return; } std::string progress = build_progress_bar(step, steps, progress_char, show_head); + int step_width = static_cast(std::to_string(steps).size()); const char* lf = (step == steps ? "\n" : ""); - printf("\r%s %i/%i - %s\033[K%s", progress.c_str(), step, steps, speed_text.c_str(), lf); + printf("\r%s %*i/%i - %10s%s%s\033[K%s", progress.c_str(), step_width, step, steps, speed_text.c_str(), + eta_text.empty() ? "" : " - ETA ", eta_text.c_str(), lf); fflush(stdout); // for linux } +static int show_eta = -1; // -1 - estimate duration, 0 - hide, 1 - show +static float passed_time = 0.f; + void pretty_progress(int step, int steps, float time) { if (sd_progress_cb) { sd_progress_cb(step, steps, time, sd_progress_cb_data); return; } if (step == 0) { + show_eta = -1; // reinitialize for batch generations + passed_time = 0.f; return; } + std::string remainder_text = ""; + if (show_eta && step < steps) { // if timer is not disabled and bar is not filled, + if (show_eta == -1 && step) // estimate the total time once, then + show_eta = (std::abs(time * steps / step) < 15.f) ? 0 : 1; // hide the timer if total is less than 15 seconds + if (show_eta) { + unsigned remainder = (passed_time += time) / step * (steps - step); // average speed; time*(steps-step) for current + remainder_text = remainder < 3600 ? sd_format("%02u:%02u", remainder / 60, remainder % 60) + : sd_format("%u:%02u:%02u", remainder / 3600, (remainder / 60) % 60, remainder % 60); + } + } const char* unit = "s/it"; float speed = time; if (speed < 1.0f && speed > 0.f) { speed = 1.0f / speed; unit = "it/s"; } - print_progress_line(step, steps, sd_format("%.2f%s", speed, unit)); + print_progress_line(step, steps, sd_format("%.2f%s", speed, unit), '=', true, remainder_text); } void pretty_bytes_progress(int step, int steps, uint64_t bytes_processed, float elapsed_seconds) { From 2e2ba3faec6717378e74d92fc5da867a0e13078b Mon Sep 17 00:00:00 2001 From: leejet Date: Wed, 21 Oct 2026 23:32:19 +0800 Subject: [PATCH 3/5] feat: add Fibo 2.0 Dev and Edit Turbo support (#2180) --- README.md | 2 + assets/fibo2/dev_edit.png | Bin 0 -> 511959 bytes assets/fibo2/t2i.png | Bin 0 -> 513270 bytes docs/edit.md | 12 +- docs/fibo2.md | 53 +++ examples/server/api.md | 3 +- examples/server/model_catalog.cpp | 2 +- examples/server/recipes/fibo2-dev.json | 39 ++ examples/server/recipes/fibo2-edit-turbo.json | 39 ++ src/conditioning/conditioner.hpp | 105 +++-- src/conditioning/fibo2.hpp | 182 ++++++++ src/model.h | 10 +- src/model/diffusion/fibo2.hpp | 395 ++++++++++++++++++ src/model/diffusion/model.hpp | 16 + src/model_loader.cpp | 4 + src/name_conversion.cpp | 22 +- src/pipeline/diffusion_engine.cpp | 31 +- src/pipeline/image.cpp | 34 +- src/pipeline/model_builders.cpp | 9 +- src/pipeline/request.cpp | 2 +- src/runtime/image_preprocess.cpp | 36 ++ src/runtime/image_preprocess.h | 4 + 22 files changed, 931 insertions(+), 69 deletions(-) create mode 100644 assets/fibo2/dev_edit.png create mode 100644 assets/fibo2/t2i.png create mode 100644 docs/fibo2.md create mode 100644 examples/server/recipes/fibo2-dev.json create mode 100644 examples/server/recipes/fibo2-edit-turbo.json create mode 100644 src/conditioning/fibo2.hpp create mode 100644 src/model/diffusion/fibo2.hpp diff --git a/README.md b/README.md index b4ab2f5ab2..1337c5b92f 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ API and command-line option may change frequently.*** - [FLUX.2-dev/FLUX.2-klein](./docs/flux2.md) - [FLUX.3 Image Klein / Klein Base](./docs/flux3.md) - [MOSS-Image-Base / MOSS-Image-SFT](./docs/moss_image.md) + - [Fibo 2.0 Dev](./docs/fibo2.md) - [Lens](./docs/lens.md) - [Chroma](./docs/chroma.md) - [Chroma1-Radiance](./docs/chroma_radiance.md) @@ -79,6 +80,7 @@ API and command-line option may change frequently.*** - [Boogu Image Edit](./docs/boogu_image.md) - [Mage-Flow-Edit](./docs/mage_flow.md#image-editing) - [LLaDA-Image Edit](./docs/llada_image.md#image-editing) + - [Fibo 2.0 Dev / Edit Turbo](./docs/fibo2.md#editing-and-turbo) - Video Models - [Wan2.1/Wan2.2](./docs/wan.md) - [MiniMax-H3](./docs/minimax_h3.md) diff --git a/assets/fibo2/dev_edit.png b/assets/fibo2/dev_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..fd6e06be13ae95d736abc14fe8a70f4688d63fe4 GIT binary patch literal 511959 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