保存BERT模型遇AttributeError:无法序列化本地对象的解决方法
解决TensorFlow加载SavedModel后无法用Pickle序列化的问题
错误原因
你通过tf.saved_model.load()加载的SavedModel对象,内部包含TensorFlow生成的本地类实例(即报错信息中的Loader._recreate_base_user_object.<locals>._UserObject),这类对象不支持Python的Pickle序列化机制,因此触发AttributeError。
解决方案
方案1:直接使用TensorFlow原生SavedModel格式(推荐)
完全不需要将加载后的模型转存为Pickle,TensorFlow的SavedModel格式本身就是为模型持久化设计的,直接用以下方式即可完成保存和加载:
# 保存模型 tf.saved_model.save(bert_tf, 'my_model3') # 后续加载模型(直接使用,无需Pickle) loaded_model = tf.saved_model.load('my_model3')
方案2:若必须使用Pickle序列化(特殊场景)
如果需要将模型相关数据和其他Pickle序列化对象整合,可以拆分模型结构和权重分别处理:
# 1. 保存模型结构为JSON字符串 model_json = bert_tf.to_json() # 2. 保存模型权重 bert_tf.save_weights('bert_weights.h5') # 3. 将结构和权重路径打包后Pickle序列化 import pickle with open('model_pickle.pkl', 'wb') as f: pickle.dump({ 'model_json': model_json, 'weights_path': 'bert_weights.h5' }, f) # ---------------------- # 加载时的代码 # ---------------------- with open('model_pickle.pkl', 'rb') as f: saved_data = pickle.load(f) from tensorflow.keras.models import model_from_json # 重建模型结构 loaded_model = model_from_json(saved_data['model_json']) # 加载权重 loaded_model.load_weights(saved_data['weights_path'])
补充:关于之前model.save()出错的问题
如果之前调用model.save()失败,大概率是因为BERT模型包含自定义层或TF Hub组件,可尝试指定保存格式为HDF5:
bert_tf.save('bert_model.h5', save_format='h5')
加载时直接用keras.models.load_model('bert_model.h5')即可。
内容的提问来源于stack exchange,提问作者Sid R.
相关产品推荐
相关产品推荐

