Feature Extraction
Transformers
Safetensors
cue
user-simulation
dialogue
persona
custom_code
cue / decoder_flamingo.py
AnjaliRuban's picture
Upload folder using huggingface_hub
d9d4242 verified
Raw History Blame Contribute Delete
2.02 kB
"""Flamingo-style GATED XATTN-DENSE residual blocks (Alayrac et al., 2022)."""
from __future__ import annotations
import torch
import torch.nn as nn
class GatedXAttnDense(nn.Module):
"""Cross-attend LM hidden states to persona memory, then gated dense FFN.
Gates are learnable scalars initialized to 0 so tanh(alpha)=0 at start.
Block math runs in fp32: bf16 MHA/LayerNorm is unstable, and ``0 * nan``
would still poison the residual when gates are zero.
"""
def __init__(
self,
hidden_dim: int,
num_heads: int = 8,
ff_mult: int = 4,
dropout: float = 0.0,
) -> None:
super().__init__()
self.ln_xattn = nn.LayerNorm(hidden_dim)
self.xattn = nn.MultiheadAttention(
embed_dim=hidden_dim,
num_heads=num_heads,
dropout=dropout,
batch_first=True,
)
self.alpha_xattn = nn.Parameter(torch.zeros(1))
self.ln_dense = nn.LayerNorm(hidden_dim)
self.dense = nn.Sequential(
nn.Linear(hidden_dim, hidden_dim * ff_mult),
nn.GELU(),
nn.Linear(hidden_dim * ff_mult, hidden_dim),
)
self.alpha_dense = nn.Parameter(torch.zeros(1))
def forward(self, hidden: torch.Tensor, persona_tokens: torch.Tensor) -> torch.Tensor:
"""
hidden: [B, T, H]
persona_tokens: [B, M, H]
"""
orig_dtype = hidden.dtype
h = hidden.float()
kv = persona_tokens.float()
attended, _ = self.xattn(self.ln_xattn(h), kv, kv)
# Sanitize before gating: IEEE 0*inf/nan would still poison y = x + 0*a.
attended = torch.nan_to_num(attended, nan=0.0, posinf=0.0, neginf=0.0)
dense_out = torch.nan_to_num(
self.dense(self.ln_dense(h)), nan=0.0, posinf=0.0, neginf=0.0
)
h = h + torch.tanh(self.alpha_xattn).float() * attended
h = h + torch.tanh(self.alpha_dense).float() * dense_out
return h.to(dtype=orig_dtype)