我正在尝试编写客户端代码来与张量流服务器通信。我需要为 tensorflow
和 tensorflow_serving
编译的 golang protobufs。这些都来之不易,我是通过这个才做到的。基本上,使用 buf 来生成它们。这是 buf yaml:
version: v1 managed: enabled: true optimize_for: code_size # go go_package_prefix: default: "some/path" plugins: - plugin: buf.build/protocolbuffers/go out: gen/proto/go
运行成功,但运行应用程序日志:
package command-line-arguments imports my-package/internal/infer imports my-package/internal/infer/tensorflow_serving/apis imports my-package/internal/infer/tensorflow/core/protobuf imports my-package/internal/infer/tensorflow/compiler/xla/stream_executor imports my-package/internal/infer/tensorflow/compiler/xla imports my-package/internal/infer/tensorflow/compiler/xla/service imports my-package/internal/infer/tensorflow/compiler/xla: import cycle not allowed
请注意,tensorflow
和 tensorflow_serving
下的所有内容都是直接从原始存储库编译的。
令我惊讶的是,像张量流这样广泛使用的东西应该有一个导入周期,但也许确实如此。我该如何解决这个问题?
根本原因是存储库 https://www.php.cn/link/1a16abf2a3149fc7cd6083687cce01c2 确实没有正确组织原始文件(或者至少没有使其对 go 友好)。
以下两个文件导致go中的导入循环(xla
->xla/service
->xla
):
tensorflow/compiler/xla/xla.proto
import "tensorflow/compiler/xla/service/hlo.proto"
tensorflow/compiler/xla/service/hlo.proto
import "tensorflow/compiler/xla/xla_data.proto"
由于 xla_data.proto
不导入任何其他文件,我们可以将其移动到自己的包中以打破导入循环。我们可以利用 buf 的 覆盖功能xla_data.proto
不导入任何其他文件,我们可以将其移动到自己的包中以打破导入循环。我们可以利用 buf 的 覆盖功能做这个。这是最终的 buf.gen.yaml
做这个。这是最终的 buf.gen.yaml
文件:
version: v1 managed: enabled: true go_package_prefix: default: example.com/mymodule/internal override: go_package: # move the generated xla_data.pb.go file into package xla/data to break the import cycle. tensorflow/compiler/xla/xla_data.proto: 'example.com/mymodule/internal/tensorflow/compiler/xla/data' plugins: - name: go out: internal opt: - module=example.com/mymodule/internal - name: go-grpc out: internal opt: - module=example.com/mymodule/internal
这是最终的目录结构:
├── buf.gen.yaml ├── buf.work.yaml ├── buf.yaml ├── go.mod ├── go.sum ├── internal │ ├── tensorflow │ └── tensorflow_serving └── testdata ├── serving └── tensorflow
buf.gen.yaml:请参阅“tl;dr”部分。
buf.work.yaml:
version: v1 directories: - testdata/serving - testdata/tensorflow
buf.yaml:
version: v1 breaking: use: - file lint: use: - default
这是我的环境:
$ go version go version go1.20.3 linux/amd64 $ buf --version 1.17.0 $ protoc --version libprotoc 3.12.4 $ protoc-gen-go --version protoc-gen-go v1.30.0 $ protoc-gen-go-grpc --version protoc-gen-go-grpc 1.3.0 $ git version git version 2.37.2
现在在此目录的根目录中执行以下命令:
$ go mod init example.com/mymodule $ go get google.golang.org/grpc $ git clone https://www.php.cn/link/1a16abf2a3149fc7cd6083687cce01c2.git testdata/tensorflow $ git clone https://github.com/tensorflow/serving.git testdata/serving $ buf generate $ go build ./...
注释:
testdata
目录中,以便 go build
将忽略它们。internal
目录中生成文件。您可以修改 buf.gen.yaml
文件以将它们放置在您想要的任何位置。go build ./...
不会报告任何错误。但我不确定生成的文件是否有效。以上是张量流 Protobuf 中的导入周期的详细内容。更多信息请关注PHP中文网其他相关文章!