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

TensorFlow(Keras)模型转ONNX报add_slot属性缺失、UTF-8解码错误求助

问题根因
  • 第一个AttributeError: '_UserObject' object has no attribute 'add_slot'报错:是版本不兼容+模型保存参数不合理共同导致。Keras 2.6版本默认使用model.save()会同时保存优化器、训练过程用到的slot变量等训练相关信息,tf2onnx加载该SavedModel时,优化器对象会被反序列化为无add_slot属性的_UserObject,触发属性不存在报错。
  • 第二个UnicodeDecodeError报错:属于参数传值错误,tf2onnx.convert的--checkpoint参数需要传入后缀为.meta的元图定义文件,你传入的keras_metadata.pb是二进制格式文件,无法按utf-8解析为文本格式的元图定义,因此触发解码错误。
解决方案
  • 第一步:重新保存仅包含推理所需信息的模型,保存时关闭优化器、训练轨迹存储:
    执行保存的代码调整为:
    model.save(
        os.path.join("models", 'modelData'),
        include_optimizer=False,
        save_traces=False
    )
    
    其中include_optimizer=False会排除优化器相关的所有训练态数据,从根源避免add_slot相关报错,save_traces=False可以减少SavedModel的冗余信息,提升转换成功率。
  • 第二步:使用SavedModel模式执行转换,建议指定兼容Keras 2.6的ONNX opset版本:
    执行命令:
    python -m tf2onnx.convert --saved-model modelData --output model.onnx --opset 13
    
  • 若上述方案仍报错,可通过显式加载模型生成concrete function的方式转换:
    执行转换代码:
    import tensorflow as tf
    import tf2onnx
    
    # 加载模型时关闭编译,避免加载优化器
    model = tf.keras.models.load_model("modelData", compile=False)
    # 定义输入签名,和你模型的输入shape、dtype保持一致即可
    input_signature = [
        tf.TensorSpec((None, *input0_shape), dtype=tf.float32, name="input0"),
        tf.TensorSpec((None, *input1_shape), dtype=tf.float32, name="input1")
    ]
    # 转换为ONNX模型
    model_proto, _ = tf2onnx.convert.from_keras(model, input_signature=input_signature, opset=13)
    # 保存模型
    with open("model.onnx", "wb") as f:
        f.write(model_proto.SerializeToString())
    
问题确认
  • 模型保存前需要做特殊处理:仅用于推理转换的模型不需要保存训练相关数据,保存时关闭优化器存储即可。
  • 存在版本兼容问题:Keras 2.6的SavedModel序列化格式和旧版tf2onnx的优化器加载逻辑存在兼容冲突,仅保存推理态模型即可规避该问题。

内容的提问来源于stack exchange,提问作者Igor Ševo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 21:54:02