x_transformer.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. """shout-out to https://github.com/lucidrains/x-transformers/tree/main/x_transformers"""
  2. import torch
  3. from torch import nn, einsum
  4. import torch.nn.functional as F
  5. from functools import partial
  6. from inspect import isfunction
  7. from collections import namedtuple
  8. from einops import rearrange, repeat, reduce
  9. # constants
  10. DEFAULT_DIM_HEAD = 64
  11. Intermediates = namedtuple('Intermediates', [
  12. 'pre_softmax_attn',
  13. 'post_softmax_attn'
  14. ])
  15. LayerIntermediates = namedtuple('Intermediates', [
  16. 'hiddens',
  17. 'attn_intermediates'
  18. ])
  19. class AbsolutePositionalEmbedding(nn.Module):
  20. def __init__(self, dim, max_seq_len):
  21. super().__init__()
  22. self.emb = nn.Embedding(max_seq_len, dim)
  23. self.init_()
  24. def init_(self):
  25. nn.init.normal_(self.emb.weight, std=0.02)
  26. def forward(self, x):
  27. n = torch.arange(x.shape[1], device=x.device)
  28. return self.emb(n)[None, :, :]
  29. class FixedPositionalEmbedding(nn.Module):
  30. def __init__(self, dim):
  31. super().__init__()
  32. inv_freq = 1. / (10000 ** (torch.arange(0, dim, 2).float() / dim))
  33. self.register_buffer('inv_freq', inv_freq)
  34. def forward(self, x, seq_dim=1, offset=0):
  35. t = torch.arange(x.shape[seq_dim], device=x.device).type_as(self.inv_freq) + offset
  36. sinusoid_inp = torch.einsum('i , j -> i j', t, self.inv_freq)
  37. emb = torch.cat((sinusoid_inp.sin(), sinusoid_inp.cos()), dim=-1)
  38. return emb[None, :, :]
  39. # helpers
  40. def exists(val):
  41. return val is not None
  42. def default(val, d):
  43. if exists(val):
  44. return val
  45. return d() if isfunction(d) else d
  46. def always(val):
  47. def inner(*args, **kwargs):
  48. return val
  49. return inner
  50. def not_equals(val):
  51. def inner(x):
  52. return x != val
  53. return inner
  54. def equals(val):
  55. def inner(x):
  56. return x == val
  57. return inner
  58. def max_neg_value(tensor):
  59. return -torch.finfo(tensor.dtype).max
  60. # keyword argument helpers
  61. def pick_and_pop(keys, d):
  62. values = list(map(lambda key: d.pop(key), keys))
  63. return dict(zip(keys, values))
  64. def group_dict_by_key(cond, d):
  65. return_val = [dict(), dict()]
  66. for key in d.keys():
  67. match = bool(cond(key))
  68. ind = int(not match)
  69. return_val[ind][key] = d[key]
  70. return (*return_val,)
  71. def string_begins_with(prefix, str):
  72. return str.startswith(prefix)
  73. def group_by_key_prefix(prefix, d):
  74. return group_dict_by_key(partial(string_begins_with, prefix), d)
  75. def groupby_prefix_and_trim(prefix, d):
  76. kwargs_with_prefix, kwargs = group_dict_by_key(partial(string_begins_with, prefix), d)
  77. kwargs_without_prefix = dict(map(lambda x: (x[0][len(prefix):], x[1]), tuple(kwargs_with_prefix.items())))
  78. return kwargs_without_prefix, kwargs
  79. # classes
  80. class Scale(nn.Module):
  81. def __init__(self, value, fn):
  82. super().__init__()
  83. self.value = value
  84. self.fn = fn
  85. def forward(self, x, **kwargs):
  86. x, *rest = self.fn(x, **kwargs)
  87. return (x * self.value, *rest)
  88. class Rezero(nn.Module):
  89. def __init__(self, fn):
  90. super().__init__()
  91. self.fn = fn
  92. self.g = nn.Parameter(torch.zeros(1))
  93. def forward(self, x, **kwargs):
  94. x, *rest = self.fn(x, **kwargs)
  95. return (x * self.g, *rest)
  96. class ScaleNorm(nn.Module):
  97. def __init__(self, dim, eps=1e-5):
  98. super().__init__()
  99. self.scale = dim ** -0.5
  100. self.eps = eps
  101. self.g = nn.Parameter(torch.ones(1))
  102. def forward(self, x):
  103. norm = torch.norm(x, dim=-1, keepdim=True) * self.scale
  104. return x / norm.clamp(min=self.eps) * self.g
  105. class RMSNorm(nn.Module):
  106. def __init__(self, dim, eps=1e-8):
  107. super().__init__()
  108. self.scale = dim ** -0.5
  109. self.eps = eps
  110. self.g = nn.Parameter(torch.ones(dim))
  111. def forward(self, x):
  112. norm = torch.norm(x, dim=-1, keepdim=True) * self.scale
  113. return x / norm.clamp(min=self.eps) * self.g
  114. class Residual(nn.Module):
  115. def forward(self, x, residual):
  116. return x + residual
  117. class GRUGating(nn.Module):
  118. def __init__(self, dim):
  119. super().__init__()
  120. self.gru = nn.GRUCell(dim, dim)
  121. def forward(self, x, residual):
  122. gated_output = self.gru(
  123. rearrange(x, 'b n d -> (b n) d'),
  124. rearrange(residual, 'b n d -> (b n) d')
  125. )
  126. return gated_output.reshape_as(x)
  127. # feedforward
  128. class GEGLU(nn.Module):
  129. def __init__(self, dim_in, dim_out):
  130. super().__init__()
  131. self.proj = nn.Linear(dim_in, dim_out * 2)
  132. def forward(self, x):
  133. x, gate = self.proj(x).chunk(2, dim=-1)
  134. return x * F.gelu(gate)
  135. class FeedForward(nn.Module):
  136. def __init__(self, dim, dim_out=None, mult=4, glu=False, dropout=0.):
  137. super().__init__()
  138. inner_dim = int(dim * mult)
  139. dim_out = default(dim_out, dim)
  140. project_in = nn.Sequential(
  141. nn.Linear(dim, inner_dim),
  142. nn.GELU()
  143. ) if not glu else GEGLU(dim, inner_dim)
  144. self.net = nn.Sequential(
  145. project_in,
  146. nn.Dropout(dropout),
  147. nn.Linear(inner_dim, dim_out)
  148. )
  149. def forward(self, x):
  150. return self.net(x)
  151. # attention.
  152. class Attention(nn.Module):
  153. def __init__(
  154. self,
  155. dim,
  156. dim_head=DEFAULT_DIM_HEAD,
  157. heads=8,
  158. causal=False,
  159. mask=None,
  160. talking_heads=False,
  161. sparse_topk=None,
  162. use_entmax15=False,
  163. num_mem_kv=0,
  164. dropout=0.,
  165. on_attn=False
  166. ):
  167. super().__init__()
  168. if use_entmax15:
  169. raise NotImplementedError("Check out entmax activation instead of softmax activation!")
  170. self.scale = dim_head ** -0.5
  171. self.heads = heads
  172. self.causal = causal
  173. self.mask = mask
  174. inner_dim = dim_head * heads
  175. self.to_q = nn.Linear(dim, inner_dim, bias=False)
  176. self.to_k = nn.Linear(dim, inner_dim, bias=False)
  177. self.to_v = nn.Linear(dim, inner_dim, bias=False)
  178. self.dropout = nn.Dropout(dropout)
  179. # talking heads
  180. self.talking_heads = talking_heads
  181. if talking_heads:
  182. self.pre_softmax_proj = nn.Parameter(torch.randn(heads, heads))
  183. self.post_softmax_proj = nn.Parameter(torch.randn(heads, heads))
  184. # explicit topk sparse attention
  185. self.sparse_topk = sparse_topk
  186. # entmax
  187. #self.attn_fn = entmax15 if use_entmax15 else F.softmax
  188. self.attn_fn = F.softmax
  189. # add memory key / values
  190. self.num_mem_kv = num_mem_kv
  191. if num_mem_kv > 0:
  192. self.mem_k = nn.Parameter(torch.randn(heads, num_mem_kv, dim_head))
  193. self.mem_v = nn.Parameter(torch.randn(heads, num_mem_kv, dim_head))
  194. # attention on attention
  195. self.attn_on_attn = on_attn
  196. self.to_out = nn.Sequential(nn.Linear(inner_dim, dim * 2), nn.GLU()) if on_attn else nn.Linear(inner_dim, dim)
  197. def forward(
  198. self,
  199. x,
  200. context=None,
  201. mask=None,
  202. context_mask=None,
  203. rel_pos=None,
  204. sinusoidal_emb=None,
  205. prev_attn=None,
  206. mem=None
  207. ):
  208. b, n, _, h, talking_heads, device = *x.shape, self.heads, self.talking_heads, x.device
  209. kv_input = default(context, x)
  210. q_input = x
  211. k_input = kv_input
  212. v_input = kv_input
  213. if exists(mem):
  214. k_input = torch.cat((mem, k_input), dim=-2)
  215. v_input = torch.cat((mem, v_input), dim=-2)
  216. if exists(sinusoidal_emb):
  217. # in shortformer, the query would start at a position offset depending on the past cached memory
  218. offset = k_input.shape[-2] - q_input.shape[-2]
  219. q_input = q_input + sinusoidal_emb(q_input, offset=offset)
  220. k_input = k_input + sinusoidal_emb(k_input)
  221. q = self.to_q(q_input)
  222. k = self.to_k(k_input)
  223. v = self.to_v(v_input)
  224. q, k, v = map(lambda t: rearrange(t, 'b n (h d) -> b h n d', h=h), (q, k, v))
  225. input_mask = None
  226. if any(map(exists, (mask, context_mask))):
  227. q_mask = default(mask, lambda: torch.ones((b, n), device=device).bool())
  228. k_mask = q_mask if not exists(context) else context_mask
  229. k_mask = default(k_mask, lambda: torch.ones((b, k.shape[-2]), device=device).bool())
  230. q_mask = rearrange(q_mask, 'b i -> b () i ()')
  231. k_mask = rearrange(k_mask, 'b j -> b () () j')
  232. input_mask = q_mask * k_mask
  233. if self.num_mem_kv > 0:
  234. mem_k, mem_v = map(lambda t: repeat(t, 'h n d -> b h n d', b=b), (self.mem_k, self.mem_v))
  235. k = torch.cat((mem_k, k), dim=-2)
  236. v = torch.cat((mem_v, v), dim=-2)
  237. if exists(input_mask):
  238. input_mask = F.pad(input_mask, (self.num_mem_kv, 0), value=True)
  239. dots = einsum('b h i d, b h j d -> b h i j', q, k) * self.scale
  240. mask_value = max_neg_value(dots)
  241. if exists(prev_attn):
  242. dots = dots + prev_attn
  243. pre_softmax_attn = dots
  244. if talking_heads:
  245. dots = einsum('b h i j, h k -> b k i j', dots, self.pre_softmax_proj).contiguous()
  246. if exists(rel_pos):
  247. dots = rel_pos(dots)
  248. if exists(input_mask):
  249. dots.masked_fill_(~input_mask, mask_value)
  250. del input_mask
  251. if self.causal:
  252. i, j = dots.shape[-2:]
  253. r = torch.arange(i, device=device)
  254. mask = rearrange(r, 'i -> () () i ()') < rearrange(r, 'j -> () () () j')
  255. mask = F.pad(mask, (j - i, 0), value=False)
  256. dots.masked_fill_(mask, mask_value)
  257. del mask
  258. if exists(self.sparse_topk) and self.sparse_topk < dots.shape[-1]:
  259. top, _ = dots.topk(self.sparse_topk, dim=-1)
  260. vk = top[..., -1].unsqueeze(-1).expand_as(dots)
  261. mask = dots < vk
  262. dots.masked_fill_(mask, mask_value)
  263. del mask
  264. attn = self.attn_fn(dots, dim=-1)
  265. post_softmax_attn = attn
  266. attn = self.dropout(attn)
  267. if talking_heads:
  268. attn = einsum('b h i j, h k -> b k i j', attn, self.post_softmax_proj).contiguous()
  269. out = einsum('b h i j, b h j d -> b h i d', attn, v)
  270. out = rearrange(out, 'b h n d -> b n (h d)')
  271. intermediates = Intermediates(
  272. pre_softmax_attn=pre_softmax_attn,
  273. post_softmax_attn=post_softmax_attn
  274. )
  275. return self.to_out(out), intermediates
  276. class AttentionLayers(nn.Module):
  277. def __init__(
  278. self,
  279. dim,
  280. depth,
  281. heads=8,
  282. causal=False,
  283. cross_attend=False,
  284. only_cross=False,
  285. use_scalenorm=False,
  286. use_rmsnorm=False,
  287. use_rezero=False,
  288. rel_pos_num_buckets=32,
  289. rel_pos_max_distance=128,
  290. position_infused_attn=False,
  291. custom_layers=None,
  292. sandwich_coef=None,
  293. par_ratio=None,
  294. residual_attn=False,
  295. cross_residual_attn=False,
  296. macaron=False,
  297. pre_norm=True,
  298. gate_residual=False,
  299. **kwargs
  300. ):
  301. super().__init__()
  302. ff_kwargs, kwargs = groupby_prefix_and_trim('ff_', kwargs)
  303. attn_kwargs, _ = groupby_prefix_and_trim('attn_', kwargs)
  304. dim_head = attn_kwargs.get('dim_head', DEFAULT_DIM_HEAD)
  305. self.dim = dim
  306. self.depth = depth
  307. self.layers = nn.ModuleList([])
  308. self.has_pos_emb = position_infused_attn
  309. self.pia_pos_emb = FixedPositionalEmbedding(dim) if position_infused_attn else None
  310. self.rotary_pos_emb = always(None)
  311. assert rel_pos_num_buckets <= rel_pos_max_distance, 'number of relative position buckets must be less than the relative position max distance'
  312. self.rel_pos = None
  313. self.pre_norm = pre_norm
  314. self.residual_attn = residual_attn
  315. self.cross_residual_attn = cross_residual_attn
  316. norm_class = ScaleNorm if use_scalenorm else nn.LayerNorm
  317. norm_class = RMSNorm if use_rmsnorm else norm_class
  318. norm_fn = partial(norm_class, dim)
  319. norm_fn = nn.Identity if use_rezero else norm_fn
  320. branch_fn = Rezero if use_rezero else None
  321. if cross_attend and not only_cross:
  322. default_block = ('a', 'c', 'f')
  323. elif cross_attend and only_cross:
  324. default_block = ('c', 'f')
  325. else:
  326. default_block = ('a', 'f')
  327. if macaron:
  328. default_block = ('f',) + default_block
  329. if exists(custom_layers):
  330. layer_types = custom_layers
  331. elif exists(par_ratio):
  332. par_depth = depth * len(default_block)
  333. assert 1 < par_ratio <= par_depth, 'par ratio out of range'
  334. default_block = tuple(filter(not_equals('f'), default_block))
  335. par_attn = par_depth // par_ratio
  336. depth_cut = par_depth * 2 // 3 # 2 / 3 attention layer cutoff suggested by PAR paper
  337. par_width = (depth_cut + depth_cut // par_attn) // par_attn
  338. assert len(default_block) <= par_width, 'default block is too large for par_ratio'
  339. par_block = default_block + ('f',) * (par_width - len(default_block))
  340. par_head = par_block * par_attn
  341. layer_types = par_head + ('f',) * (par_depth - len(par_head))
  342. elif exists(sandwich_coef):
  343. assert sandwich_coef > 0 and sandwich_coef <= depth, 'sandwich coefficient should be less than the depth'
  344. layer_types = ('a',) * sandwich_coef + default_block * (depth - sandwich_coef) + ('f',) * sandwich_coef
  345. else:
  346. layer_types = default_block * depth
  347. self.layer_types = layer_types
  348. self.num_attn_layers = len(list(filter(equals('a'), layer_types)))
  349. for layer_type in self.layer_types:
  350. if layer_type == 'a':
  351. layer = Attention(dim, heads=heads, causal=causal, **attn_kwargs)
  352. elif layer_type == 'c':
  353. layer = Attention(dim, heads=heads, **attn_kwargs)
  354. elif layer_type == 'f':
  355. layer = FeedForward(dim, **ff_kwargs)
  356. layer = layer if not macaron else Scale(0.5, layer)
  357. else:
  358. raise Exception(f'invalid layer type {layer_type}')
  359. if isinstance(layer, Attention) and exists(branch_fn):
  360. layer = branch_fn(layer)
  361. if gate_residual:
  362. residual_fn = GRUGating(dim)
  363. else:
  364. residual_fn = Residual()
  365. self.layers.append(nn.ModuleList([
  366. norm_fn(),
  367. layer,
  368. residual_fn
  369. ]))
  370. def forward(
  371. self,
  372. x,
  373. context=None,
  374. mask=None,
  375. context_mask=None,
  376. mems=None,
  377. return_hiddens=False
  378. ):
  379. hiddens = []
  380. intermediates = []
  381. prev_attn = None
  382. prev_cross_attn = None
  383. mems = mems.copy() if exists(mems) else [None] * self.num_attn_layers
  384. for ind, (layer_type, (norm, block, residual_fn)) in enumerate(zip(self.layer_types, self.layers)):
  385. is_last = ind == (len(self.layers) - 1)
  386. if layer_type == 'a':
  387. hiddens.append(x)
  388. layer_mem = mems.pop(0)
  389. residual = x
  390. if self.pre_norm:
  391. x = norm(x)
  392. if layer_type == 'a':
  393. out, inter = block(x, mask=mask, sinusoidal_emb=self.pia_pos_emb, rel_pos=self.rel_pos,
  394. prev_attn=prev_attn, mem=layer_mem)
  395. elif layer_type == 'c':
  396. out, inter = block(x, context=context, mask=mask, context_mask=context_mask, prev_attn=prev_cross_attn)
  397. elif layer_type == 'f':
  398. out = block(x)
  399. x = residual_fn(out, residual)
  400. if layer_type in ('a', 'c'):
  401. intermediates.append(inter)
  402. if layer_type == 'a' and self.residual_attn:
  403. prev_attn = inter.pre_softmax_attn
  404. elif layer_type == 'c' and self.cross_residual_attn:
  405. prev_cross_attn = inter.pre_softmax_attn
  406. if not self.pre_norm and not is_last:
  407. x = norm(x)
  408. if return_hiddens:
  409. intermediates = LayerIntermediates(
  410. hiddens=hiddens,
  411. attn_intermediates=intermediates
  412. )
  413. return x, intermediates
  414. return x
  415. class Encoder(AttentionLayers):
  416. def __init__(self, **kwargs):
  417. assert 'causal' not in kwargs, 'cannot set causality on encoder'
  418. super().__init__(causal=False, **kwargs)
  419. class TransformerWrapper(nn.Module):
  420. def __init__(
  421. self,
  422. *,
  423. num_tokens,
  424. max_seq_len,
  425. attn_layers,
  426. emb_dim=None,
  427. max_mem_len=0.,
  428. emb_dropout=0.,
  429. num_memory_tokens=None,
  430. tie_embedding=False,
  431. use_pos_emb=True
  432. ):
  433. super().__init__()
  434. assert isinstance(attn_layers, AttentionLayers), 'attention layers must be one of Encoder or Decoder'
  435. dim = attn_layers.dim
  436. emb_dim = default(emb_dim, dim)
  437. self.max_seq_len = max_seq_len
  438. self.max_mem_len = max_mem_len
  439. self.num_tokens = num_tokens
  440. self.token_emb = nn.Embedding(num_tokens, emb_dim)
  441. self.pos_emb = AbsolutePositionalEmbedding(emb_dim, max_seq_len) if (
  442. use_pos_emb and not attn_layers.has_pos_emb) else always(0)
  443. self.emb_dropout = nn.Dropout(emb_dropout)
  444. self.project_emb = nn.Linear(emb_dim, dim) if emb_dim != dim else nn.Identity()
  445. self.attn_layers = attn_layers
  446. self.norm = nn.LayerNorm(dim)
  447. self.init_()
  448. self.to_logits = nn.Linear(dim, num_tokens) if not tie_embedding else lambda t: t @ self.token_emb.weight.t()
  449. # memory tokens (like [cls]) from Memory Transformers paper
  450. num_memory_tokens = default(num_memory_tokens, 0)
  451. self.num_memory_tokens = num_memory_tokens
  452. if num_memory_tokens > 0:
  453. self.memory_tokens = nn.Parameter(torch.randn(num_memory_tokens, dim))
  454. # let funnel encoder know number of memory tokens, if specified
  455. if hasattr(attn_layers, 'num_memory_tokens'):
  456. attn_layers.num_memory_tokens = num_memory_tokens
  457. def init_(self):
  458. nn.init.normal_(self.token_emb.weight, std=0.02)
  459. def forward(
  460. self,
  461. x,
  462. return_embeddings=False,
  463. mask=None,
  464. return_mems=False,
  465. return_attn=False,
  466. mems=None,
  467. **kwargs
  468. ):
  469. b, n, device, num_mem = *x.shape, x.device, self.num_memory_tokens
  470. x = self.token_emb(x)
  471. x += self.pos_emb(x)
  472. x = self.emb_dropout(x)
  473. x = self.project_emb(x)
  474. if num_mem > 0:
  475. mem = repeat(self.memory_tokens, 'n d -> b n d', b=b)
  476. x = torch.cat((mem, x), dim=1)
  477. # auto-handle masking after appending memory tokens
  478. if exists(mask):
  479. mask = F.pad(mask, (num_mem, 0), value=True)
  480. x, intermediates = self.attn_layers(x, mask=mask, mems=mems, return_hiddens=True, **kwargs)
  481. x = self.norm(x)
  482. mem, x = x[:, :num_mem], x[:, num_mem:]
  483. out = self.to_logits(x) if not return_embeddings else x
  484. if return_mems:
  485. hiddens = intermediates.hiddens
  486. new_mems = list(map(lambda pair: torch.cat(pair, dim=-2), zip(mems, hiddens))) if exists(mems) else hiddens
  487. new_mems = list(map(lambda t: t[..., -self.max_mem_len:, :].detach(), new_mems))
  488. return out, new_mems
  489. if return_attn:
  490. attn_maps = list(map(lambda t: t.post_softmax_attn, intermediates.attn_intermediates))
  491. return out, attn_maps
  492. return out