是否可以将 TensorFlow Serving 与分布式 TensorFlow 集群一起使用来改进 throughput/latency?

Is it possible to use TensorFlow Serving with distributed TensorFlow cluster to improve throughput/latency?

我正在研究改善延迟的方法 and/or TensorFlow Serving instance. I've seen the "Serving Inception" manual and three GitHub Issues (2, 3, 4), but all of them seem to create a separate instance of TensorFlow Serving per server and then choosing server on client. Issue 4 的吞吐量实际上是在这些东西前面添加一些负载均衡器,目前 TensorFlow Serving 本身不存在。

但是,还有 "Distributed TensorFlow" 教程展示了如何将一组机器加入到一个固定的集群中,然后手动 "pin" 一些机器进行一些计算,这可以改善延迟和吞吐量如果模型是 "wide" 并且可以很好地并行化。但是,我在任何文档中都没有看到将其与 TensorFlow Serving 结合使用的任何提及。

问题是:是否可以配置 TensorFlow Serving 以使用分布式 TensorFlow 集群?

我能够通过一些技巧让它创建和使用 gRPC 会话(而不是本地会话):

  1. 通过修改 BUILD 文件使 tensorflow/core/distributed_runtime/rpc:grpc_session 目标公开可见(默认情况下它在 tensorflow 包内部)。
  2. 将其添加为 tensorflow_serving/model_servers:tensorflow_model_server 目标的依赖项。
  3. tensorflow_model_server 添加一个名为 --session_target 的额外标志,它在 main.cc 中设置 session_bundle_config.session_target()
  4. 运行 带有 --session_target=grpc://localhost:12345 的二进制文件,其中 localhost:12345 是将用于创建主会话的任意节点。
  5. 查看我的集群代表 TensorFlow Serving 执行一些计算。

但是,由于以下三个原因,这组技巧对于 "real-world usage" 来说还不够:

  1. grpc_session 目标可能是内部原因。
  2. 正如我在 other question 中注意到的那样,当手动 "pinned" 对特定机器进行计算时,分布式 TensorFlow 工作得更好。因此,如果我们使用 TensorFlow Serving,我们需要一种方法来保存那些 "pins" 并且模型的结构与集群的结构联系在一起。我完全不确定此信息是否使用 Exporter/Saver 导出。
  3. tensorflow_model_server 创建会话一次 - 在 bootstrap 期间。如果集群的主节点宕机然后恢复,服务服务器仍然保持 "old" 会话并且无法处理进一步的请求。

总而言之,这个场景似乎还没有正式支持,但我不确定。

如果您的模型适合单台机器,那么很难看出将其分布在多台机器上会如何提高吞吐量。本质上,您正在进行可以独立完成的计算并添加依赖项。如果您的一台机器运行缓慢或崩溃,它不会使某些查询变慢,而是会使所有查询播种。

也就是说,值得进行基准测试以查看它是否有帮助,在这种情况下,要求 use-case 得到官方支持是有意义的。

关于问题:

  1. 工人分配是通过图表 .pbtxt 中的 device 字段完成的。一些 importers/exporters 清除这些分配并具有 clear_devices 标志。您可以打开图形定义(.pbtxt 文件或等效的 str(tf.get_default_graph().as_graph_def(),以及 grep 以检查 device 个字符串)

  2. 如果任何 worker 重新启动,或者存在一些临时网络连接,您的 sess.run 将失败并显示错误(不可用),您需要重新创建会话。这由 tf.train 中的 MonitoredTrainingSession 自动处理,但您需要通过服务自行处理。

如果您的模型不使用图像,或者不是完全太大,则每个 inference/serve 不需要太多计算,我说的是使用 Inception-v# 这需要 ~在 Google Cloud Platform n1-standard-1 机器上提供对图像的响应需要 1 秒。

话虽这么说,也许它是您需要扩大的吞吐量,这是一个不同的问题。那时你最好的扩展选择是使用 Docker Swarm & Compose,以及 Kubernetes 来帮助扩展和服务于你的推理 "micro-service"。如果您的用例需要,您也可以使用 flask 来迭代一系列请求。