亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

Tensorflow已經(jīng)成長(zhǎng)為事實(shí)上的機(jī)器學(xué)習(xí)(ML)平臺(tái),在業(yè)界和研究領(lǐng)域都很流行。對(duì)Tensorflow的需求和支持促成了大量圍繞訓(xùn)練和服務(wù)機(jī)器學(xué)習(xí)(ML)模型的OSS庫(kù)、工具和框架。Tensorflow服務(wù)是一個(gè)構(gòu)建在分布式生產(chǎn)環(huán)境中用于服務(wù)機(jī)器學(xué)習(xí)(ML)模型的推理方面的項(xiàng)目。

今天,我們將重點(diǎn)討論通過(guò)優(yōu)化預(yù)測(cè)服務(wù)器和客戶機(jī)來(lái)提高延遲的技術(shù)。模型預(yù)測(cè)通常是“在線”操作(在關(guān)鍵的應(yīng)用程序請(qǐng)求路徑上),因此我們的主要優(yōu)化目標(biāo)是以盡可能低的延遲處理大量請(qǐng)求。

首先讓我們快速概述一下Tensorflow服務(wù)。

什么是Tensorflow服務(wù)?

Tensorflow Serving提供靈活的服務(wù)器架構(gòu),旨在部署和服務(wù)機(jī)器學(xué)習(xí)(ML)模型。一旦模型被訓(xùn)練過(guò)并準(zhǔn)備用于預(yù)測(cè),Tensorflow服務(wù)就需要將模型導(dǎo)出為Servable兼容格式。

Servable是封裝Tensorflow對(duì)象的中心抽象。例如,模型可以表示為一個(gè)或多個(gè)可服務(wù)對(duì)象。因此,Servables是客戶機(jī)用來(lái)執(zhí)行計(jì)算(如推理)的底層對(duì)象。可服務(wù)的大小很重要,因?yàn)檩^小的模型使用更少的內(nèi)存、更少的存儲(chǔ)空間,并且將具有更快的加載時(shí)間。Servables希望模型采用SavedModel格式,以便使用Predict API加載和服務(wù)。

如何提升Tensorflow服務(wù)性能

 

Tensorflow Serving將核心服務(wù)組件放在一起,構(gòu)建一個(gè)gRPC/HTTP服務(wù)器,該服務(wù)器可以服務(wù)多個(gè)ML模型(或多個(gè)版本)、提供監(jiān)視組件和可配置的體系結(jié)構(gòu)。

Tensorflow服務(wù)與Docker

讓我們使用標(biāo)準(zhǔn)Tensorflow服務(wù)(無(wú)CPU優(yōu)化)獲得基線預(yù)測(cè)性能延遲指標(biāo)。

首先,從Tensorflow Docker hub中提取最新的服務(wù)鏡像:

docker pull tensorflow/serving:latest

出于本文的目的,所有容器都在4核15GB Ubuntu 16.04主機(jī)上運(yùn)行。

將Tensorflow模型導(dǎo)出為SavedModel格式

使用Tensorflow訓(xùn)練模型時(shí),輸出可以保存為變量檢查點(diǎn)(磁盤上的文件)。可以通過(guò)恢復(fù)模型檢查點(diǎn)或其轉(zhuǎn)換的凍結(jié)圖(二進(jìn)制)直接運(yùn)行推理。

為了使用Tensorflow服務(wù)來(lái)提供這些模型,必須將凍結(jié)圖導(dǎo)出為SavedModel格式。Tensorflow文檔提供了以SavedModel格式導(dǎo)出訓(xùn)練模型的示例。

