Mirror iflytek/AudioFly from ModelScope
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .gitattributes +36 -12
- config/config.yaml +79 -0
- ldm/__init__.py +0 -0
- ldm/modules/__init__.py +0 -0
- ldm/modules/bigvgan/__init__.py +0 -0
- ldm/modules/bigvgan/activations.py +126 -0
- ldm/modules/bigvgan/alias_free_activation/cuda/__init__.py +0 -0
- ldm/modules/bigvgan/alias_free_activation/cuda/activation1d.py +77 -0
- ldm/modules/bigvgan/alias_free_activation/cuda/anti_alias_activation.cpp +23 -0
- ldm/modules/bigvgan/alias_free_activation/cuda/anti_alias_activation_cuda.cu +246 -0
- ldm/modules/bigvgan/alias_free_activation/cuda/compat.h +29 -0
- ldm/modules/bigvgan/alias_free_activation/cuda/load.py +86 -0
- ldm/modules/bigvgan/alias_free_activation/cuda/type_shim.h +92 -0
- ldm/modules/bigvgan/alias_free_activation/torch/__init__.py +6 -0
- ldm/modules/bigvgan/alias_free_activation/torch/act.py +30 -0
- ldm/modules/bigvgan/alias_free_activation/torch/filter.py +101 -0
- ldm/modules/bigvgan/alias_free_activation/torch/resample.py +58 -0
- ldm/modules/bigvgan/bigvgan.py +545 -0
- ldm/modules/diffusionmodules/PixArt.py +1198 -0
- ldm/modules/diffusionmodules/PixArt_blocks.py +573 -0
- ldm/modules/diffusionmodules/__init__.py +0 -0
- ldm/modules/diffusionmodules/attention.py +336 -0
- ldm/modules/diffusionmodules/distributions.py +102 -0
- ldm/modules/diffusionmodules/utils.py +582 -0
- ldm/modules/latent_diffusion/__init__.py +0 -0
- ldm/modules/latent_diffusion/ddim.py +298 -0
- ldm/modules/latent_diffusion/ddpm.py +403 -0
- ldm/modules/latent_encoder/__init__.py +0 -0
- ldm/modules/latent_encoder/__pycache__/__init__.cpython-310.pyc +0 -0
- ldm/modules/latent_encoder/__pycache__/__init__.cpython-38.pyc +0 -0
- ldm/modules/latent_encoder/__pycache__/__init__.cpython-39.pyc +0 -0
- ldm/modules/latent_encoder/__pycache__/autoencoder.cpython-310.pyc +0 -0
- ldm/modules/latent_encoder/__pycache__/autoencoder.cpython-38.pyc +0 -0
- ldm/modules/latent_encoder/__pycache__/autoencoder.cpython-39.pyc +0 -0
- ldm/modules/latent_encoder/__pycache__/autoencoder1d.cpython-310.pyc +0 -0
- ldm/modules/latent_encoder/__pycache__/autoencoder1d.cpython-38.pyc +0 -0
- ldm/modules/latent_encoder/__pycache__/model.cpython-310.pyc +0 -0
- ldm/modules/latent_encoder/__pycache__/model.cpython-38.pyc +0 -0
- ldm/modules/latent_encoder/__pycache__/model.cpython-39.pyc +0 -0
- ldm/modules/latent_encoder/autoencoder.py +78 -0
- ldm/modules/latent_encoder/model.py +1013 -0
- ldm/utils/__init__.py +0 -0
- ldm/utils/diffusion_util.py +294 -0
- ldm/utils/util.py +86 -0
- models/flan-t5-large/config.json +28 -0
- models/flan-t5-large/generation_config.json +7 -0
- models/flan-t5-large/pytorch_model.bin +3 -0
- models/flan-t5-large/special_tokens_map.json +107 -0
- models/flan-t5-large/spiece.model +3 -0
- models/flan-t5-large/tokenizer.json +0 -0
.gitattributes
CHANGED
|
@@ -1,35 +1,59 @@
|
|
| 1 |
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
-
|
|
|
|
| 4 |
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
-
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
-
|
| 12 |
-
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
-
|
| 21 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
-
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
-
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
-
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
|
| 4 |
+
|
| 5 |
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 6 |
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
|
|
|
|
| 12 |
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
| 13 |
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 14 |
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 15 |
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 16 |
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
|
|
|
|
|
|
|
| 18 |
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 19 |
*.rar filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 20 |
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 21 |
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 22 |
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 23 |
*.tgz filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 24 |
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 25 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
*.zstandard filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.db* filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.ark* filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
**/*ckpt*data* filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
**/*ckpt*.meta filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
**/*ckpt*.index filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
|
| 35 |
+
*.gguf* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
*.ggml filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
*.llamafile* filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
*.pt2 filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 41 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 43 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 44 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 45 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 46 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 47 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 48 |
+
|
| 49 |
+
models/flan-t5-large/spiece.model filter=lfs diff=lfs merge=lfs -text
|
| 50 |
+
|
| 51 |
+
models/flan-t5-large/tokenizer.json filter=lfs diff=lfs merge=lfs -text
|
| 52 |
+
|
| 53 |
+
models/flan-t5-large/pytorch_model.bin filter=lfs diff=lfs merge=lfs -text
|
| 54 |
+
|
| 55 |
+
models/vae/vae.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 56 |
+
|
| 57 |
+
models/ldm/model.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 58 |
+
|
| 59 |
+
models/vocoder/bigvgan_generator.pt filter=lfs diff=lfs merge=lfs -text
|
config/config.yaml
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
model:
|
| 2 |
+
target: ldm.modules.latent_diffusion.ddpm.LatentDiffusion
|
| 3 |
+
params:
|
| 4 |
+
first_stage_config:
|
| 5 |
+
target: ldm.modules.latent_encoder.autoencoder.AutoencoderKL
|
| 6 |
+
params:
|
| 7 |
+
reload_from_ckpt: ./models/vae/vae.ckpt
|
| 8 |
+
vocoder_path: ./models/vocoder
|
| 9 |
+
embed_dim: 16
|
| 10 |
+
ddconfig:
|
| 11 |
+
double_z: true
|
| 12 |
+
mel_bins: 128
|
| 13 |
+
z_channels: 16
|
| 14 |
+
resolution: 128
|
| 15 |
+
downsample_time: false
|
| 16 |
+
in_channels: 1
|
| 17 |
+
out_ch: 1
|
| 18 |
+
ch: 128
|
| 19 |
+
ch_mult:
|
| 20 |
+
- 1
|
| 21 |
+
- 1
|
| 22 |
+
- 2
|
| 23 |
+
- 2
|
| 24 |
+
- 4
|
| 25 |
+
num_res_blocks: 2
|
| 26 |
+
attn_resolutions:
|
| 27 |
+
- 16
|
| 28 |
+
dropout: 0.0
|
| 29 |
+
|
| 30 |
+
sampling_rate: 16000
|
| 31 |
+
linear_start: 0.0015
|
| 32 |
+
linear_end: 0.0195
|
| 33 |
+
num_timesteps_cond: 1
|
| 34 |
+
timesteps: 1000
|
| 35 |
+
parameterization: eps
|
| 36 |
+
first_stage_key: fbank
|
| 37 |
+
latent_t_size: 112
|
| 38 |
+
latent_f_size: 16
|
| 39 |
+
channels: 16
|
| 40 |
+
conditioning_key: crossattn
|
| 41 |
+
scale_by_std: true
|
| 42 |
+
model_config:
|
| 43 |
+
target: ldm.modules.diffusionmodules.PixArt.PixArt_MDT
|
| 44 |
+
params:
|
| 45 |
+
input_size:
|
| 46 |
+
- 112
|
| 47 |
+
- 16
|
| 48 |
+
patch_size:
|
| 49 |
+
- 2
|
| 50 |
+
- 2
|
| 51 |
+
in_channels: 16
|
| 52 |
+
hidden_size: 1472
|
| 53 |
+
depth: 28
|
| 54 |
+
num_heads: 16
|
| 55 |
+
mlp_ratio: 4.0
|
| 56 |
+
class_dropout_prob: 0.1
|
| 57 |
+
pred_sigma: true
|
| 58 |
+
drop_path: 0.0
|
| 59 |
+
window_size: 0
|
| 60 |
+
window_block_indexes: None
|
| 61 |
+
use_rel_pos: false
|
| 62 |
+
cond_dim: 1024
|
| 63 |
+
lewei_scale: 1.0
|
| 64 |
+
overlap:
|
| 65 |
+
- 0
|
| 66 |
+
- 0
|
| 67 |
+
use_cfg: true
|
| 68 |
+
mask_ratio: 0.3
|
| 69 |
+
decode_layer: 8
|
| 70 |
+
cond_stage_config:
|
| 71 |
+
crossattn:
|
| 72 |
+
cond_stage_key: text
|
| 73 |
+
conditioning_key: crossattn
|
| 74 |
+
target: ldm.utils.util.TextEncoder
|
| 75 |
+
params:
|
| 76 |
+
ckpt_path: ./models/flan-t5-large
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
|
ldm/__init__.py
ADDED
|
File without changes
|
ldm/modules/__init__.py
ADDED
|
File without changes
|
ldm/modules/bigvgan/__init__.py
ADDED
|
File without changes
|
ldm/modules/bigvgan/activations.py
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Implementation adapted from https://github.com/EdwardDixon/snake under the MIT license.
|
| 2 |
+
# LICENSE is in incl_licenses directory.
|
| 3 |
+
|
| 4 |
+
import torch
|
| 5 |
+
from torch import nn, sin, pow
|
| 6 |
+
from torch.nn import Parameter
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
class Snake(nn.Module):
|
| 10 |
+
"""
|
| 11 |
+
Implementation of a sine-based periodic activation function
|
| 12 |
+
Shape:
|
| 13 |
+
- Input: (B, C, T)
|
| 14 |
+
- Output: (B, C, T), same shape as the input
|
| 15 |
+
Parameters:
|
| 16 |
+
- alpha - trainable parameter
|
| 17 |
+
References:
|
| 18 |
+
- This activation function is from this paper by Liu Ziyin, Tilman Hartwig, Masahito Ueda:
|
| 19 |
+
https://arxiv.org/abs/2006.08195
|
| 20 |
+
Examples:
|
| 21 |
+
>>> a1 = snake(256)
|
| 22 |
+
>>> x = torch.randn(256)
|
| 23 |
+
>>> x = a1(x)
|
| 24 |
+
"""
|
| 25 |
+
|
| 26 |
+
def __init__(
|
| 27 |
+
self, in_features, alpha=1.0, alpha_trainable=True, alpha_logscale=False
|
| 28 |
+
):
|
| 29 |
+
"""
|
| 30 |
+
Initialization.
|
| 31 |
+
INPUT:
|
| 32 |
+
- in_features: shape of the input
|
| 33 |
+
- alpha: trainable parameter
|
| 34 |
+
alpha is initialized to 1 by default, higher values = higher-frequency.
|
| 35 |
+
alpha will be trained along with the rest of your model.
|
| 36 |
+
"""
|
| 37 |
+
super(Snake, self).__init__()
|
| 38 |
+
self.in_features = in_features
|
| 39 |
+
|
| 40 |
+
# Initialize alpha
|
| 41 |
+
self.alpha_logscale = alpha_logscale
|
| 42 |
+
if self.alpha_logscale: # Log scale alphas initialized to zeros
|
| 43 |
+
self.alpha = Parameter(torch.zeros(in_features) * alpha)
|
| 44 |
+
else: # Linear scale alphas initialized to ones
|
| 45 |
+
self.alpha = Parameter(torch.ones(in_features) * alpha)
|
| 46 |
+
|
| 47 |
+
self.alpha.requires_grad = alpha_trainable
|
| 48 |
+
|
| 49 |
+
self.no_div_by_zero = 0.000000001
|
| 50 |
+
|
| 51 |
+
def forward(self, x):
|
| 52 |
+
"""
|
| 53 |
+
Forward pass of the function.
|
| 54 |
+
Applies the function to the input elementwise.
|
| 55 |
+
Snake ∶= x + 1/a * sin^2 (xa)
|
| 56 |
+
"""
|
| 57 |
+
alpha = self.alpha.unsqueeze(0).unsqueeze(-1) # Line up with x to [B, C, T]
|
| 58 |
+
if self.alpha_logscale:
|
| 59 |
+
alpha = torch.exp(alpha)
|
| 60 |
+
x = x + (1.0 / (alpha + self.no_div_by_zero)) * pow(sin(x * alpha), 2)
|
| 61 |
+
|
| 62 |
+
return x
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
class SnakeBeta(nn.Module):
|
| 66 |
+
"""
|
| 67 |
+
A modified Snake function which uses separate parameters for the magnitude of the periodic components
|
| 68 |
+
Shape:
|
| 69 |
+
- Input: (B, C, T)
|
| 70 |
+
- Output: (B, C, T), same shape as the input
|
| 71 |
+
Parameters:
|
| 72 |
+
- alpha - trainable parameter that controls frequency
|
| 73 |
+
- beta - trainable parameter that controls magnitude
|
| 74 |
+
References:
|
| 75 |
+
- This activation function is a modified version based on this paper by Liu Ziyin, Tilman Hartwig, Masahito Ueda:
|
| 76 |
+
https://arxiv.org/abs/2006.08195
|
| 77 |
+
Examples:
|
| 78 |
+
>>> a1 = snakebeta(256)
|
| 79 |
+
>>> x = torch.randn(256)
|
| 80 |
+
>>> x = a1(x)
|
| 81 |
+
"""
|
| 82 |
+
|
| 83 |
+
def __init__(
|
| 84 |
+
self, in_features, alpha=1.0, alpha_trainable=True, alpha_logscale=False
|
| 85 |
+
):
|
| 86 |
+
"""
|
| 87 |
+
Initialization.
|
| 88 |
+
INPUT:
|
| 89 |
+
- in_features: shape of the input
|
| 90 |
+
- alpha - trainable parameter that controls frequency
|
| 91 |
+
- beta - trainable parameter that controls magnitude
|
| 92 |
+
alpha is initialized to 1 by default, higher values = higher-frequency.
|
| 93 |
+
beta is initialized to 1 by default, higher values = higher-magnitude.
|
| 94 |
+
alpha will be trained along with the rest of your model.
|
| 95 |
+
"""
|
| 96 |
+
super(SnakeBeta, self).__init__()
|
| 97 |
+
self.in_features = in_features
|
| 98 |
+
|
| 99 |
+
# Initialize alpha
|
| 100 |
+
self.alpha_logscale = alpha_logscale
|
| 101 |
+
if self.alpha_logscale: # Log scale alphas initialized to zeros
|
| 102 |
+
self.alpha = Parameter(torch.zeros(in_features) * alpha)
|
| 103 |
+
self.beta = Parameter(torch.zeros(in_features) * alpha)
|
| 104 |
+
else: # Linear scale alphas initialized to ones
|
| 105 |
+
self.alpha = Parameter(torch.ones(in_features) * alpha)
|
| 106 |
+
self.beta = Parameter(torch.ones(in_features) * alpha)
|
| 107 |
+
|
| 108 |
+
self.alpha.requires_grad = alpha_trainable
|
| 109 |
+
self.beta.requires_grad = alpha_trainable
|
| 110 |
+
|
| 111 |
+
self.no_div_by_zero = 0.000000001
|
| 112 |
+
|
| 113 |
+
def forward(self, x):
|
| 114 |
+
"""
|
| 115 |
+
Forward pass of the function.
|
| 116 |
+
Applies the function to the input elementwise.
|
| 117 |
+
SnakeBeta ∶= x + 1/b * sin^2 (xa)
|
| 118 |
+
"""
|
| 119 |
+
alpha = self.alpha.unsqueeze(0).unsqueeze(-1) # Line up with x to [B, C, T]
|
| 120 |
+
beta = self.beta.unsqueeze(0).unsqueeze(-1)
|
| 121 |
+
if self.alpha_logscale:
|
| 122 |
+
alpha = torch.exp(alpha)
|
| 123 |
+
beta = torch.exp(beta)
|
| 124 |
+
x = x + (1.0 / (beta + self.no_div_by_zero)) * pow(sin(x * alpha), 2)
|
| 125 |
+
|
| 126 |
+
return x
|
ldm/modules/bigvgan/alias_free_activation/cuda/__init__.py
ADDED
|
File without changes
|
ldm/modules/bigvgan/alias_free_activation/cuda/activation1d.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2024 NVIDIA CORPORATION.
|
| 2 |
+
# Licensed under the MIT license.
|
| 3 |
+
|
| 4 |
+
import torch
|
| 5 |
+
import torch.nn as nn
|
| 6 |
+
from alias_free_activation.torch.resample import UpSample1d, DownSample1d
|
| 7 |
+
|
| 8 |
+
# load fused CUDA kernel: this enables importing anti_alias_activation_cuda
|
| 9 |
+
from alias_free_activation.cuda import load
|
| 10 |
+
|
| 11 |
+
anti_alias_activation_cuda = load.load()
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
class FusedAntiAliasActivation(torch.autograd.Function):
|
| 15 |
+
"""
|
| 16 |
+
Assumes filter size 12, replication padding on upsampling/downsampling, and logscale alpha/beta parameters as inputs.
|
| 17 |
+
The hyperparameters are hard-coded in the kernel to maximize speed.
|
| 18 |
+
NOTE: The fused kenrel is incorrect for Activation1d with different hyperparameters.
|
| 19 |
+
"""
|
| 20 |
+
|
| 21 |
+
@staticmethod
|
| 22 |
+
def forward(ctx, inputs, up_ftr, down_ftr, alpha, beta):
|
| 23 |
+
activation_results = anti_alias_activation_cuda.forward(
|
| 24 |
+
inputs, up_ftr, down_ftr, alpha, beta
|
| 25 |
+
)
|
| 26 |
+
|
| 27 |
+
return activation_results
|
| 28 |
+
|
| 29 |
+
@staticmethod
|
| 30 |
+
def backward(ctx, output_grads):
|
| 31 |
+
raise NotImplementedError
|
| 32 |
+
return output_grads, None, None
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
class Activation1d(nn.Module):
|
| 36 |
+
def __init__(
|
| 37 |
+
self,
|
| 38 |
+
activation,
|
| 39 |
+
up_ratio: int = 2,
|
| 40 |
+
down_ratio: int = 2,
|
| 41 |
+
up_kernel_size: int = 12,
|
| 42 |
+
down_kernel_size: int = 12,
|
| 43 |
+
fused: bool = True,
|
| 44 |
+
):
|
| 45 |
+
super().__init__()
|
| 46 |
+
self.up_ratio = up_ratio
|
| 47 |
+
self.down_ratio = down_ratio
|
| 48 |
+
self.act = activation
|
| 49 |
+
self.upsample = UpSample1d(up_ratio, up_kernel_size)
|
| 50 |
+
self.downsample = DownSample1d(down_ratio, down_kernel_size)
|
| 51 |
+
|
| 52 |
+
self.fused = fused # Whether to use fused CUDA kernel or not
|
| 53 |
+
|
| 54 |
+
def forward(self, x):
|
| 55 |
+
if not self.fused:
|
| 56 |
+
x = self.upsample(x)
|
| 57 |
+
x = self.act(x)
|
| 58 |
+
x = self.downsample(x)
|
| 59 |
+
return x
|
| 60 |
+
else:
|
| 61 |
+
if self.act.__class__.__name__ == "Snake":
|
| 62 |
+
beta = self.act.alpha.data # Snake uses same params for alpha and beta
|
| 63 |
+
else:
|
| 64 |
+
beta = (
|
| 65 |
+
self.act.beta.data
|
| 66 |
+
) # Snakebeta uses different params for alpha and beta
|
| 67 |
+
alpha = self.act.alpha.data
|
| 68 |
+
if (
|
| 69 |
+
not self.act.alpha_logscale
|
| 70 |
+
): # Exp baked into cuda kernel, cancel it out with a log
|
| 71 |
+
alpha = torch.log(alpha)
|
| 72 |
+
beta = torch.log(beta)
|
| 73 |
+
|
| 74 |
+
x = FusedAntiAliasActivation.apply(
|
| 75 |
+
x, self.upsample.filter, self.downsample.lowpass.filter, alpha, beta
|
| 76 |
+
)
|
| 77 |
+
return x
|
ldm/modules/bigvgan/alias_free_activation/cuda/anti_alias_activation.cpp
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* coding=utf-8
|
| 2 |
+
* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
|
| 3 |
+
*
|
| 4 |
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
* you may not use this file except in compliance with the License.
|
| 6 |
+
* You may obtain a copy of the License at
|
| 7 |
+
*
|
| 8 |
+
* http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
*
|
| 10 |
+
* Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
* See the License for the specific language governing permissions and
|
| 14 |
+
* limitations under the License.
|
| 15 |
+
*/
|
| 16 |
+
|
| 17 |
+
#include <torch/extension.h>
|
| 18 |
+
|
| 19 |
+
extern "C" torch::Tensor fwd_cuda(torch::Tensor const &input, torch::Tensor const &up_filter, torch::Tensor const &down_filter, torch::Tensor const &alpha, torch::Tensor const &beta);
|
| 20 |
+
|
| 21 |
+
PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
|
| 22 |
+
m.def("forward", &fwd_cuda, "Anti-Alias Activation forward (CUDA)");
|
| 23 |
+
}
|
ldm/modules/bigvgan/alias_free_activation/cuda/anti_alias_activation_cuda.cu
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* coding=utf-8
|
| 2 |
+
* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
|
| 3 |
+
*
|
| 4 |
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
* you may not use this file except in compliance with the License.
|
| 6 |
+
* You may obtain a copy of the License at
|
| 7 |
+
*
|
| 8 |
+
* http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
*
|
| 10 |
+
* Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
* See the License for the specific language governing permissions and
|
| 14 |
+
* limitations under the License.
|
| 15 |
+
*/
|
| 16 |
+
|
| 17 |
+
#include <ATen/ATen.h>
|
| 18 |
+
#include <cuda.h>
|
| 19 |
+
#include <cuda_runtime.h>
|
| 20 |
+
#include <cuda_fp16.h>
|
| 21 |
+
#include <cuda_profiler_api.h>
|
| 22 |
+
#include <ATen/cuda/CUDAContext.h>
|
| 23 |
+
#include <torch/extension.h>
|
| 24 |
+
#include "type_shim.h"
|
| 25 |
+
#include <assert.h>
|
| 26 |
+
#include <cfloat>
|
| 27 |
+
#include <limits>
|
| 28 |
+
#include <stdint.h>
|
| 29 |
+
#include <c10/macros/Macros.h>
|
| 30 |
+
|
| 31 |
+
namespace
|
| 32 |
+
{
|
| 33 |
+
// Hard-coded hyperparameters
|
| 34 |
+
// WARP_SIZE and WARP_BATCH must match the return values batches_per_warp and
|
| 35 |
+
constexpr int ELEMENTS_PER_LDG_STG = 1; //(WARP_ITERATIONS < 4) ? 1 : 4;
|
| 36 |
+
constexpr int BUFFER_SIZE = 32;
|
| 37 |
+
constexpr int FILTER_SIZE = 12;
|
| 38 |
+
constexpr int HALF_FILTER_SIZE = 6;
|
| 39 |
+
constexpr int UPSAMPLE_REPLICATION_PAD = 5; // 5 on each side, matching torch impl
|
| 40 |
+
constexpr int DOWNSAMPLE_REPLICATION_PAD_LEFT = 5; // matching torch impl
|
| 41 |
+
constexpr int DOWNSAMPLE_REPLICATION_PAD_RIGHT = 6; // matching torch impl
|
| 42 |
+
|
| 43 |
+
template <typename input_t, typename output_t, typename acc_t>
|
| 44 |
+
__global__ void anti_alias_activation_forward(
|
| 45 |
+
output_t *dst,
|
| 46 |
+
const input_t *src,
|
| 47 |
+
const input_t *up_ftr,
|
| 48 |
+
const input_t *down_ftr,
|
| 49 |
+
const input_t *alpha,
|
| 50 |
+
const input_t *beta,
|
| 51 |
+
int batch_size,
|
| 52 |
+
int channels,
|
| 53 |
+
int seq_len)
|
| 54 |
+
{
|
| 55 |
+
// Up and downsample filters
|
| 56 |
+
input_t up_filter[FILTER_SIZE];
|
| 57 |
+
input_t down_filter[FILTER_SIZE];
|
| 58 |
+
|
| 59 |
+
// Load data from global memory including extra indices reserved for replication paddings
|
| 60 |
+
input_t elements[2 * FILTER_SIZE + 2 * BUFFER_SIZE + 2 * UPSAMPLE_REPLICATION_PAD] = {0};
|
| 61 |
+
input_t intermediates[2 * FILTER_SIZE + 2 * BUFFER_SIZE + DOWNSAMPLE_REPLICATION_PAD_LEFT + DOWNSAMPLE_REPLICATION_PAD_RIGHT] = {0};
|
| 62 |
+
|
| 63 |
+
// Output stores downsampled output before writing to dst
|
| 64 |
+
output_t output[BUFFER_SIZE];
|
| 65 |
+
|
| 66 |
+
// blockDim/threadIdx = (128, 1, 1)
|
| 67 |
+
// gridDim/blockIdx = (seq_blocks, channels, batches)
|
| 68 |
+
int block_offset = (blockIdx.x * 128 * BUFFER_SIZE + seq_len * (blockIdx.y + gridDim.y * blockIdx.z));
|
| 69 |
+
int local_offset = threadIdx.x * BUFFER_SIZE;
|
| 70 |
+
int seq_offset = blockIdx.x * 128 * BUFFER_SIZE + local_offset;
|
| 71 |
+
|
| 72 |
+
// intermediate have double the seq_len
|
| 73 |
+
int intermediate_local_offset = threadIdx.x * BUFFER_SIZE * 2;
|
| 74 |
+
int intermediate_seq_offset = blockIdx.x * 128 * BUFFER_SIZE * 2 + intermediate_local_offset;
|
| 75 |
+
|
| 76 |
+
// Get values needed for replication padding before moving pointer
|
| 77 |
+
const input_t *right_most_pntr = src + (seq_len * (blockIdx.y + gridDim.y * blockIdx.z));
|
| 78 |
+
input_t seq_left_most_value = right_most_pntr[0];
|
| 79 |
+
input_t seq_right_most_value = right_most_pntr[seq_len - 1];
|
| 80 |
+
|
| 81 |
+
// Move src and dst pointers
|
| 82 |
+
src += block_offset + local_offset;
|
| 83 |
+
dst += block_offset + local_offset;
|
| 84 |
+
|
| 85 |
+
// Alpha and beta values for snake activatons. Applies exp by default
|
| 86 |
+
alpha = alpha + blockIdx.y;
|
| 87 |
+
input_t alpha_val = expf(alpha[0]);
|
| 88 |
+
beta = beta + blockIdx.y;
|
| 89 |
+
input_t beta_val = expf(beta[0]);
|
| 90 |
+
|
| 91 |
+
#pragma unroll
|
| 92 |
+
for (int it = 0; it < FILTER_SIZE; it += 1)
|
| 93 |
+
{
|
| 94 |
+
up_filter[it] = up_ftr[it];
|
| 95 |
+
down_filter[it] = down_ftr[it];
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
// Apply replication padding for upsampling, matching torch impl
|
| 99 |
+
#pragma unroll
|
| 100 |
+
for (int it = -HALF_FILTER_SIZE; it < BUFFER_SIZE + HALF_FILTER_SIZE; it += 1)
|
| 101 |
+
{
|
| 102 |
+
int element_index = seq_offset + it; // index for element
|
| 103 |
+
if ((element_index < 0) && (element_index >= -UPSAMPLE_REPLICATION_PAD))
|
| 104 |
+
{
|
| 105 |
+
elements[2 * (HALF_FILTER_SIZE + it)] = 2 * seq_left_most_value;
|
| 106 |
+
}
|
| 107 |
+
if ((element_index >= seq_len) && (element_index < seq_len + UPSAMPLE_REPLICATION_PAD))
|
| 108 |
+
{
|
| 109 |
+
elements[2 * (HALF_FILTER_SIZE + it)] = 2 * seq_right_most_value;
|
| 110 |
+
}
|
| 111 |
+
if ((element_index >= 0) && (element_index < seq_len))
|
| 112 |
+
{
|
| 113 |
+
elements[2 * (HALF_FILTER_SIZE + it)] = 2 * src[it];
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
// Apply upsampling strided convolution and write to intermediates. It reserves DOWNSAMPLE_REPLICATION_PAD_LEFT for replication padding of the downsampilng conv later
|
| 118 |
+
#pragma unroll
|
| 119 |
+
for (int it = 0; it < (2 * BUFFER_SIZE + 2 * FILTER_SIZE); it += 1)
|
| 120 |
+
{
|
| 121 |
+
input_t acc = 0.0;
|
| 122 |
+
int element_index = intermediate_seq_offset + it; // index for intermediate
|
| 123 |
+
#pragma unroll
|
| 124 |
+
for (int f_idx = 0; f_idx < FILTER_SIZE; f_idx += 1)
|
| 125 |
+
{
|
| 126 |
+
if ((element_index + f_idx) >= 0)
|
| 127 |
+
{
|
| 128 |
+
acc += up_filter[f_idx] * elements[it + f_idx];
|
| 129 |
+
}
|
| 130 |
+
}
|
| 131 |
+
intermediates[it + DOWNSAMPLE_REPLICATION_PAD_LEFT] = acc;
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
// Apply activation function. It reserves DOWNSAMPLE_REPLICATION_PAD_LEFT and DOWNSAMPLE_REPLICATION_PAD_RIGHT for replication padding of the downsampilng conv later
|
| 135 |
+
double no_div_by_zero = 0.000000001;
|
| 136 |
+
#pragma unroll
|
| 137 |
+
for (int it = 0; it < 2 * BUFFER_SIZE + 2 * FILTER_SIZE; it += 1)
|
| 138 |
+
{
|
| 139 |
+
intermediates[it + DOWNSAMPLE_REPLICATION_PAD_LEFT] += (1.0 / (beta_val + no_div_by_zero)) * sinf(intermediates[it + DOWNSAMPLE_REPLICATION_PAD_LEFT] * alpha_val) * sinf(intermediates[it + DOWNSAMPLE_REPLICATION_PAD_LEFT] * alpha_val);
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
// Apply replication padding before downsampling conv from intermediates
|
| 143 |
+
#pragma unroll
|
| 144 |
+
for (int it = 0; it < DOWNSAMPLE_REPLICATION_PAD_LEFT; it += 1)
|
| 145 |
+
{
|
| 146 |
+
intermediates[it] = intermediates[DOWNSAMPLE_REPLICATION_PAD_LEFT];
|
| 147 |
+
}
|
| 148 |
+
#pragma unroll
|
| 149 |
+
for (int it = DOWNSAMPLE_REPLICATION_PAD_LEFT + 2 * BUFFER_SIZE + 2 * FILTER_SIZE; it < DOWNSAMPLE_REPLICATION_PAD_LEFT + 2 * BUFFER_SIZE + 2 * FILTER_SIZE + DOWNSAMPLE_REPLICATION_PAD_RIGHT; it += 1)
|
| 150 |
+
{
|
| 151 |
+
intermediates[it] = intermediates[DOWNSAMPLE_REPLICATION_PAD_LEFT + 2 * BUFFER_SIZE + 2 * FILTER_SIZE - 1];
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
// Apply downsample strided convolution (assuming stride=2) from intermediates
|
| 155 |
+
#pragma unroll
|
| 156 |
+
for (int it = 0; it < BUFFER_SIZE; it += 1)
|
| 157 |
+
{
|
| 158 |
+
input_t acc = 0.0;
|
| 159 |
+
#pragma unroll
|
| 160 |
+
for (int f_idx = 0; f_idx < FILTER_SIZE; f_idx += 1)
|
| 161 |
+
{
|
| 162 |
+
// Add constant DOWNSAMPLE_REPLICATION_PAD_RIGHT to match torch implementation
|
| 163 |
+
acc += down_filter[f_idx] * intermediates[it * 2 + f_idx + DOWNSAMPLE_REPLICATION_PAD_RIGHT];
|
| 164 |
+
}
|
| 165 |
+
output[it] = acc;
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
// Write output to dst
|
| 169 |
+
#pragma unroll
|
| 170 |
+
for (int it = 0; it < BUFFER_SIZE; it += ELEMENTS_PER_LDG_STG)
|
| 171 |
+
{
|
| 172 |
+
int element_index = seq_offset + it;
|
| 173 |
+
if (element_index < seq_len)
|
| 174 |
+
{
|
| 175 |
+
dst[it] = output[it];
|
| 176 |
+
}
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
template <typename input_t, typename output_t, typename acc_t>
|
| 182 |
+
void dispatch_anti_alias_activation_forward(
|
| 183 |
+
output_t *dst,
|
| 184 |
+
const input_t *src,
|
| 185 |
+
const input_t *up_ftr,
|
| 186 |
+
const input_t *down_ftr,
|
| 187 |
+
const input_t *alpha,
|
| 188 |
+
const input_t *beta,
|
| 189 |
+
int batch_size,
|
| 190 |
+
int channels,
|
| 191 |
+
int seq_len)
|
| 192 |
+
{
|
| 193 |
+
if (seq_len == 0)
|
| 194 |
+
{
|
| 195 |
+
return;
|
| 196 |
+
}
|
| 197 |
+
else
|
| 198 |
+
{
|
| 199 |
+
// Use 128 threads per block to maximimize gpu utilization
|
| 200 |
+
constexpr int threads_per_block = 128;
|
| 201 |
+
constexpr int seq_len_per_block = 4096;
|
| 202 |
+
int blocks_per_seq_len = (seq_len + seq_len_per_block - 1) / seq_len_per_block;
|
| 203 |
+
dim3 blocks(blocks_per_seq_len, channels, batch_size);
|
| 204 |
+
dim3 threads(threads_per_block, 1, 1);
|
| 205 |
+
|
| 206 |
+
anti_alias_activation_forward<input_t, output_t, acc_t>
|
| 207 |
+
<<<blocks, threads, 0, at::cuda::getCurrentCUDAStream()>>>(dst, src, up_ftr, down_ftr, alpha, beta, batch_size, channels, seq_len);
|
| 208 |
+
}
|
| 209 |
+
}
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
extern "C" torch::Tensor fwd_cuda(torch::Tensor const &input, torch::Tensor const &up_filter, torch::Tensor const &down_filter, torch::Tensor const &alpha, torch::Tensor const &beta)
|
| 213 |
+
{
|
| 214 |
+
// Input is a 3d tensor with dimensions [batches, channels, seq_len]
|
| 215 |
+
const int batches = input.size(0);
|
| 216 |
+
const int channels = input.size(1);
|
| 217 |
+
const int seq_len = input.size(2);
|
| 218 |
+
|
| 219 |
+
// Output
|
| 220 |
+
auto act_options = input.options().requires_grad(false);
|
| 221 |
+
|
| 222 |
+
torch::Tensor anti_alias_activation_results =
|
| 223 |
+
torch::empty({batches, channels, seq_len}, act_options);
|
| 224 |
+
|
| 225 |
+
void *input_ptr = static_cast<void *>(input.data_ptr());
|
| 226 |
+
void *up_filter_ptr = static_cast<void *>(up_filter.data_ptr());
|
| 227 |
+
void *down_filter_ptr = static_cast<void *>(down_filter.data_ptr());
|
| 228 |
+
void *alpha_ptr = static_cast<void *>(alpha.data_ptr());
|
| 229 |
+
void *beta_ptr = static_cast<void *>(beta.data_ptr());
|
| 230 |
+
void *anti_alias_activation_results_ptr = static_cast<void *>(anti_alias_activation_results.data_ptr());
|
| 231 |
+
|
| 232 |
+
DISPATCH_FLOAT_HALF_AND_BFLOAT(
|
| 233 |
+
input.scalar_type(),
|
| 234 |
+
"dispatch anti alias activation_forward",
|
| 235 |
+
dispatch_anti_alias_activation_forward<scalar_t, scalar_t, float>(
|
| 236 |
+
reinterpret_cast<scalar_t *>(anti_alias_activation_results_ptr),
|
| 237 |
+
reinterpret_cast<const scalar_t *>(input_ptr),
|
| 238 |
+
reinterpret_cast<const scalar_t *>(up_filter_ptr),
|
| 239 |
+
reinterpret_cast<const scalar_t *>(down_filter_ptr),
|
| 240 |
+
reinterpret_cast<const scalar_t *>(alpha_ptr),
|
| 241 |
+
reinterpret_cast<const scalar_t *>(beta_ptr),
|
| 242 |
+
batches,
|
| 243 |
+
channels,
|
| 244 |
+
seq_len););
|
| 245 |
+
return anti_alias_activation_results;
|
| 246 |
+
}
|
ldm/modules/bigvgan/alias_free_activation/cuda/compat.h
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* coding=utf-8
|
| 2 |
+
* Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
|
| 3 |
+
*
|
| 4 |
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
* you may not use this file except in compliance with the License.
|
| 6 |
+
* You may obtain a copy of the License at
|
| 7 |
+
*
|
| 8 |
+
* http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
*
|
| 10 |
+
* Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
* See the License for the specific language governing permissions and
|
| 14 |
+
* limitations under the License.
|
| 15 |
+
*/
|
| 16 |
+
|
| 17 |
+
/*This code is copied fron NVIDIA apex:
|
| 18 |
+
* https://github.com/NVIDIA/apex
|
| 19 |
+
* with minor changes. */
|
| 20 |
+
|
| 21 |
+
#ifndef TORCH_CHECK
|
| 22 |
+
#define TORCH_CHECK AT_CHECK
|
| 23 |
+
#endif
|
| 24 |
+
|
| 25 |
+
#ifdef VERSION_GE_1_3
|
| 26 |
+
#define DATA_PTR data_ptr
|
| 27 |
+
#else
|
| 28 |
+
#define DATA_PTR data
|
| 29 |
+
#endif
|
ldm/modules/bigvgan/alias_free_activation/cuda/load.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2024 NVIDIA CORPORATION.
|
| 2 |
+
# Licensed under the MIT license.
|
| 3 |
+
|
| 4 |
+
import os
|
| 5 |
+
import pathlib
|
| 6 |
+
import subprocess
|
| 7 |
+
|
| 8 |
+
from torch.utils import cpp_extension
|
| 9 |
+
|
| 10 |
+
"""
|
| 11 |
+
Setting this param to a list has a problem of generating different compilation commands (with diferent order of architectures) and leading to recompilation of fused kernels.
|
| 12 |
+
Set it to empty stringo avoid recompilation and assign arch flags explicity in extra_cuda_cflags below
|
| 13 |
+
"""
|
| 14 |
+
os.environ["TORCH_CUDA_ARCH_LIST"] = ""
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def load():
|
| 18 |
+
# Check if cuda 11 is installed for compute capability 8.0
|
| 19 |
+
cc_flag = []
|
| 20 |
+
_, bare_metal_major, _ = _get_cuda_bare_metal_version(cpp_extension.CUDA_HOME)
|
| 21 |
+
if int(bare_metal_major) >= 11:
|
| 22 |
+
cc_flag.append("-gencode")
|
| 23 |
+
cc_flag.append("arch=compute_80,code=sm_80")
|
| 24 |
+
|
| 25 |
+
# Build path
|
| 26 |
+
srcpath = pathlib.Path(__file__).parent.absolute()
|
| 27 |
+
buildpath = srcpath / "build"
|
| 28 |
+
_create_build_dir(buildpath)
|
| 29 |
+
|
| 30 |
+
# Helper function to build the kernels.
|
| 31 |
+
def _cpp_extention_load_helper(name, sources, extra_cuda_flags):
|
| 32 |
+
return cpp_extension.load(
|
| 33 |
+
name=name,
|
| 34 |
+
sources=sources,
|
| 35 |
+
build_directory=buildpath,
|
| 36 |
+
extra_cflags=[
|
| 37 |
+
"-O3",
|
| 38 |
+
],
|
| 39 |
+
extra_cuda_cflags=[
|
| 40 |
+
"-O3",
|
| 41 |
+
"-gencode",
|
| 42 |
+
"arch=compute_70,code=sm_70",
|
| 43 |
+
"--use_fast_math",
|
| 44 |
+
]
|
| 45 |
+
+ extra_cuda_flags
|
| 46 |
+
+ cc_flag,
|
| 47 |
+
verbose=True,
|
| 48 |
+
)
|
| 49 |
+
|
| 50 |
+
extra_cuda_flags = [
|
| 51 |
+
"-U__CUDA_NO_HALF_OPERATORS__",
|
| 52 |
+
"-U__CUDA_NO_HALF_CONVERSIONS__",
|
| 53 |
+
"--expt-relaxed-constexpr",
|
| 54 |
+
"--expt-extended-lambda",
|
| 55 |
+
]
|
| 56 |
+
|
| 57 |
+
sources = [
|
| 58 |
+
srcpath / "anti_alias_activation.cpp",
|
| 59 |
+
srcpath / "anti_alias_activation_cuda.cu",
|
| 60 |
+
]
|
| 61 |
+
anti_alias_activation_cuda = _cpp_extention_load_helper(
|
| 62 |
+
"anti_alias_activation_cuda", sources, extra_cuda_flags
|
| 63 |
+
)
|
| 64 |
+
|
| 65 |
+
return anti_alias_activation_cuda
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def _get_cuda_bare_metal_version(cuda_dir):
|
| 69 |
+
raw_output = subprocess.check_output(
|
| 70 |
+
[cuda_dir + "/bin/nvcc", "-V"], universal_newlines=True
|
| 71 |
+
)
|
| 72 |
+
output = raw_output.split()
|
| 73 |
+
release_idx = output.index("release") + 1
|
| 74 |
+
release = output[release_idx].split(".")
|
| 75 |
+
bare_metal_major = release[0]
|
| 76 |
+
bare_metal_minor = release[1][0]
|
| 77 |
+
|
| 78 |
+
return raw_output, bare_metal_major, bare_metal_minor
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def _create_build_dir(buildpath):
|
| 82 |
+
try:
|
| 83 |
+
os.mkdir(buildpath)
|
| 84 |
+
except OSError:
|
| 85 |
+
if not os.path.isdir(buildpath):
|
| 86 |
+
print(f"Creation of the build directory {buildpath} failed")
|
ldm/modules/bigvgan/alias_free_activation/cuda/type_shim.h
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* coding=utf-8
|
| 2 |
+
* Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
|
| 3 |
+
*
|
| 4 |
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
* you may not use this file except in compliance with the License.
|
| 6 |
+
* You may obtain a copy of the License at
|
| 7 |
+
*
|
| 8 |
+
* http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
*
|
| 10 |
+
* Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
* See the License for the specific language governing permissions and
|
| 14 |
+
* limitations under the License.
|
| 15 |
+
*/
|
| 16 |
+
|
| 17 |
+
#include <ATen/ATen.h>
|
| 18 |
+
#include "compat.h"
|
| 19 |
+
|
| 20 |
+
#define DISPATCH_FLOAT_HALF_AND_BFLOAT(TYPE, NAME, ...) \
|
| 21 |
+
switch (TYPE) \
|
| 22 |
+
{ \
|
| 23 |
+
case at::ScalarType::Float: \
|
| 24 |
+
{ \
|
| 25 |
+
using scalar_t = float; \
|
| 26 |
+
__VA_ARGS__; \
|
| 27 |
+
break; \
|
| 28 |
+
} \
|
| 29 |
+
case at::ScalarType::Half: \
|
| 30 |
+
{ \
|
| 31 |
+
using scalar_t = at::Half; \
|
| 32 |
+
__VA_ARGS__; \
|
| 33 |
+
break; \
|
| 34 |
+
} \
|
| 35 |
+
case at::ScalarType::BFloat16: \
|
| 36 |
+
{ \
|
| 37 |
+
using scalar_t = at::BFloat16; \
|
| 38 |
+
__VA_ARGS__; \
|
| 39 |
+
break; \
|
| 40 |
+
} \
|
| 41 |
+
default: \
|
| 42 |
+
AT_ERROR(#NAME, " not implemented for '", toString(TYPE), "'"); \
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
#define DISPATCH_FLOAT_HALF_AND_BFLOAT_INOUT_TYPES(TYPEIN, TYPEOUT, NAME, ...) \
|
| 46 |
+
switch (TYPEIN) \
|
| 47 |
+
{ \
|
| 48 |
+
case at::ScalarType::Float: \
|
| 49 |
+
{ \
|
| 50 |
+
using scalar_t_in = float; \
|
| 51 |
+
switch (TYPEOUT) \
|
| 52 |
+
{ \
|
| 53 |
+
case at::ScalarType::Float: \
|
| 54 |
+
{ \
|
| 55 |
+
using scalar_t_out = float; \
|
| 56 |
+
__VA_ARGS__; \
|
| 57 |
+
break; \
|
| 58 |
+
} \
|
| 59 |
+
case at::ScalarType::Half: \
|
| 60 |
+
{ \
|
| 61 |
+
using scalar_t_out = at::Half; \
|
| 62 |
+
__VA_ARGS__; \
|
| 63 |
+
break; \
|
| 64 |
+
} \
|
| 65 |
+
case at::ScalarType::BFloat16: \
|
| 66 |
+
{ \
|
| 67 |
+
using scalar_t_out = at::BFloat16; \
|
| 68 |
+
__VA_ARGS__; \
|
| 69 |
+
break; \
|
| 70 |
+
} \
|
| 71 |
+
default: \
|
| 72 |
+
AT_ERROR(#NAME, " not implemented for '", toString(TYPEOUT), "'"); \
|
| 73 |
+
} \
|
| 74 |
+
break; \
|
| 75 |
+
} \
|
| 76 |
+
case at::ScalarType::Half: \
|
| 77 |
+
{ \
|
| 78 |
+
using scalar_t_in = at::Half; \
|
| 79 |
+
using scalar_t_out = at::Half; \
|
| 80 |
+
__VA_ARGS__; \
|
| 81 |
+
break; \
|
| 82 |
+
} \
|
| 83 |
+
case at::ScalarType::BFloat16: \
|
| 84 |
+
{ \
|
| 85 |
+
using scalar_t_in = at::BFloat16; \
|
| 86 |
+
using scalar_t_out = at::BFloat16; \
|
| 87 |
+
__VA_ARGS__; \
|
| 88 |
+
break; \
|
| 89 |
+
} \
|
| 90 |
+
default: \
|
| 91 |
+
AT_ERROR(#NAME, " not implemented for '", toString(TYPEIN), "'"); \
|
| 92 |
+
}
|
ldm/modules/bigvgan/alias_free_activation/torch/__init__.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Adapted from https://github.com/junjun3518/alias-free-torch under the Apache License 2.0
|
| 2 |
+
# LICENSE is in incl_licenses directory.
|
| 3 |
+
|
| 4 |
+
from .filter import *
|
| 5 |
+
from .resample import *
|
| 6 |
+
from .act import *
|
ldm/modules/bigvgan/alias_free_activation/torch/act.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Adapted from https://github.com/junjun3518/alias-free-torch under the Apache License 2.0
|
| 2 |
+
# LICENSE is in incl_licenses directory.
|
| 3 |
+
|
| 4 |
+
import torch.nn as nn
|
| 5 |
+
from alias_free_activation.torch.resample import UpSample1d, DownSample1d
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
class Activation1d(nn.Module):
|
| 9 |
+
def __init__(
|
| 10 |
+
self,
|
| 11 |
+
activation,
|
| 12 |
+
up_ratio: int = 2,
|
| 13 |
+
down_ratio: int = 2,
|
| 14 |
+
up_kernel_size: int = 12,
|
| 15 |
+
down_kernel_size: int = 12,
|
| 16 |
+
):
|
| 17 |
+
super().__init__()
|
| 18 |
+
self.up_ratio = up_ratio
|
| 19 |
+
self.down_ratio = down_ratio
|
| 20 |
+
self.act = activation
|
| 21 |
+
self.upsample = UpSample1d(up_ratio, up_kernel_size)
|
| 22 |
+
self.downsample = DownSample1d(down_ratio, down_kernel_size)
|
| 23 |
+
|
| 24 |
+
# x: [B,C,T]
|
| 25 |
+
def forward(self, x):
|
| 26 |
+
x = self.upsample(x)
|
| 27 |
+
x = self.act(x)
|
| 28 |
+
x = self.downsample(x)
|
| 29 |
+
|
| 30 |
+
return x
|
ldm/modules/bigvgan/alias_free_activation/torch/filter.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Adapted from https://github.com/junjun3518/alias-free-torch under the Apache License 2.0
|
| 2 |
+
# LICENSE is in incl_licenses directory.
|
| 3 |
+
|
| 4 |
+
import torch
|
| 5 |
+
import torch.nn as nn
|
| 6 |
+
import torch.nn.functional as F
|
| 7 |
+
import math
|
| 8 |
+
|
| 9 |
+
if "sinc" in dir(torch):
|
| 10 |
+
sinc = torch.sinc
|
| 11 |
+
else:
|
| 12 |
+
# This code is adopted from adefossez's julius.core.sinc under the MIT License
|
| 13 |
+
# https://adefossez.github.io/julius/julius/core.html
|
| 14 |
+
# LICENSE is in incl_licenses directory.
|
| 15 |
+
def sinc(x: torch.Tensor):
|
| 16 |
+
"""
|
| 17 |
+
Implementation of sinc, i.e. sin(pi * x) / (pi * x)
|
| 18 |
+
__Warning__: Different to julius.sinc, the input is multiplied by `pi`!
|
| 19 |
+
"""
|
| 20 |
+
return torch.where(
|
| 21 |
+
x == 0,
|
| 22 |
+
torch.tensor(1.0, device=x.device, dtype=x.dtype),
|
| 23 |
+
torch.sin(math.pi * x) / math.pi / x,
|
| 24 |
+
)
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
# This code is adopted from adefossez's julius.lowpass.LowPassFilters under the MIT License
|
| 28 |
+
# https://adefossez.github.io/julius/julius/lowpass.html
|
| 29 |
+
# LICENSE is in incl_licenses directory.
|
| 30 |
+
def kaiser_sinc_filter1d(
|
| 31 |
+
cutoff, half_width, kernel_size
|
| 32 |
+
): # return filter [1,1,kernel_size]
|
| 33 |
+
even = kernel_size % 2 == 0
|
| 34 |
+
half_size = kernel_size // 2
|
| 35 |
+
|
| 36 |
+
# For kaiser window
|
| 37 |
+
delta_f = 4 * half_width
|
| 38 |
+
A = 2.285 * (half_size - 1) * math.pi * delta_f + 7.95
|
| 39 |
+
if A > 50.0:
|
| 40 |
+
beta = 0.1102 * (A - 8.7)
|
| 41 |
+
elif A >= 21.0:
|
| 42 |
+
beta = 0.5842 * (A - 21) ** 0.4 + 0.07886 * (A - 21.0)
|
| 43 |
+
else:
|
| 44 |
+
beta = 0.0
|
| 45 |
+
window = torch.kaiser_window(kernel_size, beta=beta, periodic=False)
|
| 46 |
+
|
| 47 |
+
# ratio = 0.5/cutoff -> 2 * cutoff = 1 / ratio
|
| 48 |
+
if even:
|
| 49 |
+
time = torch.arange(-half_size, half_size) + 0.5
|
| 50 |
+
else:
|
| 51 |
+
time = torch.arange(kernel_size) - half_size
|
| 52 |
+
if cutoff == 0:
|
| 53 |
+
filter_ = torch.zeros_like(time)
|
| 54 |
+
else:
|
| 55 |
+
filter_ = 2 * cutoff * window * sinc(2 * cutoff * time)
|
| 56 |
+
"""
|
| 57 |
+
Normalize filter to have sum = 1, otherwise we will have a small leakage of the constant component in the input signal.
|
| 58 |
+
"""
|
| 59 |
+
filter_ /= filter_.sum()
|
| 60 |
+
filter = filter_.view(1, 1, kernel_size)
|
| 61 |
+
|
| 62 |
+
return filter
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
class LowPassFilter1d(nn.Module):
|
| 66 |
+
def __init__(
|
| 67 |
+
self,
|
| 68 |
+
cutoff=0.5,
|
| 69 |
+
half_width=0.6,
|
| 70 |
+
stride: int = 1,
|
| 71 |
+
padding: bool = True,
|
| 72 |
+
padding_mode: str = "replicate",
|
| 73 |
+
kernel_size: int = 12,
|
| 74 |
+
):
|
| 75 |
+
"""
|
| 76 |
+
kernel_size should be even number for stylegan3 setup, in this implementation, odd number is also possible.
|
| 77 |
+
"""
|
| 78 |
+
super().__init__()
|
| 79 |
+
if cutoff < -0.0:
|
| 80 |
+
raise ValueError("Minimum cutoff must be larger than zero.")
|
| 81 |
+
if cutoff > 0.5:
|
| 82 |
+
raise ValueError("A cutoff above 0.5 does not make sense.")
|
| 83 |
+
self.kernel_size = kernel_size
|
| 84 |
+
self.even = kernel_size % 2 == 0
|
| 85 |
+
self.pad_left = kernel_size // 2 - int(self.even)
|
| 86 |
+
self.pad_right = kernel_size // 2
|
| 87 |
+
self.stride = stride
|
| 88 |
+
self.padding = padding
|
| 89 |
+
self.padding_mode = padding_mode
|
| 90 |
+
filter = kaiser_sinc_filter1d(cutoff, half_width, kernel_size)
|
| 91 |
+
self.register_buffer("filter", filter)
|
| 92 |
+
|
| 93 |
+
# Input [B, C, T]
|
| 94 |
+
def forward(self, x):
|
| 95 |
+
_, C, _ = x.shape
|
| 96 |
+
|
| 97 |
+
if self.padding:
|
| 98 |
+
x = F.pad(x, (self.pad_left, self.pad_right), mode=self.padding_mode)
|
| 99 |
+
out = F.conv1d(x, self.filter.expand(C, -1, -1), stride=self.stride, groups=C)
|
| 100 |
+
|
| 101 |
+
return out
|
ldm/modules/bigvgan/alias_free_activation/torch/resample.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Adapted from https://github.com/junjun3518/alias-free-torch under the Apache License 2.0
|
| 2 |
+
# LICENSE is in incl_licenses directory.
|
| 3 |
+
|
| 4 |
+
import torch.nn as nn
|
| 5 |
+
from torch.nn import functional as F
|
| 6 |
+
from alias_free_activation.torch.filter import LowPassFilter1d
|
| 7 |
+
from alias_free_activation.torch.filter import kaiser_sinc_filter1d
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
class UpSample1d(nn.Module):
|
| 11 |
+
def __init__(self, ratio=2, kernel_size=None):
|
| 12 |
+
super().__init__()
|
| 13 |
+
self.ratio = ratio
|
| 14 |
+
self.kernel_size = (
|
| 15 |
+
int(6 * ratio // 2) * 2 if kernel_size is None else kernel_size
|
| 16 |
+
)
|
| 17 |
+
self.stride = ratio
|
| 18 |
+
self.pad = self.kernel_size // ratio - 1
|
| 19 |
+
self.pad_left = self.pad * self.stride + (self.kernel_size - self.stride) // 2
|
| 20 |
+
self.pad_right = (
|
| 21 |
+
self.pad * self.stride + (self.kernel_size - self.stride + 1) // 2
|
| 22 |
+
)
|
| 23 |
+
filter = kaiser_sinc_filter1d(
|
| 24 |
+
cutoff=0.5 / ratio, half_width=0.6 / ratio, kernel_size=self.kernel_size
|
| 25 |
+
)
|
| 26 |
+
self.register_buffer("filter", filter)
|
| 27 |
+
|
| 28 |
+
# x: [B, C, T]
|
| 29 |
+
def forward(self, x):
|
| 30 |
+
_, C, _ = x.shape
|
| 31 |
+
|
| 32 |
+
x = F.pad(x, (self.pad, self.pad), mode="replicate")
|
| 33 |
+
x = self.ratio * F.conv_transpose1d(
|
| 34 |
+
x, self.filter.expand(C, -1, -1), stride=self.stride, groups=C
|
| 35 |
+
)
|
| 36 |
+
x = x[..., self.pad_left : -self.pad_right]
|
| 37 |
+
|
| 38 |
+
return x
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
class DownSample1d(nn.Module):
|
| 42 |
+
def __init__(self, ratio=2, kernel_size=None):
|
| 43 |
+
super().__init__()
|
| 44 |
+
self.ratio = ratio
|
| 45 |
+
self.kernel_size = (
|
| 46 |
+
int(6 * ratio // 2) * 2 if kernel_size is None else kernel_size
|
| 47 |
+
)
|
| 48 |
+
self.lowpass = LowPassFilter1d(
|
| 49 |
+
cutoff=0.5 / ratio,
|
| 50 |
+
half_width=0.6 / ratio,
|
| 51 |
+
stride=ratio,
|
| 52 |
+
kernel_size=self.kernel_size,
|
| 53 |
+
)
|
| 54 |
+
|
| 55 |
+
def forward(self, x):
|
| 56 |
+
xx = self.lowpass(x)
|
| 57 |
+
|
| 58 |
+
return xx
|
ldm/modules/bigvgan/bigvgan.py
ADDED
|
@@ -0,0 +1,545 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2024 NVIDIA CORPORATION.
|
| 2 |
+
# Licensed under the MIT license.
|
| 3 |
+
|
| 4 |
+
# Adapted from https://github.com/jik876/hifi-gan under the MIT license.
|
| 5 |
+
# LICENSE is in incl_licenses directory.
|
| 6 |
+
|
| 7 |
+
import os
|
| 8 |
+
import json
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
from typing import Optional, Union, Dict
|
| 11 |
+
|
| 12 |
+
import torch
|
| 13 |
+
import torch.nn as nn
|
| 14 |
+
from torch.nn import Conv1d, ConvTranspose1d
|
| 15 |
+
from torch.nn.utils import weight_norm, remove_weight_norm
|
| 16 |
+
|
| 17 |
+
import sys
|
| 18 |
+
|
| 19 |
+
sys.path.append("./ldm/modules/bigvgan")
|
| 20 |
+
import activations
|
| 21 |
+
from alias_free_activation.torch.act import Activation1d as TorchActivation1d
|
| 22 |
+
|
| 23 |
+
from huggingface_hub import PyTorchModelHubMixin, hf_hub_download
|
| 24 |
+
import numpy as np
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
class AttrDict(dict):
|
| 28 |
+
def __init__(self, *args, **kwargs):
|
| 29 |
+
super(AttrDict, self).__init__(*args, **kwargs)
|
| 30 |
+
self.__dict__ = self
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def init_weights(m, mean=0.0, std=0.01):
|
| 34 |
+
classname = m.__class__.__name__
|
| 35 |
+
if classname.find("Conv") != -1:
|
| 36 |
+
m.weight.data.normal_(mean, std)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def get_padding(kernel_size, dilation=1):
|
| 40 |
+
return int((kernel_size * dilation - dilation) / 2)
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def load_hparams_from_json(path) -> AttrDict:
|
| 44 |
+
with open(path) as f:
|
| 45 |
+
data = f.read()
|
| 46 |
+
return AttrDict(json.loads(data))
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
class AMPBlock1(torch.nn.Module):
|
| 50 |
+
"""
|
| 51 |
+
AMPBlock applies Snake / SnakeBeta activation functions with trainable parameters that control periodicity, defined for each layer.
|
| 52 |
+
AMPBlock1 has additional self.convs2 that contains additional Conv1d layers with a fixed dilation=1 followed by each layer in self.convs1
|
| 53 |
+
|
| 54 |
+
Args:
|
| 55 |
+
h (AttrDict): Hyperparameters.
|
| 56 |
+
channels (int): Number of convolution channels.
|
| 57 |
+
kernel_size (int): Size of the convolution kernel. Default is 3.
|
| 58 |
+
dilation (tuple): Dilation rates for the convolutions. Each dilation layer has two convolutions. Default is (1, 3, 5).
|
| 59 |
+
activation (str): Activation function type. Should be either 'snake' or 'snakebeta'. Default is None.
|
| 60 |
+
"""
|
| 61 |
+
|
| 62 |
+
def __init__(
|
| 63 |
+
self,
|
| 64 |
+
h: AttrDict,
|
| 65 |
+
channels: int,
|
| 66 |
+
kernel_size: int = 3,
|
| 67 |
+
dilation: tuple = (1, 3, 5),
|
| 68 |
+
activation: str = None,
|
| 69 |
+
):
|
| 70 |
+
super().__init__()
|
| 71 |
+
|
| 72 |
+
self.h = h
|
| 73 |
+
|
| 74 |
+
self.convs1 = nn.ModuleList(
|
| 75 |
+
[
|
| 76 |
+
weight_norm(
|
| 77 |
+
Conv1d(
|
| 78 |
+
channels,
|
| 79 |
+
channels,
|
| 80 |
+
kernel_size,
|
| 81 |
+
stride=1,
|
| 82 |
+
dilation=d,
|
| 83 |
+
padding=get_padding(kernel_size, d),
|
| 84 |
+
)
|
| 85 |
+
)
|
| 86 |
+
for d in dilation
|
| 87 |
+
]
|
| 88 |
+
)
|
| 89 |
+
self.convs1.apply(init_weights)
|
| 90 |
+
|
| 91 |
+
self.convs2 = nn.ModuleList(
|
| 92 |
+
[
|
| 93 |
+
weight_norm(
|
| 94 |
+
Conv1d(
|
| 95 |
+
channels,
|
| 96 |
+
channels,
|
| 97 |
+
kernel_size,
|
| 98 |
+
stride=1,
|
| 99 |
+
dilation=1,
|
| 100 |
+
padding=get_padding(kernel_size, 1),
|
| 101 |
+
)
|
| 102 |
+
)
|
| 103 |
+
for _ in range(len(dilation))
|
| 104 |
+
]
|
| 105 |
+
)
|
| 106 |
+
self.convs2.apply(init_weights)
|
| 107 |
+
|
| 108 |
+
self.num_layers = len(self.convs1) + len(
|
| 109 |
+
self.convs2
|
| 110 |
+
) # Total number of conv layers
|
| 111 |
+
|
| 112 |
+
# Select which Activation1d, lazy-load cuda version to ensure backward compatibility
|
| 113 |
+
if self.h.get("use_cuda_kernel", False):
|
| 114 |
+
from alias_free_activation.cuda.activation1d import (
|
| 115 |
+
Activation1d as CudaActivation1d,
|
| 116 |
+
)
|
| 117 |
+
|
| 118 |
+
Activation1d = CudaActivation1d
|
| 119 |
+
else:
|
| 120 |
+
Activation1d = TorchActivation1d
|
| 121 |
+
|
| 122 |
+
# Activation functions
|
| 123 |
+
if activation == "snake":
|
| 124 |
+
self.activations = nn.ModuleList(
|
| 125 |
+
[
|
| 126 |
+
Activation1d(
|
| 127 |
+
activation=activations.Snake(
|
| 128 |
+
channels, alpha_logscale=h.snake_logscale
|
| 129 |
+
)
|
| 130 |
+
)
|
| 131 |
+
for _ in range(self.num_layers)
|
| 132 |
+
]
|
| 133 |
+
)
|
| 134 |
+
elif activation == "snakebeta":
|
| 135 |
+
self.activations = nn.ModuleList(
|
| 136 |
+
[
|
| 137 |
+
Activation1d(
|
| 138 |
+
activation=activations.SnakeBeta(
|
| 139 |
+
channels, alpha_logscale=h.snake_logscale
|
| 140 |
+
)
|
| 141 |
+
)
|
| 142 |
+
for _ in range(self.num_layers)
|
| 143 |
+
]
|
| 144 |
+
)
|
| 145 |
+
else:
|
| 146 |
+
raise NotImplementedError(
|
| 147 |
+
"activation incorrectly specified. check the config file and look for 'activation'."
|
| 148 |
+
)
|
| 149 |
+
|
| 150 |
+
def forward(self, x):
|
| 151 |
+
acts1, acts2 = self.activations[::2], self.activations[1::2]
|
| 152 |
+
for c1, c2, a1, a2 in zip(self.convs1, self.convs2, acts1, acts2):
|
| 153 |
+
xt = a1(x)
|
| 154 |
+
xt = c1(xt)
|
| 155 |
+
xt = a2(xt)
|
| 156 |
+
xt = c2(xt)
|
| 157 |
+
x = xt + x
|
| 158 |
+
|
| 159 |
+
return x
|
| 160 |
+
|
| 161 |
+
def remove_weight_norm(self):
|
| 162 |
+
for l in self.convs1:
|
| 163 |
+
remove_weight_norm(l)
|
| 164 |
+
for l in self.convs2:
|
| 165 |
+
remove_weight_norm(l)
|
| 166 |
+
|
| 167 |
+
|
| 168 |
+
class AMPBlock2(torch.nn.Module):
|
| 169 |
+
"""
|
| 170 |
+
AMPBlock applies Snake / SnakeBeta activation functions with trainable parameters that control periodicity, defined for each layer.
|
| 171 |
+
Unlike AMPBlock1, AMPBlock2 does not contain extra Conv1d layers with fixed dilation=1
|
| 172 |
+
|
| 173 |
+
Args:
|
| 174 |
+
h (AttrDict): Hyperparameters.
|
| 175 |
+
channels (int): Number of convolution channels.
|
| 176 |
+
kernel_size (int): Size of the convolution kernel. Default is 3.
|
| 177 |
+
dilation (tuple): Dilation rates for the convolutions. Each dilation layer has two convolutions. Default is (1, 3, 5).
|
| 178 |
+
activation (str): Activation function type. Should be either 'snake' or 'snakebeta'. Default is None.
|
| 179 |
+
"""
|
| 180 |
+
|
| 181 |
+
def __init__(
|
| 182 |
+
self,
|
| 183 |
+
h: AttrDict,
|
| 184 |
+
channels: int,
|
| 185 |
+
kernel_size: int = 3,
|
| 186 |
+
dilation: tuple = (1, 3, 5),
|
| 187 |
+
activation: str = None,
|
| 188 |
+
):
|
| 189 |
+
super().__init__()
|
| 190 |
+
|
| 191 |
+
self.h = h
|
| 192 |
+
|
| 193 |
+
self.convs = nn.ModuleList(
|
| 194 |
+
[
|
| 195 |
+
weight_norm(
|
| 196 |
+
Conv1d(
|
| 197 |
+
channels,
|
| 198 |
+
channels,
|
| 199 |
+
kernel_size,
|
| 200 |
+
stride=1,
|
| 201 |
+
dilation=d,
|
| 202 |
+
padding=get_padding(kernel_size, d),
|
| 203 |
+
)
|
| 204 |
+
)
|
| 205 |
+
for d in dilation
|
| 206 |
+
]
|
| 207 |
+
)
|
| 208 |
+
self.convs.apply(init_weights)
|
| 209 |
+
|
| 210 |
+
self.num_layers = len(self.convs) # Total number of conv layers
|
| 211 |
+
|
| 212 |
+
# Select which Activation1d, lazy-load cuda version to ensure backward compatibility
|
| 213 |
+
if self.h.get("use_cuda_kernel", False):
|
| 214 |
+
from alias_free_activation.cuda.activation1d import (
|
| 215 |
+
Activation1d as CudaActivation1d,
|
| 216 |
+
)
|
| 217 |
+
|
| 218 |
+
Activation1d = CudaActivation1d
|
| 219 |
+
else:
|
| 220 |
+
Activation1d = TorchActivation1d
|
| 221 |
+
|
| 222 |
+
# Activation functions
|
| 223 |
+
if activation == "snake":
|
| 224 |
+
self.activations = nn.ModuleList(
|
| 225 |
+
[
|
| 226 |
+
Activation1d(
|
| 227 |
+
activation=activations.Snake(
|
| 228 |
+
channels, alpha_logscale=h.snake_logscale
|
| 229 |
+
)
|
| 230 |
+
)
|
| 231 |
+
for _ in range(self.num_layers)
|
| 232 |
+
]
|
| 233 |
+
)
|
| 234 |
+
elif activation == "snakebeta":
|
| 235 |
+
self.activations = nn.ModuleList(
|
| 236 |
+
[
|
| 237 |
+
Activation1d(
|
| 238 |
+
activation=activations.SnakeBeta(
|
| 239 |
+
channels, alpha_logscale=h.snake_logscale
|
| 240 |
+
)
|
| 241 |
+
)
|
| 242 |
+
for _ in range(self.num_layers)
|
| 243 |
+
]
|
| 244 |
+
)
|
| 245 |
+
else:
|
| 246 |
+
raise NotImplementedError(
|
| 247 |
+
"activation incorrectly specified. check the config file and look for 'activation'."
|
| 248 |
+
)
|
| 249 |
+
|
| 250 |
+
def forward(self, x):
|
| 251 |
+
for c, a in zip(self.convs, self.activations):
|
| 252 |
+
xt = a(x)
|
| 253 |
+
xt = c(xt)
|
| 254 |
+
x = xt + x
|
| 255 |
+
|
| 256 |
+
def remove_weight_norm(self):
|
| 257 |
+
for l in self.convs:
|
| 258 |
+
remove_weight_norm(l)
|
| 259 |
+
|
| 260 |
+
|
| 261 |
+
class BigVGAN(
|
| 262 |
+
torch.nn.Module
|
| 263 |
+
# PyTorchModelHubMixin,
|
| 264 |
+
# library_name="bigvgan",
|
| 265 |
+
# repo_url="https://github.com/NVIDIA/BigVGAN",
|
| 266 |
+
# docs_url="https://github.com/NVIDIA/BigVGAN/blob/main/README.md",
|
| 267 |
+
# pipeline_tag="audio-to-audio",
|
| 268 |
+
# license="mit",
|
| 269 |
+
# tags=["neural-vocoder", "audio-generation", "arxiv:2206.04658"],
|
| 270 |
+
):
|
| 271 |
+
"""
|
| 272 |
+
BigVGAN is a neural vocoder model that applies anti-aliased periodic activation for residual blocks (resblocks).
|
| 273 |
+
New in BigVGAN-v2: it can optionally use optimized CUDA kernels for AMP (anti-aliased multi-periodicity) blocks.
|
| 274 |
+
|
| 275 |
+
Args:
|
| 276 |
+
h (AttrDict): Hyperparameters.
|
| 277 |
+
use_cuda_kernel (bool): If set to True, loads optimized CUDA kernels for AMP. This should be used for inference only, as training is not supported with CUDA kernels.
|
| 278 |
+
|
| 279 |
+
Note:
|
| 280 |
+
- The `use_cuda_kernel` parameter should be used for inference only, as training with CUDA kernels is not supported.
|
| 281 |
+
- Ensure that the activation function is correctly specified in the hyperparameters (h.activation).
|
| 282 |
+
"""
|
| 283 |
+
|
| 284 |
+
def __init__(self, path: str, use_cuda_kernel: bool = False):
|
| 285 |
+
super().__init__()
|
| 286 |
+
h = self.load_config(path)
|
| 287 |
+
self.h = h
|
| 288 |
+
self.h["use_cuda_kernel"] = use_cuda_kernel
|
| 289 |
+
|
| 290 |
+
# Select which Activation1d, lazy-load cuda version to ensure backward compatibility
|
| 291 |
+
if self.h.get("use_cuda_kernel", False):
|
| 292 |
+
from alias_free_activation.cuda.activation1d import (
|
| 293 |
+
Activation1d as CudaActivation1d,
|
| 294 |
+
)
|
| 295 |
+
|
| 296 |
+
Activation1d = CudaActivation1d
|
| 297 |
+
else:
|
| 298 |
+
Activation1d = TorchActivation1d
|
| 299 |
+
|
| 300 |
+
self.num_kernels = len(h.resblock_kernel_sizes)
|
| 301 |
+
self.num_upsamples = len(h.upsample_rates)
|
| 302 |
+
|
| 303 |
+
# Pre-conv
|
| 304 |
+
self.conv_pre = weight_norm(
|
| 305 |
+
Conv1d(h.num_mels, h.upsample_initial_channel, 7, 1, padding=3)
|
| 306 |
+
)
|
| 307 |
+
|
| 308 |
+
# Define which AMPBlock to use. BigVGAN uses AMPBlock1 as default
|
| 309 |
+
if h.resblock == "1":
|
| 310 |
+
resblock_class = AMPBlock1
|
| 311 |
+
elif h.resblock == "2":
|
| 312 |
+
resblock_class = AMPBlock2
|
| 313 |
+
else:
|
| 314 |
+
raise ValueError(
|
| 315 |
+
f"Incorrect resblock class specified in hyperparameters. Got {h.resblock}"
|
| 316 |
+
)
|
| 317 |
+
|
| 318 |
+
# Transposed conv-based upsamplers. does not apply anti-aliasing
|
| 319 |
+
self.ups = nn.ModuleList()
|
| 320 |
+
for i, (u, k) in enumerate(zip(h.upsample_rates, h.upsample_kernel_sizes)):
|
| 321 |
+
self.ups.append(
|
| 322 |
+
nn.ModuleList(
|
| 323 |
+
[
|
| 324 |
+
weight_norm(
|
| 325 |
+
ConvTranspose1d(
|
| 326 |
+
h.upsample_initial_channel // (2**i),
|
| 327 |
+
h.upsample_initial_channel // (2 ** (i + 1)),
|
| 328 |
+
k,
|
| 329 |
+
u,
|
| 330 |
+
padding=(k - u) // 2,
|
| 331 |
+
)
|
| 332 |
+
)
|
| 333 |
+
]
|
| 334 |
+
)
|
| 335 |
+
)
|
| 336 |
+
|
| 337 |
+
# Residual blocks using anti-aliased multi-periodicity composition modules (AMP)
|
| 338 |
+
self.resblocks = nn.ModuleList()
|
| 339 |
+
for i in range(len(self.ups)):
|
| 340 |
+
ch = h.upsample_initial_channel // (2 ** (i + 1))
|
| 341 |
+
for j, (k, d) in enumerate(
|
| 342 |
+
zip(h.resblock_kernel_sizes, h.resblock_dilation_sizes)
|
| 343 |
+
):
|
| 344 |
+
self.resblocks.append(
|
| 345 |
+
resblock_class(h, ch, k, d, activation=h.activation)
|
| 346 |
+
)
|
| 347 |
+
|
| 348 |
+
# Post-conv
|
| 349 |
+
activation_post = (
|
| 350 |
+
activations.Snake(ch, alpha_logscale=h.snake_logscale)
|
| 351 |
+
if h.activation == "snake"
|
| 352 |
+
else (
|
| 353 |
+
activations.SnakeBeta(ch, alpha_logscale=h.snake_logscale)
|
| 354 |
+
if h.activation == "snakebeta"
|
| 355 |
+
else None
|
| 356 |
+
)
|
| 357 |
+
)
|
| 358 |
+
if activation_post is None:
|
| 359 |
+
raise NotImplementedError(
|
| 360 |
+
"activation incorrectly specified. check the config file and look for 'activation'."
|
| 361 |
+
)
|
| 362 |
+
|
| 363 |
+
self.activation_post = Activation1d(activation=activation_post)
|
| 364 |
+
|
| 365 |
+
# Whether to use bias for the final conv_post. Default to True for backward compatibility
|
| 366 |
+
self.use_bias_at_final = h.get("use_bias_at_final", True)
|
| 367 |
+
self.conv_post = weight_norm(
|
| 368 |
+
Conv1d(ch, 1, 7, 1, padding=3, bias=self.use_bias_at_final)
|
| 369 |
+
)
|
| 370 |
+
|
| 371 |
+
# Weight initialization
|
| 372 |
+
for i in range(len(self.ups)):
|
| 373 |
+
self.ups[i].apply(init_weights)
|
| 374 |
+
self.conv_post.apply(init_weights)
|
| 375 |
+
|
| 376 |
+
# Final tanh activation. Defaults to True for backward compatibility
|
| 377 |
+
self.use_tanh_at_final = h.get("use_tanh_at_final", True)
|
| 378 |
+
|
| 379 |
+
def load_config(self, path):
|
| 380 |
+
with open(path) as f:
|
| 381 |
+
data = f.read()
|
| 382 |
+
json_config = json.loads(data)
|
| 383 |
+
h = AttrDict(json_config)
|
| 384 |
+
return h
|
| 385 |
+
|
| 386 |
+
def forward(self, x):
|
| 387 |
+
# Pre-conv
|
| 388 |
+
x = self.conv_pre(x)
|
| 389 |
+
|
| 390 |
+
for i in range(self.num_upsamples):
|
| 391 |
+
# Upsampling
|
| 392 |
+
for i_up in range(len(self.ups[i])):
|
| 393 |
+
x = self.ups[i][i_up](x)
|
| 394 |
+
# AMP blocks
|
| 395 |
+
xs = None
|
| 396 |
+
for j in range(self.num_kernels):
|
| 397 |
+
if xs is None:
|
| 398 |
+
xs = self.resblocks[i * self.num_kernels + j](x)
|
| 399 |
+
else:
|
| 400 |
+
xs += self.resblocks[i * self.num_kernels + j](x)
|
| 401 |
+
x = xs / self.num_kernels
|
| 402 |
+
|
| 403 |
+
# Post-conv
|
| 404 |
+
x = self.activation_post(x)
|
| 405 |
+
x = self.conv_post(x)
|
| 406 |
+
# Final tanh activation
|
| 407 |
+
if self.use_tanh_at_final:
|
| 408 |
+
x = torch.tanh(x)
|
| 409 |
+
else:
|
| 410 |
+
x = torch.clamp(x, min=-1.0, max=1.0) # Bound the output to [-1, 1]
|
| 411 |
+
|
| 412 |
+
return x
|
| 413 |
+
|
| 414 |
+
def remove_weight_norm(self):
|
| 415 |
+
try:
|
| 416 |
+
print("Removing weight norm...")
|
| 417 |
+
for l in self.ups:
|
| 418 |
+
for l_i in l:
|
| 419 |
+
remove_weight_norm(l_i)
|
| 420 |
+
for l in self.resblocks:
|
| 421 |
+
l.remove_weight_norm()
|
| 422 |
+
remove_weight_norm(self.conv_pre)
|
| 423 |
+
remove_weight_norm(self.conv_post)
|
| 424 |
+
except ValueError:
|
| 425 |
+
print("[INFO] Model already removed weight norm. Skipping!")
|
| 426 |
+
pass
|
| 427 |
+
|
| 428 |
+
# Additional methods for huggingface_hub support
|
| 429 |
+
def _save_pretrained(self, save_directory: Path) -> None:
|
| 430 |
+
"""Save weights and config.json from a Pytorch model to a local directory."""
|
| 431 |
+
|
| 432 |
+
model_path = save_directory / "bigvgan_generator.pt"
|
| 433 |
+
torch.save({"generator": self.state_dict()}, model_path)
|
| 434 |
+
|
| 435 |
+
config_path = save_directory / "config.json"
|
| 436 |
+
with open(config_path, "w") as config_file:
|
| 437 |
+
json.dump(self.h, config_file, indent=4)
|
| 438 |
+
|
| 439 |
+
@classmethod
|
| 440 |
+
def _from_pretrained(
|
| 441 |
+
cls,
|
| 442 |
+
*,
|
| 443 |
+
model_id: str,
|
| 444 |
+
revision: str,
|
| 445 |
+
cache_dir: str,
|
| 446 |
+
force_download: bool,
|
| 447 |
+
proxies: Optional[Dict],
|
| 448 |
+
resume_download: bool,
|
| 449 |
+
local_files_only: bool,
|
| 450 |
+
token: Union[str, bool, None],
|
| 451 |
+
map_location: str = "cpu", # Additional argument
|
| 452 |
+
strict: bool = False, # Additional argument
|
| 453 |
+
use_cuda_kernel: bool = False,
|
| 454 |
+
**model_kwargs,
|
| 455 |
+
):
|
| 456 |
+
"""Load Pytorch pretrained weights and return the loaded model."""
|
| 457 |
+
|
| 458 |
+
# Download and load hyperparameters (h) used by BigVGAN
|
| 459 |
+
if os.path.isdir(model_id):
|
| 460 |
+
print("Loading config.json from local directory")
|
| 461 |
+
config_file = os.path.join(model_id, "config.json")
|
| 462 |
+
else:
|
| 463 |
+
config_file = hf_hub_download(
|
| 464 |
+
repo_id=model_id,
|
| 465 |
+
filename="config.json",
|
| 466 |
+
revision=revision,
|
| 467 |
+
cache_dir=cache_dir,
|
| 468 |
+
force_download=force_download,
|
| 469 |
+
proxies=proxies,
|
| 470 |
+
resume_download=resume_download,
|
| 471 |
+
token=token,
|
| 472 |
+
local_files_only=local_files_only,
|
| 473 |
+
)
|
| 474 |
+
h = load_hparams_from_json(config_file)
|
| 475 |
+
|
| 476 |
+
# instantiate BigVGAN using h
|
| 477 |
+
if use_cuda_kernel:
|
| 478 |
+
print(
|
| 479 |
+
f"[WARNING] You have specified use_cuda_kernel=True during BigVGAN.from_pretrained(). Only inference is supported (training is not implemented)!"
|
| 480 |
+
)
|
| 481 |
+
print(
|
| 482 |
+
f"[WARNING] You need nvcc and ninja installed in your system that matches your PyTorch build is using to build the kernel. If not, the model will fail to initialize or generate incorrect waveform!"
|
| 483 |
+
)
|
| 484 |
+
print(
|
| 485 |
+
f"[WARNING] For detail, see the official GitHub repository: https://github.com/NVIDIA/BigVGAN?tab=readme-ov-file#using-custom-cuda-kernel-for-synthesis"
|
| 486 |
+
)
|
| 487 |
+
model = cls(h, use_cuda_kernel=use_cuda_kernel)
|
| 488 |
+
|
| 489 |
+
# Download and load pretrained generator weight
|
| 490 |
+
if os.path.isdir(model_id):
|
| 491 |
+
print("Loading weights from local directory")
|
| 492 |
+
model_file = os.path.join(model_id, "bigvgan_generator.pt")
|
| 493 |
+
else:
|
| 494 |
+
print(f"Loading weights from {model_id}")
|
| 495 |
+
model_file = hf_hub_download(
|
| 496 |
+
repo_id=model_id,
|
| 497 |
+
filename="bigvgan_generator.pt",
|
| 498 |
+
revision=revision,
|
| 499 |
+
cache_dir=cache_dir,
|
| 500 |
+
force_download=force_download,
|
| 501 |
+
proxies=proxies,
|
| 502 |
+
resume_download=resume_download,
|
| 503 |
+
token=token,
|
| 504 |
+
local_files_only=local_files_only,
|
| 505 |
+
)
|
| 506 |
+
|
| 507 |
+
checkpoint_dict = torch.load(model_file, map_location=map_location)
|
| 508 |
+
|
| 509 |
+
try:
|
| 510 |
+
model.load_state_dict(checkpoint_dict["generator"])
|
| 511 |
+
except RuntimeError:
|
| 512 |
+
print(
|
| 513 |
+
f"[INFO] the pretrained checkpoint does not contain weight norm. Loading the checkpoint after removing weight norm!"
|
| 514 |
+
)
|
| 515 |
+
model.remove_weight_norm()
|
| 516 |
+
model.load_state_dict(checkpoint_dict["generator"])
|
| 517 |
+
|
| 518 |
+
return model
|
| 519 |
+
|
| 520 |
+
|
| 521 |
+
class VocoderBigVGAN(object):
|
| 522 |
+
def __init__(self, ckpt_vocoder, device="cuda"):
|
| 523 |
+
vocoder_sd = torch.load(
|
| 524 |
+
os.path.join(ckpt_vocoder, "bigvgan_generator.pt"), map_location="cpu"
|
| 525 |
+
)
|
| 526 |
+
|
| 527 |
+
vocoder_args = os.path.join(ckpt_vocoder, "config.json")
|
| 528 |
+
|
| 529 |
+
self.generator = BigVGAN(vocoder_args)
|
| 530 |
+
self.generator.load_state_dict(vocoder_sd["generator"])
|
| 531 |
+
self.generator.eval()
|
| 532 |
+
|
| 533 |
+
self.device = device
|
| 534 |
+
self.generator.to(self.device)
|
| 535 |
+
self.generator.remove_weight_norm()
|
| 536 |
+
|
| 537 |
+
def vocode(self, spec):
|
| 538 |
+
with torch.no_grad():
|
| 539 |
+
if isinstance(spec, np.ndarray):
|
| 540 |
+
spec = torch.from_numpy(spec).unsqueeze(0)
|
| 541 |
+
spec = spec.to(dtype=torch.float32, device=self.device)
|
| 542 |
+
return self.generator(spec).squeeze().cpu().numpy()
|
| 543 |
+
|
| 544 |
+
def __call__(self, wav):
|
| 545 |
+
return self.vocode(wav)
|
ldm/modules/diffusionmodules/PixArt.py
ADDED
|
@@ -0,0 +1,1198 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from abc import abstractmethod
|
| 2 |
+
from functools import partial
|
| 3 |
+
import math
|
| 4 |
+
from typing import Iterable
|
| 5 |
+
|
| 6 |
+
import numpy as np
|
| 7 |
+
import torch as th
|
| 8 |
+
import torch.nn as nn
|
| 9 |
+
import torch.nn.functional as F
|
| 10 |
+
|
| 11 |
+
from timm.models.vision_transformer import Attention, Mlp
|
| 12 |
+
from positional_encodings.torch_encodings import PositionalEncoding1D
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
from timm.models.layers import DropPath
|
| 16 |
+
from .utils import auto_grad_checkpoint, to_2tuple
|
| 17 |
+
from .PixArt_blocks import (
|
| 18 |
+
t2i_modulate,
|
| 19 |
+
WindowAttention,
|
| 20 |
+
MultiHeadCrossAttention,
|
| 21 |
+
T2IFinalLayer,
|
| 22 |
+
TimestepEmbedder,
|
| 23 |
+
FinalLayer,
|
| 24 |
+
)
|
| 25 |
+
import xformers.ops
|
| 26 |
+
|
| 27 |
+
import math
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
class PatchEmbed(nn.Module):
|
| 31 |
+
"""2D Image to Patch Embedding"""
|
| 32 |
+
|
| 33 |
+
def __init__(
|
| 34 |
+
self,
|
| 35 |
+
img_size=(256, 16),
|
| 36 |
+
patch_size=(16, 4),
|
| 37 |
+
overlap=(0, 0),
|
| 38 |
+
in_chans=128,
|
| 39 |
+
embed_dim=768,
|
| 40 |
+
norm_layer=None,
|
| 41 |
+
flatten=True,
|
| 42 |
+
bias=True,
|
| 43 |
+
):
|
| 44 |
+
super().__init__()
|
| 45 |
+
|
| 46 |
+
self.img_size = img_size
|
| 47 |
+
self.patch_size = patch_size
|
| 48 |
+
self.ol = overlap
|
| 49 |
+
self.grid_size = (
|
| 50 |
+
math.ceil((img_size[0] - patch_size[0]) / (patch_size[0] - overlap[0])) + 1,
|
| 51 |
+
math.ceil((img_size[1] - patch_size[1]) / (patch_size[1] - overlap[1])) + 1,
|
| 52 |
+
)
|
| 53 |
+
self.pad_size = (
|
| 54 |
+
(self.grid_size[0] - 1) * (self.patch_size[0] - overlap[0])
|
| 55 |
+
+ self.patch_size[0]
|
| 56 |
+
- self.img_size[0],
|
| 57 |
+
+(self.grid_size[1] - 1) * (self.patch_size[1] - overlap[1])
|
| 58 |
+
+ self.patch_size[1]
|
| 59 |
+
- self.img_size[1],
|
| 60 |
+
)
|
| 61 |
+
self.pad_size = (self.pad_size[0] // 2, self.pad_size[1] // 2)
|
| 62 |
+
|
| 63 |
+
self.num_patches = self.grid_size[0] * self.grid_size[1]
|
| 64 |
+
self.flatten = flatten
|
| 65 |
+
|
| 66 |
+
self.proj = nn.Conv2d(
|
| 67 |
+
in_chans,
|
| 68 |
+
embed_dim,
|
| 69 |
+
kernel_size=patch_size,
|
| 70 |
+
stride=(patch_size[0] - overlap[0], patch_size[1] - overlap[1]),
|
| 71 |
+
bias=bias,
|
| 72 |
+
)
|
| 73 |
+
self.norm = norm_layer(embed_dim) if norm_layer else nn.Identity()
|
| 74 |
+
|
| 75 |
+
def forward(self, x):
|
| 76 |
+
|
| 77 |
+
x = F.pad(
|
| 78 |
+
x,
|
| 79 |
+
(
|
| 80 |
+
self.pad_size[-1],
|
| 81 |
+
self.pad_size[-1],
|
| 82 |
+
self.pad_size[-2],
|
| 83 |
+
self.pad_size[-2],
|
| 84 |
+
),
|
| 85 |
+
"constant",
|
| 86 |
+
0,
|
| 87 |
+
)
|
| 88 |
+
x = self.proj(x)
|
| 89 |
+
if self.flatten:
|
| 90 |
+
x = x.flatten(2).transpose(1, 2) # BCHW -> BNC
|
| 91 |
+
x = self.norm(x)
|
| 92 |
+
return x
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
class PatchEmbed_1D(nn.Module):
|
| 96 |
+
def __init__(
|
| 97 |
+
self,
|
| 98 |
+
img_size=(256, 16),
|
| 99 |
+
in_chans=8,
|
| 100 |
+
embed_dim=1152,
|
| 101 |
+
norm_layer=None,
|
| 102 |
+
bias=True,
|
| 103 |
+
):
|
| 104 |
+
super().__init__()
|
| 105 |
+
|
| 106 |
+
self.proj = nn.Linear(in_chans * img_size[1], embed_dim, bias=bias)
|
| 107 |
+
self.norm = norm_layer(embed_dim) if norm_layer else nn.Identity()
|
| 108 |
+
|
| 109 |
+
def forward(self, x):
|
| 110 |
+
|
| 111 |
+
x = th.einsum("bctf->btfc", x)
|
| 112 |
+
x = x.flatten(2) # BTFC -> BTD
|
| 113 |
+
x = self.proj(x)
|
| 114 |
+
x = self.norm(x)
|
| 115 |
+
return x
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
def modulate(x, shift, scale):
|
| 119 |
+
return x * (1 + scale.unsqueeze(1)) + shift.unsqueeze(1)
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
def t2i_modulate(x, shift, scale):
|
| 123 |
+
return x * (1 + scale) + shift
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
class PixArtBlock(nn.Module):
|
| 127 |
+
"""
|
| 128 |
+
A PixArt block with adaptive layer norm (adaLN-single) conditioning.
|
| 129 |
+
"""
|
| 130 |
+
|
| 131 |
+
def __init__(
|
| 132 |
+
self,
|
| 133 |
+
hidden_size,
|
| 134 |
+
num_heads,
|
| 135 |
+
mlp_ratio=4.0,
|
| 136 |
+
drop_path=0.0,
|
| 137 |
+
window_size=0,
|
| 138 |
+
input_size=None,
|
| 139 |
+
use_rel_pos=False,
|
| 140 |
+
**block_kwargs
|
| 141 |
+
):
|
| 142 |
+
super().__init__()
|
| 143 |
+
self.hidden_size = hidden_size
|
| 144 |
+
self.norm1 = nn.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6)
|
| 145 |
+
self.attn = WindowAttention(
|
| 146 |
+
hidden_size,
|
| 147 |
+
num_heads=num_heads,
|
| 148 |
+
qkv_bias=True,
|
| 149 |
+
input_size=input_size if window_size == 0 else (window_size, window_size),
|
| 150 |
+
use_rel_pos=use_rel_pos,
|
| 151 |
+
**block_kwargs
|
| 152 |
+
)
|
| 153 |
+
self.cross_attn = MultiHeadCrossAttention(
|
| 154 |
+
hidden_size, num_heads, **block_kwargs
|
| 155 |
+
)
|
| 156 |
+
self.norm2 = nn.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6)
|
| 157 |
+
# to be compatible with lower version pytorch
|
| 158 |
+
approx_gelu = lambda: nn.GELU(approximate="tanh")
|
| 159 |
+
self.mlp = Mlp(
|
| 160 |
+
in_features=hidden_size,
|
| 161 |
+
hidden_features=int(hidden_size * mlp_ratio),
|
| 162 |
+
act_layer=approx_gelu,
|
| 163 |
+
drop=0,
|
| 164 |
+
)
|
| 165 |
+
self.drop_path = DropPath(drop_path) if drop_path > 0.0 else nn.Identity()
|
| 166 |
+
self.window_size = window_size
|
| 167 |
+
self.scale_shift_table = nn.Parameter(
|
| 168 |
+
th.randn(6, hidden_size) / hidden_size**0.5
|
| 169 |
+
)
|
| 170 |
+
|
| 171 |
+
def forward(self, x, y, t, mask=None, **kwargs):
|
| 172 |
+
B, N, C = x.shape
|
| 173 |
+
|
| 174 |
+
shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = (
|
| 175 |
+
self.scale_shift_table[None] + t.reshape(B, 6, -1)
|
| 176 |
+
).chunk(6, dim=1)
|
| 177 |
+
x = x + self.drop_path(
|
| 178 |
+
gate_msa
|
| 179 |
+
* self.attn(t2i_modulate(self.norm1(x), shift_msa, scale_msa)).reshape(
|
| 180 |
+
B, N, C
|
| 181 |
+
)
|
| 182 |
+
)
|
| 183 |
+
x = x + self.cross_attn(x, y, mask)
|
| 184 |
+
x = x + self.drop_path(
|
| 185 |
+
gate_mlp * self.mlp(t2i_modulate(self.norm2(x), shift_mlp, scale_mlp))
|
| 186 |
+
)
|
| 187 |
+
|
| 188 |
+
return x
|
| 189 |
+
|
| 190 |
+
|
| 191 |
+
from ldm.modules.diffusionmodules.attention import CrossAttention_1D
|
| 192 |
+
|
| 193 |
+
|
| 194 |
+
class PixArtBlock_Slow(nn.Module):
|
| 195 |
+
"""
|
| 196 |
+
A PixArt block with adaptive layer norm (adaLN-single) conditioning.
|
| 197 |
+
"""
|
| 198 |
+
|
| 199 |
+
def __init__(
|
| 200 |
+
self,
|
| 201 |
+
hidden_size,
|
| 202 |
+
num_heads,
|
| 203 |
+
mlp_ratio=4.0,
|
| 204 |
+
drop_path=0.0,
|
| 205 |
+
window_size=0,
|
| 206 |
+
input_size=None,
|
| 207 |
+
use_rel_pos=False,
|
| 208 |
+
**block_kwargs
|
| 209 |
+
):
|
| 210 |
+
super().__init__()
|
| 211 |
+
self.hidden_size = hidden_size
|
| 212 |
+
self.norm1 = nn.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6)
|
| 213 |
+
self.attn = CrossAttention_1D(
|
| 214 |
+
query_dim=hidden_size,
|
| 215 |
+
context_dim=hidden_size,
|
| 216 |
+
heads=num_heads,
|
| 217 |
+
dim_head=int(hidden_size / num_heads),
|
| 218 |
+
)
|
| 219 |
+
self.cross_attn = CrossAttention_1D(
|
| 220 |
+
query_dim=hidden_size,
|
| 221 |
+
context_dim=hidden_size,
|
| 222 |
+
heads=num_heads,
|
| 223 |
+
dim_head=int(hidden_size / num_heads),
|
| 224 |
+
)
|
| 225 |
+
self.norm2 = nn.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6)
|
| 226 |
+
# to be compatible with lower version pytorch
|
| 227 |
+
approx_gelu = lambda: nn.GELU(approximate="tanh")
|
| 228 |
+
self.mlp = Mlp(
|
| 229 |
+
in_features=hidden_size,
|
| 230 |
+
hidden_features=int(hidden_size * mlp_ratio),
|
| 231 |
+
act_layer=approx_gelu,
|
| 232 |
+
drop=0,
|
| 233 |
+
)
|
| 234 |
+
self.drop_path = DropPath(drop_path) if drop_path > 0.0 else nn.Identity()
|
| 235 |
+
self.window_size = window_size
|
| 236 |
+
self.scale_shift_table = nn.Parameter(
|
| 237 |
+
th.randn(6, hidden_size) / hidden_size**0.5
|
| 238 |
+
)
|
| 239 |
+
|
| 240 |
+
def forward(self, x, y, t, mask=None, **kwargs):
|
| 241 |
+
B, N, C = x.shape
|
| 242 |
+
|
| 243 |
+
shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = (
|
| 244 |
+
self.scale_shift_table[None] + t.reshape(B, 6, -1)
|
| 245 |
+
).chunk(6, dim=1)
|
| 246 |
+
x = x + self.drop_path(
|
| 247 |
+
gate_msa
|
| 248 |
+
* self.attn(t2i_modulate(self.norm1(x), shift_msa, scale_msa)).reshape(
|
| 249 |
+
B, N, C
|
| 250 |
+
)
|
| 251 |
+
)
|
| 252 |
+
x = x + self.cross_attn(x, y, mask)
|
| 253 |
+
x = x + self.drop_path(
|
| 254 |
+
gate_mlp * self.mlp(t2i_modulate(self.norm2(x), shift_mlp, scale_mlp))
|
| 255 |
+
)
|
| 256 |
+
|
| 257 |
+
return x
|
| 258 |
+
|
| 259 |
+
|
| 260 |
+
class PixArt(nn.Module):
|
| 261 |
+
"""
|
| 262 |
+
Diffusion model with a Transformer backbone.
|
| 263 |
+
"""
|
| 264 |
+
|
| 265 |
+
def __init__(
|
| 266 |
+
self,
|
| 267 |
+
input_size=(256, 16),
|
| 268 |
+
patch_size=(16, 4),
|
| 269 |
+
overlap=(0, 0),
|
| 270 |
+
in_channels=8,
|
| 271 |
+
hidden_size=1152,
|
| 272 |
+
depth=28,
|
| 273 |
+
num_heads=16,
|
| 274 |
+
mlp_ratio=4.0,
|
| 275 |
+
class_dropout_prob=0.1,
|
| 276 |
+
pred_sigma=True,
|
| 277 |
+
drop_path: float = 0.0,
|
| 278 |
+
window_size=0,
|
| 279 |
+
window_block_indexes=None,
|
| 280 |
+
use_rel_pos=False,
|
| 281 |
+
cond_dim=1024,
|
| 282 |
+
lewei_scale=1.0,
|
| 283 |
+
use_cfg=True,
|
| 284 |
+
cfg_scale=4.0,
|
| 285 |
+
config=None,
|
| 286 |
+
model_max_length=120,
|
| 287 |
+
**kwargs
|
| 288 |
+
):
|
| 289 |
+
if window_block_indexes is None:
|
| 290 |
+
window_block_indexes = []
|
| 291 |
+
super().__init__()
|
| 292 |
+
self.use_cfg = use_cfg
|
| 293 |
+
self.cfg_scale = cfg_scale
|
| 294 |
+
self.input_size = input_size
|
| 295 |
+
self.pred_sigma = pred_sigma
|
| 296 |
+
self.in_channels = in_channels
|
| 297 |
+
self.out_channels = in_channels * 2 if pred_sigma else in_channels
|
| 298 |
+
self.patch_size = patch_size
|
| 299 |
+
self.num_heads = num_heads
|
| 300 |
+
self.lewei_scale = (lewei_scale,)
|
| 301 |
+
|
| 302 |
+
self.x_embedder = PatchEmbed(
|
| 303 |
+
input_size, patch_size, overlap, in_channels, hidden_size, bias=True
|
| 304 |
+
)
|
| 305 |
+
|
| 306 |
+
self.t_embedder = TimestepEmbedder(hidden_size)
|
| 307 |
+
num_patches = self.x_embedder.num_patches
|
| 308 |
+
self.base_size = input_size[0] // self.patch_size[0] * 2
|
| 309 |
+
# Will use fixed sin-cos embedding:
|
| 310 |
+
self.register_buffer("pos_embed", th.zeros(1, num_patches, hidden_size))
|
| 311 |
+
|
| 312 |
+
approx_gelu = lambda: nn.GELU(approximate="tanh")
|
| 313 |
+
self.t_block = nn.Sequential(
|
| 314 |
+
nn.SiLU(), nn.Linear(hidden_size, 6 * hidden_size, bias=True)
|
| 315 |
+
)
|
| 316 |
+
self.y_embedder = nn.Linear(cond_dim, hidden_size)
|
| 317 |
+
drop_path = [
|
| 318 |
+
x.item() for x in th.linspace(0, drop_path, depth)
|
| 319 |
+
] # stochastic depth decay rule
|
| 320 |
+
self.blocks = nn.ModuleList(
|
| 321 |
+
[
|
| 322 |
+
PixArtBlock(
|
| 323 |
+
hidden_size,
|
| 324 |
+
num_heads,
|
| 325 |
+
mlp_ratio=mlp_ratio,
|
| 326 |
+
drop_path=drop_path[i],
|
| 327 |
+
input_size=(
|
| 328 |
+
self.x_embedder.grid_size[0],
|
| 329 |
+
self.x_embedder.grid_size[1],
|
| 330 |
+
),
|
| 331 |
+
window_size=0,
|
| 332 |
+
use_rel_pos=False,
|
| 333 |
+
)
|
| 334 |
+
for i in range(depth)
|
| 335 |
+
]
|
| 336 |
+
)
|
| 337 |
+
self.final_layer = T2IFinalLayer(hidden_size, patch_size, self.out_channels)
|
| 338 |
+
|
| 339 |
+
self.initialize_weights()
|
| 340 |
+
|
| 341 |
+
def forward(self, x, timestep, context_list, context_mask_list=None, **kwargs):
|
| 342 |
+
"""
|
| 343 |
+
Forward pass of PixArt.
|
| 344 |
+
x: (N, C, H, W) tensor of spatial inputs (images or latent representations of images)
|
| 345 |
+
t: (N,) tensor of diffusion timesteps
|
| 346 |
+
y: (N, 1, 120, C) tensor of class labels
|
| 347 |
+
"""
|
| 348 |
+
x = x.to(self.dtype)
|
| 349 |
+
timestep = timestep.to(self.dtype)
|
| 350 |
+
y = context_list[0].to(self.dtype)
|
| 351 |
+
pos_embed = self.pos_embed.to(self.dtype)
|
| 352 |
+
self.h, self.w = self.x_embedder.grid_size[0], self.x_embedder.grid_size[1]
|
| 353 |
+
|
| 354 |
+
x = self.x_embedder(x) + pos_embed
|
| 355 |
+
t = self.t_embedder(timestep.to(x.dtype))
|
| 356 |
+
t0 = self.t_block(t)
|
| 357 |
+
y = self.y_embedder(y)
|
| 358 |
+
mask = context_mask_list[0]
|
| 359 |
+
|
| 360 |
+
assert mask is not None
|
| 361 |
+
# if mask is not None:
|
| 362 |
+
|
| 363 |
+
y = y.masked_select(mask.unsqueeze(-1) != 0).view(1, -1, x.shape[-1])
|
| 364 |
+
y_lens = mask.sum(dim=1).tolist()
|
| 365 |
+
y_lens = [int(_) for _ in y_lens]
|
| 366 |
+
for block in self.blocks:
|
| 367 |
+
x = auto_grad_checkpoint(block, x, y, t0, y_lens)
|
| 368 |
+
x = self.final_layer(x, t)
|
| 369 |
+
x = self.unpatchify(x)
|
| 370 |
+
return x
|
| 371 |
+
|
| 372 |
+
def forward_with_dpmsolver(self, x, timestep, y, mask=None, **kwargs):
|
| 373 |
+
"""
|
| 374 |
+
dpm solver donnot need variance prediction
|
| 375 |
+
"""
|
| 376 |
+
# https://github.com/openai/glide-text2im/blob/main/notebooks/text2im.ipynb
|
| 377 |
+
model_out = self.forward(x, timestep, y, mask)
|
| 378 |
+
return model_out.chunk(2, dim=1)[0]
|
| 379 |
+
|
| 380 |
+
def forward_with_cfg(self, x, timestep, y, cfg_scale, mask=None, **kwargs):
|
| 381 |
+
"""
|
| 382 |
+
Forward pass of PixArt, but also batches the unconditional forward pass for classifier-free guidance.
|
| 383 |
+
"""
|
| 384 |
+
# https://github.com/openai/glide-text2im/blob/main/notebooks/text2im.ipynb
|
| 385 |
+
half = x[: len(x) // 2]
|
| 386 |
+
combined = th.cat([half, half], dim=0)
|
| 387 |
+
model_out = self.forward(combined, timestep, y, mask)
|
| 388 |
+
model_out = model_out["x"] if isinstance(model_out, dict) else model_out
|
| 389 |
+
eps, rest = model_out[:, :8], model_out[:, 8:]
|
| 390 |
+
cond_eps, uncond_eps = th.split(eps, len(eps) // 2, dim=0)
|
| 391 |
+
half_eps = uncond_eps + cfg_scale * (cond_eps - uncond_eps)
|
| 392 |
+
eps = th.cat([half_eps, half_eps], dim=0)
|
| 393 |
+
return eps
|
| 394 |
+
|
| 395 |
+
def unpatchify(self, x):
|
| 396 |
+
"""
|
| 397 |
+
x: (N, T, patch_size 0 * patch_size 1 * C)
|
| 398 |
+
imgs: (Bs. 256. 16. 8)
|
| 399 |
+
"""
|
| 400 |
+
|
| 401 |
+
c = self.out_channels
|
| 402 |
+
p0 = self.x_embedder.patch_size[0]
|
| 403 |
+
p1 = self.x_embedder.patch_size[1]
|
| 404 |
+
h, w = self.x_embedder.grid_size[0], self.x_embedder.grid_size[1]
|
| 405 |
+
|
| 406 |
+
x = x.reshape(shape=(x.shape[0], h, w, p0, p1, c))
|
| 407 |
+
x = th.einsum("nhwpqc->nchpwq", x)
|
| 408 |
+
imgs = x.reshape(shape=(x.shape[0], c, h * p0, w * p1))
|
| 409 |
+
return imgs
|
| 410 |
+
|
| 411 |
+
def initialize_weights(self):
|
| 412 |
+
# Initialize transformer layers:
|
| 413 |
+
def _basic_init(module):
|
| 414 |
+
if isinstance(module, nn.Linear):
|
| 415 |
+
th.nn.init.xavier_uniform_(module.weight)
|
| 416 |
+
if module.bias is not None:
|
| 417 |
+
nn.init.constant_(module.bias, 0)
|
| 418 |
+
|
| 419 |
+
self.apply(_basic_init)
|
| 420 |
+
|
| 421 |
+
# Initialize (and freeze) pos_embed by sin-cos embedding:
|
| 422 |
+
pos_embed = get_2d_sincos_pos_embed(
|
| 423 |
+
self.pos_embed.shape[-1],
|
| 424 |
+
self.x_embedder.grid_size,
|
| 425 |
+
lewei_scale=self.lewei_scale,
|
| 426 |
+
base_size=self.base_size,
|
| 427 |
+
)
|
| 428 |
+
self.pos_embed.data.copy_(th.from_numpy(pos_embed).float().unsqueeze(0))
|
| 429 |
+
|
| 430 |
+
# Initialize patch_embed like nn.Linear (instead of nn.Conv2d):
|
| 431 |
+
w = self.x_embedder.proj.weight.data
|
| 432 |
+
nn.init.xavier_uniform_(w.view([w.shape[0], -1]))
|
| 433 |
+
|
| 434 |
+
# Initialize timestep embedding MLP:
|
| 435 |
+
nn.init.normal_(self.t_embedder.mlp[0].weight, std=0.02)
|
| 436 |
+
nn.init.normal_(self.t_embedder.mlp[2].weight, std=0.02)
|
| 437 |
+
nn.init.normal_(self.t_block[1].weight, std=0.02)
|
| 438 |
+
|
| 439 |
+
# Initialize caption embedding MLP:
|
| 440 |
+
nn.init.normal_(self.y_embedder.weight, std=0.02)
|
| 441 |
+
|
| 442 |
+
# Zero-out adaLN modulation layers in PixArt blocks:
|
| 443 |
+
for block in self.blocks:
|
| 444 |
+
nn.init.constant_(block.cross_attn.proj.weight, 0)
|
| 445 |
+
nn.init.constant_(block.cross_attn.proj.bias, 0)
|
| 446 |
+
|
| 447 |
+
# Zero-out output layers:
|
| 448 |
+
nn.init.constant_(self.final_layer.linear.weight, 0)
|
| 449 |
+
nn.init.constant_(self.final_layer.linear.bias, 0)
|
| 450 |
+
|
| 451 |
+
@property
|
| 452 |
+
def dtype(self):
|
| 453 |
+
return next(self.parameters()).dtype
|
| 454 |
+
|
| 455 |
+
|
| 456 |
+
class SwiGLU(nn.Module):
|
| 457 |
+
def __init__(
|
| 458 |
+
self,
|
| 459 |
+
dim: int,
|
| 460 |
+
hidden_dim: int,
|
| 461 |
+
multiple_of: int,
|
| 462 |
+
):
|
| 463 |
+
super().__init__()
|
| 464 |
+
|
| 465 |
+
hidden_dim = multiple_of * ((hidden_dim + multiple_of - 1) // multiple_of)
|
| 466 |
+
|
| 467 |
+
self.w1 = nn.Linear(dim, hidden_dim, bias=False)
|
| 468 |
+
self.w2 = nn.Linear(hidden_dim, dim, bias=False)
|
| 469 |
+
self.w3 = nn.Linear(dim, hidden_dim, bias=False)
|
| 470 |
+
|
| 471 |
+
def forward(self, x):
|
| 472 |
+
return self.w2(F.silu(self.w1(x)) * self.w3(x))
|
| 473 |
+
|
| 474 |
+
|
| 475 |
+
class MDTBlock(nn.Module):
|
| 476 |
+
"""
|
| 477 |
+
A PixArt block with adaptive layer norm (adaLN-single) conditioning.
|
| 478 |
+
"""
|
| 479 |
+
|
| 480 |
+
def __init__(
|
| 481 |
+
self,
|
| 482 |
+
hidden_size,
|
| 483 |
+
num_heads,
|
| 484 |
+
mlp_ratio=4.0,
|
| 485 |
+
FFN_type="SwiGLU",
|
| 486 |
+
drop_path=0.0,
|
| 487 |
+
window_size=0,
|
| 488 |
+
input_size=None,
|
| 489 |
+
use_rel_pos=False,
|
| 490 |
+
skip=False,
|
| 491 |
+
**block_kwargs
|
| 492 |
+
):
|
| 493 |
+
super().__init__()
|
| 494 |
+
self.hidden_size = hidden_size
|
| 495 |
+
self.norm1 = nn.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6)
|
| 496 |
+
self.attn = WindowAttention(
|
| 497 |
+
hidden_size,
|
| 498 |
+
num_heads=num_heads,
|
| 499 |
+
qkv_bias=True,
|
| 500 |
+
input_size=input_size if window_size == 0 else (window_size, window_size),
|
| 501 |
+
use_rel_pos=use_rel_pos,
|
| 502 |
+
**block_kwargs
|
| 503 |
+
)
|
| 504 |
+
self.cross_attn = MultiHeadCrossAttention(
|
| 505 |
+
hidden_size, num_heads, **block_kwargs
|
| 506 |
+
)
|
| 507 |
+
self.norm2 = nn.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6)
|
| 508 |
+
# to be compatible with lower version pytorch
|
| 509 |
+
approx_gelu = lambda: nn.GELU(approximate="tanh")
|
| 510 |
+
if FFN_type == "mlp":
|
| 511 |
+
self.mlp = Mlp(
|
| 512 |
+
in_features=hidden_size,
|
| 513 |
+
hidden_features=int(hidden_size * mlp_ratio),
|
| 514 |
+
act_layer=approx_gelu,
|
| 515 |
+
drop=0,
|
| 516 |
+
)
|
| 517 |
+
elif FFN_type == "SwiGLU":
|
| 518 |
+
self.mlp = SwiGLU(hidden_size, int(hidden_size * mlp_ratio), 1)
|
| 519 |
+
self.drop_path = DropPath(drop_path) if drop_path > 0.0 else nn.Identity()
|
| 520 |
+
self.window_size = window_size
|
| 521 |
+
self.scale_shift_table = nn.Parameter(
|
| 522 |
+
th.randn(6, hidden_size) / hidden_size**0.5
|
| 523 |
+
)
|
| 524 |
+
|
| 525 |
+
self.skip_linear = nn.Linear(2 * hidden_size, hidden_size) if skip else None
|
| 526 |
+
|
| 527 |
+
def forward(self, x, y, t, mask=None, skip=None, ids_keep=None, **kwargs):
|
| 528 |
+
B, N, C = x.shape
|
| 529 |
+
if self.skip_linear is not None:
|
| 530 |
+
x = self.skip_linear(th.cat([x, skip], dim=-1))
|
| 531 |
+
|
| 532 |
+
shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = (
|
| 533 |
+
self.scale_shift_table[None] + t.reshape(B, 6, -1)
|
| 534 |
+
).chunk(6, dim=1)
|
| 535 |
+
x = x + self.drop_path(
|
| 536 |
+
gate_msa
|
| 537 |
+
* self.attn(t2i_modulate(self.norm1(x), shift_msa, scale_msa)).reshape(
|
| 538 |
+
B, N, C
|
| 539 |
+
)
|
| 540 |
+
)
|
| 541 |
+
x = x + self.cross_attn(x, y, mask)
|
| 542 |
+
x = x + self.drop_path(
|
| 543 |
+
gate_mlp * self.mlp(t2i_modulate(self.norm2(x), shift_mlp, scale_mlp))
|
| 544 |
+
)
|
| 545 |
+
|
| 546 |
+
return x
|
| 547 |
+
|
| 548 |
+
|
| 549 |
+
class DEBlock(nn.Module):
|
| 550 |
+
"""
|
| 551 |
+
Decoder block with added SpecTNT transformer
|
| 552 |
+
"""
|
| 553 |
+
|
| 554 |
+
def __init__(
|
| 555 |
+
self,
|
| 556 |
+
hidden_size,
|
| 557 |
+
num_heads,
|
| 558 |
+
mlp_ratio=4.0,
|
| 559 |
+
FFN_type="SwiGLU",
|
| 560 |
+
drop_path=0.0,
|
| 561 |
+
window_size=0,
|
| 562 |
+
input_size=None,
|
| 563 |
+
use_rel_pos=False,
|
| 564 |
+
skip=False,
|
| 565 |
+
num_f=None,
|
| 566 |
+
num_t=None,
|
| 567 |
+
**block_kwargs
|
| 568 |
+
):
|
| 569 |
+
super().__init__()
|
| 570 |
+
self.hidden_size = hidden_size
|
| 571 |
+
self.norm1 = nn.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6)
|
| 572 |
+
self.attn = WindowAttention(
|
| 573 |
+
hidden_size,
|
| 574 |
+
num_heads=num_heads,
|
| 575 |
+
qkv_bias=True,
|
| 576 |
+
input_size=input_size if window_size == 0 else (window_size, window_size),
|
| 577 |
+
use_rel_pos=use_rel_pos,
|
| 578 |
+
**block_kwargs
|
| 579 |
+
)
|
| 580 |
+
self.cross_attn = MultiHeadCrossAttention(
|
| 581 |
+
hidden_size, num_heads, **block_kwargs
|
| 582 |
+
)
|
| 583 |
+
|
| 584 |
+
self.norm2 = nn.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6)
|
| 585 |
+
self.norm3 = nn.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6)
|
| 586 |
+
self.norm4 = nn.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6)
|
| 587 |
+
self.norm5 = nn.LayerNorm(
|
| 588 |
+
hidden_size * num_f, elementwise_affine=False, eps=1e-6
|
| 589 |
+
)
|
| 590 |
+
self.norm6 = nn.LayerNorm(
|
| 591 |
+
hidden_size * num_f, elementwise_affine=False, eps=1e-6
|
| 592 |
+
)
|
| 593 |
+
# to be compatible with lower version pytorch
|
| 594 |
+
approx_gelu = lambda: nn.GELU(approximate="tanh")
|
| 595 |
+
if FFN_type == "mlp":
|
| 596 |
+
self.mlp = Mlp(
|
| 597 |
+
in_features=hidden_size,
|
| 598 |
+
hidden_features=int(hidden_size * mlp_ratio),
|
| 599 |
+
act_layer=approx_gelu,
|
| 600 |
+
drop=0,
|
| 601 |
+
)
|
| 602 |
+
|
| 603 |
+
elif FFN_type == "SwiGLU":
|
| 604 |
+
self.mlp = SwiGLU(hidden_size, int(hidden_size * mlp_ratio), 1)
|
| 605 |
+
self.drop_path = DropPath(drop_path) if drop_path > 0.0 else nn.Identity()
|
| 606 |
+
self.window_size = window_size
|
| 607 |
+
self.scale_shift_table = nn.Parameter(
|
| 608 |
+
th.randn(6, hidden_size) / hidden_size**0.5
|
| 609 |
+
)
|
| 610 |
+
|
| 611 |
+
self.skip_linear = nn.Linear(2 * hidden_size, hidden_size) if skip else None
|
| 612 |
+
|
| 613 |
+
self.F_transformer = WindowAttention(
|
| 614 |
+
hidden_size,
|
| 615 |
+
num_heads=4,
|
| 616 |
+
qkv_bias=True,
|
| 617 |
+
input_size=input_size if window_size == 0 else (window_size, window_size),
|
| 618 |
+
use_rel_pos=use_rel_pos,
|
| 619 |
+
**block_kwargs
|
| 620 |
+
)
|
| 621 |
+
|
| 622 |
+
self.T_transformer = WindowAttention(
|
| 623 |
+
hidden_size * num_f,
|
| 624 |
+
num_heads=16,
|
| 625 |
+
qkv_bias=True,
|
| 626 |
+
input_size=input_size if window_size == 0 else (window_size, window_size),
|
| 627 |
+
use_rel_pos=use_rel_pos,
|
| 628 |
+
**block_kwargs
|
| 629 |
+
)
|
| 630 |
+
|
| 631 |
+
self.f_pos = nn.Embedding(num_f, hidden_size)
|
| 632 |
+
self.t_pos = nn.Embedding(num_t, hidden_size * num_f)
|
| 633 |
+
self.num_f = num_f
|
| 634 |
+
self.num_t = num_t
|
| 635 |
+
|
| 636 |
+
def forward(self, x, end, y, t, mask=None, skip=None, ids_keep=None, **kwargs):
|
| 637 |
+
B, D, C = x.shape
|
| 638 |
+
T = self.num_t
|
| 639 |
+
F_add_1 = self.num_f
|
| 640 |
+
|
| 641 |
+
x_normal = x
|
| 642 |
+
|
| 643 |
+
if self.skip_linear is not None:
|
| 644 |
+
x_normal = self.skip_linear(th.cat([x_normal, skip], dim=-1))
|
| 645 |
+
|
| 646 |
+
D = T * (F_add_1 - 1)
|
| 647 |
+
|
| 648 |
+
shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = (
|
| 649 |
+
self.scale_shift_table[None] + t.reshape(B, 6, -1)
|
| 650 |
+
).chunk(6, dim=1)
|
| 651 |
+
x_normal = x_normal + self.drop_path(
|
| 652 |
+
gate_msa
|
| 653 |
+
* self.attn(
|
| 654 |
+
t2i_modulate(self.norm1(x_normal), shift_msa, scale_msa)
|
| 655 |
+
).reshape(B, D, C)
|
| 656 |
+
)
|
| 657 |
+
|
| 658 |
+
x_normal = x_normal.reshape(B, T, F_add_1 - 1, C)
|
| 659 |
+
x_normal = th.cat((x_normal, end), 2)
|
| 660 |
+
|
| 661 |
+
x_normal = x_normal.reshape(B * T, F_add_1, C)
|
| 662 |
+
pos_f = th.arange(self.num_f, device=x.device).unsqueeze(0).expand(B * T, -1)
|
| 663 |
+
|
| 664 |
+
x_normal = x_normal + self.f_pos(pos_f)
|
| 665 |
+
|
| 666 |
+
x_normal = x_normal + self.F_transformer(self.norm3(x_normal))
|
| 667 |
+
|
| 668 |
+
x_normal = x_normal.reshape(B, T, F_add_1 * C)
|
| 669 |
+
pos_t = th.arange(self.num_t, device=x.device).unsqueeze(0).expand(B, -1)
|
| 670 |
+
x_normal = x_normal + self.t_pos(pos_t)
|
| 671 |
+
x_normal = x_normal + self.T_transformer(self.norm5(x_normal))
|
| 672 |
+
|
| 673 |
+
x_normal = x_normal.reshape(B, T, F_add_1, C)
|
| 674 |
+
end = x_normal[:, :, -1, :].unsqueeze(2)
|
| 675 |
+
x_normal = x_normal[:, :, :-1, :]
|
| 676 |
+
x_normal = x_normal.reshape(B, T * (F_add_1 - 1), C)
|
| 677 |
+
|
| 678 |
+
x_normal = x_normal + self.cross_attn(x_normal, y, mask)
|
| 679 |
+
x_normal = x_normal + self.drop_path(
|
| 680 |
+
gate_mlp
|
| 681 |
+
* self.mlp(t2i_modulate(self.norm2(x_normal), shift_mlp, scale_mlp))
|
| 682 |
+
)
|
| 683 |
+
|
| 684 |
+
return x_normal, end
|
| 685 |
+
|
| 686 |
+
|
| 687 |
+
class PixArt_MDT(nn.Module):
|
| 688 |
+
"""
|
| 689 |
+
Diffusion model with a Transformer backbone.
|
| 690 |
+
"""
|
| 691 |
+
|
| 692 |
+
def __init__(
|
| 693 |
+
self,
|
| 694 |
+
input_size=(256, 16),
|
| 695 |
+
patch_size=(16, 4),
|
| 696 |
+
overlap=(0, 0),
|
| 697 |
+
in_channels=8,
|
| 698 |
+
hidden_size=1152,
|
| 699 |
+
depth=28,
|
| 700 |
+
num_heads=16,
|
| 701 |
+
mlp_ratio=4.0,
|
| 702 |
+
class_dropout_prob=0.1,
|
| 703 |
+
pred_sigma=False,
|
| 704 |
+
drop_path: float = 0.0,
|
| 705 |
+
window_size=0,
|
| 706 |
+
window_block_indexes=None,
|
| 707 |
+
use_rel_pos=False,
|
| 708 |
+
cond_dim=1024,
|
| 709 |
+
lewei_scale=1.0,
|
| 710 |
+
use_cfg=True,
|
| 711 |
+
cfg_scale=4.0,
|
| 712 |
+
config=None,
|
| 713 |
+
model_max_length=120,
|
| 714 |
+
mask_ratio=None,
|
| 715 |
+
decode_layer=4,
|
| 716 |
+
**kwargs
|
| 717 |
+
):
|
| 718 |
+
if window_block_indexes is None:
|
| 719 |
+
window_block_indexes = []
|
| 720 |
+
super().__init__()
|
| 721 |
+
self.use_cfg = use_cfg
|
| 722 |
+
self.cfg_scale = cfg_scale
|
| 723 |
+
self.input_size = input_size
|
| 724 |
+
self.pred_sigma = pred_sigma
|
| 725 |
+
self.in_channels = in_channels
|
| 726 |
+
self.out_channels = in_channels
|
| 727 |
+
self.patch_size = patch_size
|
| 728 |
+
self.num_heads = num_heads
|
| 729 |
+
self.lewei_scale = (lewei_scale,)
|
| 730 |
+
decode_layer = int(decode_layer)
|
| 731 |
+
|
| 732 |
+
self.x_embedder = PatchEmbed(
|
| 733 |
+
input_size, patch_size, overlap, in_channels, hidden_size, bias=True
|
| 734 |
+
)
|
| 735 |
+
|
| 736 |
+
self.t_embedder = TimestepEmbedder(hidden_size)
|
| 737 |
+
num_patches = self.x_embedder.num_patches
|
| 738 |
+
self.base_size = input_size[0] // self.patch_size[0] * 2
|
| 739 |
+
# Will use fixed sin-cos embedding:
|
| 740 |
+
self.register_buffer("pos_embed", th.zeros(1, num_patches, hidden_size))
|
| 741 |
+
|
| 742 |
+
approx_gelu = lambda: nn.GELU(approximate="tanh")
|
| 743 |
+
self.t_block = nn.Sequential(
|
| 744 |
+
nn.SiLU(), nn.Linear(hidden_size, 6 * hidden_size, bias=True)
|
| 745 |
+
)
|
| 746 |
+
|
| 747 |
+
self.y_embedder = nn.Linear(cond_dim, hidden_size)
|
| 748 |
+
|
| 749 |
+
half_depth = (depth - decode_layer) // 2
|
| 750 |
+
self.half_depth = half_depth
|
| 751 |
+
|
| 752 |
+
drop_path_half = [
|
| 753 |
+
x.item() for x in th.linspace(0, drop_path, half_depth)
|
| 754 |
+
] # stochastic depth decay rule
|
| 755 |
+
drop_path_decode = [x.item() for x in th.linspace(0, drop_path, decode_layer)]
|
| 756 |
+
self.en_inblocks = nn.ModuleList(
|
| 757 |
+
[
|
| 758 |
+
MDTBlock(
|
| 759 |
+
hidden_size,
|
| 760 |
+
num_heads,
|
| 761 |
+
mlp_ratio=mlp_ratio,
|
| 762 |
+
drop_path=drop_path_half[i],
|
| 763 |
+
input_size=(
|
| 764 |
+
self.x_embedder.grid_size[0],
|
| 765 |
+
self.x_embedder.grid_size[1],
|
| 766 |
+
),
|
| 767 |
+
window_size=0,
|
| 768 |
+
use_rel_pos=False,
|
| 769 |
+
FFN_type="mlp",
|
| 770 |
+
)
|
| 771 |
+
for i in range(half_depth)
|
| 772 |
+
]
|
| 773 |
+
)
|
| 774 |
+
self.en_outblocks = nn.ModuleList(
|
| 775 |
+
[
|
| 776 |
+
MDTBlock(
|
| 777 |
+
hidden_size,
|
| 778 |
+
num_heads,
|
| 779 |
+
mlp_ratio=mlp_ratio,
|
| 780 |
+
drop_path=drop_path_half[i],
|
| 781 |
+
input_size=(
|
| 782 |
+
self.x_embedder.grid_size[0],
|
| 783 |
+
self.x_embedder.grid_size[1],
|
| 784 |
+
),
|
| 785 |
+
window_size=0,
|
| 786 |
+
use_rel_pos=False,
|
| 787 |
+
skip=True,
|
| 788 |
+
FFN_type="mlp",
|
| 789 |
+
)
|
| 790 |
+
for i in range(half_depth)
|
| 791 |
+
]
|
| 792 |
+
)
|
| 793 |
+
self.de_blocks = nn.ModuleList(
|
| 794 |
+
[
|
| 795 |
+
MDTBlock(
|
| 796 |
+
hidden_size,
|
| 797 |
+
num_heads,
|
| 798 |
+
mlp_ratio=mlp_ratio,
|
| 799 |
+
drop_path=drop_path_decode[i],
|
| 800 |
+
input_size=(
|
| 801 |
+
self.x_embedder.grid_size[0],
|
| 802 |
+
self.x_embedder.grid_size[1],
|
| 803 |
+
),
|
| 804 |
+
window_size=0,
|
| 805 |
+
use_rel_pos=False,
|
| 806 |
+
skip=True,
|
| 807 |
+
FFN_type="mlp",
|
| 808 |
+
)
|
| 809 |
+
for i in range(decode_layer)
|
| 810 |
+
]
|
| 811 |
+
)
|
| 812 |
+
self.sideblocks = nn.ModuleList(
|
| 813 |
+
[
|
| 814 |
+
MDTBlock(
|
| 815 |
+
hidden_size,
|
| 816 |
+
num_heads,
|
| 817 |
+
mlp_ratio=mlp_ratio,
|
| 818 |
+
input_size=(
|
| 819 |
+
self.x_embedder.grid_size[0],
|
| 820 |
+
self.x_embedder.grid_size[1],
|
| 821 |
+
),
|
| 822 |
+
window_size=0,
|
| 823 |
+
use_rel_pos=False,
|
| 824 |
+
FFN_type="mlp",
|
| 825 |
+
)
|
| 826 |
+
for _ in range(1)
|
| 827 |
+
]
|
| 828 |
+
)
|
| 829 |
+
|
| 830 |
+
self.final_layer = T2IFinalLayer(hidden_size, patch_size, self.out_channels)
|
| 831 |
+
|
| 832 |
+
self.decoder_pos_embed = nn.Parameter(
|
| 833 |
+
th.zeros(1, num_patches, hidden_size), requires_grad=True
|
| 834 |
+
)
|
| 835 |
+
if mask_ratio is not None:
|
| 836 |
+
self.mask_token = nn.Parameter(th.zeros(1, 1, hidden_size))
|
| 837 |
+
self.mask_ratio = float(mask_ratio)
|
| 838 |
+
self.decode_layer = int(decode_layer)
|
| 839 |
+
else:
|
| 840 |
+
self.mask_token = nn.Parameter(
|
| 841 |
+
th.zeros(1, 1, hidden_size), requires_grad=False
|
| 842 |
+
)
|
| 843 |
+
self.mask_ratio = None
|
| 844 |
+
self.decode_layer = int(decode_layer)
|
| 845 |
+
|
| 846 |
+
self.initialize_weights()
|
| 847 |
+
|
| 848 |
+
def forward(self, x, t, context, mask=None, enable_mask=False, **kwargs):
|
| 849 |
+
"""
|
| 850 |
+
Forward pass of PixArt.
|
| 851 |
+
x: (N, C, H, W) tensor of spatial inputs (images or latent representations of images)
|
| 852 |
+
t: (N,) tensor of diffusion timesteps
|
| 853 |
+
y: (N, 1, 120, C) tensor of class labels
|
| 854 |
+
"""
|
| 855 |
+
x = x.to(self.dtype)
|
| 856 |
+
t = t.to(self.dtype)
|
| 857 |
+
|
| 858 |
+
y = context.to(self.dtype)
|
| 859 |
+
pos_embed = self.pos_embed.to(self.dtype)
|
| 860 |
+
self.h, self.w = self.x_embedder.grid_size[0], self.x_embedder.grid_size[1]
|
| 861 |
+
|
| 862 |
+
x = self.x_embedder(x) + pos_embed
|
| 863 |
+
t = self.t_embedder(t.to(x.dtype))
|
| 864 |
+
t0 = self.t_block(t)
|
| 865 |
+
y = self.y_embedder(y)
|
| 866 |
+
|
| 867 |
+
try:
|
| 868 |
+
|
| 869 |
+
mask = mask
|
| 870 |
+
except:
|
| 871 |
+
mask = th.ones(x.shape[0], 1).to(x.device)
|
| 872 |
+
print("MASK !!!!!!!!!!!!!!!!!!!!!!!!!")
|
| 873 |
+
|
| 874 |
+
assert mask is not None
|
| 875 |
+
|
| 876 |
+
y = y.masked_select(mask.unsqueeze(-1) != 0).view(1, -1, x.shape[-1])
|
| 877 |
+
y_lens = mask.sum(dim=1).tolist()
|
| 878 |
+
y_lens = [int(_) for _ in y_lens]
|
| 879 |
+
|
| 880 |
+
input_skip = x
|
| 881 |
+
|
| 882 |
+
masked_stage = False
|
| 883 |
+
skips = []
|
| 884 |
+
# TODO : masking op for training
|
| 885 |
+
if self.mask_ratio is not None and self.training:
|
| 886 |
+
|
| 887 |
+
rand_mask_ratio = th.rand(1, device=x.device)
|
| 888 |
+
rand_mask_ratio = rand_mask_ratio * 0.2 + self.mask_ratio
|
| 889 |
+
|
| 890 |
+
x, mask, ids_restore, ids_keep = self.random_masking(x, rand_mask_ratio)
|
| 891 |
+
masked_stage = True
|
| 892 |
+
|
| 893 |
+
for block in self.en_inblocks:
|
| 894 |
+
if masked_stage:
|
| 895 |
+
x = auto_grad_checkpoint(block, x, y, t0, y_lens, ids_keep=ids_keep)
|
| 896 |
+
else:
|
| 897 |
+
x = auto_grad_checkpoint(block, x, y, t0, y_lens, ids_keep=None)
|
| 898 |
+
skips.append(x)
|
| 899 |
+
|
| 900 |
+
for block in self.en_outblocks:
|
| 901 |
+
if masked_stage:
|
| 902 |
+
x = auto_grad_checkpoint(
|
| 903 |
+
block, x, y, t0, y_lens, skip=skips.pop(), ids_keep=ids_keep
|
| 904 |
+
)
|
| 905 |
+
else:
|
| 906 |
+
x = auto_grad_checkpoint(
|
| 907 |
+
block, x, y, t0, y_lens, skip=skips.pop(), ids_keep=None
|
| 908 |
+
)
|
| 909 |
+
|
| 910 |
+
if self.mask_ratio is not None and self.training:
|
| 911 |
+
x = self.forward_side_interpolater(x, y, t0, y_lens, mask, ids_restore)
|
| 912 |
+
masked_stage = False
|
| 913 |
+
else:
|
| 914 |
+
# add pos embed
|
| 915 |
+
x = x + self.decoder_pos_embed
|
| 916 |
+
|
| 917 |
+
for i in range(len(self.de_blocks)):
|
| 918 |
+
block = self.de_blocks[i]
|
| 919 |
+
this_skip = input_skip
|
| 920 |
+
|
| 921 |
+
x = auto_grad_checkpoint(
|
| 922 |
+
block, x, y, t0, y_lens, skip=this_skip, ids_keep=None
|
| 923 |
+
)
|
| 924 |
+
|
| 925 |
+
x = self.final_layer(x, t)
|
| 926 |
+
x = self.unpatchify(x)
|
| 927 |
+
return x
|
| 928 |
+
|
| 929 |
+
def forward_with_dpmsolver(self, x, timestep, y, mask=None, **kwargs):
|
| 930 |
+
"""
|
| 931 |
+
dpm solver donnot need variance prediction
|
| 932 |
+
"""
|
| 933 |
+
# https://github.com/openai/glide-text2im/blob/main/notebooks/text2im.ipynb
|
| 934 |
+
model_out = self.forward(x, timestep, y, mask)
|
| 935 |
+
return model_out.chunk(2, dim=1)[0]
|
| 936 |
+
|
| 937 |
+
def forward_with_cfg(
|
| 938 |
+
self, x, timestep, context_list, context_mask_list=None, cfg_scale=4.0, **kwargs
|
| 939 |
+
):
|
| 940 |
+
"""
|
| 941 |
+
Forward pass of PixArt, but also batches the unconditional forward pass for classifier-free guidance.
|
| 942 |
+
"""
|
| 943 |
+
# https://github.com/openai/glide-text2im/blob/main/notebooks/text2im.ipynb
|
| 944 |
+
half = x[: len(x) // 2]
|
| 945 |
+
combined = th.cat([half, half], dim=0)
|
| 946 |
+
model_out = self.forward(
|
| 947 |
+
combined, timestep, context_list, context_mask_list=None
|
| 948 |
+
)
|
| 949 |
+
model_out = model_out["x"] if isinstance(model_out, dict) else model_out
|
| 950 |
+
eps, rest = model_out[:, :8], model_out[:, 8:]
|
| 951 |
+
cond_eps, uncond_eps = th.split(eps, len(eps) // 2, dim=0)
|
| 952 |
+
half_eps = uncond_eps + cfg_scale * (cond_eps - uncond_eps)
|
| 953 |
+
eps = th.cat([half_eps, half_eps], dim=0)
|
| 954 |
+
return eps
|
| 955 |
+
|
| 956 |
+
def unpatchify(self, x):
|
| 957 |
+
"""
|
| 958 |
+
x: (N, T, patch_size 0 * patch_size 1 * C)
|
| 959 |
+
imgs: (Bs. 256. 16. 8)
|
| 960 |
+
"""
|
| 961 |
+
if self.x_embedder.ol == (0, 0) or self.x_embedder.ol == [0, 0]:
|
| 962 |
+
c = self.out_channels
|
| 963 |
+
p0 = self.x_embedder.patch_size[0]
|
| 964 |
+
p1 = self.x_embedder.patch_size[1]
|
| 965 |
+
h, w = self.x_embedder.grid_size[0], self.x_embedder.grid_size[1]
|
| 966 |
+
|
| 967 |
+
x = x.reshape(shape=(x.shape[0], h, w, p0, p1, c))
|
| 968 |
+
x = th.einsum("nhwpqc->nchpwq", x)
|
| 969 |
+
imgs = x.reshape(shape=(x.shape[0], c, h * p0, w * p1))
|
| 970 |
+
return imgs
|
| 971 |
+
|
| 972 |
+
lf = self.x_embedder.grid_size[0]
|
| 973 |
+
rf = self.x_embedder.grid_size[1]
|
| 974 |
+
lp = self.x_embedder.patch_size[0]
|
| 975 |
+
rp = self.x_embedder.patch_size[1]
|
| 976 |
+
lo = self.x_embedder.ol[0]
|
| 977 |
+
ro = self.x_embedder.ol[1]
|
| 978 |
+
lm = self.x_embedder.img_size[0]
|
| 979 |
+
rm = self.x_embedder.img_size[1]
|
| 980 |
+
lpad = self.x_embedder.pad_size[0]
|
| 981 |
+
rpad = self.x_embedder.pad_size[1]
|
| 982 |
+
bs = x.shape[0]
|
| 983 |
+
|
| 984 |
+
torch_map = self.torch_map
|
| 985 |
+
|
| 986 |
+
c = self.out_channels
|
| 987 |
+
|
| 988 |
+
x = x.reshape(shape=(bs, lf, rf, lp, rp, c))
|
| 989 |
+
x = th.einsum("nhwpqc->nchwpq", x)
|
| 990 |
+
|
| 991 |
+
added_map = th.zeros(bs, c, lm + 2 * lpad, rm + 2 * rpad).to(x.device)
|
| 992 |
+
|
| 993 |
+
for i in range(lf):
|
| 994 |
+
for j in range(rf):
|
| 995 |
+
xx = (i) * (lp - lo)
|
| 996 |
+
yy = (j) * (rp - ro)
|
| 997 |
+
added_map[:, :, xx : (xx + lp), yy : (yy + rp)] += x[:, :, i, j, :, :]
|
| 998 |
+
|
| 999 |
+
added_map = added_map[:][:][lpad : lm + lpad, rpad : rm + rpad]
|
| 1000 |
+
return th.mul(added_map.to(x.device), torch_map.to(x.device))
|
| 1001 |
+
|
| 1002 |
+
def random_masking(self, x, mask_ratio):
|
| 1003 |
+
"""
|
| 1004 |
+
Perform per-sample random masking by per-sample shuffling.
|
| 1005 |
+
Per-sample shuffling is done by argsort random noise.
|
| 1006 |
+
x: [N, L, D], sequence
|
| 1007 |
+
"""
|
| 1008 |
+
N, L, D = x.shape # batch, length, dim
|
| 1009 |
+
len_keep = int(L * (1 - mask_ratio))
|
| 1010 |
+
noise = th.rand(N, L, device=x.device)
|
| 1011 |
+
|
| 1012 |
+
# sort noise for each sample
|
| 1013 |
+
# ascend: small is keep, large is remove
|
| 1014 |
+
ids_shuffle = th.argsort(noise, dim=1)
|
| 1015 |
+
ids_restore = th.argsort(ids_shuffle, dim=1)
|
| 1016 |
+
|
| 1017 |
+
# keep the first subset
|
| 1018 |
+
ids_keep = ids_shuffle[:, :len_keep]
|
| 1019 |
+
x_masked = th.gather(x, dim=1, index=ids_keep.unsqueeze(-1).repeat(1, 1, D))
|
| 1020 |
+
|
| 1021 |
+
# generate the binary mask: 0 is keep, 1 is remove
|
| 1022 |
+
mask = th.ones([N, L], device=x.device)
|
| 1023 |
+
mask[:, :len_keep] = 0
|
| 1024 |
+
# unshuffle to get the binary mask
|
| 1025 |
+
mask = th.gather(mask, dim=1, index=ids_restore)
|
| 1026 |
+
|
| 1027 |
+
return x_masked, mask, ids_restore, ids_keep
|
| 1028 |
+
|
| 1029 |
+
def forward_side_interpolater(self, x, y, t0, y_lens, mask, ids_restore):
|
| 1030 |
+
# append mask tokens to sequence
|
| 1031 |
+
mask_tokens = self.mask_token.repeat(
|
| 1032 |
+
x.shape[0], ids_restore.shape[1] - x.shape[1], 1
|
| 1033 |
+
)
|
| 1034 |
+
x_ = th.cat([x, mask_tokens], dim=1)
|
| 1035 |
+
x = th.gather(
|
| 1036 |
+
x_, dim=1, index=ids_restore.unsqueeze(-1).repeat(1, 1, x.shape[2])
|
| 1037 |
+
) # unshuffle
|
| 1038 |
+
|
| 1039 |
+
# add pos embed
|
| 1040 |
+
x = x + self.decoder_pos_embed
|
| 1041 |
+
|
| 1042 |
+
# pass to the basic block
|
| 1043 |
+
x_before = x
|
| 1044 |
+
for sideblock in self.sideblocks:
|
| 1045 |
+
x = sideblock(x, y, t0, y_lens, ids_keep=None)
|
| 1046 |
+
|
| 1047 |
+
# masked shortcut
|
| 1048 |
+
mask = mask.unsqueeze(dim=-1)
|
| 1049 |
+
x = x * mask + (1 - mask) * x_before
|
| 1050 |
+
|
| 1051 |
+
return x
|
| 1052 |
+
|
| 1053 |
+
def initialize_weights(self):
|
| 1054 |
+
# Initialize transformer layers:
|
| 1055 |
+
def _basic_init(module):
|
| 1056 |
+
if isinstance(module, nn.Linear):
|
| 1057 |
+
th.nn.init.xavier_uniform_(module.weight)
|
| 1058 |
+
if module.bias is not None:
|
| 1059 |
+
nn.init.constant_(module.bias, 0)
|
| 1060 |
+
|
| 1061 |
+
self.apply(_basic_init)
|
| 1062 |
+
|
| 1063 |
+
# Initialize (and freeze) pos_embed by sin-cos embedding:
|
| 1064 |
+
pos_embed = get_2d_sincos_pos_embed(
|
| 1065 |
+
self.pos_embed.shape[-1],
|
| 1066 |
+
self.x_embedder.grid_size,
|
| 1067 |
+
lewei_scale=self.lewei_scale,
|
| 1068 |
+
base_size=self.base_size,
|
| 1069 |
+
)
|
| 1070 |
+
self.pos_embed.data.copy_(th.from_numpy(pos_embed).float().unsqueeze(0))
|
| 1071 |
+
|
| 1072 |
+
# Initialize patch_embed like nn.Linear (instead of nn.Conv2d):
|
| 1073 |
+
w = self.x_embedder.proj.weight.data
|
| 1074 |
+
nn.init.xavier_uniform_(w.view([w.shape[0], -1]))
|
| 1075 |
+
|
| 1076 |
+
# Initialize timestep embedding MLP:
|
| 1077 |
+
nn.init.normal_(self.t_embedder.mlp[0].weight, std=0.02)
|
| 1078 |
+
nn.init.normal_(self.t_embedder.mlp[2].weight, std=0.02)
|
| 1079 |
+
nn.init.normal_(self.t_block[1].weight, std=0.02)
|
| 1080 |
+
|
| 1081 |
+
# Initialize caption embedding MLP:
|
| 1082 |
+
nn.init.normal_(self.y_embedder.weight, std=0.02)
|
| 1083 |
+
|
| 1084 |
+
# Zero-out adaLN modulation layers in PixArt blocks:
|
| 1085 |
+
for block in self.en_inblocks:
|
| 1086 |
+
nn.init.constant_(block.cross_attn.proj.weight, 0)
|
| 1087 |
+
nn.init.constant_(block.cross_attn.proj.bias, 0)
|
| 1088 |
+
for block in self.en_outblocks:
|
| 1089 |
+
nn.init.constant_(block.cross_attn.proj.weight, 0)
|
| 1090 |
+
nn.init.constant_(block.cross_attn.proj.bias, 0)
|
| 1091 |
+
for block in self.de_blocks:
|
| 1092 |
+
nn.init.constant_(block.cross_attn.proj.weight, 0)
|
| 1093 |
+
nn.init.constant_(block.cross_attn.proj.bias, 0)
|
| 1094 |
+
for block in self.sideblocks:
|
| 1095 |
+
nn.init.constant_(block.cross_attn.proj.weight, 0)
|
| 1096 |
+
nn.init.constant_(block.cross_attn.proj.bias, 0)
|
| 1097 |
+
|
| 1098 |
+
# Zero-out output layers:
|
| 1099 |
+
nn.init.constant_(self.final_layer.linear.weight, 0)
|
| 1100 |
+
nn.init.constant_(self.final_layer.linear.bias, 0)
|
| 1101 |
+
|
| 1102 |
+
if self.x_embedder.ol == [0, 0] or self.x_embedder.ol == (0, 0):
|
| 1103 |
+
return
|
| 1104 |
+
|
| 1105 |
+
lf = self.x_embedder.grid_size[0]
|
| 1106 |
+
rf = self.x_embedder.grid_size[1]
|
| 1107 |
+
lp = self.x_embedder.patch_size[0]
|
| 1108 |
+
rp = self.x_embedder.patch_size[1]
|
| 1109 |
+
lo = self.x_embedder.ol[0]
|
| 1110 |
+
ro = self.x_embedder.ol[1]
|
| 1111 |
+
lm = self.x_embedder.img_size[0]
|
| 1112 |
+
rm = self.x_embedder.img_size[1]
|
| 1113 |
+
lpad = self.x_embedder.pad_size[0]
|
| 1114 |
+
rpad = self.x_embedder.pad_size[1]
|
| 1115 |
+
|
| 1116 |
+
torch_map = th.zeros(lm + 2 * lpad, rm + 2 * rpad).to("cuda")
|
| 1117 |
+
for i in range(lf):
|
| 1118 |
+
for j in range(rf):
|
| 1119 |
+
xx = (i) * (lp - lo)
|
| 1120 |
+
yy = (j) * (rp - ro)
|
| 1121 |
+
torch_map[xx : (xx + lp), yy : (yy + rp)] += 1
|
| 1122 |
+
torch_map = torch_map[lpad : lm + lpad, rpad : rm + rpad]
|
| 1123 |
+
self.torch_map = th.reciprocal(torch_map)
|
| 1124 |
+
|
| 1125 |
+
@property
|
| 1126 |
+
def dtype(self):
|
| 1127 |
+
return next(self.parameters()).dtype
|
| 1128 |
+
|
| 1129 |
+
|
| 1130 |
+
def get_2d_sincos_pos_embed(
|
| 1131 |
+
embed_dim,
|
| 1132 |
+
grid_size,
|
| 1133 |
+
cls_token=False,
|
| 1134 |
+
extra_tokens=0,
|
| 1135 |
+
lewei_scale=1.0,
|
| 1136 |
+
base_size_x=256 // 4,
|
| 1137 |
+
base_size_y=16 // 4,
|
| 1138 |
+
base_size=128,
|
| 1139 |
+
):
|
| 1140 |
+
"""
|
| 1141 |
+
grid_size: int of the grid height and width
|
| 1142 |
+
return:
|
| 1143 |
+
pos_embed: [grid_size*grid_size, embed_dim] or [1+grid_size*grid_size, embed_dim] (w/ or w/o cls_token)
|
| 1144 |
+
"""
|
| 1145 |
+
if isinstance(grid_size, int):
|
| 1146 |
+
grid_size = to_2tuple(grid_size)
|
| 1147 |
+
|
| 1148 |
+
grid_h = (
|
| 1149 |
+
np.arange(grid_size[0], dtype=np.float32)
|
| 1150 |
+
/ (grid_size[0] / base_size_x)
|
| 1151 |
+
/ lewei_scale
|
| 1152 |
+
)
|
| 1153 |
+
grid_w = (
|
| 1154 |
+
np.arange(grid_size[1], dtype=np.float32)
|
| 1155 |
+
/ (grid_size[1] / base_size_y)
|
| 1156 |
+
/ lewei_scale
|
| 1157 |
+
)
|
| 1158 |
+
|
| 1159 |
+
grid = np.meshgrid(grid_w, grid_h) # here w goes first
|
| 1160 |
+
grid = np.stack(grid, axis=0)
|
| 1161 |
+
grid = grid.reshape([2, 1, grid_size[1], grid_size[0]])
|
| 1162 |
+
|
| 1163 |
+
pos_embed = get_2d_sincos_pos_embed_from_grid(embed_dim, grid)
|
| 1164 |
+
if cls_token and extra_tokens > 0:
|
| 1165 |
+
pos_embed = np.concatenate(
|
| 1166 |
+
[np.zeros([extra_tokens, embed_dim]), pos_embed], axis=0
|
| 1167 |
+
)
|
| 1168 |
+
return pos_embed
|
| 1169 |
+
|
| 1170 |
+
|
| 1171 |
+
def get_2d_sincos_pos_embed_from_grid(embed_dim, grid):
|
| 1172 |
+
assert embed_dim % 2 == 0
|
| 1173 |
+
|
| 1174 |
+
# use half of dimensions to encode grid_h
|
| 1175 |
+
emb_h = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[0])
|
| 1176 |
+
emb_w = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[1])
|
| 1177 |
+
|
| 1178 |
+
return np.concatenate([emb_h, emb_w], axis=1)
|
| 1179 |
+
|
| 1180 |
+
|
| 1181 |
+
def get_1d_sincos_pos_embed_from_grid(embed_dim, pos):
|
| 1182 |
+
"""
|
| 1183 |
+
embed_dim: output dimension for each position
|
| 1184 |
+
pos: a list of positions to be encoded: size (M,)
|
| 1185 |
+
out: (M, D)
|
| 1186 |
+
"""
|
| 1187 |
+
assert embed_dim % 2 == 0
|
| 1188 |
+
omega = np.arange(embed_dim // 2, dtype=np.float64)
|
| 1189 |
+
omega /= embed_dim / 2.0
|
| 1190 |
+
omega = 1.0 / 10000**omega
|
| 1191 |
+
|
| 1192 |
+
pos = pos.reshape(-1)
|
| 1193 |
+
out = np.einsum("m,d->md", pos, omega)
|
| 1194 |
+
|
| 1195 |
+
emb_sin = np.sin(out)
|
| 1196 |
+
emb_cos = np.cos(out)
|
| 1197 |
+
|
| 1198 |
+
return np.concatenate([emb_sin, emb_cos], axis=1)
|
ldm/modules/diffusionmodules/PixArt_blocks.py
ADDED
|
@@ -0,0 +1,573 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
|
| 4 |
+
# This source code is licensed under the license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
# --------------------------------------------------------
|
| 7 |
+
# References:
|
| 8 |
+
# GLIDE: https://github.com/openai/glide-text2im
|
| 9 |
+
# MAE: https://github.com/facebookresearch/mae/blob/main/models_mae.py
|
| 10 |
+
# --------------------------------------------------------
|
| 11 |
+
import math
|
| 12 |
+
import torch
|
| 13 |
+
import torch.nn as nn
|
| 14 |
+
from timm.models.vision_transformer import Mlp, Attention as Attention_
|
| 15 |
+
from einops import rearrange, repeat
|
| 16 |
+
import xformers.ops
|
| 17 |
+
|
| 18 |
+
from .utils import add_decomposed_rel_pos
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def modulate(x, shift, scale):
|
| 22 |
+
return x * (1 + scale.unsqueeze(1)) + shift.unsqueeze(1)
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def t2i_modulate(x, shift, scale):
|
| 26 |
+
return x * (1 + scale) + shift
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
class MultiHeadCrossAttention_org(nn.Module):
|
| 30 |
+
|
| 31 |
+
def __init__(self, n_feat, n_head, attn_drop=0.0, proj_drop=0):
|
| 32 |
+
"""Construct an MultiHeadedAttention object."""
|
| 33 |
+
super(MultiHeadCrossAttention, self).__init__()
|
| 34 |
+
assert n_feat % n_head == 0
|
| 35 |
+
# We assume d_v always equals d_k
|
| 36 |
+
self.d_k = n_feat // n_head
|
| 37 |
+
self.h = n_head
|
| 38 |
+
self.linear_q = nn.Linear(n_feat, n_feat)
|
| 39 |
+
self.linear_k = nn.Linear(n_feat, n_feat)
|
| 40 |
+
self.linear_v = nn.Linear(n_feat, n_feat)
|
| 41 |
+
self.proj = nn.Linear(n_feat, n_feat)
|
| 42 |
+
self.attn = None
|
| 43 |
+
self.dropout = nn.Dropout(p=attn_drop)
|
| 44 |
+
self.proj_drop = nn.Dropout(proj_drop)
|
| 45 |
+
|
| 46 |
+
def forward_qkv(self, query, key, value):
|
| 47 |
+
"""Transform query, key and value.
|
| 48 |
+
|
| 49 |
+
Args:
|
| 50 |
+
query (torch.Tensor): Query tensor (#batch, time1, size).
|
| 51 |
+
key (torch.Tensor): Key tensor (#batch, time2, size).
|
| 52 |
+
value (torch.Tensor): Value tensor (#batch, time2, size).
|
| 53 |
+
|
| 54 |
+
Returns:
|
| 55 |
+
torch.Tensor: Transformed query tensor (#batch, n_head, time1, d_k).
|
| 56 |
+
torch.Tensor: Transformed key tensor (#batch, n_head, time2, d_k).
|
| 57 |
+
torch.Tensor: Transformed value tensor (#batch, n_head, time2, d_k).
|
| 58 |
+
|
| 59 |
+
"""
|
| 60 |
+
n_batch = query.size(0)
|
| 61 |
+
q = self.linear_q(query).view(n_batch, -1, self.h, self.d_k)
|
| 62 |
+
k = self.linear_k(key).view(n_batch, -1, self.h, self.d_k)
|
| 63 |
+
v = self.linear_v(value).view(n_batch, -1, self.h, self.d_k)
|
| 64 |
+
|
| 65 |
+
q = q.transpose(1, 2)
|
| 66 |
+
k = k.transpose(1, 2)
|
| 67 |
+
v = v.transpose(1, 2)
|
| 68 |
+
|
| 69 |
+
return q, k, v
|
| 70 |
+
|
| 71 |
+
def forward_attention(self, value, scores, mask):
|
| 72 |
+
"""Compute attention context vector.
|
| 73 |
+
|
| 74 |
+
Args:
|
| 75 |
+
value (torch.Tensor): Transformed value (#batch, n_head, time2, d_k).
|
| 76 |
+
scores (torch.Tensor): Attention score (#batch, n_head, time1, time2).
|
| 77 |
+
mask (torch.Tensor): Mask (#batch, 1, time2) or (#batch, time1, time2).
|
| 78 |
+
|
| 79 |
+
Returns:
|
| 80 |
+
torch.Tensor: Transformed value (#batch, time1, d_model)
|
| 81 |
+
weighted by the attention score (#batch, time1, time2).
|
| 82 |
+
|
| 83 |
+
"""
|
| 84 |
+
n_batch = value.size(0)
|
| 85 |
+
if mask is not None:
|
| 86 |
+
mask = mask.unsqueeze(1).eq(0)
|
| 87 |
+
min_value = torch.finfo(scores.dtype).min
|
| 88 |
+
scores = scores.masked_fill(mask, min_value)
|
| 89 |
+
self.attn = torch.softmax(scores, dim=-1).masked_fill(mask, 0.0)
|
| 90 |
+
else:
|
| 91 |
+
self.attn = torch.softmax(scores, dim=-1)
|
| 92 |
+
|
| 93 |
+
p_attn = self.dropout(self.attn)
|
| 94 |
+
x = torch.matmul(p_attn, value)
|
| 95 |
+
x = x.transpose(1, 2).contiguous().view(n_batch, -1, self.h * self.d_k)
|
| 96 |
+
|
| 97 |
+
return self.proj_drop(self.proj(x))
|
| 98 |
+
|
| 99 |
+
def forward(self, x, cond, mask):
|
| 100 |
+
"""Compute scaled dot product attention.
|
| 101 |
+
|
| 102 |
+
Args:
|
| 103 |
+
query (torch.Tensor): Query tensor (#batch, time1, size).
|
| 104 |
+
key (torch.Tensor): Key tensor (#batch, time2, size).
|
| 105 |
+
value (torch.Tensor): Value tensor (#batch, time2, size).
|
| 106 |
+
mask (torch.Tensor): Mask tensor (#batch, 1, time2) or
|
| 107 |
+
(#batch, time1, time2).
|
| 108 |
+
|
| 109 |
+
Returns:
|
| 110 |
+
torch.Tensor: Output tensor (#batch, time1, d_model).
|
| 111 |
+
|
| 112 |
+
"""
|
| 113 |
+
q, k, v = self.forward_qkv(x, cond, cond)
|
| 114 |
+
scores = torch.matmul(q, k.transpose(-2, -1)) / math.sqrt(self.d_k)
|
| 115 |
+
return self.forward_attention(v, scores, mask)
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
class MultiHeadCrossAttention(nn.Module):
|
| 119 |
+
def __init__(
|
| 120 |
+
self, d_model, num_heads, attn_drop=0.0, proj_drop=0.0, **block_kwargs
|
| 121 |
+
):
|
| 122 |
+
super(MultiHeadCrossAttention, self).__init__()
|
| 123 |
+
assert d_model % num_heads == 0, "d_model must be divisible by num_heads"
|
| 124 |
+
|
| 125 |
+
self.d_model = d_model
|
| 126 |
+
self.num_heads = num_heads
|
| 127 |
+
self.head_dim = d_model // num_heads
|
| 128 |
+
|
| 129 |
+
self.q_linear = nn.Linear(d_model, d_model)
|
| 130 |
+
self.kv_linear = nn.Linear(d_model, d_model * 2)
|
| 131 |
+
self.attn_drop = nn.Dropout(attn_drop)
|
| 132 |
+
self.proj = nn.Linear(d_model, d_model)
|
| 133 |
+
self.proj_drop = nn.Dropout(proj_drop)
|
| 134 |
+
|
| 135 |
+
def forward(self, x, cond, mask=None):
|
| 136 |
+
# query/value: img tokens; key: condition; mask: if padding tokens
|
| 137 |
+
B, N, C = x.shape
|
| 138 |
+
|
| 139 |
+
q = self.q_linear(x).view(1, -1, self.num_heads, self.head_dim)
|
| 140 |
+
|
| 141 |
+
kv = self.kv_linear(cond).view(1, -1, 2, self.num_heads, self.head_dim)
|
| 142 |
+
k, v = kv.unbind(2)
|
| 143 |
+
attn_bias = None
|
| 144 |
+
assert mask is not None
|
| 145 |
+
|
| 146 |
+
attn_bias = xformers.ops.fmha.BlockDiagonalMask.from_seqlens([N] * B, mask)
|
| 147 |
+
|
| 148 |
+
x = xformers.ops.memory_efficient_attention(
|
| 149 |
+
q, k, v, p=self.attn_drop.p, attn_bias=attn_bias
|
| 150 |
+
)
|
| 151 |
+
|
| 152 |
+
x = x.view(B, -1, C)
|
| 153 |
+
x = self.proj(x)
|
| 154 |
+
x = self.proj_drop(x)
|
| 155 |
+
|
| 156 |
+
return x
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
class WindowAttention(Attention_):
|
| 160 |
+
"""Multi-head Attention block with relative position embeddings."""
|
| 161 |
+
|
| 162 |
+
def __init__(
|
| 163 |
+
self,
|
| 164 |
+
dim,
|
| 165 |
+
num_heads=8,
|
| 166 |
+
qkv_bias=True,
|
| 167 |
+
use_rel_pos=False,
|
| 168 |
+
rel_pos_zero_init=True,
|
| 169 |
+
input_size=None,
|
| 170 |
+
**block_kwargs,
|
| 171 |
+
):
|
| 172 |
+
"""
|
| 173 |
+
Args:
|
| 174 |
+
dim (int): Number of input channels.
|
| 175 |
+
num_heads (int): Number of attention heads.
|
| 176 |
+
qkv_bias (bool: If True, add a learnable bias to query, key, value.
|
| 177 |
+
rel_pos (bool): If True, add relative positional embeddings to the attention map.
|
| 178 |
+
rel_pos_zero_init (bool): If True, zero initialize relative positional parameters.
|
| 179 |
+
input_size (int or None): Input resolution for calculating the relative positional
|
| 180 |
+
parameter size.
|
| 181 |
+
"""
|
| 182 |
+
super().__init__(dim, num_heads=num_heads, qkv_bias=qkv_bias, **block_kwargs)
|
| 183 |
+
|
| 184 |
+
self.use_rel_pos = use_rel_pos
|
| 185 |
+
if self.use_rel_pos:
|
| 186 |
+
# initialize relative positional embeddings
|
| 187 |
+
self.rel_pos_h = nn.Parameter(
|
| 188 |
+
torch.zeros(2 * input_size[0] - 1, self.head_dim)
|
| 189 |
+
)
|
| 190 |
+
self.rel_pos_w = nn.Parameter(
|
| 191 |
+
torch.zeros(2 * input_size[1] - 1, self.head_dim)
|
| 192 |
+
)
|
| 193 |
+
|
| 194 |
+
if not rel_pos_zero_init:
|
| 195 |
+
nn.init.trunc_normal_(self.rel_pos_h, std=0.02)
|
| 196 |
+
nn.init.trunc_normal_(self.rel_pos_w, std=0.02)
|
| 197 |
+
|
| 198 |
+
def forward(self, x, mask=None):
|
| 199 |
+
B, N, C = x.shape
|
| 200 |
+
qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads)
|
| 201 |
+
q, k, v = qkv.unbind(2)
|
| 202 |
+
if use_fp32_attention := getattr(self, "fp32_attention", False):
|
| 203 |
+
q, k, v = q.float(), k.float(), v.float()
|
| 204 |
+
|
| 205 |
+
attn_bias = None
|
| 206 |
+
if mask is not None:
|
| 207 |
+
attn_bias = torch.zeros(
|
| 208 |
+
[B * self.num_heads, q.shape[1], k.shape[1]],
|
| 209 |
+
dtype=q.dtype,
|
| 210 |
+
device=q.device,
|
| 211 |
+
)
|
| 212 |
+
attn_bias.masked_fill_(
|
| 213 |
+
mask.squeeze(1).repeat(self.num_heads, 1, 1) == 0, float("-inf")
|
| 214 |
+
)
|
| 215 |
+
|
| 216 |
+
x = xformers.ops.memory_efficient_attention(
|
| 217 |
+
q, k, v, p=self.attn_drop.p, attn_bias=attn_bias
|
| 218 |
+
)
|
| 219 |
+
|
| 220 |
+
x = x.view(B, N, C)
|
| 221 |
+
x = self.proj(x)
|
| 222 |
+
x = self.proj_drop(x)
|
| 223 |
+
return x
|
| 224 |
+
|
| 225 |
+
|
| 226 |
+
#################################################################################
|
| 227 |
+
# AMP attention with fp32 softmax to fix loss NaN problem during training #
|
| 228 |
+
#################################################################################
|
| 229 |
+
class Attention(Attention_):
|
| 230 |
+
def forward(self, x):
|
| 231 |
+
B, N, C = x.shape
|
| 232 |
+
qkv = (
|
| 233 |
+
self.qkv(x)
|
| 234 |
+
.reshape(B, N, 3, self.num_heads, C // self.num_heads)
|
| 235 |
+
.permute(2, 0, 3, 1, 4)
|
| 236 |
+
)
|
| 237 |
+
q, k, v = qkv.unbind(0) # make torchscript happy (cannot use tensor as tuple)
|
| 238 |
+
use_fp32_attention = getattr(self, "fp32_attention", False)
|
| 239 |
+
if use_fp32_attention:
|
| 240 |
+
q, k = q.float(), k.float()
|
| 241 |
+
with torch.cuda.amp.autocast(enabled=not use_fp32_attention):
|
| 242 |
+
attn = (q @ k.transpose(-2, -1)) * self.scale
|
| 243 |
+
attn = attn.softmax(dim=-1)
|
| 244 |
+
|
| 245 |
+
attn = self.attn_drop(attn)
|
| 246 |
+
|
| 247 |
+
x = (attn @ v).transpose(1, 2).reshape(B, N, C)
|
| 248 |
+
x = self.proj(x)
|
| 249 |
+
x = self.proj_drop(x)
|
| 250 |
+
return x
|
| 251 |
+
|
| 252 |
+
|
| 253 |
+
class FinalLayer(nn.Module):
|
| 254 |
+
"""
|
| 255 |
+
The final layer of PixArt.
|
| 256 |
+
"""
|
| 257 |
+
|
| 258 |
+
def __init__(self, hidden_size, patch_size, out_channels):
|
| 259 |
+
super().__init__()
|
| 260 |
+
self.norm_final = nn.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6)
|
| 261 |
+
self.linear = nn.Linear(
|
| 262 |
+
hidden_size, patch_size * patch_size * out_channels, bias=True
|
| 263 |
+
)
|
| 264 |
+
self.adaLN_modulation = nn.Sequential(
|
| 265 |
+
nn.SiLU(), nn.Linear(hidden_size, 2 * hidden_size, bias=True)
|
| 266 |
+
)
|
| 267 |
+
|
| 268 |
+
def forward(self, x, c):
|
| 269 |
+
shift, scale = self.adaLN_modulation(c).chunk(2, dim=1)
|
| 270 |
+
x = modulate(self.norm_final(x), shift, scale)
|
| 271 |
+
x = self.linear(x)
|
| 272 |
+
return x
|
| 273 |
+
|
| 274 |
+
|
| 275 |
+
class T2IFinalLayer(nn.Module):
|
| 276 |
+
"""
|
| 277 |
+
The final layer of PixArt.
|
| 278 |
+
"""
|
| 279 |
+
|
| 280 |
+
def __init__(self, hidden_size, patch_size, out_channels):
|
| 281 |
+
super().__init__()
|
| 282 |
+
self.norm_final = nn.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6)
|
| 283 |
+
self.linear = nn.Linear(
|
| 284 |
+
hidden_size, patch_size[0] * patch_size[1] * out_channels, bias=True
|
| 285 |
+
)
|
| 286 |
+
self.scale_shift_table = nn.Parameter(
|
| 287 |
+
torch.randn(2, hidden_size) / hidden_size**0.5
|
| 288 |
+
)
|
| 289 |
+
self.out_channels = out_channels
|
| 290 |
+
self.initialize_weights()
|
| 291 |
+
|
| 292 |
+
def initialize_weights(self):
|
| 293 |
+
def _basic_init(module):
|
| 294 |
+
if isinstance(module, nn.Linear):
|
| 295 |
+
torch.nn.init.xavier_uniform_(module.weight)
|
| 296 |
+
if module.bias is not None:
|
| 297 |
+
nn.init.constant_(module.bias, 0)
|
| 298 |
+
|
| 299 |
+
self.apply(_basic_init)
|
| 300 |
+
|
| 301 |
+
def forward(self, x, t):
|
| 302 |
+
shift, scale = (self.scale_shift_table[None] + t[:, None]).chunk(2, dim=1)
|
| 303 |
+
x = t2i_modulate(self.norm_final(x), shift, scale)
|
| 304 |
+
x = self.linear(x)
|
| 305 |
+
return x
|
| 306 |
+
|
| 307 |
+
|
| 308 |
+
class MaskFinalLayer(nn.Module):
|
| 309 |
+
"""
|
| 310 |
+
The final layer of PixArt.
|
| 311 |
+
"""
|
| 312 |
+
|
| 313 |
+
def __init__(self, final_hidden_size, c_emb_size, patch_size, out_channels):
|
| 314 |
+
super().__init__()
|
| 315 |
+
self.norm_final = nn.LayerNorm(
|
| 316 |
+
final_hidden_size, elementwise_affine=False, eps=1e-6
|
| 317 |
+
)
|
| 318 |
+
self.linear = nn.Linear(
|
| 319 |
+
final_hidden_size, patch_size * patch_size * out_channels, bias=True
|
| 320 |
+
)
|
| 321 |
+
self.adaLN_modulation = nn.Sequential(
|
| 322 |
+
nn.SiLU(), nn.Linear(c_emb_size, 2 * final_hidden_size, bias=True)
|
| 323 |
+
)
|
| 324 |
+
|
| 325 |
+
def forward(self, x, t):
|
| 326 |
+
shift, scale = self.adaLN_modulation(t).chunk(2, dim=1)
|
| 327 |
+
x = modulate(self.norm_final(x), shift, scale)
|
| 328 |
+
x = self.linear(x)
|
| 329 |
+
return x
|
| 330 |
+
|
| 331 |
+
|
| 332 |
+
class DecoderLayer(nn.Module):
|
| 333 |
+
"""
|
| 334 |
+
The final layer of PixArt.
|
| 335 |
+
"""
|
| 336 |
+
|
| 337 |
+
def __init__(self, hidden_size, decoder_hidden_size):
|
| 338 |
+
super().__init__()
|
| 339 |
+
self.norm_decoder = nn.LayerNorm(
|
| 340 |
+
hidden_size, elementwise_affine=False, eps=1e-6
|
| 341 |
+
)
|
| 342 |
+
self.linear = nn.Linear(hidden_size, decoder_hidden_size, bias=True)
|
| 343 |
+
self.adaLN_modulation = nn.Sequential(
|
| 344 |
+
nn.SiLU(), nn.Linear(hidden_size, 2 * hidden_size, bias=True)
|
| 345 |
+
)
|
| 346 |
+
|
| 347 |
+
def forward(self, x, t):
|
| 348 |
+
shift, scale = self.adaLN_modulation(t).chunk(2, dim=1)
|
| 349 |
+
x = modulate(self.norm_decoder(x), shift, scale)
|
| 350 |
+
x = self.linear(x)
|
| 351 |
+
return x
|
| 352 |
+
|
| 353 |
+
|
| 354 |
+
#################################################################################
|
| 355 |
+
# Embedding Layers for Timesteps and Class Labels #
|
| 356 |
+
#################################################################################
|
| 357 |
+
class TimestepEmbedder(nn.Module):
|
| 358 |
+
"""
|
| 359 |
+
Embeds scalar timesteps into vector representations.
|
| 360 |
+
"""
|
| 361 |
+
|
| 362 |
+
def __init__(self, hidden_size, frequency_embedding_size=256):
|
| 363 |
+
super().__init__()
|
| 364 |
+
self.mlp = nn.Sequential(
|
| 365 |
+
nn.Linear(frequency_embedding_size, hidden_size, bias=True),
|
| 366 |
+
nn.SiLU(),
|
| 367 |
+
nn.Linear(hidden_size, hidden_size, bias=True),
|
| 368 |
+
)
|
| 369 |
+
self.frequency_embedding_size = frequency_embedding_size
|
| 370 |
+
|
| 371 |
+
@staticmethod
|
| 372 |
+
def timestep_embedding(t, dim, max_period=10000):
|
| 373 |
+
"""
|
| 374 |
+
Create sinusoidal timestep embeddings.
|
| 375 |
+
:param t: a 1-D Tensor of N indices, one per batch element.
|
| 376 |
+
These may be fractional.
|
| 377 |
+
:param dim: the dimension of the output.
|
| 378 |
+
:param max_period: controls the minimum frequency of the embeddings.
|
| 379 |
+
:return: an (N, D) Tensor of positional embeddings.
|
| 380 |
+
"""
|
| 381 |
+
# https://github.com/openai/glide-text2im/blob/main/glide_text2im/nn.py
|
| 382 |
+
half = dim // 2
|
| 383 |
+
freqs = torch.exp(
|
| 384 |
+
-math.log(max_period)
|
| 385 |
+
* torch.arange(start=0, end=half, dtype=torch.float32, device=t.device)
|
| 386 |
+
/ half
|
| 387 |
+
)
|
| 388 |
+
args = t[:, None].float() * freqs[None]
|
| 389 |
+
embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1)
|
| 390 |
+
if dim % 2:
|
| 391 |
+
embedding = torch.cat(
|
| 392 |
+
[embedding, torch.zeros_like(embedding[:, :1])], dim=-1
|
| 393 |
+
)
|
| 394 |
+
return embedding
|
| 395 |
+
|
| 396 |
+
def forward(self, t):
|
| 397 |
+
t_freq = self.timestep_embedding(t, self.frequency_embedding_size).to(
|
| 398 |
+
self.dtype
|
| 399 |
+
)
|
| 400 |
+
return self.mlp(t_freq)
|
| 401 |
+
|
| 402 |
+
@property
|
| 403 |
+
def dtype(self):
|
| 404 |
+
|
| 405 |
+
return next(self.parameters()).dtype
|
| 406 |
+
|
| 407 |
+
|
| 408 |
+
class SizeEmbedder(TimestepEmbedder):
|
| 409 |
+
"""
|
| 410 |
+
Embeds scalar timesteps into vector representations.
|
| 411 |
+
"""
|
| 412 |
+
|
| 413 |
+
def __init__(self, hidden_size, frequency_embedding_size=256):
|
| 414 |
+
super().__init__(
|
| 415 |
+
hidden_size=hidden_size, frequency_embedding_size=frequency_embedding_size
|
| 416 |
+
)
|
| 417 |
+
self.mlp = nn.Sequential(
|
| 418 |
+
nn.Linear(frequency_embedding_size, hidden_size, bias=True),
|
| 419 |
+
nn.SiLU(),
|
| 420 |
+
nn.Linear(hidden_size, hidden_size, bias=True),
|
| 421 |
+
)
|
| 422 |
+
self.frequency_embedding_size = frequency_embedding_size
|
| 423 |
+
self.outdim = hidden_size
|
| 424 |
+
|
| 425 |
+
def forward(self, s, bs):
|
| 426 |
+
if s.ndim == 1:
|
| 427 |
+
s = s[:, None]
|
| 428 |
+
assert s.ndim == 2
|
| 429 |
+
if s.shape[0] != bs:
|
| 430 |
+
s = s.repeat(bs // s.shape[0], 1)
|
| 431 |
+
assert s.shape[0] == bs
|
| 432 |
+
b, dims = s.shape[0], s.shape[1]
|
| 433 |
+
s = rearrange(s, "b d -> (b d)")
|
| 434 |
+
s_freq = self.timestep_embedding(s, self.frequency_embedding_size).to(
|
| 435 |
+
self.dtype
|
| 436 |
+
)
|
| 437 |
+
s_emb = self.mlp(s_freq)
|
| 438 |
+
s_emb = rearrange(s_emb, "(b d) d2 -> b (d d2)", b=b, d=dims, d2=self.outdim)
|
| 439 |
+
return s_emb
|
| 440 |
+
|
| 441 |
+
@property
|
| 442 |
+
def dtype(self):
|
| 443 |
+
|
| 444 |
+
return next(self.parameters()).dtype
|
| 445 |
+
|
| 446 |
+
|
| 447 |
+
class LabelEmbedder(nn.Module):
|
| 448 |
+
"""
|
| 449 |
+
Embeds class labels into vector representations. Also handles label dropout for classifier-free guidance.
|
| 450 |
+
"""
|
| 451 |
+
|
| 452 |
+
def __init__(self, num_classes, hidden_size, dropout_prob):
|
| 453 |
+
super().__init__()
|
| 454 |
+
use_cfg_embedding = dropout_prob > 0
|
| 455 |
+
self.embedding_table = nn.Embedding(
|
| 456 |
+
num_classes + use_cfg_embedding, hidden_size
|
| 457 |
+
)
|
| 458 |
+
self.num_classes = num_classes
|
| 459 |
+
self.dropout_prob = dropout_prob
|
| 460 |
+
|
| 461 |
+
def token_drop(self, labels, force_drop_ids=None):
|
| 462 |
+
"""
|
| 463 |
+
Drops labels to enable classifier-free guidance.
|
| 464 |
+
"""
|
| 465 |
+
if force_drop_ids is None:
|
| 466 |
+
drop_ids = torch.rand(labels.shape[0]).cuda() < self.dropout_prob
|
| 467 |
+
else:
|
| 468 |
+
drop_ids = force_drop_ids == 1
|
| 469 |
+
labels = torch.where(drop_ids, self.num_classes, labels)
|
| 470 |
+
return labels
|
| 471 |
+
|
| 472 |
+
def forward(self, labels, train, force_drop_ids=None):
|
| 473 |
+
use_dropout = self.dropout_prob > 0
|
| 474 |
+
if (train and use_dropout) or (force_drop_ids is not None):
|
| 475 |
+
labels = self.token_drop(labels, force_drop_ids)
|
| 476 |
+
return self.embedding_table(labels)
|
| 477 |
+
|
| 478 |
+
|
| 479 |
+
class CaptionEmbedder(nn.Module):
|
| 480 |
+
"""
|
| 481 |
+
Embeds class labels into vector representations. Also handles label dropout for classifier-free guidance.
|
| 482 |
+
"""
|
| 483 |
+
|
| 484 |
+
def __init__(
|
| 485 |
+
self,
|
| 486 |
+
in_channels,
|
| 487 |
+
hidden_size,
|
| 488 |
+
uncond_prob,
|
| 489 |
+
act_layer=nn.GELU(approximate="tanh"),
|
| 490 |
+
token_num=120,
|
| 491 |
+
):
|
| 492 |
+
super().__init__()
|
| 493 |
+
self.y_proj = Mlp(
|
| 494 |
+
in_features=in_channels,
|
| 495 |
+
hidden_features=hidden_size,
|
| 496 |
+
out_features=hidden_size,
|
| 497 |
+
act_layer=act_layer,
|
| 498 |
+
drop=0,
|
| 499 |
+
)
|
| 500 |
+
self.register_buffer(
|
| 501 |
+
"y_embedding",
|
| 502 |
+
nn.Parameter(torch.randn(token_num, in_channels) / in_channels**0.5),
|
| 503 |
+
)
|
| 504 |
+
self.uncond_prob = uncond_prob
|
| 505 |
+
|
| 506 |
+
def token_drop(self, caption, force_drop_ids=None):
|
| 507 |
+
"""
|
| 508 |
+
Drops labels to enable classifier-free guidance.
|
| 509 |
+
"""
|
| 510 |
+
if force_drop_ids is None:
|
| 511 |
+
drop_ids = torch.rand(caption.shape[0]).cuda() < self.uncond_prob
|
| 512 |
+
else:
|
| 513 |
+
drop_ids = force_drop_ids == 1
|
| 514 |
+
caption = torch.where(drop_ids[:, None, None, None], self.y_embedding, caption)
|
| 515 |
+
return caption
|
| 516 |
+
|
| 517 |
+
def forward(self, caption, train, force_drop_ids=None):
|
| 518 |
+
if train:
|
| 519 |
+
assert caption.shape[2:] == self.y_embedding.shape
|
| 520 |
+
use_dropout = self.uncond_prob > 0
|
| 521 |
+
if (train and use_dropout) or (force_drop_ids is not None):
|
| 522 |
+
caption = self.token_drop(caption, force_drop_ids)
|
| 523 |
+
caption = self.y_proj(caption)
|
| 524 |
+
return caption
|
| 525 |
+
|
| 526 |
+
|
| 527 |
+
class CaptionEmbedderDoubleBr(nn.Module):
|
| 528 |
+
"""
|
| 529 |
+
Embeds class labels into vector representations. Also handles label dropout for classifier-free guidance.
|
| 530 |
+
"""
|
| 531 |
+
|
| 532 |
+
def __init__(
|
| 533 |
+
self,
|
| 534 |
+
in_channels,
|
| 535 |
+
hidden_size,
|
| 536 |
+
uncond_prob,
|
| 537 |
+
act_layer=nn.GELU(approximate="tanh"),
|
| 538 |
+
token_num=120,
|
| 539 |
+
):
|
| 540 |
+
super().__init__()
|
| 541 |
+
self.proj = Mlp(
|
| 542 |
+
in_features=in_channels,
|
| 543 |
+
hidden_features=hidden_size,
|
| 544 |
+
out_features=hidden_size,
|
| 545 |
+
act_layer=act_layer,
|
| 546 |
+
drop=0,
|
| 547 |
+
)
|
| 548 |
+
self.embedding = nn.Parameter(torch.randn(1, in_channels) / 10**0.5)
|
| 549 |
+
self.y_embedding = nn.Parameter(torch.randn(token_num, in_channels) / 10**0.5)
|
| 550 |
+
self.uncond_prob = uncond_prob
|
| 551 |
+
|
| 552 |
+
def token_drop(self, global_caption, caption, force_drop_ids=None):
|
| 553 |
+
"""
|
| 554 |
+
Drops labels to enable classifier-free guidance.
|
| 555 |
+
"""
|
| 556 |
+
if force_drop_ids is None:
|
| 557 |
+
drop_ids = torch.rand(global_caption.shape[0]).cuda() < self.uncond_prob
|
| 558 |
+
else:
|
| 559 |
+
drop_ids = force_drop_ids == 1
|
| 560 |
+
global_caption = torch.where(drop_ids[:, None], self.embedding, global_caption)
|
| 561 |
+
caption = torch.where(drop_ids[:, None, None, None], self.y_embedding, caption)
|
| 562 |
+
return global_caption, caption
|
| 563 |
+
|
| 564 |
+
def forward(self, caption, train, force_drop_ids=None):
|
| 565 |
+
assert caption.shape[2:] == self.y_embedding.shape
|
| 566 |
+
global_caption = caption.mean(dim=2).squeeze()
|
| 567 |
+
use_dropout = self.uncond_prob > 0
|
| 568 |
+
if (train and use_dropout) or (force_drop_ids is not None):
|
| 569 |
+
global_caption, caption = self.token_drop(
|
| 570 |
+
global_caption, caption, force_drop_ids
|
| 571 |
+
)
|
| 572 |
+
y_embed = self.proj(global_caption)
|
| 573 |
+
return y_embed, caption
|
ldm/modules/diffusionmodules/__init__.py
ADDED
|
File without changes
|
ldm/modules/diffusionmodules/attention.py
ADDED
|
@@ -0,0 +1,336 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from inspect import isfunction
|
| 2 |
+
import math
|
| 3 |
+
import torch
|
| 4 |
+
import torch.nn.functional as F
|
| 5 |
+
from torch import nn, einsum
|
| 6 |
+
from einops import rearrange, repeat
|
| 7 |
+
|
| 8 |
+
from ldm.utils.diffusion_util import checkpoint
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def exists(val):
|
| 12 |
+
return val is not None
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def uniq(arr):
|
| 16 |
+
return {el: True for el in arr}.keys()
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def default(val, d):
|
| 20 |
+
if exists(val):
|
| 21 |
+
return val
|
| 22 |
+
return d() if isfunction(d) else d
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def max_neg_value(t):
|
| 26 |
+
return -torch.finfo(t.dtype).max
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def init_(tensor):
|
| 30 |
+
dim = tensor.shape[-1]
|
| 31 |
+
std = 1 / math.sqrt(dim)
|
| 32 |
+
tensor.uniform_(-std, std)
|
| 33 |
+
return tensor
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
# feedforward
|
| 37 |
+
class GEGLU(nn.Module):
|
| 38 |
+
def __init__(self, dim_in, dim_out):
|
| 39 |
+
super().__init__()
|
| 40 |
+
self.proj = nn.Linear(dim_in, dim_out * 2)
|
| 41 |
+
|
| 42 |
+
def forward(self, x):
|
| 43 |
+
x, gate = self.proj(x).chunk(2, dim=-1)
|
| 44 |
+
return x * F.gelu(gate)
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
class FeedForward(nn.Module):
|
| 48 |
+
def __init__(self, dim, dim_out=None, mult=4, glu=False, dropout=0.0):
|
| 49 |
+
super().__init__()
|
| 50 |
+
inner_dim = int(dim * mult)
|
| 51 |
+
dim_out = default(dim_out, dim)
|
| 52 |
+
project_in = (
|
| 53 |
+
nn.Sequential(nn.Linear(dim, inner_dim), nn.GELU())
|
| 54 |
+
if not glu
|
| 55 |
+
else GEGLU(dim, inner_dim)
|
| 56 |
+
)
|
| 57 |
+
|
| 58 |
+
self.net = nn.Sequential(
|
| 59 |
+
project_in, nn.Dropout(dropout), nn.Linear(inner_dim, dim_out)
|
| 60 |
+
)
|
| 61 |
+
|
| 62 |
+
def forward(self, x):
|
| 63 |
+
return self.net(x)
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
def zero_module(module):
|
| 67 |
+
"""
|
| 68 |
+
Zero out the parameters of a module and return it.
|
| 69 |
+
"""
|
| 70 |
+
for p in module.parameters():
|
| 71 |
+
p.detach().zero_()
|
| 72 |
+
return module
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
def Normalize(in_channels):
|
| 76 |
+
return torch.nn.GroupNorm(
|
| 77 |
+
num_groups=32, num_channels=in_channels, eps=1e-6, affine=True
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
class LinearAttention(nn.Module):
|
| 82 |
+
def __init__(self, dim, heads=4, dim_head=32):
|
| 83 |
+
super().__init__()
|
| 84 |
+
self.heads = heads
|
| 85 |
+
hidden_dim = dim_head * heads
|
| 86 |
+
self.to_qkv = nn.Conv2d(dim, hidden_dim * 3, 1, bias=False)
|
| 87 |
+
self.to_out = nn.Conv2d(hidden_dim, dim, 1)
|
| 88 |
+
|
| 89 |
+
def forward(self, x):
|
| 90 |
+
b, c, h, w = x.shape
|
| 91 |
+
qkv = self.to_qkv(x)
|
| 92 |
+
q, k, v = rearrange(
|
| 93 |
+
qkv, "b (qkv heads c) h w -> qkv b heads c (h w)", heads=self.heads, qkv=3
|
| 94 |
+
)
|
| 95 |
+
k = k.softmax(dim=-1)
|
| 96 |
+
context = torch.einsum("bhdn,bhen->bhde", k, v)
|
| 97 |
+
out = torch.einsum("bhde,bhdn->bhen", context, q)
|
| 98 |
+
out = rearrange(
|
| 99 |
+
out, "b heads c (h w) -> b (heads c) h w", heads=self.heads, h=h, w=w
|
| 100 |
+
)
|
| 101 |
+
return self.to_out(out)
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
class SpatialSelfAttention(nn.Module):
|
| 105 |
+
def __init__(self, in_channels):
|
| 106 |
+
super().__init__()
|
| 107 |
+
self.in_channels = in_channels
|
| 108 |
+
|
| 109 |
+
self.norm = Normalize(in_channels)
|
| 110 |
+
self.q = torch.nn.Conv2d(
|
| 111 |
+
in_channels, in_channels, kernel_size=1, stride=1, padding=0
|
| 112 |
+
)
|
| 113 |
+
self.k = torch.nn.Conv2d(
|
| 114 |
+
in_channels, in_channels, kernel_size=1, stride=1, padding=0
|
| 115 |
+
)
|
| 116 |
+
self.v = torch.nn.Conv2d(
|
| 117 |
+
in_channels, in_channels, kernel_size=1, stride=1, padding=0
|
| 118 |
+
)
|
| 119 |
+
self.proj_out = torch.nn.Conv2d(
|
| 120 |
+
in_channels, in_channels, kernel_size=1, stride=1, padding=0
|
| 121 |
+
)
|
| 122 |
+
|
| 123 |
+
def forward(self, x):
|
| 124 |
+
h_ = x
|
| 125 |
+
h_ = self.norm(h_)
|
| 126 |
+
q = self.q(h_)
|
| 127 |
+
k = self.k(h_)
|
| 128 |
+
v = self.v(h_)
|
| 129 |
+
|
| 130 |
+
# compute attention
|
| 131 |
+
b, c, h, w = q.shape
|
| 132 |
+
q = rearrange(q, "b c h w -> b (h w) c")
|
| 133 |
+
k = rearrange(k, "b c h w -> b c (h w)")
|
| 134 |
+
w_ = torch.einsum("bij,bjk->bik", q, k)
|
| 135 |
+
|
| 136 |
+
w_ = w_ * (int(c) ** (-0.5))
|
| 137 |
+
w_ = torch.nn.functional.softmax(w_, dim=2)
|
| 138 |
+
|
| 139 |
+
# attend to values
|
| 140 |
+
v = rearrange(v, "b c h w -> b c (h w)")
|
| 141 |
+
w_ = rearrange(w_, "b i j -> b j i")
|
| 142 |
+
h_ = torch.einsum("bij,bjk->bik", v, w_)
|
| 143 |
+
h_ = rearrange(h_, "b c (h w) -> b c h w", h=h)
|
| 144 |
+
h_ = self.proj_out(h_)
|
| 145 |
+
|
| 146 |
+
return x + h_
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
class CrossAttention(nn.Module):
|
| 150 |
+
def __init__(self, query_dim, context_dim=None, heads=8, dim_head=64, dropout=0.0):
|
| 151 |
+
super().__init__()
|
| 152 |
+
inner_dim = dim_head * heads
|
| 153 |
+
self.id = inner_dim
|
| 154 |
+
context_dim = default(context_dim, query_dim)
|
| 155 |
+
self.context_dim = context_dim
|
| 156 |
+
self.qdim = query_dim
|
| 157 |
+
self.scale = dim_head**-0.5
|
| 158 |
+
self.heads = heads
|
| 159 |
+
|
| 160 |
+
self.to_q = nn.Linear(query_dim, inner_dim, bias=False)
|
| 161 |
+
self.to_k = nn.Linear(context_dim, inner_dim, bias=False)
|
| 162 |
+
self.to_v = nn.Linear(context_dim, inner_dim, bias=False)
|
| 163 |
+
|
| 164 |
+
self.to_out = nn.Sequential(
|
| 165 |
+
nn.Linear(inner_dim, query_dim), nn.Dropout(dropout)
|
| 166 |
+
)
|
| 167 |
+
|
| 168 |
+
def forward(self, x, context=None, mask=None):
|
| 169 |
+
h = self.heads
|
| 170 |
+
q = self.to_q(x)
|
| 171 |
+
context = default(context, x)
|
| 172 |
+
|
| 173 |
+
k = self.to_k(context)
|
| 174 |
+
v = self.to_v(context)
|
| 175 |
+
|
| 176 |
+
q, k, v = map(lambda t: rearrange(t, "b n (h d) -> (b h) n d", h=h), (q, k, v))
|
| 177 |
+
|
| 178 |
+
sim = einsum("b i d, b j d -> b i j", q, k) * self.scale
|
| 179 |
+
|
| 180 |
+
if exists(mask):
|
| 181 |
+
mask = rearrange(mask, "b ... -> b (...)")
|
| 182 |
+
max_neg_value = -torch.finfo(sim.dtype).max
|
| 183 |
+
mask = repeat(mask, "b j -> (b h) () j", h=h)
|
| 184 |
+
sim.masked_fill_(~(mask == 1), max_neg_value)
|
| 185 |
+
|
| 186 |
+
# attention, what we cannot get enough of
|
| 187 |
+
attn = sim.softmax(dim=-1)
|
| 188 |
+
|
| 189 |
+
out = einsum("b i j, b j d -> b i d", attn, v)
|
| 190 |
+
out = rearrange(out, "(b h) n d -> b n (h d)", h=h)
|
| 191 |
+
return self.to_out(out)
|
| 192 |
+
|
| 193 |
+
|
| 194 |
+
class CrossAttention_1D(nn.Module):
|
| 195 |
+
def __init__(self, query_dim, context_dim=None, heads=8, dim_head=64, dropout=0.0):
|
| 196 |
+
super().__init__()
|
| 197 |
+
inner_dim = dim_head * heads
|
| 198 |
+
self.id = inner_dim
|
| 199 |
+
context_dim = default(context_dim, query_dim)
|
| 200 |
+
self.context_dim = context_dim
|
| 201 |
+
self.qdim = query_dim
|
| 202 |
+
self.scale = dim_head**-0.5
|
| 203 |
+
self.heads = heads
|
| 204 |
+
|
| 205 |
+
self.to_q = nn.Linear(query_dim, inner_dim, bias=False)
|
| 206 |
+
self.to_k = nn.Linear(context_dim, inner_dim, bias=False)
|
| 207 |
+
self.to_v = nn.Linear(context_dim, inner_dim, bias=False)
|
| 208 |
+
|
| 209 |
+
self.to_out = nn.Sequential(
|
| 210 |
+
nn.Linear(inner_dim, query_dim), nn.Dropout(dropout)
|
| 211 |
+
)
|
| 212 |
+
|
| 213 |
+
def forward(self, x, context=None, mask=None):
|
| 214 |
+
h = self.heads
|
| 215 |
+
q = self.to_q(x)
|
| 216 |
+
context = default(context, x)
|
| 217 |
+
|
| 218 |
+
k = self.to_k(context)
|
| 219 |
+
v = self.to_v(context)
|
| 220 |
+
|
| 221 |
+
q, k, v = map(lambda t: rearrange(t, "b n (h d) -> (b h) n d", h=h), (q, k, v))
|
| 222 |
+
|
| 223 |
+
sim = einsum("b i d, b j d -> b i j", q, k) * self.scale
|
| 224 |
+
|
| 225 |
+
if exists(mask):
|
| 226 |
+
mask = rearrange(mask, "b ... -> b (...)")
|
| 227 |
+
max_neg_value = -torch.finfo(sim.dtype).max
|
| 228 |
+
mask = repeat(mask, "b j -> (b h) () j", h=h)
|
| 229 |
+
sim.masked_fill_(~(mask == 1), max_neg_value)
|
| 230 |
+
|
| 231 |
+
# attention, what we cannot get enough of
|
| 232 |
+
attn = sim.softmax(dim=-1)
|
| 233 |
+
|
| 234 |
+
out = einsum("b i j, b j d -> b i d", attn, v)
|
| 235 |
+
out = rearrange(out, "(b h) n d -> b n (h d)", h=h)
|
| 236 |
+
return self.to_out(out)
|
| 237 |
+
|
| 238 |
+
|
| 239 |
+
class BasicTransformerBlock(nn.Module):
|
| 240 |
+
def __init__(
|
| 241 |
+
self,
|
| 242 |
+
dim,
|
| 243 |
+
n_heads,
|
| 244 |
+
d_head,
|
| 245 |
+
dropout=0.0,
|
| 246 |
+
context_dim=None,
|
| 247 |
+
gated_ff=True,
|
| 248 |
+
checkpoint=True,
|
| 249 |
+
):
|
| 250 |
+
super().__init__()
|
| 251 |
+
self.attn1 = CrossAttention(
|
| 252 |
+
query_dim=dim, heads=n_heads, dim_head=d_head, dropout=dropout
|
| 253 |
+
) # is a self-attention
|
| 254 |
+
self.ff = FeedForward(dim, dropout=dropout, glu=gated_ff)
|
| 255 |
+
self.attn2 = CrossAttention(
|
| 256 |
+
query_dim=dim,
|
| 257 |
+
context_dim=context_dim,
|
| 258 |
+
heads=n_heads,
|
| 259 |
+
dim_head=d_head,
|
| 260 |
+
dropout=dropout,
|
| 261 |
+
) # is self-attn if context is none
|
| 262 |
+
self.norm1 = nn.LayerNorm(dim)
|
| 263 |
+
self.norm2 = nn.LayerNorm(dim)
|
| 264 |
+
self.norm3 = nn.LayerNorm(dim)
|
| 265 |
+
self.checkpoint = checkpoint
|
| 266 |
+
|
| 267 |
+
def forward(self, x, context=None, mask=None):
|
| 268 |
+
if context is None:
|
| 269 |
+
return checkpoint(self._forward, (x,), self.parameters(), self.checkpoint)
|
| 270 |
+
else:
|
| 271 |
+
return checkpoint(
|
| 272 |
+
self._forward, (x, context, mask), self.parameters(), self.checkpoint
|
| 273 |
+
)
|
| 274 |
+
|
| 275 |
+
def _forward(self, x, context=None, mask=None):
|
| 276 |
+
x = self.attn1(self.norm1(x)) + x
|
| 277 |
+
x = self.attn2(self.norm2(x), context=context, mask=mask) + x
|
| 278 |
+
x = self.ff(self.norm3(x)) + x
|
| 279 |
+
return x
|
| 280 |
+
|
| 281 |
+
|
| 282 |
+
class SpatialTransformer(nn.Module):
|
| 283 |
+
"""
|
| 284 |
+
Transformer block for image-like data.
|
| 285 |
+
First, project the input (aka embedding)
|
| 286 |
+
and reshape to b, t, d.
|
| 287 |
+
Then apply standard transformer action.
|
| 288 |
+
Finally, reshape to image
|
| 289 |
+
"""
|
| 290 |
+
|
| 291 |
+
def __init__(
|
| 292 |
+
self,
|
| 293 |
+
in_channels,
|
| 294 |
+
n_heads,
|
| 295 |
+
d_head,
|
| 296 |
+
depth=1,
|
| 297 |
+
dropout=0.0,
|
| 298 |
+
context_dim=None,
|
| 299 |
+
):
|
| 300 |
+
super().__init__()
|
| 301 |
+
|
| 302 |
+
context_dim = context_dim
|
| 303 |
+
|
| 304 |
+
self.in_channels = in_channels
|
| 305 |
+
inner_dim = n_heads * d_head
|
| 306 |
+
self.norm = Normalize(in_channels)
|
| 307 |
+
|
| 308 |
+
self.proj_in = nn.Conv2d(
|
| 309 |
+
in_channels, inner_dim, kernel_size=1, stride=1, padding=0
|
| 310 |
+
)
|
| 311 |
+
|
| 312 |
+
self.transformer_blocks = nn.ModuleList(
|
| 313 |
+
[
|
| 314 |
+
BasicTransformerBlock(
|
| 315 |
+
inner_dim, n_heads, d_head, dropout=dropout, context_dim=context_dim
|
| 316 |
+
)
|
| 317 |
+
for d in range(depth)
|
| 318 |
+
]
|
| 319 |
+
)
|
| 320 |
+
|
| 321 |
+
self.proj_out = zero_module(
|
| 322 |
+
nn.Conv2d(inner_dim, in_channels, kernel_size=1, stride=1, padding=0)
|
| 323 |
+
)
|
| 324 |
+
|
| 325 |
+
def forward(self, x, context=None, mask=None):
|
| 326 |
+
# note: if no context is given, cross-attention defaults to self-attention
|
| 327 |
+
b, c, h, w = x.shape
|
| 328 |
+
x_in = x
|
| 329 |
+
x = self.norm(x)
|
| 330 |
+
x = self.proj_in(x)
|
| 331 |
+
x = rearrange(x, "b c h w -> b (h w) c")
|
| 332 |
+
for block in self.transformer_blocks:
|
| 333 |
+
x = block(x, context=context, mask=mask)
|
| 334 |
+
x = rearrange(x, "b (h w) c -> b c h w", h=h, w=w)
|
| 335 |
+
x = self.proj_out(x)
|
| 336 |
+
return x + x_in
|
ldm/modules/diffusionmodules/distributions.py
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
import numpy as np
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
class AbstractDistribution:
|
| 6 |
+
def sample(self):
|
| 7 |
+
raise NotImplementedError()
|
| 8 |
+
|
| 9 |
+
def mode(self):
|
| 10 |
+
raise NotImplementedError()
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
class DiracDistribution(AbstractDistribution):
|
| 14 |
+
def __init__(self, value):
|
| 15 |
+
self.value = value
|
| 16 |
+
|
| 17 |
+
def sample(self):
|
| 18 |
+
return self.value
|
| 19 |
+
|
| 20 |
+
def mode(self):
|
| 21 |
+
return self.value
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
class DiagonalGaussianDistribution(object):
|
| 25 |
+
def __init__(self, parameters, deterministic=False):
|
| 26 |
+
self.parameters = parameters
|
| 27 |
+
self.mean, self.logvar = torch.chunk(parameters, 2, dim=1)
|
| 28 |
+
self.logvar = torch.clamp(self.logvar, -30.0, 20.0)
|
| 29 |
+
self.deterministic = deterministic
|
| 30 |
+
self.std = torch.exp(0.5 * self.logvar)
|
| 31 |
+
self.var = torch.exp(self.logvar)
|
| 32 |
+
if self.deterministic:
|
| 33 |
+
self.var = self.std = torch.zeros_like(self.mean).to(
|
| 34 |
+
device=self.parameters.device
|
| 35 |
+
)
|
| 36 |
+
|
| 37 |
+
def sample(self):
|
| 38 |
+
x = self.mean + self.std * torch.randn(self.mean.shape).to(
|
| 39 |
+
device=self.parameters.device
|
| 40 |
+
)
|
| 41 |
+
return x
|
| 42 |
+
|
| 43 |
+
def kl(self, other=None):
|
| 44 |
+
if self.deterministic:
|
| 45 |
+
return torch.Tensor([0.0])
|
| 46 |
+
else:
|
| 47 |
+
if other is None:
|
| 48 |
+
return 0.5 * torch.mean(
|
| 49 |
+
torch.pow(self.mean, 2) + self.var - 1.0 - self.logvar,
|
| 50 |
+
dim=[1, 2, 3],
|
| 51 |
+
)
|
| 52 |
+
else:
|
| 53 |
+
return 0.5 * torch.mean(
|
| 54 |
+
torch.pow(self.mean - other.mean, 2) / other.var
|
| 55 |
+
+ self.var / other.var
|
| 56 |
+
- 1.0
|
| 57 |
+
- self.logvar
|
| 58 |
+
+ other.logvar,
|
| 59 |
+
dim=[1, 2, 3],
|
| 60 |
+
)
|
| 61 |
+
|
| 62 |
+
def nll(self, sample, dims=[1, 2, 3]):
|
| 63 |
+
if self.deterministic:
|
| 64 |
+
return torch.Tensor([0.0])
|
| 65 |
+
logtwopi = np.log(2.0 * np.pi)
|
| 66 |
+
return 0.5 * torch.sum(
|
| 67 |
+
logtwopi + self.logvar + torch.pow(sample - self.mean, 2) / self.var,
|
| 68 |
+
dim=dims,
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
def mode(self):
|
| 72 |
+
return self.mean
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
def normal_kl(mean1, logvar1, mean2, logvar2):
|
| 76 |
+
"""
|
| 77 |
+
source: https://github.com/openai/guided-diffusion/blob/27c20a8fab9cb472df5d6bdd6c8d11c8f430b924/guided_diffusion/losses.py#L12
|
| 78 |
+
Compute the KL divergence between two gaussians.
|
| 79 |
+
Shapes are automatically broadcasted, so batches can be compared to
|
| 80 |
+
scalars, among other use cases.
|
| 81 |
+
"""
|
| 82 |
+
tensor = None
|
| 83 |
+
for obj in (mean1, logvar1, mean2, logvar2):
|
| 84 |
+
if isinstance(obj, torch.Tensor):
|
| 85 |
+
tensor = obj
|
| 86 |
+
break
|
| 87 |
+
assert tensor is not None, "at least one argument must be a Tensor"
|
| 88 |
+
|
| 89 |
+
# Force variances to be Tensors. Broadcasting helps convert scalars to
|
| 90 |
+
# Tensors, but it does not work for torch.exp().
|
| 91 |
+
logvar1, logvar2 = [
|
| 92 |
+
x if isinstance(x, torch.Tensor) else torch.tensor(x).to(tensor)
|
| 93 |
+
for x in (logvar1, logvar2)
|
| 94 |
+
]
|
| 95 |
+
|
| 96 |
+
return 0.5 * (
|
| 97 |
+
-1.0
|
| 98 |
+
+ logvar2
|
| 99 |
+
- logvar1
|
| 100 |
+
+ torch.exp(logvar1 - logvar2)
|
| 101 |
+
+ ((mean1 - mean2) ** 2) * torch.exp(-logvar2)
|
| 102 |
+
)
|
ldm/modules/diffusionmodules/utils.py
ADDED
|
@@ -0,0 +1,582 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import sys
|
| 3 |
+
import torch.nn as nn
|
| 4 |
+
from torch.utils.checkpoint import checkpoint, checkpoint_sequential
|
| 5 |
+
import torch.nn.functional as F
|
| 6 |
+
import torch
|
| 7 |
+
import torch.distributed as dist
|
| 8 |
+
import re
|
| 9 |
+
import math
|
| 10 |
+
from collections.abc import Iterable
|
| 11 |
+
from itertools import repeat
|
| 12 |
+
from torchvision import transforms as T
|
| 13 |
+
import random
|
| 14 |
+
from PIL import Image
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def _ntuple(n):
|
| 18 |
+
def parse(x):
|
| 19 |
+
if isinstance(x, Iterable) and not isinstance(x, str):
|
| 20 |
+
return x
|
| 21 |
+
return tuple(repeat(x, n))
|
| 22 |
+
|
| 23 |
+
return parse
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
to_1tuple = _ntuple(1)
|
| 27 |
+
to_2tuple = _ntuple(2)
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def set_grad_checkpoint(model, use_fp32_attention=False, gc_step=1):
|
| 31 |
+
assert isinstance(model, nn.Module)
|
| 32 |
+
|
| 33 |
+
def set_attr(module):
|
| 34 |
+
module.grad_checkpointing = True
|
| 35 |
+
module.fp32_attention = use_fp32_attention
|
| 36 |
+
module.grad_checkpointing_step = gc_step
|
| 37 |
+
|
| 38 |
+
model.apply(set_attr)
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def auto_grad_checkpoint(module, *args, **kwargs):
|
| 42 |
+
if getattr(module, "grad_checkpointing", False):
|
| 43 |
+
if not isinstance(module, Iterable):
|
| 44 |
+
return checkpoint(module, *args, **kwargs)
|
| 45 |
+
gc_step = module[0].grad_checkpointing_step
|
| 46 |
+
return checkpoint_sequential(module, gc_step, *args, **kwargs)
|
| 47 |
+
return module(*args, **kwargs)
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def checkpoint_sequential(functions, step, input, *args, **kwargs):
|
| 51 |
+
|
| 52 |
+
# Hack for keyword-only parameter in a python 2.7-compliant way
|
| 53 |
+
preserve = kwargs.pop("preserve_rng_state", True)
|
| 54 |
+
if kwargs:
|
| 55 |
+
raise ValueError("Unexpected keyword arguments: " + ",".join(kwargs))
|
| 56 |
+
|
| 57 |
+
def run_function(start, end, functions):
|
| 58 |
+
def forward(input):
|
| 59 |
+
for j in range(start, end + 1):
|
| 60 |
+
input = functions[j](input, *args)
|
| 61 |
+
return input
|
| 62 |
+
|
| 63 |
+
return forward
|
| 64 |
+
|
| 65 |
+
if isinstance(functions, torch.nn.Sequential):
|
| 66 |
+
functions = list(functions.children())
|
| 67 |
+
|
| 68 |
+
# the last chunk has to be non-volatile
|
| 69 |
+
end = -1
|
| 70 |
+
segment = len(functions) // step
|
| 71 |
+
for start in range(0, step * (segment - 1), step):
|
| 72 |
+
end = start + step - 1
|
| 73 |
+
input = checkpoint(
|
| 74 |
+
run_function(start, end, functions), input, preserve_rng_state=preserve
|
| 75 |
+
)
|
| 76 |
+
return run_function(end + 1, len(functions) - 1, functions)(input)
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
def window_partition(x, window_size):
|
| 80 |
+
"""
|
| 81 |
+
Partition into non-overlapping windows with padding if needed.
|
| 82 |
+
Args:
|
| 83 |
+
x (tensor): input tokens with [B, H, W, C].
|
| 84 |
+
window_size (int): window size.
|
| 85 |
+
|
| 86 |
+
Returns:
|
| 87 |
+
windows: windows after partition with [B * num_windows, window_size, window_size, C].
|
| 88 |
+
(Hp, Wp): padded height and width before partition
|
| 89 |
+
"""
|
| 90 |
+
B, H, W, C = x.shape
|
| 91 |
+
|
| 92 |
+
pad_h = (window_size - H % window_size) % window_size
|
| 93 |
+
pad_w = (window_size - W % window_size) % window_size
|
| 94 |
+
if pad_h > 0 or pad_w > 0:
|
| 95 |
+
x = F.pad(x, (0, 0, 0, pad_w, 0, pad_h))
|
| 96 |
+
Hp, Wp = H + pad_h, W + pad_w
|
| 97 |
+
|
| 98 |
+
x = x.view(B, Hp // window_size, window_size, Wp // window_size, window_size, C)
|
| 99 |
+
windows = (
|
| 100 |
+
x.permute(0, 1, 3, 2, 4, 5).contiguous().view(-1, window_size, window_size, C)
|
| 101 |
+
)
|
| 102 |
+
return windows, (Hp, Wp)
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
def window_unpartition(windows, window_size, pad_hw, hw):
|
| 106 |
+
"""
|
| 107 |
+
Window unpartition into original sequences and removing padding.
|
| 108 |
+
Args:
|
| 109 |
+
x (tensor): input tokens with [B * num_windows, window_size, window_size, C].
|
| 110 |
+
window_size (int): window size.
|
| 111 |
+
pad_hw (Tuple): padded height and width (Hp, Wp).
|
| 112 |
+
hw (Tuple): original height and width (H, W) before padding.
|
| 113 |
+
|
| 114 |
+
Returns:
|
| 115 |
+
x: unpartitioned sequences with [B, H, W, C].
|
| 116 |
+
"""
|
| 117 |
+
Hp, Wp = pad_hw
|
| 118 |
+
H, W = hw
|
| 119 |
+
B = windows.shape[0] // (Hp * Wp // window_size // window_size)
|
| 120 |
+
x = windows.view(
|
| 121 |
+
B, Hp // window_size, Wp // window_size, window_size, window_size, -1
|
| 122 |
+
)
|
| 123 |
+
x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, Hp, Wp, -1)
|
| 124 |
+
|
| 125 |
+
if Hp > H or Wp > W:
|
| 126 |
+
x = x[:, :H, :W, :].contiguous()
|
| 127 |
+
return x
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
def get_rel_pos(q_size, k_size, rel_pos):
|
| 131 |
+
"""
|
| 132 |
+
Get relative positional embeddings according to the relative positions of
|
| 133 |
+
query and key sizes.
|
| 134 |
+
Args:
|
| 135 |
+
q_size (int): size of query q.
|
| 136 |
+
k_size (int): size of key k.
|
| 137 |
+
rel_pos (Tensor): relative position embeddings (L, C).
|
| 138 |
+
|
| 139 |
+
Returns:
|
| 140 |
+
Extracted positional embeddings according to relative positions.
|
| 141 |
+
"""
|
| 142 |
+
max_rel_dist = int(2 * max(q_size, k_size) - 1)
|
| 143 |
+
# Interpolate rel pos if needed.
|
| 144 |
+
if rel_pos.shape[0] != max_rel_dist:
|
| 145 |
+
# Interpolate rel pos.
|
| 146 |
+
rel_pos_resized = F.interpolate(
|
| 147 |
+
rel_pos.reshape(1, rel_pos.shape[0], -1).permute(0, 2, 1),
|
| 148 |
+
size=max_rel_dist,
|
| 149 |
+
mode="linear",
|
| 150 |
+
)
|
| 151 |
+
rel_pos_resized = rel_pos_resized.reshape(-1, max_rel_dist).permute(1, 0)
|
| 152 |
+
else:
|
| 153 |
+
rel_pos_resized = rel_pos
|
| 154 |
+
|
| 155 |
+
# Scale the coords with short length if shapes for q and k are different.
|
| 156 |
+
q_coords = torch.arange(q_size)[:, None] * max(k_size / q_size, 1.0)
|
| 157 |
+
k_coords = torch.arange(k_size)[None, :] * max(q_size / k_size, 1.0)
|
| 158 |
+
relative_coords = (q_coords - k_coords) + (k_size - 1) * max(q_size / k_size, 1.0)
|
| 159 |
+
|
| 160 |
+
return rel_pos_resized[relative_coords.long()]
|
| 161 |
+
|
| 162 |
+
|
| 163 |
+
def add_decomposed_rel_pos(attn, q, rel_pos_h, rel_pos_w, q_size, k_size):
|
| 164 |
+
"""
|
| 165 |
+
Calculate decomposed Relative Positional Embeddings from :paper:`mvitv2`.
|
| 166 |
+
https://github.com/facebookresearch/mvit/blob/19786631e330df9f3622e5402b4a419a263a2c80/mvit/models/attention.py # noqa B950
|
| 167 |
+
Args:
|
| 168 |
+
attn (Tensor): attention map.
|
| 169 |
+
q (Tensor): query q in the attention layer with shape (B, q_h * q_w, C).
|
| 170 |
+
rel_pos_h (Tensor): relative position embeddings (Lh, C) for height axis.
|
| 171 |
+
rel_pos_w (Tensor): relative position embeddings (Lw, C) for width axis.
|
| 172 |
+
q_size (Tuple): spatial sequence size of query q with (q_h, q_w).
|
| 173 |
+
k_size (Tuple): spatial sequence size of key k with (k_h, k_w).
|
| 174 |
+
|
| 175 |
+
Returns:
|
| 176 |
+
attn (Tensor): attention map with added relative positional embeddings.
|
| 177 |
+
"""
|
| 178 |
+
q_h, q_w = q_size
|
| 179 |
+
k_h, k_w = k_size
|
| 180 |
+
Rh = get_rel_pos(q_h, k_h, rel_pos_h)
|
| 181 |
+
Rw = get_rel_pos(q_w, k_w, rel_pos_w)
|
| 182 |
+
|
| 183 |
+
B, _, dim = q.shape
|
| 184 |
+
r_q = q.reshape(B, q_h, q_w, dim)
|
| 185 |
+
rel_h = torch.einsum("bhwc,hkc->bhwk", r_q, Rh)
|
| 186 |
+
rel_w = torch.einsum("bhwc,wkc->bhwk", r_q, Rw)
|
| 187 |
+
|
| 188 |
+
attn = (
|
| 189 |
+
attn.view(B, q_h, q_w, k_h, k_w)
|
| 190 |
+
+ rel_h[:, :, :, :, None]
|
| 191 |
+
+ rel_w[:, :, :, None, :]
|
| 192 |
+
).view(B, q_h * q_w, k_h * k_w)
|
| 193 |
+
|
| 194 |
+
return attn
|
| 195 |
+
|
| 196 |
+
|
| 197 |
+
def mean_flat(tensor):
|
| 198 |
+
return tensor.mean(dim=list(range(1, tensor.ndim)))
|
| 199 |
+
|
| 200 |
+
|
| 201 |
+
#################################################################################
|
| 202 |
+
# Token Masking and Unmasking #
|
| 203 |
+
#################################################################################
|
| 204 |
+
def get_mask(
|
| 205 |
+
batch, length, mask_ratio, device, mask_type=None, data_info=None, extra_len=0
|
| 206 |
+
):
|
| 207 |
+
"""
|
| 208 |
+
Get the binary mask for the input sequence.
|
| 209 |
+
Args:
|
| 210 |
+
- batch: batch size
|
| 211 |
+
- length: sequence length
|
| 212 |
+
- mask_ratio: ratio of tokens to mask
|
| 213 |
+
- data_info: dictionary with info for reconstruction
|
| 214 |
+
return:
|
| 215 |
+
mask_dict with following keys:
|
| 216 |
+
- mask: binary mask, 0 is keep, 1 is remove
|
| 217 |
+
- ids_keep: indices of tokens to keep
|
| 218 |
+
- ids_restore: indices to restore the original order
|
| 219 |
+
"""
|
| 220 |
+
assert mask_type in ["random", "fft", "laplacian", "group"]
|
| 221 |
+
mask = torch.ones([batch, length], device=device)
|
| 222 |
+
len_keep = int(length * (1 - mask_ratio)) - extra_len
|
| 223 |
+
|
| 224 |
+
if mask_type in ["random", "group"]:
|
| 225 |
+
noise = torch.rand(batch, length, device=device)
|
| 226 |
+
ids_shuffle = torch.argsort(noise, dim=1)
|
| 227 |
+
ids_restore = torch.argsort(ids_shuffle, dim=1)
|
| 228 |
+
# keep the first subset
|
| 229 |
+
ids_keep = ids_shuffle[:, :len_keep]
|
| 230 |
+
ids_removed = ids_shuffle[:, len_keep:]
|
| 231 |
+
|
| 232 |
+
elif mask_type in ["fft", "laplacian"]:
|
| 233 |
+
if "strength" in data_info:
|
| 234 |
+
strength = data_info["strength"]
|
| 235 |
+
|
| 236 |
+
else:
|
| 237 |
+
N = data_info["N"][0]
|
| 238 |
+
img = data_info["ori_img"]
|
| 239 |
+
|
| 240 |
+
_, C, H, W = img.shape
|
| 241 |
+
if mask_type == "fft":
|
| 242 |
+
|
| 243 |
+
reshaped_image = img.reshape((batch, -1, H // N, N, W // N, N))
|
| 244 |
+
fft_image = torch.fft.fftn(reshaped_image, dim=(3, 5))
|
| 245 |
+
|
| 246 |
+
strength = torch.sum(torch.abs(fft_image), dim=(1, 3, 5)).reshape(
|
| 247 |
+
(
|
| 248 |
+
batch,
|
| 249 |
+
-1,
|
| 250 |
+
)
|
| 251 |
+
)
|
| 252 |
+
elif type == "laplacian":
|
| 253 |
+
laplacian_kernel = torch.tensor(
|
| 254 |
+
[[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], dtype=torch.float32
|
| 255 |
+
).reshape(1, 1, 3, 3)
|
| 256 |
+
laplacian_kernel = laplacian_kernel.repeat(C, 1, 1, 1)
|
| 257 |
+
|
| 258 |
+
reshaped_image = (
|
| 259 |
+
img.reshape(-1, C, H // N, N, W // N, N)
|
| 260 |
+
.permute(0, 2, 4, 1, 3, 5)
|
| 261 |
+
.reshape(-1, C, N, N)
|
| 262 |
+
)
|
| 263 |
+
laplacian_response = F.conv2d(
|
| 264 |
+
reshaped_image, laplacian_kernel, padding=1, groups=C
|
| 265 |
+
)
|
| 266 |
+
strength = laplacian_response.sum(dim=[1, 2, 3]).reshape(
|
| 267 |
+
(
|
| 268 |
+
batch,
|
| 269 |
+
-1,
|
| 270 |
+
)
|
| 271 |
+
)
|
| 272 |
+
|
| 273 |
+
probabilities = strength / (strength.max(dim=1)[0][:, None] + 1e-5)
|
| 274 |
+
ids_shuffle = torch.multinomial(
|
| 275 |
+
probabilities.clip(1e-5, 1), length, replacement=False
|
| 276 |
+
)
|
| 277 |
+
ids_keep = ids_shuffle[:, :len_keep]
|
| 278 |
+
ids_restore = torch.argsort(ids_shuffle, dim=1)
|
| 279 |
+
ids_removed = ids_shuffle[:, len_keep:]
|
| 280 |
+
|
| 281 |
+
mask[:, :len_keep] = 0
|
| 282 |
+
mask = torch.gather(mask, dim=1, index=ids_restore)
|
| 283 |
+
|
| 284 |
+
return {
|
| 285 |
+
"mask": mask,
|
| 286 |
+
"ids_keep": ids_keep,
|
| 287 |
+
"ids_restore": ids_restore,
|
| 288 |
+
"ids_removed": ids_removed,
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
|
| 292 |
+
def mask_out_token(x, ids_keep, ids_removed=None):
|
| 293 |
+
"""
|
| 294 |
+
Mask out the tokens specified by ids_keep.
|
| 295 |
+
Args:
|
| 296 |
+
- x: input sequence, [N, L, D]
|
| 297 |
+
- ids_keep: indices of tokens to keep
|
| 298 |
+
return:
|
| 299 |
+
- x_masked: masked sequence
|
| 300 |
+
"""
|
| 301 |
+
N, L, D = x.shape
|
| 302 |
+
x_remain = torch.gather(x, dim=1, index=ids_keep.unsqueeze(-1).repeat(1, 1, D))
|
| 303 |
+
if ids_removed is not None:
|
| 304 |
+
x_masked = torch.gather(
|
| 305 |
+
x, dim=1, index=ids_removed.unsqueeze(-1).repeat(1, 1, D)
|
| 306 |
+
)
|
| 307 |
+
return x_remain, x_masked
|
| 308 |
+
else:
|
| 309 |
+
return x_remain
|
| 310 |
+
|
| 311 |
+
|
| 312 |
+
def mask_tokens(x, mask_ratio):
|
| 313 |
+
"""
|
| 314 |
+
Perform per-sample random masking by per-sample shuffling.
|
| 315 |
+
Per-sample shuffling is done by argsort random noise.
|
| 316 |
+
x: [N, L, D], sequence
|
| 317 |
+
"""
|
| 318 |
+
N, L, D = x.shape
|
| 319 |
+
len_keep = int(L * (1 - mask_ratio))
|
| 320 |
+
|
| 321 |
+
noise = torch.rand(N, L, device=x.device)
|
| 322 |
+
|
| 323 |
+
# sort noise for each sample
|
| 324 |
+
ids_shuffle = torch.argsort(noise, dim=1)
|
| 325 |
+
ids_restore = torch.argsort(ids_shuffle, dim=1)
|
| 326 |
+
|
| 327 |
+
# keep the first subset
|
| 328 |
+
ids_keep = ids_shuffle[:, :len_keep]
|
| 329 |
+
x_masked = torch.gather(x, dim=1, index=ids_keep.unsqueeze(-1).repeat(1, 1, D))
|
| 330 |
+
|
| 331 |
+
# generate the binary mask: 0 is keep, 1 is remove
|
| 332 |
+
mask = torch.ones([N, L], device=x.device)
|
| 333 |
+
mask[:, :len_keep] = 0
|
| 334 |
+
mask = torch.gather(mask, dim=1, index=ids_restore)
|
| 335 |
+
|
| 336 |
+
return x_masked, mask, ids_restore
|
| 337 |
+
|
| 338 |
+
|
| 339 |
+
def unmask_tokens(x, ids_restore, mask_token):
|
| 340 |
+
# x: [N, T, D] if extras == 0 (i.e., no cls token) else x: [N, T+1, D]
|
| 341 |
+
mask_tokens = mask_token.repeat(x.shape[0], ids_restore.shape[1] - x.shape[1], 1)
|
| 342 |
+
x = torch.cat([x, mask_tokens], dim=1)
|
| 343 |
+
x = torch.gather(
|
| 344 |
+
x, dim=1, index=ids_restore.unsqueeze(-1).repeat(1, 1, x.shape[2])
|
| 345 |
+
) # unshuffle
|
| 346 |
+
return x
|
| 347 |
+
|
| 348 |
+
|
| 349 |
+
# Parse 'None' to None and others to float value
|
| 350 |
+
def parse_float_none(s):
|
| 351 |
+
assert isinstance(s, str)
|
| 352 |
+
return None if s == "None" else float(s)
|
| 353 |
+
|
| 354 |
+
|
| 355 |
+
# ----------------------------------------------------------------------------
|
| 356 |
+
# Parse a comma separated list of numbers or ranges and return a list of ints.
|
| 357 |
+
# Example: '1,2,5-10' returns [1, 2, 5, 6, 7, 8, 9, 10]
|
| 358 |
+
|
| 359 |
+
|
| 360 |
+
def parse_int_list(s):
|
| 361 |
+
if isinstance(s, list):
|
| 362 |
+
return s
|
| 363 |
+
ranges = []
|
| 364 |
+
range_re = re.compile(r"^(\d+)-(\d+)$")
|
| 365 |
+
for p in s.split(","):
|
| 366 |
+
if m := range_re.match(p):
|
| 367 |
+
ranges.extend(range(int(m.group(1)), int(m.group(2)) + 1))
|
| 368 |
+
else:
|
| 369 |
+
ranges.append(int(p))
|
| 370 |
+
return ranges
|
| 371 |
+
|
| 372 |
+
|
| 373 |
+
def init_processes(fn, args):
|
| 374 |
+
"""Initialize the distributed environment."""
|
| 375 |
+
os.environ["MASTER_ADDR"] = args.master_address
|
| 376 |
+
os.environ["MASTER_PORT"] = str(random.randint(2000, 6000))
|
| 377 |
+
print(f'MASTER_ADDR = {os.environ["MASTER_ADDR"]}')
|
| 378 |
+
print(f'MASTER_PORT = {os.environ["MASTER_PORT"]}')
|
| 379 |
+
torch.cuda.set_device(args.local_rank)
|
| 380 |
+
dist.init_process_group(
|
| 381 |
+
backend="nccl",
|
| 382 |
+
init_method="env://",
|
| 383 |
+
rank=args.global_rank,
|
| 384 |
+
world_size=args.global_size,
|
| 385 |
+
)
|
| 386 |
+
fn(args)
|
| 387 |
+
if args.global_size > 1:
|
| 388 |
+
cleanup()
|
| 389 |
+
|
| 390 |
+
|
| 391 |
+
def mprint(*args, **kwargs):
|
| 392 |
+
"""
|
| 393 |
+
Print only from rank 0.
|
| 394 |
+
"""
|
| 395 |
+
if dist.get_rank() == 0:
|
| 396 |
+
print(*args, **kwargs)
|
| 397 |
+
|
| 398 |
+
|
| 399 |
+
def cleanup():
|
| 400 |
+
"""
|
| 401 |
+
End DDP training.
|
| 402 |
+
"""
|
| 403 |
+
dist.barrier()
|
| 404 |
+
mprint("Done!")
|
| 405 |
+
dist.barrier()
|
| 406 |
+
dist.destroy_process_group()
|
| 407 |
+
|
| 408 |
+
|
| 409 |
+
class Logger(object):
|
| 410 |
+
"""
|
| 411 |
+
Redirect stderr to stdout, optionally print stdout to a file,
|
| 412 |
+
and optionally force flushing on both stdout and the file.
|
| 413 |
+
"""
|
| 414 |
+
|
| 415 |
+
def __init__(self, file_name=None, file_mode="w", should_flush=True):
|
| 416 |
+
self.file = None
|
| 417 |
+
|
| 418 |
+
if file_name is not None:
|
| 419 |
+
self.file = open(file_name, file_mode)
|
| 420 |
+
|
| 421 |
+
self.should_flush = should_flush
|
| 422 |
+
self.stdout = sys.stdout
|
| 423 |
+
self.stderr = sys.stderr
|
| 424 |
+
|
| 425 |
+
sys.stdout = self
|
| 426 |
+
sys.stderr = self
|
| 427 |
+
|
| 428 |
+
def __enter__(self):
|
| 429 |
+
return self
|
| 430 |
+
|
| 431 |
+
def __exit__(self, exc_type, exc_value, traceback):
|
| 432 |
+
self.close()
|
| 433 |
+
|
| 434 |
+
def write(self, text):
|
| 435 |
+
"""Write text to stdout (and a file) and optionally flush."""
|
| 436 |
+
if (
|
| 437 |
+
len(text) == 0
|
| 438 |
+
): # workaround for a bug in VSCode debugger: sys.stdout.write(''); sys.stdout.flush() => crash
|
| 439 |
+
return
|
| 440 |
+
|
| 441 |
+
if self.file is not None:
|
| 442 |
+
self.file.write(text)
|
| 443 |
+
|
| 444 |
+
self.stdout.write(text)
|
| 445 |
+
|
| 446 |
+
if self.should_flush:
|
| 447 |
+
self.flush()
|
| 448 |
+
|
| 449 |
+
def flush(self):
|
| 450 |
+
"""Flush written text to both stdout and a file, if open."""
|
| 451 |
+
if self.file is not None:
|
| 452 |
+
self.file.flush()
|
| 453 |
+
|
| 454 |
+
self.stdout.flush()
|
| 455 |
+
|
| 456 |
+
def close(self):
|
| 457 |
+
"""Flush, close possible files, and remove stdout/stderr mirroring."""
|
| 458 |
+
self.flush()
|
| 459 |
+
|
| 460 |
+
# if using multiple loggers, prevent closing in wrong order
|
| 461 |
+
if sys.stdout is self:
|
| 462 |
+
sys.stdout = self.stdout
|
| 463 |
+
if sys.stderr is self:
|
| 464 |
+
sys.stderr = self.stderr
|
| 465 |
+
|
| 466 |
+
if self.file is not None:
|
| 467 |
+
self.file.close()
|
| 468 |
+
|
| 469 |
+
|
| 470 |
+
class StackedRandomGenerator:
|
| 471 |
+
def __init__(self, device, seeds):
|
| 472 |
+
super().__init__()
|
| 473 |
+
self.generators = [
|
| 474 |
+
torch.Generator(device).manual_seed(int(seed) % (1 << 32)) for seed in seeds
|
| 475 |
+
]
|
| 476 |
+
|
| 477 |
+
def randn(self, size, **kwargs):
|
| 478 |
+
assert size[0] == len(self.generators)
|
| 479 |
+
return torch.stack(
|
| 480 |
+
[torch.randn(size[1:], generator=gen, **kwargs) for gen in self.generators]
|
| 481 |
+
)
|
| 482 |
+
|
| 483 |
+
def randn_like(self, input):
|
| 484 |
+
return self.randn(
|
| 485 |
+
input.shape, dtype=input.dtype, layout=input.layout, device=input.device
|
| 486 |
+
)
|
| 487 |
+
|
| 488 |
+
def randint(self, *args, size, **kwargs):
|
| 489 |
+
assert size[0] == len(self.generators)
|
| 490 |
+
return torch.stack(
|
| 491 |
+
[
|
| 492 |
+
torch.randint(*args, size=size[1:], generator=gen, **kwargs)
|
| 493 |
+
for gen in self.generators
|
| 494 |
+
]
|
| 495 |
+
)
|
| 496 |
+
|
| 497 |
+
|
| 498 |
+
def prepare_prompt_ar(prompt, ratios, device="cpu", show=True):
|
| 499 |
+
# get aspect_ratio or ar
|
| 500 |
+
aspect_ratios = re.findall(r"--aspect_ratio\s+(\d+:\d+)", prompt)
|
| 501 |
+
ars = re.findall(r"--ar\s+(\d+:\d+)", prompt)
|
| 502 |
+
custom_hw = re.findall(r"--hw\s+(\d+:\d+)", prompt)
|
| 503 |
+
if show:
|
| 504 |
+
print("aspect_ratios:", aspect_ratios, "ars:", ars, "hws:", custom_hw)
|
| 505 |
+
prompt_clean = prompt.split("--aspect_ratio")[0].split("--ar")[0].split("--hw")[0]
|
| 506 |
+
if len(aspect_ratios) + len(ars) + len(custom_hw) == 0 and show:
|
| 507 |
+
print(
|
| 508 |
+
"Wrong prompt format. Set to default ar: 1. change your prompt into format '--ar h:w or --hw h:w' for correct generating"
|
| 509 |
+
)
|
| 510 |
+
if len(aspect_ratios) != 0:
|
| 511 |
+
ar = float(aspect_ratios[0].split(":")[0]) / float(
|
| 512 |
+
aspect_ratios[0].split(":")[1]
|
| 513 |
+
)
|
| 514 |
+
elif len(ars) != 0:
|
| 515 |
+
ar = float(ars[0].split(":")[0]) / float(ars[0].split(":")[1])
|
| 516 |
+
else:
|
| 517 |
+
ar = 1.0
|
| 518 |
+
closest_ratio = min(ratios.keys(), key=lambda ratio: abs(float(ratio) - ar))
|
| 519 |
+
if len(custom_hw) != 0:
|
| 520 |
+
custom_hw = [
|
| 521 |
+
float(custom_hw[0].split(":")[0]),
|
| 522 |
+
float(custom_hw[0].split(":")[1]),
|
| 523 |
+
]
|
| 524 |
+
else:
|
| 525 |
+
custom_hw = ratios[closest_ratio]
|
| 526 |
+
default_hw = ratios[closest_ratio]
|
| 527 |
+
prompt_show = f"prompt: {prompt_clean.strip()}\nSize: --ar {closest_ratio}, --bin hw {ratios[closest_ratio]}, --custom hw {custom_hw}"
|
| 528 |
+
return (
|
| 529 |
+
prompt_clean,
|
| 530 |
+
prompt_show,
|
| 531 |
+
torch.tensor(default_hw, device=device)[None],
|
| 532 |
+
torch.tensor([float(closest_ratio)], device=device)[None],
|
| 533 |
+
torch.tensor(custom_hw, device=device)[None],
|
| 534 |
+
)
|
| 535 |
+
|
| 536 |
+
|
| 537 |
+
def resize_and_crop_tensor(samples: torch.Tensor, new_width: int, new_height: int):
|
| 538 |
+
orig_hw = torch.tensor([samples.shape[2], samples.shape[3]], dtype=torch.int)
|
| 539 |
+
custom_hw = torch.tensor([int(new_height), int(new_width)], dtype=torch.int)
|
| 540 |
+
|
| 541 |
+
if (orig_hw != custom_hw).all():
|
| 542 |
+
ratio = max(custom_hw[0] / orig_hw[0], custom_hw[1] / orig_hw[1])
|
| 543 |
+
resized_width = int(orig_hw[1] * ratio)
|
| 544 |
+
resized_height = int(orig_hw[0] * ratio)
|
| 545 |
+
|
| 546 |
+
transform = T.Compose(
|
| 547 |
+
[
|
| 548 |
+
T.Resize((resized_height, resized_width)),
|
| 549 |
+
T.CenterCrop(custom_hw.tolist()),
|
| 550 |
+
]
|
| 551 |
+
)
|
| 552 |
+
return transform(samples)
|
| 553 |
+
else:
|
| 554 |
+
return samples
|
| 555 |
+
|
| 556 |
+
|
| 557 |
+
def resize_and_crop_img(img: Image, new_width, new_height):
|
| 558 |
+
orig_width, orig_height = img.size
|
| 559 |
+
|
| 560 |
+
ratio = max(new_width / orig_width, new_height / orig_height)
|
| 561 |
+
resized_width = int(orig_width * ratio)
|
| 562 |
+
resized_height = int(orig_height * ratio)
|
| 563 |
+
|
| 564 |
+
img = img.resize((resized_width, resized_height), Image.LANCZOS)
|
| 565 |
+
|
| 566 |
+
left = (resized_width - new_width) / 2
|
| 567 |
+
top = (resized_height - new_height) / 2
|
| 568 |
+
right = (resized_width + new_width) / 2
|
| 569 |
+
bottom = (resized_height + new_height) / 2
|
| 570 |
+
|
| 571 |
+
img = img.crop((left, top, right, bottom))
|
| 572 |
+
|
| 573 |
+
return img
|
| 574 |
+
|
| 575 |
+
|
| 576 |
+
def mask_feature(emb, mask):
|
| 577 |
+
if emb.shape[0] == 1:
|
| 578 |
+
keep_index = mask.sum().item()
|
| 579 |
+
return emb[:, :, :keep_index, :], keep_index
|
| 580 |
+
else:
|
| 581 |
+
masked_feature = emb * mask[:, None, :, None]
|
| 582 |
+
return masked_feature, emb.shape[2]
|
ldm/modules/latent_diffusion/__init__.py
ADDED
|
File without changes
|
ldm/modules/latent_diffusion/ddim.py
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
import numpy as np
|
| 3 |
+
from tqdm import tqdm
|
| 4 |
+
from functools import partial
|
| 5 |
+
|
| 6 |
+
from ldm.utils.diffusion_util import (
|
| 7 |
+
make_ddim_sampling_parameters,
|
| 8 |
+
make_ddim_timesteps,
|
| 9 |
+
noise_like,
|
| 10 |
+
extract_into_tensor,
|
| 11 |
+
)
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
class DDIMSampler(object):
|
| 15 |
+
def __init__(self, model, schedule="linear", device=torch.device("cuda"), **kwargs):
|
| 16 |
+
super().__init__()
|
| 17 |
+
self.model = model
|
| 18 |
+
self.ddpm_num_timesteps = model.num_timesteps
|
| 19 |
+
self.schedule = schedule
|
| 20 |
+
self.device = device
|
| 21 |
+
|
| 22 |
+
def register_buffer(self, name, attr):
|
| 23 |
+
if type(attr) == torch.Tensor:
|
| 24 |
+
if attr.device != self.device:
|
| 25 |
+
attr = attr.to(self.device)
|
| 26 |
+
setattr(self, name, attr)
|
| 27 |
+
|
| 28 |
+
def make_schedule(
|
| 29 |
+
self, ddim_num_steps, ddim_discretize="uniform", ddim_eta=0.0, verbose=True
|
| 30 |
+
):
|
| 31 |
+
self.ddim_timesteps = make_ddim_timesteps(
|
| 32 |
+
ddim_discr_method=ddim_discretize,
|
| 33 |
+
num_ddim_timesteps=ddim_num_steps,
|
| 34 |
+
num_ddpm_timesteps=self.ddpm_num_timesteps,
|
| 35 |
+
verbose=verbose,
|
| 36 |
+
)
|
| 37 |
+
alphas_cumprod = self.model.alphas_cumprod
|
| 38 |
+
assert (
|
| 39 |
+
alphas_cumprod.shape[0] == self.ddpm_num_timesteps
|
| 40 |
+
), "alphas have to be defined for each timestep"
|
| 41 |
+
to_torch = lambda x: x.clone().detach().to(torch.float32).to(self.model.device)
|
| 42 |
+
|
| 43 |
+
self.register_buffer("betas", to_torch(self.model.betas))
|
| 44 |
+
self.register_buffer("alphas_cumprod", to_torch(alphas_cumprod))
|
| 45 |
+
self.register_buffer(
|
| 46 |
+
"alphas_cumprod_prev", to_torch(self.model.alphas_cumprod_prev)
|
| 47 |
+
)
|
| 48 |
+
|
| 49 |
+
# calculations for diffusion q(x_t | x_{t-1}) and others
|
| 50 |
+
self.register_buffer(
|
| 51 |
+
"sqrt_alphas_cumprod", to_torch(np.sqrt(alphas_cumprod.cpu()))
|
| 52 |
+
)
|
| 53 |
+
self.register_buffer(
|
| 54 |
+
"sqrt_one_minus_alphas_cumprod",
|
| 55 |
+
to_torch(np.sqrt(1.0 - alphas_cumprod.cpu())),
|
| 56 |
+
)
|
| 57 |
+
self.register_buffer(
|
| 58 |
+
"log_one_minus_alphas_cumprod", to_torch(np.log(1.0 - alphas_cumprod.cpu()))
|
| 59 |
+
)
|
| 60 |
+
self.register_buffer(
|
| 61 |
+
"sqrt_recip_alphas_cumprod", to_torch(np.sqrt(1.0 / alphas_cumprod.cpu()))
|
| 62 |
+
)
|
| 63 |
+
self.register_buffer(
|
| 64 |
+
"sqrt_recipm1_alphas_cumprod",
|
| 65 |
+
to_torch(np.sqrt(1.0 / alphas_cumprod.cpu() - 1)),
|
| 66 |
+
)
|
| 67 |
+
|
| 68 |
+
# ddim sampling parameters
|
| 69 |
+
ddim_sigmas, ddim_alphas, ddim_alphas_prev = make_ddim_sampling_parameters(
|
| 70 |
+
alphacums=alphas_cumprod.cpu(),
|
| 71 |
+
ddim_timesteps=self.ddim_timesteps,
|
| 72 |
+
eta=ddim_eta,
|
| 73 |
+
verbose=verbose,
|
| 74 |
+
)
|
| 75 |
+
self.register_buffer("ddim_sigmas", ddim_sigmas)
|
| 76 |
+
self.register_buffer("ddim_alphas", ddim_alphas)
|
| 77 |
+
self.register_buffer("ddim_alphas_prev", ddim_alphas_prev)
|
| 78 |
+
self.register_buffer("ddim_sqrt_one_minus_alphas", np.sqrt(1.0 - ddim_alphas))
|
| 79 |
+
sigmas_for_original_sampling_steps = ddim_eta * torch.sqrt(
|
| 80 |
+
(1 - self.alphas_cumprod_prev)
|
| 81 |
+
/ (1 - self.alphas_cumprod)
|
| 82 |
+
* (1 - self.alphas_cumprod / self.alphas_cumprod_prev)
|
| 83 |
+
)
|
| 84 |
+
self.register_buffer(
|
| 85 |
+
"ddim_sigmas_for_original_num_steps", sigmas_for_original_sampling_steps
|
| 86 |
+
)
|
| 87 |
+
|
| 88 |
+
@torch.no_grad()
|
| 89 |
+
def sample(
|
| 90 |
+
self,
|
| 91 |
+
S,
|
| 92 |
+
batch_size,
|
| 93 |
+
shape,
|
| 94 |
+
conditioning=None,
|
| 95 |
+
callback=None,
|
| 96 |
+
normals_sequence=None,
|
| 97 |
+
img_callback=None,
|
| 98 |
+
quantize_x0=False,
|
| 99 |
+
eta=0.0,
|
| 100 |
+
mask=None,
|
| 101 |
+
x0=None,
|
| 102 |
+
temperature=1.0,
|
| 103 |
+
noise_dropout=0.0,
|
| 104 |
+
score_corrector=None,
|
| 105 |
+
corrector_kwargs=None,
|
| 106 |
+
verbose=True,
|
| 107 |
+
x_T=None,
|
| 108 |
+
log_every_t=100,
|
| 109 |
+
unconditional_guidance_scale=1.0,
|
| 110 |
+
unconditional_conditioning=None,
|
| 111 |
+
# this has to come in the same format as the conditioning, # e.g. as encoded tokens, ...
|
| 112 |
+
**kwargs
|
| 113 |
+
):
|
| 114 |
+
self.make_schedule(ddim_num_steps=S, ddim_eta=eta, verbose=verbose)
|
| 115 |
+
# sampling
|
| 116 |
+
C, H, W = shape
|
| 117 |
+
size = (batch_size, C, H, W)
|
| 118 |
+
samples, intermediates = self.ddim_sampling(
|
| 119 |
+
conditioning,
|
| 120 |
+
size,
|
| 121 |
+
callback=callback,
|
| 122 |
+
img_callback=img_callback,
|
| 123 |
+
quantize_denoised=quantize_x0,
|
| 124 |
+
mask=mask,
|
| 125 |
+
x0=x0,
|
| 126 |
+
ddim_use_original_steps=False,
|
| 127 |
+
noise_dropout=noise_dropout,
|
| 128 |
+
temperature=temperature,
|
| 129 |
+
score_corrector=score_corrector,
|
| 130 |
+
corrector_kwargs=corrector_kwargs,
|
| 131 |
+
x_T=x_T,
|
| 132 |
+
log_every_t=log_every_t,
|
| 133 |
+
unconditional_guidance_scale=unconditional_guidance_scale,
|
| 134 |
+
unconditional_conditioning=unconditional_conditioning,
|
| 135 |
+
)
|
| 136 |
+
return samples, intermediates
|
| 137 |
+
|
| 138 |
+
@torch.no_grad()
|
| 139 |
+
def ddim_sampling(
|
| 140 |
+
self,
|
| 141 |
+
cond,
|
| 142 |
+
shape,
|
| 143 |
+
x_T=None,
|
| 144 |
+
ddim_use_original_steps=False,
|
| 145 |
+
callback=None,
|
| 146 |
+
timesteps=None,
|
| 147 |
+
quantize_denoised=False,
|
| 148 |
+
mask=None,
|
| 149 |
+
x0=None,
|
| 150 |
+
img_callback=None,
|
| 151 |
+
log_every_t=100,
|
| 152 |
+
temperature=1.0,
|
| 153 |
+
noise_dropout=0.0,
|
| 154 |
+
score_corrector=None,
|
| 155 |
+
corrector_kwargs=None,
|
| 156 |
+
unconditional_guidance_scale=1.0,
|
| 157 |
+
unconditional_conditioning=None,
|
| 158 |
+
):
|
| 159 |
+
device = self.model.betas.device
|
| 160 |
+
b = shape[0]
|
| 161 |
+
if x_T is None:
|
| 162 |
+
img = torch.randn(shape, device=device)
|
| 163 |
+
else:
|
| 164 |
+
img = x_T
|
| 165 |
+
|
| 166 |
+
if timesteps is None:
|
| 167 |
+
timesteps = (
|
| 168 |
+
self.ddpm_num_timesteps
|
| 169 |
+
if ddim_use_original_steps
|
| 170 |
+
else self.ddim_timesteps
|
| 171 |
+
)
|
| 172 |
+
elif timesteps is not None and not ddim_use_original_steps:
|
| 173 |
+
subset_end = (
|
| 174 |
+
int(
|
| 175 |
+
min(timesteps / self.ddim_timesteps.shape[0], 1)
|
| 176 |
+
* self.ddim_timesteps.shape[0]
|
| 177 |
+
)
|
| 178 |
+
- 1
|
| 179 |
+
)
|
| 180 |
+
timesteps = self.ddim_timesteps[:subset_end]
|
| 181 |
+
|
| 182 |
+
intermediates = {"x_inter": [img], "pred_x0": [img]}
|
| 183 |
+
time_range = (
|
| 184 |
+
reversed(range(0, timesteps))
|
| 185 |
+
if ddim_use_original_steps
|
| 186 |
+
else np.flip(timesteps)
|
| 187 |
+
)
|
| 188 |
+
total_steps = timesteps if ddim_use_original_steps else timesteps.shape[0]
|
| 189 |
+
|
| 190 |
+
iterator = tqdm(time_range, desc="DDIM Sampler", total=total_steps)
|
| 191 |
+
|
| 192 |
+
for i, step in enumerate(iterator):
|
| 193 |
+
index = total_steps - i - 1
|
| 194 |
+
ts = torch.full((b,), step, device=device, dtype=torch.long)
|
| 195 |
+
|
| 196 |
+
if mask is not None:
|
| 197 |
+
assert x0 is not None
|
| 198 |
+
img_orig = self.model.q_sample(
|
| 199 |
+
x0, ts
|
| 200 |
+
) # TODO: deterministic forward pass?
|
| 201 |
+
img = img_orig * mask + (1.0 - mask) * img
|
| 202 |
+
|
| 203 |
+
outs = self.p_sample_ddim(
|
| 204 |
+
img,
|
| 205 |
+
cond,
|
| 206 |
+
ts,
|
| 207 |
+
index=index,
|
| 208 |
+
use_original_steps=ddim_use_original_steps,
|
| 209 |
+
quantize_denoised=quantize_denoised,
|
| 210 |
+
temperature=temperature,
|
| 211 |
+
noise_dropout=noise_dropout,
|
| 212 |
+
score_corrector=score_corrector,
|
| 213 |
+
corrector_kwargs=corrector_kwargs,
|
| 214 |
+
unconditional_guidance_scale=unconditional_guidance_scale,
|
| 215 |
+
unconditional_conditioning=unconditional_conditioning,
|
| 216 |
+
)
|
| 217 |
+
img, pred_x0 = outs
|
| 218 |
+
if callback:
|
| 219 |
+
callback(i)
|
| 220 |
+
if img_callback:
|
| 221 |
+
img_callback(pred_x0, i)
|
| 222 |
+
|
| 223 |
+
if index % log_every_t == 0 or index == total_steps - 1:
|
| 224 |
+
intermediates["x_inter"].append(img)
|
| 225 |
+
intermediates["pred_x0"].append(pred_x0)
|
| 226 |
+
|
| 227 |
+
return img, intermediates
|
| 228 |
+
|
| 229 |
+
@torch.no_grad()
|
| 230 |
+
def p_sample_ddim(
|
| 231 |
+
self,
|
| 232 |
+
x,
|
| 233 |
+
c,
|
| 234 |
+
t,
|
| 235 |
+
index,
|
| 236 |
+
repeat_noise=False,
|
| 237 |
+
use_original_steps=False,
|
| 238 |
+
quantize_denoised=False,
|
| 239 |
+
temperature=1.0,
|
| 240 |
+
noise_dropout=0.0,
|
| 241 |
+
score_corrector=None,
|
| 242 |
+
corrector_kwargs=None,
|
| 243 |
+
unconditional_guidance_scale=1.0,
|
| 244 |
+
unconditional_conditioning=None,
|
| 245 |
+
):
|
| 246 |
+
b, *_, device = *x.shape, x.device
|
| 247 |
+
|
| 248 |
+
if unconditional_conditioning is None or unconditional_guidance_scale == 1.0:
|
| 249 |
+
out = self.model.apply_model(x, t, c)
|
| 250 |
+
else:
|
| 251 |
+
x_in = x
|
| 252 |
+
t_in = t
|
| 253 |
+
out_uncond = self.model.apply_model(x_in, t_in, unconditional_conditioning)
|
| 254 |
+
out_cond = self.model.apply_model(x_in, t_in, c)
|
| 255 |
+
|
| 256 |
+
out = out_uncond + unconditional_guidance_scale * (out_cond - out_uncond)
|
| 257 |
+
e_t = out
|
| 258 |
+
if score_corrector is not None:
|
| 259 |
+
assert self.model.parameterization == "eps"
|
| 260 |
+
e_t = score_corrector.modify_score(
|
| 261 |
+
self.model, e_t, x, t, c, **corrector_kwargs
|
| 262 |
+
)
|
| 263 |
+
|
| 264 |
+
alphas = self.model.alphas_cumprod if use_original_steps else self.ddim_alphas
|
| 265 |
+
alphas_prev = (
|
| 266 |
+
self.model.alphas_cumprod_prev
|
| 267 |
+
if use_original_steps
|
| 268 |
+
else self.ddim_alphas_prev
|
| 269 |
+
)
|
| 270 |
+
sqrt_one_minus_alphas = (
|
| 271 |
+
self.model.sqrt_one_minus_alphas_cumprod
|
| 272 |
+
if use_original_steps
|
| 273 |
+
else self.ddim_sqrt_one_minus_alphas
|
| 274 |
+
)
|
| 275 |
+
sigmas = (
|
| 276 |
+
self.model.ddim_sigmas_for_original_num_steps
|
| 277 |
+
if use_original_steps
|
| 278 |
+
else self.ddim_sigmas
|
| 279 |
+
)
|
| 280 |
+
# select parameters corresponding to the currently considered timestep
|
| 281 |
+
a_t = torch.full((b, 1, 1, 1), alphas[index], device=device)
|
| 282 |
+
a_prev = torch.full((b, 1, 1, 1), alphas_prev[index], device=device)
|
| 283 |
+
sigma_t = torch.full((b, 1, 1, 1), sigmas[index], device=device)
|
| 284 |
+
sqrt_one_minus_at = torch.full(
|
| 285 |
+
(b, 1, 1, 1), sqrt_one_minus_alphas[index], device=device
|
| 286 |
+
)
|
| 287 |
+
|
| 288 |
+
# current prediction for x_0
|
| 289 |
+
pred_x0 = (x - sqrt_one_minus_at * e_t) / a_t.sqrt()
|
| 290 |
+
if quantize_denoised:
|
| 291 |
+
pred_x0, _, *_ = self.model.first_stage_model.quantize(pred_x0)
|
| 292 |
+
# direction pointing to x_t
|
| 293 |
+
dir_xt = (1.0 - a_prev - sigma_t**2).sqrt() * e_t
|
| 294 |
+
noise = sigma_t * noise_like(x.shape, device, repeat_noise) * temperature
|
| 295 |
+
if noise_dropout > 0.0:
|
| 296 |
+
noise = torch.nn.functional.dropout(noise, p=noise_dropout)
|
| 297 |
+
x_prev = a_prev.sqrt() * pred_x0 + dir_xt + noise
|
| 298 |
+
return x_prev, pred_x0
|
ldm/modules/latent_diffusion/ddpm.py
ADDED
|
@@ -0,0 +1,403 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import time
|
| 3 |
+
import torch
|
| 4 |
+
import torch.nn as nn
|
| 5 |
+
import numpy as np
|
| 6 |
+
|
| 7 |
+
import pytorch_lightning as pl
|
| 8 |
+
from functools import partial
|
| 9 |
+
|
| 10 |
+
import warnings
|
| 11 |
+
|
| 12 |
+
warnings.filterwarnings("ignore")
|
| 13 |
+
from transformers import logging
|
| 14 |
+
|
| 15 |
+
logging.set_verbosity_error()
|
| 16 |
+
|
| 17 |
+
from ldm.utils.util import exists, default, instantiate_from_config
|
| 18 |
+
|
| 19 |
+
from ldm.utils.diffusion_util import make_beta_schedule
|
| 20 |
+
from ldm.modules.latent_diffusion.ddim import DDIMSampler
|
| 21 |
+
|
| 22 |
+
import soundfile as sf
|
| 23 |
+
import logging
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
__conditioning_keys__ = {"concat": "c_concat", "crossattn": "c_crossattn", "adm": "y"}
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
class DDPM(pl.LightningModule):
|
| 30 |
+
# classic DDPM with Gaussian diffusion, in image space
|
| 31 |
+
def __init__(
|
| 32 |
+
self,
|
| 33 |
+
model_config,
|
| 34 |
+
sampling_rate=None,
|
| 35 |
+
timesteps=1000,
|
| 36 |
+
beta_schedule="linear",
|
| 37 |
+
loss_type="l2",
|
| 38 |
+
ckpt_path=None,
|
| 39 |
+
ignore_keys=[],
|
| 40 |
+
load_only_unet=False,
|
| 41 |
+
monitor="val/loss",
|
| 42 |
+
use_ema=True,
|
| 43 |
+
first_stage_key="image",
|
| 44 |
+
latent_t_size=256,
|
| 45 |
+
latent_f_size=16,
|
| 46 |
+
channels=3,
|
| 47 |
+
log_every_t=100,
|
| 48 |
+
clip_denoised=True,
|
| 49 |
+
linear_start=1e-4,
|
| 50 |
+
linear_end=2e-2,
|
| 51 |
+
cosine_s=8e-3,
|
| 52 |
+
given_betas=None,
|
| 53 |
+
original_elbo_weight=0.0,
|
| 54 |
+
v_posterior=0.0,
|
| 55 |
+
l_simple_weight=1.0,
|
| 56 |
+
conditioning_key=None,
|
| 57 |
+
parameterization="eps",
|
| 58 |
+
scheduler_config=None,
|
| 59 |
+
use_positional_encodings=False,
|
| 60 |
+
learn_logvar=False,
|
| 61 |
+
logvar_init=0.0,
|
| 62 |
+
evaluator=None,
|
| 63 |
+
clap_version="lain",
|
| 64 |
+
base_learning_rate=None,
|
| 65 |
+
clap_model=None,
|
| 66 |
+
):
|
| 67 |
+
super().__init__()
|
| 68 |
+
|
| 69 |
+
self.parameterization = parameterization
|
| 70 |
+
|
| 71 |
+
self.sampling_rate = sampling_rate
|
| 72 |
+
|
| 73 |
+
self.latent_t_size = latent_t_size
|
| 74 |
+
self.latent_f_size = latent_f_size
|
| 75 |
+
|
| 76 |
+
self.channels = channels
|
| 77 |
+
self.model = DiffusionWrapper(model_config, conditioning_key)
|
| 78 |
+
|
| 79 |
+
self.v_posterior = v_posterior
|
| 80 |
+
|
| 81 |
+
if ckpt_path is not None:
|
| 82 |
+
self.init_from_ckpt(
|
| 83 |
+
ckpt_path, ignore_keys=ignore_keys, only_model=load_only_unet
|
| 84 |
+
)
|
| 85 |
+
|
| 86 |
+
self.register_schedule(
|
| 87 |
+
given_betas=given_betas,
|
| 88 |
+
beta_schedule=beta_schedule,
|
| 89 |
+
timesteps=timesteps,
|
| 90 |
+
linear_start=linear_start,
|
| 91 |
+
linear_end=linear_end,
|
| 92 |
+
cosine_s=cosine_s,
|
| 93 |
+
)
|
| 94 |
+
|
| 95 |
+
def register_schedule(
|
| 96 |
+
self,
|
| 97 |
+
given_betas=None,
|
| 98 |
+
beta_schedule="linear",
|
| 99 |
+
timesteps=1000,
|
| 100 |
+
linear_start=1e-4,
|
| 101 |
+
linear_end=2e-2,
|
| 102 |
+
cosine_s=8e-3,
|
| 103 |
+
):
|
| 104 |
+
if exists(given_betas):
|
| 105 |
+
betas = given_betas
|
| 106 |
+
else:
|
| 107 |
+
betas = make_beta_schedule(
|
| 108 |
+
beta_schedule,
|
| 109 |
+
timesteps,
|
| 110 |
+
linear_start=linear_start,
|
| 111 |
+
linear_end=linear_end,
|
| 112 |
+
cosine_s=cosine_s,
|
| 113 |
+
)
|
| 114 |
+
alphas = 1.0 - betas
|
| 115 |
+
alphas_cumprod = np.cumprod(alphas, axis=0)
|
| 116 |
+
alphas_cumprod_prev = np.append(1.0, alphas_cumprod[:-1])
|
| 117 |
+
|
| 118 |
+
(timesteps,) = betas.shape
|
| 119 |
+
self.num_timesteps = int(timesteps)
|
| 120 |
+
self.linear_start = linear_start
|
| 121 |
+
self.linear_end = linear_end
|
| 122 |
+
assert (
|
| 123 |
+
alphas_cumprod.shape[0] == self.num_timesteps
|
| 124 |
+
), "alphas have to be defined for each timestep"
|
| 125 |
+
|
| 126 |
+
to_torch = partial(torch.tensor, dtype=torch.float32)
|
| 127 |
+
|
| 128 |
+
self.register_buffer("betas", to_torch(betas))
|
| 129 |
+
self.register_buffer("alphas_cumprod", to_torch(alphas_cumprod))
|
| 130 |
+
self.register_buffer("alphas_cumprod_prev", to_torch(alphas_cumprod_prev))
|
| 131 |
+
|
| 132 |
+
# calculations for diffusion q(x_t | x_{t-1}) and others
|
| 133 |
+
self.register_buffer("sqrt_alphas_cumprod", to_torch(np.sqrt(alphas_cumprod)))
|
| 134 |
+
self.register_buffer(
|
| 135 |
+
"sqrt_one_minus_alphas_cumprod", to_torch(np.sqrt(1.0 - alphas_cumprod))
|
| 136 |
+
)
|
| 137 |
+
self.register_buffer(
|
| 138 |
+
"log_one_minus_alphas_cumprod", to_torch(np.log(1.0 - alphas_cumprod))
|
| 139 |
+
)
|
| 140 |
+
self.register_buffer(
|
| 141 |
+
"sqrt_recip_alphas_cumprod", to_torch(np.sqrt(1.0 / alphas_cumprod))
|
| 142 |
+
)
|
| 143 |
+
self.register_buffer(
|
| 144 |
+
"sqrt_recipm1_alphas_cumprod", to_torch(np.sqrt(1.0 / alphas_cumprod - 1))
|
| 145 |
+
)
|
| 146 |
+
|
| 147 |
+
# calculations for posterior q(x_{t-1} | x_t, x_0)
|
| 148 |
+
posterior_variance = (1 - self.v_posterior) * betas * (
|
| 149 |
+
1.0 - alphas_cumprod_prev
|
| 150 |
+
) / (1.0 - alphas_cumprod) + self.v_posterior * betas
|
| 151 |
+
# above: equal to 1. / (1. / (1. - alpha_cumprod_tm1) + alpha_t / beta_t)
|
| 152 |
+
self.register_buffer("posterior_variance", to_torch(posterior_variance))
|
| 153 |
+
# below: log calculation clipped because the posterior variance is 0 at the beginning of the diffusion chain
|
| 154 |
+
self.register_buffer(
|
| 155 |
+
"posterior_log_variance_clipped",
|
| 156 |
+
to_torch(np.log(np.maximum(posterior_variance, 1e-20))),
|
| 157 |
+
)
|
| 158 |
+
self.register_buffer(
|
| 159 |
+
"posterior_mean_coef1",
|
| 160 |
+
to_torch(betas * np.sqrt(alphas_cumprod_prev) / (1.0 - alphas_cumprod)),
|
| 161 |
+
)
|
| 162 |
+
self.register_buffer(
|
| 163 |
+
"posterior_mean_coef2",
|
| 164 |
+
to_torch(
|
| 165 |
+
(1.0 - alphas_cumprod_prev) * np.sqrt(alphas) / (1.0 - alphas_cumprod)
|
| 166 |
+
),
|
| 167 |
+
)
|
| 168 |
+
|
| 169 |
+
if self.parameterization == "eps":
|
| 170 |
+
lvlb_weights = self.betas**2 / (
|
| 171 |
+
2
|
| 172 |
+
* self.posterior_variance
|
| 173 |
+
* to_torch(alphas)
|
| 174 |
+
* (1 - self.alphas_cumprod)
|
| 175 |
+
)
|
| 176 |
+
elif self.parameterization == "x0":
|
| 177 |
+
lvlb_weights = (
|
| 178 |
+
0.5
|
| 179 |
+
* np.sqrt(torch.Tensor(alphas_cumprod))
|
| 180 |
+
/ (2.0 * 1 - torch.Tensor(alphas_cumprod))
|
| 181 |
+
)
|
| 182 |
+
else:
|
| 183 |
+
raise NotImplementedError("mu not supported")
|
| 184 |
+
# TODO how to choose this term
|
| 185 |
+
lvlb_weights[0] = lvlb_weights[1]
|
| 186 |
+
self.register_buffer("lvlb_weights", lvlb_weights, persistent=False)
|
| 187 |
+
assert not torch.isnan(self.lvlb_weights).all()
|
| 188 |
+
|
| 189 |
+
def init_from_ckpt(self, path, ignore_keys=list(), only_model=False):
|
| 190 |
+
sd = torch.load(path, map_location="cpu")
|
| 191 |
+
if "state_dict" in list(sd.keys()):
|
| 192 |
+
sd = sd["state_dict"]
|
| 193 |
+
keys = list(sd.keys())
|
| 194 |
+
for k in keys:
|
| 195 |
+
for ik in ignore_keys:
|
| 196 |
+
if k.startswith(ik):
|
| 197 |
+
print("Deleting key {} from state_dict.".format(k))
|
| 198 |
+
del sd[k]
|
| 199 |
+
missing, unexpected = (
|
| 200 |
+
self.load_state_dict(sd, strict=False)
|
| 201 |
+
if not only_model
|
| 202 |
+
else self.model.load_state_dict(sd, strict=False)
|
| 203 |
+
)
|
| 204 |
+
print(
|
| 205 |
+
f"Restored from {path} with {len(missing)} missing and {len(unexpected)} unexpected keys"
|
| 206 |
+
)
|
| 207 |
+
if len(missing) > 0:
|
| 208 |
+
print(f"Missing Keys: {missing}")
|
| 209 |
+
if len(unexpected) > 0:
|
| 210 |
+
print(f"Unexpected Keys: {unexpected}")
|
| 211 |
+
|
| 212 |
+
|
| 213 |
+
class LatentDiffusion(DDPM):
|
| 214 |
+
"""main class"""
|
| 215 |
+
|
| 216 |
+
def __init__(
|
| 217 |
+
self,
|
| 218 |
+
first_stage_config,
|
| 219 |
+
cond_stage_config,
|
| 220 |
+
num_timesteps_cond=None,
|
| 221 |
+
cond_stage_key="image",
|
| 222 |
+
cond_stage_trainable=False,
|
| 223 |
+
concat_mode=True,
|
| 224 |
+
cond_stage_forward=None,
|
| 225 |
+
conditioning_key=None,
|
| 226 |
+
scale_factor=1.0,
|
| 227 |
+
scale_by_std=False,
|
| 228 |
+
*args,
|
| 229 |
+
**kwargs,
|
| 230 |
+
):
|
| 231 |
+
self.num_timesteps_cond = default(num_timesteps_cond, 1)
|
| 232 |
+
self.scale_by_std = scale_by_std
|
| 233 |
+
assert self.num_timesteps_cond <= kwargs["timesteps"]
|
| 234 |
+
self.conditioning_key = conditioning_key
|
| 235 |
+
|
| 236 |
+
ckpt_path = kwargs.pop("ckpt_path", None)
|
| 237 |
+
ignore_keys = kwargs.pop("ignore_keys", [])
|
| 238 |
+
super().__init__(conditioning_key=conditioning_key, *args, **kwargs)
|
| 239 |
+
self.concat_mode = concat_mode
|
| 240 |
+
self.cond_stage_key = cond_stage_key
|
| 241 |
+
try:
|
| 242 |
+
self.num_downs = len(first_stage_config.params.ddconfig.ch_mult) - 1
|
| 243 |
+
except:
|
| 244 |
+
self.num_downs = 0
|
| 245 |
+
if not scale_by_std:
|
| 246 |
+
self.scale_factor = scale_factor
|
| 247 |
+
else:
|
| 248 |
+
self.register_buffer("scale_factor", torch.tensor(scale_factor))
|
| 249 |
+
self.instantiate_first_stage(first_stage_config)
|
| 250 |
+
self.instantiate_cond_stage(cond_stage_config)
|
| 251 |
+
self.cond_stage_forward = cond_stage_forward
|
| 252 |
+
self.clip_denoised = False
|
| 253 |
+
self.restarted_from_ckpt = False
|
| 254 |
+
if ckpt_path is not None:
|
| 255 |
+
self.init_from_ckpt(ckpt_path, ignore_keys)
|
| 256 |
+
self.restarted_from_ckpt = True
|
| 257 |
+
|
| 258 |
+
def make_cond_schedule(
|
| 259 |
+
self,
|
| 260 |
+
):
|
| 261 |
+
self.cond_ids = torch.full(
|
| 262 |
+
size=(self.num_timesteps,),
|
| 263 |
+
fill_value=self.num_timesteps - 1,
|
| 264 |
+
dtype=torch.long,
|
| 265 |
+
)
|
| 266 |
+
ids = torch.round(
|
| 267 |
+
torch.linspace(0, self.num_timesteps - 1, self.num_timesteps_cond)
|
| 268 |
+
).long()
|
| 269 |
+
self.cond_ids[: self.num_timesteps_cond] = ids
|
| 270 |
+
|
| 271 |
+
def register_schedule(
|
| 272 |
+
self,
|
| 273 |
+
given_betas=None,
|
| 274 |
+
beta_schedule="linear",
|
| 275 |
+
timesteps=1000,
|
| 276 |
+
linear_start=1e-4,
|
| 277 |
+
linear_end=2e-2,
|
| 278 |
+
cosine_s=8e-3,
|
| 279 |
+
):
|
| 280 |
+
super().register_schedule(
|
| 281 |
+
given_betas, beta_schedule, timesteps, linear_start, linear_end, cosine_s
|
| 282 |
+
)
|
| 283 |
+
|
| 284 |
+
self.shorten_cond_schedule = self.num_timesteps_cond > 1
|
| 285 |
+
if self.shorten_cond_schedule:
|
| 286 |
+
self.make_cond_schedule()
|
| 287 |
+
|
| 288 |
+
def instantiate_first_stage(self, config):
|
| 289 |
+
model = instantiate_from_config(config)
|
| 290 |
+
self.first_stage_model = model.eval()
|
| 291 |
+
for param in self.first_stage_model.parameters():
|
| 292 |
+
param.requires_grad = False
|
| 293 |
+
|
| 294 |
+
def instantiate_cond_stage(self, config):
|
| 295 |
+
model = instantiate_from_config(config[self.conditioning_key])
|
| 296 |
+
self.cond_stage_model = model
|
| 297 |
+
|
| 298 |
+
@torch.no_grad()
|
| 299 |
+
def decode_first_stage(self, z, predict_cids=False, force_not_quantize=False):
|
| 300 |
+
z = 1.0 / self.scale_factor * z
|
| 301 |
+
z = z.permute(0, 1, 3, 2)
|
| 302 |
+
|
| 303 |
+
return self.first_stage_model.decode(z)
|
| 304 |
+
|
| 305 |
+
def save_wav(self, mel, savepath=None):
|
| 306 |
+
|
| 307 |
+
mel = mel.squeeze(1)
|
| 308 |
+
waveform = self.first_stage_model.vocoder(mel)
|
| 309 |
+
waveform = waveform[: 10 * 44100]
|
| 310 |
+
sf.write(savepath, waveform, samplerate=44100)
|
| 311 |
+
|
| 312 |
+
def apply_model(self, x_noisy, t, cond, return_ids=False):
|
| 313 |
+
x_recon = self.model(x_noisy, t, cond=cond)
|
| 314 |
+
return x_recon
|
| 315 |
+
|
| 316 |
+
@torch.no_grad()
|
| 317 |
+
def sample_log(
|
| 318 |
+
self,
|
| 319 |
+
cond,
|
| 320 |
+
batch_size,
|
| 321 |
+
ddim,
|
| 322 |
+
ddim_steps,
|
| 323 |
+
cfg=1.0,
|
| 324 |
+
uncond=None,
|
| 325 |
+
use_plms=False,
|
| 326 |
+
mask=None,
|
| 327 |
+
wav_sec=None,
|
| 328 |
+
**kwargs,
|
| 329 |
+
):
|
| 330 |
+
|
| 331 |
+
latent_width = self.latent_t_size
|
| 332 |
+
|
| 333 |
+
shape = (self.channels, latent_width, self.latent_f_size)
|
| 334 |
+
|
| 335 |
+
intermediate = None
|
| 336 |
+
|
| 337 |
+
ddim_sampler = DDIMSampler(self)
|
| 338 |
+
samples, _ = ddim_sampler.sample(
|
| 339 |
+
ddim_steps,
|
| 340 |
+
batch_size,
|
| 341 |
+
shape,
|
| 342 |
+
cond,
|
| 343 |
+
verbose=False,
|
| 344 |
+
unconditional_guidance_scale=cfg,
|
| 345 |
+
unconditional_conditioning=uncond,
|
| 346 |
+
mask=mask,
|
| 347 |
+
**kwargs,
|
| 348 |
+
)
|
| 349 |
+
|
| 350 |
+
return samples
|
| 351 |
+
|
| 352 |
+
@torch.no_grad()
|
| 353 |
+
def generate_sample(
|
| 354 |
+
self,
|
| 355 |
+
textlist=[],
|
| 356 |
+
name=None,
|
| 357 |
+
cfg=3.5,
|
| 358 |
+
ddim_steps=200,
|
| 359 |
+
outputdir="",
|
| 360 |
+
quite=False,
|
| 361 |
+
wav_sec=4,
|
| 362 |
+
):
|
| 363 |
+
|
| 364 |
+
batch_size = len(textlist)
|
| 365 |
+
|
| 366 |
+
save_path = os.path.join(outputdir, name + ".wav")
|
| 367 |
+
xc = textlist
|
| 368 |
+
|
| 369 |
+
cond = {}
|
| 370 |
+
cond[self.conditioning_key] = self.cond_stage_model.get_cond(xc)
|
| 371 |
+
|
| 372 |
+
uncond = {}
|
| 373 |
+
uncond[self.conditioning_key] = self.cond_stage_model.get_uncond(batch_size)
|
| 374 |
+
|
| 375 |
+
samples = self.sample_log(
|
| 376 |
+
cond=cond,
|
| 377 |
+
batch_size=batch_size,
|
| 378 |
+
x_T=None,
|
| 379 |
+
ddim=True,
|
| 380 |
+
ddim_steps=ddim_steps,
|
| 381 |
+
eta=1.0,
|
| 382 |
+
cfg=cfg,
|
| 383 |
+
uncond=uncond,
|
| 384 |
+
use_plms=False,
|
| 385 |
+
wav_sec=wav_sec,
|
| 386 |
+
)
|
| 387 |
+
mel = self.decode_first_stage(samples)
|
| 388 |
+
os.makedirs(outputdir, exist_ok=True)
|
| 389 |
+
self.save_wav(mel, savepath=save_path)
|
| 390 |
+
|
| 391 |
+
|
| 392 |
+
class DiffusionWrapper(pl.LightningModule):
|
| 393 |
+
def __init__(self, diff_model_config, conditioning_key):
|
| 394 |
+
super().__init__()
|
| 395 |
+
self.diffusion_model = instantiate_from_config(diff_model_config)
|
| 396 |
+
self.conditioning_key = conditioning_key
|
| 397 |
+
|
| 398 |
+
def forward(self, x, t, cond):
|
| 399 |
+
|
| 400 |
+
xc = x
|
| 401 |
+
context, mask = cond[self.conditioning_key]
|
| 402 |
+
out = self.diffusion_model(xc, t=t, context=context, mask=mask)
|
| 403 |
+
return out
|
ldm/modules/latent_encoder/__init__.py
ADDED
|
File without changes
|
ldm/modules/latent_encoder/__pycache__/__init__.cpython-310.pyc
ADDED
|
Binary file (166 Bytes). View file
|
|
|
ldm/modules/latent_encoder/__pycache__/__init__.cpython-38.pyc
ADDED
|
Binary file (197 Bytes). View file
|
|
|
ldm/modules/latent_encoder/__pycache__/__init__.cpython-39.pyc
ADDED
|
Binary file (188 Bytes). View file
|
|
|
ldm/modules/latent_encoder/__pycache__/autoencoder.cpython-310.pyc
ADDED
|
Binary file (2.2 kB). View file
|
|
|
ldm/modules/latent_encoder/__pycache__/autoencoder.cpython-38.pyc
ADDED
|
Binary file (13.8 kB). View file
|
|
|
ldm/modules/latent_encoder/__pycache__/autoencoder.cpython-39.pyc
ADDED
|
Binary file (2.22 kB). View file
|
|
|
ldm/modules/latent_encoder/__pycache__/autoencoder1d.cpython-310.pyc
ADDED
|
Binary file (15.2 kB). View file
|
|
|
ldm/modules/latent_encoder/__pycache__/autoencoder1d.cpython-38.pyc
ADDED
|
Binary file (15.2 kB). View file
|
|
|
ldm/modules/latent_encoder/__pycache__/model.cpython-310.pyc
ADDED
|
Binary file (20.4 kB). View file
|
|
|
ldm/modules/latent_encoder/__pycache__/model.cpython-38.pyc
ADDED
|
Binary file (20.8 kB). View file
|
|
|
ldm/modules/latent_encoder/__pycache__/model.cpython-39.pyc
ADDED
|
Binary file (20.6 kB). View file
|
|
|
ldm/modules/latent_encoder/autoencoder.py
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import torch
|
| 3 |
+
import logging
|
| 4 |
+
import pytorch_lightning as pl
|
| 5 |
+
|
| 6 |
+
from ldm.modules.bigvgan.bigvgan import VocoderBigVGAN
|
| 7 |
+
from ldm.modules.latent_encoder.model import Encoder, Decoder
|
| 8 |
+
|
| 9 |
+
from ldm.modules.diffusionmodules.distributions import (
|
| 10 |
+
DiagonalGaussianDistribution,
|
| 11 |
+
)
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
import soundfile as sf
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
class AutoencoderKL(pl.LightningModule):
|
| 18 |
+
def __init__(
|
| 19 |
+
self,
|
| 20 |
+
ddconfig=None,
|
| 21 |
+
embed_dim=None,
|
| 22 |
+
reload_from_ckpt=None,
|
| 23 |
+
ignore_keys=[],
|
| 24 |
+
vocoder_path=None,
|
| 25 |
+
):
|
| 26 |
+
super().__init__()
|
| 27 |
+
|
| 28 |
+
self.encoder = Encoder(**ddconfig)
|
| 29 |
+
self.decoder = Decoder(**ddconfig)
|
| 30 |
+
self.vocoder_path = vocoder_path
|
| 31 |
+
|
| 32 |
+
self.quant_conv = torch.nn.Conv2d(2 * ddconfig["z_channels"], 2 * embed_dim, 1)
|
| 33 |
+
self.post_quant_conv = torch.nn.Conv2d(embed_dim, ddconfig["z_channels"], 1)
|
| 34 |
+
|
| 35 |
+
self.vocoder = VocoderBigVGAN(self.vocoder_path, device="cuda")
|
| 36 |
+
self.reload_from_ckpt = reload_from_ckpt
|
| 37 |
+
|
| 38 |
+
if self.reload_from_ckpt is not None:
|
| 39 |
+
checkpoint = torch.load(self.reload_from_ckpt)
|
| 40 |
+
|
| 41 |
+
load_todo_keys = {}
|
| 42 |
+
|
| 43 |
+
pretrained_state_dict = checkpoint
|
| 44 |
+
current_state_dict = self.state_dict()
|
| 45 |
+
for key in current_state_dict:
|
| 46 |
+
if (
|
| 47 |
+
key in pretrained_state_dict.keys()
|
| 48 |
+
and pretrained_state_dict[key].size()
|
| 49 |
+
== current_state_dict[key].size()
|
| 50 |
+
):
|
| 51 |
+
load_todo_keys[key] = pretrained_state_dict[key]
|
| 52 |
+
else:
|
| 53 |
+
logging.info("Key %s mismatch during loading, seems fine" % key)
|
| 54 |
+
|
| 55 |
+
self.load_state_dict(load_todo_keys, strict=False)
|
| 56 |
+
self.reloaded = True
|
| 57 |
+
else:
|
| 58 |
+
logging.info("Train from scratch")
|
| 59 |
+
|
| 60 |
+
def encode(self, x):
|
| 61 |
+
h = self.encoder(x)
|
| 62 |
+
moments = self.quant_conv(h)
|
| 63 |
+
posterior = DiagonalGaussianDistribution(moments)
|
| 64 |
+
|
| 65 |
+
return posterior
|
| 66 |
+
|
| 67 |
+
def decode(self, z):
|
| 68 |
+
z = self.post_quant_conv(z)
|
| 69 |
+
fbk = self.decoder(z)
|
| 70 |
+
|
| 71 |
+
return fbk
|
| 72 |
+
|
| 73 |
+
def forward(self, input, sample_posterior=True):
|
| 74 |
+
posterior = self.encode(input)
|
| 75 |
+
z = posterior.sample()
|
| 76 |
+
dec = self.decode(z)
|
| 77 |
+
|
| 78 |
+
return dec, posterior
|
ldm/modules/latent_encoder/model.py
ADDED
|
@@ -0,0 +1,1013 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import math
|
| 2 |
+
import torch
|
| 3 |
+
import torch.nn as nn
|
| 4 |
+
import numpy as np
|
| 5 |
+
from einops import rearrange
|
| 6 |
+
|
| 7 |
+
from ldm.utils.util import instantiate_from_config
|
| 8 |
+
from ldm.modules.diffusionmodules.attention import LinearAttention
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def get_timestep_embedding(timesteps, embedding_dim):
|
| 12 |
+
"""
|
| 13 |
+
This matches the implementation in Denoising Diffusion Probabilistic Models:
|
| 14 |
+
From Fairseq.
|
| 15 |
+
Build sinusoidal embeddings.
|
| 16 |
+
This matches the implementation in tensor2tensor, but differs slightly
|
| 17 |
+
from the description in Section 3.5 of "Attention Is All You Need".
|
| 18 |
+
"""
|
| 19 |
+
assert len(timesteps.shape) == 1
|
| 20 |
+
|
| 21 |
+
half_dim = embedding_dim // 2
|
| 22 |
+
emb = math.log(10000) / (half_dim - 1)
|
| 23 |
+
emb = torch.exp(torch.arange(half_dim, dtype=torch.float32) * -emb)
|
| 24 |
+
emb = emb.to(device=timesteps.device)
|
| 25 |
+
emb = timesteps.float()[:, None] * emb[None, :]
|
| 26 |
+
emb = torch.cat([torch.sin(emb), torch.cos(emb)], dim=1)
|
| 27 |
+
if embedding_dim % 2 == 1: # zero pad
|
| 28 |
+
emb = torch.nn.functional.pad(emb, (0, 1, 0, 0))
|
| 29 |
+
return emb
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def nonlinearity(x):
|
| 33 |
+
# swish
|
| 34 |
+
return x * torch.sigmoid(x)
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
def Normalize(in_channels, num_groups=32):
|
| 38 |
+
return torch.nn.GroupNorm(
|
| 39 |
+
num_groups=num_groups, num_channels=in_channels, eps=1e-6, affine=True
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
class Upsample(nn.Module):
|
| 44 |
+
def __init__(self, in_channels, with_conv):
|
| 45 |
+
super().__init__()
|
| 46 |
+
self.with_conv = with_conv
|
| 47 |
+
if self.with_conv:
|
| 48 |
+
self.conv = torch.nn.Conv2d(
|
| 49 |
+
in_channels, in_channels, kernel_size=3, stride=1, padding=1
|
| 50 |
+
)
|
| 51 |
+
|
| 52 |
+
def forward(self, x):
|
| 53 |
+
x = torch.nn.functional.interpolate(x, scale_factor=2.0, mode="nearest")
|
| 54 |
+
if self.with_conv:
|
| 55 |
+
x = self.conv(x)
|
| 56 |
+
return x
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
class Downsample(nn.Module):
|
| 60 |
+
def __init__(self, in_channels, with_conv):
|
| 61 |
+
super().__init__()
|
| 62 |
+
self.with_conv = with_conv
|
| 63 |
+
|
| 64 |
+
if self.with_conv:
|
| 65 |
+
# no asymmetric padding in torch conv, must do it ourselves
|
| 66 |
+
self.conv = torch.nn.Conv2d(
|
| 67 |
+
in_channels, in_channels, kernel_size=3, stride=2, padding=0
|
| 68 |
+
)
|
| 69 |
+
|
| 70 |
+
def forward(self, x):
|
| 71 |
+
if self.with_conv:
|
| 72 |
+
pad = (0, 1, 0, 1)
|
| 73 |
+
x = torch.nn.functional.pad(x, pad, mode="constant", value=0)
|
| 74 |
+
x = self.conv(x)
|
| 75 |
+
else:
|
| 76 |
+
x = torch.nn.functional.avg_pool2d(x, kernel_size=2, stride=2)
|
| 77 |
+
return x
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
class ResnetBlock(nn.Module):
|
| 81 |
+
def __init__(
|
| 82 |
+
self,
|
| 83 |
+
*,
|
| 84 |
+
in_channels,
|
| 85 |
+
out_channels=None,
|
| 86 |
+
conv_shortcut=False,
|
| 87 |
+
dropout,
|
| 88 |
+
temb_channels=512,
|
| 89 |
+
):
|
| 90 |
+
super().__init__()
|
| 91 |
+
self.in_channels = in_channels
|
| 92 |
+
out_channels = in_channels if out_channels is None else out_channels
|
| 93 |
+
self.out_channels = out_channels
|
| 94 |
+
self.use_conv_shortcut = conv_shortcut
|
| 95 |
+
|
| 96 |
+
self.norm1 = Normalize(in_channels)
|
| 97 |
+
self.conv1 = torch.nn.Conv2d(
|
| 98 |
+
in_channels, out_channels, kernel_size=3, stride=1, padding=1
|
| 99 |
+
)
|
| 100 |
+
if temb_channels > 0:
|
| 101 |
+
self.temb_proj = torch.nn.Linear(temb_channels, out_channels)
|
| 102 |
+
self.norm2 = Normalize(out_channels)
|
| 103 |
+
self.dropout = torch.nn.Dropout(dropout)
|
| 104 |
+
self.conv2 = torch.nn.Conv2d(
|
| 105 |
+
out_channels, out_channels, kernel_size=3, stride=1, padding=1
|
| 106 |
+
)
|
| 107 |
+
if self.in_channels != self.out_channels:
|
| 108 |
+
if self.use_conv_shortcut:
|
| 109 |
+
self.conv_shortcut = torch.nn.Conv2d(
|
| 110 |
+
in_channels, out_channels, kernel_size=3, stride=1, padding=1
|
| 111 |
+
)
|
| 112 |
+
else:
|
| 113 |
+
self.nin_shortcut = torch.nn.Conv2d(
|
| 114 |
+
in_channels, out_channels, kernel_size=1, stride=1, padding=0
|
| 115 |
+
)
|
| 116 |
+
|
| 117 |
+
def forward(self, x, temb):
|
| 118 |
+
h = x
|
| 119 |
+
h = self.norm1(h)
|
| 120 |
+
h = nonlinearity(h)
|
| 121 |
+
h = self.conv1(h)
|
| 122 |
+
|
| 123 |
+
if temb is not None:
|
| 124 |
+
h = h + self.temb_proj(nonlinearity(temb))[:, :, None, None]
|
| 125 |
+
|
| 126 |
+
h = self.norm2(h)
|
| 127 |
+
h = nonlinearity(h)
|
| 128 |
+
h = self.dropout(h)
|
| 129 |
+
h = self.conv2(h)
|
| 130 |
+
|
| 131 |
+
if self.in_channels != self.out_channels:
|
| 132 |
+
if self.use_conv_shortcut:
|
| 133 |
+
x = self.conv_shortcut(x)
|
| 134 |
+
else:
|
| 135 |
+
x = self.nin_shortcut(x)
|
| 136 |
+
|
| 137 |
+
return x + h
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
class LinAttnBlock(LinearAttention):
|
| 141 |
+
"""to match AttnBlock usage"""
|
| 142 |
+
|
| 143 |
+
def __init__(self, in_channels):
|
| 144 |
+
super().__init__(dim=in_channels, heads=1, dim_head=in_channels)
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
class AttnBlock(nn.Module):
|
| 148 |
+
def __init__(self, in_channels):
|
| 149 |
+
super().__init__()
|
| 150 |
+
self.in_channels = in_channels
|
| 151 |
+
|
| 152 |
+
self.norm = Normalize(in_channels)
|
| 153 |
+
self.q = torch.nn.Conv2d(
|
| 154 |
+
in_channels, in_channels, kernel_size=1, stride=1, padding=0
|
| 155 |
+
)
|
| 156 |
+
self.k = torch.nn.Conv2d(
|
| 157 |
+
in_channels, in_channels, kernel_size=1, stride=1, padding=0
|
| 158 |
+
)
|
| 159 |
+
self.v = torch.nn.Conv2d(
|
| 160 |
+
in_channels, in_channels, kernel_size=1, stride=1, padding=0
|
| 161 |
+
)
|
| 162 |
+
self.proj_out = torch.nn.Conv2d(
|
| 163 |
+
in_channels, in_channels, kernel_size=1, stride=1, padding=0
|
| 164 |
+
)
|
| 165 |
+
|
| 166 |
+
def forward(self, x):
|
| 167 |
+
h_ = x
|
| 168 |
+
h_ = self.norm(h_)
|
| 169 |
+
q = self.q(h_)
|
| 170 |
+
k = self.k(h_)
|
| 171 |
+
v = self.v(h_)
|
| 172 |
+
|
| 173 |
+
# compute attention
|
| 174 |
+
b, c, h, w = q.shape
|
| 175 |
+
q = q.reshape(b, c, h * w)
|
| 176 |
+
q = q.permute(0, 2, 1)
|
| 177 |
+
k = k.reshape(b, c, h * w)
|
| 178 |
+
w_ = torch.bmm(q, k)
|
| 179 |
+
w_ = w_ * (int(c) ** (-0.5))
|
| 180 |
+
w_ = torch.nn.functional.softmax(w_, dim=2)
|
| 181 |
+
|
| 182 |
+
# attend to values
|
| 183 |
+
v = v.reshape(b, c, h * w)
|
| 184 |
+
w_ = w_.permute(0, 2, 1)
|
| 185 |
+
h_ = torch.bmm(v, w_)
|
| 186 |
+
h_ = h_.reshape(b, c, h, w)
|
| 187 |
+
|
| 188 |
+
h_ = self.proj_out(h_)
|
| 189 |
+
|
| 190 |
+
return x + h_
|
| 191 |
+
|
| 192 |
+
|
| 193 |
+
def make_attn(in_channels, attn_type="vanilla"):
|
| 194 |
+
assert attn_type in ["vanilla", "linear", "none"], f"attn_type {attn_type} unknown"
|
| 195 |
+
print(f"making attention of type '{attn_type}' with {in_channels} in_channels")
|
| 196 |
+
if attn_type == "vanilla":
|
| 197 |
+
return AttnBlock(in_channels)
|
| 198 |
+
elif attn_type == "none":
|
| 199 |
+
return nn.Identity(in_channels)
|
| 200 |
+
else:
|
| 201 |
+
return LinAttnBlock(in_channels)
|
| 202 |
+
|
| 203 |
+
|
| 204 |
+
class Model(nn.Module):
|
| 205 |
+
def __init__(
|
| 206 |
+
self,
|
| 207 |
+
*,
|
| 208 |
+
ch,
|
| 209 |
+
out_ch,
|
| 210 |
+
ch_mult=(1, 2, 4, 8),
|
| 211 |
+
num_res_blocks,
|
| 212 |
+
attn_resolutions,
|
| 213 |
+
dropout=0.0,
|
| 214 |
+
resamp_with_conv=True,
|
| 215 |
+
in_channels,
|
| 216 |
+
resolution,
|
| 217 |
+
use_timestep=True,
|
| 218 |
+
use_linear_attn=False,
|
| 219 |
+
attn_type="vanilla",
|
| 220 |
+
):
|
| 221 |
+
super().__init__()
|
| 222 |
+
if use_linear_attn:
|
| 223 |
+
attn_type = "linear"
|
| 224 |
+
self.ch = ch
|
| 225 |
+
self.temb_ch = self.ch * 4
|
| 226 |
+
self.num_resolutions = len(ch_mult)
|
| 227 |
+
self.num_res_blocks = num_res_blocks
|
| 228 |
+
self.resolution = resolution
|
| 229 |
+
self.in_channels = in_channels
|
| 230 |
+
|
| 231 |
+
self.use_timestep = use_timestep
|
| 232 |
+
if self.use_timestep:
|
| 233 |
+
|
| 234 |
+
self.temb = nn.Module()
|
| 235 |
+
self.temb.dense = nn.ModuleList(
|
| 236 |
+
[
|
| 237 |
+
torch.nn.Linear(self.ch, self.temb_ch),
|
| 238 |
+
torch.nn.Linear(self.temb_ch, self.temb_ch),
|
| 239 |
+
]
|
| 240 |
+
)
|
| 241 |
+
|
| 242 |
+
# downsampling
|
| 243 |
+
self.conv_in = torch.nn.Conv2d(
|
| 244 |
+
in_channels, self.ch, kernel_size=3, stride=1, padding=1
|
| 245 |
+
)
|
| 246 |
+
|
| 247 |
+
curr_res = resolution
|
| 248 |
+
in_ch_mult = (1,) + tuple(ch_mult)
|
| 249 |
+
self.down = nn.ModuleList()
|
| 250 |
+
for i_level in range(self.num_resolutions):
|
| 251 |
+
block = nn.ModuleList()
|
| 252 |
+
attn = nn.ModuleList()
|
| 253 |
+
block_in = ch * in_ch_mult[i_level]
|
| 254 |
+
block_out = ch * ch_mult[i_level]
|
| 255 |
+
for i_block in range(self.num_res_blocks):
|
| 256 |
+
block.append(
|
| 257 |
+
ResnetBlock(
|
| 258 |
+
in_channels=block_in,
|
| 259 |
+
out_channels=block_out,
|
| 260 |
+
temb_channels=self.temb_ch,
|
| 261 |
+
dropout=dropout,
|
| 262 |
+
)
|
| 263 |
+
)
|
| 264 |
+
block_in = block_out
|
| 265 |
+
if curr_res in attn_resolutions:
|
| 266 |
+
attn.append(make_attn(block_in, attn_type=attn_type))
|
| 267 |
+
down = nn.Module()
|
| 268 |
+
down.block = block
|
| 269 |
+
down.attn = attn
|
| 270 |
+
if i_level != self.num_resolutions - 1:
|
| 271 |
+
down.downsample = Downsample(block_in, resamp_with_conv)
|
| 272 |
+
curr_res = curr_res // 2
|
| 273 |
+
self.down.append(down)
|
| 274 |
+
|
| 275 |
+
# middle
|
| 276 |
+
self.mid = nn.Module()
|
| 277 |
+
self.mid.block_1 = ResnetBlock(
|
| 278 |
+
in_channels=block_in,
|
| 279 |
+
out_channels=block_in,
|
| 280 |
+
temb_channels=self.temb_ch,
|
| 281 |
+
dropout=dropout,
|
| 282 |
+
)
|
| 283 |
+
self.mid.attn_1 = make_attn(block_in, attn_type=attn_type)
|
| 284 |
+
self.mid.block_2 = ResnetBlock(
|
| 285 |
+
in_channels=block_in,
|
| 286 |
+
out_channels=block_in,
|
| 287 |
+
temb_channels=self.temb_ch,
|
| 288 |
+
dropout=dropout,
|
| 289 |
+
)
|
| 290 |
+
|
| 291 |
+
# upsampling
|
| 292 |
+
self.up = nn.ModuleList()
|
| 293 |
+
for i_level in reversed(range(self.num_resolutions)):
|
| 294 |
+
block = nn.ModuleList()
|
| 295 |
+
attn = nn.ModuleList()
|
| 296 |
+
block_out = ch * ch_mult[i_level]
|
| 297 |
+
skip_in = ch * ch_mult[i_level]
|
| 298 |
+
for i_block in range(self.num_res_blocks + 1):
|
| 299 |
+
if i_block == self.num_res_blocks:
|
| 300 |
+
skip_in = ch * in_ch_mult[i_level]
|
| 301 |
+
block.append(
|
| 302 |
+
ResnetBlock(
|
| 303 |
+
in_channels=block_in + skip_in,
|
| 304 |
+
out_channels=block_out,
|
| 305 |
+
temb_channels=self.temb_ch,
|
| 306 |
+
dropout=dropout,
|
| 307 |
+
)
|
| 308 |
+
)
|
| 309 |
+
block_in = block_out
|
| 310 |
+
if curr_res in attn_resolutions:
|
| 311 |
+
attn.append(make_attn(block_in, attn_type=attn_type))
|
| 312 |
+
up = nn.Module()
|
| 313 |
+
up.block = block
|
| 314 |
+
up.attn = attn
|
| 315 |
+
if i_level != 0:
|
| 316 |
+
up.upsample = Upsample(block_in, resamp_with_conv)
|
| 317 |
+
curr_res = curr_res * 2
|
| 318 |
+
self.up.insert(0, up) # prepend to get consistent order
|
| 319 |
+
|
| 320 |
+
# end
|
| 321 |
+
self.norm_out = Normalize(block_in)
|
| 322 |
+
self.conv_out = torch.nn.Conv2d(
|
| 323 |
+
block_in, out_ch, kernel_size=3, stride=1, padding=1
|
| 324 |
+
)
|
| 325 |
+
|
| 326 |
+
def forward(self, x, t=None, context=None):
|
| 327 |
+
|
| 328 |
+
if context is not None:
|
| 329 |
+
# assume aligned context, cat along channel axis
|
| 330 |
+
x = torch.cat((x, context), dim=1)
|
| 331 |
+
if self.use_timestep:
|
| 332 |
+
|
| 333 |
+
assert t is not None
|
| 334 |
+
temb = get_timestep_embedding(t, self.ch)
|
| 335 |
+
temb = self.temb.dense[0](temb)
|
| 336 |
+
temb = nonlinearity(temb)
|
| 337 |
+
temb = self.temb.dense[1](temb)
|
| 338 |
+
else:
|
| 339 |
+
temb = None
|
| 340 |
+
|
| 341 |
+
# downsampling
|
| 342 |
+
hs = [self.conv_in(x)]
|
| 343 |
+
for i_level in range(self.num_resolutions):
|
| 344 |
+
for i_block in range(self.num_res_blocks):
|
| 345 |
+
h = self.down[i_level].block[i_block](hs[-1], temb)
|
| 346 |
+
if len(self.down[i_level].attn) > 0:
|
| 347 |
+
h = self.down[i_level].attn[i_block](h)
|
| 348 |
+
hs.append(h)
|
| 349 |
+
if i_level != self.num_resolutions - 1:
|
| 350 |
+
hs.append(self.down[i_level].downsample(hs[-1]))
|
| 351 |
+
|
| 352 |
+
# middle
|
| 353 |
+
h = hs[-1]
|
| 354 |
+
h = self.mid.block_1(h, temb)
|
| 355 |
+
h = self.mid.attn_1(h)
|
| 356 |
+
h = self.mid.block_2(h, temb)
|
| 357 |
+
|
| 358 |
+
# upsampling
|
| 359 |
+
for i_level in reversed(range(self.num_resolutions)):
|
| 360 |
+
for i_block in range(self.num_res_blocks + 1):
|
| 361 |
+
h = self.up[i_level].block[i_block](
|
| 362 |
+
torch.cat([h, hs.pop()], dim=1), temb
|
| 363 |
+
)
|
| 364 |
+
if len(self.up[i_level].attn) > 0:
|
| 365 |
+
h = self.up[i_level].attn[i_block](h)
|
| 366 |
+
if i_level != 0:
|
| 367 |
+
h = self.up[i_level].upsample(h)
|
| 368 |
+
|
| 369 |
+
# end
|
| 370 |
+
h = self.norm_out(h)
|
| 371 |
+
h = nonlinearity(h)
|
| 372 |
+
h = self.conv_out(h)
|
| 373 |
+
return h
|
| 374 |
+
|
| 375 |
+
def get_last_layer(self):
|
| 376 |
+
return self.conv_out.weight
|
| 377 |
+
|
| 378 |
+
|
| 379 |
+
class Encoder(nn.Module):
|
| 380 |
+
def __init__(
|
| 381 |
+
self,
|
| 382 |
+
*,
|
| 383 |
+
ch,
|
| 384 |
+
out_ch,
|
| 385 |
+
ch_mult=(1, 2, 4, 8),
|
| 386 |
+
num_res_blocks,
|
| 387 |
+
attn_resolutions,
|
| 388 |
+
dropout=0.0,
|
| 389 |
+
resamp_with_conv=True,
|
| 390 |
+
in_channels,
|
| 391 |
+
resolution,
|
| 392 |
+
z_channels,
|
| 393 |
+
double_z=True,
|
| 394 |
+
use_linear_attn=False,
|
| 395 |
+
attn_type="vanilla",
|
| 396 |
+
**ignore_kwargs,
|
| 397 |
+
):
|
| 398 |
+
super().__init__()
|
| 399 |
+
if use_linear_attn:
|
| 400 |
+
attn_type = "linear"
|
| 401 |
+
self.ch = ch
|
| 402 |
+
self.temb_ch = 0
|
| 403 |
+
self.num_resolutions = len(ch_mult)
|
| 404 |
+
self.num_res_blocks = num_res_blocks
|
| 405 |
+
self.resolution = resolution
|
| 406 |
+
self.in_channels = in_channels
|
| 407 |
+
|
| 408 |
+
# downsampling
|
| 409 |
+
self.conv_in = torch.nn.Conv2d(
|
| 410 |
+
in_channels, self.ch, kernel_size=3, stride=1, padding=1
|
| 411 |
+
)
|
| 412 |
+
|
| 413 |
+
curr_res = resolution
|
| 414 |
+
in_ch_mult = (1,) + tuple(ch_mult)
|
| 415 |
+
self.in_ch_mult = in_ch_mult
|
| 416 |
+
self.down = nn.ModuleList()
|
| 417 |
+
for i_level in range(self.num_resolutions):
|
| 418 |
+
block = nn.ModuleList()
|
| 419 |
+
attn = nn.ModuleList()
|
| 420 |
+
block_in = ch * in_ch_mult[i_level]
|
| 421 |
+
block_out = ch * ch_mult[i_level]
|
| 422 |
+
for i_block in range(self.num_res_blocks):
|
| 423 |
+
block.append(
|
| 424 |
+
ResnetBlock(
|
| 425 |
+
in_channels=block_in,
|
| 426 |
+
out_channels=block_out,
|
| 427 |
+
temb_channels=self.temb_ch,
|
| 428 |
+
dropout=dropout,
|
| 429 |
+
)
|
| 430 |
+
)
|
| 431 |
+
block_in = block_out
|
| 432 |
+
if curr_res in attn_resolutions:
|
| 433 |
+
|
| 434 |
+
attn.append(make_attn(block_in, attn_type=attn_type))
|
| 435 |
+
down = nn.Module()
|
| 436 |
+
down.block = block
|
| 437 |
+
down.attn = attn
|
| 438 |
+
if i_level < self.num_resolutions - 2:
|
| 439 |
+
|
| 440 |
+
down.downsample = Downsample(block_in, resamp_with_conv)
|
| 441 |
+
curr_res = curr_res // 2
|
| 442 |
+
|
| 443 |
+
self.down.append(down)
|
| 444 |
+
|
| 445 |
+
# middle
|
| 446 |
+
self.mid = nn.Module()
|
| 447 |
+
self.mid.block_1 = ResnetBlock(
|
| 448 |
+
in_channels=block_in,
|
| 449 |
+
out_channels=block_in,
|
| 450 |
+
temb_channels=self.temb_ch,
|
| 451 |
+
dropout=dropout,
|
| 452 |
+
)
|
| 453 |
+
self.mid.attn_1 = make_attn(block_in, attn_type=attn_type)
|
| 454 |
+
self.mid.block_2 = ResnetBlock(
|
| 455 |
+
in_channels=block_in,
|
| 456 |
+
out_channels=block_in,
|
| 457 |
+
temb_channels=self.temb_ch,
|
| 458 |
+
dropout=dropout,
|
| 459 |
+
)
|
| 460 |
+
|
| 461 |
+
# end
|
| 462 |
+
self.norm_out = Normalize(block_in)
|
| 463 |
+
self.conv_out = torch.nn.Conv2d(
|
| 464 |
+
block_in,
|
| 465 |
+
2 * z_channels if double_z else z_channels,
|
| 466 |
+
kernel_size=3,
|
| 467 |
+
stride=1,
|
| 468 |
+
padding=1,
|
| 469 |
+
)
|
| 470 |
+
|
| 471 |
+
def forward(self, x):
|
| 472 |
+
|
| 473 |
+
temb = None
|
| 474 |
+
|
| 475 |
+
# downsampling
|
| 476 |
+
hs = [self.conv_in(x)]
|
| 477 |
+
for i_level in range(self.num_resolutions):
|
| 478 |
+
for i_block in range(self.num_res_blocks):
|
| 479 |
+
h = self.down[i_level].block[i_block](hs[-1], temb)
|
| 480 |
+
if len(self.down[i_level].attn) > 0:
|
| 481 |
+
h = self.down[i_level].attn[i_block](h)
|
| 482 |
+
hs.append(h)
|
| 483 |
+
if i_level < self.num_resolutions - 2:
|
| 484 |
+
|
| 485 |
+
hs.append(self.down[i_level].downsample(hs[-1]))
|
| 486 |
+
|
| 487 |
+
# middle
|
| 488 |
+
h = hs[-1]
|
| 489 |
+
h = self.mid.block_1(h, temb)
|
| 490 |
+
h = self.mid.attn_1(h)
|
| 491 |
+
h = self.mid.block_2(h, temb)
|
| 492 |
+
|
| 493 |
+
# end
|
| 494 |
+
h = self.norm_out(h)
|
| 495 |
+
h = nonlinearity(h)
|
| 496 |
+
h = self.conv_out(h)
|
| 497 |
+
return h
|
| 498 |
+
|
| 499 |
+
|
| 500 |
+
class Decoder(nn.Module):
|
| 501 |
+
def __init__(
|
| 502 |
+
self,
|
| 503 |
+
*,
|
| 504 |
+
ch,
|
| 505 |
+
out_ch,
|
| 506 |
+
ch_mult=(1, 2, 4, 8),
|
| 507 |
+
num_res_blocks,
|
| 508 |
+
attn_resolutions,
|
| 509 |
+
dropout=0.0,
|
| 510 |
+
resamp_with_conv=True,
|
| 511 |
+
in_channels,
|
| 512 |
+
resolution,
|
| 513 |
+
z_channels,
|
| 514 |
+
give_pre_end=False,
|
| 515 |
+
tanh_out=False,
|
| 516 |
+
use_linear_attn=False,
|
| 517 |
+
attn_type="vanilla",
|
| 518 |
+
**ignorekwargs,
|
| 519 |
+
):
|
| 520 |
+
super().__init__()
|
| 521 |
+
if use_linear_attn:
|
| 522 |
+
attn_type = "linear"
|
| 523 |
+
self.ch = ch
|
| 524 |
+
self.temb_ch = 0
|
| 525 |
+
self.num_resolutions = len(ch_mult)
|
| 526 |
+
self.num_res_blocks = num_res_blocks
|
| 527 |
+
self.resolution = resolution
|
| 528 |
+
self.in_channels = in_channels
|
| 529 |
+
self.give_pre_end = give_pre_end
|
| 530 |
+
self.tanh_out = tanh_out
|
| 531 |
+
|
| 532 |
+
# compute in_ch_mult, block_in and curr_res at lowest res
|
| 533 |
+
in_ch_mult = (1,) + tuple(ch_mult)
|
| 534 |
+
block_in = ch * ch_mult[self.num_resolutions - 1]
|
| 535 |
+
curr_res = resolution // 2 ** (self.num_resolutions - 1)
|
| 536 |
+
self.z_shape = (1, z_channels, curr_res, curr_res)
|
| 537 |
+
print(
|
| 538 |
+
"Working with z of shape {} = {} dimensions.".format(
|
| 539 |
+
self.z_shape, np.prod(self.z_shape)
|
| 540 |
+
)
|
| 541 |
+
)
|
| 542 |
+
|
| 543 |
+
self.conv_in = torch.nn.Conv2d(
|
| 544 |
+
z_channels, block_in, kernel_size=3, stride=1, padding=1
|
| 545 |
+
)
|
| 546 |
+
|
| 547 |
+
# middle
|
| 548 |
+
self.mid = nn.Module()
|
| 549 |
+
self.mid.block_1 = ResnetBlock(
|
| 550 |
+
in_channels=block_in,
|
| 551 |
+
out_channels=block_in,
|
| 552 |
+
temb_channels=self.temb_ch,
|
| 553 |
+
dropout=dropout,
|
| 554 |
+
)
|
| 555 |
+
self.mid.attn_1 = make_attn(block_in, attn_type=attn_type)
|
| 556 |
+
self.mid.block_2 = ResnetBlock(
|
| 557 |
+
in_channels=block_in,
|
| 558 |
+
out_channels=block_in,
|
| 559 |
+
temb_channels=self.temb_ch,
|
| 560 |
+
dropout=dropout,
|
| 561 |
+
)
|
| 562 |
+
|
| 563 |
+
# upsampling
|
| 564 |
+
self.up = nn.ModuleList()
|
| 565 |
+
for i_level in reversed(range(self.num_resolutions)):
|
| 566 |
+
block = nn.ModuleList()
|
| 567 |
+
attn = nn.ModuleList()
|
| 568 |
+
block_out = ch * ch_mult[i_level]
|
| 569 |
+
for i_block in range(self.num_res_blocks + 1):
|
| 570 |
+
block.append(
|
| 571 |
+
ResnetBlock(
|
| 572 |
+
in_channels=block_in,
|
| 573 |
+
out_channels=block_out,
|
| 574 |
+
temb_channels=self.temb_ch,
|
| 575 |
+
dropout=dropout,
|
| 576 |
+
)
|
| 577 |
+
)
|
| 578 |
+
block_in = block_out
|
| 579 |
+
if curr_res in attn_resolutions:
|
| 580 |
+
|
| 581 |
+
attn.append(make_attn(block_in, attn_type=attn_type))
|
| 582 |
+
up = nn.Module()
|
| 583 |
+
up.block = block
|
| 584 |
+
up.attn = attn
|
| 585 |
+
if i_level > 1:
|
| 586 |
+
|
| 587 |
+
up.upsample = Upsample(block_in, resamp_with_conv)
|
| 588 |
+
curr_res = curr_res * 2
|
| 589 |
+
self.up.insert(0, up) # prepend to get consistent order
|
| 590 |
+
|
| 591 |
+
# end
|
| 592 |
+
self.norm_out = Normalize(block_in)
|
| 593 |
+
self.conv_out = torch.nn.Conv2d(
|
| 594 |
+
block_in, out_ch, kernel_size=3, stride=1, padding=1
|
| 595 |
+
)
|
| 596 |
+
|
| 597 |
+
def forward(self, z):
|
| 598 |
+
|
| 599 |
+
self.last_z_shape = z.shape
|
| 600 |
+
|
| 601 |
+
temb = None
|
| 602 |
+
|
| 603 |
+
h = self.conv_in(z)
|
| 604 |
+
|
| 605 |
+
# middle
|
| 606 |
+
h = self.mid.block_1(h, temb)
|
| 607 |
+
h = self.mid.attn_1(h)
|
| 608 |
+
h = self.mid.block_2(h, temb)
|
| 609 |
+
|
| 610 |
+
# upsampling
|
| 611 |
+
for i_level in reversed(range(self.num_resolutions)):
|
| 612 |
+
for i_block in range(self.num_res_blocks + 1):
|
| 613 |
+
h = self.up[i_level].block[i_block](h, temb)
|
| 614 |
+
if len(self.up[i_level].attn) > 0:
|
| 615 |
+
h = self.up[i_level].attn[i_block](h)
|
| 616 |
+
if i_level > 1:
|
| 617 |
+
|
| 618 |
+
h = self.up[i_level].upsample(h)
|
| 619 |
+
|
| 620 |
+
# end
|
| 621 |
+
if self.give_pre_end:
|
| 622 |
+
return h
|
| 623 |
+
|
| 624 |
+
h = self.norm_out(h)
|
| 625 |
+
h = nonlinearity(h)
|
| 626 |
+
h = self.conv_out(h)
|
| 627 |
+
if self.tanh_out:
|
| 628 |
+
h = torch.tanh(h)
|
| 629 |
+
return h
|
| 630 |
+
|
| 631 |
+
|
| 632 |
+
class SimpleDecoder(nn.Module):
|
| 633 |
+
def __init__(self, in_channels, out_channels, *args, **kwargs):
|
| 634 |
+
super().__init__()
|
| 635 |
+
self.model = nn.ModuleList(
|
| 636 |
+
[
|
| 637 |
+
nn.Conv2d(in_channels, in_channels, 1),
|
| 638 |
+
ResnetBlock(
|
| 639 |
+
in_channels=in_channels,
|
| 640 |
+
out_channels=2 * in_channels,
|
| 641 |
+
temb_channels=0,
|
| 642 |
+
dropout=0.0,
|
| 643 |
+
),
|
| 644 |
+
ResnetBlock(
|
| 645 |
+
in_channels=2 * in_channels,
|
| 646 |
+
out_channels=4 * in_channels,
|
| 647 |
+
temb_channels=0,
|
| 648 |
+
dropout=0.0,
|
| 649 |
+
),
|
| 650 |
+
ResnetBlock(
|
| 651 |
+
in_channels=4 * in_channels,
|
| 652 |
+
out_channels=2 * in_channels,
|
| 653 |
+
temb_channels=0,
|
| 654 |
+
dropout=0.0,
|
| 655 |
+
),
|
| 656 |
+
nn.Conv2d(2 * in_channels, in_channels, 1),
|
| 657 |
+
Upsample(in_channels, with_conv=True),
|
| 658 |
+
]
|
| 659 |
+
)
|
| 660 |
+
# end
|
| 661 |
+
self.norm_out = Normalize(in_channels)
|
| 662 |
+
self.conv_out = torch.nn.Conv2d(
|
| 663 |
+
in_channels, out_channels, kernel_size=3, stride=1, padding=1
|
| 664 |
+
)
|
| 665 |
+
|
| 666 |
+
def forward(self, x):
|
| 667 |
+
for i, layer in enumerate(self.model):
|
| 668 |
+
if i in [1, 2, 3]:
|
| 669 |
+
x = layer(x, None)
|
| 670 |
+
else:
|
| 671 |
+
x = layer(x)
|
| 672 |
+
|
| 673 |
+
h = self.norm_out(x)
|
| 674 |
+
h = nonlinearity(h)
|
| 675 |
+
x = self.conv_out(h)
|
| 676 |
+
return x
|
| 677 |
+
|
| 678 |
+
|
| 679 |
+
class UpsampleDecoder(nn.Module):
|
| 680 |
+
def __init__(
|
| 681 |
+
self,
|
| 682 |
+
in_channels,
|
| 683 |
+
out_channels,
|
| 684 |
+
ch,
|
| 685 |
+
num_res_blocks,
|
| 686 |
+
resolution,
|
| 687 |
+
ch_mult=(2, 2),
|
| 688 |
+
dropout=0.0,
|
| 689 |
+
):
|
| 690 |
+
super().__init__()
|
| 691 |
+
# upsampling
|
| 692 |
+
self.temb_ch = 0
|
| 693 |
+
self.num_resolutions = len(ch_mult)
|
| 694 |
+
self.num_res_blocks = num_res_blocks
|
| 695 |
+
block_in = in_channels
|
| 696 |
+
curr_res = resolution // 2 ** (self.num_resolutions - 1)
|
| 697 |
+
self.res_blocks = nn.ModuleList()
|
| 698 |
+
self.upsample_blocks = nn.ModuleList()
|
| 699 |
+
for i_level in range(self.num_resolutions):
|
| 700 |
+
res_block = []
|
| 701 |
+
block_out = ch * ch_mult[i_level]
|
| 702 |
+
for i_block in range(self.num_res_blocks + 1):
|
| 703 |
+
res_block.append(
|
| 704 |
+
ResnetBlock(
|
| 705 |
+
in_channels=block_in,
|
| 706 |
+
out_channels=block_out,
|
| 707 |
+
temb_channels=self.temb_ch,
|
| 708 |
+
dropout=dropout,
|
| 709 |
+
)
|
| 710 |
+
)
|
| 711 |
+
block_in = block_out
|
| 712 |
+
self.res_blocks.append(nn.ModuleList(res_block))
|
| 713 |
+
if i_level != self.num_resolutions - 1:
|
| 714 |
+
self.upsample_blocks.append(Upsample(block_in, True))
|
| 715 |
+
curr_res = curr_res * 2
|
| 716 |
+
|
| 717 |
+
# end
|
| 718 |
+
self.norm_out = Normalize(block_in)
|
| 719 |
+
self.conv_out = torch.nn.Conv2d(
|
| 720 |
+
block_in, out_channels, kernel_size=3, stride=1, padding=1
|
| 721 |
+
)
|
| 722 |
+
|
| 723 |
+
def forward(self, x):
|
| 724 |
+
# upsampling
|
| 725 |
+
h = x
|
| 726 |
+
for k, i_level in enumerate(range(self.num_resolutions)):
|
| 727 |
+
for i_block in range(self.num_res_blocks + 1):
|
| 728 |
+
h = self.res_blocks[i_level][i_block](h, None)
|
| 729 |
+
if i_level != self.num_resolutions - 1:
|
| 730 |
+
h = self.upsample_blocks[k](h)
|
| 731 |
+
h = self.norm_out(h)
|
| 732 |
+
h = nonlinearity(h)
|
| 733 |
+
h = self.conv_out(h)
|
| 734 |
+
return h
|
| 735 |
+
|
| 736 |
+
|
| 737 |
+
class LatentRescaler(nn.Module):
|
| 738 |
+
def __init__(self, factor, in_channels, mid_channels, out_channels, depth=2):
|
| 739 |
+
super().__init__()
|
| 740 |
+
# residual block, interpolate, residual block
|
| 741 |
+
self.factor = factor
|
| 742 |
+
self.conv_in = nn.Conv2d(
|
| 743 |
+
in_channels, mid_channels, kernel_size=3, stride=1, padding=1
|
| 744 |
+
)
|
| 745 |
+
self.res_block1 = nn.ModuleList(
|
| 746 |
+
[
|
| 747 |
+
ResnetBlock(
|
| 748 |
+
in_channels=mid_channels,
|
| 749 |
+
out_channels=mid_channels,
|
| 750 |
+
temb_channels=0,
|
| 751 |
+
dropout=0.0,
|
| 752 |
+
)
|
| 753 |
+
for _ in range(depth)
|
| 754 |
+
]
|
| 755 |
+
)
|
| 756 |
+
self.attn = AttnBlock(mid_channels)
|
| 757 |
+
self.res_block2 = nn.ModuleList(
|
| 758 |
+
[
|
| 759 |
+
ResnetBlock(
|
| 760 |
+
in_channels=mid_channels,
|
| 761 |
+
out_channels=mid_channels,
|
| 762 |
+
temb_channels=0,
|
| 763 |
+
dropout=0.0,
|
| 764 |
+
)
|
| 765 |
+
for _ in range(depth)
|
| 766 |
+
]
|
| 767 |
+
)
|
| 768 |
+
|
| 769 |
+
self.conv_out = nn.Conv2d(
|
| 770 |
+
mid_channels,
|
| 771 |
+
out_channels,
|
| 772 |
+
kernel_size=1,
|
| 773 |
+
)
|
| 774 |
+
|
| 775 |
+
def forward(self, x):
|
| 776 |
+
x = self.conv_in(x)
|
| 777 |
+
for block in self.res_block1:
|
| 778 |
+
x = block(x, None)
|
| 779 |
+
x = torch.nn.functional.interpolate(
|
| 780 |
+
x,
|
| 781 |
+
size=(
|
| 782 |
+
int(round(x.shape[2] * self.factor)),
|
| 783 |
+
int(round(x.shape[3] * self.factor)),
|
| 784 |
+
),
|
| 785 |
+
)
|
| 786 |
+
x = self.attn(x)
|
| 787 |
+
for block in self.res_block2:
|
| 788 |
+
x = block(x, None)
|
| 789 |
+
x = self.conv_out(x)
|
| 790 |
+
return x
|
| 791 |
+
|
| 792 |
+
|
| 793 |
+
class MergedRescaleEncoder(nn.Module):
|
| 794 |
+
def __init__(
|
| 795 |
+
self,
|
| 796 |
+
in_channels,
|
| 797 |
+
ch,
|
| 798 |
+
resolution,
|
| 799 |
+
out_ch,
|
| 800 |
+
num_res_blocks,
|
| 801 |
+
attn_resolutions,
|
| 802 |
+
dropout=0.0,
|
| 803 |
+
resamp_with_conv=True,
|
| 804 |
+
ch_mult=(1, 2, 4, 8),
|
| 805 |
+
rescale_factor=1.0,
|
| 806 |
+
rescale_module_depth=1,
|
| 807 |
+
):
|
| 808 |
+
super().__init__()
|
| 809 |
+
intermediate_chn = ch * ch_mult[-1]
|
| 810 |
+
self.encoder = Encoder(
|
| 811 |
+
in_channels=in_channels,
|
| 812 |
+
num_res_blocks=num_res_blocks,
|
| 813 |
+
ch=ch,
|
| 814 |
+
ch_mult=ch_mult,
|
| 815 |
+
z_channels=intermediate_chn,
|
| 816 |
+
double_z=False,
|
| 817 |
+
resolution=resolution,
|
| 818 |
+
attn_resolutions=attn_resolutions,
|
| 819 |
+
dropout=dropout,
|
| 820 |
+
resamp_with_conv=resamp_with_conv,
|
| 821 |
+
out_ch=None,
|
| 822 |
+
)
|
| 823 |
+
self.rescaler = LatentRescaler(
|
| 824 |
+
factor=rescale_factor,
|
| 825 |
+
in_channels=intermediate_chn,
|
| 826 |
+
mid_channels=intermediate_chn,
|
| 827 |
+
out_channels=out_ch,
|
| 828 |
+
depth=rescale_module_depth,
|
| 829 |
+
)
|
| 830 |
+
|
| 831 |
+
def forward(self, x):
|
| 832 |
+
x = self.encoder(x)
|
| 833 |
+
x = self.rescaler(x)
|
| 834 |
+
return x
|
| 835 |
+
|
| 836 |
+
|
| 837 |
+
class MergedRescaleDecoder(nn.Module):
|
| 838 |
+
def __init__(
|
| 839 |
+
self,
|
| 840 |
+
z_channels,
|
| 841 |
+
out_ch,
|
| 842 |
+
resolution,
|
| 843 |
+
num_res_blocks,
|
| 844 |
+
attn_resolutions,
|
| 845 |
+
ch,
|
| 846 |
+
ch_mult=(1, 2, 4, 8),
|
| 847 |
+
dropout=0.0,
|
| 848 |
+
resamp_with_conv=True,
|
| 849 |
+
rescale_factor=1.0,
|
| 850 |
+
rescale_module_depth=1,
|
| 851 |
+
):
|
| 852 |
+
super().__init__()
|
| 853 |
+
tmp_chn = z_channels * ch_mult[-1]
|
| 854 |
+
self.decoder = Decoder(
|
| 855 |
+
out_ch=out_ch,
|
| 856 |
+
z_channels=tmp_chn,
|
| 857 |
+
attn_resolutions=attn_resolutions,
|
| 858 |
+
dropout=dropout,
|
| 859 |
+
resamp_with_conv=resamp_with_conv,
|
| 860 |
+
in_channels=None,
|
| 861 |
+
num_res_blocks=num_res_blocks,
|
| 862 |
+
ch_mult=ch_mult,
|
| 863 |
+
resolution=resolution,
|
| 864 |
+
ch=ch,
|
| 865 |
+
)
|
| 866 |
+
self.rescaler = LatentRescaler(
|
| 867 |
+
factor=rescale_factor,
|
| 868 |
+
in_channels=z_channels,
|
| 869 |
+
mid_channels=tmp_chn,
|
| 870 |
+
out_channels=tmp_chn,
|
| 871 |
+
depth=rescale_module_depth,
|
| 872 |
+
)
|
| 873 |
+
|
| 874 |
+
def forward(self, x):
|
| 875 |
+
x = self.rescaler(x)
|
| 876 |
+
x = self.decoder(x)
|
| 877 |
+
return x
|
| 878 |
+
|
| 879 |
+
|
| 880 |
+
class Upsampler(nn.Module):
|
| 881 |
+
def __init__(self, in_size, out_size, in_channels, out_channels, ch_mult=2):
|
| 882 |
+
super().__init__()
|
| 883 |
+
assert out_size >= in_size
|
| 884 |
+
num_blocks = int(np.log2(out_size // in_size)) + 1
|
| 885 |
+
factor_up = 1.0 + (out_size % in_size)
|
| 886 |
+
print(
|
| 887 |
+
f"Building {self.__class__.__name__} with in_size: {in_size} --> out_size {out_size} and factor {factor_up}"
|
| 888 |
+
)
|
| 889 |
+
self.rescaler = LatentRescaler(
|
| 890 |
+
factor=factor_up,
|
| 891 |
+
in_channels=in_channels,
|
| 892 |
+
mid_channels=2 * in_channels,
|
| 893 |
+
out_channels=in_channels,
|
| 894 |
+
)
|
| 895 |
+
self.decoder = Decoder(
|
| 896 |
+
out_ch=out_channels,
|
| 897 |
+
resolution=out_size,
|
| 898 |
+
z_channels=in_channels,
|
| 899 |
+
num_res_blocks=2,
|
| 900 |
+
attn_resolutions=[],
|
| 901 |
+
in_channels=None,
|
| 902 |
+
ch=in_channels,
|
| 903 |
+
ch_mult=[ch_mult for _ in range(num_blocks)],
|
| 904 |
+
)
|
| 905 |
+
|
| 906 |
+
def forward(self, x):
|
| 907 |
+
x = self.rescaler(x)
|
| 908 |
+
x = self.decoder(x)
|
| 909 |
+
return x
|
| 910 |
+
|
| 911 |
+
|
| 912 |
+
class Resize(nn.Module):
|
| 913 |
+
def __init__(self, in_channels=None, learned=False, mode="bilinear"):
|
| 914 |
+
super().__init__()
|
| 915 |
+
self.with_conv = learned
|
| 916 |
+
self.mode = mode
|
| 917 |
+
if self.with_conv:
|
| 918 |
+
print(
|
| 919 |
+
f"Note: {self.__class__.__name} uses learned downsampling and will ignore the fixed {mode} mode"
|
| 920 |
+
)
|
| 921 |
+
raise NotImplementedError()
|
| 922 |
+
assert in_channels is not None
|
| 923 |
+
# no asymmetric padding in torch conv, must do it ourselves
|
| 924 |
+
self.conv = torch.nn.Conv2d(
|
| 925 |
+
in_channels, in_channels, kernel_size=4, stride=2, padding=1
|
| 926 |
+
)
|
| 927 |
+
|
| 928 |
+
def forward(self, x, scale_factor=1.0):
|
| 929 |
+
if scale_factor == 1.0:
|
| 930 |
+
return x
|
| 931 |
+
else:
|
| 932 |
+
x = torch.nn.functional.interpolate(
|
| 933 |
+
x, mode=self.mode, align_corners=False, scale_factor=scale_factor
|
| 934 |
+
)
|
| 935 |
+
return x
|
| 936 |
+
|
| 937 |
+
|
| 938 |
+
class FirstStagePostProcessor(nn.Module):
|
| 939 |
+
|
| 940 |
+
def __init__(
|
| 941 |
+
self,
|
| 942 |
+
ch_mult: list,
|
| 943 |
+
in_channels,
|
| 944 |
+
pretrained_model: nn.Module = None,
|
| 945 |
+
reshape=False,
|
| 946 |
+
n_channels=None,
|
| 947 |
+
dropout=0.0,
|
| 948 |
+
pretrained_config=None,
|
| 949 |
+
):
|
| 950 |
+
super().__init__()
|
| 951 |
+
if pretrained_config is None:
|
| 952 |
+
assert (
|
| 953 |
+
pretrained_model is not None
|
| 954 |
+
), 'Either "pretrained_model" or "pretrained_config" must not be None'
|
| 955 |
+
self.pretrained_model = pretrained_model
|
| 956 |
+
else:
|
| 957 |
+
assert (
|
| 958 |
+
pretrained_config is not None
|
| 959 |
+
), 'Either "pretrained_model" or "pretrained_config" must not be None'
|
| 960 |
+
self.instantiate_pretrained(pretrained_config)
|
| 961 |
+
|
| 962 |
+
self.do_reshape = reshape
|
| 963 |
+
|
| 964 |
+
if n_channels is None:
|
| 965 |
+
n_channels = self.pretrained_model.encoder.ch
|
| 966 |
+
|
| 967 |
+
self.proj_norm = Normalize(in_channels, num_groups=in_channels // 2)
|
| 968 |
+
self.proj = nn.Conv2d(
|
| 969 |
+
in_channels, n_channels, kernel_size=3, stride=1, padding=1
|
| 970 |
+
)
|
| 971 |
+
|
| 972 |
+
blocks = []
|
| 973 |
+
downs = []
|
| 974 |
+
ch_in = n_channels
|
| 975 |
+
for m in ch_mult:
|
| 976 |
+
blocks.append(
|
| 977 |
+
ResnetBlock(
|
| 978 |
+
in_channels=ch_in, out_channels=m * n_channels, dropout=dropout
|
| 979 |
+
)
|
| 980 |
+
)
|
| 981 |
+
ch_in = m * n_channels
|
| 982 |
+
downs.append(Downsample(ch_in, with_conv=False))
|
| 983 |
+
|
| 984 |
+
self.model = nn.ModuleList(blocks)
|
| 985 |
+
self.downsampler = nn.ModuleList(downs)
|
| 986 |
+
|
| 987 |
+
def instantiate_pretrained(self, config):
|
| 988 |
+
model = instantiate_from_config(config)
|
| 989 |
+
self.pretrained_model = model.eval()
|
| 990 |
+
|
| 991 |
+
for param in self.pretrained_model.parameters():
|
| 992 |
+
param.requires_grad = False
|
| 993 |
+
|
| 994 |
+
@torch.no_grad()
|
| 995 |
+
def encode_with_pretrained(self, x):
|
| 996 |
+
c = self.pretrained_model.encode(x)
|
| 997 |
+
if isinstance(c, DiagonalGaussianDistribution):
|
| 998 |
+
c = c.mode()
|
| 999 |
+
return c
|
| 1000 |
+
|
| 1001 |
+
def forward(self, x):
|
| 1002 |
+
z_fs = self.encode_with_pretrained(x)
|
| 1003 |
+
z = self.proj_norm(z_fs)
|
| 1004 |
+
z = self.proj(z)
|
| 1005 |
+
z = nonlinearity(z)
|
| 1006 |
+
|
| 1007 |
+
for submodel, downmodel in zip(self.model, self.downsampler):
|
| 1008 |
+
z = submodel(z, temb=None)
|
| 1009 |
+
z = downmodel(z)
|
| 1010 |
+
|
| 1011 |
+
if self.do_reshape:
|
| 1012 |
+
z = rearrange(z, "b c h w -> b (h w) c")
|
| 1013 |
+
return z
|
ldm/utils/__init__.py
ADDED
|
File without changes
|
ldm/utils/diffusion_util.py
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# adopted from
|
| 2 |
+
# https://github.com/openai/improved-diffusion/blob/main/improved_diffusion/gaussian_diffusion.py
|
| 3 |
+
# and
|
| 4 |
+
# https://github.com/lucidrains/denoising-diffusion-pytorch/blob/7706bdfc6f527f58d33f84b7b522e61e6e3164b3/denoising_diffusion_pytorch/denoising_diffusion_pytorch.py
|
| 5 |
+
# and
|
| 6 |
+
# https://github.com/openai/guided-diffusion/blob/0ba878e517b276c45d1195eb29f6f5f72659a05b/guided_diffusion/nn.py
|
| 7 |
+
#
|
| 8 |
+
# thanks!
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
import os
|
| 12 |
+
import math
|
| 13 |
+
import torch
|
| 14 |
+
import torch.nn as nn
|
| 15 |
+
import numpy as np
|
| 16 |
+
from einops import repeat
|
| 17 |
+
|
| 18 |
+
from ldm.utils.util import instantiate_from_config
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def make_beta_schedule(
|
| 22 |
+
schedule, n_timestep, linear_start=1e-4, linear_end=2e-2, cosine_s=8e-3
|
| 23 |
+
):
|
| 24 |
+
if schedule == "linear":
|
| 25 |
+
betas = (
|
| 26 |
+
torch.linspace(
|
| 27 |
+
linear_start**0.5, linear_end**0.5, n_timestep, dtype=torch.float64
|
| 28 |
+
)
|
| 29 |
+
** 2
|
| 30 |
+
)
|
| 31 |
+
|
| 32 |
+
elif schedule == "cosine":
|
| 33 |
+
timesteps = (
|
| 34 |
+
torch.arange(n_timestep + 1, dtype=torch.float64) / n_timestep + cosine_s
|
| 35 |
+
)
|
| 36 |
+
alphas = timesteps / (1 + cosine_s) * np.pi / 2
|
| 37 |
+
alphas = torch.cos(alphas).pow(2)
|
| 38 |
+
alphas = alphas / alphas[0]
|
| 39 |
+
betas = 1 - alphas[1:] / alphas[:-1]
|
| 40 |
+
betas = np.clip(betas, a_min=0, a_max=0.999)
|
| 41 |
+
|
| 42 |
+
elif schedule == "sqrt_linear":
|
| 43 |
+
betas = torch.linspace(
|
| 44 |
+
linear_start, linear_end, n_timestep, dtype=torch.float64
|
| 45 |
+
)
|
| 46 |
+
elif schedule == "sqrt":
|
| 47 |
+
betas = (
|
| 48 |
+
torch.linspace(linear_start, linear_end, n_timestep, dtype=torch.float64)
|
| 49 |
+
** 0.5
|
| 50 |
+
)
|
| 51 |
+
else:
|
| 52 |
+
raise ValueError(f"schedule '{schedule}' unknown.")
|
| 53 |
+
return betas.numpy()
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
def make_ddim_timesteps(
|
| 57 |
+
ddim_discr_method, num_ddim_timesteps, num_ddpm_timesteps, verbose=True
|
| 58 |
+
):
|
| 59 |
+
if ddim_discr_method == "uniform":
|
| 60 |
+
c = num_ddpm_timesteps // num_ddim_timesteps
|
| 61 |
+
ddim_timesteps = np.asarray(list(range(0, num_ddpm_timesteps, c)))
|
| 62 |
+
elif ddim_discr_method == "quad":
|
| 63 |
+
ddim_timesteps = (
|
| 64 |
+
(np.linspace(0, np.sqrt(num_ddpm_timesteps * 0.8), num_ddim_timesteps)) ** 2
|
| 65 |
+
).astype(int)
|
| 66 |
+
else:
|
| 67 |
+
raise NotImplementedError(
|
| 68 |
+
f'There is no ddim discretization method called "{ddim_discr_method}"'
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
# add one to get the final alpha values right (the ones from first scale to data during sampling)
|
| 72 |
+
steps_out = ddim_timesteps + 1
|
| 73 |
+
if verbose:
|
| 74 |
+
print(f"Selected timesteps for ddim sampler: {steps_out}")
|
| 75 |
+
return steps_out
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
def make_ddim_sampling_parameters(alphacums, ddim_timesteps, eta, verbose=True):
|
| 79 |
+
# select alphas for computing the variance schedule
|
| 80 |
+
alphas = alphacums[ddim_timesteps]
|
| 81 |
+
alphas_prev = np.asarray([alphacums[0]] + alphacums[ddim_timesteps[:-1]].tolist())
|
| 82 |
+
|
| 83 |
+
# according the the formula provided in https://arxiv.org/abs/2010.02502
|
| 84 |
+
sigmas = eta * np.sqrt(
|
| 85 |
+
(1 - alphas_prev) / (1 - alphas) * (1 - alphas / alphas_prev)
|
| 86 |
+
)
|
| 87 |
+
if verbose:
|
| 88 |
+
print(
|
| 89 |
+
f"Selected alphas for ddim sampler: a_t: {alphas}; a_(t-1): {alphas_prev}"
|
| 90 |
+
)
|
| 91 |
+
print(
|
| 92 |
+
f"For the chosen value of eta, which is {eta}, "
|
| 93 |
+
f"this results in the following sigma_t schedule for ddim sampler {sigmas}"
|
| 94 |
+
)
|
| 95 |
+
return sigmas, alphas, alphas_prev
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
def betas_for_alpha_bar(num_diffusion_timesteps, alpha_bar, max_beta=0.999):
|
| 99 |
+
"""
|
| 100 |
+
Create a beta schedule that discretizes the given alpha_t_bar function,
|
| 101 |
+
which defines the cumulative product of (1-beta) over time from t = [0,1].
|
| 102 |
+
:param num_diffusion_timesteps: the number of betas to produce.
|
| 103 |
+
:param alpha_bar: a lambda that takes an argument t from 0 to 1 and
|
| 104 |
+
produces the cumulative product of (1-beta) up to that
|
| 105 |
+
part of the diffusion process.
|
| 106 |
+
:param max_beta: the maximum beta to use; use values lower than 1 to
|
| 107 |
+
prevent singularities.
|
| 108 |
+
"""
|
| 109 |
+
betas = []
|
| 110 |
+
for i in range(num_diffusion_timesteps):
|
| 111 |
+
t1 = i / num_diffusion_timesteps
|
| 112 |
+
t2 = (i + 1) / num_diffusion_timesteps
|
| 113 |
+
betas.append(min(1 - alpha_bar(t2) / alpha_bar(t1), max_beta))
|
| 114 |
+
return np.array(betas)
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
def extract_into_tensor(a, t, x_shape):
|
| 118 |
+
b, *_ = t.shape
|
| 119 |
+
out = a.gather(-1, t).contiguous()
|
| 120 |
+
return out.reshape(b, *((1,) * (len(x_shape) - 1))).contiguous()
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
def checkpoint(func, inputs, params, flag):
|
| 124 |
+
"""
|
| 125 |
+
Evaluate a function without caching intermediate activations, allowing for
|
| 126 |
+
reduced memory at the expense of extra compute in the backward pass.
|
| 127 |
+
:param func: the function to evaluate.
|
| 128 |
+
:param inputs: the argument sequence to pass to `func`.
|
| 129 |
+
:param params: a sequence of parameters `func` depends on but does not
|
| 130 |
+
explicitly take as arguments.
|
| 131 |
+
:param flag: if False, disable gradient checkpointing.
|
| 132 |
+
"""
|
| 133 |
+
if flag:
|
| 134 |
+
args = tuple(inputs) + tuple(params)
|
| 135 |
+
return CheckpointFunction.apply(func, len(inputs), *args)
|
| 136 |
+
else:
|
| 137 |
+
return func(*inputs)
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
class CheckpointFunction(torch.autograd.Function):
|
| 141 |
+
@staticmethod
|
| 142 |
+
def forward(ctx, run_function, length, *args):
|
| 143 |
+
ctx.run_function = run_function
|
| 144 |
+
ctx.input_tensors = list(args[:length])
|
| 145 |
+
ctx.input_params = list(args[length:])
|
| 146 |
+
|
| 147 |
+
with torch.no_grad():
|
| 148 |
+
output_tensors = ctx.run_function(*ctx.input_tensors)
|
| 149 |
+
return output_tensors
|
| 150 |
+
|
| 151 |
+
@staticmethod
|
| 152 |
+
def backward(ctx, *output_grads):
|
| 153 |
+
ctx.input_tensors = [x.detach().requires_grad_(True) for x in ctx.input_tensors]
|
| 154 |
+
with torch.enable_grad():
|
| 155 |
+
# Fixes a bug where the first op in run_function modifies the
|
| 156 |
+
# Tensor storage in place, which is not allowed for detach()'d
|
| 157 |
+
# Tensors.
|
| 158 |
+
shallow_copies = [x.view_as(x) for x in ctx.input_tensors]
|
| 159 |
+
output_tensors = ctx.run_function(*shallow_copies)
|
| 160 |
+
input_grads = torch.autograd.grad(
|
| 161 |
+
output_tensors,
|
| 162 |
+
ctx.input_tensors + ctx.input_params,
|
| 163 |
+
output_grads,
|
| 164 |
+
allow_unused=True,
|
| 165 |
+
)
|
| 166 |
+
del ctx.input_tensors
|
| 167 |
+
del ctx.input_params
|
| 168 |
+
del output_tensors
|
| 169 |
+
return (None, None) + input_grads
|
| 170 |
+
|
| 171 |
+
|
| 172 |
+
def timestep_embedding(timesteps, dim, max_period=10000, repeat_only=False):
|
| 173 |
+
"""
|
| 174 |
+
Create sinusoidal timestep embeddings.
|
| 175 |
+
:param timesteps: a 1-D Tensor of N indices, one per batch element.
|
| 176 |
+
These may be fractional.
|
| 177 |
+
:param dim: the dimension of the output.
|
| 178 |
+
:param max_period: controls the minimum frequency of the embeddings.
|
| 179 |
+
:return: an [N x dim] Tensor of positional embeddings.
|
| 180 |
+
"""
|
| 181 |
+
if not repeat_only:
|
| 182 |
+
half = dim // 2
|
| 183 |
+
freqs = torch.exp(
|
| 184 |
+
-math.log(max_period)
|
| 185 |
+
* torch.arange(start=0, end=half, dtype=torch.float32)
|
| 186 |
+
/ half
|
| 187 |
+
).to(device=timesteps.device)
|
| 188 |
+
args = timesteps[:, None].float() * freqs[None]
|
| 189 |
+
embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1)
|
| 190 |
+
if dim % 2:
|
| 191 |
+
embedding = torch.cat(
|
| 192 |
+
[embedding, torch.zeros_like(embedding[:, :1])], dim=-1
|
| 193 |
+
)
|
| 194 |
+
else:
|
| 195 |
+
embedding = repeat(timesteps, "b -> b d", d=dim)
|
| 196 |
+
return embedding
|
| 197 |
+
|
| 198 |
+
|
| 199 |
+
def zero_module(module):
|
| 200 |
+
"""
|
| 201 |
+
Zero out the parameters of a module and return it.
|
| 202 |
+
"""
|
| 203 |
+
for p in module.parameters():
|
| 204 |
+
p.detach().zero_()
|
| 205 |
+
return module
|
| 206 |
+
|
| 207 |
+
|
| 208 |
+
def scale_module(module, scale):
|
| 209 |
+
"""
|
| 210 |
+
Scale the parameters of a module and return it.
|
| 211 |
+
"""
|
| 212 |
+
for p in module.parameters():
|
| 213 |
+
p.detach().mul_(scale)
|
| 214 |
+
return module
|
| 215 |
+
|
| 216 |
+
|
| 217 |
+
def mean_flat(tensor):
|
| 218 |
+
"""
|
| 219 |
+
Take the mean over all non-batch dimensions.
|
| 220 |
+
"""
|
| 221 |
+
return tensor.mean(dim=list(range(1, len(tensor.shape))))
|
| 222 |
+
|
| 223 |
+
|
| 224 |
+
def normalization(channels):
|
| 225 |
+
"""
|
| 226 |
+
Make a standard normalization layer.
|
| 227 |
+
:param channels: number of input channels.
|
| 228 |
+
:return: an nn.Module for normalization.
|
| 229 |
+
"""
|
| 230 |
+
return GroupNorm32(32, channels)
|
| 231 |
+
|
| 232 |
+
|
| 233 |
+
# PyTorch 1.7 has SiLU, but we support PyTorch 1.5.
|
| 234 |
+
class SiLU(nn.Module):
|
| 235 |
+
def forward(self, x):
|
| 236 |
+
return x * torch.sigmoid(x)
|
| 237 |
+
|
| 238 |
+
|
| 239 |
+
class GroupNorm32(nn.GroupNorm):
|
| 240 |
+
def forward(self, x):
|
| 241 |
+
return super().forward(x.float()).type(x.dtype)
|
| 242 |
+
|
| 243 |
+
|
| 244 |
+
def conv_nd(dims, *args, **kwargs):
|
| 245 |
+
"""
|
| 246 |
+
Create a 1D, 2D, or 3D convolution module.
|
| 247 |
+
"""
|
| 248 |
+
if dims == 1:
|
| 249 |
+
return nn.Conv1d(*args, **kwargs)
|
| 250 |
+
elif dims == 2:
|
| 251 |
+
return nn.Conv2d(*args, **kwargs)
|
| 252 |
+
elif dims == 3:
|
| 253 |
+
return nn.Conv3d(*args, **kwargs)
|
| 254 |
+
raise ValueError(f"unsupported dimensions: {dims}")
|
| 255 |
+
|
| 256 |
+
|
| 257 |
+
def linear(*args, **kwargs):
|
| 258 |
+
"""
|
| 259 |
+
Create a linear module.
|
| 260 |
+
"""
|
| 261 |
+
return nn.Linear(*args, **kwargs)
|
| 262 |
+
|
| 263 |
+
|
| 264 |
+
def avg_pool_nd(dims, *args, **kwargs):
|
| 265 |
+
"""
|
| 266 |
+
Create a 1D, 2D, or 3D average pooling module.
|
| 267 |
+
"""
|
| 268 |
+
if dims == 1:
|
| 269 |
+
return nn.AvgPool1d(*args, **kwargs)
|
| 270 |
+
elif dims == 2:
|
| 271 |
+
return nn.AvgPool2d(*args, **kwargs)
|
| 272 |
+
elif dims == 3:
|
| 273 |
+
return nn.AvgPool3d(*args, **kwargs)
|
| 274 |
+
raise ValueError(f"unsupported dimensions: {dims}")
|
| 275 |
+
|
| 276 |
+
|
| 277 |
+
class HybridConditioner(nn.Module):
|
| 278 |
+
def __init__(self, c_concat_config, c_crossattn_config):
|
| 279 |
+
super().__init__()
|
| 280 |
+
self.concat_conditioner = instantiate_from_config(c_concat_config)
|
| 281 |
+
self.crossattn_conditioner = instantiate_from_config(c_crossattn_config)
|
| 282 |
+
|
| 283 |
+
def forward(self, c_concat, c_crossattn):
|
| 284 |
+
c_concat = self.concat_conditioner(c_concat)
|
| 285 |
+
c_crossattn = self.crossattn_conditioner(c_crossattn)
|
| 286 |
+
return {"c_concat": [c_concat], "c_crossattn": [c_crossattn]}
|
| 287 |
+
|
| 288 |
+
|
| 289 |
+
def noise_like(shape, device, repeat=False):
|
| 290 |
+
repeat_noise = lambda: torch.randn((1, *shape[1:]), device=device).repeat(
|
| 291 |
+
shape[0], *((1,) * (len(shape) - 1))
|
| 292 |
+
)
|
| 293 |
+
noise = lambda: torch.randn(shape, device=device)
|
| 294 |
+
return repeat_noise() if repeat else noise()
|
ldm/utils/util.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2022 Machine Vision and Learning Group, LMU Munich
|
| 2 |
+
# copy from https://github.com/CompVis/latent-diffusion/blob/main/ldm/lr_scheduler.py under the MIT license
|
| 3 |
+
# LICENSE is in incl_licenses directory.
|
| 4 |
+
import torch
|
| 5 |
+
import importlib
|
| 6 |
+
import torch.nn as nn
|
| 7 |
+
|
| 8 |
+
from inspect import isfunction
|
| 9 |
+
|
| 10 |
+
from transformers import (
|
| 11 |
+
AutoTokenizer,
|
| 12 |
+
T5EncoderModel,
|
| 13 |
+
)
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def exists(x):
|
| 17 |
+
return x is not None
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def default(val, d):
|
| 21 |
+
if exists(val):
|
| 22 |
+
return val
|
| 23 |
+
return d() if isfunction(d) else d
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def instantiate_from_config(config, reload=False):
|
| 27 |
+
if not "target" in config:
|
| 28 |
+
if config == "__is_first_stage__":
|
| 29 |
+
return None
|
| 30 |
+
elif config == "__is_unconditional__":
|
| 31 |
+
return None
|
| 32 |
+
raise KeyError("Expected key `target` to instantiate.")
|
| 33 |
+
return get_obj_from_str(config["target"], reload=reload)(
|
| 34 |
+
**config.get("params", dict())
|
| 35 |
+
)
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
def get_obj_from_str(string, reload=False):
|
| 39 |
+
module, cls = string.rsplit(".", 1)
|
| 40 |
+
if reload:
|
| 41 |
+
module_imp = importlib.import_module(module)
|
| 42 |
+
importlib.reload(module_imp)
|
| 43 |
+
return getattr(importlib.import_module(module, package=None), cls)
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
class TextEncoder(nn.Module):
|
| 47 |
+
|
| 48 |
+
def __init__(self, ckpt_path=None):
|
| 49 |
+
super().__init__()
|
| 50 |
+
|
| 51 |
+
self.tokenizer = AutoTokenizer.from_pretrained(ckpt_path)
|
| 52 |
+
self.model = T5EncoderModel.from_pretrained(ckpt_path)
|
| 53 |
+
self.model.eval()
|
| 54 |
+
self.device = "cuda"
|
| 55 |
+
|
| 56 |
+
def get_uncond(self, batchsize):
|
| 57 |
+
|
| 58 |
+
hidden_state, _ = self([""])
|
| 59 |
+
hidden_state = torch.cat([hidden_state] * batchsize).float()
|
| 60 |
+
attention_mask = (
|
| 61 |
+
torch.ones((batchsize, hidden_state.size(1))).to(self.device).float()
|
| 62 |
+
)
|
| 63 |
+
return [hidden_state, attention_mask]
|
| 64 |
+
|
| 65 |
+
def forward(self, batch):
|
| 66 |
+
return self.get_cond(batch)
|
| 67 |
+
|
| 68 |
+
def get_cond(self, prompt):
|
| 69 |
+
device = self.model.device
|
| 70 |
+
token = self.tokenizer(
|
| 71 |
+
prompt,
|
| 72 |
+
max_length=128,
|
| 73 |
+
padding=True,
|
| 74 |
+
truncation=True,
|
| 75 |
+
return_tensors="pt",
|
| 76 |
+
)
|
| 77 |
+
input_ids, attention_mask = token.input_ids.to(device), token.attention_mask.to(
|
| 78 |
+
device
|
| 79 |
+
)
|
| 80 |
+
|
| 81 |
+
with torch.no_grad():
|
| 82 |
+
hidden_states = self.model(
|
| 83 |
+
input_ids=input_ids, attention_mask=attention_mask
|
| 84 |
+
)[0]
|
| 85 |
+
|
| 86 |
+
return [hidden_states, attention_mask.float()]
|
models/flan-t5-large/config.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"architectures": [
|
| 3 |
+
"T5ForConditionalGeneration"
|
| 4 |
+
],
|
| 5 |
+
"d_ff": 2816,
|
| 6 |
+
"d_kv": 64,
|
| 7 |
+
"d_model": 1024,
|
| 8 |
+
"decoder_start_token_id": 0,
|
| 9 |
+
"dropout_rate": 0.1,
|
| 10 |
+
"eos_token_id": 1,
|
| 11 |
+
"feed_forward_proj": "gated-gelu",
|
| 12 |
+
"initializer_factor": 1.0,
|
| 13 |
+
"is_encoder_decoder": true,
|
| 14 |
+
"layer_norm_epsilon": 1e-06,
|
| 15 |
+
"model_type": "t5",
|
| 16 |
+
"n_positions": 512,
|
| 17 |
+
"num_decoder_layers": 24,
|
| 18 |
+
"num_heads": 16,
|
| 19 |
+
"num_layers": 24,
|
| 20 |
+
"output_past": true,
|
| 21 |
+
"pad_token_id": 0,
|
| 22 |
+
"relative_attention_max_distance": 128,
|
| 23 |
+
"relative_attention_num_buckets": 32,
|
| 24 |
+
"tie_word_embeddings": false,
|
| 25 |
+
"transformers_version": "4.23.1",
|
| 26 |
+
"use_cache": true,
|
| 27 |
+
"vocab_size": 32128
|
| 28 |
+
}
|
models/flan-t5-large/generation_config.json
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"_from_model_config": true,
|
| 3 |
+
"decoder_start_token_id": 0,
|
| 4 |
+
"eos_token_id": 1,
|
| 5 |
+
"pad_token_id": 0,
|
| 6 |
+
"transformers_version": "4.27.0.dev0"
|
| 7 |
+
}
|
models/flan-t5-large/pytorch_model.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:93249e5f2b058ccddd0f4f5ef82aad80e262133eb103f1b42dc2da4b9bc97b36
|
| 3 |
+
size 3132781861
|
models/flan-t5-large/special_tokens_map.json
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"additional_special_tokens": [
|
| 3 |
+
"<extra_id_0>",
|
| 4 |
+
"<extra_id_1>",
|
| 5 |
+
"<extra_id_2>",
|
| 6 |
+
"<extra_id_3>",
|
| 7 |
+
"<extra_id_4>",
|
| 8 |
+
"<extra_id_5>",
|
| 9 |
+
"<extra_id_6>",
|
| 10 |
+
"<extra_id_7>",
|
| 11 |
+
"<extra_id_8>",
|
| 12 |
+
"<extra_id_9>",
|
| 13 |
+
"<extra_id_10>",
|
| 14 |
+
"<extra_id_11>",
|
| 15 |
+
"<extra_id_12>",
|
| 16 |
+
"<extra_id_13>",
|
| 17 |
+
"<extra_id_14>",
|
| 18 |
+
"<extra_id_15>",
|
| 19 |
+
"<extra_id_16>",
|
| 20 |
+
"<extra_id_17>",
|
| 21 |
+
"<extra_id_18>",
|
| 22 |
+
"<extra_id_19>",
|
| 23 |
+
"<extra_id_20>",
|
| 24 |
+
"<extra_id_21>",
|
| 25 |
+
"<extra_id_22>",
|
| 26 |
+
"<extra_id_23>",
|
| 27 |
+
"<extra_id_24>",
|
| 28 |
+
"<extra_id_25>",
|
| 29 |
+
"<extra_id_26>",
|
| 30 |
+
"<extra_id_27>",
|
| 31 |
+
"<extra_id_28>",
|
| 32 |
+
"<extra_id_29>",
|
| 33 |
+
"<extra_id_30>",
|
| 34 |
+
"<extra_id_31>",
|
| 35 |
+
"<extra_id_32>",
|
| 36 |
+
"<extra_id_33>",
|
| 37 |
+
"<extra_id_34>",
|
| 38 |
+
"<extra_id_35>",
|
| 39 |
+
"<extra_id_36>",
|
| 40 |
+
"<extra_id_37>",
|
| 41 |
+
"<extra_id_38>",
|
| 42 |
+
"<extra_id_39>",
|
| 43 |
+
"<extra_id_40>",
|
| 44 |
+
"<extra_id_41>",
|
| 45 |
+
"<extra_id_42>",
|
| 46 |
+
"<extra_id_43>",
|
| 47 |
+
"<extra_id_44>",
|
| 48 |
+
"<extra_id_45>",
|
| 49 |
+
"<extra_id_46>",
|
| 50 |
+
"<extra_id_47>",
|
| 51 |
+
"<extra_id_48>",
|
| 52 |
+
"<extra_id_49>",
|
| 53 |
+
"<extra_id_50>",
|
| 54 |
+
"<extra_id_51>",
|
| 55 |
+
"<extra_id_52>",
|
| 56 |
+
"<extra_id_53>",
|
| 57 |
+
"<extra_id_54>",
|
| 58 |
+
"<extra_id_55>",
|
| 59 |
+
"<extra_id_56>",
|
| 60 |
+
"<extra_id_57>",
|
| 61 |
+
"<extra_id_58>",
|
| 62 |
+
"<extra_id_59>",
|
| 63 |
+
"<extra_id_60>",
|
| 64 |
+
"<extra_id_61>",
|
| 65 |
+
"<extra_id_62>",
|
| 66 |
+
"<extra_id_63>",
|
| 67 |
+
"<extra_id_64>",
|
| 68 |
+
"<extra_id_65>",
|
| 69 |
+
"<extra_id_66>",
|
| 70 |
+
"<extra_id_67>",
|
| 71 |
+
"<extra_id_68>",
|
| 72 |
+
"<extra_id_69>",
|
| 73 |
+
"<extra_id_70>",
|
| 74 |
+
"<extra_id_71>",
|
| 75 |
+
"<extra_id_72>",
|
| 76 |
+
"<extra_id_73>",
|
| 77 |
+
"<extra_id_74>",
|
| 78 |
+
"<extra_id_75>",
|
| 79 |
+
"<extra_id_76>",
|
| 80 |
+
"<extra_id_77>",
|
| 81 |
+
"<extra_id_78>",
|
| 82 |
+
"<extra_id_79>",
|
| 83 |
+
"<extra_id_80>",
|
| 84 |
+
"<extra_id_81>",
|
| 85 |
+
"<extra_id_82>",
|
| 86 |
+
"<extra_id_83>",
|
| 87 |
+
"<extra_id_84>",
|
| 88 |
+
"<extra_id_85>",
|
| 89 |
+
"<extra_id_86>",
|
| 90 |
+
"<extra_id_87>",
|
| 91 |
+
"<extra_id_88>",
|
| 92 |
+
"<extra_id_89>",
|
| 93 |
+
"<extra_id_90>",
|
| 94 |
+
"<extra_id_91>",
|
| 95 |
+
"<extra_id_92>",
|
| 96 |
+
"<extra_id_93>",
|
| 97 |
+
"<extra_id_94>",
|
| 98 |
+
"<extra_id_95>",
|
| 99 |
+
"<extra_id_96>",
|
| 100 |
+
"<extra_id_97>",
|
| 101 |
+
"<extra_id_98>",
|
| 102 |
+
"<extra_id_99>"
|
| 103 |
+
],
|
| 104 |
+
"eos_token": "</s>",
|
| 105 |
+
"pad_token": "<pad>",
|
| 106 |
+
"unk_token": "<unk>"
|
| 107 |
+
}
|
models/flan-t5-large/spiece.model
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d60acb128cf7b7f2536e8f38a5b18a05535c9e14c7a355904270e15b0945ea86
|
| 3 |
+
size 791656
|
models/flan-t5-large/tokenizer.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|