Cortex-0 / src /model /block.py
Frankenstein-Labs's picture
feat(vision): Phase 4 — encodeur image ViT
6857ec0 verified
Raw History Blame Contribute Delete
1.49 kB
"""Bloc Transformer pre-norm avec résidus — écrit à la main.
Forme pre-norm (justifiée dans docs/architecture.md §2.2) :
x = x + Attention(LayerNorm(x))
x = x + FeedForward(LayerNorm(x))
La normalisation est appliquée *avant* chaque sous-couche. Le gradient traverse
la connexion résiduelle sans être multiplié par une norme, ce qui stabilise
l'entraînement des modèles profonds.
"""
from __future__ import annotations
import torch.nn as nn
from src.model.attention import MultiHeadSelfAttention
from src.model.ffn import FeedForward
class TransformerBlock(nn.Module):
"""Un bloc = attention causale + FFN, chacun précédé d'une LayerNorm."""
def __init__(
self,
n_embd: int,
n_head: int,
dropout: float = 0.0,
bias: bool = False,
ffn_mult: int = 4,
rope_theta: float = 10000.0,
use_rope: bool = True,
causal: bool = True,
):
super().__init__()
self.ln_1 = nn.LayerNorm(n_embd, bias=bias)
self.attn = MultiHeadSelfAttention(
n_embd, n_head, dropout=dropout, bias=bias, rope_theta=rope_theta,
use_rope=use_rope, causal=causal,
)
self.ln_2 = nn.LayerNorm(n_embd, bias=bias)
self.ffn = FeedForward(n_embd, mult=ffn_mult, dropout=dropout, bias=bias)
def forward(self, x, cos=None, sin=None):
x = x + self.attn(self.ln_1(x), cos, sin)
x = x + self.ffn(self.ln_2(x))
return x