BlidReview's picture
weights, code, eval script
bdce880 verified
Raw
History Blame Contribute Delete
2.94 kB
import math
import torch
import torch.nn as nn
from einops import rearrange
class RotaryEmbedding(nn.Module):
def __init__(self, dim, min_freq=1 / 2, scale=1.):
super().__init__()
inv_freq = 1. / (10000 ** (torch.arange(0, dim, 2).float() / dim))
self.min_freq = min_freq
self.scale = scale
self.register_buffer('inv_freq', inv_freq)
def forward(self, coordinates, device):
# coordinates [b, n]
t = coordinates.to(device).type_as(self.inv_freq)
t = t * (self.scale / self.min_freq)
freqs = torch.einsum('... i , j -> ... i j', t, self.inv_freq) # [b, n, d//2]
return torch.cat((freqs, freqs), dim=-1) # [b, n, d]
def rotate_half(x):
x = rearrange(x, '... (j d) -> ... j d', j=2)
x1, x2 = x.unbind(dim=-2)
return torch.cat((-x2, x1), dim=-1)
def apply_rotary_pos_emb(t, freqs):
return (t * freqs.cos()) + (rotate_half(t) * freqs.sin())
def apply_2d_rotary_pos_emb(t, freqs_x, freqs_y):
# split t into first half and second half
# t: [b, h, n, d]
# freq_x/y: [b, n, d]
d = t.shape[-1]
t_x, t_y = t[..., :d // 2], t[..., d // 2:]
return torch.cat((apply_rotary_pos_emb(t_x, freqs_x),
apply_rotary_pos_emb(t_y, freqs_y)), dim=-1)
class PositionalEncoding(nn.Module):
"Implement the PE function."
def __init__(self, d_model, dropout, max_len=421 * 421):
super(PositionalEncoding, self).__init__()
self.dropout = nn.Dropout(p=dropout)
# Compute the positional encodings once in log space.
pe = torch.zeros(max_len, d_model)
position = torch.arange(0, max_len).unsqueeze(1)
div_term = torch.exp(
torch.arange(0, d_model, 2) * -(math.log(10000.0) / d_model)
)
pe[:, 0::2] = torch.sin(position * div_term)
pe[:, 1::2] = torch.cos(position * div_term)
pe = pe.unsqueeze(0)
self.register_buffer("pe", pe)
def forward(self, x):
x = x + self.pe[:, : x.size(1)].requires_grad_(False)
return self.dropout(x)
def timestep_embedding(timesteps, dim, max_period=10000, repeat_only=False):
"""
Create sinusoidal timestep embeddings.
:param timesteps: a 1-D Tensor of N indices, one per batch element.
These may be fractional.
:param dim: the dimension of the output.
:param max_period: controls the minimum frequency of the embeddings.
:return: an [N x dim] Tensor of positional embeddings.
"""
half = dim // 2
freqs = torch.exp(
-math.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32) / half
).to(device=timesteps.device)
args = timesteps[:, None].float() * freqs[None]
embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1)
if dim % 2:
embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1)
return embedding