|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| from typing import Callable, Optional
|
| from diffusers.models.normalization import RMSNorm
|
| from torch import nn
|
| import torch
|
| import torch.nn.functional as F
|
| import numbers
|
| from torch.nn.parameter import Parameter
|
| from torch.nn import init
|
|
|
|
|
| norm_layer_type = Callable[[int, float, bool], nn.Module]
|
|
|
|
|
| class CustomLayerNorm(nn.Module):
|
| """
|
| Custom LayerNorm implementation to replace Apex FusedLayerNorm
|
| """
|
| def __init__(self, normalized_shape, eps=1e-5, elementwise_affine=True):
|
| super(CustomLayerNorm, self).__init__()
|
|
|
| if isinstance(normalized_shape, numbers.Integral):
|
| normalized_shape = (normalized_shape,)
|
| self.normalized_shape = torch.Size(normalized_shape)
|
| self.eps = eps
|
| self.elementwise_affine = elementwise_affine
|
|
|
| if self.elementwise_affine:
|
| self.weight = Parameter(torch.Tensor(*normalized_shape))
|
| self.bias = Parameter(torch.Tensor(*normalized_shape))
|
| else:
|
| self.register_parameter('weight', None)
|
| self.register_parameter('bias', None)
|
| self.reset_parameters()
|
|
|
| def reset_parameters(self):
|
| if self.elementwise_affine:
|
| init.ones_(self.weight)
|
| init.zeros_(self.bias)
|
|
|
| def forward(self, input):
|
| return F.layer_norm(
|
| input, self.normalized_shape, self.weight, self.bias, self.eps)
|
|
|
|
|
| class CustomRMSNorm(nn.Module):
|
| """
|
| Custom RMSNorm implementation to replace Apex FusedRMSNorm
|
| """
|
| def __init__(self, normalized_shape, eps=1e-5, elementwise_affine=True):
|
| super(CustomRMSNorm, self).__init__()
|
|
|
| if isinstance(normalized_shape, numbers.Integral):
|
| normalized_shape = (normalized_shape,)
|
| self.normalized_shape = torch.Size(normalized_shape)
|
| self.eps = eps
|
| self.elementwise_affine = elementwise_affine
|
|
|
| if self.elementwise_affine:
|
| self.weight = Parameter(torch.ones(*normalized_shape))
|
| else:
|
| self.register_parameter('weight', None)
|
|
|
| def forward(self, input):
|
|
|
| dims = tuple(range(-len(self.normalized_shape), 0))
|
|
|
|
|
| variance = input.pow(2).mean(dim=dims, keepdim=True)
|
| rms = torch.sqrt(variance + self.eps)
|
|
|
|
|
| normalized = input / rms
|
|
|
| if self.elementwise_affine:
|
|
|
| if hasattr(torch, 'float8_e4m3fn'):
|
| fp8_types = (torch.float8_e4m3fn, torch.float8_e5m2)
|
| if self.weight.dtype in fp8_types:
|
|
|
| weight = self.weight.to(input.dtype)
|
| return normalized * weight
|
|
|
| return normalized * self.weight
|
| return normalized
|
|
|
|
|
| def get_norm_layer(norm_type: Optional[str]) -> norm_layer_type:
|
|
|
| def _norm_layer(dim: int, eps: float, elementwise_affine: bool):
|
| if norm_type is None:
|
| return nn.Identity()
|
|
|
| if norm_type == "layer":
|
| return nn.LayerNorm(
|
| normalized_shape=dim,
|
| eps=eps,
|
| elementwise_affine=elementwise_affine,
|
| )
|
|
|
| if norm_type == "rms":
|
| return RMSNorm(
|
| dim=dim,
|
| eps=eps,
|
| elementwise_affine=elementwise_affine,
|
| )
|
|
|
| if norm_type == "fusedln":
|
|
|
| return CustomLayerNorm(
|
| normalized_shape=dim,
|
| elementwise_affine=elementwise_affine,
|
| eps=eps,
|
| )
|
|
|
| if norm_type == "fusedrms":
|
|
|
| return CustomRMSNorm(
|
| normalized_shape=dim,
|
| elementwise_affine=elementwise_affine,
|
| eps=eps,
|
| )
|
|
|
| raise NotImplementedError(f"{norm_type} is not supported")
|
|
|
| return _norm_layer |