Skip to content

Commit b8226b9

Browse files
Philip Bontragerfacebook-github-bot
authored andcommitted
Reorg OSS Diffusion Components to diffusion_labs folder (#480)
Summary: Based on this [proposal](https://docs.google.com/document/d/1GtN2urD8PiRr1X4COzvbVbNE8LWRrcoYkAO4v2aogO8/edit) to reorganize diffusion components and models under a new `diffusion_labs`. This is the first in a stack of diffs. This one only reorganizes what's already been moved to OSS. This is primarily moving files with a couple of changes based on the proposal: - predictors.py is split into a separate file per predictor - adm is moved out of dalle2 to be it's own model adm_unet - Dalle2ImageTransform is moved to dalle2 out of transforms - schedule.py is renamed to discrete_guassian_schedule.py and an abstract DIffusionSchedule class was added - An abstract adapter class was added to be a generic type and enforce the `forward` signature - An abstract sampler class was added to be a generic type and enforce the `forward` and `generator` signature - A new dalle2_model unit test was added Differential Revision: D49790849 Pulled By: pbontrager fbshipit-source-id: 98fe40c2418dc542cced940dc761a9cd602b0398
1 parent f2cfe1a commit b8226b9

45 files changed

Lines changed: 654 additions & 348 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

tests/modules/diffusion/test_cfguidance.py renamed to tests/diffusion_labs/test_adapter_cfguidance.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
import torch
1010
from tests.test_utils import assert_expected, set_rng_seed
1111
from torch import nn
12-
from torchmultimodal.modules.diffusion.cfguidance import CFGuidance
13-
from torchmultimodal.utils.diffusion_utils import DiffusionOutput
12+
from torchmultimodal.diffusion_labs.modules.adapters.cfguidance import CFGuidance
13+
from torchmultimodal.diffusion_labs.utils.common import DiffusionOutput
1414

1515

1616
@pytest.fixture(autouse=True)
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
import torch
1111
from tests.test_utils import assert_expected, set_rng_seed
1212
from torch import nn
13-
from torchmultimodal.models.dalle2.adm.adm import ADM, ADMStack, ADMUNet
14-
from torchmultimodal.models.dalle2.adm.attention_block import ADMAttentionBlock
15-
from torchmultimodal.models.dalle2.adm.res_block import ADMResBlock
13+
from torchmultimodal.diffusion_labs.models.adm_unet.adm import ADM, ADMStack, ADMUNet
14+
from torchmultimodal.diffusion_labs.models.adm_unet.attention_block import (
15+
ADMAttentionBlock,
16+
)
17+
from torchmultimodal.diffusion_labs.models.adm_unet.res_block import ADMResBlock
1618

1719

1820
@pytest.fixture(autouse=True)
@@ -116,7 +118,7 @@ def test_predict_variance_value_incorrect_channel_dim_error(
116118

117119

118120
# All expected values come after first testing the ADMUNet has the exact output
119-
# as the corresponding UNet class in d2go, then simply forward passing
121+
# as the corresponding author UNet implementation, then simply forward passing
120122
# ADMUNet with params, random seed, and initialization order in this file.
121123
class TestADMUNet:
122124
@pytest.fixture
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010

1111
import torch
1212
from tests.test_utils import assert_expected, set_rng_seed
13-
from torchmultimodal.models.dalle2.adm.attention_block import ADMAttentionBlock
14-
from torchmultimodal.models.dalle2.adm.res_block import (
13+
from torchmultimodal.diffusion_labs.models.adm_unet.attention_block import (
14+
ADMAttentionBlock,
15+
)
16+
from torchmultimodal.diffusion_labs.models.adm_unet.res_block import (
1517
adm_res_block,
1618
adm_res_downsample_block,
1719
adm_res_upsample_block,
@@ -47,7 +49,7 @@ def t(params):
4749

4850

4951
# All expected values come after first testing the ADMResBlock has the exact output
50-
# as the corresponding residual block class in d2go, then simply forward passing
52+
# as the corresponding residual block class from ADM authors, then simply forward passing
5153
# ADMResBlock with params, random seed, and initialization order in this file.
5254
class TestADMResBlock:
5355
@pytest.fixture

tests/models/dalle2/test_adm_crossattention.py renamed to tests/diffusion_labs/test_adm_crossattention.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import torch
1010
from tests.test_utils import assert_expected, set_rng_seed
11-
from torchmultimodal.models.dalle2.adm.attention_block import (
11+
from torchmultimodal.diffusion_labs.models.adm_unet.attention_block import (
1212
adm_attention,
1313
ADMCrossAttention,
1414
)
@@ -44,7 +44,7 @@ def c(params):
4444

4545

4646
# All expected values come after first testing that ADMCrossAttention has
47-
# the exact output as the corresponding QKVAttention class in d2go, then simply forward passing
47+
# the exact output as the corresponding QKVAttention class in ADM, then simply forward passing
4848
# ADMCrossAttention with params, random seed, and initialization order in this file.
4949
class TestADMCrossAttention:
5050
@pytest.fixture
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# LICENSE file in the root directory of this source tree.
77

88
from PIL import Image
9-
from torchmultimodal.utils.diffusion_utils import cascaded_resize
9+
from torchmultimodal.diffusion_labs.utils.common import cascaded_resize
1010

1111

1212
def test_cascaded_resize():
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/env fbpython
2+
# Copyright (c) Meta Platforms, Inc. and affiliates.
3+
# All rights reserved.
4+
#
5+
# This source code is licensed under the BSD-style license found in the
6+
# LICENSE file in the root directory of this source tree.
7+
8+
import torch
9+
from PIL import Image
10+
from tests.test_utils import assert_expected, set_rng_seed
11+
from torchmultimodal.diffusion_labs.models.dalle2.dalle2_decoder import dalle2_decoder
12+
from torchmultimodal.diffusion_labs.models.dalle2.transforms import Dalle2ImageTransform
13+
14+
15+
def test_dalle2_model():
16+
set_rng_seed(4)
17+
model = dalle2_decoder(
18+
timesteps=1,
19+
time_embed_dim=1,
20+
cond_embed_dim=1,
21+
clip_embed_dim=1,
22+
clip_embed_name="clip_image",
23+
predict_variance_value=True,
24+
image_channels=1,
25+
depth=32,
26+
num_resize=1,
27+
num_res_per_layer=1,
28+
use_cf_guidance=True,
29+
clip_image_guidance_dropout=0.1,
30+
guidance_strength=7.0,
31+
learn_null_emb=True,
32+
)
33+
model.eval()
34+
x = torch.randn(1, 1, 4, 4)
35+
c = torch.ones((1, 1))
36+
with torch.no_grad():
37+
actual = model(x, conditional_inputs={"clip_image": c}).mean()
38+
expected = torch.as_tensor(0.12768)
39+
assert_expected(actual, expected, rtol=0, atol=1e-4)
40+
41+
42+
def test_dalle2_image_transform():
43+
img_size = 5
44+
transform = Dalle2ImageTransform(image_size=img_size, image_min=-1, image_max=1)
45+
image = Image.new("RGB", size=(20, 20), color=(128, 0, 0))
46+
actual = transform(image).sum()
47+
normalized128 = 128 / 255 * 2 - 1
48+
normalized0 = -1
49+
expected = torch.tensor(
50+
normalized128 * img_size**2 + 2 * normalized0 * img_size**2
51+
)
52+
assert_expected(actual, expected, rtol=0, atol=1e-4)

tests/modules/losses/test_diffusion_loss.py renamed to tests/diffusion_labs/test_diffusion_losses.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@
99
import torch
1010
import torch.nn as nn
1111
from tests.test_utils import assert_expected, set_rng_seed
12-
from torchmultimodal.modules.diffusion.schedules import (
13-
DiffusionSchedule,
12+
from torchmultimodal.diffusion_labs.modules.losses.diffusion_hybrid_loss import (
13+
DiffusionHybridLoss,
14+
)
15+
from torchmultimodal.diffusion_labs.modules.losses.vlb_loss import VLBLoss
16+
from torchmultimodal.diffusion_labs.schedules.discrete_gaussian_schedule import (
17+
DiscreteGaussianSchedule,
1418
linear_beta_schedule,
1519
)
16-
from torchmultimodal.modules.losses.diffusion import DiffusionHybridLoss, VLBLoss
17-
from torchmultimodal.utils.diffusion_utils import DiffusionOutput
20+
from torchmultimodal.diffusion_labs.utils.common import DiffusionOutput
1821

1922

2023
@pytest.fixture(autouse=True)
@@ -24,7 +27,7 @@ def set_seed():
2427

2528
@pytest.fixture
2629
def schedule():
27-
return DiffusionSchedule(linear_beta_schedule(1000))
30+
return DiscreteGaussianSchedule(linear_beta_schedule(1000))
2831

2932

3033
@pytest.fixture
@@ -44,7 +47,7 @@ def target():
4447

4548

4649
# All expected values come after first testing the HybridLoss has the exact output
47-
# as the corresponding p_losses in D2Go Guassian Diffusion
50+
# as the corresponding p_losses in Guassian Diffusion
4851
class TestDiffusionHybridLoss:
4952
@pytest.fixture
5053
def loss(self, schedule):

tests/transforms/test_diffusion_transforms.py renamed to tests/diffusion_labs/test_diffusion_transform.py

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@
66
# LICENSE file in the root directory of this source tree.
77

88
import torch
9-
from PIL import Image
10-
from tests.test_utils import assert_expected
11-
from torchmultimodal.transforms.diffusion_transforms import (
12-
Dalle2ImageTransform,
9+
from torchmultimodal.diffusion_labs.transforms.diffusion_transform import (
1310
RandomDiffusionSteps,
1411
)
1512

@@ -30,16 +27,3 @@ def test_random_diffusion_steps():
3027
actual = len(transform(torch.ones(1)))
3128
expected = 4
3229
assert actual == expected, "Transform not returning correct keys"
33-
34-
35-
def test_dalle_image_transform():
36-
img_size = 5
37-
transform = Dalle2ImageTransform(image_size=img_size, image_min=-1, image_max=1)
38-
image = Image.new("RGB", size=(20, 20), color=(128, 0, 0))
39-
actual = transform(image).sum()
40-
normalized128 = 128 / 255 * 2 - 1
41-
normalized0 = -1
42-
expected = torch.tensor(
43-
normalized128 * img_size**2 + 2 * normalized0 * img_size**2
44-
)
45-
assert_expected(actual, expected, rtol=0, atol=1e-4)

tests/modules/diffusion/test_schedule.py renamed to tests/diffusion_labs/test_discrete_schedule.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
import pytest
99
import torch
1010
from tests.test_utils import assert_expected, set_rng_seed
11-
from torchmultimodal.modules.diffusion.schedules import (
11+
from torchmultimodal.diffusion_labs.schedules.discrete_gaussian_schedule import (
1212
cosine_beta_schedule,
13-
DiffusionSchedule,
13+
DiscreteGaussianSchedule,
1414
linear_beta_schedule,
1515
quadratic_beta_schedule,
1616
sigmoid_beta_schedule,
@@ -23,11 +23,11 @@ def set_seed():
2323

2424

2525
# All expected values come after first testing the Schedule has the exact output
26-
# as the corresponding q methods from GaussianDiffusion in D2Go
26+
# as the corresponding q methods from GaussianDiffusion
2727
class TestDiffusionSchedule:
2828
@pytest.fixture
2929
def module(self):
30-
schedule = DiffusionSchedule(linear_beta_schedule(1000))
30+
schedule = DiscreteGaussianSchedule(linear_beta_schedule(1000))
3131
return schedule
3232

3333
@pytest.fixture

0 commit comments

Comments
 (0)