vladmandic / automatic

SD.Next: Advanced Implementation of Stable Diffusion and other Diffusion-based generative image models
https://github.com/vladmandic/automatic
GNU Affero General Public License v3.0
5.71k stars 425 forks source link

[Feature]: Project save/load feature #905

Closed nistvan86 closed 1 year ago

nistvan86 commented 1 year ago

Feature description

Currently the only way to restore a previous generation is from an output image which has the generation data embedded as metadata, and send it to the "Text" or "Image" tab. However this doesn't include every parameter used.

For example the image metadata lacks the ControlNet source images used. Or in case the Dynamic Prompts or Unprompted extensions the original prompt/negative prompt with the template expressions are not kept. etc.

It would be nice to be able to restore a complete project quickly. I can imagine this as exporting it as a zip which contains the metadata (json/yaml) and all additional uploaded resource files. Then it's a matter of uploading this zip file again to get back to the project.

I don't expect this to be an easy feature, as probably the biggest barrier is that every extension stores it's UI settings differently. But maybe your fork could define a SD.Next specific API for extensions where it can fetch/send persistent data when a project is saved/restored and the community can patch extension repositories to support it.

Version Platform Description

No response

vladmandic commented 1 year ago

its not just ui problem, problem is that variables passed to extension are without context - all i'd know is array of some values, i wouldn't even know which value corresponds to which setting.

but regarding metadata - each extension can append to metadata just before image is saved, that is relatively easy and quick - and each extension should do that.

as-it-is, its outside of my scope to analyze each extension separately (that is bound to fail). but asking extension owner to append their metadata? for sure.

for example, those 3 lines in extension would be enough as main app will call that method just before image is saved:

def on_before_image_saved(params: ImageSaveParams):
    if 'parameters' in params.pnginfo: # parameters exist so append ours
        params.pnginfo['parameters'] += f', Score: {score}'
nistvan86 commented 1 year ago

I don't think this is sufficient for eg. ControlNet to save/restore the used control images. It's essentially one big ever growing string. If I try to serialize the image into that it will crash the image preview of the UI which shows this string.

vladmandic commented 1 year ago

of course. same would apply to any workflow that relies on img2img. input image is critical for reproducability of results, but it cannot be saved as part of params.

nistvan86 commented 1 year ago

You are right, img2img is even more obvious example to this restore issue.

Makes me wonder if it would be possible to create additional binary chunks inside the output png image to save these eg. through this on_before_image_saved, so you won't have to come up with something completely new. (I'm not sure how the restore currently is happening from existing metadata).

I've seen some creative uses of extra data on top of png files, like TavernAI's character definition gets embedded into the avatar image. Or the PICO-8 fantasy console's game files are png files with the artwork of the game and the ROM image piggybacked on it.

vladmandic commented 1 year ago

interesting idea. unfortunately, each metadata value must fit into single chunk and maximum chunk size is 64kb.