首页 > 通讯 > > 正文

什么是TFserving?如何用TFserving部署深度学习模型?

2020-08-26 11:06:02    来源:Python中文社区

1.什么是TFserving

当你训好你的模型,需要提供给外部使用的时候,你就需要把模型部署到线上,并提供合适的接口给外部调用。你可能会考虑一些问题:

用什么来部署

怎么提供api接口

多个模型GPU资源如何分配

线上模型如何更新而服务不中断

目前流行的深度学习框架Tensorflow和Pytorch, Pytorch官方并没有提供合适的线上部署方案;Tensorflow则提供了TFserving方案来部署线上模型推理。另外,Model Server for Apache MXNet 为MXNet模型提供推理服务。

本文为TFServing的使用指南。如果你是pytorch或者MXNet模型,也可以通过ONNX转成TFserving的模型,部署在TFServing上。

那什么是TFserving?

TFserving是Google 2017推出的线上推理服务;采用C/S架构,客户端可通过gRPC和RESTfull API与模型服务进行通信。

TFServing的特点:

支持模型版本控制和回滚:Manager会进行模型的版本的管理

支持并发,实现高吞吐量

开箱即用,并且可定制化

支持多模型服务

支持批处理

支持热更新:Source加载本地模型,通知Manager有新的模型需要加载,Manager检查模型的版本,通知Source创建的Loader进行加载模型

支持分布式模型

2.TFserving安装

强烈建议采用docker方式安装TFserving,安装依赖docker和nvidia-docker(TFserving的gpu需要)

docker 安装

#安装yum-utils工具和device-mapper相关依赖包

yuminstall-yyum-utils\

device-mapper-persistent-data\

lvm2

#添加docker-cestable版本的仓库

yum-config-manager\

--add-repo\

https://download.docker.com/linux/centos/docker-ce.repo

#更新yum缓存文件

yummakecachefast

#查看所有可安装的docker-ce版本

yumlistdocker-ce--showduplicates|sort-r

#安装docker-ce

yuminstalldocker-ce-17.12.1.ce-1.el7.centos

#允许开机启动docker-ce服务

systemctlenabledocker.service

#启动Docker-ce服务

systemctlstartdocker

#运行测试容器hello-world

dockerrun--rmhello-world

nvidia-docker 安装

#安装nvidia-docker2

yuminstall-ynvidia-docker2-2.0.3-1.docker17.12.1.ce

#重启docker服务

servicedockerrestart

安装TFserving

dockerpulltensorflow/serving:latest-gpu

#可以选择其他版本如dockerpulltensorflow/serving:1.14.0-rc0-gpu

注意:docker版本和nvidia-docker要匹配

目前最新的nvidia-docker需要Docker为19.03 可参考官方https://github.com/NVIDIA/nvidia-docker

nvidia-docker2 支持Docker版本低于19.03的其他版本(需>=1.12),现有服务器有18.09,1.17,1.13 https://github.com/NVIDIA/nvidia-docker/wiki/Installation-(version-2.0)

3.TFserving使用说明

3.1 模型转换

TFserving的模型需要转换成TFserving的格式, 不支持通常的checkpoint和pb格式。

TFserving的模型包含一个.pb文件和variables目录(可以为空),导出格式如下:.

├──1

│├──saved_model.pb

│└──variables

├──2

│├──saved_model.pb

│└──variables

不同的深度学习框架的转换路径:

(1)pytorch(.pth)-->onnx(.onnx)-->tensorflow(.pb)-->TFserving

(2)keras(.h5)-->tensorflow(.pb)-->TFserving

(3)tensorflow(.pb)-->TFserving

这里详细介绍下pb转换成TFserving模型

importtensorflowastf

defcreate_graph(pb_file):

"""CreatesagraphfromsavedGraphDeffileandreturnsasaver."""

#Createsgraphfromsavedgraph_def.pb.

withtf.gfile.FastGFile(pb_file,'rb')asf:

