百度飞桨的 Paddle Serving 可以实现服务器端快速部署,最近,随着飞桨更新到 1.7 版本,Paddle Serving 也有了新变化。更新后的 Paddle Serving 有哪些改进?能给用户带来多大程度的生产力提高?本文将带你一睹为快。
古人云:行百里者半九十。相信在深度学习领域中,很多作算法的小伙伴都会对这句话产生共鸣。辛辛苦苦搭建好网络,望眼欲穿得训练调试好模型,等到最后要部署,面对纷繁复杂的实际部署环境时,才发现原来终极大魔王在这里!python
固然这个魔王不会喊打喊杀,但他会给你出难题,情景多是这样的:git
在此紧要关头,是否有什么捷径帮助小伙伴顺利通关呢?这个真的能够有,那就是国内最先开源开放、功能完备的开源深度学习平台飞桨所提供的 Paddle Serving 功能。github
Paddle Serving 是飞桨的服务化部署框架,长期目标就是为人工智能落地的最后一千米提供愈来愈专业、可靠、易用的服务。随着飞桨开源框架推出最新的 1.7 版本,Paddle Serving 的最新版本也闪亮登场。有了它,和魔王的对话情景就要变一变啦!算法
Paddle Serving 真的那么好吗?固然!Paddle Serving 秉承模型即服务(Model As A Service,MAAS)的理念,全面打通并自动化飞桨训练框架与 Paddle Serving 的衔接流程,让用户在使用飞桨成功完成模型训练的那一刻,收获的再也不只是模型,而是同时拥有了该模型的推理服务,使用户可以在几分钟内将模型转化为一个能够在服务器端部署的远程服务。总的来讲,Paddle Serving 具备以下四大特色:json
图 1 Paddle Serving 工做流程示意图后端
千言万语不如一个行动,具体 Paddle Serving 有哪些闪亮操做,我们且往下看!服务器
模型即服务:网络
一行命令启动推理服务并发
所谓模型即服务,是指成功训练出来的模型便可直接被用来部署上线一个推理业务。在这方面飞桨提供了专门的 API 接口用于将训练成功的模型保存成指定的格式,而后无需编写其余代码,直接使用 Paddle Serving 功能中的一条命令便可将这个模型部署到服务器上,造成线上推理业务。具体如何操做,请看下面的示例。app
本例将使用房价预测模型来演示操做方法,下载及解压方式以下所示,下载解压后模型及相关配置文件保存在「uci_housing」文件夹中。
wget --no-check-certificate https://paddle-serving.bj.bcebos.com/uci_housing.tar.gz tar -xzf uci_housing.tar.gz
做为服务端计算机环境中须要提早安装有 Paddle Serving 功能的 paddle_serving_server 模块,若是没有安装,则能够根据硬件环境使用选择其中一行命令安装。
pip install paddle_serving_server //在CPU环境上安装paddle_serving_server pip install paddke_serving_server_gpu //在GPU环境上安装paddle_serving_server
下面见证奇迹的时候到了!请看一键启动模型推理服务:
python -m paddle_serving_server.serve --model uci_housing_model/ --thread 10 --port 9292 --name uci
其中各个参数的含义以下:
当返回以下信息时则表示服务端启动成功。
* Running onhttp://0.0.0.0:9292/(Press CTRL+C to quit)
线上推理服务部署成功后,本例中的 url 格式为「http://127.0.0.1:9292/uci/prediction」。须要使用推理服务的用户能够经过 HTTP 协议将输入数据以以下报文的格式发送给服务端。服务端在计算出结果后,会将推理出的价格返回给用户。
curl -H "Content-Type:application/json" -X POST -d '{"x": [0.0137, -0.1136, 0.2553, -0.0692, 0.0582, -0.0727, -0.1583, -0.0584, 0.6283, 0.4919, 0.1856, 0.0795, -0.0332], "fetch":["price"]}'http://127.0.0.1:9292/uci/prediction
模型的保存方法请参见:
https://github.com/PaddlePaddle/Serving/blob/a4d478d79e120229572bcd56a001688bd7e07b94/doc/SAVE.md
上面的操做方法适用于一些不须要较为复杂的数据预处理过程的普通模型,也就是输入数据能够直接被使用进行推理计算的模型。那么对于一些须要预处理的模型,Paddle Serving 有应对之法么?其实很简单。
通常我们本身搞不定的事情会怎么处理呢?找朋友帮忙呗,一个好汉三个帮嘛!咱们能够为服务端再配个朋友——客户端。让客户端将输入数据预处理为服务端能够读取的形式。
可能有人会问:「多了一个客户端,那操做会不会变得复杂呢?」严格的说,只是多了几个步骤,相信 10 分钟仍是能够搞定的!下面咱们就以 Bert As Service 业务为例,看看如何在十分钟以内将它部署上线!
十分钟构建 Bert As Service
Bert As Service 是 Github 社区比较火爆的代码库,其目标是给定输入一个句子,推理服务能够将句子表示成一个语义向量返回给客户端。Bert 模型是目前 NLP 领域比较热门的模型,在多种公开的 NLP 任务上都取得了很好的效果。若是使用 Bert 模型计算出的语义向量做为其余 NLP 模型的输入,这将对提高模型的表现有很大的帮助。因此能够想象若是你成功部署一台能够对外提供 Bert As Service 服务的服务器,那么你必定会很快成为社区中最靓的仔!。
为了实现这个目标,你仅须要四个步骤就可使用 Paddle Serving 花十分钟部署上线一个这样的服务。
Paddle Serving 支持基于飞桨训练的各类模型,并经过指定模型的输入和输出变量来保存可服务模型。为了便于演示,咱们从飞桨的预训练模型应用工具 PaddleHub 中加载一个已经训练好的 Bert 中文模型「bert_chinese_L-12_H-768_A-12」,并利用以下代码将该模型及相关配置文件保存为能够用于部署服务的格式。其中服务端和客户端的配置分别放在「bert_seq20_model」和「bert_seq20_client」文件夹中。
import paddlehub as hub model_name = "bert_chinese_L-12_H-768_A-12" #获取模型文件 module = hub.Module(model_name) #获取模型的输入输出信息以及program inputs, outputs, program = module.context( trainable=True, max_seq_len=20) #将输入输出的名称与模型中的输入输出变量一一映射 feed_keys = ["input_ids", "position_ids", "segment_ids", "input_mask", ] fetch_keys = ["pooled_output", "sequence_output"] feed_dict = dict(zip(feed_keys, [inputs[x] for x in feed_keys])) fetch_dict = dict(zip(fetch_keys, [outputs[x] for x in fetch_keys])) #保存serving须要的模型与配置文件,参数1是server端模型与配置文件保存的目录,参数2是client端配置文件保存的目录,参数3是输入dict,参数4是输出dict,参数5是模型的program import paddle_serving_client.io as serving_io serving_io.save_model("bert_seq20_model", "bert_seq20_client", feed_dict, fetch_dict, program)
在服务端的计算机上使用以下命令启动服务,其中 gpu_ids 表示 GPU 索引号。
python -m paddle_serving_server_gpu.serve --model bert_seq20_model --thread 10 --port 9292 --gpu_ids 0
当返回以下信息时则表示服务端启动成功。
Server[baidu::paddle_serving::predictor::general_model:: GeneralModelServiceImpl] is serving on port=9292.
Paddle Serving 拥有针对多个经典数据集的数据预处理模块,对于本示例的中文 Bert 语义表示的计算,咱们采用 paddle_serving_app 下的 ChineseBertReader 类对数据做预处理操做,这样开发者能够很容易得到一个原始中文句子所对应的语义向量,用于做为推理服务模型的输入。安装 paddle_serving_app 的方法以下所示。
pip install paddle_serving_app
import os import sys from paddle_serving_client import Client from paddle_serving_app import ChineseBertReader #定义数据预处理reader reader = ChineseBertReader() #指定要获取的预测结果 fetch = ["pooled_output"] #指定server端地址 endpoint_list = ["127.0.0.1:9292"] #定义client类 client = Client() #加载client配置文件 client.load_client_config("bert_seq20_client/serving_client_conf.prototxt") #链接server端 client.connect(endpoint_list) #从标准输入读取数据,发送给server端,并打印结果 for line in sys.stdin: feed_dict = reader.process(line) result = client.predict(feed=feed_dict, fetch=fetch) print(result)
将须要推理中文句子制做成 txt 文件,例如 data.txt。而后运行脚本访问服务器,便可获取推理结果。
cat data.txt | python bert_client.py
Bert As Service 示例相关的脚本请参见:
https://github.com/PaddlePaddle/Serving/tree/develop/python/examples/bert
部署后吞吐性能大幅领先
功能怎么样,数听说了算!吞吐性能是对相同线上服务部署质量的重要评价指标。在 4 块 NVIDIA Tesla V100 上对基于 Paddle Serving 部署的 Bert As Service 进行性能测试,并与基于业界同类最优产品实现的 Bert As Service 作比对。在采用了相同的 batch size 和并发数的条件下,其比对数据结果如图 2 所示,使用 Paddle Serving 部署的服务的吞吐性能大幅领先,batch size 为 128 的请况下,吞吐率超出 58.3%!
图 2 Paddle Serving 性能压力测试吞吐量示意图
此外,以下表所示,飞桨的工程师们还提供了多个其它任务领域的模型推理服务示例以及性能分析的工具。欢迎各位小伙伴根据本身的需求下载使用。
性能可视化工具 Timeline
Paddle Serving 支持性能可视化工具 Timeline,该工具能够查看客户端启动后各个进程的各阶段 timeline。以 Bert As Service 服务为例,Timeline 可视化后的结果如图 3 所示,其中 bert_pre 表明客户端的数据预处理阶段,client_infer 表明客户端完成预测请求的发送和接收结果的阶段,每一个进程的第二行展现的是服务端各个算子的 timeline。
经过 Timeline 用户能够很容易发现预估服务在各个环节的耗时,有的放矢的优化预估流程。针对 Bert 这样的热门模型,在接下来的版本中,Paddle Serving 还会在 paddle_serving_app 中持续开放新的高性能预处理 reader 接口。
图 3 Timeline 性能可视化工具界面效果图
Timeline 的使用方法请参见:
https://github.com/PaddlePaddle/Serving/tree/develop/python/examples/util
Paddle Serving 是面向社区用户的核心诉求进行打造,在易用性方面相比此前的版本有了大幅度提高,用户甚至不须要掌握多深厚的飞桨相关知识便可使用 Paddle Serving 部署模型推理服务,极大的提高了部署效率。Paddle Serving 会在接下来的版本中继续下降用户的使用门槛,提供更多语言类型的客户端,以及 Kubernetes 部署的相关组件,开放更多可以开箱即用的模型,敬请关注!
若是您加入官方 QQ 群,您将赶上大批志同道合的深度学习同窗。官方 QQ 群:703252161。
若是您想详细了解更多飞桨的相关内容,请参阅如下文档。