bojone / bert4keras

keras implement of transformers for humans
https://kexue.fm/archives/6915
Apache License 2.0
5.37k stars 927 forks source link

如何加载google原版bert代码finetune后的权重 #423

Open geolvr opened 2 years ago

geolvr commented 2 years ago

提问时请尽可能提供如下信息:

基本信息

核心代码

config_path = '../chinese_L-12_H-768_A-12/bert_config.json'
checkpoint_path = '..chinese_L-12_H-768_A-12/bert_model.ckpt'
dict_path = '../chinese_L-12_H-768_A-12/vocab.txt'
......
# 加载预训练模型
bert = build_transformer_model(
    config_path=config_path,
    checkpoint_path=checkpoint_path,  
    model=model_name,
    return_keras_model=False,
    # hierarchical_position=True,
)
output = Lambda(lambda x: x[:, 0], name='CLS-token')(bert.model.output)
output = Dense(
    units=num_classes,
    activation='softmax',
    kernel_initializer=bert.initializer)(output)
model = keras.models.Model(bert.model.input, output)

文本分类任务,借鉴了example中的例子做模型定义,如上代码。现在想加载用谷歌原版bert代码finetune出来的权重(ckpt形式),并用bert4keras这套代码来推理。如果我用bert.load_weights_from_checkpoints, 则最后一个dense层的权重加载不进来。因为如代码所示,dense层不属于bert的一部分,model的定义是bert + Lambda层 + Dense层。而keras的Model又没有直接加载ckpt权重的功能。如果直接在“checkpoint_path=”处指定训练好的ckpt权重,也是一样的问题。所以应该怎么做呢?看了几个相关issue还是没搞明白,请指点。

xv44586 commented 2 years ago

model.save_weights(xx)

load

model.load_weights(xx)

geolvr commented 2 years ago

model.save_weights(xx)

load

model.load_weights(xx) 是要加载别人用谷歌官方bert代码(tensorflow)训练好的ckpt格式权重。

xv44586 commented 2 years ago

model.save_weights(xx)

load

model.load_weights(xx) 是要加载别人用谷歌官方bert代码(tensorflow)训练好的ckpt格式权重。

build_transformer_model(checkpoint_path=xxx,...) 这里已经load 了pre-train bert ckpt,你现在已经加了自己的dense 层并进行了fine-tune,此时你只需要把你自己训练的这个model 存下来,推理的时候把自己的模型load 进来

ps: 推理阶段load google的ckpt 干嘛?你已经fine-tune了,不load自己的load他的干嘛?

geolvr commented 2 years ago

model.save_weights(xx)

load

model.load_weights(xx) 是要加载别人用谷歌官方bert代码(tensorflow)训练好的ckpt格式权重。

build_transformer_model(checkpoint_path=xxx,...) 这里已经load 了pre-train bert ckpt,你现在已经加了自己的dense 层并进行了fine-tune,此时你只需要把你自己训练的这个model 存下来,推理的时候把自己的模型load 进来

ps: 推理阶段load google的ckpt 干嘛?你已经fine-tune了,不load自己的load他的干嘛?

出于某些原因,finetune是用google官方的代码进行的,我用bert4keras只是拿来推理,这个条件是定死的,就是这么个场景。其实就只是想问,在这个死条件下,有没有好办法能把google funetune出的权重加载到bert4keras这套体系下。

xv44586 commented 2 years ago
  1. 修改 apply_final_layers,构建与你用google 代码finetune一样的计算图(也就是加一个dence 层);
  2. 修改variable_mapping,增加对应layer 与weights的对应关系(dence 层对应哪个weights)