Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 969d0f252c | |||
| 343f7c5c8a |
@@ -65,7 +65,6 @@ jobs:
|
|||||||
python -m uv pip install -e [quality,test]
|
python -m uv pip install -e [quality,test]
|
||||||
python -m uv pip install -U transformers@git+https://github.com/huggingface/transformers
|
python -m uv pip install -U transformers@git+https://github.com/huggingface/transformers
|
||||||
python -m uv pip install accelerate@git+https://github.com/huggingface/accelerate
|
python -m uv pip install accelerate@git+https://github.com/huggingface/accelerate
|
||||||
python -m uv pip install pytest-reportlog
|
|
||||||
|
|
||||||
- name: Environment
|
- name: Environment
|
||||||
run: |
|
run: |
|
||||||
@@ -151,7 +150,6 @@ jobs:
|
|||||||
${CONDA_RUN} python -m uv pip install -e [quality,test]
|
${CONDA_RUN} python -m uv pip install -e [quality,test]
|
||||||
${CONDA_RUN} python -m uv pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cpu
|
${CONDA_RUN} python -m uv pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cpu
|
||||||
${CONDA_RUN} python -m uv pip install accelerate@git+https://github.com/huggingface/accelerate
|
${CONDA_RUN} python -m uv pip install accelerate@git+https://github.com/huggingface/accelerate
|
||||||
${CONDA_RUN} python -m uv pip install pytest-reportlog
|
|
||||||
|
|
||||||
- name: Environment
|
- name: Environment
|
||||||
shell: arch -arch arm64 bash {0}
|
shell: arch -arch arm64 bash {0}
|
||||||
|
|||||||
@@ -105,4 +105,4 @@ jobs:
|
|||||||
python -m pytest -n 1 --max-worker-restart=0 --dist=loadfile \
|
python -m pytest -n 1 --max-worker-restart=0 --dist=loadfile \
|
||||||
-s -v \
|
-s -v \
|
||||||
--make-reports=tests_${{ matrix.config.report }} \
|
--make-reports=tests_${{ matrix.config.report }} \
|
||||||
tests/lora/
|
tests/lora/test_lora_layers_peft.py
|
||||||
|
|||||||
@@ -21,7 +21,10 @@ env:
|
|||||||
jobs:
|
jobs:
|
||||||
setup_torch_cuda_pipeline_matrix:
|
setup_torch_cuda_pipeline_matrix:
|
||||||
name: Setup Torch Pipelines CUDA Slow Tests Matrix
|
name: Setup Torch Pipelines CUDA Slow Tests Matrix
|
||||||
runs-on: ubuntu-latest
|
runs-on: [single-gpu, nvidia-gpu, t4, ci]
|
||||||
|
container:
|
||||||
|
image: diffusers/diffusers-pytorch-cpu # this is a CPU image, but we need it to fetch the matrix
|
||||||
|
options: --shm-size "16gb" --ipc host
|
||||||
outputs:
|
outputs:
|
||||||
pipeline_test_matrix: ${{ steps.fetch_pipeline_matrix.outputs.pipeline_test_matrix }}
|
pipeline_test_matrix: ${{ steps.fetch_pipeline_matrix.outputs.pipeline_test_matrix }}
|
||||||
steps:
|
steps:
|
||||||
@@ -29,20 +32,24 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 2
|
fetch-depth: 2
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v4
|
|
||||||
with:
|
|
||||||
python-version: "3.8"
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
pip install -e .
|
apt-get update && apt-get install libsndfile1-dev libgl1 -y
|
||||||
pip install huggingface_hub
|
python -m venv /opt/venv && export PATH="/opt/venv/bin:$PATH"
|
||||||
|
python -m uv pip install -e [quality,test]
|
||||||
|
python -m uv pip install accelerate@git+https://github.com/huggingface/accelerate.git
|
||||||
|
|
||||||
|
- name: Environment
|
||||||
|
run: |
|
||||||
|
python utils/print_env.py
|
||||||
|
|
||||||
- name: Fetch Pipeline Matrix
|
- name: Fetch Pipeline Matrix
|
||||||
id: fetch_pipeline_matrix
|
id: fetch_pipeline_matrix
|
||||||
run: |
|
run: |
|
||||||
matrix=$(python utils/fetch_torch_cuda_pipeline_test_matrix.py)
|
matrix=$(python utils/fetch_torch_cuda_pipeline_test_matrix.py)
|
||||||
echo $matrix
|
echo $matrix
|
||||||
echo "pipeline_test_matrix=$matrix" >> $GITHUB_OUTPUT
|
echo "pipeline_test_matrix=$matrix" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Pipeline Tests Artifacts
|
- name: Pipeline Tests Artifacts
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
|
|||||||
@@ -53,8 +53,6 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install -U setuptools wheel twine
|
pip install -U setuptools wheel twine
|
||||||
pip install -U torch --index-url https://download.pytorch.org/whl/cpu
|
|
||||||
pip install -U transformers
|
|
||||||
|
|
||||||
- name: Build the dist files
|
- name: Build the dist files
|
||||||
run: python setup.py bdist_wheel && python setup.py sdist
|
run: python setup.py bdist_wheel && python setup.py sdist
|
||||||
|
|||||||
@@ -19,16 +19,6 @@ authors:
|
|||||||
family-names: Rasul
|
family-names: Rasul
|
||||||
- given-names: Mishig
|
- given-names: Mishig
|
||||||
family-names: Davaadorj
|
family-names: Davaadorj
|
||||||
- given-names: Dhruv
|
|
||||||
family-names: Nair
|
|
||||||
- given-names: Sayak
|
|
||||||
family-names: Paul
|
|
||||||
- given-names: Steven
|
|
||||||
family-names: Liu
|
|
||||||
- given-names: William
|
|
||||||
family-names: Berman
|
|
||||||
- given-names: Yiyi
|
|
||||||
family-names: Xu
|
|
||||||
- given-names: Thomas
|
- given-names: Thomas
|
||||||
family-names: Wolf
|
family-names: Wolf
|
||||||
repository-code: 'https://github.com/huggingface/diffusers'
|
repository-code: 'https://github.com/huggingface/diffusers'
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ Please refer to the [How to use Stable Diffusion in Apple Silicon](https://huggi
|
|||||||
|
|
||||||
## Quickstart
|
## Quickstart
|
||||||
|
|
||||||
Generating outputs is super easy with 🤗 Diffusers. To generate an image from text, use the `from_pretrained` method to load any pretrained diffusion model (browse the [Hub](https://huggingface.co/models?library=diffusers&sort=downloads) for 22000+ checkpoints):
|
Generating outputs is super easy with 🤗 Diffusers. To generate an image from text, use the `from_pretrained` method to load any pretrained diffusion model (browse the [Hub](https://huggingface.co/models?library=diffusers&sort=downloads) for 19000+ checkpoints):
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from diffusers import DiffusionPipeline
|
from diffusers import DiffusionPipeline
|
||||||
@@ -219,7 +219,7 @@ Also, say 👋 in our public Discord channel <a href="https://discord.gg/G7tWnz9
|
|||||||
- https://github.com/deep-floyd/IF
|
- https://github.com/deep-floyd/IF
|
||||||
- https://github.com/bentoml/BentoML
|
- https://github.com/bentoml/BentoML
|
||||||
- https://github.com/bmaltais/kohya_ss
|
- https://github.com/bmaltais/kohya_ss
|
||||||
- +9000 other amazing GitHub repositories 💪
|
- +8000 other amazing GitHub repositories 💪
|
||||||
|
|
||||||
Thank you for using us ❤️.
|
Thank you for using us ❤️.
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ We also want to thank @heejkoo for the very helpful overview of papers, code and
|
|||||||
|
|
||||||
```bibtex
|
```bibtex
|
||||||
@misc{von-platen-etal-2022-diffusers,
|
@misc{von-platen-etal-2022-diffusers,
|
||||||
author = {Patrick von Platen and Suraj Patil and Anton Lozhkov and Pedro Cuenca and Nathan Lambert and Kashif Rasul and Mishig Davaadorj and Dhruv Nair and Sayak Paul and William Berman and Yiyi Xu and Steven Liu and Thomas Wolf},
|
author = {Patrick von Platen and Suraj Patil and Anton Lozhkov and Pedro Cuenca and Nathan Lambert and Kashif Rasul and Mishig Davaadorj and Thomas Wolf},
|
||||||
title = {Diffusers: State-of-the-art diffusion models},
|
title = {Diffusers: State-of-the-art diffusion models},
|
||||||
year = {2022},
|
year = {2022},
|
||||||
publisher = {GitHub},
|
publisher = {GitHub},
|
||||||
|
|||||||
@@ -400,10 +400,6 @@
|
|||||||
title: DPMSolverSDEScheduler
|
title: DPMSolverSDEScheduler
|
||||||
- local: api/schedulers/singlestep_dpm_solver
|
- local: api/schedulers/singlestep_dpm_solver
|
||||||
title: DPMSolverSinglestepScheduler
|
title: DPMSolverSinglestepScheduler
|
||||||
- local: api/schedulers/edm_multistep_dpm_solver
|
|
||||||
title: EDMDPMSolverMultistepScheduler
|
|
||||||
- local: api/schedulers/edm_euler
|
|
||||||
title: EDMEulerScheduler
|
|
||||||
- local: api/schedulers/euler_ancestral
|
- local: api/schedulers/euler_ancestral
|
||||||
title: EulerAncestralDiscreteScheduler
|
title: EulerAncestralDiscreteScheduler
|
||||||
- local: api/schedulers/euler
|
- local: api/schedulers/euler
|
||||||
|
|||||||
@@ -408,29 +408,6 @@ Make sure to check out the Schedulers [guide](../../using-diffusers/schedulers)
|
|||||||
|
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th align=center>Without FreeInit enabled</th>
|
|
||||||
<th align=center>With FreeInit enabled</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align=center>
|
|
||||||
panda playing a guitar
|
|
||||||
<br />
|
|
||||||
<img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/animatediff-no-freeinit.gif"
|
|
||||||
alt="panda playing a guitar"
|
|
||||||
style="width: 300px;" />
|
|
||||||
</td>
|
|
||||||
<td align=center>
|
|
||||||
panda playing a guitar
|
|
||||||
<br/>
|
|
||||||
<img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/animatediff-freeinit.gif"
|
|
||||||
alt="panda playing a guitar"
|
|
||||||
style="width: 300px;" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
## Using AnimateLCM
|
## Using AnimateLCM
|
||||||
|
|
||||||
[AnimateLCM](https://animatelcm.github.io/) is a motion module checkpoint and an [LCM LoRA](https://huggingface.co/docs/diffusers/using-diffusers/inference_with_lcm_lora) that have been created using a consistency learning strategy that decouples the distillation of the image generation priors and the motion generation priors.
|
[AnimateLCM](https://animatelcm.github.io/) is a motion module checkpoint and an [LCM LoRA](https://huggingface.co/docs/diffusers/using-diffusers/inference_with_lcm_lora) that have been created using a consistency learning strategy that decouples the distillation of the image generation priors and the motion generation priors.
|
||||||
|
|||||||
@@ -172,41 +172,3 @@ inpaint = StableDiffusionInpaintPipeline(**text2img.components)
|
|||||||
|
|
||||||
# now you can use text2img(...), img2img(...), inpaint(...) just like the call methods of each respective pipeline
|
# now you can use text2img(...), img2img(...), inpaint(...) just like the call methods of each respective pipeline
|
||||||
```
|
```
|
||||||
|
|
||||||
### Create web demos using `gradio`
|
|
||||||
|
|
||||||
The Stable Diffusion pipelines are automatically supported in [Gradio](https://github.com/gradio-app/gradio/), a library that makes creating beautiful and user-friendly machine learning apps on the web a breeze. First, make sure you have Gradio installed:
|
|
||||||
|
|
||||||
```
|
|
||||||
pip install -U gradio
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, create a web demo around any Stable Diffusion-based pipeline. For example, you can create an image generation pipeline in a single line of code with Gradio's [`Interface.from_pipeline`](https://www.gradio.app/docs/interface#interface-from-pipeline) function:
|
|
||||||
|
|
||||||
```py
|
|
||||||
from diffusers import StableDiffusionPipeline
|
|
||||||
import gradio as gr
|
|
||||||
|
|
||||||
pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4")
|
|
||||||
|
|
||||||
gr.Interface.from_pipeline(pipe).launch()
|
|
||||||
```
|
|
||||||
|
|
||||||
which opens an intuitive drag-and-drop interface in your browser:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Similarly, you could create a demo for an image-to-image pipeline with:
|
|
||||||
|
|
||||||
```py
|
|
||||||
from diffusers import StableDiffusionImg2ImgPipeline
|
|
||||||
import gradio as gr
|
|
||||||
|
|
||||||
|
|
||||||
pipe = StableDiffusionImg2ImgPipeline.from_pretrained("runwayml/stable-diffusion-v1-5")
|
|
||||||
|
|
||||||
gr.Interface.from_pipeline(pipe).launch()
|
|
||||||
```
|
|
||||||
|
|
||||||
By default, the web demo runs on a local server. If you'd like to share it with others, you can generate a temporary public
|
|
||||||
link by setting `share=True` in `launch()`. Or, you can host your demo on [Hugging Face Spaces](https://huggingface.co/spaces)https://huggingface.co/spaces for a permanent link.
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<!--Copyright 2024 The HuggingFace Team. All rights reserved.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
||||||
the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
specific language governing permissions and limitations under the License.
|
|
||||||
-->
|
|
||||||
|
|
||||||
# EDMEulerScheduler
|
|
||||||
|
|
||||||
The Karras formulation of the Euler scheduler (Algorithm 2) from the [Elucidating the Design Space of Diffusion-Based Generative Models](https://huggingface.co/papers/2206.00364) paper by Karras et al. This is a fast scheduler which can often generate good outputs in 20-30 steps. The scheduler is based on the original [k-diffusion](https://github.com/crowsonkb/k-diffusion/blob/481677d114f6ea445aa009cf5bd7a9cdee909e47/k_diffusion/sampling.py#L51) implementation by [Katherine Crowson](https://github.com/crowsonkb/).
|
|
||||||
|
|
||||||
|
|
||||||
## EDMEulerScheduler
|
|
||||||
[[autodoc]] EDMEulerScheduler
|
|
||||||
|
|
||||||
## EDMEulerSchedulerOutput
|
|
||||||
[[autodoc]] schedulers.scheduling_edm_euler.EDMEulerSchedulerOutput
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
<!--Copyright 2024 The HuggingFace Team. All rights reserved.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
||||||
the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
specific language governing permissions and limitations under the License.
|
|
||||||
-->
|
|
||||||
|
|
||||||
# EDMDPMSolverMultistepScheduler
|
|
||||||
|
|
||||||
`EDMDPMSolverMultistepScheduler` is a [Karras formulation](https://huggingface.co/papers/2206.00364) of `DPMSolverMultistep`, a multistep scheduler from [DPM-Solver: A Fast ODE Solver for Diffusion Probabilistic Model Sampling in Around 10 Steps](https://huggingface.co/papers/2206.00927) and [DPM-Solver++: Fast Solver for Guided Sampling of Diffusion Probabilistic Models](https://huggingface.co/papers/2211.01095) by Cheng Lu, Yuhao Zhou, Fan Bao, Jianfei Chen, Chongxuan Li, and Jun Zhu.
|
|
||||||
|
|
||||||
DPMSolver (and the improved version DPMSolver++) is a fast dedicated high-order solver for diffusion ODEs with convergence order guarantee. Empirically, DPMSolver sampling with only 20 steps can generate high-quality
|
|
||||||
samples, and it can generate quite good samples even in 10 steps.
|
|
||||||
|
|
||||||
## EDMDPMSolverMultistepScheduler
|
|
||||||
[[autodoc]] EDMDPMSolverMultistepScheduler
|
|
||||||
|
|
||||||
## SchedulerOutput
|
|
||||||
[[autodoc]] schedulers.scheduling_utils.SchedulerOutput
|
|
||||||
@@ -45,7 +45,7 @@ Make sure to include the token `toy_face` in the prompt and then you can perform
|
|||||||
```python
|
```python
|
||||||
prompt = "toy_face of a hacker with a hoodie"
|
prompt = "toy_face of a hacker with a hoodie"
|
||||||
|
|
||||||
lora_scale = 0.9
|
lora_scale= 0.9
|
||||||
image = pipe(
|
image = pipe(
|
||||||
prompt, num_inference_steps=30, cross_attention_kwargs={"scale": lora_scale}, generator=torch.manual_seed(0)
|
prompt, num_inference_steps=30, cross_attention_kwargs={"scale": lora_scale}, generator=torch.manual_seed(0)
|
||||||
).images[0]
|
).images[0]
|
||||||
@@ -114,7 +114,7 @@ To return to only using one adapter, use the [`~diffusers.loaders.UNet2DConditio
|
|||||||
pipe.set_adapters("toy")
|
pipe.set_adapters("toy")
|
||||||
|
|
||||||
prompt = "toy_face of a hacker with a hoodie"
|
prompt = "toy_face of a hacker with a hoodie"
|
||||||
lora_scale = 0.9
|
lora_scale= 0.9
|
||||||
image = pipe(
|
image = pipe(
|
||||||
prompt, num_inference_steps=30, cross_attention_kwargs={"scale": lora_scale}, generator=torch.manual_seed(0)
|
prompt, num_inference_steps=30, cross_attention_kwargs={"scale": lora_scale}, generator=torch.manual_seed(0)
|
||||||
).images[0]
|
).images[0]
|
||||||
@@ -127,12 +127,11 @@ Or to disable all adapters entirely, use the [`~diffusers.loaders.UNet2DConditio
|
|||||||
pipe.disable_lora()
|
pipe.disable_lora()
|
||||||
|
|
||||||
prompt = "toy_face of a hacker with a hoodie"
|
prompt = "toy_face of a hacker with a hoodie"
|
||||||
|
lora_scale= 0.9
|
||||||
image = pipe(prompt, num_inference_steps=30, generator=torch.manual_seed(0)).images[0]
|
image = pipe(prompt, num_inference_steps=30, generator=torch.manual_seed(0)).images[0]
|
||||||
image
|
image
|
||||||
```
|
```
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Manage active adapters
|
## Manage active adapters
|
||||||
|
|
||||||
You have attached multiple adapters in this tutorial, and if you're feeling a bit lost on what adapters have been attached to the pipeline's components, use the [`~diffusers.loaders.LoraLoaderMixin.get_active_adapters`] method to check the list of active adapters:
|
You have attached multiple adapters in this tutorial, and if you're feeling a bit lost on what adapters have been attached to the pipeline's components, use the [`~diffusers.loaders.LoraLoaderMixin.get_active_adapters`] method to check the list of active adapters:
|
||||||
|
|||||||
@@ -239,7 +239,5 @@ pipeline.to("cuda")
|
|||||||
prompt = "柴犬、カラフルアート"
|
prompt = "柴犬、カラフルアート"
|
||||||
|
|
||||||
image = pipeline(prompt=prompt).images[0]
|
image = pipeline(prompt=prompt).images[0]
|
||||||
```
|
|
||||||
|
|
||||||
> [!TIP]
|
```
|
||||||
> When using `trust_remote_code=True`, it is also strongly encouraged to pass a commit hash as a `revision` to make sure the author of the models did not update the code with some malicious new lines (unless you fully trust the authors of the models).
|
|
||||||
@@ -60,23 +60,6 @@ repo_id = "runwayml/stable-diffusion-v1-5"
|
|||||||
pipe = StableDiffusionImg2ImgPipeline.from_pretrained(repo_id)
|
pipe = StableDiffusionImg2ImgPipeline.from_pretrained(repo_id)
|
||||||
```
|
```
|
||||||
|
|
||||||
You can use the Space below to gauge the memory requirements of a pipeline you want to load beforehand without downloading the pipeline checkpoints:
|
|
||||||
|
|
||||||
<div class="block dark:hidden">
|
|
||||||
<iframe
|
|
||||||
src="https://diffusers-compute-pipeline-size.hf.space?__theme=light"
|
|
||||||
width="850"
|
|
||||||
height="1600"
|
|
||||||
></iframe>
|
|
||||||
</div>
|
|
||||||
<div class="hidden dark:block">
|
|
||||||
<iframe
|
|
||||||
src="https://diffusers-compute-pipeline-size.hf.space?__theme=dark"
|
|
||||||
width="850"
|
|
||||||
height="1600"
|
|
||||||
></iframe>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
### Local pipeline
|
### Local pipeline
|
||||||
|
|
||||||
To load a diffusion pipeline locally, use [`git-lfs`](https://git-lfs.github.com/) to manually download the checkpoint (in this case, [`runwayml/stable-diffusion-v1-5`](https://huggingface.co/runwayml/stable-diffusion-v1-5)) to your local disk. This creates a local folder, `./stable-diffusion-v1-5`, on your disk:
|
To load a diffusion pipeline locally, use [`git-lfs`](https://git-lfs.github.com/) to manually download the checkpoint (in this case, [`runwayml/stable-diffusion-v1-5`](https://huggingface.co/runwayml/stable-diffusion-v1-5)) to your local disk. This creates a local folder, `./stable-diffusion-v1-5`, on your disk:
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ Video generation is very memory intensive because you're essentially generating
|
|||||||
+ frames = pipe(image, decode_chunk_size=2, generator=generator, num_frames=25).frames[0]
|
+ frames = pipe(image, decode_chunk_size=2, generator=generator, num_frames=25).frames[0]
|
||||||
```
|
```
|
||||||
|
|
||||||
Using all these tricks together should lower the memory requirement to less than 8GB VRAM.
|
Using all these tricks togethere should lower the memory requirement to less than 8GB VRAM.
|
||||||
|
|
||||||
## Micro-conditioning
|
## Micro-conditioning
|
||||||
|
|
||||||
|
|||||||
@@ -355,7 +355,7 @@ unet_traced = torch.jit.load("unet_traced.pt")
|
|||||||
class TracedUNet(torch.nn.Module):
|
class TracedUNet(torch.nn.Module):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.in_channels = pipe.unet.config.in_channels
|
self.in_channels = pipe.unet.in_channels
|
||||||
self.device = pipe.unet.device
|
self.device = pipe.unet.device
|
||||||
|
|
||||||
def forward(self, latent_model_input, t, encoder_hidden_states):
|
def forward(self, latent_model_input, t, encoder_hidden_states):
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ Stable Diffusion 은 text-to-image *latent diffusion* 모델입니다. latent di
|
|||||||
|
|
||||||
```py
|
```py
|
||||||
>>> latents = torch.randn(
|
>>> latents = torch.randn(
|
||||||
... (batch_size, unet.config.in_channels, height // 8, width // 8),
|
... (batch_size, unet.in_channels, height // 8, width // 8),
|
||||||
... generator=generator,
|
... generator=generator,
|
||||||
... device=torch_device,
|
... device=torch_device,
|
||||||
... )
|
... )
|
||||||
|
|||||||
@@ -259,50 +259,6 @@ pip install git+https://github.com/huggingface/peft.git
|
|||||||
**Inference**
|
**Inference**
|
||||||
The inference is the same as if you train a regular LoRA 🤗
|
The inference is the same as if you train a regular LoRA 🤗
|
||||||
|
|
||||||
## Conducting EDM-style training
|
|
||||||
|
|
||||||
It's now possible to perform EDM-style training as proposed in [Elucidating the Design Space of Diffusion-Based Generative Models](https://arxiv.org/abs/2206.00364).
|
|
||||||
|
|
||||||
simply set:
|
|
||||||
|
|
||||||
```diff
|
|
||||||
+ --do_edm_style_training \
|
|
||||||
```
|
|
||||||
|
|
||||||
Other SDXL-like models that use the EDM formulation, such as [playgroundai/playground-v2.5-1024px-aesthetic](https://huggingface.co/playgroundai/playground-v2.5-1024px-aesthetic), can also be DreamBooth'd with the script. Below is an example command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
accelerate launch train_dreambooth_lora_sdxl_advanced.py \
|
|
||||||
--pretrained_model_name_or_path="playgroundai/playground-v2.5-1024px-aesthetic" \
|
|
||||||
--dataset_name="linoyts/3d_icon" \
|
|
||||||
--instance_prompt="3d icon in the style of TOK" \
|
|
||||||
--validation_prompt="a TOK icon of an astronaut riding a horse, in the style of TOK" \
|
|
||||||
--output_dir="3d-icon-SDXL-LoRA" \
|
|
||||||
--do_edm_style_training \
|
|
||||||
--caption_column="prompt" \
|
|
||||||
--mixed_precision="bf16" \
|
|
||||||
--resolution=1024 \
|
|
||||||
--train_batch_size=3 \
|
|
||||||
--repeats=1 \
|
|
||||||
--report_to="wandb"\
|
|
||||||
--gradient_accumulation_steps=1 \
|
|
||||||
--gradient_checkpointing \
|
|
||||||
--learning_rate=1.0 \
|
|
||||||
--text_encoder_lr=1.0 \
|
|
||||||
--optimizer="prodigy"\
|
|
||||||
--train_text_encoder_ti\
|
|
||||||
--train_text_encoder_ti_frac=0.5\
|
|
||||||
--lr_scheduler="constant" \
|
|
||||||
--lr_warmup_steps=0 \
|
|
||||||
--rank=8 \
|
|
||||||
--max_train_steps=1000 \
|
|
||||||
--checkpointing_steps=2000 \
|
|
||||||
--seed="0" \
|
|
||||||
--push_to_hub
|
|
||||||
```
|
|
||||||
|
|
||||||
> [!CAUTION]
|
|
||||||
> Min-SNR gamma is not supported with the EDM-style training yet. When training with the PlaygroundAI model, it's recommended to not pass any "variant".
|
|
||||||
|
|
||||||
### Tips and Tricks
|
### Tips and Tricks
|
||||||
Check out [these recommended practices](https://huggingface.co/blog/sdxl_lora_advanced_script#additional-good-practices)
|
Check out [these recommended practices](https://huggingface.co/blog/sdxl_lora_advanced_script#additional-good-practices)
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ from diffusers.utils.import_utils import is_xformers_available
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -14,11 +14,9 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import contextlib
|
|
||||||
import gc
|
import gc
|
||||||
import hashlib
|
import hashlib
|
||||||
import itertools
|
import itertools
|
||||||
import json
|
|
||||||
import logging
|
import logging
|
||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
@@ -39,7 +37,7 @@ import transformers
|
|||||||
from accelerate import Accelerator
|
from accelerate import Accelerator
|
||||||
from accelerate.logging import get_logger
|
from accelerate.logging import get_logger
|
||||||
from accelerate.utils import DistributedDataParallelKwargs, ProjectConfiguration, set_seed
|
from accelerate.utils import DistributedDataParallelKwargs, ProjectConfiguration, set_seed
|
||||||
from huggingface_hub import create_repo, hf_hub_download, upload_folder
|
from huggingface_hub import create_repo, upload_folder
|
||||||
from packaging import version
|
from packaging import version
|
||||||
from peft import LoraConfig, set_peft_model_state_dict
|
from peft import LoraConfig, set_peft_model_state_dict
|
||||||
from peft.utils import get_peft_model_state_dict
|
from peft.utils import get_peft_model_state_dict
|
||||||
@@ -57,8 +55,6 @@ from diffusers import (
|
|||||||
AutoencoderKL,
|
AutoencoderKL,
|
||||||
DDPMScheduler,
|
DDPMScheduler,
|
||||||
DPMSolverMultistepScheduler,
|
DPMSolverMultistepScheduler,
|
||||||
EDMEulerScheduler,
|
|
||||||
EulerDiscreteScheduler,
|
|
||||||
StableDiffusionXLPipeline,
|
StableDiffusionXLPipeline,
|
||||||
UNet2DConditionModel,
|
UNet2DConditionModel,
|
||||||
)
|
)
|
||||||
@@ -78,25 +74,11 @@ from diffusers.utils.torch_utils import is_compiled_module
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def determine_scheduler_type(pretrained_model_name_or_path, revision):
|
|
||||||
model_index_filename = "model_index.json"
|
|
||||||
if os.path.isdir(pretrained_model_name_or_path):
|
|
||||||
model_index = os.path.join(pretrained_model_name_or_path, model_index_filename)
|
|
||||||
else:
|
|
||||||
model_index = hf_hub_download(
|
|
||||||
repo_id=pretrained_model_name_or_path, filename=model_index_filename, revision=revision
|
|
||||||
)
|
|
||||||
|
|
||||||
with open(model_index, "r") as f:
|
|
||||||
scheduler_type = json.load(f)["scheduler"][1]
|
|
||||||
return scheduler_type
|
|
||||||
|
|
||||||
|
|
||||||
def save_model_card(
|
def save_model_card(
|
||||||
repo_id: str,
|
repo_id: str,
|
||||||
use_dora: bool,
|
use_dora: bool,
|
||||||
@@ -388,11 +370,6 @@ def parse_args(input_args=None):
|
|||||||
" `args.validation_prompt` multiple times: `args.num_validation_images`."
|
" `args.validation_prompt` multiple times: `args.num_validation_images`."
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
|
||||||
"--do_edm_style_training",
|
|
||||||
action="store_true",
|
|
||||||
help="Flag to conduct training using the EDM formulation as introduced in https://arxiv.org/abs/2206.00364.",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--with_prior_preservation",
|
"--with_prior_preservation",
|
||||||
default=False,
|
default=False,
|
||||||
@@ -1140,8 +1117,6 @@ def main(args):
|
|||||||
"You cannot use both --report_to=wandb and --hub_token due to a security risk of exposing your token."
|
"You cannot use both --report_to=wandb and --hub_token due to a security risk of exposing your token."
|
||||||
" Please use `huggingface-cli login` to authenticate with the Hub."
|
" Please use `huggingface-cli login` to authenticate with the Hub."
|
||||||
)
|
)
|
||||||
if args.do_edm_style_training and args.snr_gamma is not None:
|
|
||||||
raise ValueError("Min-SNR formulation is not supported when conducting EDM-style training.")
|
|
||||||
|
|
||||||
logging_dir = Path(args.output_dir, args.logging_dir)
|
logging_dir = Path(args.output_dir, args.logging_dir)
|
||||||
|
|
||||||
@@ -1259,19 +1234,7 @@ def main(args):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Load scheduler and models
|
# Load scheduler and models
|
||||||
scheduler_type = determine_scheduler_type(args.pretrained_model_name_or_path, args.revision)
|
noise_scheduler = DDPMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler")
|
||||||
if "EDM" in scheduler_type:
|
|
||||||
args.do_edm_style_training = True
|
|
||||||
noise_scheduler = EDMEulerScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler")
|
|
||||||
logger.info("Performing EDM-style training!")
|
|
||||||
elif args.do_edm_style_training:
|
|
||||||
noise_scheduler = EulerDiscreteScheduler.from_pretrained(
|
|
||||||
args.pretrained_model_name_or_path, subfolder="scheduler"
|
|
||||||
)
|
|
||||||
logger.info("Performing EDM-style training!")
|
|
||||||
else:
|
|
||||||
noise_scheduler = DDPMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler")
|
|
||||||
|
|
||||||
text_encoder_one = text_encoder_cls_one.from_pretrained(
|
text_encoder_one = text_encoder_cls_one.from_pretrained(
|
||||||
args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision, variant=args.variant
|
args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision, variant=args.variant
|
||||||
)
|
)
|
||||||
@@ -1289,12 +1252,7 @@ def main(args):
|
|||||||
revision=args.revision,
|
revision=args.revision,
|
||||||
variant=args.variant,
|
variant=args.variant,
|
||||||
)
|
)
|
||||||
latents_mean = latents_std = None
|
vae_scaling_factor = vae.config.scaling_factor
|
||||||
if hasattr(vae.config, "latents_mean") and vae.config.latents_mean is not None:
|
|
||||||
latents_mean = torch.tensor(vae.config.latents_mean).view(1, 4, 1, 1)
|
|
||||||
if hasattr(vae.config, "latents_std") and vae.config.latents_std is not None:
|
|
||||||
latents_std = torch.tensor(vae.config.latents_std).view(1, 4, 1, 1)
|
|
||||||
|
|
||||||
unet = UNet2DConditionModel.from_pretrained(
|
unet = UNet2DConditionModel.from_pretrained(
|
||||||
args.pretrained_model_name_or_path, subfolder="unet", revision=args.revision, variant=args.variant
|
args.pretrained_model_name_or_path, subfolder="unet", revision=args.revision, variant=args.variant
|
||||||
)
|
)
|
||||||
@@ -1832,19 +1790,6 @@ def main(args):
|
|||||||
disable=not accelerator.is_local_main_process,
|
disable=not accelerator.is_local_main_process,
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_sigmas(timesteps, n_dim=4, dtype=torch.float32):
|
|
||||||
# TODO: revisit other sampling algorithms
|
|
||||||
sigmas = noise_scheduler.sigmas.to(device=accelerator.device, dtype=dtype)
|
|
||||||
schedule_timesteps = noise_scheduler.timesteps.to(accelerator.device)
|
|
||||||
timesteps = timesteps.to(accelerator.device)
|
|
||||||
|
|
||||||
step_indices = [(schedule_timesteps == t).nonzero().item() for t in timesteps]
|
|
||||||
|
|
||||||
sigma = sigmas[step_indices].flatten()
|
|
||||||
while len(sigma.shape) < n_dim:
|
|
||||||
sigma = sigma.unsqueeze(-1)
|
|
||||||
return sigma
|
|
||||||
|
|
||||||
if args.train_text_encoder:
|
if args.train_text_encoder:
|
||||||
num_train_epochs_text_encoder = int(args.train_text_encoder_frac * args.num_train_epochs)
|
num_train_epochs_text_encoder = int(args.train_text_encoder_frac * args.num_train_epochs)
|
||||||
elif args.train_text_encoder_ti: # args.train_text_encoder_ti
|
elif args.train_text_encoder_ti: # args.train_text_encoder_ti
|
||||||
@@ -1896,15 +1841,9 @@ def main(args):
|
|||||||
pixel_values = batch["pixel_values"].to(dtype=vae.dtype)
|
pixel_values = batch["pixel_values"].to(dtype=vae.dtype)
|
||||||
model_input = vae.encode(pixel_values).latent_dist.sample()
|
model_input = vae.encode(pixel_values).latent_dist.sample()
|
||||||
|
|
||||||
if latents_mean is None and latents_std is None:
|
model_input = model_input * vae_scaling_factor
|
||||||
model_input = model_input * vae.config.scaling_factor
|
if args.pretrained_vae_model_name_or_path is None:
|
||||||
if args.pretrained_vae_model_name_or_path is None:
|
model_input = model_input.to(weight_dtype)
|
||||||
model_input = model_input.to(weight_dtype)
|
|
||||||
else:
|
|
||||||
latents_mean = latents_mean.to(device=model_input.device, dtype=model_input.dtype)
|
|
||||||
latents_std = latents_std.to(device=model_input.device, dtype=model_input.dtype)
|
|
||||||
model_input = (model_input - latents_mean) * vae.config.scaling_factor / latents_std
|
|
||||||
model_input = model_input.to(dtype=weight_dtype)
|
|
||||||
|
|
||||||
# Sample noise that we'll add to the latents
|
# Sample noise that we'll add to the latents
|
||||||
noise = torch.randn_like(model_input)
|
noise = torch.randn_like(model_input)
|
||||||
@@ -1915,32 +1854,15 @@ def main(args):
|
|||||||
)
|
)
|
||||||
|
|
||||||
bsz = model_input.shape[0]
|
bsz = model_input.shape[0]
|
||||||
|
|
||||||
# Sample a random timestep for each image
|
# Sample a random timestep for each image
|
||||||
if not args.do_edm_style_training:
|
timesteps = torch.randint(
|
||||||
timesteps = torch.randint(
|
0, noise_scheduler.config.num_train_timesteps, (bsz,), device=model_input.device
|
||||||
0, noise_scheduler.config.num_train_timesteps, (bsz,), device=model_input.device
|
)
|
||||||
)
|
timesteps = timesteps.long()
|
||||||
timesteps = timesteps.long()
|
|
||||||
else:
|
|
||||||
# in EDM formulation, the model is conditioned on the pre-conditioned noise levels
|
|
||||||
# instead of discrete timesteps, so here we sample indices to get the noise levels
|
|
||||||
# from `scheduler.timesteps`
|
|
||||||
indices = torch.randint(0, noise_scheduler.config.num_train_timesteps, (bsz,))
|
|
||||||
timesteps = noise_scheduler.timesteps[indices].to(device=model_input.device)
|
|
||||||
|
|
||||||
# Add noise to the model input according to the noise magnitude at each timestep
|
# Add noise to the model input according to the noise magnitude at each timestep
|
||||||
# (this is the forward diffusion process)
|
# (this is the forward diffusion process)
|
||||||
noisy_model_input = noise_scheduler.add_noise(model_input, noise, timesteps)
|
noisy_model_input = noise_scheduler.add_noise(model_input, noise, timesteps)
|
||||||
# For EDM-style training, we first obtain the sigmas based on the continuous timesteps.
|
|
||||||
# We then precondition the final model inputs based on these sigmas instead of the timesteps.
|
|
||||||
# Follow: Section 5 of https://arxiv.org/abs/2206.00364.
|
|
||||||
if args.do_edm_style_training:
|
|
||||||
sigmas = get_sigmas(timesteps, len(noisy_model_input.shape), noisy_model_input.dtype)
|
|
||||||
if "EDM" in scheduler_type:
|
|
||||||
inp_noisy_latents = noise_scheduler.precondition_inputs(noisy_model_input, sigmas)
|
|
||||||
else:
|
|
||||||
inp_noisy_latents = noisy_model_input / ((sigmas**2 + 1) ** 0.5)
|
|
||||||
|
|
||||||
# time ids
|
# time ids
|
||||||
add_time_ids = torch.cat(
|
add_time_ids = torch.cat(
|
||||||
@@ -1966,7 +1888,7 @@ def main(args):
|
|||||||
}
|
}
|
||||||
prompt_embeds_input = prompt_embeds.repeat(elems_to_repeat_text_embeds, 1, 1)
|
prompt_embeds_input = prompt_embeds.repeat(elems_to_repeat_text_embeds, 1, 1)
|
||||||
model_pred = unet(
|
model_pred = unet(
|
||||||
inp_noisy_latents if args.do_edm_style_training else noisy_model_input,
|
noisy_model_input,
|
||||||
timesteps,
|
timesteps,
|
||||||
prompt_embeds_input,
|
prompt_embeds_input,
|
||||||
added_cond_kwargs=unet_added_conditions,
|
added_cond_kwargs=unet_added_conditions,
|
||||||
@@ -1984,42 +1906,14 @@ def main(args):
|
|||||||
)
|
)
|
||||||
prompt_embeds_input = prompt_embeds.repeat(elems_to_repeat_text_embeds, 1, 1)
|
prompt_embeds_input = prompt_embeds.repeat(elems_to_repeat_text_embeds, 1, 1)
|
||||||
model_pred = unet(
|
model_pred = unet(
|
||||||
inp_noisy_latents if args.do_edm_style_training else noisy_model_input,
|
noisy_model_input, timesteps, prompt_embeds_input, added_cond_kwargs=unet_added_conditions
|
||||||
timesteps,
|
|
||||||
prompt_embeds_input,
|
|
||||||
added_cond_kwargs=unet_added_conditions,
|
|
||||||
).sample
|
).sample
|
||||||
|
|
||||||
weighting = None
|
|
||||||
if args.do_edm_style_training:
|
|
||||||
# Similar to the input preconditioning, the model predictions are also preconditioned
|
|
||||||
# on noised model inputs (before preconditioning) and the sigmas.
|
|
||||||
# Follow: Section 5 of https://arxiv.org/abs/2206.00364.
|
|
||||||
if "EDM" in scheduler_type:
|
|
||||||
model_pred = noise_scheduler.precondition_outputs(noisy_model_input, model_pred, sigmas)
|
|
||||||
else:
|
|
||||||
if noise_scheduler.config.prediction_type == "epsilon":
|
|
||||||
model_pred = model_pred * (-sigmas) + noisy_model_input
|
|
||||||
elif noise_scheduler.config.prediction_type == "v_prediction":
|
|
||||||
model_pred = model_pred * (-sigmas / (sigmas**2 + 1) ** 0.5) + (
|
|
||||||
noisy_model_input / (sigmas**2 + 1)
|
|
||||||
)
|
|
||||||
# We are not doing weighting here because it tends result in numerical problems.
|
|
||||||
# See: https://github.com/huggingface/diffusers/pull/7126#issuecomment-1968523051
|
|
||||||
# There might be other alternatives for weighting as well:
|
|
||||||
# https://github.com/huggingface/diffusers/pull/7126#discussion_r1505404686
|
|
||||||
if "EDM" not in scheduler_type:
|
|
||||||
weighting = (sigmas**-2.0).float()
|
|
||||||
|
|
||||||
# Get the target for loss depending on the prediction type
|
# Get the target for loss depending on the prediction type
|
||||||
if noise_scheduler.config.prediction_type == "epsilon":
|
if noise_scheduler.config.prediction_type == "epsilon":
|
||||||
target = model_input if args.do_edm_style_training else noise
|
target = noise
|
||||||
elif noise_scheduler.config.prediction_type == "v_prediction":
|
elif noise_scheduler.config.prediction_type == "v_prediction":
|
||||||
target = (
|
target = noise_scheduler.get_velocity(model_input, noise, timesteps)
|
||||||
model_input
|
|
||||||
if args.do_edm_style_training
|
|
||||||
else noise_scheduler.get_velocity(model_input, noise, timesteps)
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Unknown prediction type {noise_scheduler.config.prediction_type}")
|
raise ValueError(f"Unknown prediction type {noise_scheduler.config.prediction_type}")
|
||||||
|
|
||||||
@@ -2029,28 +1923,10 @@ def main(args):
|
|||||||
target, target_prior = torch.chunk(target, 2, dim=0)
|
target, target_prior = torch.chunk(target, 2, dim=0)
|
||||||
|
|
||||||
# Compute prior loss
|
# Compute prior loss
|
||||||
if weighting is not None:
|
prior_loss = F.mse_loss(model_pred_prior.float(), target_prior.float(), reduction="mean")
|
||||||
prior_loss = torch.mean(
|
|
||||||
(weighting.float() * (model_pred_prior.float() - target_prior.float()) ** 2).reshape(
|
|
||||||
target_prior.shape[0], -1
|
|
||||||
),
|
|
||||||
1,
|
|
||||||
)
|
|
||||||
prior_loss = prior_loss.mean()
|
|
||||||
else:
|
|
||||||
prior_loss = F.mse_loss(model_pred_prior.float(), target_prior.float(), reduction="mean")
|
|
||||||
|
|
||||||
if args.snr_gamma is None:
|
if args.snr_gamma is None:
|
||||||
if weighting is not None:
|
loss = F.mse_loss(model_pred.float(), target.float(), reduction="mean")
|
||||||
loss = torch.mean(
|
|
||||||
(weighting.float() * (model_pred.float() - target.float()) ** 2).reshape(
|
|
||||||
target.shape[0], -1
|
|
||||||
),
|
|
||||||
1,
|
|
||||||
)
|
|
||||||
loss = loss.mean()
|
|
||||||
else:
|
|
||||||
loss = F.mse_loss(model_pred.float(), target.float(), reduction="mean")
|
|
||||||
else:
|
else:
|
||||||
# Compute loss-weights as per Section 3.4 of https://arxiv.org/abs/2303.09556.
|
# Compute loss-weights as per Section 3.4 of https://arxiv.org/abs/2303.09556.
|
||||||
# Since we predict the noise instead of x_0, the original formulation is slightly changed.
|
# Since we predict the noise instead of x_0, the original formulation is slightly changed.
|
||||||
@@ -2173,18 +2049,17 @@ def main(args):
|
|||||||
# We train on the simplified learning objective. If we were previously predicting a variance, we need the scheduler to ignore it
|
# We train on the simplified learning objective. If we were previously predicting a variance, we need the scheduler to ignore it
|
||||||
scheduler_args = {}
|
scheduler_args = {}
|
||||||
|
|
||||||
if not args.do_edm_style_training:
|
if "variance_type" in pipeline.scheduler.config:
|
||||||
if "variance_type" in pipeline.scheduler.config:
|
variance_type = pipeline.scheduler.config.variance_type
|
||||||
variance_type = pipeline.scheduler.config.variance_type
|
|
||||||
|
|
||||||
if variance_type in ["learned", "learned_range"]:
|
if variance_type in ["learned", "learned_range"]:
|
||||||
variance_type = "fixed_small"
|
variance_type = "fixed_small"
|
||||||
|
|
||||||
scheduler_args["variance_type"] = variance_type
|
scheduler_args["variance_type"] = variance_type
|
||||||
|
|
||||||
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(
|
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(
|
||||||
pipeline.scheduler.config, **scheduler_args
|
pipeline.scheduler.config, **scheduler_args
|
||||||
)
|
)
|
||||||
|
|
||||||
pipeline = pipeline.to(accelerator.device)
|
pipeline = pipeline.to(accelerator.device)
|
||||||
pipeline.set_progress_bar_config(disable=True)
|
pipeline.set_progress_bar_config(disable=True)
|
||||||
@@ -2192,13 +2067,8 @@ def main(args):
|
|||||||
# run inference
|
# run inference
|
||||||
generator = torch.Generator(device=accelerator.device).manual_seed(args.seed) if args.seed else None
|
generator = torch.Generator(device=accelerator.device).manual_seed(args.seed) if args.seed else None
|
||||||
pipeline_args = {"prompt": args.validation_prompt}
|
pipeline_args = {"prompt": args.validation_prompt}
|
||||||
inference_ctx = (
|
|
||||||
contextlib.nullcontext()
|
|
||||||
if "playground" in args.pretrained_model_name_or_path
|
|
||||||
else torch.cuda.amp.autocast()
|
|
||||||
)
|
|
||||||
|
|
||||||
with inference_ctx:
|
with torch.cuda.amp.autocast():
|
||||||
images = [
|
images = [
|
||||||
pipeline(**pipeline_args, generator=generator).images[0]
|
pipeline(**pipeline_args, generator=generator).images[0]
|
||||||
for _ in range(args.num_validation_images)
|
for _ in range(args.num_validation_images)
|
||||||
@@ -2274,18 +2144,15 @@ def main(args):
|
|||||||
# We train on the simplified learning objective. If we were previously predicting a variance, we need the scheduler to ignore it
|
# We train on the simplified learning objective. If we were previously predicting a variance, we need the scheduler to ignore it
|
||||||
scheduler_args = {}
|
scheduler_args = {}
|
||||||
|
|
||||||
if not args.do_edm_style_training:
|
if "variance_type" in pipeline.scheduler.config:
|
||||||
if "variance_type" in pipeline.scheduler.config:
|
variance_type = pipeline.scheduler.config.variance_type
|
||||||
variance_type = pipeline.scheduler.config.variance_type
|
|
||||||
|
|
||||||
if variance_type in ["learned", "learned_range"]:
|
if variance_type in ["learned", "learned_range"]:
|
||||||
variance_type = "fixed_small"
|
variance_type = "fixed_small"
|
||||||
|
|
||||||
scheduler_args["variance_type"] = variance_type
|
scheduler_args["variance_type"] = variance_type
|
||||||
|
|
||||||
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(
|
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(pipeline.scheduler.config, **scheduler_args)
|
||||||
pipeline.scheduler.config, **scheduler_args
|
|
||||||
)
|
|
||||||
|
|
||||||
# load attention processors
|
# load attention processors
|
||||||
pipeline.load_lora_weights(args.output_dir)
|
pipeline.load_lora_weights(args.output_dir)
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
# Community Pipeline Examples
|
# Community Examples
|
||||||
|
|
||||||
> **For more information about community pipelines, please have a look at [this issue](https://github.com/huggingface/diffusers/issues/841).**
|
> **For more information about community pipelines, please have a look at [this issue](https://github.com/huggingface/diffusers/issues/841).**
|
||||||
|
|
||||||
**Community pipeline** examples consist pipelines that have been added by the community.
|
**Community** examples consist of both inference and training examples that have been added by the community.
|
||||||
Please have a look at the following tables to get an overview of all community examples. Click on the **Code Example** to get a copy-and-paste ready code example that you can try out.
|
Please have a look at the following table to get an overview of all community examples. Click on the **Code Example** to get a copy-and-paste ready code example that you can try out.
|
||||||
If a community pipeline doesn't work as expected, please open an issue and ping the author on it.
|
If a community doesn't work as expected, please open an issue and ping the author on it.
|
||||||
|
|
||||||
Please also check out our [Community Scripts](https://github.com/huggingface/diffusers/blob/main/examples/community/README_community_scripts.md) examples for tips and tricks that you can use with diffusers without having to run a community pipeline.
|
|
||||||
|
|
||||||
| Example | Description | Code Example | Colab | Author |
|
| Example | Description | Code Example | Colab | Author |
|
||||||
|:--------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------:|
|
|:--------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------:|
|
||||||
@@ -1889,7 +1887,7 @@ In the above code, the `prompt2` is appended to the `prompt`, which is more than
|
|||||||
|
|
||||||
For more results, checkout [PR #6114](https://github.com/huggingface/diffusers/pull/6114).
|
For more results, checkout [PR #6114](https://github.com/huggingface/diffusers/pull/6114).
|
||||||
|
|
||||||
### Example Images Mixing (with CoCa)
|
## Example Images Mixing (with CoCa)
|
||||||
```python
|
```python
|
||||||
import requests
|
import requests
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
@@ -2936,7 +2934,7 @@ pipe(prompt =prompt, rp_args = rp_args)
|
|||||||
|
|
||||||
The Pipeline supports `compel` syntax. Input prompts using the `compel` structure will be automatically applied and processed.
|
The Pipeline supports `compel` syntax. Input prompts using the `compel` structure will be automatically applied and processed.
|
||||||
|
|
||||||
### Diffusion Posterior Sampling Pipeline
|
## Diffusion Posterior Sampling Pipeline
|
||||||
* Reference paper
|
* Reference paper
|
||||||
```
|
```
|
||||||
@article{chung2022diffusion,
|
@article{chung2022diffusion,
|
||||||
|
|||||||
@@ -1,232 +0,0 @@
|
|||||||
# Community Scripts
|
|
||||||
|
|
||||||
**Community scripts** consist of inference examples using Diffusers pipelines that have been added by the community.
|
|
||||||
Please have a look at the following table to get an overview of all community examples. Click on the **Code Example** to get a copy-and-paste code example that you can try out.
|
|
||||||
If a community script doesn't work as expected, please open an issue and ping the author on it.
|
|
||||||
|
|
||||||
| Example | Description | Code Example | Colab | Author |
|
|
||||||
|:--------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------:|
|
|
||||||
| Using IP-Adapter with negative noise | Using negative noise with IP-adapter to better control the generation (see the [original post](https://github.com/huggingface/diffusers/discussions/7167) on the forum for more details) | [IP-Adapter Negative Noise](#ip-adapter-negative-noise) | | [Álvaro Somoza](https://github.com/asomoza)|
|
|
||||||
| asymmetric tiling |configure seamless image tiling independently for the X and Y axes | [Asymmetric Tiling](#asymmetric-tiling ) | | [alexisrolland](https://github.com/alexisrolland)|
|
|
||||||
|
|
||||||
|
|
||||||
## Example usages
|
|
||||||
|
|
||||||
### IP Adapter Negative Noise
|
|
||||||
|
|
||||||
Diffusers pipelines are fully integrated with IP-Adapter, which allows you to prompt the diffusion model with an image. However, it does not support negative image prompts (there is no `negative_ip_adapter_image` argument) the same way it supports negative text prompts. When you pass an `ip_adapter_image,` it will create a zero-filled tensor as a negative image. This script shows you how to create a negative noise from `ip_adapter_image` and use it to significantly improve the generation quality while preserving the composition of images.
|
|
||||||
|
|
||||||
[cubiq](https://github.com/cubiq) initially developed this feature in his [repository](https://github.com/cubiq/ComfyUI_IPAdapter_plus). The community script was contributed by [asomoza](https://github.com/Somoza). You can find more details about this experimentation [this discussion](https://github.com/huggingface/diffusers/discussions/7167)
|
|
||||||
|
|
||||||
IP-Adapter without negative noise
|
|
||||||
|source|result|
|
|
||||||
|---|---|
|
|
||||||
|||
|
|
||||||
|
|
||||||
IP-Adapter with negative noise
|
|
||||||
|source|result|
|
|
||||||
|---|---|
|
|
||||||
|||
|
|
||||||
|
|
||||||
```python
|
|
||||||
import torch
|
|
||||||
|
|
||||||
from diffusers import AutoencoderKL, DPMSolverMultistepScheduler, StableDiffusionXLPipeline
|
|
||||||
from diffusers.models import ImageProjection
|
|
||||||
from diffusers.utils import load_image
|
|
||||||
|
|
||||||
|
|
||||||
def encode_image(
|
|
||||||
image_encoder,
|
|
||||||
feature_extractor,
|
|
||||||
image,
|
|
||||||
device,
|
|
||||||
num_images_per_prompt,
|
|
||||||
output_hidden_states=None,
|
|
||||||
negative_image=None,
|
|
||||||
):
|
|
||||||
dtype = next(image_encoder.parameters()).dtype
|
|
||||||
|
|
||||||
if not isinstance(image, torch.Tensor):
|
|
||||||
image = feature_extractor(image, return_tensors="pt").pixel_values
|
|
||||||
|
|
||||||
image = image.to(device=device, dtype=dtype)
|
|
||||||
if output_hidden_states:
|
|
||||||
image_enc_hidden_states = image_encoder(image, output_hidden_states=True).hidden_states[-2]
|
|
||||||
image_enc_hidden_states = image_enc_hidden_states.repeat_interleave(num_images_per_prompt, dim=0)
|
|
||||||
|
|
||||||
if negative_image is None:
|
|
||||||
uncond_image_enc_hidden_states = image_encoder(
|
|
||||||
torch.zeros_like(image), output_hidden_states=True
|
|
||||||
).hidden_states[-2]
|
|
||||||
else:
|
|
||||||
if not isinstance(negative_image, torch.Tensor):
|
|
||||||
negative_image = feature_extractor(negative_image, return_tensors="pt").pixel_values
|
|
||||||
negative_image = negative_image.to(device=device, dtype=dtype)
|
|
||||||
uncond_image_enc_hidden_states = image_encoder(negative_image, output_hidden_states=True).hidden_states[-2]
|
|
||||||
|
|
||||||
uncond_image_enc_hidden_states = uncond_image_enc_hidden_states.repeat_interleave(num_images_per_prompt, dim=0)
|
|
||||||
return image_enc_hidden_states, uncond_image_enc_hidden_states
|
|
||||||
else:
|
|
||||||
image_embeds = image_encoder(image).image_embeds
|
|
||||||
image_embeds = image_embeds.repeat_interleave(num_images_per_prompt, dim=0)
|
|
||||||
uncond_image_embeds = torch.zeros_like(image_embeds)
|
|
||||||
|
|
||||||
return image_embeds, uncond_image_embeds
|
|
||||||
|
|
||||||
|
|
||||||
@torch.no_grad()
|
|
||||||
def prepare_ip_adapter_image_embeds(
|
|
||||||
unet,
|
|
||||||
image_encoder,
|
|
||||||
feature_extractor,
|
|
||||||
ip_adapter_image,
|
|
||||||
do_classifier_free_guidance,
|
|
||||||
device,
|
|
||||||
num_images_per_prompt,
|
|
||||||
ip_adapter_negative_image=None,
|
|
||||||
):
|
|
||||||
if not isinstance(ip_adapter_image, list):
|
|
||||||
ip_adapter_image = [ip_adapter_image]
|
|
||||||
|
|
||||||
if len(ip_adapter_image) != len(unet.encoder_hid_proj.image_projection_layers):
|
|
||||||
raise ValueError(
|
|
||||||
f"`ip_adapter_image` must have same length as the number of IP Adapters. Got {len(ip_adapter_image)} images and {len(unet.encoder_hid_proj.image_projection_layers)} IP Adapters."
|
|
||||||
)
|
|
||||||
|
|
||||||
image_embeds = []
|
|
||||||
for single_ip_adapter_image, image_proj_layer in zip(
|
|
||||||
ip_adapter_image, unet.encoder_hid_proj.image_projection_layers
|
|
||||||
):
|
|
||||||
output_hidden_state = not isinstance(image_proj_layer, ImageProjection)
|
|
||||||
single_image_embeds, single_negative_image_embeds = encode_image(
|
|
||||||
image_encoder,
|
|
||||||
feature_extractor,
|
|
||||||
single_ip_adapter_image,
|
|
||||||
device,
|
|
||||||
1,
|
|
||||||
output_hidden_state,
|
|
||||||
negative_image=ip_adapter_negative_image,
|
|
||||||
)
|
|
||||||
single_image_embeds = torch.stack([single_image_embeds] * num_images_per_prompt, dim=0)
|
|
||||||
single_negative_image_embeds = torch.stack([single_negative_image_embeds] * num_images_per_prompt, dim=0)
|
|
||||||
|
|
||||||
if do_classifier_free_guidance:
|
|
||||||
single_image_embeds = torch.cat([single_negative_image_embeds, single_image_embeds])
|
|
||||||
single_image_embeds = single_image_embeds.to(device)
|
|
||||||
|
|
||||||
image_embeds.append(single_image_embeds)
|
|
||||||
|
|
||||||
return image_embeds
|
|
||||||
|
|
||||||
|
|
||||||
vae = AutoencoderKL.from_pretrained(
|
|
||||||
"madebyollin/sdxl-vae-fp16-fix",
|
|
||||||
torch_dtype=torch.float16,
|
|
||||||
).to("cuda")
|
|
||||||
|
|
||||||
pipeline = StableDiffusionXLPipeline.from_pretrained(
|
|
||||||
"RunDiffusion/Juggernaut-XL-v9",
|
|
||||||
torch_dtype=torch.float16,
|
|
||||||
vae=vae,
|
|
||||||
variant="fp16",
|
|
||||||
).to("cuda")
|
|
||||||
|
|
||||||
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(pipeline.scheduler.config)
|
|
||||||
pipeline.scheduler.config.use_karras_sigmas = True
|
|
||||||
|
|
||||||
pipeline.load_ip_adapter(
|
|
||||||
"h94/IP-Adapter",
|
|
||||||
subfolder="sdxl_models",
|
|
||||||
weight_name="ip-adapter-plus_sdxl_vit-h.safetensors",
|
|
||||||
image_encoder_folder="models/image_encoder",
|
|
||||||
)
|
|
||||||
pipeline.set_ip_adapter_scale(0.7)
|
|
||||||
|
|
||||||
ip_image = load_image("source.png")
|
|
||||||
negative_ip_image = load_image("noise.png")
|
|
||||||
|
|
||||||
image_embeds = prepare_ip_adapter_image_embeds(
|
|
||||||
unet=pipeline.unet,
|
|
||||||
image_encoder=pipeline.image_encoder,
|
|
||||||
feature_extractor=pipeline.feature_extractor,
|
|
||||||
ip_adapter_image=[[ip_image]],
|
|
||||||
do_classifier_free_guidance=True,
|
|
||||||
device="cuda",
|
|
||||||
num_images_per_prompt=1,
|
|
||||||
ip_adapter_negative_image=negative_ip_image,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
prompt = "cinematic photo of a cyborg in the city, 4k, high quality, intricate, highly detailed"
|
|
||||||
negative_prompt = "blurry, smooth, plastic"
|
|
||||||
|
|
||||||
image = pipeline(
|
|
||||||
prompt=prompt,
|
|
||||||
negative_prompt=negative_prompt,
|
|
||||||
ip_adapter_image_embeds=image_embeds,
|
|
||||||
guidance_scale=6.0,
|
|
||||||
num_inference_steps=25,
|
|
||||||
generator=torch.Generator(device="cpu").manual_seed(1556265306),
|
|
||||||
).images[0]
|
|
||||||
|
|
||||||
image.save("result.png")
|
|
||||||
```
|
|
||||||
|
|
||||||
### Asymmetric Tiling
|
|
||||||
Stable Diffusion is not trained to generate seamless textures. However, you can use this simple script to add tiling to your generation. This script is contributed by [alexisrolland](https://github.com/alexisrolland). See more details in the [this issue](https://github.com/huggingface/diffusers/issues/556)
|
|
||||||
|
|
||||||
|
|
||||||
|Generated|Tiled|
|
|
||||||
|---|---|
|
|
||||||
|||
|
|
||||||
|
|
||||||
|
|
||||||
```py
|
|
||||||
import torch
|
|
||||||
from typing import Optional
|
|
||||||
from diffusers import StableDiffusionPipeline
|
|
||||||
from diffusers.models.lora import LoRACompatibleConv
|
|
||||||
|
|
||||||
def seamless_tiling(pipeline, x_axis, y_axis):
|
|
||||||
def asymmetric_conv2d_convforward(self, input: torch.Tensor, weight: torch.Tensor, bias: Optional[torch.Tensor] = None):
|
|
||||||
self.paddingX = (self._reversed_padding_repeated_twice[0], self._reversed_padding_repeated_twice[1], 0, 0)
|
|
||||||
self.paddingY = (0, 0, self._reversed_padding_repeated_twice[2], self._reversed_padding_repeated_twice[3])
|
|
||||||
working = torch.nn.functional.pad(input, self.paddingX, mode=x_mode)
|
|
||||||
working = torch.nn.functional.pad(working, self.paddingY, mode=y_mode)
|
|
||||||
return torch.nn.functional.conv2d(working, weight, bias, self.stride, torch.nn.modules.utils._pair(0), self.dilation, self.groups)
|
|
||||||
x_mode = 'circular' if x_axis else 'constant'
|
|
||||||
y_mode = 'circular' if y_axis else 'constant'
|
|
||||||
targets = [pipeline.vae, pipeline.text_encoder, pipeline.unet]
|
|
||||||
convolution_layers = []
|
|
||||||
for target in targets:
|
|
||||||
for module in target.modules():
|
|
||||||
if isinstance(module, torch.nn.Conv2d):
|
|
||||||
convolution_layers.append(module)
|
|
||||||
for layer in convolution_layers:
|
|
||||||
if isinstance(layer, LoRACompatibleConv) and layer.lora_layer is None:
|
|
||||||
layer.lora_layer = lambda * x: 0
|
|
||||||
layer._conv_forward = asymmetric_conv2d_convforward.__get__(layer, torch.nn.Conv2d)
|
|
||||||
return pipeline
|
|
||||||
|
|
||||||
pipeline = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16, use_safetensors=True)
|
|
||||||
pipeline.enable_model_cpu_offload()
|
|
||||||
prompt = ["texture of a red brick wall"]
|
|
||||||
seed = 123456
|
|
||||||
generator = torch.Generator(device='cuda').manual_seed(seed)
|
|
||||||
|
|
||||||
pipeline = seamless_tiling(pipeline=pipeline, x_axis=True, y_axis=True)
|
|
||||||
image = pipeline(
|
|
||||||
prompt=prompt,
|
|
||||||
width=512,
|
|
||||||
height=512,
|
|
||||||
num_inference_steps=20,
|
|
||||||
guidance_scale=7,
|
|
||||||
num_images_per_prompt=1,
|
|
||||||
generator=generator
|
|
||||||
).images[0]
|
|
||||||
seamless_tiling(pipeline=pipeline, x_axis=False, y_axis=False)
|
|
||||||
|
|
||||||
torch.cuda.empty_cache()
|
|
||||||
image.save('image.png')
|
|
||||||
```
|
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
modeled after the textual_inversion.py / train_dreambooth.py and the work
|
modeled after the textual_inversion.py / train_dreambooth.py and the work
|
||||||
of justinpinkney here: https://github.com/justinpinkney/stable-diffusion/blob/main/notebooks/imagic.ipynb
|
of justinpinkney here: https://github.com/justinpinkney/stable-diffusion/blob/main/notebooks/imagic.ipynb
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
import warnings
|
import warnings
|
||||||
from typing import List, Optional, Union
|
from typing import List, Optional, Union
|
||||||
|
|||||||
@@ -440,7 +440,7 @@ def betas_for_alpha_bar(
|
|||||||
return math.exp(t * -12.0)
|
return math.exp(t * -12.0)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Unsupported alpha_transform_type: {alpha_transform_type}")
|
raise ValueError(f"Unsupported alpha_tranform_type: {alpha_transform_type}")
|
||||||
|
|
||||||
betas = []
|
betas = []
|
||||||
for i in range(num_diffusion_timesteps):
|
for i in range(num_diffusion_timesteps):
|
||||||
|
|||||||
@@ -348,7 +348,7 @@ def betas_for_alpha_bar(
|
|||||||
return math.exp(t * -12.0)
|
return math.exp(t * -12.0)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Unsupported alpha_transform_type: {alpha_transform_type}")
|
raise ValueError(f"Unsupported alpha_tranform_type: {alpha_transform_type}")
|
||||||
|
|
||||||
betas = []
|
betas = []
|
||||||
for i in range(num_diffusion_timesteps):
|
for i in range(num_diffusion_timesteps):
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ from diffusers.utils import BaseOutput, check_min_version
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
|
|
||||||
class MarigoldDepthOutput(BaseOutput):
|
class MarigoldDepthOutput(BaseOutput):
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ def prepare_mask_and_masked_image(image, mask, height, width, return_image: bool
|
|||||||
dimensions: ``batch x channels x height x width``.
|
dimensions: ``batch x channels x height x width``.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# checkpoint. #TODO(Yiyi) - need to clean this up later
|
# checkpoint. TOD(Yiyi) - need to clean this up later
|
||||||
if image is None:
|
if image is None:
|
||||||
raise ValueError("`image` input cannot be undefined.")
|
raise ValueError("`image` input cannot be undefined.")
|
||||||
|
|
||||||
@@ -277,7 +277,7 @@ def prepare_mask_and_masked_image(image, mask, height, width, return_image: bool
|
|||||||
# images are in latent space and thus can't
|
# images are in latent space and thus can't
|
||||||
# be masked set masked_image to None
|
# be masked set masked_image to None
|
||||||
# we assume that the checkpoint is not an inpainting
|
# we assume that the checkpoint is not an inpainting
|
||||||
# checkpoint. #TODO(Yiyi) - need to clean this up later
|
# checkpoint. TOD(Yiyi) - need to clean this up later
|
||||||
masked_image = None
|
masked_image = None
|
||||||
else:
|
else:
|
||||||
masked_image = image * (mask < 0.5)
|
masked_image = image * (mask < 0.5)
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ def betas_for_alpha_bar(
|
|||||||
return math.exp(t * -12.0)
|
return math.exp(t * -12.0)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Unsupported alpha_transform_type: {alpha_transform_type}")
|
raise ValueError(f"Unsupported alpha_tranform_type: {alpha_transform_type}")
|
||||||
|
|
||||||
betas = []
|
betas = []
|
||||||
for i in range(num_diffusion_timesteps):
|
for i in range(num_diffusion_timesteps):
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
"""
|
"""
|
||||||
modified based on diffusion library from Huggingface: https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion.py
|
modified based on diffusion library from Huggingface: https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
from typing import Callable, List, Optional, Union
|
from typing import Callable, List, Optional, Union
|
||||||
|
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ class StableDiffusionIPEXPipeline(
|
|||||||
# 5. Prepare latent variables
|
# 5. Prepare latent variables
|
||||||
latents = self.prepare_latents(
|
latents = self.prepare_latents(
|
||||||
batch_size * num_images_per_prompt,
|
batch_size * num_images_per_prompt,
|
||||||
self.unet.config.in_channels,
|
self.unet.in_channels,
|
||||||
height,
|
height,
|
||||||
width,
|
width,
|
||||||
prompt_embeds.dtype,
|
prompt_embeds.dtype,
|
||||||
@@ -679,7 +679,7 @@ class StableDiffusionIPEXPipeline(
|
|||||||
timesteps = self.scheduler.timesteps
|
timesteps = self.scheduler.timesteps
|
||||||
|
|
||||||
# 5. Prepare latent variables
|
# 5. Prepare latent variables
|
||||||
num_channels_latents = self.unet.config.in_channels
|
num_channels_latents = self.unet.in_channels
|
||||||
latents = self.prepare_latents(
|
latents = self.prepare_latents(
|
||||||
batch_size * num_images_per_prompt,
|
batch_size * num_images_per_prompt,
|
||||||
num_channels_latents,
|
num_channels_latents,
|
||||||
|
|||||||
@@ -917,7 +917,7 @@ class TensorRTStableDiffusionPipeline(StableDiffusionPipeline):
|
|||||||
text_embeddings = self.__encode_prompt(prompt, negative_prompt)
|
text_embeddings = self.__encode_prompt(prompt, negative_prompt)
|
||||||
|
|
||||||
# Pre-initialize latents
|
# Pre-initialize latents
|
||||||
num_channels_latents = self.unet.config.in_channels
|
num_channels_latents = self.unet.in_channels
|
||||||
latents = self.prepare_latents(
|
latents = self.prepare_latents(
|
||||||
batch_size,
|
batch_size,
|
||||||
num_channels_latents,
|
num_channels_latents,
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ def slerp(val, low, high):
|
|||||||
|
|
||||||
|
|
||||||
class UnCLIPTextInterpolationPipeline(DiffusionPipeline):
|
class UnCLIPTextInterpolationPipeline(DiffusionPipeline):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Pipeline for prompt-to-prompt interpolation on CLIP text embeddings and using the UnCLIP / Dall-E to decode them to images.
|
Pipeline for prompt-to-prompt interpolation on CLIP text embeddings and using the UnCLIP / Dall-E to decode them to images.
|
||||||
|
|
||||||
@@ -48,7 +49,7 @@ class UnCLIPTextInterpolationPipeline(DiffusionPipeline):
|
|||||||
Tokenizer of class
|
Tokenizer of class
|
||||||
[CLIPTokenizer](https://huggingface.co/docs/transformers/v4.21.0/en/model_doc/clip#transformers.CLIPTokenizer).
|
[CLIPTokenizer](https://huggingface.co/docs/transformers/v4.21.0/en/model_doc/clip#transformers.CLIPTokenizer).
|
||||||
prior ([`PriorTransformer`]):
|
prior ([`PriorTransformer`]):
|
||||||
The canonical unCLIP prior to approximate the image embedding from the text embedding.
|
The canonincal unCLIP prior to approximate the image embedding from the text embedding.
|
||||||
text_proj ([`UnCLIPTextProjModel`]):
|
text_proj ([`UnCLIPTextProjModel`]):
|
||||||
Utility class to prepare and combine the embeddings before they are passed to the decoder.
|
Utility class to prepare and combine the embeddings before they are passed to the decoder.
|
||||||
decoder ([`UNet2DConditionModel`]):
|
decoder ([`UNet2DConditionModel`]):
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ if is_wandb_available():
|
|||||||
import wandb
|
import wandb
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ if is_wandb_available():
|
|||||||
import wandb
|
import wandb
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ if is_wandb_available():
|
|||||||
import wandb
|
import wandb
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ if is_wandb_available():
|
|||||||
import wandb
|
import wandb
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ if is_wandb_available():
|
|||||||
import wandb
|
import wandb
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ if is_wandb_available():
|
|||||||
import wandb
|
import wandb
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ if is_wandb_available():
|
|||||||
import wandb
|
import wandb
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ if is_wandb_available():
|
|||||||
import wandb
|
import wandb
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ from diffusers.utils.import_utils import is_xformers_available
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ if is_wandb_available():
|
|||||||
import wandb
|
import wandb
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ from diffusers.utils import check_min_version
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
# Cache compiled models across invocations of this script.
|
# Cache compiled models across invocations of this script.
|
||||||
cc.initialize_cache(os.path.expanduser("~/.cache/jax/compilation_cache"))
|
cc.initialize_cache(os.path.expanduser("~/.cache/jax/compilation_cache"))
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ if is_wandb_available():
|
|||||||
import wandb
|
import wandb
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ if is_wandb_available():
|
|||||||
import wandb
|
import wandb
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ from diffusers.utils.torch_utils import is_compiled_module
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__, log_level="INFO")
|
logger = get_logger(__name__, log_level="INFO")
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ if is_wandb_available():
|
|||||||
import wandb
|
import wandb
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__, log_level="INFO")
|
logger = get_logger(__name__, log_level="INFO")
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ if is_wandb_available():
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__, log_level="INFO")
|
logger = get_logger(__name__, log_level="INFO")
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ from diffusers.utils import check_min_version, is_wandb_available
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__, log_level="INFO")
|
logger = get_logger(__name__, log_level="INFO")
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ from diffusers.utils import check_min_version, is_wandb_available
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__, log_level="INFO")
|
logger = get_logger(__name__, log_level="INFO")
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ if is_wandb_available():
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__, log_level="INFO")
|
logger = get_logger(__name__, log_level="INFO")
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ TODO:
|
|||||||
6. Integrate to training x
|
6. Integrate to training x
|
||||||
7. Test
|
7. Test
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -637,7 +637,7 @@ def main(args):
|
|||||||
generator=generator,
|
generator=generator,
|
||||||
batch_size=args.eval_batch_size,
|
batch_size=args.eval_batch_size,
|
||||||
num_inference_steps=args.ddpm_num_inference_steps,
|
num_inference_steps=args.ddpm_num_inference_steps,
|
||||||
output_type="np",
|
output_type="numpy",
|
||||||
).images
|
).images
|
||||||
|
|
||||||
if args.use_ema:
|
if args.use_ema:
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""Conversion script for stable diffusion checkpoints which _only_ contain a controlnet."""
|
""" Conversion script for stable diffusion checkpoints which _only_ contain a controlnet. """
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import re
|
import re
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ if is_wandb_available():
|
|||||||
import wandb
|
import wandb
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ if is_wandb_available():
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__, log_level="INFO")
|
logger = get_logger(__name__, log_level="INFO")
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ from diffusers.utils import check_min_version
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ from diffusers.utils.torch_utils import is_compiled_module
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__, log_level="INFO")
|
logger = get_logger(__name__, log_level="INFO")
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ from diffusers.utils.torch_utils import is_compiled_module
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
@@ -425,11 +425,6 @@ def parse_args(input_args=None):
|
|||||||
default=4,
|
default=4,
|
||||||
help=("The dimension of the LoRA update matrices."),
|
help=("The dimension of the LoRA update matrices."),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
|
||||||
"--debug_loss",
|
|
||||||
action="store_true",
|
|
||||||
help="debug loss for each image, if filenames are awailable in the dataset",
|
|
||||||
)
|
|
||||||
|
|
||||||
if input_args is not None:
|
if input_args is not None:
|
||||||
args = parser.parse_args(input_args)
|
args = parser.parse_args(input_args)
|
||||||
@@ -608,7 +603,6 @@ def main(args):
|
|||||||
# Move unet, vae and text_encoder to device and cast to weight_dtype
|
# Move unet, vae and text_encoder to device and cast to weight_dtype
|
||||||
# The VAE is in float32 to avoid NaN losses.
|
# The VAE is in float32 to avoid NaN losses.
|
||||||
unet.to(accelerator.device, dtype=weight_dtype)
|
unet.to(accelerator.device, dtype=weight_dtype)
|
||||||
|
|
||||||
if args.pretrained_vae_model_name_or_path is None:
|
if args.pretrained_vae_model_name_or_path is None:
|
||||||
vae.to(accelerator.device, dtype=torch.float32)
|
vae.to(accelerator.device, dtype=torch.float32)
|
||||||
else:
|
else:
|
||||||
@@ -896,17 +890,13 @@ def main(args):
|
|||||||
tokens_one, tokens_two = tokenize_captions(examples)
|
tokens_one, tokens_two = tokenize_captions(examples)
|
||||||
examples["input_ids_one"] = tokens_one
|
examples["input_ids_one"] = tokens_one
|
||||||
examples["input_ids_two"] = tokens_two
|
examples["input_ids_two"] = tokens_two
|
||||||
if args.debug_loss:
|
|
||||||
fnames = [os.path.basename(image.filename) for image in examples[image_column] if image.filename]
|
|
||||||
if fnames:
|
|
||||||
examples["filenames"] = fnames
|
|
||||||
return examples
|
return examples
|
||||||
|
|
||||||
with accelerator.main_process_first():
|
with accelerator.main_process_first():
|
||||||
if args.max_train_samples is not None:
|
if args.max_train_samples is not None:
|
||||||
dataset["train"] = dataset["train"].shuffle(seed=args.seed).select(range(args.max_train_samples))
|
dataset["train"] = dataset["train"].shuffle(seed=args.seed).select(range(args.max_train_samples))
|
||||||
# Set the training transforms
|
# Set the training transforms
|
||||||
train_dataset = dataset["train"].with_transform(preprocess_train, output_all_columns=True)
|
train_dataset = dataset["train"].with_transform(preprocess_train)
|
||||||
|
|
||||||
def collate_fn(examples):
|
def collate_fn(examples):
|
||||||
pixel_values = torch.stack([example["pixel_values"] for example in examples])
|
pixel_values = torch.stack([example["pixel_values"] for example in examples])
|
||||||
@@ -915,7 +905,7 @@ def main(args):
|
|||||||
crop_top_lefts = [example["crop_top_lefts"] for example in examples]
|
crop_top_lefts = [example["crop_top_lefts"] for example in examples]
|
||||||
input_ids_one = torch.stack([example["input_ids_one"] for example in examples])
|
input_ids_one = torch.stack([example["input_ids_one"] for example in examples])
|
||||||
input_ids_two = torch.stack([example["input_ids_two"] for example in examples])
|
input_ids_two = torch.stack([example["input_ids_two"] for example in examples])
|
||||||
result = {
|
return {
|
||||||
"pixel_values": pixel_values,
|
"pixel_values": pixel_values,
|
||||||
"input_ids_one": input_ids_one,
|
"input_ids_one": input_ids_one,
|
||||||
"input_ids_two": input_ids_two,
|
"input_ids_two": input_ids_two,
|
||||||
@@ -923,11 +913,6 @@ def main(args):
|
|||||||
"crop_top_lefts": crop_top_lefts,
|
"crop_top_lefts": crop_top_lefts,
|
||||||
}
|
}
|
||||||
|
|
||||||
filenames = [example["filenames"] for example in examples if "filenames" in example]
|
|
||||||
if filenames:
|
|
||||||
result["filenames"] = filenames
|
|
||||||
return result
|
|
||||||
|
|
||||||
# DataLoaders creation:
|
# DataLoaders creation:
|
||||||
train_dataloader = torch.utils.data.DataLoader(
|
train_dataloader = torch.utils.data.DataLoader(
|
||||||
train_dataset,
|
train_dataset,
|
||||||
@@ -1120,9 +1105,7 @@ def main(args):
|
|||||||
loss = F.mse_loss(model_pred.float(), target.float(), reduction="none")
|
loss = F.mse_loss(model_pred.float(), target.float(), reduction="none")
|
||||||
loss = loss.mean(dim=list(range(1, len(loss.shape)))) * mse_loss_weights
|
loss = loss.mean(dim=list(range(1, len(loss.shape)))) * mse_loss_weights
|
||||||
loss = loss.mean()
|
loss = loss.mean()
|
||||||
if args.debug_loss and "filenames" in batch:
|
|
||||||
for fname in batch["filenames"]:
|
|
||||||
accelerator.log({"loss_for_" + fname: loss}, step=global_step)
|
|
||||||
# Gather the losses across all processes for logging (if we use distributed training).
|
# Gather the losses across all processes for logging (if we use distributed training).
|
||||||
avg_loss = accelerator.gather(loss.repeat(args.train_batch_size)).mean()
|
avg_loss = accelerator.gather(loss.repeat(args.train_batch_size)).mean()
|
||||||
train_loss += avg_loss.item() / args.gradient_accumulation_steps
|
train_loss += avg_loss.item() / args.gradient_accumulation_steps
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ from diffusers.utils.torch_utils import is_compiled_module
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
@@ -911,7 +911,6 @@ def main(args):
|
|||||||
)
|
)
|
||||||
precomputed_dataset = precomputed_dataset.with_transform(preprocess_train)
|
precomputed_dataset = precomputed_dataset.with_transform(preprocess_train)
|
||||||
|
|
||||||
del compute_vae_encodings_fn, compute_embeddings_fn, text_encoder_one, text_encoder_two
|
|
||||||
del text_encoders, tokenizers, vae
|
del text_encoders, tokenizers, vae
|
||||||
gc.collect()
|
gc.collect()
|
||||||
torch.cuda.empty_cache()
|
torch.cuda.empty_cache()
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ else:
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ else:
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ else:
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ from diffusers.utils.import_utils import is_xformers_available
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__, log_level="INFO")
|
logger = get_logger(__name__, log_level="INFO")
|
||||||
|
|
||||||
@@ -648,7 +648,7 @@ def main(args):
|
|||||||
generator=generator,
|
generator=generator,
|
||||||
batch_size=args.eval_batch_size,
|
batch_size=args.eval_batch_size,
|
||||||
num_inference_steps=args.ddpm_num_inference_steps,
|
num_inference_steps=args.ddpm_num_inference_steps,
|
||||||
output_type="np",
|
output_type="numpy",
|
||||||
).images
|
).images
|
||||||
|
|
||||||
if args.use_ema:
|
if args.use_ema:
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ if is_wandb_available():
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__, log_level="INFO")
|
logger = get_logger(__name__, log_level="INFO")
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ if is_wandb_available():
|
|||||||
|
|
||||||
|
|
||||||
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
# Will error if the minimal version of diffusers is not installed. Remove at your own risks.
|
||||||
check_min_version("0.28.0.dev0")
|
check_min_version("0.27.0.dev0")
|
||||||
|
|
||||||
logger = get_logger(__name__, log_level="INFO")
|
logger = get_logger(__name__, log_level="INFO")
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""Conversion script for the LDM checkpoints."""
|
""" Conversion script for the LDM checkpoints. """
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""Conversion script for the LDM checkpoints."""
|
""" Conversion script for the LDM checkpoints. """
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
|
|||||||
@@ -1195,9 +1195,9 @@ def superres_check_against_original(dump_path, unet_checkpoint_path):
|
|||||||
if_II_model = IFStageIII(device="cuda", dir_or_name=orig_path, model_kwargs={"precision": "fp32"}).model
|
if_II_model = IFStageIII(device="cuda", dir_or_name=orig_path, model_kwargs={"precision": "fp32"}).model
|
||||||
|
|
||||||
batch_size = 1
|
batch_size = 1
|
||||||
channels = model.config.in_channels // 2
|
channels = model.in_channels // 2
|
||||||
height = model.config.sample_size
|
height = model.sample_size
|
||||||
width = model.config.sample_size
|
width = model.sample_size
|
||||||
height = 1024
|
height = 1024
|
||||||
width = 1024
|
width = 1024
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""Conversion script for the LDM checkpoints."""
|
""" Conversion script for the LDM checkpoints. """
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
"""Conversion script for the LoRA's safetensors checkpoints."""
|
""" Conversion script for the LoRA's safetensors checkpoints. """
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""Conversion script for the LDM checkpoints."""
|
""" Conversion script for the LDM checkpoints. """
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""Conversion script for the NCSNPP checkpoints."""
|
""" Conversion script for the NCSNPP checkpoints. """
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""Conversion script for the AudioLDM2 checkpoints."""
|
""" Conversion script for the AudioLDM2 checkpoints."""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import re
|
import re
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""Conversion script for the AudioLDM checkpoints."""
|
""" Conversion script for the AudioLDM checkpoints."""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import re
|
import re
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""Conversion script for stable diffusion checkpoints which _only_ contain a controlnet."""
|
""" Conversion script for stable diffusion checkpoints which _only_ contain a controlnet. """
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""Conversion script for the MusicLDM checkpoints."""
|
""" Conversion script for the MusicLDM checkpoints."""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import re
|
import re
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""Conversion script for the LDM checkpoints."""
|
""" Conversion script for the LDM checkpoints. """
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import importlib
|
import importlib
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""Conversion script for the Versatile Stable Diffusion checkpoints."""
|
""" Conversion script for the Versatile Stable Diffusion checkpoints. """
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ $ python convert_zero123_to_diffusers.py \
|
|||||||
--original_config_file /path/zero123/configs/sd-objaverse-finetune-c_concat-256.yaml
|
--original_config_file /path/zero123/configs/sd-objaverse-finetune-c_concat-256.yaml
|
||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
import torch
|
import torch
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ version_range_max = max(sys.version_info[1], 10) + 1
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="diffusers",
|
name="diffusers",
|
||||||
version="0.28.0.dev0", # expected format is one of x.y.z.dev0, or x.y.z.rc1 or x.y.z (no to dashes, yes to dots)
|
version="0.27.0.dev0", # expected format is one of x.y.z.dev0, or x.y.z.rc1 or x.y.z (no to dashes, yes to dots)
|
||||||
description="State-of-the-art diffusion in PyTorch and JAX.",
|
description="State-of-the-art diffusion in PyTorch and JAX.",
|
||||||
long_description=open("README.md", "r", encoding="utf-8").read(),
|
long_description=open("README.md", "r", encoding="utf-8").read(),
|
||||||
long_description_content_type="text/markdown",
|
long_description_content_type="text/markdown",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
__version__ = "0.28.0.dev0"
|
__version__ = "0.27.0.dev0"
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""ConfigMixin base class and utilities."""
|
""" ConfigMixin base class and utilities."""
|
||||||
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
import functools
|
import functools
|
||||||
import importlib
|
import importlib
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import torch
|
|||||||
from huggingface_hub.utils import validate_hf_hub_args
|
from huggingface_hub.utils import validate_hf_hub_args
|
||||||
from safetensors import safe_open
|
from safetensors import safe_open
|
||||||
|
|
||||||
from ..models.modeling_utils import _LOW_CPU_MEM_USAGE_DEFAULT, load_state_dict
|
from ..models.modeling_utils import _LOW_CPU_MEM_USAGE_DEFAULT
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
_get_model_file,
|
_get_model_file,
|
||||||
is_accelerate_available,
|
is_accelerate_available,
|
||||||
@@ -182,7 +182,7 @@ class IPAdapterMixin:
|
|||||||
elif key.startswith("ip_adapter."):
|
elif key.startswith("ip_adapter."):
|
||||||
state_dict["ip_adapter"][key.replace("ip_adapter.", "")] = f.get_tensor(key)
|
state_dict["ip_adapter"][key.replace("ip_adapter.", "")] = f.get_tensor(key)
|
||||||
else:
|
else:
|
||||||
state_dict = load_state_dict(model_file)
|
state_dict = torch.load(model_file, map_location="cpu")
|
||||||
else:
|
else:
|
||||||
state_dict = pretrained_model_name_or_path_or_dict
|
state_dict = pretrained_model_name_or_path_or_dict
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ from packaging import version
|
|||||||
from torch import nn
|
from torch import nn
|
||||||
|
|
||||||
from .. import __version__
|
from .. import __version__
|
||||||
from ..models.modeling_utils import _LOW_CPU_MEM_USAGE_DEFAULT, load_state_dict
|
from ..models.modeling_utils import _LOW_CPU_MEM_USAGE_DEFAULT
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
USE_PEFT_BACKEND,
|
USE_PEFT_BACKEND,
|
||||||
_get_model_file,
|
_get_model_file,
|
||||||
@@ -281,7 +281,7 @@ class LoraLoaderMixin:
|
|||||||
subfolder=subfolder,
|
subfolder=subfolder,
|
||||||
user_agent=user_agent,
|
user_agent=user_agent,
|
||||||
)
|
)
|
||||||
state_dict = load_state_dict(model_file)
|
state_dict = torch.load(model_file, map_location="cpu")
|
||||||
else:
|
else:
|
||||||
state_dict = pretrained_model_name_or_path_or_dict
|
state_dict = pretrained_model_name_or_path_or_dict
|
||||||
|
|
||||||
|
|||||||
@@ -198,13 +198,8 @@ def _convert_kohya_lora_to_diffusers(state_dict, unet_name="unet", text_encoder_
|
|||||||
unet_state_dict[diffusers_name] = state_dict.pop(key)
|
unet_state_dict[diffusers_name] = state_dict.pop(key)
|
||||||
unet_state_dict[diffusers_name.replace(".down.", ".up.")] = state_dict.pop(lora_name_up)
|
unet_state_dict[diffusers_name.replace(".down.", ".up.")] = state_dict.pop(lora_name_up)
|
||||||
|
|
||||||
elif lora_name.startswith(("lora_te_", "lora_te1_", "lora_te2_")):
|
elif lora_name.startswith("lora_te_"):
|
||||||
if lora_name.startswith(("lora_te_", "lora_te1_")):
|
diffusers_name = key.replace("lora_te_", "").replace("_", ".")
|
||||||
key_to_replace = "lora_te_" if lora_name.startswith("lora_te_") else "lora_te1_"
|
|
||||||
else:
|
|
||||||
key_to_replace = "lora_te2_"
|
|
||||||
|
|
||||||
diffusers_name = key.replace(key_to_replace, "").replace("_", ".")
|
|
||||||
diffusers_name = diffusers_name.replace("text.model", "text_model")
|
diffusers_name = diffusers_name.replace("text.model", "text_model")
|
||||||
diffusers_name = diffusers_name.replace("self.attn", "self_attn")
|
diffusers_name = diffusers_name.replace("self.attn", "self_attn")
|
||||||
diffusers_name = diffusers_name.replace("q.proj.lora", "to_q_lora")
|
diffusers_name = diffusers_name.replace("q.proj.lora", "to_q_lora")
|
||||||
@@ -212,22 +207,52 @@ def _convert_kohya_lora_to_diffusers(state_dict, unet_name="unet", text_encoder_
|
|||||||
diffusers_name = diffusers_name.replace("v.proj.lora", "to_v_lora")
|
diffusers_name = diffusers_name.replace("v.proj.lora", "to_v_lora")
|
||||||
diffusers_name = diffusers_name.replace("out.proj.lora", "to_out_lora")
|
diffusers_name = diffusers_name.replace("out.proj.lora", "to_out_lora")
|
||||||
if "self_attn" in diffusers_name:
|
if "self_attn" in diffusers_name:
|
||||||
if lora_name.startswith(("lora_te_", "lora_te1_")):
|
te_state_dict[diffusers_name] = state_dict.pop(key)
|
||||||
te_state_dict[diffusers_name] = state_dict.pop(key)
|
te_state_dict[diffusers_name.replace(".down.", ".up.")] = state_dict.pop(lora_name_up)
|
||||||
te_state_dict[diffusers_name.replace(".down.", ".up.")] = state_dict.pop(lora_name_up)
|
|
||||||
else:
|
|
||||||
te2_state_dict[diffusers_name] = state_dict.pop(key)
|
|
||||||
te2_state_dict[diffusers_name.replace(".down.", ".up.")] = state_dict.pop(lora_name_up)
|
|
||||||
elif "mlp" in diffusers_name:
|
elif "mlp" in diffusers_name:
|
||||||
# Be aware that this is the new diffusers convention and the rest of the code might
|
# Be aware that this is the new diffusers convention and the rest of the code might
|
||||||
# not utilize it yet.
|
# not utilize it yet.
|
||||||
diffusers_name = diffusers_name.replace(".lora.", ".lora_linear_layer.")
|
diffusers_name = diffusers_name.replace(".lora.", ".lora_linear_layer.")
|
||||||
if lora_name.startswith(("lora_te_", "lora_te1_")):
|
te_state_dict[diffusers_name] = state_dict.pop(key)
|
||||||
te_state_dict[diffusers_name] = state_dict.pop(key)
|
te_state_dict[diffusers_name.replace(".down.", ".up.")] = state_dict.pop(lora_name_up)
|
||||||
te_state_dict[diffusers_name.replace(".down.", ".up.")] = state_dict.pop(lora_name_up)
|
|
||||||
else:
|
# (sayakpaul): Duplicate code. Needs to be cleaned.
|
||||||
te2_state_dict[diffusers_name] = state_dict.pop(key)
|
elif lora_name.startswith("lora_te1_"):
|
||||||
te2_state_dict[diffusers_name.replace(".down.", ".up.")] = state_dict.pop(lora_name_up)
|
diffusers_name = key.replace("lora_te1_", "").replace("_", ".")
|
||||||
|
diffusers_name = diffusers_name.replace("text.model", "text_model")
|
||||||
|
diffusers_name = diffusers_name.replace("self.attn", "self_attn")
|
||||||
|
diffusers_name = diffusers_name.replace("q.proj.lora", "to_q_lora")
|
||||||
|
diffusers_name = diffusers_name.replace("k.proj.lora", "to_k_lora")
|
||||||
|
diffusers_name = diffusers_name.replace("v.proj.lora", "to_v_lora")
|
||||||
|
diffusers_name = diffusers_name.replace("out.proj.lora", "to_out_lora")
|
||||||
|
if "self_attn" in diffusers_name:
|
||||||
|
te_state_dict[diffusers_name] = state_dict.pop(key)
|
||||||
|
te_state_dict[diffusers_name.replace(".down.", ".up.")] = state_dict.pop(lora_name_up)
|
||||||
|
elif "mlp" in diffusers_name:
|
||||||
|
# Be aware that this is the new diffusers convention and the rest of the code might
|
||||||
|
# not utilize it yet.
|
||||||
|
diffusers_name = diffusers_name.replace(".lora.", ".lora_linear_layer.")
|
||||||
|
te_state_dict[diffusers_name] = state_dict.pop(key)
|
||||||
|
te_state_dict[diffusers_name.replace(".down.", ".up.")] = state_dict.pop(lora_name_up)
|
||||||
|
|
||||||
|
# (sayakpaul): Duplicate code. Needs to be cleaned.
|
||||||
|
elif lora_name.startswith("lora_te2_"):
|
||||||
|
diffusers_name = key.replace("lora_te2_", "").replace("_", ".")
|
||||||
|
diffusers_name = diffusers_name.replace("text.model", "text_model")
|
||||||
|
diffusers_name = diffusers_name.replace("self.attn", "self_attn")
|
||||||
|
diffusers_name = diffusers_name.replace("q.proj.lora", "to_q_lora")
|
||||||
|
diffusers_name = diffusers_name.replace("k.proj.lora", "to_k_lora")
|
||||||
|
diffusers_name = diffusers_name.replace("v.proj.lora", "to_v_lora")
|
||||||
|
diffusers_name = diffusers_name.replace("out.proj.lora", "to_out_lora")
|
||||||
|
if "self_attn" in diffusers_name:
|
||||||
|
te2_state_dict[diffusers_name] = state_dict.pop(key)
|
||||||
|
te2_state_dict[diffusers_name.replace(".down.", ".up.")] = state_dict.pop(lora_name_up)
|
||||||
|
elif "mlp" in diffusers_name:
|
||||||
|
# Be aware that this is the new diffusers convention and the rest of the code might
|
||||||
|
# not utilize it yet.
|
||||||
|
diffusers_name = diffusers_name.replace(".lora.", ".lora_linear_layer.")
|
||||||
|
te2_state_dict[diffusers_name] = state_dict.pop(key)
|
||||||
|
te2_state_dict[diffusers_name.replace(".down.", ".up.")] = state_dict.pop(lora_name_up)
|
||||||
|
|
||||||
# Rename the alphas so that they can be mapped appropriately.
|
# Rename the alphas so that they can be mapped appropriately.
|
||||||
if lora_name_alpha in state_dict:
|
if lora_name_alpha in state_dict:
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""Conversion script for the Stable Diffusion checkpoints."""
|
""" Conversion script for the Stable Diffusion checkpoints."""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
@@ -454,8 +454,7 @@ def set_image_size(pipeline_class_name, original_config, checkpoint, image_size=
|
|||||||
model_type = infer_model_type(original_config, checkpoint, model_type)
|
model_type = infer_model_type(original_config, checkpoint, model_type)
|
||||||
|
|
||||||
if pipeline_class_name == "StableDiffusionUpscalePipeline":
|
if pipeline_class_name == "StableDiffusionUpscalePipeline":
|
||||||
image_size = original_config["model"]["params"]["unet_config"]["params"]["image_size"]
|
return 512
|
||||||
return image_size
|
|
||||||
|
|
||||||
elif model_type in ["SDXL", "SDXL-Refiner", "Playground"]:
|
elif model_type in ["SDXL", "SDXL-Refiner", "Playground"]:
|
||||||
image_size = 1024
|
image_size = 1024
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import torch
|
|||||||
from huggingface_hub.utils import validate_hf_hub_args
|
from huggingface_hub.utils import validate_hf_hub_args
|
||||||
from torch import nn
|
from torch import nn
|
||||||
|
|
||||||
from ..models.modeling_utils import load_state_dict
|
|
||||||
from ..utils import _get_model_file, is_accelerate_available, is_transformers_available, logging
|
from ..utils import _get_model_file, is_accelerate_available, is_transformers_available, logging
|
||||||
|
|
||||||
|
|
||||||
@@ -101,7 +100,7 @@ def load_textual_inversion_state_dicts(pretrained_model_name_or_paths, **kwargs)
|
|||||||
subfolder=subfolder,
|
subfolder=subfolder,
|
||||||
user_agent=user_agent,
|
user_agent=user_agent,
|
||||||
)
|
)
|
||||||
state_dict = load_state_dict(model_file)
|
state_dict = torch.load(model_file, map_location="cpu")
|
||||||
else:
|
else:
|
||||||
state_dict = pretrained_model_name_or_path
|
state_dict = pretrained_model_name_or_path
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ from ..models.embeddings import (
|
|||||||
IPAdapterPlusImageProjection,
|
IPAdapterPlusImageProjection,
|
||||||
MultiIPAdapterImageProjection,
|
MultiIPAdapterImageProjection,
|
||||||
)
|
)
|
||||||
from ..models.modeling_utils import _LOW_CPU_MEM_USAGE_DEFAULT, load_model_dict_into_meta, load_state_dict
|
from ..models.modeling_utils import _LOW_CPU_MEM_USAGE_DEFAULT, load_model_dict_into_meta
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
USE_PEFT_BACKEND,
|
USE_PEFT_BACKEND,
|
||||||
_get_model_file,
|
_get_model_file,
|
||||||
@@ -214,7 +214,7 @@ class UNet2DConditionLoadersMixin:
|
|||||||
subfolder=subfolder,
|
subfolder=subfolder,
|
||||||
user_agent=user_agent,
|
user_agent=user_agent,
|
||||||
)
|
)
|
||||||
state_dict = load_state_dict(model_file)
|
state_dict = torch.load(model_file, map_location="cpu")
|
||||||
else:
|
else:
|
||||||
state_dict = pretrained_model_name_or_path_or_dict
|
state_dict = pretrained_model_name_or_path_or_dict
|
||||||
|
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ class BasicTransformerBlock(nn.Module):
|
|||||||
) -> torch.FloatTensor:
|
) -> torch.FloatTensor:
|
||||||
if cross_attention_kwargs is not None:
|
if cross_attention_kwargs is not None:
|
||||||
if cross_attention_kwargs.get("scale", None) is not None:
|
if cross_attention_kwargs.get("scale", None) is not None:
|
||||||
logger.warning("Passing `scale` to `cross_attention_kwargs` is deprecated. `scale` will be ignored.")
|
logger.warning("Passing `scale` to `cross_attention_kwargs` is depcrecated. `scale` will be ignored.")
|
||||||
|
|
||||||
# Notice that normalization is always applied before the real computation in the following blocks.
|
# Notice that normalization is always applied before the real computation in the following blocks.
|
||||||
# 0. Self-Attention
|
# 0. Self-Attention
|
||||||
|
|||||||
@@ -424,7 +424,7 @@ class Attention(nn.Module):
|
|||||||
# If doesn't apply LoRA do `add_k_proj` or `add_v_proj`
|
# If doesn't apply LoRA do `add_k_proj` or `add_v_proj`
|
||||||
is_lora_activated.pop("add_k_proj", None)
|
is_lora_activated.pop("add_k_proj", None)
|
||||||
is_lora_activated.pop("add_v_proj", None)
|
is_lora_activated.pop("add_v_proj", None)
|
||||||
# 2. else it is not possible that only some layers have LoRA activated
|
# 2. else it is not posssible that only some layers have LoRA activated
|
||||||
if not all(is_lora_activated.values()):
|
if not all(is_lora_activated.values()):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Make sure that either all layers or no layers have LoRA activated, but have {is_lora_activated}"
|
f"Make sure that either all layers or no layers have LoRA activated, but have {is_lora_activated}"
|
||||||
@@ -2098,7 +2098,7 @@ class LoRAAttnAddedKVProcessor(nn.Module):
|
|||||||
|
|
||||||
class IPAdapterAttnProcessor(nn.Module):
|
class IPAdapterAttnProcessor(nn.Module):
|
||||||
r"""
|
r"""
|
||||||
Attention processor for Multiple IP-Adapters.
|
Attention processor for Multiple IP-Adapater.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
hidden_size (`int`):
|
hidden_size (`int`):
|
||||||
@@ -2152,8 +2152,8 @@ class IPAdapterAttnProcessor(nn.Module):
|
|||||||
encoder_hidden_states, ip_hidden_states = encoder_hidden_states
|
encoder_hidden_states, ip_hidden_states = encoder_hidden_states
|
||||||
else:
|
else:
|
||||||
deprecation_message = (
|
deprecation_message = (
|
||||||
"You have passed a tensor as `encoder_hidden_states`. This is deprecated and will be removed in a future release."
|
"You have passed a tensor as `encoder_hidden_states`.This is deprecated and will be removed in a future release."
|
||||||
" Please make sure to update your script to pass `encoder_hidden_states` as a tuple to suppress this warning."
|
" Please make sure to update your script to pass `encoder_hidden_states` as a tuple to supress this warning."
|
||||||
)
|
)
|
||||||
deprecate("encoder_hidden_states not a tuple", "1.0.0", deprecation_message, standard_warn=False)
|
deprecate("encoder_hidden_states not a tuple", "1.0.0", deprecation_message, standard_warn=False)
|
||||||
end_pos = encoder_hidden_states.shape[1] - self.num_tokens[0]
|
end_pos = encoder_hidden_states.shape[1] - self.num_tokens[0]
|
||||||
@@ -2253,7 +2253,7 @@ class IPAdapterAttnProcessor(nn.Module):
|
|||||||
|
|
||||||
class IPAdapterAttnProcessor2_0(torch.nn.Module):
|
class IPAdapterAttnProcessor2_0(torch.nn.Module):
|
||||||
r"""
|
r"""
|
||||||
Attention processor for IP-Adapter for PyTorch 2.0.
|
Attention processor for IP-Adapater for PyTorch 2.0.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
hidden_size (`int`):
|
hidden_size (`int`):
|
||||||
@@ -2312,8 +2312,8 @@ class IPAdapterAttnProcessor2_0(torch.nn.Module):
|
|||||||
encoder_hidden_states, ip_hidden_states = encoder_hidden_states
|
encoder_hidden_states, ip_hidden_states = encoder_hidden_states
|
||||||
else:
|
else:
|
||||||
deprecation_message = (
|
deprecation_message = (
|
||||||
"You have passed a tensor as `encoder_hidden_states`. This is deprecated and will be removed in a future release."
|
"You have passed a tensor as `encoder_hidden_states`.This is deprecated and will be removed in a future release."
|
||||||
" Please make sure to update your script to pass `encoder_hidden_states` as a tuple to suppress this warning."
|
" Please make sure to update your script to pass `encoder_hidden_states` as a tuple to supress this warning."
|
||||||
)
|
)
|
||||||
deprecate("encoder_hidden_states not a tuple", "1.0.0", deprecation_message, standard_warn=False)
|
deprecate("encoder_hidden_states not a tuple", "1.0.0", deprecation_message, standard_warn=False)
|
||||||
end_pos = encoder_hidden_states.shape[1] - self.num_tokens[0]
|
end_pos = encoder_hidden_states.shape[1] - self.num_tokens[0]
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ class ControlNetModel(ModelMixin, ConfigMixin, FromOriginalControlNetMixin):
|
|||||||
elif encoder_hid_dim_type == "text_image_proj":
|
elif encoder_hid_dim_type == "text_image_proj":
|
||||||
# image_embed_dim DOESN'T have to be `cross_attention_dim`. To not clutter the __init__ too much
|
# image_embed_dim DOESN'T have to be `cross_attention_dim`. To not clutter the __init__ too much
|
||||||
# they are set to `cross_attention_dim` here as this is exactly the required dimension for the currently only use
|
# they are set to `cross_attention_dim` here as this is exactly the required dimension for the currently only use
|
||||||
# case when `addition_embed_type == "text_image_proj"` (Kandinsky 2.1)`
|
# case when `addition_embed_type == "text_image_proj"` (Kadinsky 2.1)`
|
||||||
self.encoder_hid_proj = TextImageProjection(
|
self.encoder_hid_proj = TextImageProjection(
|
||||||
text_embed_dim=encoder_hid_dim,
|
text_embed_dim=encoder_hid_dim,
|
||||||
image_embed_dim=cross_attention_dim,
|
image_embed_dim=cross_attention_dim,
|
||||||
@@ -330,7 +330,7 @@ class ControlNetModel(ModelMixin, ConfigMixin, FromOriginalControlNetMixin):
|
|||||||
elif addition_embed_type == "text_image":
|
elif addition_embed_type == "text_image":
|
||||||
# text_embed_dim and image_embed_dim DON'T have to be `cross_attention_dim`. To not clutter the __init__ too much
|
# text_embed_dim and image_embed_dim DON'T have to be `cross_attention_dim`. To not clutter the __init__ too much
|
||||||
# they are set to `cross_attention_dim` here as this is exactly the required dimension for the currently only use
|
# they are set to `cross_attention_dim` here as this is exactly the required dimension for the currently only use
|
||||||
# case when `addition_embed_type == "text_image"` (Kandinsky 2.1)`
|
# case when `addition_embed_type == "text_image"` (Kadinsky 2.1)`
|
||||||
self.add_embedding = TextImageTimeEmbedding(
|
self.add_embedding = TextImageTimeEmbedding(
|
||||||
text_embed_dim=cross_attention_dim, image_embed_dim=cross_attention_dim, time_embed_dim=time_embed_dim
|
text_embed_dim=cross_attention_dim, image_embed_dim=cross_attention_dim, time_embed_dim=time_embed_dim
|
||||||
)
|
)
|
||||||
@@ -509,9 +509,6 @@ class ControlNetModel(ModelMixin, ConfigMixin, FromOriginalControlNetMixin):
|
|||||||
if controlnet.class_embedding:
|
if controlnet.class_embedding:
|
||||||
controlnet.class_embedding.load_state_dict(unet.class_embedding.state_dict())
|
controlnet.class_embedding.load_state_dict(unet.class_embedding.state_dict())
|
||||||
|
|
||||||
if hasattr(controlnet, "add_embedding"):
|
|
||||||
controlnet.add_embedding.load_state_dict(unet.add_embedding.state_dict())
|
|
||||||
|
|
||||||
controlnet.down_blocks.load_state_dict(unet.down_blocks.state_dict())
|
controlnet.down_blocks.load_state_dict(unet.down_blocks.state_dict())
|
||||||
controlnet.mid_block.load_state_dict(unet.mid_block.state_dict())
|
controlnet.mid_block.load_state_dict(unet.mid_block.state_dict())
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""PyTorch - Flax general utilities."""
|
""" PyTorch - Flax general utilities."""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import jax.numpy as jnp
|
import jax.numpy as jnp
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
"""PyTorch - Flax general utilities."""
|
""" PyTorch - Flax general utilities."""
|
||||||
|
|
||||||
from pickle import UnpicklingError
|
from pickle import UnpicklingError
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import os
|
|||||||
import re
|
import re
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from pathlib import Path
|
|
||||||
from typing import Any, Callable, List, Optional, Tuple, Union
|
from typing import Any, Callable, List, Optional, Tuple, Union
|
||||||
|
|
||||||
import safetensors
|
import safetensors
|
||||||
@@ -108,12 +107,7 @@ def load_state_dict(checkpoint_file: Union[str, os.PathLike], variant: Optional[
|
|||||||
if file_extension == SAFETENSORS_FILE_EXTENSION:
|
if file_extension == SAFETENSORS_FILE_EXTENSION:
|
||||||
return safetensors.torch.load_file(checkpoint_file, device="cpu")
|
return safetensors.torch.load_file(checkpoint_file, device="cpu")
|
||||||
else:
|
else:
|
||||||
weights_only_kwarg = {"weights_only": True} if is_torch_version(">=", "1.13") else {}
|
return torch.load(checkpoint_file, map_location="cpu")
|
||||||
return torch.load(
|
|
||||||
checkpoint_file,
|
|
||||||
map_location="cpu",
|
|
||||||
**weights_only_kwarg,
|
|
||||||
)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
try:
|
try:
|
||||||
with open(checkpoint_file) as f:
|
with open(checkpoint_file) as f:
|
||||||
@@ -373,18 +367,18 @@ class ModelMixin(torch.nn.Module, PushToHubMixin):
|
|||||||
# Save the model
|
# Save the model
|
||||||
if safe_serialization:
|
if safe_serialization:
|
||||||
safetensors.torch.save_file(
|
safetensors.torch.save_file(
|
||||||
state_dict, Path(save_directory, weights_name).as_posix(), metadata={"format": "pt"}
|
state_dict, os.path.join(save_directory, weights_name), metadata={"format": "pt"}
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
torch.save(state_dict, Path(save_directory, weights_name).as_posix())
|
torch.save(state_dict, os.path.join(save_directory, weights_name))
|
||||||
|
|
||||||
logger.info(f"Model weights saved in {Path(save_directory, weights_name).as_posix()}")
|
logger.info(f"Model weights saved in {os.path.join(save_directory, weights_name)}")
|
||||||
|
|
||||||
if push_to_hub:
|
if push_to_hub:
|
||||||
# Create a new empty model card and eventually tag it
|
# Create a new empty model card and eventually tag it
|
||||||
model_card = load_or_create_model_card(repo_id, token=token)
|
model_card = load_or_create_model_card(repo_id, token=token)
|
||||||
model_card = populate_model_card(model_card)
|
model_card = populate_model_card(model_card)
|
||||||
model_card.save(Path(save_directory, "README.md").as_posix())
|
model_card.save(os.path.join(save_directory, "README.md"))
|
||||||
|
|
||||||
self._upload_folder(
|
self._upload_folder(
|
||||||
save_directory,
|
save_directory,
|
||||||
|
|||||||
@@ -20,15 +20,15 @@ from .transformers.transformer_temporal import (
|
|||||||
|
|
||||||
|
|
||||||
class TransformerTemporalModelOutput(TransformerTemporalModelOutput):
|
class TransformerTemporalModelOutput(TransformerTemporalModelOutput):
|
||||||
deprecation_message = "Importing `TransformerTemporalModelOutput` from `diffusers.models.transformer_temporal` is deprecated and this will be removed in a future version. Please use `from diffusers.models.transformers.transformer_temporal import TransformerTemporalModelOutput`, instead."
|
deprecation_message = "Importing `TransformerTemporalModelOutput` from `diffusers.models.transformer_temporal` is deprecated and this will be removed in a future version. Please use `from diffusers.models.transformers.tranformer_temporal import TransformerTemporalModelOutput`, instead."
|
||||||
deprecate("TransformerTemporalModelOutput", "0.29", deprecation_message)
|
deprecate("TransformerTemporalModelOutput", "0.29", deprecation_message)
|
||||||
|
|
||||||
|
|
||||||
class TransformerTemporalModel(TransformerTemporalModel):
|
class TransformerTemporalModel(TransformerTemporalModel):
|
||||||
deprecation_message = "Importing `TransformerTemporalModel` from `diffusers.models.transformer_temporal` is deprecated and this will be removed in a future version. Please use `from diffusers.models.transformers.transformer_temporal import TransformerTemporalModel`, instead."
|
deprecation_message = "Importing `TransformerTemporalModel` from `diffusers.models.transformer_temporal` is deprecated and this will be removed in a future version. Please use `from diffusers.models.transformers.tranformer_temporal import TransformerTemporalModel`, instead."
|
||||||
deprecate("TransformerTemporalModel", "0.29", deprecation_message)
|
deprecate("TransformerTemporalModel", "0.29", deprecation_message)
|
||||||
|
|
||||||
|
|
||||||
class TransformerSpatioTemporalModel(TransformerSpatioTemporalModel):
|
class TransformerSpatioTemporalModel(TransformerSpatioTemporalModel):
|
||||||
deprecation_message = "Importing `TransformerSpatioTemporalModel` from `diffusers.models.transformer_temporal` is deprecated and this will be removed in a future version. Please use `from diffusers.models.transformers.transformer_temporal import TransformerSpatioTemporalModel`, instead."
|
deprecation_message = "Importing `TransformerSpatioTemporalModel` from `diffusers.models.transformer_temporal` is deprecated and this will be removed in a future version. Please use `from diffusers.models.transformers.tranformer_temporal import TransformerSpatioTemporalModel`, instead."
|
||||||
deprecate("TransformerTemporalModelOutput", "0.29", deprecation_message)
|
deprecate("TransformerTemporalModelOutput", "0.29", deprecation_message)
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ class Transformer2DModel(ModelMixin, ConfigMixin):
|
|||||||
if norm_type == "layer_norm" and num_embeds_ada_norm is not None:
|
if norm_type == "layer_norm" and num_embeds_ada_norm is not None:
|
||||||
deprecation_message = (
|
deprecation_message = (
|
||||||
f"The configuration file of this model: {self.__class__} is outdated. `norm_type` is either not set or"
|
f"The configuration file of this model: {self.__class__} is outdated. `norm_type` is either not set or"
|
||||||
" incorrectly set to `'layer_norm'`. Make sure to set `norm_type` to `'ada_norm'` in the config."
|
" incorrectly set to `'layer_norm'`.Make sure to set `norm_type` to `'ada_norm'` in the config."
|
||||||
" Please make sure to update the config accordingly as leaving `norm_type` might led to incorrect"
|
" Please make sure to update the config accordingly as leaving `norm_type` might led to incorrect"
|
||||||
" results in future versions. If you have downloaded this checkpoint from the Hugging Face Hub, it"
|
" results in future versions. If you have downloaded this checkpoint from the Hugging Face Hub, it"
|
||||||
" would be very nice if you could open a Pull request for the `transformer/config.json` file"
|
" would be very nice if you could open a Pull request for the `transformer/config.json` file"
|
||||||
@@ -308,7 +308,7 @@ class Transformer2DModel(ModelMixin, ConfigMixin):
|
|||||||
"""
|
"""
|
||||||
if cross_attention_kwargs is not None:
|
if cross_attention_kwargs is not None:
|
||||||
if cross_attention_kwargs.get("scale", None) is not None:
|
if cross_attention_kwargs.get("scale", None) is not None:
|
||||||
logger.warning("Passing `scale` to `cross_attention_kwargs` is deprecated. `scale` will be ignored.")
|
logger.warning("Passing `scale` to `cross_attention_kwargs` is depcrecated. `scale` will be ignored.")
|
||||||
# ensure attention_mask is a bias, and give it a singleton query_tokens dimension.
|
# ensure attention_mask is a bias, and give it a singleton query_tokens dimension.
|
||||||
# we may have done this conversion already, e.g. if we came here via UNet2DConditionModel#forward.
|
# we may have done this conversion already, e.g. if we came here via UNet2DConditionModel#forward.
|
||||||
# we can tell by counting dims; if ndim == 2: it's a mask rather than a bias.
|
# we can tell by counting dims; if ndim == 2: it's a mask rather than a bias.
|
||||||
|
|||||||
@@ -846,7 +846,7 @@ class UNetMidBlock2DCrossAttn(nn.Module):
|
|||||||
) -> torch.FloatTensor:
|
) -> torch.FloatTensor:
|
||||||
if cross_attention_kwargs is not None:
|
if cross_attention_kwargs is not None:
|
||||||
if cross_attention_kwargs.get("scale", None) is not None:
|
if cross_attention_kwargs.get("scale", None) is not None:
|
||||||
logger.warning("Passing `scale` to `cross_attention_kwargs` is deprecated. `scale` will be ignored.")
|
logger.warning("Passing `scale` to `cross_attention_kwargs` is depcrecated. `scale` will be ignored.")
|
||||||
|
|
||||||
hidden_states = self.resnets[0](hidden_states, temb)
|
hidden_states = self.resnets[0](hidden_states, temb)
|
||||||
for attn, resnet in zip(self.attentions, self.resnets[1:]):
|
for attn, resnet in zip(self.attentions, self.resnets[1:]):
|
||||||
@@ -986,7 +986,7 @@ class UNetMidBlock2DSimpleCrossAttn(nn.Module):
|
|||||||
) -> torch.FloatTensor:
|
) -> torch.FloatTensor:
|
||||||
cross_attention_kwargs = cross_attention_kwargs if cross_attention_kwargs is not None else {}
|
cross_attention_kwargs = cross_attention_kwargs if cross_attention_kwargs is not None else {}
|
||||||
if cross_attention_kwargs.get("scale", None) is not None:
|
if cross_attention_kwargs.get("scale", None) is not None:
|
||||||
logger.warning("Passing `scale` to `cross_attention_kwargs` is deprecated. `scale` will be ignored.")
|
logger.warning("Passing `scale` to `cross_attention_kwargs` is depcrecated. `scale` will be ignored.")
|
||||||
|
|
||||||
if attention_mask is None:
|
if attention_mask is None:
|
||||||
# if encoder_hidden_states is defined: we are doing cross-attn, so we should use cross-attn mask.
|
# if encoder_hidden_states is defined: we are doing cross-attn, so we should use cross-attn mask.
|
||||||
@@ -1116,7 +1116,7 @@ class AttnDownBlock2D(nn.Module):
|
|||||||
) -> Tuple[torch.FloatTensor, Tuple[torch.FloatTensor, ...]]:
|
) -> Tuple[torch.FloatTensor, Tuple[torch.FloatTensor, ...]]:
|
||||||
cross_attention_kwargs = cross_attention_kwargs if cross_attention_kwargs is not None else {}
|
cross_attention_kwargs = cross_attention_kwargs if cross_attention_kwargs is not None else {}
|
||||||
if cross_attention_kwargs.get("scale", None) is not None:
|
if cross_attention_kwargs.get("scale", None) is not None:
|
||||||
logger.warning("Passing `scale` to `cross_attention_kwargs` is deprecated. `scale` will be ignored.")
|
logger.warning("Passing `scale` to `cross_attention_kwargs` is depcrecated. `scale` will be ignored.")
|
||||||
|
|
||||||
output_states = ()
|
output_states = ()
|
||||||
|
|
||||||
@@ -1241,7 +1241,7 @@ class CrossAttnDownBlock2D(nn.Module):
|
|||||||
) -> Tuple[torch.FloatTensor, Tuple[torch.FloatTensor, ...]]:
|
) -> Tuple[torch.FloatTensor, Tuple[torch.FloatTensor, ...]]:
|
||||||
if cross_attention_kwargs is not None:
|
if cross_attention_kwargs is not None:
|
||||||
if cross_attention_kwargs.get("scale", None) is not None:
|
if cross_attention_kwargs.get("scale", None) is not None:
|
||||||
logger.warning("Passing `scale` to `cross_attention_kwargs` is deprecated. `scale` will be ignored.")
|
logger.warning("Passing `scale` to `cross_attention_kwargs` is depcrecated. `scale` will be ignored.")
|
||||||
|
|
||||||
output_states = ()
|
output_states = ()
|
||||||
|
|
||||||
@@ -1986,7 +1986,7 @@ class SimpleCrossAttnDownBlock2D(nn.Module):
|
|||||||
) -> Tuple[torch.FloatTensor, Tuple[torch.FloatTensor, ...]]:
|
) -> Tuple[torch.FloatTensor, Tuple[torch.FloatTensor, ...]]:
|
||||||
cross_attention_kwargs = cross_attention_kwargs if cross_attention_kwargs is not None else {}
|
cross_attention_kwargs = cross_attention_kwargs if cross_attention_kwargs is not None else {}
|
||||||
if cross_attention_kwargs.get("scale", None) is not None:
|
if cross_attention_kwargs.get("scale", None) is not None:
|
||||||
logger.warning("Passing `scale` to `cross_attention_kwargs` is deprecated. `scale` will be ignored.")
|
logger.warning("Passing `scale` to `cross_attention_kwargs` is depcrecated. `scale` will be ignored.")
|
||||||
|
|
||||||
output_states = ()
|
output_states = ()
|
||||||
|
|
||||||
@@ -2201,7 +2201,7 @@ class KCrossAttnDownBlock2D(nn.Module):
|
|||||||
) -> Tuple[torch.FloatTensor, Tuple[torch.FloatTensor, ...]]:
|
) -> Tuple[torch.FloatTensor, Tuple[torch.FloatTensor, ...]]:
|
||||||
cross_attention_kwargs = cross_attention_kwargs if cross_attention_kwargs is not None else {}
|
cross_attention_kwargs = cross_attention_kwargs if cross_attention_kwargs is not None else {}
|
||||||
if cross_attention_kwargs.get("scale", None) is not None:
|
if cross_attention_kwargs.get("scale", None) is not None:
|
||||||
logger.warning("Passing `scale` to `cross_attention_kwargs` is deprecated. `scale` will be ignored.")
|
logger.warning("Passing `scale` to `cross_attention_kwargs` is depcrecated. `scale` will be ignored.")
|
||||||
|
|
||||||
output_states = ()
|
output_states = ()
|
||||||
|
|
||||||
@@ -2483,7 +2483,7 @@ class CrossAttnUpBlock2D(nn.Module):
|
|||||||
) -> torch.FloatTensor:
|
) -> torch.FloatTensor:
|
||||||
if cross_attention_kwargs is not None:
|
if cross_attention_kwargs is not None:
|
||||||
if cross_attention_kwargs.get("scale", None) is not None:
|
if cross_attention_kwargs.get("scale", None) is not None:
|
||||||
logger.warning("Passing `scale` to `cross_attention_kwargs` is deprecated. `scale` will be ignored.")
|
logger.warning("Passing `scale` to `cross_attention_kwargs` is depcrecated. `scale` will be ignored.")
|
||||||
|
|
||||||
is_freeu_enabled = (
|
is_freeu_enabled = (
|
||||||
getattr(self, "s1", None)
|
getattr(self, "s1", None)
|
||||||
@@ -3312,7 +3312,7 @@ class SimpleCrossAttnUpBlock2D(nn.Module):
|
|||||||
) -> torch.FloatTensor:
|
) -> torch.FloatTensor:
|
||||||
cross_attention_kwargs = cross_attention_kwargs if cross_attention_kwargs is not None else {}
|
cross_attention_kwargs = cross_attention_kwargs if cross_attention_kwargs is not None else {}
|
||||||
if cross_attention_kwargs.get("scale", None) is not None:
|
if cross_attention_kwargs.get("scale", None) is not None:
|
||||||
logger.warning("Passing `scale` to `cross_attention_kwargs` is deprecated. `scale` will be ignored.")
|
logger.warning("Passing `scale` to `cross_attention_kwargs` is depcrecated. `scale` will be ignored.")
|
||||||
|
|
||||||
if attention_mask is None:
|
if attention_mask is None:
|
||||||
# if encoder_hidden_states is defined: we are doing cross-attn, so we should use cross-attn mask.
|
# if encoder_hidden_states is defined: we are doing cross-attn, so we should use cross-attn mask.
|
||||||
@@ -3694,7 +3694,7 @@ class KAttentionBlock(nn.Module):
|
|||||||
) -> torch.FloatTensor:
|
) -> torch.FloatTensor:
|
||||||
cross_attention_kwargs = cross_attention_kwargs if cross_attention_kwargs is not None else {}
|
cross_attention_kwargs = cross_attention_kwargs if cross_attention_kwargs is not None else {}
|
||||||
if cross_attention_kwargs.get("scale", None) is not None:
|
if cross_attention_kwargs.get("scale", None) is not None:
|
||||||
logger.warning("Passing `scale` to `cross_attention_kwargs` is deprecated. `scale` will be ignored.")
|
logger.warning("Passing `scale` to `cross_attention_kwargs` is depcrecated. `scale` will be ignored.")
|
||||||
|
|
||||||
# 1. Self-Attention
|
# 1. Self-Attention
|
||||||
if self.add_self_attention:
|
if self.add_self_attention:
|
||||||
|
|||||||
@@ -580,7 +580,7 @@ class UNet2DConditionModel(ModelMixin, ConfigMixin, UNet2DConditionLoadersMixin,
|
|||||||
elif encoder_hid_dim_type == "text_image_proj":
|
elif encoder_hid_dim_type == "text_image_proj":
|
||||||
# image_embed_dim DOESN'T have to be `cross_attention_dim`. To not clutter the __init__ too much
|
# image_embed_dim DOESN'T have to be `cross_attention_dim`. To not clutter the __init__ too much
|
||||||
# they are set to `cross_attention_dim` here as this is exactly the required dimension for the currently only use
|
# they are set to `cross_attention_dim` here as this is exactly the required dimension for the currently only use
|
||||||
# case when `addition_embed_type == "text_image_proj"` (Kandinsky 2.1)`
|
# case when `addition_embed_type == "text_image_proj"` (Kadinsky 2.1)`
|
||||||
self.encoder_hid_proj = TextImageProjection(
|
self.encoder_hid_proj = TextImageProjection(
|
||||||
text_embed_dim=encoder_hid_dim,
|
text_embed_dim=encoder_hid_dim,
|
||||||
image_embed_dim=cross_attention_dim,
|
image_embed_dim=cross_attention_dim,
|
||||||
@@ -660,7 +660,7 @@ class UNet2DConditionModel(ModelMixin, ConfigMixin, UNet2DConditionLoadersMixin,
|
|||||||
elif addition_embed_type == "text_image":
|
elif addition_embed_type == "text_image":
|
||||||
# text_embed_dim and image_embed_dim DON'T have to be `cross_attention_dim`. To not clutter the __init__ too much
|
# text_embed_dim and image_embed_dim DON'T have to be `cross_attention_dim`. To not clutter the __init__ too much
|
||||||
# they are set to `cross_attention_dim` here as this is exactly the required dimension for the currently only use
|
# they are set to `cross_attention_dim` here as this is exactly the required dimension for the currently only use
|
||||||
# case when `addition_embed_type == "text_image"` (Kandinsky 2.1)`
|
# case when `addition_embed_type == "text_image"` (Kadinsky 2.1)`
|
||||||
self.add_embedding = TextImageTimeEmbedding(
|
self.add_embedding = TextImageTimeEmbedding(
|
||||||
text_embed_dim=cross_attention_dim, image_embed_dim=cross_attention_dim, time_embed_dim=time_embed_dim
|
text_embed_dim=cross_attention_dim, image_embed_dim=cross_attention_dim, time_embed_dim=time_embed_dim
|
||||||
)
|
)
|
||||||
@@ -1010,7 +1010,7 @@ class UNet2DConditionModel(ModelMixin, ConfigMixin, UNet2DConditionLoadersMixin,
|
|||||||
if self.encoder_hid_proj is not None and self.config.encoder_hid_dim_type == "text_proj":
|
if self.encoder_hid_proj is not None and self.config.encoder_hid_dim_type == "text_proj":
|
||||||
encoder_hidden_states = self.encoder_hid_proj(encoder_hidden_states)
|
encoder_hidden_states = self.encoder_hid_proj(encoder_hidden_states)
|
||||||
elif self.encoder_hid_proj is not None and self.config.encoder_hid_dim_type == "text_image_proj":
|
elif self.encoder_hid_proj is not None and self.config.encoder_hid_dim_type == "text_image_proj":
|
||||||
# Kandinsky 2.1 - style
|
# Kadinsky 2.1 - style
|
||||||
if "image_embeds" not in added_cond_kwargs:
|
if "image_embeds" not in added_cond_kwargs:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"{self.__class__} has the config param `encoder_hid_dim_type` set to 'text_image_proj' which requires the keyword argument `image_embeds` to be passed in `added_conditions`"
|
f"{self.__class__} has the config param `encoder_hid_dim_type` set to 'text_image_proj' which requires the keyword argument `image_embeds` to be passed in `added_conditions`"
|
||||||
@@ -1081,8 +1081,6 @@ class UNet2DConditionModel(ModelMixin, ConfigMixin, UNet2DConditionLoadersMixin,
|
|||||||
A tuple of tensors that if specified are added to the residuals of down unet blocks.
|
A tuple of tensors that if specified are added to the residuals of down unet blocks.
|
||||||
mid_block_additional_residual: (`torch.Tensor`, *optional*):
|
mid_block_additional_residual: (`torch.Tensor`, *optional*):
|
||||||
A tensor that if specified is added to the residual of the middle unet block.
|
A tensor that if specified is added to the residual of the middle unet block.
|
||||||
down_intrablock_additional_residuals (`tuple` of `torch.Tensor`, *optional*):
|
|
||||||
additional residuals to be added within UNet down blocks, for example from T2I-Adapter side model(s)
|
|
||||||
encoder_attention_mask (`torch.Tensor`):
|
encoder_attention_mask (`torch.Tensor`):
|
||||||
A cross-attention mask of shape `(batch, sequence_length)` is applied to `encoder_hidden_states`. If
|
A cross-attention mask of shape `(batch, sequence_length)` is applied to `encoder_hidden_states`. If
|
||||||
`True` the mask is kept, otherwise if `False` it is discarded. Mask will be converted into a bias,
|
`True` the mask is kept, otherwise if `False` it is discarded. Mask will be converted into a bias,
|
||||||
@@ -1090,6 +1088,18 @@ class UNet2DConditionModel(ModelMixin, ConfigMixin, UNet2DConditionLoadersMixin,
|
|||||||
return_dict (`bool`, *optional*, defaults to `True`):
|
return_dict (`bool`, *optional*, defaults to `True`):
|
||||||
Whether or not to return a [`~models.unets.unet_2d_condition.UNet2DConditionOutput`] instead of a plain
|
Whether or not to return a [`~models.unets.unet_2d_condition.UNet2DConditionOutput`] instead of a plain
|
||||||
tuple.
|
tuple.
|
||||||
|
cross_attention_kwargs (`dict`, *optional*):
|
||||||
|
A kwargs dictionary that if specified is passed along to the [`AttnProcessor`].
|
||||||
|
added_cond_kwargs: (`dict`, *optional*):
|
||||||
|
A kwargs dictionary containin additional embeddings that if specified are added to the embeddings that
|
||||||
|
are passed along to the UNet blocks.
|
||||||
|
down_block_additional_residuals (`tuple` of `torch.Tensor`, *optional*):
|
||||||
|
additional residuals to be added to UNet long skip connections from down blocks to up blocks for
|
||||||
|
example from ControlNet side model(s)
|
||||||
|
mid_block_additional_residual (`torch.Tensor`, *optional*):
|
||||||
|
additional residual to be added to UNet mid block output, for example from ControlNet side model
|
||||||
|
down_intrablock_additional_residuals (`tuple` of `torch.Tensor`, *optional*):
|
||||||
|
additional residuals to be added within UNet down blocks, for example from T2I-Adapter side model(s)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
[`~models.unets.unet_2d_condition.UNet2DConditionOutput`] or `tuple`:
|
[`~models.unets.unet_2d_condition.UNet2DConditionOutput`] or `tuple`:
|
||||||
@@ -1175,14 +1185,7 @@ class UNet2DConditionModel(ModelMixin, ConfigMixin, UNet2DConditionLoadersMixin,
|
|||||||
cross_attention_kwargs["gligen"] = {"objs": self.position_net(**gligen_args)}
|
cross_attention_kwargs["gligen"] = {"objs": self.position_net(**gligen_args)}
|
||||||
|
|
||||||
# 3. down
|
# 3. down
|
||||||
# we're popping the `scale` instead of getting it because otherwise `scale` will be propagated
|
lora_scale = cross_attention_kwargs.get("scale", 1.0) if cross_attention_kwargs is not None else 1.0
|
||||||
# to the internal blocks and will raise deprecation warnings. this will be confusing for our users.
|
|
||||||
if cross_attention_kwargs is not None:
|
|
||||||
cross_attention_kwargs = cross_attention_kwargs.copy()
|
|
||||||
lora_scale = cross_attention_kwargs.pop("scale", 1.0)
|
|
||||||
else:
|
|
||||||
lora_scale = 1.0
|
|
||||||
|
|
||||||
if USE_PEFT_BACKEND:
|
if USE_PEFT_BACKEND:
|
||||||
# weight the lora layers by setting `lora_scale` for each PEFT layer
|
# weight the lora layers by setting `lora_scale` for each PEFT layer
|
||||||
scale_lora_layers(self, lora_scale)
|
scale_lora_layers(self, lora_scale)
|
||||||
|
|||||||
@@ -1183,7 +1183,7 @@ class CrossAttnDownBlockMotion(nn.Module):
|
|||||||
):
|
):
|
||||||
if cross_attention_kwargs is not None:
|
if cross_attention_kwargs is not None:
|
||||||
if cross_attention_kwargs.get("scale", None) is not None:
|
if cross_attention_kwargs.get("scale", None) is not None:
|
||||||
logger.warning("Passing `scale` to `cross_attention_kwargs` is deprecated. `scale` will be ignored.")
|
logger.warning("Passing `scale` to `cross_attention_kwargs` is depcrecated. `scale` will be ignored.")
|
||||||
|
|
||||||
output_states = ()
|
output_states = ()
|
||||||
|
|
||||||
@@ -1367,7 +1367,7 @@ class CrossAttnUpBlockMotion(nn.Module):
|
|||||||
) -> torch.FloatTensor:
|
) -> torch.FloatTensor:
|
||||||
if cross_attention_kwargs is not None:
|
if cross_attention_kwargs is not None:
|
||||||
if cross_attention_kwargs.get("scale", None) is not None:
|
if cross_attention_kwargs.get("scale", None) is not None:
|
||||||
logger.warning("Passing `scale` to `cross_attention_kwargs` is deprecated. `scale` will be ignored.")
|
logger.warning("Passing `scale` to `cross_attention_kwargs` is depcrecated. `scale` will be ignored.")
|
||||||
|
|
||||||
is_freeu_enabled = (
|
is_freeu_enabled = (
|
||||||
getattr(self, "s1", None)
|
getattr(self, "s1", None)
|
||||||
@@ -1707,7 +1707,7 @@ class UNetMidBlockCrossAttnMotion(nn.Module):
|
|||||||
) -> torch.FloatTensor:
|
) -> torch.FloatTensor:
|
||||||
if cross_attention_kwargs is not None:
|
if cross_attention_kwargs is not None:
|
||||||
if cross_attention_kwargs.get("scale", None) is not None:
|
if cross_attention_kwargs.get("scale", None) is not None:
|
||||||
logger.warning("Passing `scale` to `cross_attention_kwargs` is deprecated. `scale` will be ignored.")
|
logger.warning("Passing `scale` to `cross_attention_kwargs` is depcrecated. `scale` will be ignored.")
|
||||||
|
|
||||||
hidden_states = self.resnets[0](hidden_states, temb)
|
hidden_states = self.resnets[0](hidden_states, temb)
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user