lllyasviel / stable-diffusion-webui-forge

GNU Affero General Public License v3.0
7.48k stars 723 forks source link

[Bug]: ControlNet does not work when making txt2img requests via the API #375

Closed ashleykleynhans closed 6 months ago

ashleykleynhans commented 6 months ago

Checklist

What happened?

I am able to successfully use ControlNet with txt2img within the WebUI GUI, but when I want to do the same thing via the API, I get the following error:

*** Error running process_before_every_sampling: /workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py
    Traceback (most recent call last):
      File "/workspace/stable-diffusion-webui-forge/modules/scripts.py", line 830, in process_before_every_sampling
        script.process_before_every_sampling(p, *script_args, **kwargs)
      File "/workspace/venv/lib/python3.10/site-packages/torch/utils/_contextlib.py", line 115, in decorate_context
        return func(*args, **kwargs)
      File "/workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py", line 410, in process_before_every_sampling
        for i, unit in enumerate(self.get_enabled_units(args)):
      File "/workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py", line 97, in get_enabled_units
        enabled_units = [x for x in units if x.enabled]
      File "/workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py", line 97, in <listcomp>
        enabled_units = [x for x in units if x.enabled]
    AttributeError: 'dict' object has no attribute 'enabled'

This still continues to happen even when I set enabled to true in my payload.

"enabled": true

Steps to reproduce the problem

POST the following JSON payload to the /sdapi/v1/txt2img endpoint:

            {
                "override_settings": {
                    "sd_model_checkpoint": "sd_xl_base_1.0",
                    "sd_vae": "sdxl_vae.safetensors"
                },
                "prompt": "a photo of an astronaut riding a horse on mars",
                "negative_prompt": "",
                "seed": -1,
                "batch_size": 1,
                "steps": 30,
                "cfg_scale": 7,
                "width": 1024,
                "height": 1024,
                "sampler_name": "DPM++ SDE Karras",
                "sampler_index": "DPM++ SDE Karras",
                "restore_faces": false,
                "alwayson_scripts": {
                    "controlnet": {
                        "args": [
                            {
                                "module": "canny",
                                "model": "diffusers_xl_canny_full [2b69fca4]",
                                "weight": 1,
                                "resize_mode": "Crop and Resize",
                                "lowvram": false,
                                "processor_res": 1024,
                                "threshold_a": 75,
                                "threshold_b": 75,
                                "guidance": 1,
                                "guidance_start": 0,
                                "guidance_end": 1,
                                "control_mode": "Balanced",
                                "pixel_perfect": false
                            }
                        ]
                    }
                }
            }

What should have happened?

The ControlNet unit should have activated and been applied to the request.

What browsers do you use to access the UI ?

Other

Sysinfo

sysinfo-2024-02-23-14-04.json

Console logs

################################################################
Install script for stable-diffusion + Web UI
Tested on Debian 11 (Bullseye), Fedora 34+ and openSUSE Leap 15.4 or newer.
################################################################

################################################################
Running on root user
################################################################

################################################################
Repo already cloned, using it as install directory
################################################################

################################################################
python venv already activate or run without venv: /workspace/venv
################################################################

################################################################
Launching launch.py...
################################################################
Using TCMalloc: libtcmalloc_minimal.so.4
libtcmalloc_minimal.so.4 is not linked with libpthreadand will trigger undefined symbol: ptthread_Key_Create error
Using TCMalloc: libtcmalloc.so.4
libtcmalloc.so.4 is not linked with libpthreadand will trigger undefined symbol: ptthread_Key_Create error
Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]
Version: f0.0.1-latest
Commit hash: f11456e2d38d6b7f8432cd6952fb2f10fc2081b3
Launching Web UI with arguments: -f --port 3001 --listen --api --xformers --enable-insecure-extension-access --no-half-vae --no-hashing --opt-sdp-attention
Total VRAM 24248 MB, total RAM 257605 MB
xformers version: 0.0.23.post1
Set vram state to: NORMAL_VRAM
Device: cuda:0 NVIDIA RTX A5000 : native
VAE dtype: torch.bfloat16
Using xformers cross attention
ControlNet preprocessor location: /workspace/stable-diffusion-webui-forge/models/ControlNetPreprocessor
14:05:54 - ReActor - STATUS - Running v0.6.1 on Device: CUDA
Loading weights [None] from /workspace/stable-diffusion-webui-forge/models/Stable-diffusion/turboDiffusionXL_v112.safetensors
2024-02-23 14:05:54,408 - ControlNet - INFO - ControlNet UI callback registered.
Running on local URL:  http://0.0.0.0:3001
model_type EPS
UNet ADM Dimension 2816
Using xformers attention in VAE
Working with z of shape (1, 4, 32, 32) = 4096 dimensions.
Using xformers attention in VAE

