日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

手把手教你使用TF服务将TensorFlow模型部署到生产环境

發(fā)布時間:2025/6/17 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 手把手教你使用TF服务将TensorFlow模型部署到生产环境 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2019獨角獸企業(yè)重金招聘Python工程師標準>>>

介紹

將機器學(xué)習(xí)(ML)模型應(yīng)用于生產(chǎn)環(huán)境已成為一個火熱的的話題,許多框架提供了旨在解決此問題的不同解決方案。為解決這一問題,谷歌發(fā)布了TensorFlow(TF)服務(wù),以期待解決將ML模型部署到生產(chǎn)中的問題。

本文提供了一個關(guān)于服務(wù)于預(yù)先訓(xùn)練的卷積語義分割網(wǎng)絡(luò)的實踐教程。閱讀本文后,你將能夠使用TF服務(wù)來部署和向TF訓(xùn)練的深度CNN發(fā)出請求等操作。另外,本文將概述TF服務(wù)的API及其工作原理。如果你想學(xué)習(xí)本教程并在計算機上運行示例,請完整了解本文。但是,如果你只想了解TensorFlow服務(wù),你可以專注于前兩部分。

TensorFlow服務(wù)庫-概述

首先我們需要花一些時間來了解TF Serving如何處理ML模型的整個生命周期。在這里,我們將介紹TF服務(wù)的主要構(gòu)建塊,本部分的目標是提供TF服務(wù)API的介紹。如需深入了解,請訪問TF服務(wù)文檔頁面。

TensorFlow服務(wù)由一些抽象組成,這些抽象類用于不同任務(wù)的API,其中最重要的是Servable,Loader,Source和Manager,讓我們來看看他們之間是如何互動的:

簡單來說,當TF Serving識別磁盤上的模型時,Source組件就開始工作啦,整個服務(wù)生命周期也算開始了,Source組件負責識別應(yīng)加載的新模型。實際上,它會密切關(guān)注文件系統(tǒng),以確定新模型版本何時到達磁盤。當它看到新版本模型時,它會為該特定版本的模型創(chuàng)建一個Loader。

總之,Loader幾乎了解模型的所有內(nèi)容,包括如何加載以及如何估計模型所需的資源,例如請求的RAM和GPU內(nèi)存。Loader還有一個指向磁盤上模型的指針以及用于加載它的所有必要的元數(shù)據(jù)。但是有一個問題:加載器不允許加載模型。創(chuàng)建Loader后,Source會將其作為Aspired Version發(fā)送給Manager。

收到模型的Aspired Version后,Manager繼續(xù)執(zhí)行服務(wù)過程。這里有兩種可能性,一個是推送第一個模型版本進行部署,在這種情況下,Manager將確保所需的資源可用,完成后,Manager會授予Loader加載模型的權(quán)限;第二是我們推出現(xiàn)有模型的新版本,在這種情況下,管理員必須先咨詢版本策略插件,然后再繼續(xù)操作,版本策略確定如何進行加載新模型版本的過程。

具體來說,在第一種情況下,我們可以確保我們的系統(tǒng)始終可用于傳入客戶的請求。此時,我們同時加載了兩個模型版本,只有在加載完成后,Manager才會卸載舊版本,并且可以安全地在模型之間切換。另一方面,如果我們想通過不使用額外緩沖區(qū)來節(jié)省資源,我們可以選擇保留數(shù)據(jù)。最后,當客戶端請求模型的handle時,管理器返回Servable的handle。

在接下來的部分中,我們將介紹如何使用TF服務(wù)提供卷積神經(jīng)網(wǎng)絡(luò)(CNN)。

導(dǎo)出服務(wù)模型

為TensorFlow構(gòu)建的ML模型提供服務(wù)的第一步是確保它的格式正確,為此,TensorFlow提供了SavedModel類。

SavedModel是TensorFlow模型的通用序列化格式,如果你熟悉TF,則可以使用TensorFlow Saver來保留模型的變量。

TensorFlow Saver提供了將模型的檢查點文件保存到磁盤或從磁盤恢復(fù)的功能。實際上,SavedModel包裝了TensorFlow Saver,它是導(dǎo)出TF模型進行服務(wù)的標準方式。

