4.5 Tensorflow Serving | Tensorflow Serving

Tensorflow Serving 是一个生产级别的灵活高性能的机器学习模型服务系统。Tensorflow Serving 在保持相同的服务架构和 APIs 的前提下让部署新的算法和实验变得更加简单。Tensorflow Serving 提供了和 Tesorflow 模型开箱即用的集成,同时可以容易的扩展到为其他模型和数据提供服务。

可以从如下几点开始了解 TensorFlow Serving:

TensorFlow Serving

图 4.1: TensorFlow Serving

4.5.1 Architecture Overview | 架构总览

4.5.1.1 Key Concepts | 核心概念

想要了解 TensorFlow Serving 的架构,你需要先了解如下几个核心概念:

4.5.1.1.1 Servables

Servables 是 TensorFlow Serving 中最核心的抽象,是客户端用于执行计算 (例如:查找或推断) 的底层对象。

Servables 的大小和力度是灵活的,单个 Servable 可能包含从一个查找表的单个分片,到一个单独的模型,或是推理模型的元组。Servables 可以是任何类型或接口,这使得其具有灵活性并易于将来的改进,例如:

  • 流式结果
  • 实验性 APIs
  • 异步操作模式

Servables 并不管理自身的生命周期。

典型的 Servables 包括:

  • 一个 TensorFlow 的 SavedModelBundle (tensorflow::Session)
  • 一个用于 Embedding 的查找表或词汇表

Servables Versions

TensorFlow Serving 能够在一个服务实例的生命周期内处理一个或多个 版本 (versions) 的 Servable,这使得新的算法配置,权重和其他数据可以随时被加载。Versions 使得多个版本的 Servable 可以并发加载,并支持逐步转出 (gradual rollout) 和实验。在提供服务时,客户端可以请求最新版本的模型或是制定版本 ID 的模型。

Servables Streams

一个 Servables Stream 是多个版本的 Servable 的序列,其按照版本号的递增排序。

Models

TensorFlow Serving 将一个 模型 (model) 表示为一个或多个 Servables。一个机器学习模型可能包括一个或多个算法 (包括学习到的权重) 和查找表。

你可以将一个 复合模型 (composite model) 表示成如下形式:

  • 多个独立的 Servables
  • 一个组合的 Servables

一个 Servable 也可能是一个模型的一部分,例如,一个大的查找表可能被分割到多个不同的 TensorFlow Serving 实例中。

4.5.1.1.2 Loaders

Loaders 管理一个 Servable 的生命周期。Loader API 提供了一个独立于特定机器学习算法,数据和用户产品用例的通用基础平台。具体说,Loaders 将一个 Servable 的加载和卸载的 API 进行了标准化。

4.5.1.1.3 Sources

Sources 是用于查找和提供 Servables 的插件模块,每个 Source 提供零个或多个 Servable Streams。对于每个 Servable Stream,一个 Source 为一个 Loader 实例对不同版本的载入提供支持。(一个 Source 通常是由零个或多个 SourceAdapters 链接在一起,其中最后一项将触发 Loaders。)

TensorFlow Serving 中 Sources 的接口可以从任意的存储系统中发现 Servables,TesorFlow Serving 包含了 Source 实现的通用引用。例如:Sources 可以利用 RPC 等机制,并可以轮训文件系统。

Sources 可以维护多个 Servables 或 不同版本分片中的状态,这将有助于 Servables 在不同版本之间进行 Delta (diff) 更新。

Aspired Versions

Aspired Versions 代表那些应该被加载和准备好的 Servable Versions 的集合。Sources 在同一时间为单个 Servable Stream 与这个 Servable Versions 的集合进行通讯。当一个 Source 为管理器 (Managers) 提供一个新的 Aspired Versions 的列表是,对于 Servable Strema 而言,其将取代之前的列表。同时管理器将卸载所有之前被加载但未出现在当前列表中的 Versions。

了解更多有关 Version 加载的信息,请参见 Advanced Tutorial

4.5.1.1.4 Managers

Managers 维护 Servables 的整个生命周期,包括:

  • 加载 Servables
  • 为 Servables 提供服务
  • 卸载 Servables

Managers 从 Sources 获取信息并跟踪所有的 Versions。Manager 尽可能的满足 Sources 的请求,但当所需的资源不存在时,会拒绝载入一个 Aspired Versions。Manager 也可能延迟触发一个卸载 (unload),例如:基于要确保任意时点都要至少有一个 Version 被加载的策略,Manager 需要等待一个新的 Version 完成加载后再卸载之前的 Version。

