Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use 🧨diffusers model #1583

Merged
merged 251 commits into from
Jan 15, 2023
Merged

use 🧨diffusers model #1583

merged 251 commits into from
Jan 15, 2023

Conversation

keturn
Copy link
Contributor

@keturn keturn commented Nov 27, 2022

The goal is to reduce the amount of model code InvokeAI has to maintain by integrating https://github.com/huggingface/diffusers , using that to replace the existing ldm (descended from the original CompVis implementation).

I think the plan is that we keep the public APIs in ldm.invoke.generator stable while swapping out the implementations to be diffusers-based.

Discord discussion thread: https://discord.com/channels/1020123559063990373/1031668022294884392

[This is a continuation of #1384. The branch is now hosted in the InvokeAI repo instead of a fork for easier collaboration.]

Usage

Add a section to your models.yaml like this:

diffusers-1.5:
  description: Diffusers version of Stable Diffusion version 1.5
  format: diffusers
  repo_id: runwayml/stable-diffusion-v1-5

Note the format: diffusers.
The repo_id is as it appears on huggingface.co.

Sub-Tasks

i.e. things keturn would love to delegate.

To Do: txt2img

  • don't load redundant models! (i.e. both the ckpt and the diffusers formats)
  • allow scheduler selection
  • support extra scheduler parameters (e.g. DDIM's eta).
  • honor float16 setting for loading model
  • update callback users with the new signature.
    • at least done for invoke_ai_web_server. Not sure if the other instances are still in use?
  • fix prompt fragment weighting. Refer to WeightedFrozenCLIPEmbedder.
  • honor safety-checker setting
  • allow loading a custom VAE
  • make work with inpainting model
  • long prompts error out, instead of logging and proceeding with the truncated version. (May be only with certain prompt operators.)
  • karras_max?

waiting on upstream diffusers

To Do: img2img

  • bug: crashes when strength is too low (zero timestamps. upstream bug in img2img pipeline?)
  • make sure we use the correct seeded noise
  • make work with inpainting model
  • decide if we need to keep --inpaint_replace now that --strength works. (Or should it apply to the results of the infill method?)
    • decision: drop inpaint_replace

To Do: txt2img2img (high-res optimization)

  • rewrite to our diffusers-based pipeline

To Do: inpainting

To Do: embiggen

  • embiggen!
    • (I took a quick look: it mostly goes through invoke's generate API instead of directly accessing the model or schedulers, so hopefully doesn't need to change much.)

Stable Diffusion 2.x support

(I think we can merge the PR without this, but we'll want it before release.)

  • black images from stable-diffusion-2.1
    • seems to only apply to the v-prediction model. stable-diffusion-2.1-base works fine.
    • also works fine when xformers is enabled.

@keturn keturn mentioned this pull request Nov 27, 2022
15 tasks
@damian0815
Copy link
Contributor

damian0815 commented Nov 27, 2022

currently getting AttributeError: 'LatentDiffusion' object has no attribute 'image_from_embeddings' doing txt2img

fixed, fix was "read the instructions in the top of the PR about putting a format: diffusers model in your models.yaml"

@damian0815
Copy link
Contributor

damian0815 commented Nov 27, 2022

looks like this needs torch==1.13 on macOS, otherwise it crashes in diffusers lib with an error about views having to be contiguous

@damian0815
Copy link
Contributor

damian0815 commented Nov 27, 2022

something weird is going on because this is not a cat playing with a ball in the forest -s 10 -S 1699080397 -W 512 -H 512 -C 7.5 -A k_lms
000823 1699080397

k_euler produces the same composition

@keturn
Copy link
Contributor Author

keturn commented Nov 27, 2022

Seems to have worked on mps here with torch 1.12: https://github.com/invoke-ai/InvokeAI/actions/runs/3559296062/jobs/5978550236

click for banana sushi output

banana sushi

Does torch 1.13 on mac perform any better with this diffusers implementation? Or is it still much much slower than torch 1.12 with the old implementation?

@damian0815
Copy link
Contributor

Seems to have worked on mps here with torch 1.12: https://github.com/invoke-ai/InvokeAI/actions/runs/3559296062/jobs/5978550236

that's actually x64, not m1/mps (check the install requirements step, calls x64 python) - github does not offer M1 hosts afaik.

Does torch 1.13 on mac perform any better with this diffusers implementation? Or is it still much much slower than torch 1.12 with the old implementation?

it seems slow but i haven't paid too much attention

@damian0815
Copy link
Contributor

something is definitely broke on mps because this is supposedly banana sushi -s 10 -S 42 -W 512 -H 512 -C 7.5 -A k_lms
000825 42

@damian0815
Copy link
Contributor

apricot sushi produces exactly the same image, as does empty string. ok, so that means that on MPS the prompt embeddings tensor is being zero'd (or inf'd?) somehow. i'll look into it later.

@keturn
Copy link
Contributor Author

keturn commented Nov 27, 2022

that's actually x64, not m1/mps (check the install requirements step, calls x64 python) - github does not offer M1 hosts afaik.

yeah, hmm, I think you're right. Well that makes it very misleading to have a check named mac-mps-cpu

@damian0815
Copy link
Contributor

there is shared memory shenanigans going on in self.clip_embedder.encode (diffusers_pipeline.py line 309) on MPS that means that the second call overwrites the first-returned tensor. .clone() should fix it, testing now.

@damian0815
Copy link
Contributor

damian0815 commented Nov 27, 2022

ok there's some deep in the weeds bug in pytorch, because:

conditioned_next_x - unconditioned_next_x

result = all zeros

conditioned_next_x.clone() - unconditioned_next_x

result = looks reasonable

i don't know why this is happening and i don't know what to do about it

@keturn
Copy link
Contributor Author

keturn commented Nov 29, 2022

Some change I just pulled in from development introduced a crash on model load, so I threw this in there as a stopgap: invoke-ai/InvokeAI@185aa24 (#1583)

If I'm reading things correctly, embedding_manager is currently a submodel defined by

personalization_config:
target: ldm.modules.embedding_manager.EmbeddingManager

The model configs like https://huggingface.co/runwayml/stable-diffusion-v1-5/blob/main/model_index.json have no such personalization_config.

Does it feel necessary to have that be data-driven, or is that class reference something we can hardcode?

@keturn
Copy link
Contributor Author

keturn commented Nov 29, 2022

conditioned_next_x - unconditioned_next_x

result = all zeros

That's weird. Both on the same device and same dtype?

@keturn
Copy link
Contributor Author

keturn commented Nov 29, 2022

development brought in a few more references to model.embedding_manager on the default code path, so I've patched over them in a few more places.

It was a kludge in one place before, but now it's spreading. Should probably the the next thing we tackle in this branch.

@keturn
Copy link
Contributor Author

keturn commented Nov 30, 2022

I had it create an EmbeddingManager. I am not sure if it's working yet but at least it's back to not-crashing.

Also pushed a couple of fixes for deprecated diffusers things, cleaning up some of the warning messages it was spewing.

@damian0815
Copy link
Contributor

realising i never answered your question about the personalization_config keturn - yes, i think it can be hardcoded

@keturn keturn changed the base branch from development to main November 30, 2022 21:55
@keturn
Copy link
Contributor Author

keturn commented Nov 30, 2022

oof. re-resolving all the conflicts after the entirety of 2.2 was rebased was a doozy, but I think I did it okay.

@keturn
Copy link
Contributor Author

keturn commented Nov 30, 2022

🚧 PLZ HOLD. DO NOT PUSH TO THIS BRANCH FOR A BIT, I WILL NEED TO FORCE-PUSH IT. 🚧

oh fiddlesticks.

this branch was based off of develop, so it contains that history.

but that history all got squashed away when it merged in to main.

that means I'm going to have to rebase this branch on main so it's not dragging in the duplicate history... okay.

- put try: blocks around places where the system tries to load an embedding
  which is incompatible with the currently loaded model
- Preferences are stored in a file named text-inversion-training/preferences.conf
- Currently the resume-from-checkpoint option is not working correctly. Possible
  bug in textual_inversion_training.py?
lstein and others added 10 commits January 13, 2023 13:04
- Front end doesn't do anything yet!!!!
- Made change to model name parsing in CLI to support ability to have merged models
  with the "+" character in their names.
- recommend ckpt version of inpainting-1.5 to user
- fix get_noise() bug in ckpt version of omnibus.py
- update scripts will now fetch new INITIAL_MODELS.yaml so that
  configure_invokeai.py will know about the diffusers versions.
- added configure_invokeai.py to menu
- menu defaults to browser-based invoke
@lstein lstein marked this pull request as ready for review January 15, 2023 13:14
- Add information on how formats have changed and the upgrade process.
- Add short bug list.
Copy link
Collaborator

@lstein lstein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ready to merge this in.

@lstein lstein merged commit 6fdbc19 into main Jan 15, 2023
@lstein lstein deleted the dev/diffusers branch January 15, 2023 14:22
@mauwii
Copy link
Contributor

mauwii commented Jan 15, 2023

Not working if one switched to diffusers and back, hope this hasn't been done by too many users 😅

/Users/mauwii/git/invoke-ai/InvokeAI/ldm/invoke/model_manager.py:765 in migrate_models           │
│                                                                                                  │
│   762 │   │   │   source = models_dir /model                                                     │
│   763 │   │   │   if source.exists():                                                            │
│   764 │   │   │   │   print(f'DEBUG: Moving {models_dir / model} into hub')                      │
│ ❱ 765 │   │   │   │   move(models_dir / model, hub)                                              │
│   766 │   │                                                                                      │
│   767 │   │   # anything else gets moved into the diffusers directory                            │768 │   │   diffusers = models_dir / 'diffusers'                                               │
│                                                                                                  │
│ /Users/mauwii/.pyenv/versions/3.10.9/lib/python3.10/shutil.py:814 in move                        │
│                                                                                                  │
│    811 │   │   real_dst = os.path.join(dst, _basename(src))                                      │
│    812 │   │                                                                                     │
│    813 │   │   if os.path.exists(real_dst):                                                      │
│ ❱  814 │   │   │   raise Error("Destination path '%s' already exists" % real_dst)                │
│    815try:                                                                                  │
│    816 │   │   os.rename(src, real_dst)                                                          │
│    817except OSError:                                                                       │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
Error: Destination path '/Users/mauwii/git/invoke-ai/InvokeAI/models/hub/models--CompVis--stable-diffusion-safety-checker' already exists

same for models/hub/models--bert-base-uncased and /models/hub/models--openai--clip-vit-large-patch14

Having 2.1 as the default model is also kind of inconvenient, since it is not really working on my mac (while 1.5 is working better):

2.1 with k_heun 1.5 with k_heun
image image

Since I created a fresh venv I assume that I am not the only User with this issue 🤔

Just to have it in place: MacBook Air M1 - 16GB - 8 GPU - MacOS 13.1

@hipsterusername
Copy link
Member

Re: models--CompVis--stable-diffusion-safety-checker' already exists - Deleting the \hub\ folder if you're trying to switch back resolves the issue.

As far as 2.1 - I believe that might just be model quality, but we should be able to confirm by testing w/ a different tool, if anyone can offer to do that.

@keturn keturn added this to the 2.3 🧨 milestone Jan 15, 2023
@mauwii mauwii restored the dev/diffusers branch January 16, 2023 20:25
@keturn keturn deleted the dev/diffusers branch January 19, 2023 20:19
lstein added a commit that referenced this pull request Jan 24, 2023
…odel (#2367)

This PR attempts to fix `--free_gpu_mem` option that was not working in
CKPT-based diffuser model after #1583.

I noticed that the memory usage after #1583 did not decrease after
generating an image when `--free_gpu_mem` option was enabled.
It turns out that the option was not propagated into `Generator`
instance, hence the generation will always run without the memory saving
procedure.

This PR also related to #2326. Initially, I was trying to make
`--free_gpu_mem` works on 🤗 diffuser model as well.
In the process, I noticed that InvokeAI will raise an exception when
`--free_gpu_mem` is enabled.
I tried to quickly fix it by simply ignoring the exception and produce a
warning message to user's console.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.