model
model.eval()
pytorch中model.eval()会对哪些函数有影响?
答:将BN和dropout这些训练和测试时行为不同的层切换到test mode。
Dropout训练和推理时的差异
众所周知,dropout是训练的时候将某层的神经元输出以
为了保证测试时每次推理的一致性,肯定是不能再随机让神经失活了,那什么都不做,让所有神经元都按正常输出值原样输出可以嘛?
从训练和测试时的输出值尺度一致性来看,答案显然是否定的。设每个神经元原始输出的绝对值均值为
因此,带dropout的层,测试时的行为是让所有神经元都输出,但输出值要从原始的
当然,也可以在训练的时候就除以
torch官方使用的是这种实现:

BatchNorm测试时统计量怎么来
Batch Normalization训练时,使用的均值和方差统计量是从同batch数据的同一特征维度统计而来。
而测试时,为了保证每个测试点的预测输出不受batch内其他数据影响,肯定得采用固定的统计量,这个统计量从何而来呢?
直观的想法是再过一遍整个训练集,在整个训练集上估计均值和方差,但在数据多的时候,每次在测试之前都要过一遍整个训练集超级费时:
因此,我们需要一个近似的在训练时估计全局统计量分布的办法。这个统计量要满足两个要求:
- 尽量反映整个训练集的分布;
- 尽量使用模型训练结束或者即将结束时的权重来计算,以便和测试时行为一致。
考虑到这两个要求,是不是想起了SGD里的momentum?采用训练时指数滑动平均的方式就可以得到测试时用的统计量,参考torch的官方文档:

model.eval()影响大模型吗
我们已经厘清了model.eval()对dropout层和batch norm层的影响,那么model.eval()影响大模型吗这个问题就等价于:大模型用batch norm和dropout吗?
首先,大模型用的都是layer norm, batch norm显然是不存在的。那么大模型开dropout吗?
先明确一下dropout的位置,大多数transformer的实现(尤其是类gpt的decoder模型中)只在self-attention的softmax概率之后使用dropout,相应的失活概率
而在LLaMA、Mistral这些常见的开源大模型中,attention_dropout都被设为0,也就是实际上不使用dropout,model.eval()对这些不开dropout的大模型实际上没有影响。