我們將使用深度殘差網(wǎng)絡(luò)(ResNet)模型,該模型可用于對(duì)ImageNet的1000個(gè)類的數(shù)據(jù)集進(jìn)行分類。下載預(yù)訓(xùn)練的ResNet-50 v2模型(https://github.com/tensorflow/models/tree/master/official/resnet#pre-trained-model),特別是channels_last(NHWC) convolution SavedModel,它通常更適合CPU。

復(fù)制下列結(jié)構(gòu)中的RestNet模型目錄:

如何提升Tensorflow服務(wù)性能

 

Tensorflow Serving期望模型采用數(shù)字排序的目錄結(jié)構(gòu)來(lái)管理模型版本控制。在這種情況下,目錄1/對(duì)應(yīng)于模型版本1,其中包含模型體系結(jié)構(gòu)saved_model.pb以及模型權(quán)重(變量)的快照。

加載并提供SavedModel

以下命令在docker容器中啟動(dòng)Tensorflow服務(wù)模型服務(wù)器。為了加載SavedModel,需要將模型的主機(jī)目錄掛載到預(yù)期的容器目錄中。

docker run -d -p 9000:8500  
 -v $(pwd)/models:/models/resnet -e MODEL_NAME=resnet 
 -t tensorflow/serving:latest
如何提升Tensorflow服務(wù)性能

 

檢查容器日志顯示,ModelServer正在運(yùn)行,準(zhǔn)備在gRPC和HTTP端點(diǎn)上為resnet模型提供推理請(qǐng)求:

I tensorflow_serving/core/loader_harness.cc:86] Successfully loaded servable version {name: resnet version: 1}
I tensorflow_serving/model_servers/server.cc:286] Running gRPC ModelServer at 0.0.0.0:8500 ... 
I tensorflow_serving/model_servers/server.cc:302] Exporting HTTP/REST API at:localhost:8501 ...
如何提升Tensorflow服務(wù)性能

 

預(yù)測(cè)客戶端

Tensorflow Serving將API服務(wù)模式定義為協(xié)議緩沖區(qū)(protobufs)。預(yù)測(cè)API的gRPC客戶端實(shí)現(xiàn)打包為tensorflow_serving.apisPython包。我們還需要tensorflowpython包來(lái)實(shí)現(xiàn)實(shí)用功能。

讓我們安裝依賴項(xiàng)來(lái)創(chuàng)建一個(gè)簡(jiǎn)單的客戶端:

virtualenv .env && source .env/bin/activate &&  
 pip install numpy grpcio opencv-python tensorflow tensorflow-serving-api
如何提升Tensorflow服務(wù)性能

 

該ResNet-50 v2模型期望在channels_last(NHWC)格式的數(shù)據(jù)結(jié)構(gòu)中使用浮點(diǎn)Tensor輸入。因此,使用opencv-python讀取輸入圖像,opencv-python以float32數(shù)據(jù)類型加載到numpy數(shù)組(height x width x channels)中。下面的腳本創(chuàng)建預(yù)測(cè)客戶端存根,將JPEG圖像數(shù)據(jù)加載到numpy數(shù)組中,轉(zhuǎn)換為張量原型,提出gRPC預(yù)測(cè)請(qǐng)求:

#!/usr/bin/env python
from __future__ import print_function
import argparse
import numpy as np
import time
tt = time.time()
import cv2
import tensorflow as tf
from grpc.beta import implementations
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2
parser = argparse.ArgumentParser(description='incetion grpc client flags.')
parser.add_argument('--host', default='0.0.0.0', help='inception serving host')
parser.add_argument('--port', default='9000', help='inception serving port')
parser.add_argument('--image', default='', help='path to JPEG image file')
FLAGS = parser.parse_args()
def main(): 
 # create prediction service client stub
 channel = implementations.insecure_channel(FLAGS.host, int(FLAGS.port))
 stub = prediction_service_pb2.beta_create_PredictionService_stub(channel)
 
 # create request
 request = predict_pb2.PredictRequest()
 request.model_spec.name = 'resnet'
 request.model_spec.signature_name = 'serving_default'
 
 # read image into numpy array
 img = cv2.imread(FLAGS.image).astype(np.float32)
 
 # convert to tensor proto and make request
 # shape is in NHWC (num_samples x height x width x channels) format
 tensor = tf.contrib.util.make_tensor_proto(img, shape=[1]+list(img.shape))
 request.inputs['input'].CopyFrom(tensor)
 resp = stub.Predict(request, 30.0)
 
 print('total time: {}s'.format(time.time() - tt))
 
if __name__ == '__main__':
 main()
如何提升Tensorflow服務(wù)性能

 

使用輸入JPEG圖像運(yùn)行客戶機(jī)的輸出如下所示:

python tf_serving_client.py --image=images/pupper.jpg 

total time: 2.56152906418s

輸出張量的預(yù)測(cè)結(jié)果為整數(shù)值和特征概率

如何提升Tensorflow服務(wù)性能

 

對(duì)于單個(gè)請(qǐng)求,這種預(yù)測(cè)延遲是不可接受的。然而,這并非完全出乎意料;服務(wù)于二進(jìn)制文件的默認(rèn)Tensorflow目標(biāo)是針對(duì)最廣泛的硬件范圍,以涵蓋大多數(shù)用例。您可能已經(jīng)從標(biāo)準(zhǔn)的Tensorflow服務(wù)容器日志中注意到:

I external/org_tensorflow/tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA

這表示Tensorflow服務(wù)二進(jìn)制文件在不兼容的CPU平臺(tái)上運(yùn)行,并未進(jìn)行優(yōu)化。

構(gòu)建CPU優(yōu)化服務(wù)二進(jìn)制

根據(jù)Tensorflow文檔,建議從源代碼編譯Tensorflow,并在運(yùn)行二進(jìn)制文件的主機(jī)平臺(tái)的CPU上使用所有可用的優(yōu)化。Tensorflow構(gòu)建選項(xiàng)公開了一些標(biāo)志,以支持構(gòu)建特定于平臺(tái)的CPU指令集:

如何提升Tensorflow服務(wù)性能

 

在本例中,我們將使用1.13:

USER=$1 
TAG=$2 
TF_SERVING_VERSION_GIT_BRANCH="r1.13" 
git clone --branch="$TF_SERVING_VERSION_GIT_BRANCH" https://github.com/tensorflow/serving
如何提升Tensorflow服務(wù)性能

 

Tensorflow服務(wù)開發(fā)鏡像使用Bazel作為構(gòu)建工具。處理器特定CPU指令集的構(gòu)建目標(biāo)可以指定如下:

TF_SERVING_BUILD_OPTIONS="--copt=-mavx --copt=-mavx2 --copt=-mfma --copt=-msse4.1 --copt=-msse4.2"

如果memory是約束,則可以使用--local_resources=2048,.5,1.0 flag 限制內(nèi)存密集型構(gòu)建過(guò)程的消耗。

以開發(fā)鏡像為基礎(chǔ)構(gòu)建服務(wù)鏡像:

#!/bin/bash
USER=$1
TAG=$2
TF_SERVING_VERSION_GIT_BRANCH="r1.13"
git clone --branch="${TF_SERVING_VERSION_GIT_BRANCH}" https://github.com/tensorflow/serving
TF_SERVING_BUILD_OPTIONS="--copt=-mavx --copt=-mavx2 --copt=-mfma --copt=-msse4.1 --copt=-msse4.2"
cd serving && 
 docker build --pull -t $USER/tensorflow-serving-devel:$TAG 
 --build-arg TF_SERVING_VERSION_GIT_BRANCH="${TF_SERVING_VERSION_GIT_BRANCH}" 
 --build-arg TF_SERVING_BUILD_OPTIONS="${TF_SERVING_BUILD_OPTIONS}" 
 -f tensorflow_serving/tools/docker/Dockerfile.devel .
cd serving && 
 docker build -t $USER/tensorflow-serving:$TAG 
 --build-arg TF_SERVING_BUILD_IMAGE=$USER/tensorflow-serving-devel:$TAG 
 -f tensorflow_serving/tools/docker/Dockerfile .
如何提升Tensorflow服務(wù)性能

 

ModelServer可以配置tensorflow特定的標(biāo)志來(lái)啟用會(huì)話并行性。以下選項(xiàng)配置兩個(gè)線程池來(lái)并行執(zhí)行:

intra_op_parallelism_threads

  • 控制用于并行執(zhí)行單個(gè)操作的最大線程數(shù)。
  • 用于并行化具有子操作的操作,這些子操作本質(zhì)上是獨(dú)立的。

inter_op_parallelism_threads

  • 控制用于并行執(zhí)行獨(dú)立不同操作的最大線程數(shù)。
  • Tensorflow Graph上的操作彼此獨(dú)立,因此可以在不同的線程上運(yùn)行。

兩個(gè)選項(xiàng)的默認(rèn)值都設(shè)置為0。這意味著,系統(tǒng)會(huì)選擇一個(gè)合適的數(shù)字,這通常需要每個(gè)CPU核心有一個(gè)線程可用。

接下來(lái),與之前類似地啟動(dòng)服務(wù)容器,這次使用從源碼構(gòu)建的docker映像,并使用Tensorflow特定的CPU優(yōu)化標(biāo)志:

docker run -d -p 9000:8500  
 -v $(pwd)/models:/models/resnet -e MODEL_NAME=resnet 
 -t $USER/tensorflow-serving:$TAG 
 --tensorflow_intra_op_parallelism=4 
 --tensorflow_inter_op_parallelism=4
如何提升Tensorflow服務(wù)性能

 

容器日志不應(yīng)再顯示CPU警告警告。在不更改任何代碼的情況下,運(yùn)行相同的預(yù)測(cè)請(qǐng)求會(huì)使預(yù)測(cè)延遲降低約35.8%:

python tf_serving_client.py --image=images/pupper.jpg 

total time: 1.64234706879s

