HuggingFace多次加载预训练BERT模型权重不一致问题求助
解决重复加载BERT分类模型权重不一致的问题
这个问题的核心是BertForSequenceClassification的分类层(classifier)是随机初始化的,即便你设置了全局种子,第一次加载模型时会消耗当前的随机状态,导致第二次初始化分类层时使用了不同的随机序列,最终出现权重差异。
以下是几个可行的解决思路:
1. 每次加载模型前重置随机种子
在每次调用from_pretrained前,重新设置所有随机种子,确保每次初始化分类层时的随机状态完全一致:
def load_bert_model(MODEL, label2id, seed_val): # 每次加载前重置所有随机种子 random.seed(seed_val) np.random.seed(seed_val) torch.manual_seed(seed_val) torch.cuda.manual_seed_all(seed_val) return BertForSequenceClassification.from_pretrained( MODEL, num_labels=len(label2id), id2label={v:k for k,v in label2id.items()}, label2id=label2id, output_attentions=False, output_hidden_states=False ) # 两次加载都使用这个封装函数 model = load_bert_model(MODEL, label2id, seed_val) model.save_pretrained('./model1/') model = load_bert_model(MODEL, label2id, seed_val) model.save_pretrained('./model2/')
2. 预保存分类层权重,后续加载复用
第一次加载模型后,单独保存分类层的权重,后续加载模型时直接替换分类层参数,避免重复随机初始化:
# 首次加载并保存基础模型+分类层权重 model = BertForSequenceClassification.from_pretrained(MODEL, num_labels=len(label2id), id2label=id2label, label2id=label2id) model.save_pretrained('./base_model/') torch.save(model.classifier.state_dict(), './classifier_weights.pt') # 后续加载流程:先加载基础模型,再覆盖分类层权重 model = BertForSequenceClassification.from_pretrained('./base_model/') model.classifier.load_state_dict(torch.load('./classifier_weights.pt'))
3. 手动初始化分类层并固定种子
跳过from_pretrained的自动分类层初始化,手动加载BERT基础模型后,在固定种子的状态下初始化分类层:
from transformers import BertModel, BertForSequenceClassification def build_bert_classifier(MODEL, num_labels, seed_val): # 加载无分类层的基础BERT模型 bert_base = BertModel.from_pretrained(MODEL) # 固定种子后手动初始化分类层 torch.manual_seed(seed_val) classifier = torch.nn.Linear(bert_base.config.hidden_size, num_labels) # 组装成完整的分类模型 model = BertForSequenceClassification(bert_base.config) model.bert = bert_base model.classifier = classifier return model
通过以上任一方法,都能保证多次加载的模型权重完全一致,满足超参数调优时的确定性需求。
内容的提问来源于stack exchange,提问作者Elias
相关产品推荐
相关产品推荐