To create a public link, set `share=True` in `launch()`.
Startup time: 13.5s (prepare environment: 3.2s, import torch: 4.1s, import gradio: 0.8s, setup paths: 0.6s, other imports: 0.4s, load scripts: 1.0s, create ui: 0.7s, gradio launch: 2.2s, add APIs: 0.4s).
extra {'cond_stage_model.clip_l.text_projection', 'cond_stage_model.clip_l.logit_scale', 'cond_stage_model.clip_g.transformer.text_model.embeddings.position_ids', 'cond_stage_model.clip_l.transformer.text_model.embeddings.position_ids'}
left over keys: dict_keys(['conditioner.embedders.0.logit_scale', 'conditioner.embedders.0.text_projection'])
Loading VAE weights specified in settings: /workspace/stable-diffusion-webui-forge/models/VAE/sdxl_vae.safetensors
To load target model SDXLClipModel
Begin to load 1 model
Moving model(s) has taken 0.18 seconds
Model loaded in 6.5s (load weights from disk: 0.9s, forge load real models: 4.8s, load VAE: 0.4s, calculate empty prompt: 0.3s).
Loading weights [31e35c80fc] from /workspace/stable-diffusion-webui-forge/models/Stable-diffusion/sd_xl_base_1.0.safetensors
model_type EPS
UNet ADM Dimension 2816
Using xformers attention in VAE
Working with z of shape (1, 4, 32, 32) = 4096 dimensions.
Using xformers attention in VAE
extra {'cond_stage_model.clip_l.text_projection', 'cond_stage_model.clip_l.logit_scale', 'cond_stage_model.clip_g.transformer.text_model.embeddings.position_ids'}
Loading VAE weights specified in settings: /workspace/stable-diffusion-webui-forge/models/VAE/sdxl_vae.safetensors
To load target model SDXLClipModel
Begin to load 1 model
Moving model(s) has taken 0.18 seconds
Model loaded in 6.4s (unload existing model: 0.9s, forge load real models: 5.0s, load VAE: 0.2s, calculate empty prompt: 0.2s).
*** Error running process: /workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py
    Traceback (most recent call last):
      File "/workspace/stable-diffusion-webui-forge/modules/scripts.py", line 798, in process
        script.process(p, *script_args)
      File "/workspace/venv/lib/python3.10/site-packages/torch/utils/_contextlib.py", line 115, in decorate_context
        return func(*args, **kwargs)
      File "/workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py", line 399, in process
        enabled_units = self.get_enabled_units(args)
      File "/workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py", line 97, in get_enabled_units
        enabled_units = [x for x in units if x.enabled]
      File "/workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py", line 97, in <listcomp>
        enabled_units = [x for x in units if x.enabled]
    AttributeError: 'dict' object has no attribute 'enabled'

---
To load target model SDXLClipModel
Begin to load 1 model
unload clone 0
Moving model(s) has taken 0.45 seconds
*** Error running process_before_every_sampling: /workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py
    Traceback (most recent call last):
      File "/workspace/stable-diffusion-webui-forge/modules/scripts.py", line 830, in process_before_every_sampling
        script.process_before_every_sampling(p, *script_args, **kwargs)
      File "/workspace/venv/lib/python3.10/site-packages/torch/utils/_contextlib.py", line 115, in decorate_context
        return func(*args, **kwargs)
      File "/workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py", line 410, in process_before_every_sampling
        for i, unit in enumerate(self.get_enabled_units(args)):
      File "/workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py", line 97, in get_enabled_units
        enabled_units = [x for x in units if x.enabled]
      File "/workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py", line 97, in <listcomp>
        enabled_units = [x for x in units if x.enabled]
    AttributeError: 'dict' object has no attribute 'enabled'

