diff --git a/doc/TRAIN_TO_SERVICE.md b/doc/TRAIN_TO_SERVICE.md
index a64e5e49265fe59d5e26a5aa2d653cd4c1b536fd..6009619317f297a36e980962b4e7ba2d929feff7 100644
--- a/doc/TRAIN_TO_SERVICE.md
+++ b/doc/TRAIN_TO_SERVICE.md
@@ -1,6 +1,8 @@
# 使用PaddleServing快速搭建预测服务
-## 准备环境
+Paddle Serving是Paddle的高性能在线预测服务框架,可以灵活支持大多数模型的部署。本文中将以IMDB评论情感分析任务为例通过9步展示从模型的训练到部署预测服务的全流程。
+
+## Step1:准备环境
Paddle Serving可以部署在Centos和Ubuntu等Linux环境上,在其他系统上或者不希望安装serving模块的环境中仍然可以通过http服务来访问server端的预测服务。
@@ -14,7 +16,7 @@ pip install paddle_serving_client #client端
简单准备后,我们将以IMDB评论情感分析任务为例,展示从模型训练到部署预测服务的流程。示例中的所有代码都可以在Paddle Serving代码库的[IMDB示例](https://github.com/PaddlePaddle/Serving/tree/develop/python/examples/imdb)中找到,示例中使用的数据和词典文件可以通过执行IMDB示例代码中的get_data.sh脚本得到。
-## 训练任务与数据集
+## Step2:确定任务和原始数据格式
IMDB评论情感分析任务是对电影评论的内容进行二分类,判断该评论是属于正面评论还是负面评论。
@@ -26,10 +28,13 @@ saw a trailer for this on another video, and decided to rent when it came out. b
这是一条英文评论样本,样本中使用|作为分隔符,分隔符之前为评论的内容,分隔符之后是样本的标签,0代表负样本,即负面评论,1代表正样本,即正面评论。
-## 数据预处理
+## Step3:定义Reader,划分训练集、测试集
对于原始文本我们需要将它转化为神经网络可以使用的数字id。imdb_reader.py脚本中定义了文本id化的方法,通过词典文件imdb.vocab将单词映射为整形数。
+
+ imdb_reader.py
+
```python
import sys
import os
@@ -95,6 +100,7 @@ class IMDBDataset(dg.MultiSlotDataGenerator):
return data_iter
```
+
映射之后的样本类似于以下的格式:
@@ -104,9 +110,12 @@ class IMDBDataset(dg.MultiSlotDataGenerator):
这样神经网络就可以将转化后的文本信息作为特征值进行训练。
-## 训练和保存模型
+## Step4:定义CNN网络进行训练并保存
+
+接下来我们使用[CNN模型](https://www.paddlepaddle.org.cn/documentation/docs/zh/user_guides/nlp_case/understand_sentiment/README.cn.html#cnn)来进行训练。在nets.py脚本中定义网络结构。
-接下来我们使用[CNN模型](https://www.paddlepaddle.org.cn/documentation/docs/zh/user_guides/nlp_case/understand_sentiment/README.cn.html#cnn)来进行训练。在nets.py脚本中定义网络结构如下。
+
+ nets.py
```python
import sys
@@ -145,7 +154,12 @@ def cnn_net(data,
return avg_cost, acc, prediction
```
-使用训练样本进行训练,训练脚本为local_train.py
+
+
+使用训练样本进行训练,训练脚本为local_train.py。在训练结束后使用paddle_serving_client.io.save_model函数来保存部署预测服务使用的模型文件和配置文件。
+
+
+ local_train.py
```python
import os
@@ -196,7 +210,7 @@ if __name__ == "__main__":
#执行训练
exe = fluid.Executor(fluid.CPUPlace())
exe.run(fluid.default_startup_program())
- epochs = 6
+ epochs = 100
import paddle_serving_client.io as serving_io
@@ -204,21 +218,29 @@ if __name__ == "__main__":
exe.train_from_dataset(
program=fluid.default_main_program(), dataset=dataset, debug=False)
logger.info("TRAIN --> pass: {}".format(i))
- if i == 5:
- #在第6个epoch时使用PaddleServing中的模型保存接口保存出Serving所需的模型和配置文件
+ if i == 99:
+ #在训练结束时使用PaddleServing中的模型保存接口保存出Serving所需的模型和配置文件
serving_io.save_model("{}_model".format(model_name),
"{}_client_conf".format(model_name),
{"words": data}, {"prediction": prediction},
fluid.default_main_program())
```
-执行loca_train.py脚本会进行训练并在训练结束时保存模型和配置文件。保存的文件分为imdb_cnn_client_conf和imdb_cnn_model文件夹,前者包含client端的配置文件,后者包含server端的配置文件和保存的模型文件。
+
-## 部署预测服务
+执行loca_train.py脚本会进行训练并在训练结束时保存模型和配置文件。保存的文件分为imdb_cnn_client_conf和imdb_cnn_model文件夹,前者包含client端的配置文件,后者包含server端的配置文件和保存的模型文件。
+save_model函数的参数列表如下:
+| 参数 | 含义 |
+| -------------------- | ------------------------------------------------------------ |
+| server_model_folder | 保存server端配置文件和模型文件的目录 |
+| client_config_folder | 保存client端配置文件的目录 |
+| feed_var_dict | 用于预测的模型的输入,dict类型,key可以自定义,value为模型中的input variable,每个key对应一个variable,使用预测服务时,输入数据使用key作为输入的名称 |
+| fetch_var_dict | 用于预测的模型的输出,dict类型,key可以自定义,value为模型中的input variable,每个key对应一个variable,使用预测服务时,通过key来获取返回数据 |
+| main_program | 模型的program |
-Paddle Serving框架支持两种预测服务方式,一种是通过RPC进行通信,一种是通过HTTP进行通信,下面将分别介绍这两种方式的部署方法。
+## Step5:部署RPC预测服务
-### RPC预测服务
+Paddle Serving框架支持两种预测服务方式,一种是通过RPC进行通信,一种是通过HTTP进行通信,下面将先介绍RPC预测服务的部署和使用方法,在Step8开始介绍HTTP预测服务的部署和使用。
```shell
python -m paddle_serving_server.serve --model imdb_cnn_model/ --port 9292 #cpu预测服务
@@ -229,8 +251,12 @@ python -m paddle_serving_server_gpu.serve --model imdb_cnn_model/ --port 9292 --
执行完以上命令之一,就完成了IMDB 情感分析任务的RPC预测服务部署。
+## Step6:复用Reader,定义远程RPC客户端
下面我们通过Python代码来访问RPC预测服务,脚本为test_client.py
+
+ test_client.py
+
```python
from paddle_serving_client import Client
from imdb_reader import IMDBDataset
@@ -252,17 +278,21 @@ for line in sys.stdin:
print("{} {}".format(fetch_map["prediction"][1], label[0]))
```
+
+
脚本从标准输入接收数据,并打印出样本预测为1的概率与真实的label。
-使用方式如下:
+## Step7:调用RPC服务,测试模型效果
+
+以上一步实现的客户端为例运行预测服务,使用方式如下:
```shell
cat test_data/part-0 | python test_client.py imdb_lstm_client_conf/serving_client_conf.prototxt imdb.vocab
```
-使用test_data/part-0文件中的2084个样本测试,模型预测的准确率为64.25%。
+使用test_data/part-0文件中的2084个样本进行测试测试,模型预测的准确率为86.90%,。
-### HTTP预测服务
+## Step8:部署HTTP预测服务
使用HTTP预测服务时,client端不需要安装Paddle Serving的任何模块,仅需要能发送HTTP请求即可。当然HTTP的通信方式会相较于RPC的通信方式在通信阶段消耗更多的时间。
@@ -272,6 +302,9 @@ Serving提供了示例代码,通过执行[IMDB示例](https://github.com/Paddl
下面我们来看一下启动HTTP预测服务的脚本text_classify_service.py。
+
+ text_clssify_service.py
+
```python
from paddle_serving_server.web_service import WebService
from imdb_reader import IMDBDataset
@@ -301,6 +334,7 @@ imdb_service.prepare_server(
imdb_service.prepare_dict({"dict_file_path": sys.argv[4]})
imdb_service.run_server()
```
+
启动命令
@@ -310,8 +344,10 @@ python text_classify_service.py imdb_cnn_model/ workdir/ 9292 imdb.vocab
以上命令中参数1为保存的server端模型和配置文件,参数2为工作目录会保存一些预测服务工作时的配置文件,该目录可以不存在但需要指定名称,预测服务会自行创建,参数3为端口号,参数4为词典文件。
+## Step9:明文数据调用预测服务
启动完HTTP预测服务,即可通过一行命令进行预测:
```
curl -H "Content-Type:application/json" -X POST -d '{"words": "i am very sad | 0", "fetch":["prediction"]}' http://127.0.0.1:9292/imdb/prediction
```
+预测流程正常时,会返回预测概率。