精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

什么是TensorFlow Serving?構建CPU優化服務二進制代碼

電子工程師 ? 來源:lp ? 2019-04-04 17:26 ? 次閱讀

TensorFlow已經發展成為事實上的ML(機器學習)平臺,在業界和研究領域都很流行。對TensorFlow的需求和支持促成了一系列圍繞培訓和服務ML模型的OSS庫、工具和框架。TensorFlow Serving是一個構建在分布式生產環境中、主要為ML模型提供推理服務的項目。

Mux在其基礎設施的幾個部分中使用TensorFlow Serving,我們之前已經討論過使用TensorFlow來實現按標題編碼(per-title-encoding)功能。今天,我們將重點關注通過優化預測服務器和客戶端來改善延遲的技術。模型預測通常是“在線”操作(在關鍵的應用請求路徑上),因此我們的主要優化目標是以盡可能低的延遲處理大量的請求。

首先,讓我們簡要介紹一下TensorFlow Serving。

什么是TensorFlow Serving?

TensorFlow Serving提供了靈活的服務器架構,旨在部署和服務ML模型。一旦模型經過訓練并可以用于預測,TensorFlow Serving需要將模型導出到可服務類(Servable)兼容格式。

Servable是包裝TensorFlow對象的中心抽象。例如,模型可以表示為一個或多個Servable。因此,Servable是客戶端用于執行計算(如推理)的底層對象。Servable的大小很重要,由于較小的模型使用更少的內存、更少的存儲,因此將有更快的加載時間(加載時間更短)。Servable要求模型以SavedModel格式加載,并使用PerdictAPI提供服務。

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

Tensorflow Serving and Docker

讓我們使用標準的TensorFlow Serving獲得基線預測性能延遲指標(未使用CPU優化)。

首先,從TensorFlow Docker hub提取最新的服務映像文件:

dockerpulltensorflow/serving:latest

在這篇文章中,所有的容器都運行在一個4核、15 GB、Ubuntu 16.04主機上。

將TensorFlow模型導出到SavedModel格式

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

為了使用TensorFlow服務這些模型,必須靜態圖導出到SavedModel格式。TensorFlow文檔可查詢以SavedModel格式導出預訓練模型的示例。

TensorFlow還提供了一系列官方和研究模型作為實驗、研究或生產的入門資料

例如,我們將使用深殘余網絡(ResNet)模型,可用于對ImageNet的1000個類的數據集進行分類。下載預訓練ResNet-50 v2模型,特別是channels_last (NHWC)卷積SavedModel,這對于CPU來說通常更好。

在以下結構中復制RestNet模型目錄:

models/1/saved_model.pbvariables/variables.data-00000-of-00001variables.index

TensorFlow Serving按數字排序的目錄結構管理模型版本。在本例中,目錄1/對應于模型版本1,其中包含模型體系結構。saved_model.pb以及模型權重(變量)的快照。

加載和服務SavedModel

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

dockerrun-d-p9000:8500\-v$(pwd)/models:/models/resnet-eMODEL_NAME=resnet\-ttensorflow/serving:latest

檢查容器日志,確定ModelServer正在運行并可以在GRPC和HTTP端點上為resnet模型提供服務:

Itensorflow_serving/core/loader_harness.cc:86]Successfullyloadedservableversion{name:resnetversion:1}Itensorflow_serving/model_servers/server.cc:286]RunninggRPCModelServerat0.0.0.0:8500...Itensorflow_serving/model_servers/server.cc:302]ExportingHTTP/RESTAPIat:localhost:8501...

預測客戶端

TensorFlow將API服務模式定義為協議緩沖器(protobuf)。預測API的gRPC客戶端用例會被打包為tensorflow_serving.apis Python包。考慮到實用功能,我們還需要tensorflow Python包。

讓我們安裝倚賴項(dependencies)創建一個簡單的客戶端:

virtualenv.env&&source.env/bin/activate&&\pipinstallnumpygrpcioopencv-pythontensorflowtensorflow-serving-api

ResNet-50 v2模型要求浮點Tensor輸入應采用Channel_last(NHWC)格式的數據結構。因此,輸入圖像是使用OpenCV-python讀取的,它以32位浮點數據類型加載到numpy數組(高度x寬度x通道)中。下面的腳本創建預測客戶端存根,并將JPEG圖像數據加載到numpy數組中,然后轉換為TensorProto以發出GRPC預測請求:

#!/usr/bin/envpythonfrom__future__importprint_functionimportargparseimportnumpyasnpimporttimett=time.time()importcv2importtensorflowastffromgrpc.betaimportimplementationsfromtensorflow_serving.apisimportpredict_pb2fromtensorflow_serving.apisimportprediction_service_pb2parser=argparse.ArgumentParser(description='incetiongrpcclientflags.')parser.add_argument('--host',default='0.0.0.0',help='inceptionservinghost')parser.add_argument('--port',default='9000',help='inceptionservingport')parser.add_argument('--image',default='',help='pathtoJPEGimagefile')FLAGS=parser.parse_args()defmain():#createpredictionserviceclientstubchannel=implementations.insecure_channel(FLAGS.host,int(FLAGS.port))stub=prediction_service_pb2.beta_create_PredictionService_stub(channel)#createrequestrequest=predict_pb2.PredictRequest()request.model_spec.name='resnet'request.model_spec.signature_name='serving_default'#readimageintonumpyarrayimg=cv2.imread(FLAGS.image).astype(np.float32)#converttotensorprotoandmakerequest#shapeisinNHWC(num_samplesxheightxwidthxchannels)formattensor=tf.contrib.util.make_tensor_proto(img,shape=[1]+list(img.shape))request.inputs['input'].CopyFrom(tensor)resp=stub.Predict(request,30.0)print('totaltime:{}s'.format(time.time()-tt))if__name__=='__main__':main()

使用JPEG圖像作為輸入,運行客戶端的輸出如下所示:

pythontf_serving_client.py--image=images/pupper.jpgtotaltime:2.56152906418s

輸出Tensor的預測結果為一個整數值和各特征的概率。

outputs{key:"classes"value{dtype:DT_INT64tensor_shape{dim{size:1}}int64_val:238}}outputs{key:"probabilities"...

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

Iexternal/org_tensorflow/tensorflow/core/platform/cpu_feature_guard.cc:141]YourCPUsupportsinstructionsthatthisTensorFlowbinarywasnotcompiledtouse:AVX2FMA

這表明TensorFlow二進制程序運行在不兼容的CPU平臺上,而該平臺沒有為其進行優化。

構建CPU優化服務二進制代碼

根據 TensorFlow文獻資料,建議從源代碼編譯TensorFlow,并采用運行二進制文件的主機平臺的CPU提供的所有優化。TensorFlow給出了Build選項標志,以便為特定于平臺的CPU指令集構建二進制代碼:

指令集 標志
AVX -Copt=-mavx
AVX 2 -Copt=-mavx 2
FMA --copt=-mfma
SSE 4.1 -Copt=-msse4.1
SSE 4.2 -Copt=-msse4.2
全部由處理器支持 --copt=-march=native

克隆TensorFlow固定到特定版本。在這種情況下,我們將使用1.13(發表此文時的最新版本):

USER=$1TAG=$2TF_SERVING_VERSION_GIT_BRANCH="r1.13"gitclone--branch="$TF_SERVING_VERSION_GIT_BRANCH"https://github.com/tensorflow/serving

TensorFlow Serving映像使用Bazel作為Build工具。針對特定處理器CPU指令集的生成目標可以用如下方式指定:

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

如果內存有限制,則使用--local_resources=2048,.5,1.0標志。參考TensorFlow與Docker聯合服務和Bazel docs的文獻作為這些構建標志上的資源。

使用開發圖像建立serving image作為服務基類:

#!/bin/bashUSER=$1TAG=$2TF_SERVING_VERSION_GIT_BRANCH="r1.13"gitclone--branch="${TF_SERVING_VERSION_GIT_BRANCH}"https://github.com/tensorflow/servingTF_SERVING_BUILD_OPTIONS="--copt=-mavx--copt=-mavx2--copt=-mfma--copt=-msse4.1--copt=-msse4.2"cdserving&&\dockerbuild--pull-t$USER/tensorflow-serving-devel:$TAG\--build-argTF_SERVING_VERSION_GIT_BRANCH="${TF_SERVING_VERSION_GIT_BRANCH}"\--build-argTF_SERVING_BUILD_OPTIONS="${TF_SERVING_BUILD_OPTIONS}"\-ftensorflow_serving/tools/docker/Dockerfile.devel.cdserving&&\dockerbuild-t$USER/tensorflow-serving:$TAG\--build-argTF_SERVING_BUILD_IMAGE=$USER/tensorflow-serving-devel:$TAG\-ftensorflow_serving/tools/docker/Dockerfile.