Tensorflow Serving Managers 提供一个简单 (simple) 的窄接口 (narrow interface)1GetServableHandler(),用于客户端访问以加载的 Servable 实例。

4.5.1.1.5 Core

TensorFlow Serving Core 通过 TensorFlow Serving APIs 管理 Servales 的如下方面:

  • 生命周期 (lifecycle)
  • 度量信息 (metrics)

TensorFlow Serving Core 将 Servables 和 Loaders 视为不透明的对象 (opaque objects)。

4.5.1.2 Life of a Servable | Servable 的生命周期

TensorFlow Serving Architecture

图 4.2: TensorFlow Serving Architecture

一般来说:

  1. Sources 建立 Loaders 用于 Servable Versions。
  2. Loaders 作为 Aspired Versions 被发送到 Mananger,并加载并为客户端的请求提供服务。

更详细的:

  1. 一个 Source 插件对一个特定的 Version 创建一个 Loader,这个 Loader 包含了需要载入 Servable 的全部元信息。
  2. Source 通过一个回调函数来通知 Manager 此时的 Aspired Version。
  3. Manager 根据 Version Policy 的设置决定接下来的操作,可能是卸载之前的 Version,或是载入一个新的 Version。
  4. 如果 Manager 的认为操作是安全的,则会赋予 Loader 相应的资源并通知 Loader 载入一个新的 Version。
  5. 客户端向 Manager 请求 Servable,可指定一个版本或是请求最新的版本,Manager 返回一个对应的处理器。

例如:一个 Source 请求一个包含最近更新的权重的 TensorFlow 计算图,其权重信息存储在硬盘的一个文件中。

  1. Source 检测到一个新版本的模型权重,其会创建一个包含指向磁盘中模型数据指针的 Loader。
  2. Source 通知 Dynamic Manager 此时的 Aspired Version。
  3. Dynamic Manager 应用 Version Policy 并决定载入新版本。
  4. Dynamic Manager 通知 Loader 目前有充足的内存,Loader 利用新的权重实例化 Tensorflow 计算图。
  5. 一个客户端请求最新版本的模型,Dynamic Manager 返回一个最新版本 Servable 的处理器。

4.5.1.3 Extensibility | 可扩展性

TensorFlow Serving 提供多种用于添加新功能的扩展点。

4.5.1.3.1 Version Policy

Version Policy 用于指定一个服务流 (Servable Stream) 中 Version 的加载和卸载顺序。

TensorFlow Serving 包含两个适用于大多数已知用例的策略。包括可用性确保策略 (Svailability Preserving Policy) (即避免没有任何版本被加载,通常是在卸载一个旧的版本之前加载一个新的版本) 和资源确保策略 (Resource Preserving Policy) (即避免同时加载两个版本带来的资源需求加倍,在加载一个新的版本之前卸载一个旧的版本)。在 TensorFlow Serving 的简单实践中,服务的可用性至关重要,同时资源成本相对较低,可用性确保策略 (Svailability Preserving Policy) 将确保在卸载一个旧的版本之前载入一个新的版本并使其就绪。在 TensorFlow Serving 的复杂实践中,例如在多服务实例之间管理不同的版本,资源确保策略 (Resource Preserving Policy) 则需要最少的资源 (无需额外的缓冲区来加载新的版本)。

4.5.1.3.2 Source

新的 Sources 可以支持新的文件系统,云端产品和后端算法。TensorFlow Serving 提供了一些通用的构建组件用于便捷快速的构架新的 Sources。例如:TensorFlow Serving 包含了一个对单个 Source 进行 Polling Behavior 的包装工具。对于特定的算法和数据托管 Servables,Sources 和 Loaders 紧密相关。

有关如何创建自定义的 Source,请参阅 Custom Source 文档。

4.5.1.3.3 Loaders

Loaders 是添加算法和数据后端的扩展点,TensorFlow 即为这样一个算法后端。例如:你可以实现一个新的 Loader,以便加载,提供访问,卸载一些新的机器学习模型实例。我们期望为查找表和其他算法构建新的 Loaders。

有关如何创建自定义的 Servable,请参阅 Custom Servable 文档。

4.5.1.3.4 Batcher

