RMSNorm原理详解

可参考文章:(27 封私信) 为什么最新的大模型普遍用RMSNorm? - 知乎

背景和动机

深度学习网络训练中,归一化Normalization 大大提升了训练稳定性和收敛速度,例如LayerNorm 和BatchNrom。

在Transformer中,使用的是LayerNorm对单个样本的所有特征维度做均值和方差归一化。

但是在LayerNorm计算中,包含均值标准差的计算(涉及到平方、开方),且还有两个参数(scalebias)进行仿射变换。

RMSNorm是一种轻量的归一化方案,最终目的是保持归一化效果的同时,减少计算开销和参数量。

Transformer内容详解(通透版)-CSDN博客

原理

假设输入向量为x=[x1,x2,...,xd](这里指网络某一层单个样本的特征维度)

1. 计算均方根RMS:

RMS(x) = \sqrt{\frac{1}{d}\sum_{i-1}^{d}{x_i}^2}

2. 归一化操作:用RMS代替LayerNorm中的均值和标准差进行归一化

\hat{x} = \frac{x}{RMS(x)+\epsilon }

\epsilon是一个很小的数,防止除0。

3. 缩放scale

y_i = g_i \cdot \hat{x_i}

通常没有偏置项bias,因为去除均值后,偏置的作用减小。

为什么去掉均值?

作者实验证明,去除均值计算并不会显著损害模型性能,反而降低了计算开销。

从理论上解释,因为均值的作用主要是把分布中心化,但网络的非线性和后续层的偏置参数等,也能补偿这一点。

代码

import torch
import torch.nn as nn

class RMSNorm(nn.Module):
    def __init__(self, dim, eps=1e-8):
        """
        RMSNorm实现
        :param dim: 输入特征的维度大小
        :param eps: 防止除零的小常数
        """
        super().__init__()
        self.eps = eps
        self.scale = nn.Parameter(torch.ones(dim))  # 可训练的缩放参数g

    def forward(self, x):
        # x的形状通常是 [batch_size, ..., dim]
        # 计算均方根(RMS)
        rms = x.pow(2).mean(dim=-1, keepdim=True).sqrt()  # shape: [..., 1]
        x_normed = x / (rms + self.eps)                   # 归一化操作
        return self.scale * x_normed                       # 乘以缩放参数

# 测试示例
if __name__ == "__main__":
    x = torch.randn(2, 3, 4)  # 例如形状为(batch=2, seq=3, dim=4)
    rmsnorm = RMSNorm(dim=4)
    y = rmsnorm(x)
    print(y)

### RMSNorm归一化方法的基本原理和实现机制 RMSNorm(Root Mean Square Normalization)是一种归一化技术,旨在提升深度学习模型的训练速度和稳定性。与传统的 LayerNorm 和 BatchNorm 不同,RMSNorm 通过简化归一化过程,减少了计算开销并提高了模型的适应性。 #### 基本原理 RMSNorm 的核心思想是通过对输入数据的平方均值进行归一化,而不是像 LayerNorm 那样同时考虑均值和方差。具体来说,RMSNorm 只关注输入数据的均方根(RMS),即每个特征通道的平方均值的平方根。这样做的好处是可以避免计算均值带来的额外开销,从而提高计算效率。 对于一个输入张量 $ x $,其形状为 $ (N, C, H, W) $,其中 $ N $ 是 batch 大小,$ C $ 是通道数,$ H $ 和 $ W $ 分别是高度和宽度。RMSNorm 的归一化公式可以表示为: $$ \text{RMSNorm}(x) = \frac{x}{\sqrt{\frac{1}{C} \sum_{i=1}^{C} x_i^2 + \epsilon}} \cdot \gamma + \beta $$ 其中: - $ x_i $ 表示第 $ i $ 个通道的数据。 - $ \epsilon $ 是一个小的常数,用于防止除以零。 - $ \gamma $ 和 $ \beta $ 是可学习的缩放和偏移参数。 #### 实现机制 在实现上,RMSNorm 主要分为以下几个步骤: 1. **计算平方均值**:对于每个通道,计算其平方均值。这一步骤可以通过简单的数学运算实现。 2. **归一化**:使用平方均值对输入数据进行归一化,确保每个通道的数据具有相似的尺度。 3. **可学习参数的应用**:引入可学习的缩放参数 $ \gamma $ 和偏移参数 $ \beta $,以恢复模型的表达能力。这些参数在训练过程中通过梯度下降进行优化。 4. **应用到模型中**:将 RMSNorm 应用于神经网络的各个层中,通常是在激活函数之前或之后。 #### 示例代码 以下是一个简单的 Python 实现示例,展示了如何在 PyTorch 中实现 RMSNorm: ```python import torch import torch.nn as nn class RMSNorm(nn.Module): def __init__(self, dim, eps=1e-8): super().__init__() self.eps = eps self.gamma = nn.Parameter(torch.ones(dim)) self.beta = nn.Parameter(torch.zeros(dim)) def forward(self, x): # 计算平方均值 mean_square = (x ** 2).mean(dim=-1, keepdim=True) # 归一化 x_normalized = x / torch.sqrt(mean_square + self.eps) # 应用可学习参数 return self.gamma * x_normalized + self.beta # 使用示例 dim = 64 # 假设特征维度为64 rms_norm = RMSNorm(dim) input_tensor = torch.randn(32, dim) # 输入张量 output_tensor = rms_norm(input_tensor) ``` #### 优势与应用场景 RMSNorm 相比于传统的归一化方法,具有以下优势: - **计算效率高**:由于不需要计算均值,RMSNorm 的计算复杂度较低。 - **适用于动态计算图**:RMSNorm 更适合在动态计算图中使用,因为它不依赖于固定的 batch 大小。 - **支持大规模训练**:在大规模训练任务中,RMSNorm 能够更好地保持模型的稳定性和收敛速度。 RMSNorm 在诸如 Llama 等大模型中得到了广泛应用,特别是在需要高效训练和推理的场景下,表现出色。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小老大MUTA️

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值