HARSHIT-hash-07
feat: integrated cloud-based diffusion inference module
17f1f54
Raw
History Blame Contribute Delete
6.5 kB
# # coding: utf-8
import torch
import torch.nn as nn
import math
from torch import Tensor
from helpers import freeze_params, subsequent_mask
from transformer_layers import PositionalEncoding, TransformerDecoderLayer
class SinusoidalPositionEmbeddings(nn.Module):
def __init__(self, dim: int):
super().__init__()
self.dim = dim
def forward(self, time: Tensor) -> Tensor:
# time: [B] (long or float)
device = time.device
half_dim = self.dim // 2
freq = math.log(10000) / (half_dim - 1)
freq = torch.exp(torch.arange(half_dim, device=device) * -freq)
# ensure float
time = time.float()
# [B, half_dim]
angles = time[:, None] * freq[None, :]
# [B, dim]
return torch.cat((angles.sin(), angles.cos()), dim=-1)
class ACD_Denoiser(nn.Module):
def __init__(
self,
num_layers: int = 2,
num_heads: int = 4,
hidden_size: int = 512,
ff_size: int = 2048,
dropout: float = 0.1,
emb_dropout: float = 0.1,
vocab_size: int = 1,
freeze: bool = False,
trg_size: int = 150,
decoder_trg_trg_: bool = True,
**kwargs
):
super(ACD_Denoiser, self).__init__()
# remember for repr
self.num_layers = num_layers
self.num_heads = num_heads
# Input features = joints (trg_size=150) + iconicity/bone dir+len (50*4)
# total in_feature_size = 150 + 200 = 350 (= 50 * 7)
self.in_feature_size = trg_size + (trg_size // 3) * 4
self.out_feature_size = trg_size
# Embedding for target features
self.pos_drop = nn.Dropout(p=emb_dropout)
self.trg_embed = nn.Linear(self.in_feature_size, hidden_size)
self.pe = PositionalEncoding(hidden_size, mask_count=True)
self.emb_dropout = nn.Dropout(p=emb_dropout)
# Two-layer decoder stack (as in original)
if num_layers == 2:
self.layers_pose_condition = TransformerDecoderLayer(
size=hidden_size,
ff_size=ff_size,
num_heads=num_heads,
dropout=dropout,
decoder_trg_trg=decoder_trg_trg_,
)
self.layer_norm_mid = nn.LayerNorm(hidden_size, eps=1e-6)
self.output_layer_mid = nn.Linear(hidden_size, self.in_feature_size, bias=False)
self.o1_embed = nn.Linear(trg_size, hidden_size) # joints part (50*3)
self.o2_embed = nn.Linear((trg_size // 3) * 4, hidden_size) # bones part (50*4)
self.layers_mha_ac = TransformerDecoderLayer(
size=hidden_size,
ff_size=ff_size,
num_heads=num_heads,
dropout=dropout,
decoder_trg_trg=decoder_trg_trg_,
)
self.layer_norm = nn.LayerNorm(hidden_size, eps=1e-6)
# --- time embedding ---
self.time_mlp = nn.Sequential(
SinusoidalPositionEmbeddings(hidden_size),
nn.Linear(hidden_size, hidden_size * 2),
nn.GELU(),
nn.Linear(hidden_size * 2, hidden_size),
)
# NEW: small projector to inject [sigma_B, sigma_H] (2 scalars) into the time embedding
self.time_proj = nn.Sequential(
nn.Linear(hidden_size + 2, hidden_size),
nn.GELU(),
nn.Linear(hidden_size, hidden_size),
)
# Output head -> predict x0 joints (trg_size)
self.output_layer = nn.Linear(hidden_size, trg_size, bias=False)
if freeze:
freeze_params(self)
def forward(
self,
t: Tensor,
trg_embed: Tensor = None,
encoder_output: Tensor = None,
src_mask: Tensor = None,
trg_mask: Tensor = None,
sigma_B: Tensor = None, # NEW (optional): [B]
sigma_H: Tensor = None, # NEW (optional): [B]
**kwargs,
) -> Tensor:
assert trg_mask is not None, "trg_mask required for Transformer"
# --- time conditioning ---
# base time embedding: [B, hidden]
t_base = self.time_mlp(t)
# add two-rate noise indicators; default to zeros for backward-compat
if sigma_B is None or sigma_H is None:
# type/shape safety
sigma_B = torch.zeros_like(t, dtype=t_base.dtype)
sigma_H = torch.zeros_like(t, dtype=t_base.dtype)
# concat and project back to hidden
t_aug = torch.stack([sigma_B, sigma_H], dim=-1) # [B, 2]
t_cond = self.time_proj(torch.cat([t_base, t_aug], dim=-1)) # [B, hidden]
# broadcast over time dimension of encoder_output
time_embed = t_cond[:, None, :].repeat(1, encoder_output.shape[1], 1)
# conditioning: encoder outputs + time embedding
condition = encoder_output + time_embed
condition = self.pos_drop(condition)
# target stream
trg_embed = self.trg_embed(trg_embed)
x = self.pe(trg_embed)
x = self.emb_dropout(x)
padding_mask = trg_mask
# causal mask for target self-attn
sub_mask = subsequent_mask(trg_embed.size(1)).type_as(trg_mask)
# cross-attend target stream to conditioning
x, _ = self.layers_pose_condition(
x=x,
memory=condition,
src_mask=src_mask,
trg_mask=sub_mask,
padding_mask=padding_mask,
)
# mid projection to split (joints vs bones) and re-embed
x = self.layer_norm_mid(x)
x = self.output_layer_mid(x) # [B,T,350]
o_reshaped = x.view(x.shape[0], x.shape[1], 50, 7)
o_1, o_2 = torch.split(o_reshaped, [3, 4], dim=-1) # joints(3) vs bones(4)
o_1 = o_1.reshape(o_1.shape[0], o_1.shape[1], 50 * 3)
o_2 = o_2.reshape(o_2.shape[0], o_2.shape[1], 50 * 4)
o_1 = self.o1_embed(o_1)
o_2 = self.o2_embed(o_2)
# second decoder layer mixes the two streams
x, _ = self.layers_mha_ac(
x=o_1,
memory=o_2,
src_mask=sub_mask,
trg_mask=sub_mask,
padding_mask=padding_mask,
)
# final norm + linear head -> joints x0
x = self.layer_norm(x)
output = self.output_layer(x) # [B,T,150]
return output
def __repr__(self):
return f"{self.__class__.__name__}(num_layers={self.num_layers}, num_heads={self.num_heads})"