将多个请求批处理为单个请求可以显著降低推理的策划给你本,特别是在有 GPU 等加速器的情况下。TensorFlow Serving 包含了一个用于批处理请求的小工具,它允许客户端可以轻松的将请求中特定类型的推断合成一个批处理请求,以便系统能够更有效的处理。想了解更多有关信息,请参阅 Batching Guide

4.5.1.4 Next Steps

让我们通过一个 简单的教程 开始使用 TensorFlow Serving。

4.5.2 Installation | 安装

4.5.2.1 Prerequisites | 先决条件

为了编译和使用 TensorFlow Serving,你需要了解如下预备知识。

4.5.2.1.1 Bazel (仅当需要从源码编译时)

TensorFlow Serving 需要 Bazel 0.5.4 或更高版本。你可以 在此 找到关于安装 Bazel 的介绍。

如果你已经准备好了 Bazel,整个安装过程如下:

  1. 这里 下载相应的二进制文件。假设你下载的文件为 bazel-0.5.4-installer-linux-x86_64.sh,你需要运行如下命令:
  1. 设置你的环境,将其放入你的 ~/.bashrc 文件
4.5.2.1.2 gRPC

本教程将使用 gRPC (1.0.0 或更高版本) 作为我们的 RPC 服务框架。你可以 在此 找到相关安装介绍。

4.5.2.1.3 Packages

安装 Tensorflow Serving 相关依赖,你需要执行如下命令:

构建 TensorFlow 的依赖包可能随时发生变化,如果你遇到任何问题,请参见 TensorFlow 的 构建说明。请特别注意你需要运行的 apt-get installpip install 命令。

4.5.2.1.4 TensorFlow Serving Python API PIP package

运行 Python 客户端代码无需安装 Bazel,你可以安装 tensorflow-serving-api 包:

4.5.2.2 Installing using apt-get | 通过 apt-get 安装

4.5.2.2.1 Avaliable binaries | 可用的二进制文件

TensorFlow Serving ModelServer 的二进制文件有两种形式:

tensorflow-model-server: 利用一些特定平台的编译器优化,例如 SSE4 和 AVX 指令优化的服务端。大部分用户应该首选这个,但该版本可能不适用于一些旧的机器。

tensorflow-model-server-universal: 仅利用基础的优化进行编译,不包括特定平台的指令集,因此应该能够在大多数机器上工作。在 tensorflow-model-server 无法工作时可以选用这个版本。注意,两个包的而简直名称是相同的,因此如果你已经安装了 tensorflow-model-server,请先卸载它再安装本版本。

sudo apt-get remove tensorflow-model-server

4.5.2.2.2 Installing the ModelServer | 安装 ModelServer
  1. 添加 TensorFlow Serving 分发 URI 所谓包的安装源 (一次性设置)
  1. 安装和更新 TensorFlow ModelServer

安装完毕后,可以通过 tensorflow_model_server 命令调用。

你可以通过如下代码更新 tensorflow-model-server:

如果你的处理器不支持 AVX 指令,请将上面代码中的 tensorflow-model-server 替换为 tensorflow-model-server-universal。

4.5.2.3 Installing from source | 通过源码安装

4.5.2.3.1 Clone the TensorFlow Serving repository | 克隆 TensorFlow Serving 代码库

注意上面的代码将安装最新的 master 分支的 TensorFlow Serving。如果你想安装指定分支 (例如一个 release 分支),请添加 -b <branchname>git clone 命令中。

4.5.2.3.2 Install Prerequieites | 安装先决条件

按照先决条件章节中的说明安装所有的依赖。如果在安装和配置 TensorFlow 及其依赖的过程中遇到问题,请参见 TensorFlow install instructions

4.5.2.3.3 Build | 构建

TensorFlow Serving 使用 Bazel 进行构建。使用 Bazel 命令构建单个目标或整套源码。

构建整个工程,请执行如下代码:

编译好的二进制文件位于 bazel-bin 目录中,可以通过如下命令执行:

可以通过如下代码测试你的安装:

更多的 TensorFlow Serving 的深入示例,请参见 basic tutorialadvanced tutorial

4.5.2.3.4 Optimized build | 优化的构建

我们可以通过使用一些平台的特定指令集 (例如:AVX) 进行编译从而能够有效的提高其性能。在文档的任意位置,当你遇见 bazel build 命令时,你都可以添加一些参数 -c opt --copt=-msse4.1 --copt=-msse4.2 --copt=-mavx --copt=-mavx2 --copt=-mfma --copt=-O3 --cxxopt="-D_GLIBCXX_USE_CXX11_ABI=0" (或这些参数的部分),例如:

这些指令集并不能在所有的机器上都可用,尤其是一些比较旧的机器,可能导致一些参数无法工作。你可以尝试使用其中的部分参数,或者仅使用 -c opt 以确保其能够在所有的机器上工作。

4.5.3 Serving a TensorFlow Model | 部署一个 Tensorflow 模型服务

本教程将展示如何利用 TensorFlow Serving 组件导出一个训练好的 TensorFlow 模型,并利用 tensorflow_model_server 来进行部署。如果你已经熟悉 TensorFlow Serving,并想了解其内部是如何工作的,请参见 TensorFlow Serving advanced tutorial

本教程将使用在 TensorFlow 教程中引入的手写图像 (MNIST 数据) 识别这样一个简单的 Softmax Regression 模型。如果你还不清楚什么是 TensorFlow 或 MNIST,请参见 MNIST For ML Beginners 教程。

本教程的代码主要包含两个部分:

  • 一个 Python 文件,mnist_saved_model.py,用于训练和导出模型。
  • 一个 ModelServer 二进制文件,可以通过 apt-get 安装或从 C++ 源码 (main.cc) 进行编译。TensorFlow Serving ModelServer 用于发现新导出的模型,并启动 gRPC 用于提供模型服务。

在开始本教程之前,你需要完成 先决条件

如下所有的 bazel 命令都可以使用标准的 -c opt 参数进行优化,更多相关构建优化,请参见 相关说明

4.5.3.1 Train and Export TensorFlow Model | 训练和导出 TensorFlow 模型

mnist_saved_model.py 代码中,模型的整个训练过程同 MNIST For ML Beginners 教程中相同。TensorFlow 计算图通过 TensorFlow 会话 sess 加载,以张量 (image) x 为输入,以张量 (softmax score) y 为输出。

接下来我们利用 TensorFlow 的 SavedModelBuilder 模块导出模型。SavedModelBuilder 将训练好的模型的一个快照保存到可靠存储中,以便后续加载并进行推理。

对于 SavedModel 格式的详细信息,请参见 SavedModel REAMDE.md 文档。

mnist_saved_model.py 代码中,如下代码片段说明了将模型保存至硬盘的一般流程。

SavedModelBuilder.__init__ 接受如下参数:

  • export_path 为模型导出的目录。

如果目录不存在,SavedModelBuilder 会自动创建这个目录。在本例中,我们从将其和 FLAGS.model_version 放在命令行参数中以获取导出目录。FLAGS.model_version 指定了模型的 版本 (version)。当需要导出一个新的版本的模型时,你需要制定一个更大的整数作为版本数。每个版本将被导出到指定的导出目录的不同子目录中。

你可以使用 SavedModelBuilder.add_meta_graph_and_variables() 添加 Meta Graph 和 Variables,其接受如下参数:

  • sess 为包含需要导出的训练好的模型的 TensorFlow 会话。
  • tags 为保存 Meta Graph 时的一系列 Tags。在本例中,我们计划在服务中使用计算图,我们将使用 SavedModel Tag 常量中预定义的 serve Tag。更多相关内容,更多内容请参见 tag_constants.py 和相关的 TensorFlow API 文档。
  • signature_def_map 指定了用于添加到 Meta Graph 中的从用户提供的键到 tensorflow::SignatureDef 之间的映射。Signature 指定了导出模型的类型,以及在进行推理阶段所绑定的输入和输出张量。

特殊的 Signature 键 serving_default 指定了默认的 Serving Signature。默认的 Serving Signature Defs 键及其他相关的常量定义在 SavedModel Signature 常量中。更多内容请参见 signature_constants.py 和相关的 TensorFlow API 文档

为了方便构建 Signature Defs,SavedModel API 提供了 Signature Def 工具集。在上述的 mnist_saved_model.py 代码片段中,我们使用 signature_def_utils.build_signature_def() 构建 predict_signatureclassification_signature

作为一个 predict_signature 定义的示例,工具函数接受如下参数:

  • inputs={'images': tensor_info_x} 指定输入张量的信息。
  • outputs={'scores': tensor_info_y} 指定输出评分张量的信息。
  • method_name 表示用于推理的方法。对于预测请求,其应被设置为 tensorflow/serving/predict,对于其他方法名称,请参见 signature_constants.py 和相关的 TensorFlow API 文档

