Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
renzhc
diffusers_dcu
Commits
11d18f32
Unverified
Commit
11d18f32
authored
Jul 12, 2024
by
Dhruv Nair
Committed by
GitHub
Jul 12, 2024
Browse files
Add single file loading support for AnimateDiff (#8819)
* update * update * update * update
parent
d2df40c6
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
149 additions
and
2 deletions
+149
-2
docs/source/en/api/pipelines/animatediff.md
docs/source/en/api/pipelines/animatediff.md
+14
-0
src/diffusers/loaders/single_file_model.py
src/diffusers/loaders/single_file_model.py
+4
-0
src/diffusers/loaders/single_file_utils.py
src/diffusers/loaders/single_file_utils.py
+39
-0
src/diffusers/models/unets/unet_motion_model.py
src/diffusers/models/unets/unet_motion_model.py
+2
-2
tests/single_file/test_model_motion_adapter_single_file.py
tests/single_file/test_model_motion_adapter_single_file.py
+90
-0
No files found.
docs/source/en/api/pipelines/animatediff.md
View file @
11d18f32
...
...
@@ -560,6 +560,20 @@ export_to_gif(frames, "animatelcm-motion-lora.gif")
</table>
## Using `from_single_file` with the MotionAdapter
`diffusers>=0.30.0`
supports loading the AnimateDiff checkpoints into the
`MotionAdapter`
in their original format via
`from_single_file`
```
python
from
diffusers
import
MotionAdapter
ckpt_path
=
"https://huggingface.co/Lightricks/LongAnimateDiff/blob/main/lt_long_mm_32_frames.ckpt"
adapter
=
MotionAdapter
.
from_single_file
(
ckpt_path
,
torch_dtype
=
torch
.
float16
)
pipe
=
AnimateDiffPipeline
.
from_pretrained
(
"emilianJR/epiCRealism"
,
motion_adapter
=
adapter
)
```
## AnimateDiffPipeline
[[autodoc]] AnimateDiffPipeline
...
...
src/diffusers/loaders/single_file_model.py
View file @
11d18f32
...
...
@@ -22,6 +22,7 @@ from huggingface_hub.utils import validate_hf_hub_args
from
..utils
import
deprecate
,
is_accelerate_available
,
logging
from
.single_file_utils
import
(
SingleFileComponentError
,
convert_animatediff_checkpoint_to_diffusers
,
convert_controlnet_checkpoint
,
convert_ldm_unet_checkpoint
,
convert_ldm_vae_checkpoint
,
...
...
@@ -70,6 +71,9 @@ SINGLE_FILE_LOADABLE_CLASSES = {
"checkpoint_mapping_fn"
:
convert_sd3_transformer_checkpoint_to_diffusers
,
"default_subfolder"
:
"transformer"
,
},
"MotionAdapter"
:
{
"checkpoint_mapping_fn"
:
convert_animatediff_checkpoint_to_diffusers
,
},
}
...
...
src/diffusers/loaders/single_file_utils.py
View file @
11d18f32
...
...
@@ -74,6 +74,9 @@ CHECKPOINT_KEY_NAMES = {
"stable_cascade_stage_b"
:
"down_blocks.1.0.channelwise.0.weight"
,
"stable_cascade_stage_c"
:
"clip_txt_mapper.weight"
,
"sd3"
:
"model.diffusion_model.joint_blocks.0.context_block.adaLN_modulation.1.bias"
,
"animatediff"
:
"down_blocks.0.motion_modules.0.temporal_transformer.transformer_blocks.0.attention_blocks.1.pos_encoder.pe"
,
"animatediff_v2"
:
"mid_block.motion_modules.0.temporal_transformer.norm.bias"
,
"animatediff_sdxl_beta"
:
"up_blocks.2.motion_modules.0.temporal_transformer.norm.weight"
,
}
DIFFUSERS_DEFAULT_PIPELINE_PATHS
=
{
...
...
@@ -103,6 +106,10 @@ DIFFUSERS_DEFAULT_PIPELINE_PATHS = {
"sd3"
:
{
"pretrained_model_name_or_path"
:
"stabilityai/stable-diffusion-3-medium-diffusers"
,
},
"animatediff_v1"
:
{
"pretrained_model_name_or_path"
:
"guoyww/animatediff-motion-adapter-v1-5"
},
"animatediff_v2"
:
{
"pretrained_model_name_or_path"
:
"guoyww/animatediff-motion-adapter-v1-5-2"
},
"animatediff_v3"
:
{
"pretrained_model_name_or_path"
:
"guoyww/animatediff-motion-adapter-v1-5-3"
},
"animatediff_sdxl_beta"
:
{
"pretrained_model_name_or_path"
:
"guoyww/animatediff-motion-adapter-sdxl-beta"
},
}
# Use to configure model sample size when original config is provided
...
...
@@ -485,6 +492,19 @@ def infer_diffusers_model_type(checkpoint):
elif
CHECKPOINT_KEY_NAMES
[
"sd3"
]
in
checkpoint
:
model_type
=
"sd3"
elif
CHECKPOINT_KEY_NAMES
[
"animatediff"
]
in
checkpoint
:
if
CHECKPOINT_KEY_NAMES
[
"animatediff_v2"
]
in
checkpoint
:
model_type
=
"animatediff_v2"
elif
checkpoint
[
CHECKPOINT_KEY_NAMES
[
"animatediff_sdxl_beta"
]].
shape
[
-
1
]
==
320
:
model_type
=
"animatediff_sdxl_beta"
elif
checkpoint
[
CHECKPOINT_KEY_NAMES
[
"animatediff"
]].
shape
[
1
]
==
24
:
model_type
=
"animatediff_v1"
else
:
model_type
=
"animatediff_v3"
else
:
model_type
=
"v1"
...
...
@@ -1822,3 +1842,22 @@ def create_diffusers_t5_model_from_checkpoint(
param
.
data
=
param
.
data
.
to
(
torch
.
float32
)
return
model
def
convert_animatediff_checkpoint_to_diffusers
(
checkpoint
,
**
kwargs
):
converted_state_dict
=
{}
for
k
,
v
in
checkpoint
.
items
():
if
"pos_encoder"
in
k
:
continue
else
:
converted_state_dict
[
k
.
replace
(
".norms.0"
,
".norm1"
)
.
replace
(
".norms.1"
,
".norm2"
)
.
replace
(
".ff_norm"
,
".norm3"
)
.
replace
(
".attention_blocks.0"
,
".attn1"
)
.
replace
(
".attention_blocks.1"
,
".attn2"
)
.
replace
(
".temporal_transformer"
,
""
)
]
=
v
return
converted_state_dict
src/diffusers/models/unets/unet_motion_model.py
View file @
11d18f32
...
...
@@ -19,7 +19,7 @@ import torch.nn.functional as F
import
torch.utils.checkpoint
from
...configuration_utils
import
ConfigMixin
,
FrozenDict
,
register_to_config
from
...loaders
import
UNet2DConditionLoadersMixin
from
...loaders
import
FromOriginalModelMixin
,
UNet2DConditionLoadersMixin
from
...utils
import
logging
from
..attention_processor
import
(
ADDED_KV_ATTENTION_PROCESSORS
,
...
...
@@ -93,7 +93,7 @@ class MotionModules(nn.Module):
)
class
MotionAdapter
(
ModelMixin
,
ConfigMixin
):
class
MotionAdapter
(
ModelMixin
,
ConfigMixin
,
FromOriginalModelMixin
):
@
register_to_config
def
__init__
(
self
,
...
...
tests/single_file/test_model_motion_adapter_single_file.py
0 → 100644
View file @
11d18f32
# coding=utf-8
# Copyright 2024 HuggingFace Inc.
#
# 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.
import
unittest
from
diffusers
import
(
MotionAdapter
,
)
from
diffusers.utils.testing_utils
import
(
enable_full_determinism
,
)
enable_full_determinism
()
class
MotionAdapterSingleFileTests
(
unittest
.
TestCase
):
model_class
=
MotionAdapter
def
test_single_file_components_version_v1_5
(
self
):
ckpt_path
=
"https://huggingface.co/guoyww/animatediff/blob/main/mm_sd_v15.ckpt"
repo_id
=
"guoyww/animatediff-motion-adapter-v1-5"
model
=
self
.
model_class
.
from_pretrained
(
repo_id
)
model_single_file
=
self
.
model_class
.
from_single_file
(
ckpt_path
)
PARAMS_TO_IGNORE
=
[
"torch_dtype"
,
"_name_or_path"
,
"_use_default_values"
,
"_diffusers_version"
]
for
param_name
,
param_value
in
model_single_file
.
config
.
items
():
if
param_name
in
PARAMS_TO_IGNORE
:
continue
assert
(
model
.
config
[
param_name
]
==
param_value
),
f
"
{
param_name
}
differs between pretrained loading and single file loading"
def
test_single_file_components_version_v1_5_2
(
self
):
ckpt_path
=
"https://huggingface.co/guoyww/animatediff/blob/main/mm_sd_v15_v2.ckpt"
repo_id
=
"guoyww/animatediff-motion-adapter-v1-5-2"
model
=
self
.
model_class
.
from_pretrained
(
repo_id
)
model_single_file
=
self
.
model_class
.
from_single_file
(
ckpt_path
)
PARAMS_TO_IGNORE
=
[
"torch_dtype"
,
"_name_or_path"
,
"_use_default_values"
,
"_diffusers_version"
]
for
param_name
,
param_value
in
model_single_file
.
config
.
items
():
if
param_name
in
PARAMS_TO_IGNORE
:
continue
assert
(
model
.
config
[
param_name
]
==
param_value
),
f
"
{
param_name
}
differs between pretrained loading and single file loading"
def
test_single_file_components_version_v1_5_3
(
self
):
ckpt_path
=
"https://huggingface.co/guoyww/animatediff/blob/main/v3_sd15_mm.ckpt"
repo_id
=
"guoyww/animatediff-motion-adapter-v1-5-3"
model
=
self
.
model_class
.
from_pretrained
(
repo_id
)
model_single_file
=
self
.
model_class
.
from_single_file
(
ckpt_path
)
PARAMS_TO_IGNORE
=
[
"torch_dtype"
,
"_name_or_path"
,
"_use_default_values"
,
"_diffusers_version"
]
for
param_name
,
param_value
in
model_single_file
.
config
.
items
():
if
param_name
in
PARAMS_TO_IGNORE
:
continue
assert
(
model
.
config
[
param_name
]
==
param_value
),
f
"
{
param_name
}
differs between pretrained loading and single file loading"
def
test_single_file_components_version_sdxl_beta
(
self
):
ckpt_path
=
"https://huggingface.co/guoyww/animatediff/blob/main/mm_sdxl_v10_beta.ckpt"
repo_id
=
"guoyww/animatediff-motion-adapter-sdxl-beta"
model
=
self
.
model_class
.
from_pretrained
(
repo_id
)
model_single_file
=
self
.
model_class
.
from_single_file
(
ckpt_path
)
PARAMS_TO_IGNORE
=
[
"torch_dtype"
,
"_name_or_path"
,
"_use_default_values"
,
"_diffusers_version"
]
for
param_name
,
param_value
in
model_single_file
.
config
.
items
():
if
param_name
in
PARAMS_TO_IGNORE
:
continue
assert
(
model
.
config
[
param_name
]
==
param_value
),
f
"
{
param_name
}
differs between pretrained loading and single file loading"
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment