Senryu / tiny_gdn /nn_common.py
kerzgrr's picture
Upload Senryu (apo_zero apo-v2 EMA @ step 704, from SFT step 12800)
d5df530 verified
Raw History Blame Contribute Delete
3.48 kB
from __future__ import annotations
import torch
import torch.nn.functional as F
from torch import nn
from torch.nn.attention import SDPBackend
try:
from fla.modules.layernorm import rms_norm as fused_rms_norm
except ImportError:
fused_rms_norm = None
class RMSNorm(nn.Module):
"""Zero-centered RMSNorm as used by Qwen3-Next.
On CUDA this runs FLA's single-pass Triton kernel with the ``1 + weight``
scale kept in FP32, which matches the eager FP32 math to rounding.
"""
def __init__(self, hidden_size: int, eps: float) -> None:
super().__init__()
self.weight = nn.Parameter(torch.zeros(hidden_size))
self.eps = eps
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
scale = 1.0 + self.weight.float()
if fused_rms_norm is not None and hidden_states.is_cuda:
return fused_rms_norm(hidden_states, scale, None, eps=self.eps)
input_dtype = hidden_states.dtype
normalized = hidden_states.float()
normalized = normalized * torch.rsqrt(
normalized.square().mean(dim=-1, keepdim=True) + self.eps
)
return (normalized * scale).to(dtype=input_dtype)
def linear_cross_entropy_reference(
states: torch.Tensor,
weight: torch.Tensor,
targets: torch.Tensor,
*,
z_loss_coefficient: float = 0.0,
ignore_index: int = -100,
) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
"""Eager ``(objective, cross_entropy, z_loss)`` over materialized logits."""
logits = F.linear(states, weight)
cross_entropy = F.cross_entropy(logits, targets, ignore_index=ignore_index)
reduced_dtype = torch.promote_types(logits.dtype, torch.float32)
if z_loss_coefficient > 0.0:
# Keep logits in their training dtype for logsumexp. Casting the full
# [tokens, vocab] tensor to fp32 materializes it again in the autograd
# graph; upcast only the reduced [tokens] partition.
log_partition = torch.logsumexp(logits, dim=-1).to(reduced_dtype)
z_loss = log_partition.square()[targets.ne(ignore_index)].mean()
else:
z_loss = cross_entropy.new_zeros((), dtype=reduced_dtype)
objective = cross_entropy + z_loss_coefficient * z_loss
return objective, cross_entropy.detach(), z_loss.detach()
def linear_token_logprobs_reference(
states: torch.Tensor,
weight: torch.Tensor,
targets: torch.Tensor,
*,
ignore_index: int = -100,
) -> torch.Tensor:
"""Eager fp32 ``log_softmax(states @ weight.T)[row, target]``; ignored rows are 0."""
valid = targets.ne(ignore_index)
logprobs = F.linear(states, weight).float().log_softmax(dim=-1)
picked = logprobs.gather(1, targets.masked_fill(~valid, 0)[:, None]).squeeze(1)
return picked.masked_fill(~valid, 0.0)
def softcap(values: torch.Tensor, cap: float) -> torch.Tensor:
return cap * torch.tanh(values / cap)
def situ_glu_reference(gate_up: torch.Tensor, gate_cap: float, up_cap: float) -> torch.Tensor:
"""``softcap(gate) * sigmoid(gate) * softcap(up)`` over ``[..., gate | up]``."""
gate, up = gate_up.chunk(2, dim=-1)
return softcap(gate, gate_cap) * torch.sigmoid(gate) * softcap(up, up_cap)
def attention_sdpa_backends(device: torch.device) -> list[SDPBackend]:
if device.type != "cuda":
return [SDPBackend.MATH]
return [
SDPBackend.CUDNN_ATTENTION,
SDPBackend.FLASH_ATTENTION,
SDPBackend.EFFICIENT_ATTENTION,
]