提高預(yù)測(cè)客戶端的速度

服務(wù)器端已針對(duì)其CPU平臺(tái)進(jìn)行了優(yōu)化,但超過(guò)1秒的預(yù)測(cè)延遲似乎仍然過(guò)高。

加載tensorflow_serving和tensorflow庫(kù)的延遲成本很高。每次調(diào)用tf.contrib.util.make_tensor_proto也會(huì)增加不必要的延遲開銷。

我們實(shí)際上并不需要的tensorflow或tensorflow_serving包進(jìn)行預(yù)測(cè)的請(qǐng)求。

如前所述,Tensorflow預(yù)測(cè)API被定義為protobufs。因此,可以通過(guò)生成必要的tensorflow和tensorflow_servingprotobuf python存根來(lái)替換這兩個(gè)外部依賴項(xiàng)。這避免了在客戶端本身上Pull整個(gè)Tensorflow庫(kù)。

首先,擺脫tensorflow和tensorflow_serving依賴關(guān)系,并添加grpcio-tools包。

pip uninstall tensorflow tensorflow-serving-api &&  
 pip install grpcio-tools==1.0.0
如何提升Tensorflow服務(wù)性能

 

克隆tensorflow/tensorflow和tensorflow/serving存儲(chǔ)庫(kù)并將以下protobuf文件復(fù)制到客戶端項(xiàng)目中:

如何提升Tensorflow服務(wù)性能

 

將上述protobuf文件復(fù)制到protos/目錄中并保留原始路徑:

如何提升Tensorflow服務(wù)性能

 

