You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch LayerNorm推理阶段均值和标准差为何不固定?如何提取?

关于PyTorch LayerNorm输入还原的问题

我尝试从torch.LayerNorm的输出还原原始输入,原本以为LayerNorm在推理阶段的均值和标准差是固定的,打算提取这些参数完成输入还原。我成功提取出针对原输入的融合权重和偏置(和LayerNorm自身的weight、bias参数不同),用它能还原原输入,但将其应用到新输入张量时结果完全不符。我推测LayerNorm为新输入重新计算了均值和标准差,但疑惑为何推理阶段这些值不固定。

以下是我的代码及输出:

layer = layer().eval()
with torch.inference_mode():
    out = layer(input_data)

w = torch.zeros(len(out[0, :, 0]))
b = torch.zeros(len(out[0, :, 0]))

for i in range(len(out[0, :, 0])):
    w[i] = (input_data[0, i, 0] - input_data[0, i, 10]) / (out[0, i, 0] - out[0, i, 10])
    b[i] = (input_data[0, i, 0] * out[0, i, 10] - input_data[0, i, 10] * out[0, i, 0]) / (out[0, i, 10] - out[0, i, 0])

for i1 in range(len(input_remade[0, :, 0])):
    input_remade[0, i1, :] = out[0, i1, :] * w[i1] + b[i1]
print(torch.sum(input_remade - input_data))


input_data2 = torch.randn(1, 577, 768)
input_remade2 = torch.randn(1, 577, 768)
with torch.inference_mode():
    out2 = layer(input_data2)

for i1 in range(len(input_remade2[0, :, 0])):
    input_remade2[0, i1, :] = out2[0, i1, :] * w[i1] + b[i1]
print(torch.sum(input_remade2 - input_data2))

w1 = torch.zeros(len(out2[0, :, 0]))
b1 = torch.zeros(len(out2[0, :, 0]))

for i in range(len(out2[0, :, 0])):
    w1[i] = (input_data2[0, i, 0] - input_data2[0, i, 10]) / (out2[0, i, 0] - out2[0, i, 10])
    b1[i] = (input_data2[0, i, 0] * out2[0, i, 10] - input_data2[0, i, 10] * out2[0, i, 0]) / (out2[0, i, 10] - out2[0, i, 0])

for i1 in range(len(input_remade2[0, :, 0])):
    input_remade2[0, i1, :] = out2[0, i1, :] * w1[i1] + b1[i1]
print(torch.sum(input_remade2 - input_data2))

输出:

tensor(-0.0061)
tensor(1280.9966)
tensor(0.0014)

同时想请教:是否有方法从LayerNorm层提取固定的均值和标准差?


解答

核心结论:LayerNorm不存在固定的均值/标准差

LayerNorm和BatchNorm的核心区别在于:无论训练还是推理阶段,LayerNorm都会针对每个输入样本的指定归一化维度,实时计算均值和标准差,而非像BatchNorm那样在训练阶段统计全局滑动平均的均值/方差,推理时复用固定值。

这是LayerNorm的设计目标决定的——它是对单个样本内部的特征维度做归一化(比如NLP场景中对每个token的特征向量归一化),每个输入样本的特征分布不同,计算出的均值和标准差自然不同,不存在可以提前提取的固定全局参数。

你的代码为何只对原输入有效

你计算的w和b,本质是基于原输入的均值/方差,结合LayerNorm的weight($\gamma$)和bias($\beta$)推导的线性变换参数,仅适配原输入的分布。当输入换成input_data2时,其均值/方差已经改变,用原参数自然无法还原新输入;而重新计算w1和b1后能还原,正是因为这组参数匹配了新输入的实时均值/方差。

正确的输入还原方式

LayerNorm的正向计算逻辑为:
$$ out = \gamma * \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} + \beta $$
其中$\mu$是输入x在归一化维度上的均值,$\sigma^2$是方差,$\gamma$是LayerNorm的weight,$\beta$是bias,$\epsilon$是防止除零的小常数。

要从out还原x,必须使用对应输入的$\mu$和$\sigma^2$,公式为:
$$ x = \frac{(out - \beta)}{\gamma} * \sqrt{\sigma^2 + \epsilon} + \mu $$
这里的$\mu$和$\sigma^2$是当前输入的实时计算值,无法提前获取固定值。如果需要还原输入,你需要在计算LayerNorm输出的同时,同步记录该输入对应的均值和方差。

内容的提问来源于stack exchange,提问作者Hibama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 02:45:26