---
To load target model SDXL
Begin to load 1 model
Moving model(s) has taken 0.52 seconds
100%|█████████████████████████████████████████████████████████████████████| 30/30 [00:14<00:00,  2.01it/s]
To load target model AutoencoderKL████████████████████████████████████████| 30/30 [00:14<00:00,  2.00it/s]
Begin to load 1 model
*** Error running postprocess_batch_list: /workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py
    Traceback (most recent call last):
      File "/workspace/stable-diffusion-webui-forge/modules/scripts.py", line 854, in postprocess_batch_list
        script.postprocess_batch_list(p, pp, *script_args, **kwargs)
      File "/workspace/venv/lib/python3.10/site-packages/torch/utils/_contextlib.py", line 115, in decorate_context
        return func(*args, **kwargs)
      File "/workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py", line 416, in postprocess_batch_list
        for i, unit in enumerate(self.get_enabled_units(args)):
      File "/workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py", line 97, in get_enabled_units
        enabled_units = [x for x in units if x.enabled]
      File "/workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py", line 97, in <listcomp>
        enabled_units = [x for x in units if x.enabled]
    AttributeError: 'dict' object has no attribute 'enabled'

---
Total progress: 100%|█████████████████████████████████████████████████████| 30/30 [00:14<00:00,  2.01it/s]
Total progress: 100%|█████████████████████████████████████████████████████| 30/30 [00:14<00:00,  2.00it/s]


### Additional information

_No response_
huchenlei commented 6 months ago

See https://github.com/lllyasviel/stable-diffusion-webui-forge/wiki/ControlNet-Web-API

Also you probably need to update your forge.

ashleykleynhans commented 6 months ago

See https://github.com/lllyasviel/stable-diffusion-webui-forge/wiki/ControlNet-Web-API

Also you probably need to update your forge.

Thanks for the wiki link, my forge is already at the latest commit.

ashleykleynhans commented 6 months ago

Seems I did actually need to update it, but its still not working, now I am getting a different error:

*** Error running process: /workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py
    Traceback (most recent call last):
      File "/workspace/stable-diffusion-webui-forge/modules/scripts.py", line 803, in process
        script.process(p, *script_args)
      File "/workspace/venv/lib/python3.10/site-packages/torch/utils/_contextlib.py", line 115, in decorate_context
        return func(*args, **kwargs)
      File "/workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py", line 548, in process
        self.process_unit_after_click_generate(p, unit, params, *args, **kwargs)
      File "/workspace/venv/lib/python3.10/site-packages/torch/utils/_contextlib.py", line 115, in decorate_context
        return func(*args, **kwargs)
      File "/workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py", line 298, in process_unit_after_click_generate
        input_list, resize_mode = self.get_input_data(p, unit, preprocessor, h, w)
      File "/workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py", line 203, in get_input_data
        resize_mode = external_code.resize_mode_from_value(p.resize_mode)
    AttributeError: 'StableDiffusionProcessingTxt2Img' object has no attribute 'resize_mode'

---
*** Error running process_before_every_sampling: /workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py
    Traceback (most recent call last):
      File "/workspace/stable-diffusion-webui-forge/modules/scripts.py", line 835, in process_before_every_sampling
        script.process_before_every_sampling(p, *script_args, **kwargs)
      File "/workspace/venv/lib/python3.10/site-packages/torch/utils/_contextlib.py", line 115, in decorate_context
        return func(*args, **kwargs)
      File "/workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py", line 555, in process_before_every_sampling
        self.process_unit_before_every_sampling(p, unit, self.current_params[i], *args, **kwargs)
    KeyError: 0

---
100%|█████████████████████████████████████████████████████████████████████| 20/20 [00:11<00:00,  1.72it/s]
*** Error running postprocess_batch_list: /workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py
    Traceback (most recent call last):
      File "/workspace/stable-diffusion-webui-forge/modules/scripts.py", line 859, in postprocess_batch_list
        script.postprocess_batch_list(p, pp, *script_args, **kwargs)
      File "/workspace/venv/lib/python3.10/site-packages/torch/utils/_contextlib.py", line 115, in decorate_context
        return func(*args, **kwargs)
      File "/workspace/stable-diffusion-webui-forge/extensions-builtin/sd_forge_controlnet/scripts/controlnet.py", line 561, in postprocess_batch_list
        self.process_unit_after_every_sampling(p, unit, self.current_params[i], pp, *args, **kwargs)
    KeyError: 0
ashleykleynhans commented 6 months ago

Exact same payload works fine with img2img, its only txt2img giving me issues.

ramyma commented 6 months ago

Exact same payload works fine with img2img, its only txt2img giving me issues.

Looks like you're missing the image arg; with img2img it defaults to the main image, but for txt2img you have to pass the image upon which the controlnet unit will work.