SavedModel object有一些很好的功能。首先,它允許你將多個元圖保存到單個SavedModel對象,換句話說,它允許我們?yōu)椴煌娜蝿?wù)提供不同的圖表。例如,假設(shè)你剛剛完成了模型的訓(xùn)練。在大多數(shù)情況下,要執(zhí)行推理,你的圖表不需要某些特定于訓(xùn)練的操作。這些操作可能包括優(yōu)化器的變量,學(xué)習(xí)速率調(diào)度張量,額外的預(yù)處理操作等。此外,你可能希望為移動部署提供量化版本的圖形。

在此環(huán)境中,SavedModel允許你使用不同的配置保存圖形。在我們的例子中,我們有三個不同的圖形和相應(yīng)的標簽,如“訓(xùn)練”、“推理”和“移動”。此外,這三個圖形為了提升內(nèi)存效率還共享相同的變量集。

就在不久前,如果我們想在移動設(shè)備上部署TF模型時,我們需要知道輸入和輸出張量的名稱,以便向模型提供數(shù)據(jù)或從模型獲取數(shù)據(jù)。這需要強制程序員在圖的所有張量中搜索他們所需的張量。如果張量沒有正確命名,那么任務(wù)可能非常繁瑣。

為了簡化操作,SavedModel提供對SignatureDefs的支持,SignatureDefs定義了TensorFlow支持的計算的簽名。它確定了計算圖的正確輸入和輸出張量,也就是說使用這些簽名,你可以指定用于輸入和輸出的確切節(jié)點。要使用其內(nèi)置的服務(wù)API,TF Serving要求模型包含一個或多個SignatureDefs。

要創(chuàng)建此類簽名,我們需要提供輸入,輸出和所需方法名稱的定義,輸入和輸出表示從字符串到TensorInfo對象的映射。在這里,我們定義了默認張量,用于向圖表輸入數(shù)據(jù)和從圖表接收數(shù)據(jù)。

目前,有三種服務(wù)API:分類,預(yù)測和回歸。每個簽名定義都與特定的RPC API相匹配,Classification SegnatureDef用于Classify RPC API,Predict SegnatureDef用于Predict RPC API等等依此類推。

對于分類簽名,必須有輸入張量(接收數(shù)據(jù))和兩個可能的輸出張量中的至少一個:類或分數(shù)。Regression SignatureDef只需要一個張量用于輸入,另一個用于輸出。最后,Predict signature允許動態(tài)數(shù)量的輸入和輸出張量。此外,SavedModel支持數(shù)據(jù)存儲,以用于ops初始化依賴于外部文件的情況,它還具有在創(chuàng)建SavedModel之前清除設(shè)備的機制。

