Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Serving
提交
2ed3094a
S
Serving
项目概览
PaddlePaddle
/
Serving
大约 1 年 前同步成功
通知
186
Star
833
Fork
253
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
105
列表
看板
标记
里程碑
合并请求
10
Wiki
2
Wiki
分析
仓库
DevOps
项目成员
Pages
S
Serving
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
105
Issue
105
列表
看板
标记
里程碑
合并请求
10
合并请求
10
Pages
分析
分析
仓库分析
DevOps
Wiki
2
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
2ed3094a
编写于
2月 20, 2019
作者:
W
wangguibao
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Update README
Change-Id: Ibe5059be50e111ee80fa966832809dc6269cd617
上级
cddf5e6c
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
338 addition
and
1 deletion
+338
-1
README.md
README.md
+338
-1
未找到文件。
README.md
浏览文件 @
2ed3094a
# Paddle-serving cmake project
[TOC]
# 概述
PaddlePaddle是公司开源的机器学习框架,广泛支持各种深度学习模型的定制化开发;
Paddle cloud是基于PaddlePaddle框架实现的一整套云平台,对外提供全流程的AI开发平台,对内托管集团内各产品线的机器学习云服务。
Paddle serving是Paddle cloud的在线预测部分,与Paddle cloud模型训练环节无缝衔接,对外提供机器学习预测共有云服务,对内为公司各业务线提供统一的模型预测开发框架和云服务。
# Getting Started
## 运行示例
说明:Imagenet图像分类模型,默认采用CPU模式(GPU模式请修改BCLOUD配置项,并用Dockerfile构建运行环境,
[
Docker部署请参考Wiki
](
http://agroup.baidu.com/share/md/044f552e866f4078900be503784e2468
)
)。
Step1:启动Server端:
```
shell
git clone ssh://icode.baidu.com:8235/baidu/paddle-serving/serving ~/my_paddle_serving/baidu/paddle-serving/serving
&&
cd
~/my_paddle_serving/baidu/paddle-serving/serving
&&
bcloud build
&&
./output/bin/image_class &
```
Step2:启动Client端:
```
shell
git clone ssh://icode.baidu.com:8235/baidu/paddle-serving/sdk-cpp ~/my_paddle_serving/baidu/paddle-serving/sdk-cpp
&&
cd
~/my_paddle_serving/baidu/paddle-serving/sdk-cpp
&&
bcloud build
&&
./output/bin/ximage
&&
pkill image_class
```
## 示例说明
### 预测接口定义
```
c++
syntax
=
"proto2"
;
package
baidu
.
paddle_serving
.
predictor
.
image_class
;
option
cc_generic_services
=
true
;
// x-image request相关(批量接口)
message
XImageReqInstance
{
required
bytes
image_binary
=
1
;
required
uint32
image_length
=
2
;
};
message
Request
{
repeated
XImageReqInstance
instances
=
1
;
};
// x-image response相关(批量接口)
message
DensePrediction
{
repeated
float
categories
=
1
;
};
message
ClassResponse
{
repeated
DensePrediction
predictions
=
1
;
};
message
XImageResInstance
{
required
string
response_json
=
1
;
};
message
Response
{
// Each json string is serialized from ClassResponse
repeated
XImageResInstance
predictions
=
1
;
};
// Service/method相关
service
ImageClassifyService
{
rpc
inference
(
Request
)
returns
(
Response
);
rpc
debug
(
Request
)
returns
(
Response
);
};
```
### Server端实现
用户只需定制或配置以下三类信息的实现,即可快速搭建完整的Paddle-Serving预测模块。
#### 接口改造([proto目录](http://icode.baidu.com/repos/baidu/paddle-serving/serving/tree/master:proto/))
Server端需对预测接口作如下修改即可:
```
c++
// 改动1:依赖paddle-serving option接口文件
import
"pds_option.proto"
;
...
service
ClassService
{
rpc
inference
(
Request
)
returns
(
Response
);
rpc
debug
(
Request
)
returns
(
Response
);
// 改动2:打开generate_impl开关(以支持配置驱动)
option
(
pds
.
options
).
generate_impl
=
true
;
};
```
#### 示例配置([conf目录](http://icode.baidu.com/repos/baidu/paddle-serving/serving/tree/master:conf/))
-
gflags配置项
| name | 默认值 | 含义 |
|------|--------|------|
| workflow_path | ./conf | workflow配置目录名 |
|workflow_file|workflow.conf|workflow配置文件名|
|inferservice_path|./conf|service配置目录名|
|inferservice_file|service.conf|service配置文件名|
|logger_path|./conf|日志配置目录名|
|logger_file|log.conf|日志配置文件名|
|resource_path|./conf|资源管理器目录名|
|resource_file|resource.conf|资源管理器文件名|
|reload_interval_s|10|重载线程间隔时间(s)|
-
配置文件实例(Image图像分类demo)
```
shell
# >>> service.conf
[
@Service]
name: ImageClassifyService
@workflow: workflow_image_classification
# >>> workflow.conf
[
@Workflow]
name: workflow_image_classification
path: ./conf
file: imagec_dag.conf
# >>> imagec_dag.conf
workflow_type: Sequence
[
@Node]
name: image_reader_op
type
: ImageReaderOp
[
@Node]
name: image_classify_op
type
: ImageClassifyOp
[
.@Depend]
name: image_reader_op
mode: RO
[
@Node]
name: write_json_op
type
: WriteJsonOp
[
.@Depend]
name: image_classify_op
mode: RO
# >>> resource.conf
model_manager_path: ./conf
model_manager_file: model_toolkit.conf
```
#### 定制Op算子([op目录](http://icode.baidu.com/repos/baidu/paddle-serving/serving/tree/master:op/))
-
预处理算子(ImageReaderOp):从Request中读取图像字节流,通过opencv解码,填充tensor对象并输出到channel;
-
预测调用算子(ImageClassifyOp):从ImageReaderOp的channel获得输入tensor,临时申请输出tensor,调用ModelToolkit进行预测,并将输出tensor写入channel
-
后处理算子(WriteJsonOp):从ImageClassifyop的channel获得输出tensor,将其序列化为json字符串,写入作为rpc的output;
### Client端实现
用户只需定制或配置以下三类信息,即可方便的接入预估请求,并在本地配置多套服务连接:
#### 接口改造([proto目录](http://icode.baidu.com/repos/baidu/paddle-serving/sdk-cpp/tree/master:proto))
Client端接口只需对预测接口作如下修改即可:
```
c++
// 改动1:依赖paddle-serving option接口文件
import
"pds_option.proto"
;
...
service
ImageClassifyService
{
rpc
inference
(
Request
)
returns
(
Response
);
rpc
debug
(
Request
)
returns
(
Response
);
// 改动2:打开generate_stub开关(以支持配置驱动)
option
(
pds
.
options
).
generate_stub
=
true
;
};
```
#### 连接配置([conf目录](http://icode.baidu.com/repos/baidu/paddle-serving/sdk-cpp/tree/master:conf))
```
shell
# predictions.conf
## 默认配置共享
[
DefaultVariantInfo]
Tag : default
[
.Connection]
ConnectTimeoutMicroSec : 200
ReadTimeoutMicroSec : 2000
WriteTimeoutMicroSec : 500
ConnectRetryCount : 2
MaxConnectionPerHost : 100
HedgeRequestTimeoutMicroSec :
-1
HedgeFetchRetryCount : 2
BnsReloadIntervalSeconds : 10
ConnectionType : pooled
[
.NamingInfo]
ClusterFilterStrategy : Default
LoadBalanceStrategy : la
[
.RpcParameter]
# 0-NONE, 1-SNAPPY, 2-GZIP, 3-ZLIB, 4-LZ4
CompressType : 0
Protocol : baidu_std
MaxChannelPerRequest : 3
[
@Predictor]
name : ximage
service_name : baidu.paddle_serving.predictor.image_class.ImageClassifyService
endpoint_router : WeightedRandomRender
[
.WeightedRandomRender]
VariantWeightList : 30|70
# 30% vs 70% pvs
[
.@VariantInfo]
Tag : var1
# 变体版本标识,提供上游辨识
[
..NamingInfo]
Cluster : list://127.0.0.1:8010
[
.@VariantInfo]
Tag : var2
[
..NamingInfo]
Cluster : list://127.0.0.1:8011
```
#### 请求逻辑([demo/ximage.cpp](http://icode.baidu.com/repos/baidu/paddle-serving/sdk-cpp/blob/master:demo/ximage.cpp))
```
c++
// 进程级初始化
assert
(
PredictorAPI
::
instance
().
create
(
"./conf/predictions.conf"
)
==
0
);
// 线程级预测调用:
Request
req
;
// fill request
// ...
Response
res
;
Predictor
*
ximage
=
PredictorAPI
::
instance
().
fetch_predictor
(
"ximage"
);
assert
(
ximage
!=
NULL
);
ximage
->
inference
(
req
,
res
);
// parse response
// ...
assert
(
PredictorAPI
::
instance
().
free_predictor
(
ximage
)
==
0
);
// 进程级销毁
assert
(
PredictorAPI
::
instance
().
destroy
()
==
0
);
```
## 凤巢协议兼容
Paddle Serving由凤巢观星框架发展而来,而之前框架的通信协议是nshead+compack+idl,为方便新老接口的兼容,Paddle Serving的server和client均支持向后兼容:
-
老API访问新Server,为适配老观星客户端数据包格式,新Server需通过mcpack2pb生成能解析idl格式的pb对象,详见:
[
wtitleq server实现
](
http://icode.baidu.com/repos/baidu/paddle-serving/lr-model/tree/master
)
-
新SDK访问老Server,为能够访问老观星server服务,SDK需通过mcpack2pb插件生成基于idl格式的序列化逻辑;详见:
[
wtitleq api实现
](
http://icode.baidu.com/repos/baidu/infinite-inference/as-wtitleq-demo/tree/master
)
。
凤巢广告拆包支持:Paddle Serving的SDK-Cpp为用户提供了简单易用的拆包功能,通过修改proto/conf文件开启:
```
c++
// interface.proto文件
message
PredictorRequest
{
message
AdvRequest
{
// 广告级别字段
repeated
uint32
ideaid
=
1
;
repeated
string
title
=
2
;
}
// query级别字段
required
uint64
sid
=
1
;
required
string
query
=
2
;
// ...
// 广告级别字段
repeated
AdvRequest
advs
=
3
[(
pds
.
pack_on
)
=
true
];
// 改动1:对advs字段进行拆包
}
// ...
service
WtitleqService
{
rpc
...
rpc
...
option
(
pds
.
options
).
package_size
=
10
;
// 改动2:限制单包大小
}
```
[
wtitleq sdk的proto实例
](
http://icode.baidu.com/repos/baidu/infinite-inference/as-wtitleq-demo/blob/master:proto/predictor_api.proto
)
。
```
bash
# predictions.conf文件
[
@Predictor]
# ...
[
.@VariantInfo]
#...
[
..RpcParameter]
Protocol : itp
# 改动3:修改rpc请求参数为itp协议
```
[
wtitleq sdk的conf实例
](
http://icode.baidu.com/repos/baidu/infinite-inference/as-wtitleq-demo/blob/master:conf/predictors.conf
)
。
# 框架简介
![
图片
](
http://agroup-bos.cdn.bcebos.com/63a5076471e96a08124b89101e12c1a0ec7b642a
)
-
基础框架:屏蔽一个RPC服务所需的所有元素,让用户只关注自己的业务算子的开发;
-
业务框架:基于Protobuf定制请求接口,基于有限DAG定制业务逻辑,并行化调度;
-
模型框架:CPU/FPGA/GPU等硬件异构,多模型间异步优先级调度,新引擎灵活扩展,配置化驱动;
-
用户接口:搭建服务=定义proto文件+实现/复用Op+撰写配置,支持sdk/http请求;
## 名词解释
-
预测引擎:对PaddlePaddle/Abacus/Tensorflow等各种推理计算Lib的封装,屏蔽预测模型动态Reload细节,对上层暴露统一的预测接口;
-
预测模型:由离线训练框架生成、在线预测引擎加载的数据文件或目录,以PaddleFluid模型为例,通常包括拓扑文件和参数文件;
-
Op 算子:Paddle-serving对在线(预处理/后处理等)业务逻辑的最小粒度封装,框架提供OpWithChannel和OpWithChannelAndConf这两种常用的Op基类;框架默认实现通用Op算子;
-
Node:由某个Op算子类结合参数配置组成的Op算子实例,也是Workflow中的一个执行单元;
-
DAG/Workflow:由若干个相互依赖的Node组成,每个Node均可通过特定接口获得Request对象,节点Op通过依赖关系获得其前置Op的输出对象,最后一个Node的输出默认就是Response对象;
-
Service:对一次pv的请求封装,可配置若干条Workflow,彼此之间复用当前PV的Request对象,然后各自并行/串行执行,最后将Response写入对应的输出slot中;一个Paddle-serving进程可配置多套Service接口,上游根据ServiceName决定当前访问的Service接口。
![
图片
](
http://agroup-bos.cdn.bcebos.com/2e5e3cdcc9426d16e2090e64e7d33098ae5ad826
)
## 主要功能
Paddle serving框架为策略工程师提供以下三层面的功能性扩展:
### 模型
-
预测引擎:集成PaddlePaddle、Abacus、Tensorrt、Anakin、Tensorflow等常用机器学习框架的预测Lib;
-
模型种类:支持PaddlePaddle(V1、V2、Fluid)、TensorrtUFF、Anakin、Tensorflow、Caffe等常见模型格式;
-
用户接口:支持模型加载、重载的配置化驱动,不同种类模型的预测接口完全一致;
-
模型调度:支持基于异步线程模型的多模型预估调度,实现异构资源的优先级调度;
### 业务
-
预测流程:通过有限DAG图描述一次预测从Request到Response的业务流程,节点Node是一个最小逻辑单元——OP;
-
预测逻辑:框架封装常用预处理、预测计算、后处理等常用OP,用户通过自定义OP算子实现特化处理逻辑;
### 服务
-
RPC:底层通过Baidu-rpc封装网络交互,Server端可配置化启动多个独立Service,框架会搜集Service粒度的详细业务指标,并按照BVar接口对接到Noah等监控平台;
-
SDK:基于Baidu-rpc的client进行封装,提供多下游连接管理、可扩展路由策略、可定制参数实验、自动分包等机制,支持同步、半同步、纯异步等交互模式,以及多种兼容协议,所有连接策略均通过配置驱动
# 平台简介
![
图片
](
http://agroup-bos.cdn.bcebos.com/42a0e34a7c6b36976e3932639209fd823d8f25e0
)
-
[
运维API
](
http://agroup.baidu.com/share/md/e582f543fb574e9b92445286955a976d
)
-
[
预测API
](
http://agroup.baidu.com/share/md/eb91a51739514319844ceccdb331564c
)
## 名词解释
-
用户(User):云平台注册用户,可基于平台Dashboard对账户下的端点信息进行增、删、查、改;
-
端点(Endpoit):对一个预测需求的逻辑抽象,通常包含一到多个服务变体,以方便多版本模型管理;
-
变体(Variant):一套同质化的Paddle-serving集群服务,每个实例起一个Paddle-serving进程;
-
实验(A/B Test):支持变体实验和参数化实验两种模式,变体实验根据Endpoint所属变体流量百分比实现流量随机抽样;参数化实验通过对pv绑定实验参数、由Paddle-serving进程解析参数、选择不同的代码分支进行实验;
## 主要功能
在公有云落地场景为Infinite(天衍)云平台,主要为策略工程师提供以下三方面的全流程托管:
-
统一接入代理:提供代理服务,通过zk和云平台实时同步元信息,支持多模型版本管理和A/B测试路由策略,提供统一入口和标准预测API;
-
自动化部署:对接K8S/Opera等常见PaaS部署平台,支持服务的一键部署、回滚、下线等运维操作,支持endpoint/variant/model等维度的资源管理;
-
可视化运维:对接console、notebook、dashboard等前端工具和页面,满足可视化运维需求;
# 设计文档
-
[
总体设计文档
](
http://agroup.baidu.com/paddleserving/view/office/895070
)
-
[
框架详设文档
](
http://agroup.baidu.com:8964/static/a3/e40876e464ba08ae5de14aa7710cf326456751.pdf?filename=PaddleServing%E6%9C%8D%E5%8A%A1%E6%A1%86%E6%9E%B6%E8%AF%A6%E7%BB%86%E8%AE%BE%E8%AE%A1%E6%96%87%E6%A1%A3v0_1.pdf
)
-
[
平台详设文档
](
http://agroup.baidu.com/share/office/042a0941579e49adb8c255c8b5e92d51
)
# FAQ
1.
如何修改端口配置?
-
使用该框架搭建的服务需要申请一个端口,可以通过以下方式修改端口号:
-
如果在inferservice_file里指定了port:xxx,那么就去申请该端口号;
-
否则,如果在gflags.conf里指定了--port:xxx,那就去申请该端口号;
-
否则,使用程序里指定的默认端口号:8010。
2.
如何在部署的时候配置动态端口?
-
如果使用FCCI部署协议(凤巢检索端内部的部署协议),需要(1)通过inferservice_file指定端口号;(2)修改
[
Rakefile.opera
](
http://wiki.baidu.com/pages/viewpage.action?pageId=399979183#id-%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E5%86%99production-%E7%BC%96%E5%86%99Rakefile
)
的dynamic_port_config配置
-
`@dynamic_port_config为动态端口配置,向Opera申请名为:name的动态端口,其端口号会被写到:conf文件中的:target配置项。`
例子如下:
```
@dynamic_port_config = [
{:name => 'main', :conf => 'framework/service.conf', :target => 'port'}, // 部署时自动向Opera申请端口,服务将会监听这个端口
{:name => 'main', :conf => 'predictor_valid.conf', :target => 'port'}, // valid工具向这个端口发送测试请求,确保服务已正常启动
]
```
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录