注意:tensor_info_xtensor_info_y 的 protocal buffer 结构 tensorflow::TensorInfo 定义在 这里。为了方便的构建 Tensor Infos,TensorFlow SavedModel API 提供了 utils.py 以及相关的 TensorFlow API 文档

同时注意:imagesscores 为张量的别名。它们可以为你想要的任意唯一的字符串,它们将成为张量 xy 的逻辑名称,其将为你在发送预测请求时引用的张量绑定。

例如,如果 x 代表名为 long_tensor_name_foo 的张量,y 代表名为 generated_tensor_name_bar 的张量,builder 将会存储张量的逻辑名称到真实名称的映射关系 (images -> long_tensor_name_foo) 和 (scores -> generated_tensor_name_bar)。这使得用户可以在推理时使用这些张量的逻辑名称。

作为对上述的补充,用于 Signature Def 结构和如何设置他们的相关文档,请参见 此处

让我们继续,首先,先将仓库克隆到你本地:

如果导出目录已经存在,请删除它:

如果你倾向利用 PIP 安装包安装 tensorflowtensorflow-serving-api,你可以通过简单的 python 命令运行所有的 Python 代码,安装相关的 PIP 安装包,请参见 安装说明。或者你可以使用 Bazel 编译相关的依赖并在不安装这些包的情况下运行所有的代码。如下代码经包含 Bazel 和 PIP 两种情况下的说明。

Bazel:

或者,如果已经安装了 tensorflow-serving-api,你可以运行:

下面,让我们看一下导出目录。

如上文中提到的,一个导出模型的版本的子目录会被创建。FLAGS.model_version 的默认值为 1,因此一个名为 1 的子目录被创建。

每个版本子目录中包含如下文件:

  • saved_model.pb 是序列化的 tensorflow::SavedModel 文件。其包含一个或多个计算图的定义,同时也包含模型的一些元信息,例如 Signatures。
  • variables 为一系列包含了计算图中的变量的序列化文件。

至此,整个 TensorFlow 模型导出完毕,并可用于载入。

4.5.3.2 Load Exported Model With Standard TesorFlow ModelServer | 利用标准的 TensorFlow ModelServer 载入导出的模型

如果你是用一个本地编译的 ModelServer,运行如下命令:

如果你倾向利用 apt-get 安装,可以参见 相关说明,通过如下命令启动服务:

4.5.3.3 Test the Server | 测试服务

我们可以利用提供的 mnist_client.py 测试服务。客户端会下载 MNIST 测试数据,并将预测请求发送给服务器,服务器进行推理,最终计算并得到错误率。

利用 Bazel 运行:

如果已经安装相关的 PIP 包,可以运行如下代码:

对于训练的 Softmax 模型我们预期的准确率大约在 91%,对于测试图片的前 1000 张,我们得到对应的推理错误率为 10.5%。这证明了我们成功的载入并运行了训练好的模型。

4.5.4 RESTful API | RESTful API

TensorFlow ModelServr 除了提供 gRPC APIs 以外,还支持 RESTful APIs 用于 TensorFlow 的分类,回归和预测模型。本节将介绍这些相关的 API 接口以及请求和响应的格式。

TensorFlow ModelServer 运行在 host:port 上并接受 REST API 请求:

/versions/${MODEL_VERSION} 为可选部分,如果省略的话则使用最新版本的模型。

请求 URLs 的示例如下:

请求和响应均为一个 JSON 对象,其内容取决于请求的类型和 VERB,更多内容请参见 API Specific 章节。

为了处理可能的错误,APIs 返回的 JSON 对象中包含了一个以 error 为键,错误内容为值的键值对:

4.5.4.1 Classify and Regress API | 分类和回归 API

4.5.4.1.1 Request format | 请求格式

classifyregress APIs 的请求内容必须为如下格式的 JSON 对象:

<value> 为一个 JSON 数字或字符串,<list> 为这些值的一个列表。关于如何表示一个 (或一系列) 二进制值,请参见下面的 Encoding Binary Values 章节。这个格式与 gRPC 中的 ClassificationRequestRegressionRequest protos 格式类似。两个版本均接受一个 Example 对象的列表。

4.5.4.1.2 Response format | 响应格式

一个 classify 请求返回一个 JSON 对象,其响应内容格式如下:

<label> 为一个字符串 (如果与得分没有想对应的标签的话,可以为一个空字符串 ""),<score> 为一个数值 (浮点数)。

一个 regress 请求返回一个 JSON 对象,其响应内容格式如下:

<value> 为一个数值。

gRPC API 的用户会发现其格式同 ClassificationResponseRegressionResponse protos 类似。

4.5.4.2 Predict API | 预测 API

4.5.4.2.1 Request format | 请求格式

predict API 的请求内容必须为如下格式的 JSON 对象:

其格式同 gRPC API 中的 PredictRequestCMLE predict API 类似。

当仅包含一个命名的输入时,列表里面的值应为标量 (数值或字符串)。

或者这些基础类型的列表。

张量可以自然的以嵌套的形式进行表示,因此如需手动的将其变换成列表。

对于包含多个命名的输入时,每一项应为一个包含输入名称和对应的张量值的键值对。下面的示例为一个包含 2 个实例的请求,每个实例中包含 3 命名的输入张量:

关于如何表示一个 (或一系列) 二进制值,请参见下面的 Encoding Binary Values 章节。

4.5.4.2.2 Response format | 响应格式

一个 predict 请求返回一个 JSON 对象,其响应内容格式如下:

如果模型的输出仅包含一个命名的张量,我们将会省略其名称和 predictions 键,并将其映射成一个标量或值的列表。如果模型的输出包含多个命名的张量,我们将输出一个对象的列表,同上文中提到的请求格式类似。

名称以 _bytes 结尾的张量被视为包含二进制的数据,这些数据的编码格式相对不同,将在下文中进行介绍。

4.5.4.3 JSON mapping | JSON 映射

RESTful APIs 支持 JSON 中的编码规范,这使得在不同系统之间共享数据变得更加容易。下表中列出了支持的类型,围在下表中列出的即表示暂不支持。

表 4.1: JSON Mapping
TF 数据类型 JSON 数据类型 JSON 示例 说明
DT_BOOL true, false true, false
DT_STRING string Hello World! 如果 DT_STRING 表示二进制数据 (例如:序列化的图片或 protobuf),需要使用 Base64 进行编码,更多信息请参见 Encoding binary values。
DT_INT8, DT_UINT8, DT_INT16, DT_INT32, DT_UINT32, DT_INT64, DT_UINT64 number 1, -10, 0 JSON 的值将为一个十进制数。
DT_FLOAT, DT_DOUBLE number 1.1, -10.0, 0, NaN, Infinity JSON 的值将为一个数字或一些特殊的标记值,例如:NaN,Infinity 或 -Infinity,更多信息请参见 JSON conformance。同时也接受指数计数法。

4.5.4.4 Encoding binary values | 编码二进制数据

JSON 使用 UTF-8 格式编码。如果输入特征或张量的值为二进制 (例如:图像),则你需要将数据利用 Base64 进行编码,并将其以 b64 为键封装在 JSON 对象中:

你可以为这个对象指定一个值用于输入特征或张量,相应输出的编码格式与此相同。

一个包含图片 image (二进制数据) 和标题 caption 特征的分类请求示例如下:

4.5.4.5 JSON conformance | JSON 一致性

大多数的特征和张量值为浮点数,除了有限值 (例如:3.14,1.0 等) 外,也可以是 NaN 或是无穷值 (Infinity-Infinity)。不幸的是,JSON 规范 (RFC 7159) 并不能识别这些值 (尽管 JavaScript 规范可以)。

本节中的 REST API 允许其请求和相应的 JSON 对象中包含这些值,也就是说如下的一个请求示例是有效的:

一个符合 (严格) 标准的 JSON 解析器将会无法解析 (由于无法识别和数字混合在一起的 NaNInfinity 标记)。要正确在代码中处理请求和相应,你需要一个支持这些标记的 JSON 解析器。

NaNInfinity-Infinity 这些标记可以被 proto3,Python JSON 模块和 JavaScript 语言识别。

4.5.4.6 Example | 示例

接下来我们利用 half_plus_three 示例来测试 REST APIs。

4.5.4.6.1 Start ModelServer with the REST API endpoint | 以 REST API 形式启动 ModelServer

按照 设置说明 中的步骤在系统中安装好 TensorFlow ModelServer,接着从 Git 仓库 下载 half_plus_three 模型:

启动 ModelServer 并利用 --rest_api_port 参数指定 REST API 服务的端口:

4.5.4.6.2 Make REST API calls to ModelServer | 以 REST API 形式请求 ModelServer