現(xiàn)在,讓我們看看我們?nèi)绾卧趯嵺`中做到這一點。

設(shè)置環(huán)境

在開始之前,我們需要從Github克隆此TensorFlow?DeepLab-v3。DeepLab是谷歌最好的語義分割ConvNet,網(wǎng)絡(luò)可以將圖像作為輸入并輸出類似掩模的圖像,該圖像將某些對象與背景分開。

該版本的DeepLab在Pascal VOC分段數(shù)據(jù)集上進行了訓(xùn)練,因此,它可以分割和識別多達20個類。如果你想了解有關(guān)語義分段和DeepLab-v3的更多信息,請查看深入深度卷積語義分段網(wǎng)絡(luò)和Deeplab_V3。

與服務(wù)相關(guān)的所有文件都存在于:./deeplab_v3/serving/。在那里,你會發(fā)現(xiàn)兩個重要的文件:deeplab_saved_model.py和deeplab_client.ipynb。

在進一步研究之前,請務(wù)必下載Deeplab-v3預(yù)訓(xùn)練模型。前往上面的GitHub存儲庫,單擊checkpoints鏈接,你應(yīng)該有一個名為tboard_logs /的文件夾,其中包含16645 /文件夾。

現(xiàn)在,我們需要創(chuàng)建兩個Python虛擬環(huán)境,一個用于Python 3,另一個用于Python 2,請確保安裝必要的依賴項。你可以在serving_requirements.txt和client_requirements.txt文件中找到它們。

你可能很好奇為什么需要兩個Python env,因為我們的模型DeepLab-v3是在Python 3下開發(fā)的,而TensorFlow Serving Python API僅針對Python 2發(fā)布。因此,要導(dǎo)出模型并運行TF服務(wù),我們使用Python 3 env 。

請注意,你可以使用bazel中的Serving API放棄Python 2 env。有關(guān)更多詳細信息,請參閱TF服務(wù)實例。完成這一步后,讓我們從真正重要的事情開始吧。

實例教程

TensorFlow提供了一個易于使用的高級實用程序類使用SavedModel,類名為SavedModelBuilder。SavedModelBuilder類提供了保存多個元圖,關(guān)聯(lián)變量和數(shù)據(jù)的功能。讓我們來看一個如何導(dǎo)出Deep Segmentation CNN模型進行服務(wù)的運行示例。

如上所述,要導(dǎo)出模型,我們使用啦SavedModelBuilder類。它將生成SavedModel協(xié)議緩沖區(qū)文件以及模型的變量和資源。

讓我們剖析一下代碼:

# Create SavedModelBuilder class # defines where the model will be exported export_path_base = FLAGS.export_model_dir export_path = os.path.join(tf.compat.as_bytes(export_path_base),tf.compat.as_bytes(str(FLAGS.model_version))) print('Exporting trained model to', export_path) builder = tf.saved_model.builder.SavedModelBuilder(export_path)

SavedModelBuilder接收(作為輸入)保存模型數(shù)據(jù)的目錄。這里,export_path變量是為了連接export_path_base和model_version。因此,不同的模型版本將保存在export_path_base文件夾內(nèi)的單獨目錄中。

假設(shè)我們在生產(chǎn)中有我們模型的基礎(chǔ)版本,但我們想要部署它的新版本。因為我們已經(jīng)提高了模型的準確性,并希望為我們的客戶提供這個新版本。要導(dǎo)出同一模型的不同版本,我們只需將FLAGS.model_version設(shè)置為更高的整數(shù)值即可。然后將在export_path_base文件夾中創(chuàng)建一個不同的文件夾(保存我們模型的新版本)。

現(xiàn)在,我們需要指定模型的輸入和輸出Tensors。為此,我們使用SignatureDefs,簽名定義了我們要導(dǎo)出的模型類型。它提供了從字符串(邏輯Tensor名稱)到TensorInfo對象的映射。我們的想法是,客戶端可以引用簽名定義的邏輯名稱,而不是引用輸入/輸出的實際張量名稱。

為了服務(wù)語義分段CNN,我們將創(chuàng)建一個預(yù)測簽名。請注意,build_signature_def()函數(shù)采用輸入和輸出張量的映射以及所需的API。

SignatureDef需要指定:輸入,輸出和方法名稱,我們期望輸入有三個值:一圖像,另外兩個張量指定其尺寸(高度和寬度)。對于輸出,我們只定義了一個結(jié)果-分段輸出掩碼。

# Creates the TensorInfo protobuf objects that encapsulates the input/output tensors tensor_info_input = tf.saved_model.utils.build_tensor_info(input_tensor) tensor_info_height = tf.saved_model.utils.build_tensor_info(image_height_tensor) tensor_info_width = tf.saved_model.utils.build_tensor_info(image_width_tensor)# output tensor info tensor_info_output = tf.saved_model.utils.build_tensor_info(predictions_tf)# Defines the DeepLab signatures, uses the TF Predict API # It receives an image and its dimensions and output the segmentation mask prediction_signature = (tf.saved_model.signature_def_utils.build_signature_def(inputs={'images': tensor_info_input, 'height': tensor_info_height, 'width': tensor_info_width},outputs={'segmentation_map': tensor_info_output},method_name=tf.saved_model.signature_constants.PREDICT_METHOD_NAME))

請注意,字符串‘image',‘height',‘width'和‘segmentation_map'不是張量。相反,它們是引用實際張量input_tensor,image_height_tensor和image_width_tensor的邏輯名稱。因此,它們可以是你喜歡的任何唯一字符串。此外,SignatureDefs中的映射與TensorInfo protobuf對象有關(guān),而與實際張量無關(guān)。要創(chuàng)建TensorInfo對象,我們使用實用程序函數(shù):tf.saved_model.utils.build_tensor_info(tensor)。

現(xiàn)在我們調(diào)用add_meta_graph_and_variables()函數(shù)來構(gòu)建SavedModel協(xié)議緩沖區(qū)對象,然后我們運行save()方法,它會將模型的快照保存到包含模型變量和資源的磁盤。

builder.add_meta_graph_and_variables(sess, [tf.saved_model.tag_constants.SERVING],signature_def_map={'predict_images':prediction_signature,})# export the model builder.save(as_text=True) print('Done exporting!')

現(xiàn)在我們可以運行deeplab_saved_model.py來導(dǎo)出我們的模型。

如果一切順利,你將看到文件夾./serving/versions/1,請注意,“1”表示模型的當前版本。在每個版本子目錄中,你將看到以下文件:

·saved_model.pb或saved_model.pbtxt,這是序列化的SavedModel文件。它包括模型的一個或多個圖形定義,以及簽名定義。

·變量,該文件夾包含圖形的序列化變量。

現(xiàn)在,我們已準備好啟動我們的模型服務(wù)器。為此,請運行:

$ tensorflow_model_server --port=9000 --model_name=deeplab --model_base_path=<full/path/to/serving/versions/>

該model_base_path指的是輸出模型保存,另外,我們不在路徑中指定版本文件夾,模型版本控制由TF服務(wù)處理。

生成客戶端請求

客戶端代碼非常簡單,看一下:deeplab_client.ipynb。首先,我們讀取要發(fā)送到服務(wù)器的圖像并將其轉(zhuǎn)換為正確的格式。接下來,我們創(chuàng)建一個gRPC存根,存根允許我們調(diào)用遠程服務(wù)器的方法。為此,我們將實例化prediction_service_pb2模塊的beta_create_PredictionService_stub類。此時,存根保持調(diào)用遠程過程的必要邏輯,就像它們是本地的一樣。

現(xiàn)在,我們需要創(chuàng)建和設(shè)置請求對象。由于我們的服務(wù)器實現(xiàn)了TensorFlow Predict API,因此我們需要解析Predict請求。要發(fā)出Predict請求,首先,我們從predict_pb2模塊中實例化PredictRequest類。我們還需要指定model_spec.name和model_spec.signature_name參數(shù)。該名稱參數(shù)是當我們推出的服務(wù)器定義的“模型名稱”的說法,而signature_name是指分配給邏輯名稱signature_def_map()的參數(shù)add_meta_graph()函數(shù)。

# create the RPC stub channel = implementations.insecure_channel(host, int(port)) stub = prediction_service_pb2.beta_create_PredictionService_stub(channel)# create the request object and set the name and signature_name params request = predict_pb2.PredictRequest() request.model_spec.name = 'deeplab' request.model_spec.signature_name = 'predict_images'# fill in the request object with the necessary data request.inputs['images'].CopyFrom(tf.contrib.util.make_tensor_proto(image.astype(dtype=np.float32), shape=[1, height, width, 3]))request.inputs['height'].CopyFrom(tf.contrib.util.make_tensor_proto(height, shape=[1])) request.inputs['width'].CopyFrom(tf.contrib.util.make_tensor_proto(width, shape=[1]))

接下來,我們必須提供服務(wù)器簽名中定義的輸入數(shù)據(jù)。請記住,在服務(wù)器中,我們定義了一個Predict API來預(yù)期圖像以及兩個標量(圖像的高度和寬度)。為了將輸入數(shù)據(jù)提供給請求對象,TensorFlow提供了實用程序tf.make_tensor_proto(),此方法是從Python/numpy創(chuàng)建的TensorProto對象,我們可以使用它將圖像及其尺寸提供給請求對象。

看起來我們已經(jīng)準備好調(diào)用服務(wù)器了。為此,我們調(diào)用Predict()方法(使用存根)并將請求對象作為參數(shù)傳遞。gRPC支持:同步和異步調(diào)用。因此,如果你在處理請求時想要做一些工作,我們可以調(diào)用Predict.future()而不是Predict()。

# sync requests result_future = stub.Predict(request, 30.)# For async requests # result_future = stub.Predict.future(request, 10.) # Do some work... # result_future = result_future.result()

現(xiàn)在我們可以獲取并享受結(jié)果。


原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。

轉(zhuǎn)載于:https://my.oschina.net/u/1464083/blog/3028461

總結(jié)

以上是生活随笔為你收集整理的手把手教你使用TF服务将TensorFlow模型部署到生产环境的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。