Currently, HF is buggy.

#4
by John6666 - opened

https://huggingface.co/spaces/zero-gpu-explorers/README/discussions/104
Hello.
HF is currently debugging several huge bugs.
Especially Zero GPU and Diffusers projects that seem to be related to stablepy also.
Workarounds on the user side:

  • Comment out Examples (especially None value) of Gradio
  • Be careful with functions with @spaces decorators
  • Also add @spaces decorator when loading model
Owner

Thanks for the heads-up @John6666
Iโ€™ve made some changes and will keep your tips in mind

Thank you for always maintaining the library.๐Ÿ˜ธ
I will close the Discussion.

BTW, I wonder if streamtest is going away and gone without being officially merged...
I've moved to dev2, but I've seen a few people using DiffuseCraft, which is a streamtest-only implementation version (yield images, seed).
Well, I'm sure it will be fixed in sync if they haven't modified it too much... just wondering.

John6666 changed discussion status to closed
Owner

Hello, I have added the function to the main branch

Hi, Thanks for the contact!
I'll try to transplant it.

Successfully confirmed that True/False in image_previews changes the number of return values (3 if on). However, since the Zero GPU space has recently been sped up, the step is often completed before the previews appear. (Like noise -> complete). It would be helpful to have Seed returned.
This would not be a problem for anyone using either the old or new implementation. Thanks.

https://huggingface.co/posts/cbensimon/747180194960645
The HF bug is about 70% fixed, but it's still there, and it's easy to have trouble with CUDA onloading and offloading, especially after starting the demo. stablepy is probably able to work around it thanks to frequent offloading, but libraries that assume only a CUDA environment are in trouble. If the tensor straddles the CPU and GPU, the program is sure to die.

By the way, this is totally unrelated.
It seems to be customary for Civitai and others to write metadata into image files.
I've added my own code for an image generation space that uses Serverless Inference, but as far as DiffuseCraft is concerned, I'd like to keep in line with the original as much as possible.

Although it would be so much easier if stablepy returned it, since stablepy returns images, not image files (And it should be.), I'm thinking it would be just before or after the yield in DiffuseCraft's app.py, but the timing is more difficult than I thought, especially considering the stream of the yield, even if it ends with a return...
Any ideas?

The metadata looks like this, which is probably originally WebUI's own format, so there should be no strict definition.
https://huggingface.co/spaces/cagliostrolab/animagine-xl-3.1/blob/main/app.py
https://huggingface.co/spaces/cagliostrolab/animagine-xl-3.1/blob/main/utils.py

    metadata = {
        "prompt": prompt,
        "negative_prompt": negative_prompt,
        "resolution": f"{width} x {height}",
        "guidance_scale": guidance_scale,
        "num_inference_steps": num_inference_steps,
        "seed": seed,
        "sampler": sampler,
        "sdxl_style": style_selector,
        "add_quality_tags": add_quality_tags,
        "quality_tags": quality_selector,
    }

        metadata["use_upscaler"] = None
        metadata["Model"] = {
            "Model": DESCRIPTION,
            "Model hash": "e3c47aedb0",
        }

def save_image(image, metadata, output_dir, is_colab):
    if is_colab:
        current_time = datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = f"image_{current_time}.png"   
    else:
        filename = str(uuid.uuid4()) + ".png"
    os.makedirs(output_dir, exist_ok=True)
    filepath = os.path.join(output_dir, filename)
    metadata_str = json.dumps(metadata)
    info = PngImagePlugin.PngInfo()
    info.add_text("metadata", metadata_str)
    image.save(filepath, "PNG", pnginfo=info)
    return filepath

My version

https://huggingface.co/spaces/John6666/flux-lora-the-explorer/blob/main/mod.py

def save_image(image, savefile, modelname, prompt, height, width, steps, cfg, seed):
    import uuid
    from PIL import Image, PngImagePlugin
    import json
    try:
        if savefile is None: savefile = f"{modelname.split('/')[-1]}_{str(uuid.uuid4())}.png"
        metadata = {"prompt": prompt, "Model": {"Model": modelname.split("/")[-1]}}
        metadata["num_inference_steps"] = steps
        metadata["guidance_scale"] = cfg
        metadata["seed"] = seed
        metadata["resolution"] = f"{width} x {height}"
        metadata_str = json.dumps(metadata)
        info = PngImagePlugin.PngInfo()
        info.add_text("metadata", metadata_str)
        image.save(savefile, "PNG", pnginfo=info)
        return str(Path(savefile).resolve())
    except Exception as e:
        print(f"Failed to save image file: {e}")
        raise Exception(f"Failed to save image file:") from e
Owner

I'm setting up a lighter stream to improve performance. For the metadata, I'm currently using a plain text format like in automatic1111, but I might switch to a dictionary format like you suggested.
In the yield, I use if image_path: to identify the last loop for returning the metadata. I'm not sure if this will be helpful to you, though

I'm setting up a lighter stream to improve performance.

Preview is now perfect.

