ec1117

Untitled

Jan 16th, 2026
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 26.43 KB | None | 0 0
  1. # Copyright (c) Meta Platforms, Inc. and affiliates.
  2. # All rights reserved.
  3. #
  4. # This source code is licensed under the CC-by-NC license found in the
  5. # LICENSE file in the root directory of this source tree.
  6. """
  7. Modified from https://github.com/openai/guided-diffusion/blob/main/guided_diffusion/unet.py
  8. """
  9.  
  10. import math
  11. from abc import abstractmethod
  12. from dataclasses import dataclass
  13. from typing import Optional, Tuple
  14.  
  15. import numpy as np
  16. import torch
  17. import torch.nn as nn
  18. import torch.nn.functional as F
  19. from models.nn import (
  20.     avg_pool_nd,
  21.     checkpoint,
  22.     conv_nd,
  23.     linear,
  24.     normalization,
  25.     timestep_embedding,
  26.     zero_module,
  27. )
  28.  
  29.  
  30. class ConstantEmbedding(nn.Module):
  31.     def __init__(self, in_channels, out_channels):
  32.         super().__init__()
  33.         self.embedding_table = nn.Parameter(torch.empty((1, out_channels)))
  34.         nn.init.uniform_(
  35.             self.embedding_table, -(in_channels**0.5), in_channels**0.5
  36.         )
  37.  
  38.     def forward(self, emb):
  39.         return self.embedding_table.repeat(emb.shape[0], 1)
  40.  
  41.  
  42. class AttentionPool2d(nn.Module):
  43.     """
  44.    Adapted from CLIP: https://github.com/openai/CLIP/blob/main/clip/model.py
  45.    """
  46.  
  47.     def __init__(
  48.         self,
  49.         spacial_dim: int,
  50.         embed_dim: int,
  51.         num_heads_channels: int,
  52.         output_dim: int = None,
  53.     ):
  54.         super().__init__()
  55.         self.positional_embedding = nn.Parameter(
  56.             torch.randn(embed_dim, spacial_dim**2 + 1) / embed_dim**0.5
  57.         )
  58.         self.qkv_proj = conv_nd(1, embed_dim, 3 * embed_dim, 1)
  59.         self.c_proj = conv_nd(1, embed_dim, output_dim or embed_dim, 1)
  60.         self.num_heads = embed_dim // num_heads_channels
  61.         self.attention = QKVAttention(self.num_heads)
  62.  
  63.     def forward(self, x):
  64.         b, c, *_spatial = x.shape
  65.         x = x.reshape(b, c, -1)  # NC(HW)
  66.         x = torch.cat([x.mean(dim=-1, keepdim=True), x], dim=-1)  # NC(HW+1)
  67.         x = x + self.positional_embedding[None, :, :].to(x.dtype)  # NC(HW+1)
  68.         x = self.qkv_proj(x)
  69.         x = self.attention(x)
  70.         x = self.c_proj(x)
  71.         return x[:, :, 0]
  72.  
  73.  
  74. class TimestepBlock(nn.Module):
  75.     """
  76.    Any module where forward() takes timestep embeddings as a second argument.
  77.    """
  78.  
  79.     @abstractmethod
  80.     def forward(self, x, emb):
  81.         """
  82.        Apply the module to `x` given `emb` timestep embeddings.
  83.        """
  84.  
  85.  
  86. class TimestepEmbedSequential(nn.Sequential, TimestepBlock):
  87.     """
  88.    A sequential module that passes timestep embeddings to the children that
  89.    support it as an extra input.
  90.    """
  91.  
  92.     def forward(self, x, emb):
  93.         for layer in self:
  94.             if isinstance(layer, TimestepBlock):
  95.                 x = layer(x, emb)
  96.             else:
  97.                 x = layer(x)
  98.         return x
  99.  
  100.  
  101. class Upsample(nn.Module):
  102.     """
  103.    An upsampling layer with an optional convolution.
  104.    :param channels: channels in the inputs and outputs.
  105.    :param use_conv: a bool determining if a convolution is applied.
  106.    :param dims: determines if the signal is 1D, 2D, or 3D. If 3D, then
  107.                 upsampling occurs in the inner-two dimensions.
  108.    """
  109.  
  110.     def __init__(self, channels, use_conv, dims=2, out_channels=None):
  111.         super().__init__()
  112.         self.channels = channels
  113.         self.out_channels = out_channels or channels
  114.         self.use_conv = use_conv
  115.         self.dims = dims
  116.         if use_conv:
  117.             self.conv = conv_nd(dims, self.channels, self.out_channels, 3, padding=1)
  118.  
  119.     def forward(self, x):
  120.         assert x.shape[1] == self.channels
  121.         if self.dims == 3:
  122.             x = F.interpolate(
  123.                 x, (x.shape[2], x.shape[3] * 2, x.shape[4] * 2), mode="nearest"
  124.             )
  125.         else:
  126.             x = F.interpolate(x, scale_factor=2, mode="nearest")
  127.         if self.use_conv:
  128.             x = self.conv(x)
  129.         return x
  130.  
  131.  
  132. class Downsample(nn.Module):
  133.     """
  134.    A downsampling layer with an optional convolution.
  135.    :param channels: channels in the inputs and outputs.
  136.    :param use_conv: a bool determining if a convolution is applied.
  137.    :param dims: determines if the signal is 1D, 2D, or 3D. If 3D, then
  138.                 downsampling occurs in the inner-two dimensions.
  139.    """
  140.  
  141.     def __init__(self, channels, use_conv, dims=2, out_channels=None):
  142.         super().__init__()
  143.         self.channels = channels
  144.         self.out_channels = out_channels or channels
  145.         self.use_conv = use_conv
  146.         self.dims = dims
  147.         stride = 2 if dims != 3 else (1, 2, 2)
  148.         if use_conv:
  149.             self.op = conv_nd(
  150.                 dims, self.channels, self.out_channels, 3, stride=stride, padding=1
  151.             )
  152.         else:
  153.             assert self.channels == self.out_channels
  154.             self.op = avg_pool_nd(dims, kernel_size=stride, stride=stride)
  155.  
  156.     def forward(self, x):
  157.         assert x.shape[1] == self.channels
  158.         return self.op(x)
  159.  
  160.  
  161. class ResBlock(TimestepBlock):
  162.     """
  163.    A residual block that can optionally change the number of channels.
  164.    :param channels: the number of input channels.
  165.    :param emb_channels: the number of timestep embedding channels.
  166.    :param dropout: the rate of dropout.
  167.    :param out_channels: if specified, the number of out channels.
  168.    :param use_conv: if True and out_channels is specified, use a spatial
  169.        convolution instead of a smaller 1x1 convolution to change the
  170.        channels in the skip connection.
  171.    :param dims: determines if the signal is 1D, 2D, or 3D.
  172.    :param use_checkpoint: if True, use gradient checkpointing on this module.
  173.    :param up: if True, use this block for upsampling.
  174.    :param down: if True, use this block for downsampling.
  175.    """
  176.  
  177.     def __init__(
  178.         self,
  179.         channels,
  180.         emb_channels,
  181.         dropout,
  182.         out_channels=None,
  183.         use_conv=False,
  184.         use_scale_shift_norm=False,
  185.         dims=2,
  186.         use_checkpoint=False,
  187.         up=False,
  188.         down=False,
  189.         emb_off=False,
  190.     ):
  191.         super().__init__()
  192.         self.channels = channels
  193.         self.emb_channels = emb_channels
  194.         self.dropout = dropout
  195.         self.out_channels = out_channels or channels
  196.         self.use_conv = use_conv
  197.         self.use_checkpoint = use_checkpoint
  198.         self.use_scale_shift_norm = use_scale_shift_norm
  199.  
  200.         self.in_layers = nn.Sequential(
  201.             normalization(channels),
  202.             nn.SiLU(),
  203.             conv_nd(dims, channels, self.out_channels, 3, padding=1),
  204.         )
  205.  
  206.         self.updown = up or down
  207.  
  208.         if up:
  209.             self.h_upd = Upsample(channels, False, dims)
  210.             self.x_upd = Upsample(channels, False, dims)
  211.         elif down:
  212.             self.h_upd = Downsample(channels, False, dims)
  213.             self.x_upd = Downsample(channels, False, dims)
  214.         else:
  215.             self.h_upd = self.x_upd = nn.Identity()
  216.  
  217.         if emb_off:
  218.             self.emb_layers = ConstantEmbedding(
  219.                 emb_channels,
  220.                 2 * self.out_channels if use_scale_shift_norm else self.out_channels,
  221.             )
  222.         else:
  223.             self.emb_layers = nn.Sequential(
  224.                 nn.SiLU(),
  225.                 linear(
  226.                     emb_channels,
  227.                     2 * self.out_channels
  228.                     if use_scale_shift_norm
  229.                     else self.out_channels,
  230.                 ),
  231.             )
  232.  
  233.         self.out_layers = nn.Sequential(
  234.             normalization(self.out_channels),
  235.             nn.SiLU(),
  236.             nn.Dropout(p=dropout),
  237.             zero_module(
  238.                 conv_nd(dims, self.out_channels, self.out_channels, 3, padding=1)
  239.             ),
  240.         )
  241.  
  242.         if self.out_channels == channels:
  243.             self.skip_connection = nn.Identity()
  244.         elif use_conv:
  245.             self.skip_connection = conv_nd(
  246.                 dims, channels, self.out_channels, 3, padding=1
  247.             )
  248.         else:
  249.             self.skip_connection = conv_nd(dims, channels, self.out_channels, 1)
  250.  
  251.     def forward(self, x, emb):
  252.         """
  253.        Apply the block to a Tensor, conditioned on a timestep embedding.
  254.        :param x: an [N x C x ...] Tensor of features.
  255.        :param emb: an [N x emb_channels] Tensor of timestep embeddings.
  256.        :return: an [N x C x ...] Tensor of outputs.
  257.        """
  258.         return checkpoint(
  259.             self._forward,
  260.             (x, emb),
  261.             self.parameters(),
  262.             self.use_checkpoint and self.training,
  263.         )
  264.  
  265.     def _forward(self, x, emb):
  266.         if self.updown:
  267.             in_rest, in_conv = self.in_layers[:-1], self.in_layers[-1]
  268.             h = in_rest(x)
  269.             h = self.h_upd(h)
  270.             x = self.x_upd(x)
  271.             h = in_conv(h)
  272.         else:
  273.             h = self.in_layers(x)
  274.         emb_out = self.emb_layers(emb).type(h.dtype)
  275.         while len(emb_out.shape) < len(h.shape):
  276.             emb_out = emb_out[..., None]
  277.         if self.use_scale_shift_norm:
  278.             out_norm, out_rest = self.out_layers[0], self.out_layers[1:]
  279.             scale, shift = torch.chunk(emb_out, 2, dim=1)
  280.             h = out_norm(h) * (1 + scale) + shift
  281.             h = out_rest(h)
  282.         else:
  283.             h = h + emb_out
  284.             h = self.out_layers(h)
  285.         return self.skip_connection(x) + h
  286.  
  287.  
  288. class AttentionBlock(nn.Module):
  289.     """
  290.    An attention block that allows spatial positions to attend to each other.
  291.    Originally ported from here, but adapted to the N-d case.
  292.    https://github.com/hojonathanho/diffusion/blob/1e0dceb3b3495bbe19116a5e1b3596cd0706c543/diffusion_tf/models/unet.py#L66.
  293.    """
  294.  
  295.     def __init__(
  296.         self,
  297.         channels,
  298.         num_heads=1,
  299.         num_head_channels=-1,
  300.         use_checkpoint=False,
  301.         use_new_attention_order=False,
  302.     ):
  303.         super().__init__()
  304.         self.channels = channels
  305.         if num_head_channels == -1:
  306.             self.num_heads = num_heads
  307.         else:
  308.             assert (
  309.                 channels % num_head_channels == 0
  310.             ), f"q,k,v channels {channels} is not divisible by num_head_channels {num_head_channels}"
  311.             self.num_heads = channels // num_head_channels
  312.         self.use_checkpoint = use_checkpoint
  313.         self.norm = normalization(channels)
  314.         self.qkv = conv_nd(1, channels, channels * 3, 1)
  315.         if use_new_attention_order:
  316.             # split qkv before split heads
  317.             self.attention = QKVAttention(self.num_heads)
  318.         else:
  319.             # split heads before split qkv
  320.             self.attention = QKVAttentionLegacy(self.num_heads)
  321.  
  322.         self.proj_out = zero_module(conv_nd(1, channels, channels, 1))
  323.  
  324.     def forward(self, x):
  325.         return checkpoint(
  326.             self._forward,
  327.             (x,),
  328.             self.parameters(),
  329.             self.use_checkpoint and self.training,
  330.         )
  331.  
  332.     def _forward(self, x):
  333.         b, c, *spatial = x.shape
  334.         x = x.reshape(b, c, -1)
  335.         qkv = self.qkv(self.norm(x))
  336.         h = self.attention(qkv)
  337.         h = self.proj_out(h)
  338.         return (x + h).reshape(b, c, *spatial)
  339.  
  340.  
  341. def count_flops_attn(model, _x, y):
  342.     """
  343.    A counter for the `thop` package to count the operations in an
  344.    attention operation.
  345.    Meant to be used like:
  346.        macs, params = thop.profile(
  347.            model,
  348.            inputs=(inputs, timestamps),
  349.            custom_ops={QKVAttention: QKVAttention.count_flops},
  350.        )
  351.    """
  352.     b, c, *spatial = y[0].shape
  353.     num_spatial = int(np.prod(spatial))
  354.     # We perform two matmuls with the same number of ops.
  355.     # The first computes the weight matrix, the second computes
  356.     # the combination of the value vectors.
  357.     matmul_ops = 2 * b * (num_spatial**2) * c
  358.     model.total_ops += torch.DoubleTensor([matmul_ops])
  359.  
  360.  
  361. class QKVAttentionLegacy(nn.Module):
  362.     """
  363.    A module which performs QKV attention. Matches legacy QKVAttention + input/ouput heads shaping
  364.    """
  365.  
  366.     def __init__(self, n_heads):
  367.         super().__init__()
  368.         self.n_heads = n_heads
  369.  
  370.     def forward(self, qkv):
  371.         """
  372.        Apply QKV attention.
  373.        :param qkv: an [N x (H * 3 * C) x T] tensor of Qs, Ks, and Vs.
  374.        :return: an [N x (H * C) x T] tensor after attention.
  375.        """
  376.         bs, width, length = qkv.shape
  377.         assert width % (3 * self.n_heads) == 0
  378.         ch = width // (3 * self.n_heads)
  379.         q, k, v = qkv.reshape(bs * self.n_heads, ch * 3, length).split(ch, dim=1)
  380.         scale = 1 / math.sqrt(math.sqrt(ch))
  381.         weight = torch.einsum(
  382.             "bct,bcs->bts", q * scale, k * scale
  383.         )  # More stable with f16 than dividing afterwards
  384.         weight = torch.softmax(weight.float(), dim=-1).type(weight.dtype)
  385.         a = torch.einsum("bts,bcs->bct", weight, v)
  386.         return a.reshape(bs, -1, length)
  387.  
  388.     @staticmethod
  389.     def count_flops(model, _x, y):
  390.         return count_flops_attn(model, _x, y)
  391.  
  392.  
  393. class QKVAttention(nn.Module):
  394.     """
  395.    A module which performs QKV attention and splits in a different order.
  396.    """
  397.  
  398.     def __init__(self, n_heads):
  399.         super().__init__()
  400.         self.n_heads = n_heads
  401.  
  402.     def forward(self, qkv):
  403.         """
  404.        Apply QKV attention.
  405.        :param qkv: an [N x (3 * H * C) x T] tensor of Qs, Ks, and Vs.
  406.        :return: an [N x (H * C) x T] tensor after attention.
  407.        """
  408.         bs, width, length = qkv.shape
  409.         assert width % (3 * self.n_heads) == 0
  410.         ch = width // (3 * self.n_heads)
  411.         q, k, v = qkv.chunk(3, dim=1)
  412.         scale = 1 / math.sqrt(math.sqrt(ch))
  413.         weight = torch.einsum(
  414.             "bct,bcs->bts",
  415.             (q * scale).view(bs * self.n_heads, ch, length),
  416.             (k * scale).view(bs * self.n_heads, ch, length),
  417.         )  # More stable with f16 than dividing afterwards
  418.         weight = torch.softmax(weight.float(), dim=-1).type(weight.dtype)
  419.         a = torch.einsum(
  420.             "bts,bcs->bct", weight, v.reshape(bs * self.n_heads, ch, length)
  421.         )
  422.         return a.reshape(bs, -1, length)
  423.  
  424.     @staticmethod
  425.     def count_flops(model, _x, y):
  426.         return count_flops_attn(model, _x, y)
  427.  
  428.  
  429. @dataclass(eq=False)
  430. class UNetModel(nn.Module):
  431.     """
  432.    The full UNet model with attention and timestep embedding.
  433.    :param in_channels: channels in the input Tensor.
  434.    :param model_channels: base channel count for the model.
  435.    :param out_channels: channels in the output Tensor.
  436.    :param num_res_blocks: number of residual blocks per downsample.
  437.    :param attention_resolutions: a collection of downsample rates at which
  438.        attention will take place. May be a set, list, or tuple.
  439.        For example, if this contains 4, then at 4x downsampling, attention
  440.        will be used.
  441.    :param dropout: the dropout probability.
  442.    :param channel_mult: channel multiplier for each level of the UNet.
  443.    :param conv_resample: if True, use learned convolutions for upsampling and
  444.        downsampling.
  445.    :param dims: determines if the signal is 1D, 2D, or 3D.
  446.    :param num_classes: if specified (as an int), then this model will be
  447.        class-conditional with `num_classes` classes.
  448.    :param use_checkpoint: use gradient checkpointing to reduce memory usage.
  449.    :param num_heads: the number of attention heads in each attention layer.
  450.    :param num_heads_channels: if specified, ignore num_heads and instead use
  451.                               a fixed channel width per attention head.
  452.    :param num_heads_upsample: works with num_heads to set a different number
  453.                               of heads for upsampling. Deprecated.
  454.    :param use_scale_shift_norm: use a FiLM-like conditioning mechanism.
  455.    :param resblock_updown: use residual blocks for up/downsampling.
  456.    :param use_new_attention_order: use a different attention pattern for potentially
  457.                                    increased efficiency.
  458.    """
  459.  
  460.     in_channels: int
  461.     model_channels: int = 128
  462.     out_channels: int = 3
  463.     num_res_blocks: int = 2
  464.     attention_resolutions: Tuple[int] = (1, 2, 2, 2)
  465.     dropout: float = 0.0
  466.     channel_mult: Tuple[int] = (1, 2, 4, 8)
  467.     conv_resample: bool = True
  468.     dims: int = 2
  469.     num_classes: Optional[int] = None
  470.     use_checkpoint: bool = False
  471.     num_heads: int = 1
  472.     num_head_channels: int = -1
  473.     num_heads_upsample: int = -1
  474.     use_scale_shift_norm: bool = False
  475.     resblock_updown: bool = False
  476.     use_new_attention_order: bool = False
  477.     with_fourier_features: bool = False
  478.     ignore_time: bool = False
  479.     input_projection: bool = True
  480.  
  481.     image_size: int = -1  # not used...
  482.     _target_: str = "lib.models.gd_unet.UNetModel"
  483.  
  484.     def __post_init__(self):
  485.         super().__init__()
  486.  
  487.         if self.with_fourier_features:
  488.             self.in_channels += 12
  489.  
  490.         if self.num_heads_upsample == -1:
  491.             self.num_heads_upsample = self.num_heads
  492.  
  493.         self.time_embed_dim = self.model_channels * 4
  494.         if self.ignore_time:
  495.             self.time_embed = lambda x: torch.zeros(
  496.                 x.shape[0], self.time_embed_dim, device=x.device, dtype=x.dtype
  497.             )
  498.         else:
  499.             self.time_embed = nn.Sequential(
  500.                 linear(self.model_channels, self.time_embed_dim),
  501.                 nn.SiLU(),
  502.                 linear(self.time_embed_dim, self.time_embed_dim),
  503.             )
  504.  
  505.         if self.num_classes is not None:
  506.             self.label_emb = nn.Embedding(
  507.                 self.num_classes + 1, self.time_embed_dim, padding_idx=self.num_classes
  508.             )
  509.  
  510.         ch = input_ch = int(self.channel_mult[0] * self.model_channels)
  511.         if self.input_projection:
  512.             self.input_blocks = nn.ModuleList(
  513.                 [
  514.                     TimestepEmbedSequential(
  515.                         conv_nd(self.dims, self.in_channels, ch, 3, padding=1)
  516.                     )
  517.                 ]
  518.             )
  519.         else:
  520.             self.input_blocks = nn.ModuleList(
  521.                 [TimestepEmbedSequential(torch.nn.Identity())]
  522.             )
  523.         self._feature_size = ch
  524.         input_block_chans = [ch]
  525.         ds = 1
  526.         for level, mult in enumerate(self.channel_mult):
  527.             for _ in range(self.num_res_blocks):
  528.                 layers = [
  529.                     ResBlock(
  530.                         ch,
  531.                         self.time_embed_dim,
  532.                         self.dropout,
  533.                         out_channels=int(mult * self.model_channels),
  534.                         dims=self.dims,
  535.                         use_checkpoint=self.use_checkpoint,
  536.                         use_scale_shift_norm=self.use_scale_shift_norm,
  537.                         emb_off=self.ignore_time and self.num_classes is None,
  538.                     )
  539.                 ]
  540.                 ch = int(mult * self.model_channels)
  541.                 if ds in self.attention_resolutions:
  542.                     layers.append(
  543.                         AttentionBlock(
  544.                             ch,
  545.                             use_checkpoint=self.use_checkpoint,
  546.                             num_heads=self.num_heads,
  547.                             num_head_channels=self.num_head_channels,
  548.                             use_new_attention_order=self.use_new_attention_order,
  549.                         )
  550.                     )
  551.                 self.input_blocks.append(TimestepEmbedSequential(*layers))
  552.                 self._feature_size += ch
  553.                 input_block_chans.append(ch)
  554.             if level != len(self.channel_mult) - 1:
  555.                 out_ch = ch
  556.                 self.input_blocks.append(
  557.                     TimestepEmbedSequential(
  558.                         ResBlock(
  559.                             ch,
  560.                             self.time_embed_dim,
  561.                             self.dropout,
  562.                             out_channels=out_ch,
  563.                             dims=self.dims,
  564.                             use_checkpoint=self.use_checkpoint,
  565.                             use_scale_shift_norm=self.use_scale_shift_norm,
  566.                             down=True,
  567.                             emb_off=self.ignore_time and self.num_classes is None,
  568.                         )
  569.                         if self.resblock_updown
  570.                         else Downsample(
  571.                             ch, self.conv_resample, dims=self.dims, out_channels=out_ch
  572.                         )
  573.                     )
  574.                 )
  575.                 ch = out_ch
  576.                 input_block_chans.append(ch)
  577.                 ds *= 2
  578.                 self._feature_size += ch
  579.  
  580.         self.middle_block = TimestepEmbedSequential(
  581.             ResBlock(
  582.                 ch,
  583.                 self.time_embed_dim,
  584.                 self.dropout,
  585.                 dims=self.dims,
  586.                 use_checkpoint=self.use_checkpoint,
  587.                 use_scale_shift_norm=self.use_scale_shift_norm,
  588.                 emb_off=self.ignore_time and self.num_classes is None,
  589.             ),
  590.             AttentionBlock(
  591.                 ch,
  592.                 use_checkpoint=self.use_checkpoint,
  593.                 num_heads=self.num_heads,
  594.                 num_head_channels=self.num_head_channels,
  595.                 use_new_attention_order=self.use_new_attention_order,
  596.             ),
  597.             ResBlock(
  598.                 ch,
  599.                 self.time_embed_dim,
  600.                 self.dropout,
  601.                 dims=self.dims,
  602.                 use_checkpoint=self.use_checkpoint,
  603.                 use_scale_shift_norm=self.use_scale_shift_norm,
  604.                 emb_off=self.ignore_time and self.num_classes is None,
  605.             ),
  606.         )
  607.         self._feature_size += ch
  608.  
  609.         self.output_blocks = nn.ModuleList([])
  610.         for level, mult in list(enumerate(self.channel_mult))[::-1]:
  611.             for i in range(self.num_res_blocks + 1):
  612.                 ich = input_block_chans.pop()
  613.                 layers = [
  614.                     ResBlock(
  615.                         ch + ich,
  616.                         self.time_embed_dim,
  617.                         self.dropout,
  618.                         out_channels=int(self.model_channels * mult),
  619.                         dims=self.dims,
  620.                         use_checkpoint=self.use_checkpoint,
  621.                         use_scale_shift_norm=self.use_scale_shift_norm,
  622.                         emb_off=self.ignore_time and self.num_classes is None,
  623.                     )
  624.                 ]
  625.                 ch = int(self.model_channels * mult)
  626.                 if ds in self.attention_resolutions:
  627.                     layers.append(
  628.                         AttentionBlock(
  629.                             ch,
  630.                             use_checkpoint=self.use_checkpoint,
  631.                             num_heads=self.num_heads_upsample,
  632.                             num_head_channels=self.num_head_channels,
  633.                             use_new_attention_order=self.use_new_attention_order,
  634.                         )
  635.                     )
  636.                 if level and i == self.num_res_blocks:
  637.                     out_ch = ch
  638.                     layers.append(
  639.                         ResBlock(
  640.                             ch,
  641.                             self.time_embed_dim,
  642.                             self.dropout,
  643.                             out_channels=out_ch,
  644.                             dims=self.dims,
  645.                             use_checkpoint=self.use_checkpoint,
  646.                             use_scale_shift_norm=self.use_scale_shift_norm,
  647.                             up=True,
  648.                             emb_off=self.ignore_time and self.num_classes is None,
  649.                         )
  650.                         if self.resblock_updown
  651.                         else Upsample(
  652.                             ch, self.conv_resample, dims=self.dims, out_channels=out_ch
  653.                         )
  654.                     )
  655.                     ds //= 2
  656.                 self.output_blocks.append(TimestepEmbedSequential(*layers))
  657.                 self._feature_size += ch
  658.  
  659.         self.out = nn.Sequential(
  660.             normalization(ch),
  661.             nn.SiLU(),
  662.             zero_module(conv_nd(self.dims, input_ch, self.out_channels, 3, padding=1)),
  663.         )
  664.  
  665.     def forward(self, x, timesteps, extra):
  666.         """
  667.        Apply the model to an input batch.
  668.        :param x: an [N x C x ...] Tensor of inputs.
  669.        :param timesteps: a 1-D batch of timesteps.
  670.        :param y: an [N] Tensor of labels, if class-conditional.
  671.        :return: an [N x C x ...] Tensor of outputs.
  672.        """
  673.         if self.with_fourier_features:
  674.             z_f = base2_fourier_features(x, start=6, stop=8, step=1)
  675.             x = torch.cat([x, z_f], dim=1)
  676.  
  677.         hs = []
  678.         emb = self.time_embed(timestep_embedding(timesteps, self.model_channels).to(x))
  679.  
  680.         if self.ignore_time:
  681.             emb = emb * 0.0
  682.  
  683.         if self.num_classes and "label" not in extra:
  684.             # Hack to deal with ddp find_unused_parameters not working with activation checkpointing...
  685.             # self.num_classes corresponds to the pad index of the embedding table
  686.             extra["label"] = torch.full(
  687.                 (x.size(0),), self.num_classes, dtype=torch.long, device=x.device
  688.             )
  689.  
  690.         if self.num_classes is not None and "label" in extra:
  691.             y = extra["label"]
  692.             assert (
  693.                 y.shape == x.shape[:1]
  694.             ), f"Labels have shape {y.shape}, which does not match the batch dimension of the input {x.shape}"
  695.             emb = emb + self.label_emb(y)
  696.  
  697.         h = x
  698.         if "concat_conditioning" in extra:
  699.             h = torch.cat([x, extra["concat_conditioning"]], dim=1)
  700.  
  701.         for module in self.input_blocks:
  702.             h = module(h, emb)
  703.             hs.append(h)
  704.         h = self.middle_block(h, emb)
  705.         for module in self.output_blocks:
  706.             h = torch.cat([h, hs.pop()], dim=1)
  707.             h = module(h, emb)
  708.         h = h.type(x.dtype)
  709.         result = self.out(h)
  710.         return result
  711.  
  712.  
  713. # Based on https://github.com/google-research/vdm/blob/main/model_vdm.py
  714. def base2_fourier_features(
  715.     inputs: torch.Tensor, start: int = 0, stop: int = 8, step: int = 1
  716. ) -> torch.Tensor:
  717.     freqs = torch.arange(start, stop, step, device=inputs.device, dtype=inputs.dtype)
  718.  
  719.     # Create Base 2 Fourier features
  720.     w = 2.0**freqs * 2 * np.pi
  721.     w = torch.tile(w[None, :], (1, inputs.size(1)))
  722.  
  723.     # Compute features
  724.     h = torch.repeat_interleave(inputs, len(freqs), dim=1)
  725.     h = w[:, :, None, None] * h
  726.     h = torch.cat([torch.sin(h), torch.cos(h)], dim=1)
  727.     return h
Advertisement
Add Comment
Please, Sign In to add comment