ModelServer可以用TensorFlow專用標志配置以啟用會話并行性。以下選項配置兩個線程池并行執行:

intra_op_parallelism_threads

控制用于單個操作并行執行的最大線程數。

用于具有固有非倚賴子操作的并行執行。

inter_op_parallelism_threads

控制獨立的不同操作并行執行的最大線程數。

對TensorFlow Graph的操作彼此獨立,因此可以在不同的線程上運行。

這兩個選項的默認值設置為0。這意味著,系統選擇一個適當的數字,這通常需要每個CPU核心有一個線程可用。但是,對于多核CPU并行性,我們可以手動控制。

接下來,按照與之前類似的方式啟動服務容器,這一次使用從源代碼編譯的docker映像,并使用TensorFlow特定的CPU優化標志:

dockerrun-d-p9000:8500\-v$(pwd)/models:/models/resnet-eMODEL_NAME=resnet\-t$USER/tensorflow-serving:$TAG\--tensorflow_intra_op_parallelism=4\--tensorflow_inter_op_parallelism=4

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

pythontf_serving_client.py--image=images/pupper.jpgtotaltime:1.64234706879s

提高預測客戶端的速度

我們能做得更好嗎?服務器端已經為其CPU平臺進行了優化,但超過1s的預測延遲似乎仍然太高。

問題是,加載tensorflow_serving和tensorflow庫確實會導致這個問題。每次調用tf.contrib.util.make_tensor_proto同時也增加了不必要的延遲開銷。

“等等”,你可能在想。“難道我不需要TensorFlow Python包向TensorFlow Server提出預測請求嗎?”

答案很簡單:確實如此,實際上不需要tensorflow或tensorflow_serving包發出預測請求。

如前所述,TensorFlow預測API被定義為Protobufs。因此,可以通過生成必要的tensorflow和tensorflow_serving protobuf python 存根(stubs)。這就避免了對客戶機本身整個(巨大)TensorFlow庫的調用。

首先,舍棄tensorflow和tensorflow_serving依賴項,添加grpcio-tools包。

pipuninstalltensorflowtensorflow-serving-api&&\pipinstallgrpcio-tools==1.0.0

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

tensorflow/serving/tensorflow_serving/apis/model.prototensorflow_serving/apis/predict.prototensorflow_serving/apis/prediction_service.prototensorflow/tensorflow/tensorflow/core/framework/resource_handle.prototensorflow/core/framework/tensor_shape.prototensorflow/core/framework/tensor.prototensorflow/core/framework/types.proto

將上述原型文件復制到protos/目錄并保存原始路徑:

