如何使用自定义protobuf构建tensorflow 1.13.1?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用自定义protobuf构建tensorflow 1.13.1?相关的知识,希望对你有一定的参考价值。
系统信息
- 我是否编写过自定义代码:修改bazel文件
- 操作系统平台和分发:Ubuntu 16.04
- TensorFlow安装自:来源
- TensorFlow版本:1.13.1从相应的标签下载(https://github.com/tensorflow/tensorflow/archive/v1.13.1.tar.gz)
- Python版本:Python 3.5.2
- 巴塞尔版本:0.21.0
- Protobuf版本:3.7.0(从源代码构建并放在文件系统中)
- CUDA / cuDNN版本:10.0 / 7
- GPU型号和内存:GeForce GTX 1060 Ti
上下文:默认情况下,tensorflow构建自己的protobuf代码。然而,protobuf也用于其他库,其导出的符号与tensorflow提供的符号相冲突。对该问题的唯一解决方案是对所有库(包括张量流)使用独特且独立(即,超出张量流)的protobuf版本。所以我基本上需要使用目标安装的protobuf版本构建tensorflow,它位于文件系统的某个位置。
问题:在构建tensorflow 1.13.1时,使用自定义版本的protobuf,安装在文件系统中的某个位置(不在默认系统路径中)。更具体地说,我的问题是:在tensorflow的bazel文件中需要进行哪些修改才能实现这一点。我是bazel的新手,我真的很困惑该怎么做......
这是我做的:
1)停用protobuf的内部构建,在.tf_configure.bazelrc
我添加了一行:
build --action_env TF_SYSTEM_LIBS="protobuf_archive"
除了我在默认系统路径中安装的protobuf太旧而无法解析proto3文件之外,这可以正常工作。不管怎样,这不是一个真正的问题,因为我想使用我的自定义protobuf版本3.7.0。
2)指定在哪里找到protobuf我使用new_local_repository
而不是tf_http_archive
更改了workspace.bzl文件。
这里@ PATH_TO_PROTOBUF @如果我的文件系统中安装了protobuf库的路径。
new_local_repository(
name = "protobuf_archive",
path = "@PATH_TO_PROTOBUF@",
build_file = clean_dep("//third_party/systemlibs:protobuf.BUILD"),
)
new_local_repository(
name = "com_google_protobuf",
path = "@PATH_TO_PROTOBUF@",
system_build_file = clean_dep("//third_party/systemlibs:protobuf.BUILD"),
system_link_files =
"//third_party/systemlibs:protobuf.bzl": "protobuf.bzl",
,
)
new_local_repository(
name = "com_google_protobuf_cc",
path = "@PATH_TO_PROTOBUF@",
system_build_file = clean_dep("//third_party/systemlibs:protobuf.BUILD"),
system_link_files =
"//third_party/systemlibs:protobuf.bzl": "protobuf.bzl",
,
)
3)我通过更改规则使用的二进制文件更改了位于tensorflow-1.13.1 / third_party / systemlibs中的protobuf.BUILD文件:
cc_library(
name = "protobuf",
hdrs = HEADERS,
linkopts = ["@PATH_TO_PROTOBUF@/lib/libprotobuf.so"],
visibility = ["//visibility:public"],
)
cc_library(
name = "protobuf_headers",
hdrs = HEADERS,
linkopts = ["@PATH_TO_PROTOBUF@/lib/libprotobuf.so"],
visibility = ["//visibility:public"],
)
cc_library(
name = "protoc_lib",
linkopts = ["@PATH_TO_PROTOBUF@/lib/libprotoc.so"],
visibility = ["//visibility:public"],
)
genrule(
name = "protoc",
outs = ["protoc.bin"],
cmd = "ln -s @PATH_TO_PROTOBUF@/bin/protoc $@",
executable = 1,
visibility = ["//visibility:public"],
)
这样我认为一切都会有效,但是当我运行构建时:
ERROR: .../tensorflow-1.13.1/tensorflow/core/BUILD:2460:1: ProtoCompile tensorflow/core/lib/core/error_codes.pb.cc failed (Exit 127): protoc.bin failed: error executing command
(cd /home/robin/.cache/bazel/_bazel_robin/c04a70144cd329180403af87e4cbdc44/execroot/org_tensorflow && \
exec env - \
PATH=/bin:/usr/bin \
bazel-out/host/genfiles/external/protobuf_archive/protoc.bin '--cpp_out=bazel-out/host/genfiles/' -I. -Iexternal/protobuf_archive -Ibazel-out/host/genfiles/external/protobuf_archive tensorflow/core/lib/core/error_codes.proto)
Execution platform: @bazel_tools//platforms:host_platform
[32 / 203] 6 actions, 5 running
Executing genrule @protobuf_archive//:link_headers [for host]; 0s local
ProtoCompile .../core/lib/core/error_codes.pb.cc [for host]; 0s local
Compiling tensorflow/core/platform/default/logging.cc [for host]; 0s local
ProtoCompile tensorflow/core/example/example.pb.cc [for host]; 0s local
Executing genrule @local_config_cuda//cuda:cuda-include; 0s local
[-----] Writing file external/llvm/llvm-tblgen-2.params [for host]
bazel-out/host/genfiles/external/protobuf_archive/protoc.bin: error while loading shared libraries: libprotoc.so.18: cannot open shared object file: No such file or directory
显然protoc失败只是因为加载器找不到libprotoc。
4)所以解决方案对我来说是微不足道的,只需设置LD_LIBRARY_PATH就可以自动找到libprotoc.so。遗憾的是,以下解决方案均无效:
A)直接设置LD_LIBRARY_PATH
export LD_LIBRARY_PATH=@PATH_TO_PROTOBUF@/lib
bazel build //tensorflow:tensorflow_cc.So
B)通过.tf_configure.bazelrc
设置LD_LIBRARY_PATH:
build --action_env LD_LIBRARY_PATH="@PATH_TO_PROTOBUF@/lib"
输出与之前完全相同,所以我的第一句话就是不导出LD_LIBRARY_PATH(据我所知)。这可以解释为:
exec env - \
PATH=/bin:/usr/bin \
bazel-out/host/genfiles/external/protobuf_archive/protoc.bin '--cpp_out=bazel-out/host/genfiles/'
不包含像这样的表达式
LD_LIBRARY_PATH=@PATH_TO_PROTOBUF@/lib/
我google了很长时间没有找到任何解决方案来解决这个问题(我测试了很多但没有任何效果)...也许这是我使用的Bazel版本的限制?不幸的是我不能使用更新版本的Bazel,因为tensorflow 1.13.1禁止它。
所以现在我不知道该怎么做......我想解决方案是对张量流的bazel项目文件做一些修改......
对于那些感兴趣的人,我找到了一个不那么优雅的解决方案,但似乎有效:
1)写一个脚本call_proto.sh
export LD_LIBRARY_PATH=@TARGET_PROTOBUF_LIB_DIR@:$LD_LIBRARY_PATH
@TARGET_PROTOC_EXECUTABLE@ $@
用足够的值替换@ TARGET_PROTOBUF_LIB_DIR @和@ TARGET_PROTOC_EXECUTABLE @(包含protoc库的库目录和protoc可执行文件的完整路径)。
2)从我之前的例子中,在tensorflow-1.13.1 / third_party / systemlibs / protobuf.BUILD中替换:
genrule(
name = "protoc",
outs = ["protoc.bin"],
cmd = "ln -s @PATH_TO_PROTOBUF@/bin/protoc $@",
executable = 1,
visibility = ["//visibility:public"],
)
通过
genrule(
name = "protoc",
outs = ["protoc.bin"],
cmd = "ln -s @PROTO_CALL_SCRIPT@ $@",
executable = 1,
visibility = ["//visibility:public"],
)
使用@ PROTO_CALL_SCRIPT @上一个脚本文件的路径...
这确实解决了将LD_LIBRARY_PATH传递给protoc调用的问题。
不幸的是,现在出现了另一个问题:
ERROR: /home/robin/.cache/bazel/_bazel_robin/c04a70144cd329180403af87e4cbdc44/external/protobuf_archive/BUILD.bazel:44:1: declared output 'external/protobuf_archive/google/protobuf/any.pb.h' is a dangling symbolic link
[21 / 86] 7 actions, 6 running
Executing genrule @protobuf_archive//:link_headers [for host]; 0s local
Executing genrule @local_config_cuda//cuda:cuda-include; 0s local
@com_google_absl//absl/base:dynamic_annotations; 0s local
Executing genrule @local_config_cuda//cuda:cuda-lib [for host]; 0s local
ProtoCompile tensorflow/core/example/example.pb.cc [for host]; 0s local
ProtoCompile tensorflow/core/example/example.pb.cc; 0s local
[-----] //tensorflow/cc:ops/candidate_sampling_ops_gen_cc
ERROR: /home/robin/.cache/bazel/_bazel_robin/c04a70144cd329180403af87e4cbdc44/external/protobuf_archive/BUILD.bazel:44:1: declared output 'external/protobuf_archive/google/protobuf/any.proto' is a dangling symbolic link
[21 / 89] 7 actions, 6 running
Executing genrule @protobuf_archive//:link_headers [for host]; 0s local
Executing genrule @local_config_cuda//cuda:cuda-include; 0s local
@com_google_absl//absl/base:dynamic_annotations; 0s local
Executing genrule @local_config_cuda//cuda:cuda-lib [for host]; 0s local
ProtoCompile tensorflow/core/example/example.pb.cc [for host]; 0s local
ProtoCompile tensorflow/core/example/example.pb.cc; 0s local
[-----] //tensorflow/cc:ops/candidate_sampling_ops_gen_cc
ERROR: /home/robin/.cache/bazel/_bazel_robin/c04a70144cd329180403af87e4cbdc44/external/protobuf_archive/BUILD.bazel:44:1: declared output 'external/protobuf_archive/google/protobuf/arena.h' is a dangling symbolic link
[21 / 89] 7 actions, 6 running
...
同样的错误消息is a dangling symbolic link
出现在protobuf的所有标题。
确实在相应的protobuf_archive文件夹中,我有悬挂的符号链接,如:
any.pb.h -> /usr/include/google/protobuf/any.pb.h
据我所知,问题来自genrule link_headers
:
genrule(
name = "link_headers",
outs = HEADERS,
cmd = """
echo "OUTS=$(OUTS) include=$(INCLUDEDIR)"
for i in $(OUTS); do
f=$$i#$(@D)/
mkdir -p $(@D)/$$f%/*
ln -sf $(INCLUDEDIR)/$$f $(@D)/$$f
done
""",
)
由于INCLUDEDIR
值(/usr/include
)所有生成的符号链接都无效。
解决方案是修改thios规则以使其指向有效的包含文件夹:
genrule(
name = "link_headers",
outs = HEADERS,
cmd = """
for i in $(OUTS); do
f=$$i#$(@D)/
mkdir -p $(@D)/$$f%/*
ln -sf @TARGET_PROTOBUF_INCLUDE@/$$f $(@D)/$$f
done
""",
)
与@ TARGET_PROTOBUF_INCLUDE @ protobuf的路径包括文件系统中的dir ...现在符号链接正确生成,悬空符号链接的错误消失。
我有错误报告protobuf的一些头文件是未知的......为了解决这个问题,解决方案只是为protobuf.BUILD中的HEADERS
生成足够的值。我将HEADERS
的值设置为:
HEADERS = [
"google/protobuf/any.h",
"google/protobuf/any.pb.h",
"google/protobuf/any.proto",
"google/protobuf/api.pb.h",
"google/protobuf/api.proto",
"google/protobuf/arena.h",
"google/protobuf/arena_impl.h",
"google/protobuf/arenastring.h",
"google/protobuf/compiler/code_generator.h",
"google/protobuf/compiler/command_line_interface.h",
"google/protobuf/compiler/cpp/cpp_generator.h",
"google/protobuf/compiler/csharp/csharp_generator.h",
"google/protobuf/compiler/csharp/csharp_names.h",
"google/protobuf/compiler/importer.h",
"google/protobuf/compiler/java/java_generator.h",
"google/protobuf/compiler/java/java_names.h",
"google/protobuf/compiler/js/js_generator.h",
"google/protobuf/compiler/js/well_known_types_embed.h",
"google/protobuf/compiler/objectivec/objectivec_generator.h",
"google/protobuf/compiler/objectivec/objectivec_helpers.h",
"google/protobuf/compiler/parser.h",
"google/protobuf/compiler/php/php_generator.h",
"google/protobuf/compiler/plugin.h",
"google/protobuf/compiler/plugin.pb.h",
"google/protobuf/compiler/plugin.proto",
"google/protobuf/compiler/python/python_generator.h",
"google/protobuf/compiler/ruby/ruby_generator.h",
"google/protobuf/descriptor.h",
"google/protobuf/descriptor.pb.h",
"google/protobuf/descriptor.proto",
"google/protobuf/descriptor_database.h",
"google/protobuf/duration.pb.h",
"google/protobuf/duration.proto",
"google/protobuf/dynamic_message.h",
"google/protobuf/empty.pb.h",
"google/protobuf/empty.proto",
"google/protobuf/extension_set.h",
"google/protobuf/extension_set_inl.h",
"google/protobuf/field_mask.pb.h",
"google/protobuf/field_mask.proto",
"google/protobuf/generated_enum_reflection.h",
"google/protobuf/generated_enum_util.h",
"google/protobuf/generated_message_reflection.h",
"google/protobuf/generated_message_table_driven.h",
"google/protobuf/generated_message_util.h",
"google/protobuf/has_bits.h",
"google/protobuf/implicit_weak_message.h",
"google/protobuf/inlined_string_field.h",
"google/protobuf/io/coded_stream.h",
"google/protobuf/io/gzip_stream.h",
"google/protobuf/io/printer.h",
"google/protobuf/io/strtod.h",
"google/protobuf/io/tokenizer.h",
"google/protobuf/io/zero_copy_stream.h",
"google/protobuf/io/zero_copy_stream_impl.h",
"google/protobuf/io/zero_copy_stream_impl_lite.h",
"google/protobuf/map.h",
"google/protobuf/map_entry.h",
"google/protobuf/map_entry_lite.h",
"google/protobuf/map_field.h",
"google/protobuf/map_field_inl.h",
"google/protobuf/map_field_lite.h",
"google/protobuf/map_type_handler.h",
"google/protobuf/message.h",
"google/protobuf/message_lite.h",
"google/protobuf/metadata.h",
"google/protobuf/metadata_lite.h",
"google/protobuf/parse_context.h",
"google/protobuf/port.h",
"google/protobuf/port_def.inc",
"google/protobuf/port_undef.inc",
"google/protobuf/reflection.h",
"google/protobuf/reflection_ops.h",
"google/protobuf/repeated_field.h",
"google/protobuf/service.h",
"google/protobuf/source_context.pb.h",
"google/protobuf/source_context.proto",
"google/protobuf/struct.pb.h",
"google/protobuf/struct.proto",
"google/protobuf/stubs/bytestream.h",
"google/protobuf/stubs/callback.h",
"google/protobuf/stubs/casts.h",
"google/protobuf/stubs/common.h",
"google/protobuf/stubs/fastmem.h",
"google/protobuf/stubs/hash.h",
"google/protobuf/stubs/logging.h",
"google/protobuf/stubs/macros.h",
"google/protobuf/stubs/mutex.h",
"google/protobuf/stubs/once.h",
"google/protobuf/stubs/platform_macros.h",
"google/protobuf/stubs/port.h",
"google/protobuf/stubs/status.h",
"google/protobuf/stubs/stl_util.h",
"google/protobuf/stubs/stringpiece.h",
"google/protobuf/stubs/strutil.h",
"google/protobuf/stubs/template_util.h",
"google/protobuf/text_format.h",
"google/protobuf/timestamp.pb.h",
"google/protobuf/timestamp.proto",
"google/protobuf/type.pb.h",
"google/protobuf/type.proto"以上是关于如何使用自定义protobuf构建tensorflow 1.13.1?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Protobuf.net C# 序列化自定义对象基础属性
如何使用 mingw 在 Windows 中构建 protobuf-c?
从 protobuf-net 中的自定义 RuntimeTypeModel 生成 .proto 文件