ashleykleynhans commented 6 months ago

Exact same payload works fine with img2img, its only txt2img giving me issues.

Looks like you're missing the image arg; with img2img it defaults to the main image, but for txt2img you have to pass the image upon which the controlnet unit will work.

Thanks, its working now.

aninda-leonardo commented 5 months ago

@ashleykleynhans where did you update the image arg?

ashleykleynhans commented 5 months ago

@ashleykleynhans where did you update the image arg?

Monosnap runpod-worker-forge – txt2img_instantid py 2024-04-06 17-01-09
sumit91in commented 5 months ago

@ashleykleynhans where did you update the image arg?

Monosnap runpod-worker-forge – txt2img_instantid py 2024-04-06 17-01-09

Could you please let me know which file to change I am not able to find? I am getting the error in img2img as well. Please help

image

ashleykleynhans commented 5 months ago

@sumit91in There are no files to change, it is an API request.

ramyma commented 5 months ago

Basically the input_image property changed to image in the controlnet unit; changing the request payload accordingly should fix the issue.

sumit91in commented 5 months ago

Basically the input_image property changed to image in the controlnet unit; changing the request payload accordingly should fix the issue.

@ramyma Thank for your reply but I cant figure out where exactly i need to make the change. Now apart from the above error, i am getting the below error. image

Kindly help. Stuck on this over a week still cant figure out

ramyma commented 5 months ago

It looks like the controlnet model file you're using is broken, did it download the model again why you try to generate again? Also does it work for you through the web-ui interface?

ashleykleynhans commented 5 months ago

This issue is closed and the stuff you are posting here is not relevant, please use a forum or log a new issue, it does not belong here.

ratzycon commented 4 weeks ago

this is still happening,

no matter what i try from the API i get the same error and the controlnet image fails to apply, while it works inside the webui

this is the test script i'm using:

import io
import cv2
import base64
import requests
import json
from PIL import Image, PngImagePlugin

def test(test_image):

    url = "http://localhost:7860" # change to your SD url

    img = cv2.imread(test_image)
    retval, bytes = cv2.imencode('.png', img)
    encoded_image = base64.b64encode(bytes).decode('utf-8')

    # Note: You can no longer pass file path in payload as in sd-webui-controlnet.

    payload = {
        "prompt":"2girls, reading, book, elf, simple white background, white dress, hatsune miku",
        "negative_prompt": "",
        "sampler_name": "Euler a",
        "batch_size": 1,
        "steps": 20,
        "cfg_scale": 6,
        "width": 1024,
        "height": 1024,

        # txt2img should not need any init images except for the controlnet image
        #"init_images": [test_image],
        #"init_images": [encoded_image],

        "alwayson_scripts": {
            "controlnet": {
                "args": [
                    {
                        "enabled": True,

                        "image": encoded_image,
                        #"mask_image": encoded_image,

                        "control_mode": "Balanced", 
                        "guidance_end": 1,
                        "guidance_start": 0,
                        "pixel_perfect": True,
                        "processor_res": 512,
                        "resize_mode": "Resize and Fill",  # "Just Resize", "Crop and Resize", "Resize and Fill"
                        "threshold_a": 0.5,
                        "threshold_b": 0.5,
                        "weight": 1,
                        "save_detected_map": True,
                        "hr_option": "Both",

                        #"module": "canny",
                        "module": "lineart_anime",

                        "model": "t2i-adapter_diffusers_xl_canny [6b0c1490]",
                        #"model": "control_v11p_sd15_canny [d14c016b]",
                        #"model": "control_v11p_sd15s2_lineart_anime [3825e83e]",
                    }
                ]
            }
        }
    }

    response = requests.post(url=f'{url}/sdapi/v1/txt2img', json=payload)

    r = response.json()
    result = r['images'][0]
    image = Image.open(io.BytesIO(base64.b64decode(result.split(",", 1)[0])))

    pnginfo = PngImagePlugin.PngInfo()
    if 'parameters' in image.info and image.info['parameters'] is not None:
        pnginfo.add_text("parameters", image.info.get('parameters'))
        print("\nParameters:\n" + json.dumps(image.info, indent=4))

    image.save('test_output.png', pnginfo=pnginfo)

    print("image saved to test_output.png")

test("test.png")

controlnet test image: test

controlnet console error: error

controlnet webui in editor output with same settings (no console errors): in editor

test output using API: test_output_forge

controlnet_test.zip