diff --git a/README.md b/README.md index b85dcf3..c05a25d 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ FastAPI powered API for [Fooocus](https://github.com/lllyasviel/Fooocus) -Currently loaded Fooocus version: 2.1.25 +Currently loaded Fooocus version: 2.1.44 ### Run with Replicate Now you can use Fooocus-API by Replicate, the model is in [konieshadow/fooocus-api](https://replicate.com/konieshadow/fooocus-api). diff --git a/docs/openapi.json b/docs/openapi.json index 51b9e90..d5f3ed2 100644 --- a/docs/openapi.json +++ b/docs/openapi.json @@ -574,12 +574,18 @@ "description": "Input image for image prompt" }, "cn_stop1": { - "type": "number", - "maximum": 1, - "minimum": 0, + "anyOf": [ + { + "type": "number", + "maximum": 1, + "minimum": 0 + }, + { + "type": "null" + } + ], "title": "Cn Stop1", - "description": "Stop at for image prompt", - "default": 0.4 + "description": "Stop at for image prompt" }, "cn_weight1": { "anyOf": [ @@ -611,12 +617,18 @@ "description": "Input image for image prompt" }, "cn_stop2": { - "type": "number", - "maximum": 1, - "minimum": 0, + "anyOf": [ + { + "type": "number", + "maximum": 1, + "minimum": 0 + }, + { + "type": "null" + } + ], "title": "Cn Stop2", - "description": "Stop at for image prompt", - "default": 0.4 + "description": "Stop at for image prompt" }, "cn_weight2": { "anyOf": [ @@ -648,12 +660,18 @@ "description": "Input image for image prompt" }, "cn_stop3": { - "type": "number", - "maximum": 1, - "minimum": 0, + "anyOf": [ + { + "type": "number", + "maximum": 1, + "minimum": 0 + }, + { + "type": "null" + } + ], "title": "Cn Stop3", - "description": "Stop at for image prompt", - "default": 0.4 + "description": "Stop at for image prompt" }, "cn_weight3": { "anyOf": [ @@ -685,12 +703,18 @@ "description": "Input image for image prompt" }, "cn_stop4": { - "type": "number", - "maximum": 1, - "minimum": 0, + "anyOf": [ + { + "type": "number", + "maximum": 1, + "minimum": 0 + }, + { + "type": "null" + } + ], "title": "Cn Stop4", - "description": "Stop at for image prompt", - "default": 0.4 + "description": "Stop at for image prompt" }, "cn_weight4": { "anyOf": [ @@ -1435,7 +1459,6 @@ "$ref": "#/components/schemas/Lora" }, "type": "array", - "maxItems": 5, "title": "Loras", "default": [ { diff --git a/fooocus_api_version.py b/fooocus_api_version.py index 30287f0..ead049e 100644 --- a/fooocus_api_version.py +++ b/fooocus_api_version.py @@ -1 +1 @@ -version = '0.1.13' \ No newline at end of file +version = '0.1.14' \ No newline at end of file diff --git a/fooocusapi/models.py b/fooocusapi/models.py index f234ff3..4646de8 100644 --- a/fooocusapi/models.py +++ b/fooocusapi/models.py @@ -284,7 +284,7 @@ class Text2ImgRequest(BaseModel): base_model_name: str = 'sd_xl_base_1.0_0.9vae.safetensors' refiner_model_name: str = 'sd_xl_refiner_1.0_0.9vae.safetensors' loras: List[Lora] = Field(default=[ - Lora(model_name='sd_xl_offset_example-lora_1.0.safetensors', weight=0.5)], max_length=5) + Lora(model_name='sd_xl_offset_example-lora_1.0.safetensors', weight=0.5)]) class ImgUpscaleOrVaryRequest(Text2ImgRequest): @@ -436,32 +436,32 @@ class ImgPromptRequest(Text2ImgRequest): @classmethod def as_form(cls, cn_img1: UploadFile = Form(File(None), description="Input image for image prompt"), - cn_stop1: float = Form( - default=0.4, ge=0, le=1, description="Stop at for image prompt"), + cn_stop1: float | None = Form( + default=None, ge=0, le=1, description="Stop at for image prompt, None for default value"), cn_weight1: float | None = Form( default=None, ge=0, le=2, description="Weight for image prompt, None for default value"), cn_type1: ControlNetType = Form( default=ControlNetType.cn_ip, description="ControlNet type for image prompt"), cn_img2: UploadFile = Form( File(None), description="Input image for image prompt"), - cn_stop2: float = Form( - default=0.4, ge=0, le=1, description="Stop at for image prompt"), + cn_stop2: float | None = Form( + default=None, ge=0, le=1, description="Stop at for image prompt, None for default value"), cn_weight2: float | None = Form( default=None, ge=0, le=2, description="Weight for image prompt, None for default value"), cn_type2: ControlNetType = Form( default=ControlNetType.cn_ip, description="ControlNet type for image prompt"), cn_img3: UploadFile = Form( File(None), description="Input image for image prompt"), - cn_stop3: float = Form( - default=0.4, ge=0, le=1, description="Stop at for image prompt"), + cn_stop3: float | None = Form( + default=None, ge=0, le=1, description="Stop at for image prompt, None for default value"), cn_weight3: float | None = Form( default=None, ge=0, le=2, description="Weight for image prompt, None for default value"), cn_type3: ControlNetType = Form( default=ControlNetType.cn_ip, description="ControlNet type for image prompt"), cn_img4: UploadFile = Form( File(None), description="Input image for image prompt"), - cn_stop4: float = Form( - default=0.4, ge=0, le=1, description="Stop at for image prompt"), + cn_stop4: float | None = Form( + default=None, ge=0, le=1, description="Stop at for image prompt, None for default value"), cn_weight4: float | None = Form( default=None, ge=0, le=2, description="Weight for image prompt, None for default value"), cn_type4: ControlNetType = Form( @@ -509,6 +509,8 @@ def as_form(cls, cn_img1: UploadFile = Form(File(None), description="Input image (cn_img3, cn_stop3, cn_weight3, cn_type3), (cn_img4, cn_stop4, cn_weight4, cn_type4)] for config in image_prompt_config: cn_img, cn_stop, cn_weight, cn_type = config + if cn_stop is None: + cn_stop = flags.default_parameters[cn_type.value][0] if cn_weight is None: cn_weight = flags.default_parameters[cn_type.value][1] image_prompts.append(ImagePrompt( diff --git a/fooocusapi/repositories_versions.py b/fooocusapi/repositories_versions.py index 3db68e7..b1d0f00 100644 --- a/fooocusapi/repositories_versions.py +++ b/fooocusapi/repositories_versions.py @@ -1,7 +1,7 @@ import os -fooocus_version = '2.1.25' +fooocus_version = '2.1.44' comfy_commit_hash = os.environ.get( - 'COMFY_COMMIT_HASH', "1c5d6663faf1a33e00ec67240167b174a9cac655") + 'COMFY_COMMIT_HASH', "d1a0abd40b86f3f079b0cc71e49f9f4604831457") fooocus_commit_hash = os.environ.get( - 'FOOOCUS_COMMIT_HASH', "71e9ebc7a26bbb6ccec08aa656c98f2e38a21425") + 'FOOOCUS_COMMIT_HASH', "5e8f2f96e91817cc6691642e71edec8b8264b114") diff --git a/fooocusapi/worker.py b/fooocusapi/worker.py index 3032c75..e9bf4dd 100644 --- a/fooocusapi/worker.py +++ b/fooocusapi/worker.py @@ -24,7 +24,7 @@ def process_generate(params: ImageGenerationParams) -> List[ImageGenerationResul import modules.advanced_parameters as advanced_parameters import fooocus_extras.preprocessors as preprocessors import fooocus_extras.ip_adapter as ip_adapter - from modules.util import join_prompts, remove_empty_str, image_is_generated_in_current_ui, resize_image, HWC3 + from modules.util import join_prompts, remove_empty_str, image_is_generated_in_current_ui, resize_image, HWC3, make_sure_that_image_is_not_too_large from modules.private_logger import log from modules.upscaler import perform_upscale from modules.expansion import safe_str @@ -100,27 +100,33 @@ def make_results_from_outputs(): cn_tasks[cn_type].append([cn_img, cn_stop, cn_weight]) def build_advanced_parameters(): - adm_scaler_positive=1.5 - adm_scaler_negative=0.8 - adm_scaler_end=0.3 - adaptive_cfg=7.0 - sampler_name=flags.default_sampler - scheduler_name=flags.default_scheduler - overwrite_step=-1 - overwrite_switch=-1 - overwrite_width=-1 - overwrite_height=-1 - overwrite_vary_strength=-1 - overwrite_upscale_strength=-1 - mixing_image_prompt_and_vary_upscale=False - mixing_image_prompt_and_inpaint=False - debugging_cn_preprocessor=False - controlnet_softness=0.25 + adm_scaler_positive = 1.5 + adm_scaler_negative = 0.8 + adm_scaler_end = 0.3 + adaptive_cfg = 7.0 + sampler_name = path.default_sampler + scheduler_name = path.default_scheduler + overwrite_step = -1 + overwrite_switch = -1 + overwrite_width = -1 + overwrite_height = -1 + overwrite_vary_strength = -1 + overwrite_upscale_strength = -1 + mixing_image_prompt_and_vary_upscale = False + mixing_image_prompt_and_inpaint = False + debugging_cn_preprocessor = False + controlnet_softness = 0.25 + canny_low_threshold = 64 + canny_high_threshold = 128 + inpaint_engine = 'v1' + freeu_enabled = False + freeu_b1, freeu_b2, freeu_s1, freeu_s2 = [None] * 4 return [adm_scaler_positive, adm_scaler_negative, adm_scaler_end, adaptive_cfg, sampler_name, scheduler_name, overwrite_step, overwrite_switch, overwrite_width, overwrite_height, overwrite_vary_strength, overwrite_upscale_strength, mixing_image_prompt_and_vary_upscale, mixing_image_prompt_and_inpaint, - debugging_cn_preprocessor, controlnet_softness] + debugging_cn_preprocessor, controlnet_softness, canny_low_threshold, canny_high_threshold, inpaint_engine, + freeu_enabled, freeu_b1, freeu_b2, freeu_s1, freeu_s2] advanced_parameters.set_all_advanced_parameters(*build_advanced_parameters()) @@ -218,8 +224,9 @@ def build_advanced_parameters(): if isinstance(inpaint_image, np.ndarray) and isinstance(input_mask, np.ndarray) \ and (np.any(input_mask > 127) or len(outpaint_selections) > 0): progressbar(1, 'Downloading inpainter ...') - inpaint_head_model_path, inpaint_patch_model_path = path.downloading_inpaint_models() + inpaint_head_model_path, inpaint_patch_model_path = path.downloading_inpaint_models(advanced_parameters.inpaint_engine) loras += [(inpaint_patch_model_path, 1.0)] + print(f'[Inpaint] Current inpaint model is {inpaint_patch_model_path}') goals.append('inpaint') sampler_name = 'dpmpp_fooocus_2m_sde_inpaint_seamless' if current_tab == 'ip' or \ @@ -333,6 +340,8 @@ def build_advanced_parameters(): denoising_strength = 0.85 if advanced_parameters.overwrite_vary_strength > 0: denoising_strength = advanced_parameters.overwrite_vary_strength + + uov_input_image = make_sure_that_image_is_not_too_large(uov_input_image) initial_pixels = core.numpy_to_pytorch(uov_input_image) progressbar(13, 'VAE encoding ...') initial_latent = core.encode_vae(vae=pipeline.final_vae, pixels=initial_pixels) @@ -504,6 +513,16 @@ def build_advanced_parameters(): if len(cn_tasks[flags.cn_ip]) > 0: pipeline.final_unet = ip_adapter.patch_model(pipeline.final_unet, cn_tasks[flags.cn_ip]) + if advanced_parameters.freeu_enabled: + print(f'FreeU is enabled!') + pipeline.final_unet = core.apply_freeu( + pipeline.final_unet, + advanced_parameters.freeu_b1, + advanced_parameters.freeu_b2, + advanced_parameters.freeu_s1, + advanced_parameters.freeu_s2 + ) + results = [] all_steps = steps * image_number diff --git a/main.py b/main.py index d692661..d2d303f 100644 --- a/main.py +++ b/main.py @@ -238,14 +238,8 @@ def prepare_environments(args) -> bool: # This function was copied from [Fooocus](https://github.com/lllyasviel/Fooocus) repository. def ini_comfy_args(): - argv = sys.argv - sys.argv = [sys.argv[0]] - - from comfy.cli_args import args as comfy_args - comfy_args.disable_cuda_malloc = True - comfy_args.auto_launch = False - - sys.argv = argv + from args_manager import args + return args if __name__ == "__main__": @@ -265,6 +259,8 @@ def ini_comfy_args(): args = parser.parse_args() if prepare_environments(args): + argv = sys.argv + sys.argv = [sys.argv[0]] ini_comfy_args() # Start api server