日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

Tensorflow已經成長為事實上的機器學習(ML)平臺,在業界和研究領域都很流行。對Tensorflow的需求和支持促成了大量圍繞訓練和服務機器學習(ML)模型的OSS庫、工具和框架。Tensorflow服務是一個構建在分布式生產環境中用于服務機器學習(ML)模型的推理方面的項目。

今天,我們將重點討論通過優化預測服務器和客戶機來提高延遲的技術。模型預測通常是“在線”操作(在關鍵的應用程序請求路徑上),因此我們的主要優化目標是以盡可能低的延遲處理大量請求。

首先讓我們快速概述一下Tensorflow服務。

什么是Tensorflow服務?

Tensorflow Serving提供靈活的服務器架構,旨在部署和服務機器學習(ML)模型。一旦模型被訓練過并準備用于預測,Tensorflow服務就需要將模型導出為Servable兼容格式。

Servable是封裝Tensorflow對象的中心抽象。例如,模型可以表示為一個或多個可服務對象。因此,Servables是客戶機用來執行計算(如推理)的底層對象。可服務的大小很重要,因為較小的模型使用更少的內存、更少的存儲空間,并且將具有更快的加載時間。Servables希望模型采用SavedModel格式,以便使用Predict API加載和服務。

如何提升Tensorflow服務性能

 

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

Tensorflow服務與Docker

讓我們使用標準Tensorflow服務(無CPU優化)獲得基線預測性能延遲指標。

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

docker pull tensorflow/serving:latest

出于本文的目的,所有容器都在4核15GB Ubuntu 16.04主機上運行。

將Tensorflow模型導出為SavedModel格式

使用Tensorflow訓練模型時,輸出可以保存為變量檢查點(磁盤上的文件)。可以通過恢復模型檢查點或其轉換的凍結圖(二進制)直接運行推理。

為了使用Tensorflow服務來提供這些模型,必須將凍結圖導出為SavedModel格式。Tensorflow文檔提供了以SavedModel格式導出訓練模型的示例。

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

復制下列結構中的RestNet模型目錄:

如何提升Tensorflow服務性能

 

Tensorflow Serving期望模型采用數字排序的目錄結構來管理模型版本控制。在這種情況下,目錄1/對應于模型版本1,其中包含模型體系結構saved_model.pb以及模型權重(變量)的快照。

加載并提供SavedModel

以下命令在docker容器中啟動Tensorflow服務模型服務器。為了加載SavedModel,需要將模型的主機目錄掛載到預期的容器目錄中。

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

 

檢查容器日志顯示,ModelServer正在運行,準備在gRPC和HTTP端點上為resnet模型提供推理請求:

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服務性能

 

預測客戶端

Tensorflow Serving將API服務模式定義為協議緩沖區(protobufs)。預測API的gRPC客戶端實現打包為tensorflow_serving.apisPython包。我們還需要tensorflowpython包來實現實用功能。

讓我們安裝依賴項來創建一個簡單的客戶端:

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

 

該ResNet-50 v2模型期望在channels_last(NHWC)格式的數據結構中使用浮點Tensor輸入。因此,使用opencv-python讀取輸入圖像,opencv-python以float32數據類型加載到numpy數組(height x width x channels)中。下面的腳本創建預測客戶端存根,將JPEG圖像數據加載到numpy數組中,轉換為張量原型,提出gRPC預測請求:

#!/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服務性能

 

使用輸入JPEG圖像運行客戶機的輸出如下所示:

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

total time: 2.56152906418s

輸出張量的預測結果為整數值和特征概率

如何提升Tensorflow服務性能

 

對于單個請求,這種預測延遲是不可接受的。然而,這并非完全出乎意料;服務于二進制文件的默認Tensorflow目標是針對最廣泛的硬件范圍,以涵蓋大多數用例。您可能已經從標準的Tensorflow服務容器日志中注意到:

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服務二進制文件在不兼容的CPU平臺上運行,并未進行優化。

構建CPU優化服務二進制

根據Tensorflow文檔,建議從源代碼編譯Tensorflow,并在運行二進制文件的主機平臺的CPU上使用所有可用的優化。Tensorflow構建選項公開了一些標志,以支持構建特定于平臺的CPU指令集:

如何提升Tensorflow服務性能

 

在本例中,我們將使用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服務性能

 

Tensorflow服務開發鏡像使用Bazel作為構建工具。處理器特定CPU指令集的構建目標可以指定如下:

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

如果memory是約束,則可以使用--local_resources=2048,.5,1.0 flag 限制內存密集型構建過程的消耗。

以開發鏡像為基礎構建服務鏡像:

#!/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服務性能

 

ModelServer可以配置tensorflow特定的標志來啟用會話并行性。以下選項配置兩個線程池來并行執行:

intra_op_parallelism_threads

  • 控制用于并行執行單個操作的最大線程數。
  • 用于并行化具有子操作的操作,這些子操作本質上是獨立的。

inter_op_parallelism_threads

  • 控制用于并行執行獨立不同操作的最大線程數。
  • Tensorflow Graph上的操作彼此獨立,因此可以在不同的線程上運行。

兩個選項的默認值都設置為0。這意味著,系統會選擇一個合適的數字,這通常需要每個CPU核心有一個線程可用。

接下來,與之前類似地啟動服務容器,這次使用從源碼構建的docker映像,并使用Tensorflow特定的CPU優化標志:

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服務性能

 

容器日志不應再顯示CPU警告警告。在不更改任何代碼的情況下,運行相同的預測請求會使預測延遲降低約35.8%:

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

total time: 1.64234706879s

提高預測客戶端的速度

服務器端已針對其CPU平臺進行了優化,但超過1秒的預測延遲似乎仍然過高。

加載tensorflow_serving和tensorflow庫的延遲成本很高。每次調用tf.contrib.util.make_tensor_proto也會增加不必要的延遲開銷。

我們實際上并不需要的tensorflow或tensorflow_serving包進行預測的請求。

如前所述,Tensorflow預測API被定義為protobufs。因此,可以通過生成必要的tensorflow和tensorflow_servingprotobuf python存根來替換這兩個外部依賴項。這避免了在客戶端本身上Pull整個Tensorflow庫。

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

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

 

克隆tensorflow/tensorflow和tensorflow/serving存儲庫并將以下protobuf文件復制到客戶端項目中:

如何提升Tensorflow服務性能

 

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

如何提升Tensorflow服務性能

 

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

使用grpcio.tools.protoc以下命令生成gRPC python實現:

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服務性能

 

現在tensorflow_serving可以刪除整個模塊:

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

 

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

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

 

導入Tensorflow庫是為了使用輔助函數make_tensor_proto,該函數用于將 python / numpy對象封裝為TensorProto對象。

因此,我們可以替換以下依賴項和代碼段:

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

 

使用protobuf導入并構建TensorProto對象:

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服務性能

 

完整的python腳本在這里可用(https://gist.github.com/masroorhasan/0e73a7fc7bb2558c65933338d8194130)。運行更新的初始客戶端,該客戶端將預測請求發送到優化的Tensorflow服務:

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

total time: 0.58314920859s

下圖顯示了針對標準,優化的Tensorflow服務和客戶端超過10次運行的預測請求的延遲:

如何提升Tensorflow服務性能

 

從標準Tensorflow服務到優化版本的平均延遲降低了約70.4%。

優化預測吞吐量

Tensorflow服務也可以配置為高吞吐量處理。優化吞吐量通常是為“脫機”批處理完成的,在“脫機”批處理中并不嚴格要求延遲界限。

服務器端批處理

延遲和吞吐量之間的權衡取決于支持的batching 參數。

通過設置--enable_batching和--batching_parameters_file標記來啟用batching。可以按SessionBundleConfig的定義設置批處理參數(https://github.com/tensorflow/serving/blob/d77c9768e33e1207ac8757cff56b9ed9a53f8765/tensorflow_serving/servables/tensorflow/session_bundle_config.proto)。對于僅CPU系統,請考慮設置num_batch_threads可用的核心數。

在服務器端達到全部批處理后,推理請求在內部合并為單個大請求(張量),并在合并的請求上運行一個Tensorflow會話。在單個會話上運行一批請求是CPU/GPU并行性真正能夠發揮作用的地方。

使用Tensorflow服務進行批量處理時需要考慮的一些用例:

  • 使用異步客戶機請求填充服務器端上的batches
  • 通過將模型圖組件放在CPU / GPU上來加速批處理
  • 在從同一服務器提供多個模型時交錯預測請求
  • 強烈建議對“離線”高容量推理處理進行批處理

客戶端批處理

在客戶端進行批處理將多個輸入組合在一起以生成單個請求。

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

...
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服務性能

 

對于一批N個圖像,響應中的輸出張量將具有請求批次中相同數量的輸入的預測結果,在這種情況下N = 2:

如何提升Tensorflow服務性能

 

硬件加速

對于訓練,GPU可以更直觀地利用并行化,因為構建深度神經網絡需要大量計算才能獲得最佳解決方案。

但是,推理并非總是如此。很多時候,當圖執行步驟放在GPU設備上時,CNN將會加速推斷。然而,選擇能夠優化價格性能最佳點的硬件需要嚴格的測試、深入的技術和成本分析。硬件加速并行對于“脫機”推理batch processing更有價值。

分享到:
標簽:Tensorflow
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定