You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Kaggle下载TensorFlow版BERT模型后分词报错的解决求助

问题解决思路与代码修正

核心错误原因

你遇到的NotImplementedError是因为input_text = tf.keras.layers.Input(shape=(), dtype=tf.string)创建的是符号Keras张量——它只是计算图中的占位符,没有实际数据,无法用Python的for循环迭代遍历。而HuggingFace的BertTokenizer默认处理的是Python字符串列表,不能直接作用于符号张量。

分步解决方案

1. 修正分词逻辑(兼容TensorFlow符号张量)

用tf.py_function将分词操作包装成TensorFlow兼容的计算节点,即可在Keras模型中使用符号张量作为输入:

import tensorflow as tf
from transformers import BertTokenizer
import kagglehub
import keras
import os

# 下载模型
path = kagglehub.model_download("tensorflow/bert/tensorFlow2/en-wwm-uncased-l-24-h-1024-a-16")
print("Path to model files:", path)

# 初始化Tokenizer(用os.path.join保证跨平台路径兼容)
vocab_path = os.path.join(path, "assets", "vocab.txt")
encoder = BertTokenizer.from_pretrained(vocab_path)

# 定义兼容TensorFlow的分词函数
def tokenize_function(texts):
    # 将符号张量转为Python字符串列表
    texts = tf.make_ndarray(tf.make_tensor_proto(texts)).tolist()
    # 分词并返回Tensor格式结果
    encodings = encoder(texts, padding=True, truncation=True, return_tensors="tf")
    return encodings["input_ids"], encodings["attention_mask"], encodings["token_type_ids"]

# 构建模型输入
input_text = tf.keras.layers.Input(shape=(), dtype=tf.string, name="input_text")
# 用tf.py_function包装分词操作
input_ids, attention_mask, token_type_ids = tf.py_function(
    func=tokenize_function,
    inp=[input_text],
    Tout=[tf.int32, tf.int32, tf.int32]
)
# 为输出张量设置明确形状(Keras需要形状信息构建模型)
input_ids.set_shape((None, encoder.model_max_length))
attention_mask.set_shape((None, encoder.model_max_length))
token_type_ids.set_shape((None, encoder.model_max_length))

# 加载BERT模型
model = keras.layers.TFSMLayer(path, call_endpoint='serving_default')
# 调用模型获取输出
bert_output = model({"input_ids": input_ids, "attention_mask": attention_mask, "token_type_ids": token_type_ids})

# 测试模型(传入实际文本数据)
test_text = tf.convert_to_tensor(["Hello, this is a test sentence."])
output = bert_output(test_text)
print("BERT model output shape:", {k: v.shape for k, v in output.items()})

2. 验证模型加载正确性

若不确定TFSMLayer的call_endpoint是否匹配,可以用以下代码查看SavedModel的签名信息:

loaded_model = tf.saved_model.load(path)
print("Available model signatures:", list(loaded_model.signatures.keys()))
print("Input names for serving_default:", list(loaded_model.signatures["serving_default"].structured_input_signature[1].keys()))

如果输入名称与代码中的input_ids等不匹配,需要调整model()调用时的字典键名。

3. 替代方案:直接使用HuggingFace的TFBertModel

如果SavedModel加载遇到问题,推荐直接用Transformers库的TFBertModel从下载路径加载,更符合常规使用习惯:

from transformers import TFBertModel

# 直接加载SavedModel格式的BERT
bert_model = TFBertModel.from_pretrained(path)
# 用Tokenizer处理文本后传入模型
test_encodings = encoder(["Hello, this is a test sentence."], padding=True, truncation=True, return_tensors="tf")
output = bert_model(**test_encodings)
print("Pooled output shape:", output.pooler_output.shape)

关于模型格式转换的补充

  • 若要将.pb转为纯Keras模型,可尝试tf.keras.models.load_model(path),但仅适用于Keras导出的SavedModel;若加载失败,说明该模型是纯TensorFlow SavedModel,建议继续使用TFSMLayer或TFBertModel加载。
  • 转PyTorch模型可使用Transformers库的权重转换工具:
import torch
from transformers import BertModel, convert_tf_weight_to_pt_weight

# 转换TensorFlow权重为PyTorch格式
convert_tf_weight_to_pt_weight(path, "pytorch_bert_weights.bin")
# 加载PyTorch模型
pt_model = BertModel.from_pretrained("bert-large-uncased-whole-word-masking", state_dict=torch.load("pytorch_bert_weights.bin"))

内容的提问来源于stack exchange,提问作者Christian Waidner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 13:22:09