Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
chenpangpang
diffusers
Commits
3fb28c44
Commit
3fb28c44
authored
Nov 17, 2022
by
Patrick von Platen
Browse files
xMerge branch 'main' of
https://github.com/huggingface/diffusers
parents
2dd12e38
3346ec3a
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
280 additions
and
5 deletions
+280
-5
examples/unconditional_image_generation/README.md
examples/unconditional_image_generation/README.md
+21
-0
examples/unconditional_image_generation/train_unconditional_ort.py
...unconditional_image_generation/train_unconditional_ort.py
+251
-0
src/diffusers/pipeline_utils.py
src/diffusers/pipeline_utils.py
+3
-0
src/diffusers/pipelines/alt_diffusion/pipeline_alt_diffusion_img2img.py
...pipelines/alt_diffusion/pipeline_alt_diffusion_img2img.py
+1
-1
src/diffusers/pipelines/stable_diffusion/pipeline_cycle_diffusion.py
...rs/pipelines/stable_diffusion/pipeline_cycle_diffusion.py
+1
-1
src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_img2img.py
...nes/stable_diffusion/pipeline_stable_diffusion_img2img.py
+1
-1
src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_inpaint.py
...nes/stable_diffusion/pipeline_stable_diffusion_inpaint.py
+1
-1
src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_inpaint_legacy.py
...ble_diffusion/pipeline_stable_diffusion_inpaint_legacy.py
+1
-1
No files found.
examples/unconditional_image_generation/README.md
View file @
3fb28c44
...
@@ -127,3 +127,24 @@ dataset.push_to_hub("name_of_your_dataset", private=True)
...
@@ -127,3 +127,24 @@ dataset.push_to_hub("name_of_your_dataset", private=True)
and that's it! You can now train your model by simply setting the
`--dataset_name`
argument to the name of your dataset on the hub.
and that's it! You can now train your model by simply setting the
`--dataset_name`
argument to the name of your dataset on the hub.
More on this can also be found in
[
this blog post
](
https://huggingface.co/blog/image-search-datasets
)
.
More on this can also be found in
[
this blog post
](
https://huggingface.co/blog/image-search-datasets
)
.
#### Use ONNXRuntime to accelerate training
In order to leverage onnxruntime to accelerate training, please use train_unconditional_ort.py
The command to train a DDPM UNet model on the Oxford Flowers dataset with onnxruntime:
```
bash
accelerate launch train_unconditional_ort.py
\
--dataset_name
=
"huggan/flowers-102-categories"
\
--resolution
=
64
\
--output_dir
=
"ddpm-ema-flowers-64"
\
--train_batch_size
=
16
\
--num_epochs
=
1
\
--gradient_accumulation_steps
=
1
\
--learning_rate
=
1e-4
\
--lr_warmup_steps
=
500
\
--mixed_precision
=
fp16
```
Please contact Prathik Rao (prathikr), Sunghoon Choi (hanbitmyths), Ashwini Khade (askhade), or Peng Wang (pengwa) on github with any questions.
\ No newline at end of file
examples/unconditional_image_generation/train_unconditional_ort.py
0 → 100644
View file @
3fb28c44
import
argparse
import
math
import
os
import
torch
import
torch.nn.functional
as
F
from
accelerate
import
Accelerator
from
accelerate.logging
import
get_logger
from
datasets
import
load_dataset
from
diffusers
import
DDPMPipeline
,
DDPMScheduler
,
UNet2DModel
from
diffusers.hub_utils
import
init_git_repo
,
push_to_hub
from
diffusers.optimization
import
get_scheduler
from
diffusers.training_utils
import
EMAModel
from
onnxruntime.training.ortmodule
import
ORTModule
from
torchvision.transforms
import
(
CenterCrop
,
Compose
,
InterpolationMode
,
Normalize
,
RandomHorizontalFlip
,
Resize
,
ToTensor
,
)
from
tqdm.auto
import
tqdm
logger
=
get_logger
(
__name__
)
def
main
(
args
):
logging_dir
=
os
.
path
.
join
(
args
.
output_dir
,
args
.
logging_dir
)
accelerator
=
Accelerator
(
gradient_accumulation_steps
=
args
.
gradient_accumulation_steps
,
mixed_precision
=
args
.
mixed_precision
,
log_with
=
"tensorboard"
,
logging_dir
=
logging_dir
,
)
model
=
UNet2DModel
(
sample_size
=
args
.
resolution
,
in_channels
=
3
,
out_channels
=
3
,
layers_per_block
=
2
,
block_out_channels
=
(
128
,
128
,
256
,
256
,
512
,
512
),
down_block_types
=
(
"DownBlock2D"
,
"DownBlock2D"
,
"DownBlock2D"
,
"DownBlock2D"
,
"AttnDownBlock2D"
,
"DownBlock2D"
,
),
up_block_types
=
(
"UpBlock2D"
,
"AttnUpBlock2D"
,
"UpBlock2D"
,
"UpBlock2D"
,
"UpBlock2D"
,
"UpBlock2D"
,
),
)
model
=
ORTModule
(
model
)
noise_scheduler
=
DDPMScheduler
(
num_train_timesteps
=
1000
,
tensor_format
=
"pt"
)
optimizer
=
torch
.
optim
.
AdamW
(
model
.
parameters
(),
lr
=
args
.
learning_rate
,
betas
=
(
args
.
adam_beta1
,
args
.
adam_beta2
),
weight_decay
=
args
.
adam_weight_decay
,
eps
=
args
.
adam_epsilon
,
)
augmentations
=
Compose
(
[
Resize
(
args
.
resolution
,
interpolation
=
InterpolationMode
.
BILINEAR
),
CenterCrop
(
args
.
resolution
),
RandomHorizontalFlip
(),
ToTensor
(),
Normalize
([
0.5
],
[
0.5
]),
]
)
if
args
.
dataset_name
is
not
None
:
dataset
=
load_dataset
(
args
.
dataset_name
,
args
.
dataset_config_name
,
cache_dir
=
args
.
cache_dir
,
use_auth_token
=
True
if
args
.
use_auth_token
else
None
,
split
=
"train"
,
)
else
:
dataset
=
load_dataset
(
"imagefolder"
,
data_dir
=
args
.
train_data_dir
,
cache_dir
=
args
.
cache_dir
,
split
=
"train"
)
def
transforms
(
examples
):
images
=
[
augmentations
(
image
.
convert
(
"RGB"
))
for
image
in
examples
[
"image"
]]
return
{
"input"
:
images
}
dataset
.
set_transform
(
transforms
)
train_dataloader
=
torch
.
utils
.
data
.
DataLoader
(
dataset
,
batch_size
=
args
.
train_batch_size
,
shuffle
=
True
)
lr_scheduler
=
get_scheduler
(
args
.
lr_scheduler
,
optimizer
=
optimizer
,
num_warmup_steps
=
args
.
lr_warmup_steps
,
num_training_steps
=
(
len
(
train_dataloader
)
*
args
.
num_epochs
)
//
args
.
gradient_accumulation_steps
,
)
model
,
optimizer
,
train_dataloader
,
lr_scheduler
=
accelerator
.
prepare
(
model
,
optimizer
,
train_dataloader
,
lr_scheduler
)
num_update_steps_per_epoch
=
math
.
ceil
(
len
(
train_dataloader
)
/
args
.
gradient_accumulation_steps
)
ema_model
=
EMAModel
(
model
,
inv_gamma
=
args
.
ema_inv_gamma
,
power
=
args
.
ema_power
,
max_value
=
args
.
ema_max_decay
)
if
args
.
push_to_hub
:
repo
=
init_git_repo
(
args
,
at_init
=
True
)
if
accelerator
.
is_main_process
:
run
=
os
.
path
.
split
(
__file__
)[
-
1
].
split
(
"."
)[
0
]
accelerator
.
init_trackers
(
run
)
global_step
=
0
for
epoch
in
range
(
args
.
num_epochs
):
model
.
train
()
progress_bar
=
tqdm
(
total
=
num_update_steps_per_epoch
,
disable
=
not
accelerator
.
is_local_main_process
)
progress_bar
.
set_description
(
f
"Epoch
{
epoch
}
"
)
for
step
,
batch
in
enumerate
(
train_dataloader
):
clean_images
=
batch
[
"input"
]
# Sample noise that we'll add to the images
noise
=
torch
.
randn
(
clean_images
.
shape
).
to
(
clean_images
.
device
)
bsz
=
clean_images
.
shape
[
0
]
# Sample a random timestep for each image
timesteps
=
torch
.
randint
(
0
,
noise_scheduler
.
config
.
num_train_timesteps
,
(
bsz
,),
device
=
clean_images
.
device
).
long
()
# Add noise to the clean images according to the noise magnitude at each timestep
# (this is the forward diffusion process)
noisy_images
=
noise_scheduler
.
add_noise
(
clean_images
,
noise
,
timesteps
)
with
accelerator
.
accumulate
(
model
):
# Predict the noise residual
noise_pred
=
model
(
noisy_images
,
timesteps
,
return_dict
=
True
)[
0
]
loss
=
F
.
mse_loss
(
noise_pred
,
noise
)
accelerator
.
backward
(
loss
)
accelerator
.
clip_grad_norm_
(
model
.
parameters
(),
1.0
)
optimizer
.
step
()
lr_scheduler
.
step
()
if
args
.
use_ema
:
ema_model
.
step
(
model
)
optimizer
.
zero_grad
()
# Checks if the accelerator has performed an optimization step behind the scenes
if
accelerator
.
sync_gradients
:
progress_bar
.
update
(
1
)
global_step
+=
1
logs
=
{
"loss"
:
loss
.
detach
().
item
(),
"lr"
:
lr_scheduler
.
get_last_lr
()[
0
],
"step"
:
global_step
}
if
args
.
use_ema
:
logs
[
"ema_decay"
]
=
ema_model
.
decay
progress_bar
.
set_postfix
(
**
logs
)
accelerator
.
log
(
logs
,
step
=
global_step
)
progress_bar
.
close
()
accelerator
.
wait_for_everyone
()
# Generate sample images for visual inspection
if
accelerator
.
is_main_process
:
if
epoch
%
args
.
save_images_epochs
==
0
or
epoch
==
args
.
num_epochs
-
1
:
pipeline
=
DDPMPipeline
(
unet
=
accelerator
.
unwrap_model
(
ema_model
.
averaged_model
if
args
.
use_ema
else
model
),
scheduler
=
noise_scheduler
,
)
generator
=
torch
.
manual_seed
(
0
)
# run pipeline in inference (sample random noise and denoise)
images
=
pipeline
(
generator
=
generator
,
batch_size
=
args
.
eval_batch_size
,
output_type
=
"numpy"
).
images
# denormalize the images and save to tensorboard
images_processed
=
(
images
*
255
).
round
().
astype
(
"uint8"
)
accelerator
.
trackers
[
0
].
writer
.
add_images
(
"test_samples"
,
images_processed
.
transpose
(
0
,
3
,
1
,
2
),
epoch
)
if
epoch
%
args
.
save_model_epochs
==
0
or
epoch
==
args
.
num_epochs
-
1
:
# save the model
if
args
.
push_to_hub
:
push_to_hub
(
args
,
pipeline
,
repo
,
commit_message
=
f
"Epoch
{
epoch
}
"
,
blocking
=
False
)
else
:
pipeline
.
save_pretrained
(
args
.
output_dir
)
accelerator
.
wait_for_everyone
()
accelerator
.
end_training
()
if
__name__
==
"__main__"
:
parser
=
argparse
.
ArgumentParser
(
description
=
"Simple example of a training script."
)
parser
.
add_argument
(
"--local_rank"
,
type
=
int
,
default
=-
1
)
parser
.
add_argument
(
"--dataset_name"
,
type
=
str
,
default
=
None
)
parser
.
add_argument
(
"--dataset_config_name"
,
type
=
str
,
default
=
None
)
parser
.
add_argument
(
"--train_data_dir"
,
type
=
str
,
default
=
None
,
help
=
"A folder containing the training data."
)
parser
.
add_argument
(
"--output_dir"
,
type
=
str
,
default
=
"ddpm-model-64"
)
parser
.
add_argument
(
"--overwrite_output_dir"
,
action
=
"store_true"
)
parser
.
add_argument
(
"--cache_dir"
,
type
=
str
,
default
=
None
)
parser
.
add_argument
(
"--resolution"
,
type
=
int
,
default
=
64
)
parser
.
add_argument
(
"--train_batch_size"
,
type
=
int
,
default
=
16
)
parser
.
add_argument
(
"--eval_batch_size"
,
type
=
int
,
default
=
16
)
parser
.
add_argument
(
"--num_epochs"
,
type
=
int
,
default
=
100
)
parser
.
add_argument
(
"--save_images_epochs"
,
type
=
int
,
default
=
10
)
parser
.
add_argument
(
"--save_model_epochs"
,
type
=
int
,
default
=
10
)
parser
.
add_argument
(
"--gradient_accumulation_steps"
,
type
=
int
,
default
=
1
)
parser
.
add_argument
(
"--learning_rate"
,
type
=
float
,
default
=
1e-4
)
parser
.
add_argument
(
"--lr_scheduler"
,
type
=
str
,
default
=
"cosine"
)
parser
.
add_argument
(
"--lr_warmup_steps"
,
type
=
int
,
default
=
500
)
parser
.
add_argument
(
"--adam_beta1"
,
type
=
float
,
default
=
0.95
)
parser
.
add_argument
(
"--adam_beta2"
,
type
=
float
,
default
=
0.999
)
parser
.
add_argument
(
"--adam_weight_decay"
,
type
=
float
,
default
=
1e-6
)
parser
.
add_argument
(
"--adam_epsilon"
,
type
=
float
,
default
=
1e-08
)
parser
.
add_argument
(
"--use_ema"
,
action
=
"store_true"
,
default
=
True
)
parser
.
add_argument
(
"--ema_inv_gamma"
,
type
=
float
,
default
=
1.0
)
parser
.
add_argument
(
"--ema_power"
,
type
=
float
,
default
=
3
/
4
)
parser
.
add_argument
(
"--ema_max_decay"
,
type
=
float
,
default
=
0.9999
)
parser
.
add_argument
(
"--push_to_hub"
,
action
=
"store_true"
)
parser
.
add_argument
(
"--use_auth_token"
,
action
=
"store_true"
)
parser
.
add_argument
(
"--hub_token"
,
type
=
str
,
default
=
None
)
parser
.
add_argument
(
"--hub_model_id"
,
type
=
str
,
default
=
None
)
parser
.
add_argument
(
"--hub_private_repo"
,
action
=
"store_true"
)
parser
.
add_argument
(
"--logging_dir"
,
type
=
str
,
default
=
"logs"
)
parser
.
add_argument
(
"--mixed_precision"
,
type
=
str
,
default
=
"no"
,
choices
=
[
"no"
,
"fp16"
,
"bf16"
],
help
=
(
"Whether to use mixed precision. Choose"
"between fp16 and bf16 (bfloat16). Bf16 requires PyTorch >= 1.10."
"and an Nvidia Ampere GPU."
),
)
args
=
parser
.
parse_args
()
env_local_rank
=
int
(
os
.
environ
.
get
(
"LOCAL_RANK"
,
-
1
))
if
env_local_rank
!=
-
1
and
env_local_rank
!=
args
.
local_rank
:
args
.
local_rank
=
env_local_rank
if
args
.
dataset_name
is
None
and
args
.
train_data_dir
is
None
:
raise
ValueError
(
"You must specify either a dataset name from the hub or a train data directory."
)
main
(
args
)
src/diffusers/pipeline_utils.py
View file @
3fb28c44
...
@@ -78,6 +78,9 @@ LOADABLE_CLASSES = {
...
@@ -78,6 +78,9 @@ LOADABLE_CLASSES = {
"ProcessorMixin"
:
[
"save_pretrained"
,
"from_pretrained"
],
"ProcessorMixin"
:
[
"save_pretrained"
,
"from_pretrained"
],
"ImageProcessingMixin"
:
[
"save_pretrained"
,
"from_pretrained"
],
"ImageProcessingMixin"
:
[
"save_pretrained"
,
"from_pretrained"
],
},
},
"onnxruntime.training"
:
{
"ORTModule"
:
[
"save_pretrained"
,
"from_pretrained"
],
},
}
}
ALL_IMPORTABLE_CLASSES
=
{}
ALL_IMPORTABLE_CLASSES
=
{}
...
...
src/diffusers/pipelines/alt_diffusion/pipeline_alt_diffusion_img2img.py
View file @
3fb28c44
...
@@ -178,7 +178,7 @@ class AltDiffusionImg2ImgPipeline(DiffusionPipeline):
...
@@ -178,7 +178,7 @@ class AltDiffusionImg2ImgPipeline(DiffusionPipeline):
self
.
enable_attention_slicing
(
None
)
self
.
enable_attention_slicing
(
None
)
# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.AltDiffusionPipeline.enable_sequential_cpu_offload
# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.AltDiffusionPipeline.enable_sequential_cpu_offload
def
enable_sequential_cpu_offload
(
self
):
def
enable_sequential_cpu_offload
(
self
,
gpu_id
=
0
):
r
"""
r
"""
Offloads all models to CPU using accelerate, significantly reducing memory usage. When called, unet,
Offloads all models to CPU using accelerate, significantly reducing memory usage. When called, unet,
text_encoder, vae and safety checker have their state dicts saved to CPU and then are moved to a
text_encoder, vae and safety checker have their state dicts saved to CPU and then are moved to a
...
...
src/diffusers/pipelines/stable_diffusion/pipeline_cycle_diffusion.py
View file @
3fb28c44
...
@@ -209,7 +209,7 @@ class CycleDiffusionPipeline(DiffusionPipeline):
...
@@ -209,7 +209,7 @@ class CycleDiffusionPipeline(DiffusionPipeline):
self
.
enable_attention_slicing
(
None
)
self
.
enable_attention_slicing
(
None
)
# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.enable_sequential_cpu_offload
# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.enable_sequential_cpu_offload
def
enable_sequential_cpu_offload
(
self
):
def
enable_sequential_cpu_offload
(
self
,
gpu_id
=
0
):
r
"""
r
"""
Offloads all models to CPU using accelerate, significantly reducing memory usage. When called, unet,
Offloads all models to CPU using accelerate, significantly reducing memory usage. When called, unet,
text_encoder, vae and safety checker have their state dicts saved to CPU and then are moved to a
text_encoder, vae and safety checker have their state dicts saved to CPU and then are moved to a
...
...
src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_img2img.py
View file @
3fb28c44
...
@@ -176,7 +176,7 @@ class StableDiffusionImg2ImgPipeline(DiffusionPipeline):
...
@@ -176,7 +176,7 @@ class StableDiffusionImg2ImgPipeline(DiffusionPipeline):
self
.
enable_attention_slicing
(
None
)
self
.
enable_attention_slicing
(
None
)
# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.enable_sequential_cpu_offload
# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.enable_sequential_cpu_offload
def
enable_sequential_cpu_offload
(
self
):
def
enable_sequential_cpu_offload
(
self
,
gpu_id
=
0
):
r
"""
r
"""
Offloads all models to CPU using accelerate, significantly reducing memory usage. When called, unet,
Offloads all models to CPU using accelerate, significantly reducing memory usage. When called, unet,
text_encoder, vae and safety checker have their state dicts saved to CPU and then are moved to a
text_encoder, vae and safety checker have their state dicts saved to CPU and then are moved to a
...
...
src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_inpaint.py
View file @
3fb28c44
...
@@ -169,7 +169,7 @@ class StableDiffusionInpaintPipeline(DiffusionPipeline):
...
@@ -169,7 +169,7 @@ class StableDiffusionInpaintPipeline(DiffusionPipeline):
self
.
enable_attention_slicing
(
None
)
self
.
enable_attention_slicing
(
None
)
# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.enable_sequential_cpu_offload
# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.enable_sequential_cpu_offload
def
enable_sequential_cpu_offload
(
self
):
def
enable_sequential_cpu_offload
(
self
,
gpu_id
=
0
):
r
"""
r
"""
Offloads all models to CPU using accelerate, significantly reducing memory usage. When called, unet,
Offloads all models to CPU using accelerate, significantly reducing memory usage. When called, unet,
text_encoder, vae and safety checker have their state dicts saved to CPU and then are moved to a
text_encoder, vae and safety checker have their state dicts saved to CPU and then are moved to a
...
...
src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_inpaint_legacy.py
View file @
3fb28c44
...
@@ -189,7 +189,7 @@ class StableDiffusionInpaintPipelineLegacy(DiffusionPipeline):
...
@@ -189,7 +189,7 @@ class StableDiffusionInpaintPipelineLegacy(DiffusionPipeline):
self
.
enable_attention_slicing
(
None
)
self
.
enable_attention_slicing
(
None
)
# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.enable_sequential_cpu_offload
# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.enable_sequential_cpu_offload
def
enable_sequential_cpu_offload
(
self
):
def
enable_sequential_cpu_offload
(
self
,
gpu_id
=
0
):
r
"""
r
"""
Offloads all models to CPU using accelerate, significantly reducing memory usage. When called, unet,
Offloads all models to CPU using accelerate, significantly reducing memory usage. When called, unet,
text_encoder, vae and safety checker have their state dicts saved to CPU and then are moved to a
text_encoder, vae and safety checker have their state dicts saved to CPU and then are moved to a
...
...
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