NexusCoder / nexus /model /layers.py
AdminReal's picture
Import NexusCoder from github.com/mhieuhonda/NexusCoder
eca5751 verified
Raw
History Blame Contribute Delete
2.72 kB
"""
RMSNorm + SwiGLU layers v0.3
============================
- RMSNorm (Zhang & Sennrich, 2019) — unchanged
- SwiGLU — adds MLP-parallel variant (compute gate/up in parallel)
"""
from __future__ import annotations
import torch
import torch.nn as nn
import torch.nn.functional as F
class RMSNorm(nn.Module):
"""Root Mean Square LayerNorm (Zhang & Sennrich, 2019).
Hiệu quả hơn LayerNorm truyền thống, không có bias và không trừ mean.
"""
def __init__(self, hidden_size: int, eps: float = 1e-6):
super().__init__()
self.weight = nn.Parameter(torch.ones(hidden_size))
self.eps = eps
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
input_dtype = hidden_states.dtype
hidden_states = hidden_states.to(torch.float32)
variance = hidden_states.pow(2).mean(-1, keepdim=True)
hidden_states = hidden_states * torch.rsqrt(variance + self.eps)
return self.weight * hidden_states.to(input_dtype)
class SwiGLU(nn.Module):
"""SwiGLU activation: SiLU(gate(x)) * up(x).
v0.3: adds MLP-parallel variant — gate_proj and up_proj are computed
as a single concatenated matmul (faster on modern GPUs).
"""
def __init__(self, hidden_size: int, intermediate_size: int, parallel: bool = True):
super().__init__()
self.parallel = parallel
if parallel:
# Concatenated gate + up projection (mathematically identical, faster)
self.gate_up_proj = nn.Linear(
hidden_size, 2 * intermediate_size, bias=False,
)
self.gate_proj = None
self.up_proj = None
else:
self.gate_proj = nn.Linear(hidden_size, intermediate_size, bias=False)
self.up_proj = nn.Linear(hidden_size, intermediate_size, bias=False)
self.gate_up_proj = None
self.down_proj = nn.Linear(intermediate_size, hidden_size, bias=False)
self.intermediate_size = intermediate_size
def forward(self, x: torch.Tensor) -> torch.Tensor:
if self.parallel:
gate_up = self.gate_up_proj(x)
gate, up = gate_up[..., : self.intermediate_size], gate_up[..., self.intermediate_size :]
gate = F.silu(gate)
else:
gate = F.silu(self.gate_proj(x))
up = self.up_proj(x)
return self.down_proj(gate * up)
def _expand_token_ids_to_mask(token_ids: torch.Tensor, seq_len: int) -> torch.Tensor:
"""Helper: chuyển token ids thành attention mask."""
mask = torch.zeros(token_ids.shape[0], seq_len, device=token_ids.device)
for i, ids in enumerate(token_ids):
mask[i, : len(ids)] = 1
return mask