graph_def=tf.GraphDef()

graph_def.ParseFromString(f.read())

_=tf.import_graph_def(graph_def,name='')

defpb_to_tfserving(pb_file,export_path,pb_io_name=[],input_node_name='input',output_node_name='output',signature_name='default_tfserving'):

#pb_io_name为pb模型输入和输出的节点名称,

#input_node_name为转化后输入名

#output_node_name为转化后输出名

#signature_name为签名

create_graph(pb_file)

#tensor_name_list=[tensor.namefortensorintf.get_default_graph().as_graph_def().node]

input_name='%s:0'%pb_io_name[0]

output_name='%s:0'%pb_io_name[1]

withtf.Session()assess:

in_tensor=sess.graph.get_tensor_by_name(input_name)

out_tensor=sess.graph.get_tensor_by_name(output_name)

builder=tf.saved_model.builder.SavedModelBuilder(export_path)##export_path导出路径

inputs={input_node_name:tf.saved_model.utils.build_tensor_info(in_tensor)}

outputs={output_node_name:tf.saved_model.utils.build_tensor_info(out_tensor)}

signature=tf.saved_model.signature_def_utils.build_signature_def(

inputs,outputs,method_name=tf.saved_model.signature_constants.PREDICT_METHOD_NAME)

builder.add_meta_graph_and_variables(

sesssess=sess,tags=[tf.saved_model.tag_constants.SERVING],

signature_def_map={signature_name:signature},clear_devices=True)##signature_name为签名,可自定义

builder.save()

pb_model_path='test.pb'

pb_to_tfserving(pb_model_path,'./1',pb_io_name=['input_1_1','output_1'],signature_name='your_model')

3.2 TFserving配置和启动

模型导出后,同一个模型可以导出不同的版本(版本后数字),可以TFserving配置中指定模型和指定版本。TFserving的模型是通过模型名称和签名来唯一定位。TFserving 可以配置多个模型,充分利用GPU资源。

模型配置

#models.config