protos/tensorflow_serving/apis/*.prototensorflow/core/framework/*.proto

為了簡單起見,prediction_service.proto(預測服務)可以簡化為只實現Predict RPC。這避免了引入服務中定義的其他RPC的嵌套依賴關系。這里是簡化后的prediction_service.proto.

使用grpcio.tools.protoc:

PROTOC_OUT=protos/PROTOS=$(find.|grep"\.proto$")forpin$PROTOS;dopython-mgrpc.tools.protoc-I.--python_out=$PROTOC_OUT--grpc_python_out=$PROTOC_OUT$pdone

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

fromtensorflow_serving.apisimportpredict_pb2fromtensorflow_serving.apisimportprediction_service_pb2

中生成的Probufs替換為protos/tensorflow_serving/apis:

fromprotos.tensorflow_serving.apisimportpredict_pb2fromprotos.tensorflow_serving.apisimportprediction_service_pb2

為了使用幫助函數make_tensor_proto,導入了TensorFlow庫,也就是用于包裝python/numpy對象成為TensorProto對象。

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

importtensorflowastf...tensor=tf.contrib.util.make_tensor_proto(features)request.inputs['inputs'].CopyFrom(tensor)

導入Protobuf,構建TensorProto對象:

fromprotos.tensorflow.core.frameworkimporttensor_pb2fromprotos.tensorflow.core.frameworkimporttensor_shape_pb2fromprotos.tensorflow.core.frameworkimporttypes_pb2...#ensureNHWCshapeandbuildtensorprototensor_shape=[1]+list(img.shape)dims=[tensor_shape_pb2.TensorShapeProto.Dim(size=dim)fordimintensor_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)

完整的python腳本請訪問這里。運行更新后的初始客戶端,該客戶端向優化的TensorFlow發出預測請求:

pythontf_inception_grpc_client.py--image=images/pupper.jpgtotaltime:0.58314920859s

下圖顯示了針對標準、優化的TensorFlow和客戶端10次運行的預測請求的延遲:

顯然,從標準TensorFlow到優化版的平均延遲下降了約70.4%。

優化預測吞吐量

TensorFlow Serving也可以配置為高吞吐量處理。對吞吐量的優化通常用于“脫機”批處理,在這些批處理中,不需要有嚴格的延遲閥值。

(1) 服務器端批處理

服務器端批處理由TensorFlow Serving支持開箱即用。.

延遲和吞吐量之間的權衡取決于所支持的批處理參數。TensorFlow批處理最有效地利用硬件加速器承諾(保證)的高吞吐量。

若要啟用批處理,請設置--enable_batching和--batching_parameters_file標志。可以將批處理參數設置為SessionBundleConfig。對于只使用CPU的系統,請考慮設置num_batch_threads可以使用的核心數量。批處理配置方法可訪問這里,使用支持GPU的系統。

當服務器端的批處理請求全部到達時,推理請求在內部合并為單個大請求(Tensor),并在合并請求上運行一個TensorFlow會話。在單個會話上運行批量請求,可以真正利用CPU/GPU并行性。

批處理過程中需要考慮的Tensorflow Serving Batching進程:

在客戶端使用異步請求,以在服務器端進行批處理

在CPU/GPU上加入模型圖組件,加速批處理

在同一服務器服務多個模型時,對預測請求進行交織處理

對于“脫機”大容量推理處理,強烈推薦批處理。

(2) 客戶端批處理

客戶端的批處理是將多個輸入組合在一起,以發出單個請求。

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

...batch=[]forjpeginos.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)fordiminbatch_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)

對N個圖像的批處理,響應(相應)的輸出Tensor對于請求批處理中相同數量的輸入具有預測結果,在這種情況下,N=2(以下是N=2的情況):

outputs{key:"classes"value{dtype:DT_INT64tensor_shape{dim{size:2}}int64_val:238int64_val:121}}...

硬件加速

關于GPU:

對于訓練,GPU可以更直觀地利用并行化,因為構建深層神經網絡需要大量的計算才能得到最優解。

然而,推理的情況并不總是如此。很多時候,當圖形執行步驟放置在GPU設備上時,CNN的推理就會加快。然而,挑選能夠優化性價比的硬件,需要進行嚴格的測試、深入的技術和成本分析。硬件加速并行化對于“脫機”推理批處理(海量卷)更有價值。

在引入GPU處理之前,要考慮業務需求,并對收益(嚴格延遲、高吞吐量)進行徹底的成本(貨幣、操作、技術)分析。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • cpu
    cpu
    +關注

    關注

    68

    文章

    10825

    瀏覽量

    211148
  • 二進制
    +關注

    關注

    2

    文章

    794

    瀏覽量

    41600
  • tensorflow
    +關注

    關注

    13

    文章

    328

    瀏覽量

    60498

原文標題:如何將TensorFlow Serving的性能提高超過70%?

文章出處:【微信號:rgznai100,微信公眾號:rgznai100】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    鴻蒙二進制數組創建

    你data是非unsigned char。你里面的數據就會轉換錯亂,導致二進制的數據無法再轉換成正確的字符串 代碼實例 錯誤的代碼例子: ? //接收
    的頭像 發表于 01-31 15:24 ?1217次閱讀

    如何使用Arduino和LED矩陣構建簡單的二進制時鐘

    在這個初學者項目中,我們通過構建LED矩陣和使用Arduino來創建二進制時鐘。
    的頭像 發表于 07-25 18:51 ?5706次閱讀

    可以使用我們提供的二進制包, 或者使用源代碼, 安裝 TensorFlow

    可以使用我們提供的二進制包, 或者使用源代碼, 安裝 TensorFlow
    發表于 03-30 22:11

    如何丟棄函數的二進制代碼填入SRAM的二進制代碼

    應用程序 : 示例代碼演示了如何丟棄函數的二進制代碼, 然后填入 SRAM 的二進制代碼, 然后調用它 。 BSP版本:M451系列BSP
    發表于 08-23 06:34

    M451如何丟棄函數的二進制代碼填入SRAM的二進制代碼

    應用程序 : 示例代碼演示了如何丟棄函數的二進制代碼, 然后填入 SRAM 的二進制代碼, 然后調用它 。 BSP版本:M451系列BSP
    發表于 08-30 07:35

    二進制

    二進制   二進制與十進制的區別在于數碼的個數和進位規律有很大的區別,顧名思義,二進制的計數規律為逢二進一,是以2為基數的計數體制。10這
    發表于 04-06 23:48 ?8168次閱讀
    <b class='flag-5'>二進制</b>

    二進制編碼和二進制數據

    二進制編碼和二進制數據   二進制編碼是計算機內使用最多的碼制,它只使用兩個基本符號"0"和"1",并且通過由這兩個符號組成的
    發表于 10-13 16:22 ?4760次閱讀

    二進制電平,什么是二進制電平

    二進制電平,什么是二進制電平 在二進制數字通信系統中,每個碼元或每個符號只能是“1”和“0”兩個狀態之一。若將每個碼元可能取的狀態增
    發表于 03-17 16:51 ?2348次閱讀

    二進制加法程序【匯編版】

    二進制加法程序【匯編版】二進制加法程序【匯編版】二進制加法程序【匯編版】二進制加法程序【匯編版】
    發表于 12-29 11:02 ?0次下載

    基于軟件二進制代碼重用技術綜述

    在當前的計算機系統架構和軟件生態環境下,ROP(return-oriented programming)等基于二進制代碼重用的攻擊技術被廣泛用于內存漏洞利用.近年來。網絡空間安全形勢愈加嚴峻。學術界
    發表于 12-26 15:31 ?0次下載
    基于軟件<b class='flag-5'>二進制</b><b class='flag-5'>代碼</b>重用技術綜述

    格雷碼與二進制的轉換

    格雷碼,又叫循環二進制碼或反射二進制碼,格雷碼是我們在工程中常會遇到的一種編碼方式,它的基本的特點就是任意兩個相鄰的代碼只有一位二進制數不同,這點在下面會詳細講解到。格雷碼的基本特點就
    的頭像 發表于 03-02 15:48 ?1.8w次閱讀
    格雷碼與<b class='flag-5'>二進制</b>的轉換

    機器學習模型的最簡單方法之一將TensorFlow Serving與Docker結合起來

    TensorFlow Serving 已發布的 Docker 鏡像旨在竭盡所能來使用 CPU 架構,因此省略了一些優化以最大限度地提高兼容性。如果您沒有看到此消息,則您的
    的頭像 發表于 11-06 11:12 ?9752次閱讀

    二進制代碼相似度比較研究技術匯總

    我們知道編譯生成二進制代碼的影響因素非常的多,同一套源代碼基于不同因素的組合可以生成非常多不同二進制程序。
    的頭像 發表于 10-13 08:59 ?922次閱讀
    <b class='flag-5'>二進制</b><b class='flag-5'>代碼</b>相似度比較研究技術匯總

    構建LED二進制計數器

    電子發燒友網站提供《構建LED二進制計數器.zip》資料免費下載
    發表于 06-12 09:54 ?3次下載
    <b class='flag-5'>構建</b>LED<b class='flag-5'>二進制</b>計數器

    二進制編碼器工作原理 如何選擇二進制編碼器

    二進制編碼器是一種數字電路,它將輸入的二進制代碼轉換為對應的輸出信號。在數字系統中,編碼器用于將數據從一種形式轉換為另一種形式,以便于處理和傳輸。 二進制編碼器工作原理 輸入與輸出關系
    的頭像 發表于 11-06 09:44 ?293次閱讀