from torch import nn from torch.nn import functional as F from .unet import UNET, UNET_OutputLayer class TimeEmbedding(nn.Module): def __init__(self, n_embd): super().__init__() self.linear_1 = nn.Linear(n_embd, 4 * n_embd) self.linear_2 = nn.Linear(4 * n_embd, 4 * n_embd) def forward(self, x): # x: (1, 320) # (1, 320) -> (1, 1280) x = self.linear_1(x) # (1, 1280) -> (1, 1280) x = F.silu(x) # (1, 1280) -> (1, 1280) x = self.linear_2(x) return x class Diffusion(nn.Module): def __init__(self): super().__init__() self.time_embedding = TimeEmbedding(320) self.unet = UNET() self.final = UNET_OutputLayer(320, 4) def forward(self, latent, context, time): # latent: (Batch_Size, 4, Height / 8, Width / 8) # context: (Batch_Size, Seq_Len, Dim) # time: (1, 320) # (1, 320) -> (1, 1280) time = self.time_embedding(time) # (Batch, 4, Height / 8, Width / 8) -> (Batch, 320, Height / 8, Width / 8) output = self.unet(latent, context, time) # (Batch, 320, Height / 8, Width / 8) -> (Batch, 4, Height / 8, Width / 8) output = self.final(output) # (Batch, 4, Height / 8, Width / 8) return output