在另一个控制台中,利用 curl 命令进行 REST API 请求,一个预测 (predict) 的请求示例如下:

一个回归 (regress) 的请求示例如下:

注意:regress 可用于非默认的 Signature,但必须明确指定。一个错误的请求 URL 或请求内容将会返回 HTTP 错误代码:

4.5.5 Building Standard TensorFlow ModelServer | 构建一个标准的 TensorFlow 模型服务器

4.5.6 Serving Inception Model with TensorFlow Serving and Kubernetes |

4.5.7 Creating a new kind of servable

4.5.8 Creating a module that discovers new servable paths

4.5.9 SignatureDefs in SavedModel for TensorFlow Serving

4.5.10 Using TensorFlow Serving via Docker | 通过 Docker 使用 TensorFlow Serving

通过 Docker 使用 TensorFlow Serving 是最简单的方式之一。

4.5.10.1 Installing Docker | 安装 Docker

你可以在 Docker 官网 找到相关的安装说明,下面是一些快速链接:

4.5.10.2 Serving with Docker | 利用 Docker 提供服务

4.5.10.2.1 Pulling a serving image | 拉取镜像

在安装好 Docker 之后,你可以通过如下命令拉取 TensorFlow Serving 的最新镜像:

该操作会拉取一个安装好 TensorFlow Serving 的最小的 Docker 镜像。

如需要获取其他版本的镜像,请参见 Docker Hub 中的 tensorflow/serving 仓库。

4.5.10.2.2 Serving example | 服务示例

在拉取镜像完毕后,你可以尝试部署一个示例模型。

我们将使用一个很简单的模型 Half Plus Three 进行演示,这个模型将会对于我们提供的数据利用 0.5 * x + 3 进行预测。

想要获取这个模型,你需要先克隆 TensorFlow Serving 仓库。

接下来,运行 TensorFlow Serving 容器并指向这个模型,启动 REST API 并监听 8501 端口:

该操作将会启动 TensorFlow Serving Model Server,并将 REST API 绑定到 8501 端口上,同时将本地的模型映射到容器上期望的位置。同时我们将模型的名字作为环境变量传递给容器,这在我们请求模型结果时至关重要。

运行如下命令可以利用预测 API 请求模型结果:

注意:较旧版本的 Windows 或其他一些系统可能不包含 curl 命令,你可以从 此处 下载安装。

该操作应该返回如下结果:

更多有关 RESTful API 的信息,可以参见 此处

4.5.10.3 Developing with Docker | 利用 Docker 进行开发

4.5.10.3.1 Pulling a development image | 拉取开发镜像

对于一个需要构建 TensorFlow Serving 的开发环境,你可以尝试:

对于需要提供 GPU 支持的开发环境,可以:

4.5.10.4 Dockerfiles | Dockerfiles

目前,我们维护如下 Dockerfiles:

  • Dockerfile,一个安装了 TensorFlow Serving 的最小虚拟机。
  • Dockerfile.devel,一个包含了构建 TensorFlow Serving 所需所有依赖的最小虚拟机。
  • Dockerfile.devel-gpu,一个包含了构建 TensorFlow Serving 所需所有依赖并提供 GPU 支持的最小虚拟机。
4.5.10.4.1 Building a container from a Dockerfile | 从 Dockerfile 构建一个容器

如果你希望从一个 Dockerfile 文件构建自己的 Docker 镜像,你可以通过如下构建命令实现:

Dockerfile

Dockerfile.devel

Dockerfile.devel-gpu

提示:在尝试构建一个镜像之前,请访问 Docker Hub 的 tensorflow/serving 仓库并检查确保不存在你所需要的镜像。

在默认的情况下,构建 TensorFlow Serving 需要消耗大量内存,如果你的机器内存有限,你可以在运行 bazel 时通过指定 --local_resources 2048,.5,1.0 限制内存使用。你可以使用同样的参数来调整构建 TensorFlow Serving 时的优化选项,例如:

4.5.10.4.2 Running a container | 运行一个容器

假设你已经构建好 Dockerfile.devel 容器,运行容器,开启 gRPC 并监听 8500 端口:

至此,你可以根据上文中的说明进行开发环境的测试了。


  1. 译者注: Narrow interface 相关内容可参见:http://wiki.c2.com/?SelfDocumentingCodehttp://wiki.c2.com/?OnceAndOnlyOnce