GRN / grn /models /rope.py
hanjian.thu123
[update] app.py
17a8581
Raw History Blame Contribute Delete
11.6 kB
import math
import os
from functools import partial
from typing import Optional, Tuple, Union
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
from timm.models.layers import DropPath, drop_path
from torch.utils.checkpoint import checkpoint
def precompute_rope2d_freqs_grid(dim, dynamic_resolution_h_w, rope2d_normalized_by_hw, pad_to_multiplier=1, max_height=2048 // 16, max_width=2048 // 16, base=10000.0, device=None, scaling_factor=1.0, activated_h_div_w_templates=[]):
# split the dimension into half, one for x and one for y
half_dim = dim // 2
inv_freq = 1.0 / (base ** (torch.arange(0, half_dim, 2, dtype=torch.int64).float().to(device) / half_dim)) # namely theta, 1 / (10000^(i/half_dim)), i=0,2,..., half_dim-2
t_height = torch.arange(max_height, device=device, dtype=torch.int64).type_as(inv_freq)
t_width = torch.arange(max_width, device=device, dtype=torch.int64).type_as(inv_freq)
t_height = t_height / scaling_factor
freqs_height = torch.outer(t_height, inv_freq) # (max_height, dim / (1 for 1d, 2 for 2d, 3 for 3d) / 2), namely y*theta
t_width = t_width / scaling_factor
freqs_width = torch.outer(t_width, inv_freq) # (max_width, dim / (1 for 1d, 2 for 2d, 3 for 3d) / 2), namely x*theta
freqs_grid_map = torch.concat([
freqs_height[:, None, :].expand(-1, max_width, -1), # (max_height, max_width, dim / (1 for 1d, 2 for 2d, 3 for 3d) / 2)
freqs_width[None, :, :].expand(max_height, -1, -1), # (max_height, max_width, dim / (1 for 1d, 2 for 2d, 3 for 3d) / 2)
], dim=-1) # (max_height, max_width, dim / (1 for 1d, 2 for 2d, 3 for 3d))
freqs_grid_map = torch.stack([torch.cos(freqs_grid_map), torch.sin(freqs_grid_map)], dim=0)
# (2, max_height, max_width, dim / (1 for 1d, 2 for 2d, 3 for 3d))
rope2d_freqs_grid = {}
for h_div_w in activated_h_div_w_templates:
assert h_div_w in dynamic_resolution_h_w, f'Unknown h_div_w: {h_div_w}'
scale_schedule = dynamic_resolution_h_w[h_div_w]['1M']['image_scales']
_, ph, pw = scale_schedule[-1]
max_edge_length = freqs_grid_map.shape[1]
if ph >= pw:
uph, upw = max_edge_length, int(max_edge_length / ph * pw)
else:
uph, upw = int(max_edge_length / pw * ph), max_edge_length
rope_cache_list = []
for (_, ph, pw) in scale_schedule:
ph_mul_pw = ph * pw
if rope2d_normalized_by_hw == 1: # downsample
rope_cache = F.interpolate(freqs_grid_map[:, :uph, :upw, :].permute([0,3,1,2]), size=(ph, pw), mode='bilinear', align_corners=True)
rope_cache = rope_cache.permute([0,2,3,1]) # (2, ph, pw, half_head_dim)
elif rope2d_normalized_by_hw == 2: # star stylee
_, uph, upw = scale_schedule[-1]
indices = torch.stack([
(torch.arange(ph) * (uph / ph)).reshape(ph, 1).expand(ph, pw),
(torch.arange(pw) * (upw / pw)).reshape(1, pw).expand(ph, pw),
], dim=-1).round().int() # (ph, pw, 2)
indices = indices.reshape(-1, 2) # (ph*pw, 2)
rope_cache = freqs_grid_map[:, indices[:,0], indices[:,1], :] # (2, ph*pw, half_head_dim)
rope_cache = rope_cache.reshape(2, ph, pw, -1)
elif rope2d_normalized_by_hw == 0:
rope_cache = freqs_grid_map[:, :ph, :pw, :] # (2, ph, pw, half_head_dim)
else:
raise ValueError(f'Unknown rope2d_normalized_by_hw: {rope2d_normalized_by_hw}')
rope_cache_list.append(rope_cache.reshape(2, ph_mul_pw, -1))
cat_rope_cache = torch.cat(rope_cache_list, 1) # (2, seq_len, half_head_dim)
if cat_rope_cache.shape[1] % pad_to_multiplier:
pad = torch.zeros(2, pad_to_multiplier - cat_rope_cache.shape[1] % pad_to_multiplier, half_dim)
cat_rope_cache = torch.cat([cat_rope_cache, pad], dim=1)
cat_rope_cache = cat_rope_cache[:,None,None,None] # (2, 1, 1, 1, seq_len, half_dim)
for pn in dynamic_resolution_h_w[h_div_w]:
scale_schedule = dynamic_resolution_h_w[h_div_w][pn]['image_scales']
tmp_scale_schedule = [(1, h, w) for _, h, w in scale_schedule]
rope2d_freqs_grid[str(tuple(tmp_scale_schedule))] = cat_rope_cache
return rope2d_freqs_grid
def precompute_rope3d_freqs_grid(
dim,
rope2d_normalized_by_hw,
max_frames=128,
max_height=2048 // 8,
max_width=2048 // 8,
base=10000.0,
device=None,
activated_h_div_w_templates=[],
text_maxlen=0,
pn=None,
args=None,
**kwargs,
):
# split the dimension into three parts, one for x, one for y, and one for t
print(f'[precompute_rope4d_freqs_grid: 3d]: start')
assert dim % 2 == 0, f'Only support dim % 2 == 0, but got dim={dim}'
dim_div_2 = dim // 2
num_of_freqs_former = dim_div_2 // 3
preserve_1d_length = 600
num_of_freqs_last = dim_div_2 - num_of_freqs_former * 2 # in some cases, dim_div_2 % 3 != 0. here tackle with these cases
inv_freq_former = 1.0 / (base ** (torch.arange(num_of_freqs_former, dtype=torch.int64).float().to(device) / num_of_freqs_former)) # namely theta, 1 / (10000^(i/dim_div_3)), i=0,2,..., dim_div_3-2, totally dim_div_3 / 2 elems
inv_freq_last = 1.0 / (base ** (torch.arange(num_of_freqs_last, dtype=torch.int64).float().to(device) / num_of_freqs_last))
t_frames = torch.arange(preserve_1d_length+max_frames, device=device, dtype=torch.int64).type_as(inv_freq_former)
t_height = torch.arange(max_height, device=device, dtype=torch.int64).type_as(inv_freq_former)
t_width = torch.arange(max_width, device=device, dtype=torch.int64).type_as(inv_freq_former)
freqs_frames = torch.outer(t_frames, inv_freq_former) # (max_frames, (dim_div_2 / 3)), namely x*theta
freqs_height = torch.outer(t_height, inv_freq_former) # (max_height, (dim_div_2 / 3), namely y*theta
freqs_width = torch.outer(t_width, inv_freq_last) # (max_width, (dim_div_2 / 3)), namely x*theta
freqs_frames = torch.stack([torch.cos(freqs_frames), torch.sin(freqs_frames)], dim=0)
freqs_height = torch.stack([torch.cos(freqs_height), torch.sin(freqs_height)], dim=0)
freqs_width = torch.stack([torch.cos(freqs_width), torch.sin(freqs_width)], dim=0)
tm = preserve_1d_length
rope_text_embeds = torch.cat([
freqs_frames[ :, :tm, None, None, :].expand(-1, -1, -1, -1, -1),
freqs_height[ :, None, :1, None, :].expand(-1, tm, -1, -1, -1),
freqs_width[ :, None, None, :1, :].expand(-1, tm, -1, -1, -1),
], dim=-1) # (2, tm, 1, 1, dim_div_2)
rope_text_embeds = rope_text_embeds.reshape(2, 1, 1, 1, tm, dim_div_2)
rope2d_freqs_grid = {}
rope2d_freqs_grid['freqs_text'] = rope_text_embeds # (2, 1, 1, 1, preserve_1d_length, dim / 2)
rope2d_freqs_grid['freqs_frames'] = freqs_frames[:, tm:] # (2, max_frames, ceil(dim_div_2 / 4))
rope2d_freqs_grid['freqs_height'] = freqs_height # (2, max_height, ceil(dim_div_2 / 4))
rope2d_freqs_grid['freqs_width'] = freqs_width # (2, max_width, ceil(dim_div_2 / 4))
return rope2d_freqs_grid
def precompute_rope4d_freqs_grid(
dim,
rope2d_normalized_by_hw,
max_scales=128,
max_frames=128,
max_height=2048 // 8,
max_width=2048 // 8,
base=10000.0,
device=None,
activated_h_div_w_templates=[],
text_maxlen=0,
pn=None,
args=None,
**kwargs,
):
# split the dimension into three parts, one for x, one for y, and one for t
print(f'[precompute_rope4d_freqs_grid: 4d]: start')
assert dim % 2 == 0, f'Only support dim % 2 == 0, but got dim={dim}'
dim_div_2 = dim // 2
num_of_freqs = int(np.ceil(dim_div_2 / 4))
inv_freq = 1.0 / (base ** (torch.arange(num_of_freqs, dtype=torch.int64).float().to(device) / num_of_freqs)) # namely theta, 1 / (10000^(i/dim_div_4)), i=0,2,..., dim_div_4-2, totally dim_div_4 / 2 elems
t_scales = torch.arange(text_maxlen+max_scales, device=device, dtype=torch.int64).type_as(inv_freq)
t_frames = torch.arange(max_frames, device=device, dtype=torch.int64).type_as(inv_freq)
t_height = torch.arange(max_height, device=device, dtype=torch.int64).type_as(inv_freq)
t_width = torch.arange(max_width, device=device, dtype=torch.int64).type_as(inv_freq)
freqs_scales = torch.outer(t_scales, inv_freq) # (text_maxlen+max_scales, ceil(dim_div_2 / 4)), namely x*theta
freqs_frames = torch.outer(t_frames, inv_freq) # (max_frames, ceil(dim_div_2 / 4)), namely x*theta
freqs_height = torch.outer(t_height, inv_freq) # (max_height, ceil(dim_div_2 / 4)), namely y*theta
freqs_width = torch.outer(t_width, inv_freq) # (max_width, ceil(dim_div_2 / 4)), namely x*theta
assert num_of_freqs*4==dim_div_2
freqs_scales = torch.stack([torch.cos(freqs_scales), torch.sin(freqs_scales)], dim=0)
freqs_frames = torch.stack([torch.cos(freqs_frames), torch.sin(freqs_frames)], dim=0)
freqs_height = torch.stack([torch.cos(freqs_height), torch.sin(freqs_height)], dim=0)
freqs_width = torch.stack([torch.cos(freqs_width), torch.sin(freqs_width)], dim=0)
tm = text_maxlen
rope_text_embeds = torch.cat([
freqs_scales[ :, :tm, None, None, None, :].expand(-1, -1, -1, -1, -1, -1),
freqs_frames[ :, None, :1, None, None, :].expand(-1, tm, -1, -1, -1, -1),
freqs_height[ :, None, None, :1, None, :].expand(-1, tm, -1, -1, -1, -1),
freqs_width[ :, None, None, None, :1, :].expand(-1, tm, -1, -1, -1, -1),
], dim=-1) # (2, tm, 1, 1, 1, dim_div_2)
rope_text_embeds = rope_text_embeds.reshape(2, 1, 1, 1, tm, dim_div_2)
rope2d_freqs_grid = {}
rope2d_freqs_grid['freqs_text'] = rope_text_embeds # (2, 1, 1, 1, text_maxlen, dim / 2)
rope2d_freqs_grid['freqs_scales'] = freqs_scales[:, tm:] # (2, max_scales, ceil(dim_div_2 / 4))
rope2d_freqs_grid['freqs_frames'] = freqs_frames # (2, max_frames, ceil(dim_div_2 / 4))
rope2d_freqs_grid['freqs_height'] = freqs_height # (2, max_height, ceil(dim_div_2 / 4))
rope2d_freqs_grid['freqs_width'] = freqs_width # (2, max_width, ceil(dim_div_2 / 4))
return rope2d_freqs_grid
def apply_rotary_emb(q, k, rope_cache):
device_type = q.device.type
device_type = device_type if isinstance(device_type, str) and device_type != "mps" else "cpu"
qk = [q, k]
rope_cache = rope_cache[:,0]
with torch.autocast(device_type=device_type, enabled=False):
for i in range(2):
qk[i] = qk[i].reshape(*qk[i].shape[:-1], -1, 2)
tmp1 = qk[i][..., 1] * rope_cache[1]
tmp2 = qk[i][..., 0] * rope_cache[1]
qk[i][..., 0].mul_(rope_cache[0]).sub_(tmp1)
qk[i][..., 1].mul_(rope_cache[0]).add_(tmp2)
qk[i] = qk[i].reshape(*qk[i].shape[:-2], -1)
q, k = qk
# qk = qk.reshape(*qk.shape[:-1], -1, 2) #(2, batch_size, heads, seq_len, half_head_dim, 2)
# qk = torch.stack([
# qk[...,0] * rope_cache[0] - qk[...,1] * rope_cache[1],
# qk[...,0] * rope_cache[1] + qk[...,1] * rope_cache[0],
# ], dim=-1) # (2, batch_size, heads, seq_len, half_head_dim, 2), here stack + reshape should not be concate
# qk = qk.reshape(*qk.shape[:-2], -1) #(2, batch_size, heads, seq_len, head_dim)
# q, k = qk.unbind(dim=0) # (batch_size, heads, seq_len, head_dim)
return q, k