為簡(jiǎn)單起見,predict_service.proto可以簡(jiǎn)化為僅實(shí)現(xiàn)Predict RPC。這樣可以避免引入服務(wù)中定義的其他RPC的嵌套依賴項(xiàng)。這是簡(jiǎn)化的一個(gè)例子prediction_service.proto(https://gist.github.com/masroorhasan/8e728917ca23328895499179f4575bb8)。

使用grpcio.tools.protoc以下命令生成gRPC python實(shí)現(xiàn):

PROTOC_OUT=protos/ 
PROTOS=$(find . | grep ".proto$") 
for p in $PROTOS; do 
 python -m grpc.tools.protoc -I . --python_out=$PROTOC_OUT --grpc_python_out=$PROTOC_OUT $p
done
如何提升Tensorflow服務(wù)性能

 

現(xiàn)在tensorflow_serving可以刪除整個(gè)模塊:

from tensorflow_serving.apis import predict_pb2 
from tensorflow_serving.apis import prediction_service_pb2
如何提升Tensorflow服務(wù)性能

 

并替換為生成的protobufs protos/tensorflow_serving/apis:

from protos.tensorflow_serving.apis import predict_pb2 
from protos.tensorflow_serving.apis import prediction_service_pb2
如何提升Tensorflow服務(wù)性能

 

導(dǎo)入Tensorflow庫(kù)是為了使用輔助函數(shù)make_tensor_proto,該函數(shù)用于將 python / numpy對(duì)象封裝為TensorProto對(duì)象。

因此,我們可以替換以下依賴項(xiàng)和代碼段:

import tensorflow as tf 
...
tensor = tf.contrib.util.make_tensor_proto(features) 
request.inputs['inputs'].CopyFrom(tensor)
如何提升Tensorflow服務(wù)性能

 

使用protobuf導(dǎo)入并構(gòu)建TensorProto對(duì)象:

from protos.tensorflow.core.framework import tensor_pb2 
from protos.tensorflow.core.framework import tensor_shape_pb2 
from protos.tensorflow.core.framework import types_pb2 
...
# ensure NHWC shape and build tensor proto
tensor_shape = [1]+list(img.shape) 
dims = [tensor_shape_pb2.TensorShapeProto.Dim(size=dim) for dim in tensor_shape] 
tensor_shape = tensor_shape_pb2.TensorShapeProto(dim=dims) 
tensor = tensor_pb2.TensorProto( 
 dtype=types_pb2.DT_FLOAT,
 tensor_shape=tensor_shape,
 float_val=list(img.reshape(-1)))
request.inputs['inputs'].CopyFrom(tensor)
如何提升Tensorflow服務(wù)性能

 

完整的python腳本在這里可用(https://gist.github.com/masroorhasan/0e73a7fc7bb2558c65933338d8194130)。運(yùn)行更新的初始客戶端,該客戶端將預(yù)測(cè)請(qǐng)求發(fā)送到優(yōu)化的Tensorflow服務(wù):

python tf_inception_grpc_client.py --image=images/pupper.jpg 

total time: 0.58314920859s

下圖顯示了針對(duì)標(biāo)準(zhǔn),優(yōu)化的Tensorflow服務(wù)和客戶端超過(guò)10次運(yùn)行的預(yù)測(cè)請(qǐng)求的延遲:

如何提升Tensorflow服務(wù)性能

 

從標(biāo)準(zhǔn)Tensorflow服務(wù)到優(yōu)化版本的平均延遲降低了約70.4%。

優(yōu)化預(yù)測(cè)吞吐量

Tensorflow服務(wù)也可以配置為高吞吐量處理。優(yōu)化吞吐量通常是為“脫機(jī)”批處理完成的,在“脫機(jī)”批處理中并不嚴(yán)格要求延遲界限。

服務(wù)器端批處理

延遲和吞吐量之間的權(quán)衡取決于支持的batching 參數(shù)。

通過(guò)設(shè)置--enable_batching和--batching_parameters_file標(biāo)記來(lái)啟用batching。可以按SessionBundleConfig的定義設(shè)置批處理參數(shù)(https://github.com/tensorflow/serving/blob/d77c9768e33e1207ac8757cff56b9ed9a53f8765/tensorflow_serving/servables/tensorflow/session_bundle_config.proto)。對(duì)于僅CPU系統(tǒng),請(qǐng)考慮設(shè)置num_batch_threads可用的核心數(shù)。

在服務(wù)器端達(dá)到全部批處理后,推理請(qǐng)求在內(nèi)部合并為單個(gè)大請(qǐng)求(張量),并在合并的請(qǐng)求上運(yùn)行一個(gè)Tensorflow會(huì)話。在單個(gè)會(huì)話上運(yùn)行一批請(qǐng)求是CPU/GPU并行性真正能夠發(fā)揮作用的地方。

使用Tensorflow服務(wù)進(jìn)行批量處理時(shí)需要考慮的一些用例:

  • 使用異步客戶機(jī)請(qǐng)求填充服務(wù)器端上的batches
  • 通過(guò)將模型圖組件放在CPU / GPU上來(lái)加速批處理
  • 在從同一服務(wù)器提供多個(gè)模型時(shí)交錯(cuò)預(yù)測(cè)請(qǐng)求
  • 強(qiáng)烈建議對(duì)“離線”高容量推理處理進(jìn)行批處理

客戶端批處理

在客戶端進(jìn)行批處理將多個(gè)輸入組合在一起以生成單個(gè)請(qǐng)求。

由于ResNet模型需要NHWC格式的輸入(第一維是輸入數(shù)),我們可以將多個(gè)輸入圖像聚合成一個(gè)RPC請(qǐng)求:

...
batch = [] 
for jpeg in os.listdir(FLAGS.images_path): 
 path = os.path.join(FLAGS.images_path, jpeg)
 img = cv2.imread(path).astype(np.float32)
 batch.Append(img)
...
batch_np = np.array(batch).astype(np.float32) 
dims = [tensor_shape_pb2.TensorShapeProto.Dim(size=dim) for dim in batch_np.shape] 
t_shape = tensor_shape_pb2.TensorShapeProto(dim=dims) 
tensor = tensor_pb2.TensorProto( 
 dtype=types_pb2.DT_FLOAT,
 tensor_shape=t_shape,
 float_val=list(batched_np.reshape(-1)))
request.inputs['inputs'].CopyFrom(tensor)
如何提升Tensorflow服務(wù)性能

 

對(duì)于一批N個(gè)圖像,響應(yīng)中的輸出張量將具有請(qǐng)求批次中相同數(shù)量的輸入的預(yù)測(cè)結(jié)果,在這種情況下N = 2:

如何提升Tensorflow服務(wù)性能

 

硬件加速

對(duì)于訓(xùn)練,GPU可以更直觀地利用并行化,因?yàn)闃?gòu)建深度神經(jīng)網(wǎng)絡(luò)需要大量計(jì)算才能獲得最佳解決方案。

但是,推理并非總是如此。很多時(shí)候,當(dāng)圖執(zhí)行步驟放在GPU設(shè)備上時(shí),CNN將會(huì)加速推斷。然而,選擇能夠優(yōu)化價(jià)格性能最佳點(diǎn)的硬件需要嚴(yán)格的測(cè)試、深入的技術(shù)和成本分析。硬件加速并行對(duì)于“脫機(jī)”推理batch processing更有價(jià)值。

分享到:
標(biāo)簽:Tensorflow
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定