为何替换GPT-2的lm_head后参数量远超HuggingFace实现?
问题原因解析
核心原因是HuggingFace实现的GPT2LMHeadModel默认共享词嵌入层(transformer.wte)和语言模型头(lm_head)的权重,而你替换后的新Linear层是独立的,没有复用原有参数,导致参数量重复计算。
具体细节:
- 原实现中,
lm_head的权重直接复用了transformer.wte的权重,所以计算参数量时,这部分参数只算一次,不会重复统计。你可以通过以下代码验证:print(standard_gpt2.lm_head.weight is standard_gpt2.transformer.wte.weight) # 输出:True - 当你用
nn.Sequential包裹新的nn.Linear替换lm_head时,这个新Linear层会创建一组全新的独立参数(768*50257=38.6M),加上原模型的124.4M,总参数量就变成了163.0M,和你得到的结果完全匹配。
如何正确替换且保持参数量不变:
如果你需要用nn.Sequential包裹但不想增加参数量,可以手动让新Linear层复用原词嵌入的权重:
import torch.nn as nn # 创建Sequential层,复用原wte的权重 standard_gpt2.lm_head = nn.Sequential( nn.Linear(in_features=768, out_features=50257, bias=False) ) # 将新Linear的权重指向原wte的权重 standard_gpt2.lm_head[0].weight = standard_gpt2.transformer.wte.weight # 重新计算参数量 standard_gpt2_model_size = sum(t.numel() for t in standard_gpt2.parameters()) print(f"GPT-2 size: {standard_gpt2_model_size/1000**2:.1f}M parameters") # 输出:GPT-2 size: 124.4M parameters
内容的提问来源于stack exchange,提问作者Penguin
相关产品推荐
相关产品推荐

