【问题标题】:TensorFlow protobuf version mismatchTensorFlow protobuf 版本不匹配
【发布时间】:2017-09-15 08:44:55
【问题描述】:

我已经通过virtualenv 安装了 TensorFlow。而且效果很好。

现在我想使用 C++ 加载模型并进行预测。但是由于 protobuf 版本不匹配,我无法编译我的程序。像这样的错误:

tensorflow/core/framework/device_attributes.pb.h:17:2: error: #error This file was generated by an older version of protoc which is
 #error This file was generated by an older version of protoc which is
  ^
tensorflow/core/framework/device_attributes.pb.h:18:2: error: #error incompatible with your Protocol Buffer headers. Please
 #error incompatible with your Protocol Buffer headers.  Please
  ^
tensorflow/core/framework/device_attributes.pb.h:19:2: error: #error regenerate this file with a newer version of protoc.
 #error regenerate this file with a newer version of protoc.

在虚拟环境中:

$ pip show protobuf
Name: protobuf
Version: 3.4.0
Summary: Protocol Buffers

在外壳中:

$ protoc --version
libprotoc 3.4.0

我的环境中曾经有protobuf-2.6.1,但现在升级到3.4.0

ubuntu 16.04

【问题讨论】:

    标签: c++ tensorflow protocol-buffers


    【解决方案1】:

    问题在于 TensorFlow 编译过程使用了自己的协议缓冲区分布。从 TensorFlow v1.3.0 开始,此发行版是协议缓冲区 3.3.0。如果您想将自己的 C++ 代码与 TensorFlow 生成的标头混合使用,则需要使用完全相同的版本(或者只需使用脚本来使用 Bazel 下载的发行版)。

    另一种方法是使用您自己的 protoc 从原始消息描述文件生成您自己的标头。

    编辑:

    TensorFlow 使用的库版本目前在tensorflow/workspace.bzl 中定义(TF v1.9)。原则上,只要它与 TensorFlow 和所有其他依赖项兼容(请注意,由于源中解释的原因,有是 Protocol Buffers 的三个 HTTP 存档,protobuf_archivecom_google_protobufcom_google_protobuf_cc,因此您需要修改这三个)。

    【讨论】:

    • 在我从源代码安装 protobuf 之前,我已经完成了 apt-get remove protobuf-dev protobuf-compiler,正如你提到的那样。但实际上,当我的安装在“/usr/local/lib”中时,/usr/lib 下仍然存在一个libprotobuf.so。顺便说一句,我的 ubuntu 中有一个 libprotobuf9v5,我想这就是原因。但是卸载它会同时删除 gnome-desktop 和其他有点连线的软件包。
    • @JasonRen 是的,libprotobuf9v5 是 Ubuntu 中的 C++ 协议缓冲区运行时库。似乎 Gnome 本身正在使用协议缓冲区,因此删除它不是一个好主意。您需要编译较新版本并配置编译器和链接器以选择正确的头文件和库(正如我所说,更喜欢静态链接,否则您的程序将尝试加载系统中安装的旧版本并失败)。
    • 但是我自己的代码没有使用protobuf。 TensorFlow 使用它。如何静态链接我不直接使用的库?@jdehesa
    • 哦,请注意错误是“旧版本”!在我安装 3.4.0 之前是“新版本”,这意味着 3.4.0 可能有效吗?但是python的protobuf版本也是3.4.0!@jdehesa
    • @oyd11 库的版本在 TensorFlow 工作区中定义,目前您可以在 tensorflow/workspace.bzl 中看到它(请参阅更新的答案)。
    【解决方案2】:

    请使用与tensorflow 相同的版本来重新编译您的原型文件。如果您使用build_all_linux.sh 从源代码构建tensorflow,您将在tensorflow/tensorflow/contrib/makefile/gen/protobuf/bin/protoc 中找到它。

    【讨论】:

      【解决方案3】:

      有一个我努力解决的类似问题:编译脚本总是能够在某处找到过时的 protoc 版本。

      检查协议位置:

      which protoc # /usr/bin/protoc
      sudo apt-get uninstall protobuf-compiler
      conda uninstall protobuf
      conda uninstall libprotobuf
      exit # resign in
      

      这意味着这里有一个protoc二进制/usr/bin/protoc和头文件/usr/include/google/protoc。删除 protoc 安装不一定会删除包含文件夹中的头文件,这会导致错误重新出现。如果您在安装 protobuf 后仍然看到错误,请尝试清理每个 protobuf 位置的包含文件。

      之后,请随意为您的平台下载已编译的二进制文件(在我的例子中是 protoc-3.10.1-linux-x86_64.zip)并将其放置在方便的位置:

      mkdir ~/tmp/
      cd ~/tmp
      wget https://github.com/protocolbuffers/protobuf/releases/download/v3.10.1/protoc-3.10.1-linux-x86_64.zip
      sudo rm -rf ./protoc
      unzip protoc-3.10.1-linux-x86_64.zip -d protoc
      chmod 755 -R protoc
      BASE=/usr/local
      sudo rm -rf $BASE/include/google/protobuf/
      sudo cp protoc/bin/protoc $BASE/bin 
      sudo cp -R protoc/include/* $BASE/include 
      

      尽管在解决问题时同时看到“您的 protobuf 版本较旧”和“您的 protobuf 版本较新”,但只需使用最新版本的 protoc。

      【讨论】:

        猜你喜欢
        • 2019-08-12
        • 2019-08-18
        • 1970-01-01
        • 1970-01-01
        • 2016-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-27
        相关资源
        最近更新 更多