model_config_list{

config{

name:'your_model'

base_path:'/models/your_model/'

model_platform:'tensorflow'

#model_version_policy{

#specific{

#versions:42

#versions:43

#}

#}

#version_labels{

#key:'stable'

#value:43

#}

#version_labels{

#key:'canary'

#value:43

#}

}

config{

name:"mnist",

base_path:"/models/mnist",

model_platform:"tensorflow",

model_version_policy:{

specific:{

versions:1,

versions:2

}

}

}

#可以通过model_version_policy进行版本的控制

启动服务

#建议把模型和配置文件放在docker外的本地路径,如/home/tfserving/models,通过-v挂载到docker内部

#--model_config_file:指定模型配置文件

#-eNVIDIA_VISIBLE_DEVICES=0:指定GPU

#-p指定端口映射8500为gRpc8501为restfulapi端口

#-t为docker镜像

nvidia-dockerrun-it--privileged-d-eNVIDIA_VISIBLE_DEVICES=0-v/home/tfserving/models:/models-p8500:8500-p8501:8501\

-ttensorflow/serving:latest-gpu\

--model_config_file=/models/models.config

#/home/tfserving/models结构

├──models.config

└──your_model

├──1

│├──saved_model.pb

│└──variables

└──2

├──saved_model.pb

└──variables

#test

curlhttp://192.168.0.3:8501/v1/models/your_model

{

"model_version_status":[

{

"version":"2",

"state":"AVAILABLE",

"status":{

"error_code":"OK",

"error_message":""

}

}

]

}

#其他启动方式

#如果多个模型在不同的目录,可以通过-mount单独加载

nvidia-dockerrun-it--privileged-d-eNVIDIA_VISIBLE_DEVICES=0\

--mounttype=bind,source=/home/tfserving/models/your_model,target=/models/your_model\

--mounttype=bind,source=/home/tfserving/models/your_model/models.config,target=/models/models.config\

-p8510:8500-p8501:8501\

-ttensorflow/serving:latest-gpu\

--model_config_file=/models/models.config

3.3 TFserving服务调用

客户端可以通过gRpc和http方式调用TFserving服务模型,支持多种客户端语言,这里提供python的调用方式; 调用都是通过模型名称和签名来唯一对应一个模型

gRpc调用, gRpc的端口是8500

#

#-*-coding:utf-8-*-

importtensorflowastf

fromtensorflow_serving.apisimportpredict_pb2

fromtensorflow_serving.apisimportprediction_service_pb2_grpc

importgrpc

importtime

importnumpyasnp

importcv2

classYourModel(object):

def__init__(self,socket):

"""

Args:

socket:hostandportofthetfserving,like192.168.0.3:8500

"""

self.socket=socket

start=time.time()

self.request,selfself.stub=self.__get_request()

end=time.time()

print('initializecosttime:'+str(end-start)+'s')

def__get_request(self):

channel=grpc.insecure_channel(self.socket,options=[('grpc.max_send_message_length',1024*1024*1024),

('grpc.max_receive_message_length',1024*1024*1024)])#可设置大小

stub=prediction_service_pb2_grpc.PredictionServiceStub(channel)

request=predict_pb2.PredictRequest()

request.model_spec.name="your_model"#modelname

request.model_spec.signature_name="your_model"#modelsignaturename

returnrequest,stub

defrun(self,image):

"""

Args:

image:theinputimage(rgbformat)

Returns:embeddingisoutputofmodel

"""

img=image[...,::-1]

self.request.inputs['input'].CopyFrom(tf.contrib.util.make_tensor_proto(img))#imagesisinputofmodel

result=self.stub.Predict(self.request,30.0)

returntf.make_ndarray(result.outputs['output'])

defrun_file(self,image_file):

"""

Args:

image_file:theinputimagefile

Returns:

"""

image=cv2.imread(image_file)

image=cv2.cvtColor(image,cv2.COLOR_BGR2RGB)

returnself.run(image)

if__name__=='__main__':

model=YourModel('192.168.0.3:8500')

test_file='./test.jpg'

result=model.run_file(test_file)

print(result)

#[8.014745e-059.999199e-01]

restful api调用: restful端口是8501

importcv2

importrequests

classSelfEncoder(json.JSONEncoder):

defdefault(self,obj):

ifisinstance(obj,np.ndarray):

returnobj.tolist()

elifisinstance(obj,np.floating):

returnfloat(obj)

elifisinstance(obj,bytes):

returnstr(obj,encoding='utf-8');

returnjson.JSONEncoder.default(self,obj)

image_file='/home/tfserving/test.jpg'

image=cv2.imread(image_file)

image=cv2.cvtColor(image,cv2.COLOR_BGR2RGB)

img=image[...,::-1]

input_data={

"signature_name":"your_model",

"instances":img

}

data=json.dumps(input_data,cls=SelfEncoder,indent=None)

result=requests.post("http://192.168.0.3:8501/v1/models/your_model:predict",datadata=data)

eval(result.content)

#{'predictions':[8.01474525e-05,0.999919891]}

5.总结

本文介绍了TFserving部署线上推理服务,从模型的转换,部署启动和调用推理,欢迎交流,希望对你有帮助。我们来回答下开篇提出的问题

用什么来部署:当然是TFserving

怎么提供api接口:TFserving有提供restful api接口,现实部署时会在前面再加一层如flask api

多个模型GPU资源如何分配:TFserving支持部署多模型,通过配置

线上模型如何更新而服务不中断:TFserving支持模型的不同的版本,如your_model中1和2两个版本,当你新增一个3模型时,TFserving会自动判断,自动加载模型3为当前模型,不需要重启

相关热词搜索:

上一篇:openstack环境创建硬盘时失败 Cinder服务状态排错
下一篇:ios14正式版还能更新吗 ios14正式版怎么样好用吗

热点话题

热点推荐

头条