For the metadata, I'm currently using a plain text format like in automatic1111,

I think A1111 is more standard. You have already written...

I use if image_path: to identify the last loop for returning the metadata.

It can be a great help!

P.S.
The metadata is then successfully embedded.
Since Gradio's Image and Gallery components do not destroy the image metadata, I decided to insert the processing in this line, a little wildly, so that the GUI side does not need to be modified.
This is easy enough to rewrite in the event of a DiffuseCraft update.
Thank you very much!๐Ÿค—
https://huggingface.co/spaces/John6666/DiffuseCraftMod

from PIL import Image
def save_images(images: list[Image.Image], metadatas: list[str]):
    from PIL import PngImagePlugin
    import uuid
    try:
        output_images = []
        for image, metadata in zip(images, metadatas):
            info = PngImagePlugin.PngInfo()
            info.add_text("metadata", metadata)
            savefile = f"{str(uuid.uuid4())}.png"
            image.save(savefile, "PNG", pnginfo=info)
            output_images.append(str(Path(savefile).resolve()))
        return output_images
    except Exception as e:
        print(f"Failed to save image file: {e}")
        raise Exception(f"Failed to save image file:") from e

                info_state = info_state + "<br>" + "GENERATION DATA:<br>" + "<br>-------<br>".join(metadata).replace("\n", "<br>")

                img = save_images(img, metadata)
                
            yield img, info_state

20240920_163052_1.png

While I was in the middle of applying the changes, I realized that NoobAI's ControlNet was included in the changes this time. I was surprised.๐Ÿ˜† I thought that LoRA 6 and LoRA 7 would probably be used internally in the future, so I tried to avoid touching them as much as possible in the MOD.

I decided to hold off on showing them for now since five should be enough ๐Ÿ˜

The main account stepped on a landmine and was nuked yesterday.๐Ÿ˜ญ
Well, it was an accident, so I think it will heal in time (hopefully).

It seems some malicious version were uploaded to PyPI, but theyโ€™ve been removed now.

Scary!๐Ÿ™€ Even famous libraries do that...

since five should be enough ๐Ÿ˜

I see. Especially with Gradio, it's hard to arrange items well even if there are a lot of them, and five is usually enough.

Information about the landmine space (don't click on the links in the posts!)

https://discuss.huggingface.co/t/cant-log-in-to-my-account/126966

Anyway, my main account has been restored.๐Ÿ˜€ It doesn't seem to be back to full strength yet, but I can log in.

Nice, looks like your accountโ€™s back
Great news

https://huggingface.co/spaces/r3gm/DiffuseCraft/discussions/11
Thanks! I found a small bug or unwanted behavior, so I've made a quick PR. I haven't tested it, so if you have a better implementation, please fix it using that method.
In the case of the LoRA page that includes training data in Civitai, there were cases where the training data zip was used as the file name.
There are quite a few behaviors that are not described in the Civitai REST API manual, so I don't think there is a specific correct way to deal with them. We just write them so that they work.๐Ÿ˜Ž

By the way, I got this opinion, but I think this is probably not a problem with my Space, DiffuseCraft, or stablepy, but rather some kind of problem with the Diffusers themselves. It might be fixed by renovating the scheduler, or it might not.

 it looks like DPM++ 3M SDE Karras creates some pretty bad ghosting image in realistic model. DPM++ 2M SDE Karras works fine, though. Not sure why that is.

Most people use Euler or Euler A including me, so they probably won't notice...๐Ÿ˜…

Edit:
I have confirmed that the above commit works. I have left a URL for a sample. Also, is ultralytics' pip being attacked again? For now, I have fixed the version number.
https://civitai.com/api/download/models/611370

https://huggingface.co/spaces/r3gm/DiffuseCraft/discussions/11
Thanks! I found a small bug or unwanted behavior, so I've made a quick PR. I haven't tested it, so if you have a better implementation, please fix it using that method.
In the case of the LoRA page that includes training data in Civitai, there were cases where the training data zip was used as the file name.
There are quite a few behaviors that are not described in the Civitai REST API manual, so I don't think there is a specific correct way to deal with them. We just write them so that they work.๐Ÿ˜Ž

thanks

By the way, I got this opinion, but I think this is probably not a problem with my Space, DiffuseCraft, or stablepy, but rather some kind of problem with the Diffusers themselves. It might be fixed by renovating the scheduler, or it might not.

 it looks like DPM++ 3M SDE Karras creates some pretty bad ghosting image in realistic model. DPM++ 2M SDE Karras works fine, though. Not sure why that is.

Most people use Euler or Euler A including me, so they probably won't notice...๐Ÿ˜…

I'll take a look at it

https://huggingface.co/posts/celinah/226648885614249
If it is eventually implemented in Diffusers, DDUF may need to be taken care of to some extent on the stablepy side. It will probably only be a small change, and it is still in the concept stage, so the specification is still in flux.๐Ÿ˜ช

Yes, hopefully, DDUF will just need small changes.

Sign up or log in to comment