From 1314900c7be04a2db407c69996f68483bb2337cc Mon Sep 17 00:00:00 2001 From: MRXLT Date: Mon, 2 Mar 2020 14:45:35 +0800 Subject: [PATCH] updated readme && benchmark --- doc/bert-benchmark-batch-size-1.png | Bin 0 -> 22889 bytes doc/imdb-benchmark-server-16.png | Bin 0 -> 22925 bytes python/examples/bert/README.md | 61 +++++++++++++++++ python/examples/bert/benchmark.py | 4 +- python/examples/bert/benchmark_batch.py | 2 +- .../{test_bert_client.py => bert_client.py} | 35 ++++++---- ...{test_gpu_server.py => bert_gpu_server.py} | 2 + .../bert/{test_server.py => bert_server.py} | 0 python/examples/imdb/README.md | 64 ++---------------- python/examples/util/README.md | 23 +++++++ 10 files changed, 113 insertions(+), 78 deletions(-) create mode 100644 doc/bert-benchmark-batch-size-1.png create mode 100644 doc/imdb-benchmark-server-16.png create mode 100644 python/examples/bert/README.md rename python/examples/bert/{test_bert_client.py => bert_client.py} (83%) rename python/examples/bert/{test_gpu_server.py => bert_gpu_server.py} (96%) rename python/examples/bert/{test_server.py => bert_server.py} (100%) create mode 100644 python/examples/util/README.md diff --git a/doc/bert-benchmark-batch-size-1.png b/doc/bert-benchmark-batch-size-1.png new file mode 100644 index 0000000000000000000000000000000000000000..f870010a4d2209fc62e2a19f9c110076d6d134a2 GIT binary patch literal 22889 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

%(l{L8bq(L<69 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 literal 0 HcmV?d00001 diff --git a/python/examples/bert/README.md b/python/examples/bert/README.md new file mode 100644 index 00000000..b92bf69e --- /dev/null +++ b/python/examples/bert/README.md @@ -0,0 +1,61 @@ +## 语义理解预测服务 + +示例中采用BERT模型进行语义理解预测,将文本表示为向量的形式,可以用来做进一步的分析和预测。 + +### 获取模型 + +示例中采用[Paddlehub](https://github.com/PaddlePaddle/PaddleHub)中的[BERT中文模型](https://www.paddlepaddle.org.cn/hubdetail?name=bert_chinese_L-12_H-768_A-12&en_category=SemanticModel)。 +执行 +``` +python prepare_model.py +``` +生成server端配置文件与模型文件,存放在serving_server_model文件夹 +生成client端配置文件,存放在serving_client_conf文件夹 + +### 启动预测服务 +执行 +``` +python bert_server.py serving_server_model 9292 #启动cpu预测服务 +``` +或者 +``` +python bert_gpu_server.py serving_server_model 9292 0 #在gpu 0上启动gpu预测服务 +``` + +### 执行预测 + +执行 +``` +sh get_data.sh +``` +获取中文样例数据 + +执行 +``` +head data-c.txt | python bert_client.py +``` +将预测样例数据中的前十条样例,并将向量表示打印到标准输出。 + +### Benchmark + +模型:bert_chinese_L-12_H-768_A-12 + +设备:GPU V100 * 1 + +环境:CUDA 9.2,cudnn 7.1.4 + +测试中将样例数据中的1W个样本复制为10W个样本,每个client线程发送线程数分之一个样本,batch size为1,max_seq_len为20,时间单位为秒. + +在client线程数为4时,预测速度可以达到432样本每秒。 +由于单张GPU内部只能串行计算,client线程增多只能减少GPU的空闲时间,因此在线程数达到4之后,线程数增多对预测速度没有提升。 + +| client thread num | prepro | client infer | op0 | op1 | op2 | postpro | total | +| ------------------ | ------ | ------------ | ----- | ------ | ---- | ------- | ------ | +| 1 | 3.05 | 290.54 | 0.37 | 239.15 | 6.43 | 0.71 | 365.63 | +| 4 | 0.85 | 213.66 | 0.091 | 200.39 | 1.62 | 0.2 | 231.45 | +| 8 | 0.42 | 223.12 | 0.043 | 110.99 | 0.8 | 0.098 | 232.05 | +| 12 | 0.32 | 225.26 | 0.029 | 73.87 | 0.53 | 0.078 | 231.45 | +| 16 | 0.23 | 227.26 | 0.022 | 55.61 | 0.4 | 0.056 | 231.9 | + +总耗时变化规律如下: +![bert benchmark](../../../doc/bert-benchmark-batch-size-1.png) diff --git a/python/examples/bert/benchmark.py b/python/examples/bert/benchmark.py index 774956a3..9e8af21c 100644 --- a/python/examples/bert/benchmark.py +++ b/python/examples/bert/benchmark.py @@ -17,7 +17,7 @@ from paddle_serving_client import Client from paddle_serving_client.metric import auc from paddle_serving_client.utils import MultiThreadRunner import time -from test_bert_client import BertService +from bert_client import BertService def predict(thr_id, resource): @@ -55,7 +55,7 @@ if __name__ == '__main__': thread_num = sys.argv[3] resource = {} resource["conf_file"] = conf_file - resource["server_endpoint"] = ["127.0.0.1:9293"] + resource["server_endpoint"] = ["127.0.0.1:9292"] resource["filelist"] = [data_file] resource["thread_num"] = int(thread_num) diff --git a/python/examples/bert/benchmark_batch.py b/python/examples/bert/benchmark_batch.py index 8cf4b3a0..d8d31013 100644 --- a/python/examples/bert/benchmark_batch.py +++ b/python/examples/bert/benchmark_batch.py @@ -17,7 +17,7 @@ from paddle_serving_client import Client from paddle_serving_client.metric import auc from paddle_serving_client.utils import MultiThreadRunner import time -from test_bert_client import BertService +from bert_client import BertService def predict(thr_id, resource, batch_size): diff --git a/python/examples/bert/test_bert_client.py b/python/examples/bert/bert_client.py similarity index 83% rename from python/examples/bert/test_bert_client.py rename to python/examples/bert/bert_client.py index 47b5bf6c..452a1802 100644 --- a/python/examples/bert/test_bert_client.py +++ b/python/examples/bert/bert_client.py @@ -1,9 +1,11 @@ # coding:utf-8 +import os import sys import numpy as np import paddlehub as hub import ujson import random +import time from paddlehub.common.logger import logger import socket from paddle_serving_client import Client @@ -20,29 +22,22 @@ if is_py3: class BertService(): def __init__(self, - profile=False, max_seq_len=128, model_name="bert_uncased_L-12_H-768_A-12", show_ids=False, do_lower_case=True, process_id=0, - retry=3, - load_balance='round_robin'): + retry=3): self.process_id = process_id self.reader_flag = False self.batch_size = 0 self.max_seq_len = max_seq_len - self.profile = profile self.model_name = model_name self.show_ids = show_ids self.do_lower_case = do_lower_case - self.con_list = [] - self.con_index = 0 - self.load_balance = load_balance - self.server_list = [] - self.serving_list = [] - self.feed_var_names = '' self.retry = retry + self.profile = True if ("FLAGS_profile_client" in os.environ and + os.environ["FLAGS_profile_client"]) else False module = hub.Module(name=self.model_name) inputs, outputs, program = module.context( @@ -51,7 +46,6 @@ class BertService(): position_ids = inputs["position_ids"] segment_ids = inputs["segment_ids"] input_mask = inputs["input_mask"] - self.feed_var_names = input_ids.name + ';' + position_ids.name + ';' + segment_ids.name + ';' + input_mask.name self.reader = hub.reader.ClassifyReader( vocab_path=module.get_vocab_path(), dataset=None, @@ -69,6 +63,7 @@ class BertService(): data_generator = self.reader.data_generator( batch_size=self.batch_size, phase='predict', data=text) result = [] + prepro_start = time.time() for run_step, batch in enumerate(data_generator(), start=1): token_list = batch[0][0].reshape(-1).tolist() pos_list = batch[0][1].reshape(-1).tolist() @@ -81,6 +76,11 @@ class BertService(): "segment_ids": sent_list, "input_mask": mask_list } + prepro_end = time.time() + if self.profile: + print("PROFILE\tbert_pre_0:{} bert_pre_1:{}".format( + int(round(prepro_start * 1000000)), + int(round(prepro_end * 1000000)))) fetch_map = self.client.predict(feed=feed, fetch=fetch) return fetch_map @@ -90,6 +90,7 @@ class BertService(): data_generator = self.reader.data_generator( batch_size=self.batch_size, phase='predict', data=text) result = [] + prepro_start = time.time() for run_step, batch in enumerate(data_generator(), start=1): token_list = batch[0][0].reshape(-1).tolist() pos_list = batch[0][1].reshape(-1).tolist() @@ -108,6 +109,11 @@ class BertService(): mask_list[si * self.max_seq_len:(si + 1) * self.max_seq_len] } feed_batch.append(feed) + prepro_end = time.time() + if self.profile: + print("PROFILE\tbert_pre_0:{} bert_pre_1:{}".format( + int(round(prepro_start * 1000000)), + int(round(prepro_end * 1000000)))) fetch_map_batch = self.client.batch_predict( feed_batch=feed_batch, fetch=fetch) return fetch_map_batch @@ -116,11 +122,11 @@ class BertService(): def test(): bc = BertService( - model_name='bert_uncased_L-12_H-768_A-12', + model_name='bert_chinese_L-12_H-768_A-12', max_seq_len=20, show_ids=False, do_lower_case=True) - server_addr = ["127.0.0.1:9293"] + server_addr = ["127.0.0.1:9292"] config_file = './serving_client_conf/serving_client_conf.prototxt' fetch = ["pooled_output"] bc.load_client(config_file, server_addr) @@ -133,8 +139,7 @@ def test(): result = bc.run_batch_general(batch, fetch) batch = [] for r in result: - for e in r["pooled_output"]: - print(e) + print(r) if __name__ == '__main__': diff --git a/python/examples/bert/test_gpu_server.py b/python/examples/bert/bert_gpu_server.py similarity index 96% rename from python/examples/bert/test_gpu_server.py rename to python/examples/bert/bert_gpu_server.py index 54459a12..3fd64c34 100644 --- a/python/examples/bert/test_gpu_server.py +++ b/python/examples/bert/bert_gpu_server.py @@ -36,5 +36,7 @@ server.set_gpuid(1) server.load_model_config(sys.argv[1]) port = int(sys.argv[2]) +gpuid = sys.argv[3] +server.set_gpuid(gpuid) server.prepare_server(workdir="work_dir1", port=port, device="gpu") server.run_server() diff --git a/python/examples/bert/test_server.py b/python/examples/bert/bert_server.py similarity index 100% rename from python/examples/bert/test_server.py rename to python/examples/bert/bert_server.py diff --git a/python/examples/imdb/README.md b/python/examples/imdb/README.md index a4225026..29d72495 100644 --- a/python/examples/imdb/README.md +++ b/python/examples/imdb/README.md @@ -21,46 +21,10 @@ cat test.data | python test_client_batch.py inference.conf 4 > result 模型 :IMDB-CNN -测试中,client共发送2500条测试样本,图中数据为单个线程的耗时,时间单位为秒 - -server thread num :4 - -| client thread num | prepro | client infer | op0 | op1 | op2 | postpro | total | -| ------------------ | ------ | ------------ | ------ | ----- | ------ | ------- | ----- | -| 1 | 0.99 | 27.39 | 0.085 | 19.92 | 0.046 | 0.032 | 29.84 | -| 4 | 0.22 | 7.66 | 0.021 | 4.93 | 0.011 | 0.0082 | 8.28 | -| 8 | 0.1 | 6.66 | 0.01 | 2.42 | 0.0038 | 0.0046 | 6.95 | -| 12 | 0.074 | 6.87 | 0.0069 | 1.61 | 0.0059 | 0.0032 | 7.07 | -| 16 | 0.056 | 7.01 | 0.0053 | 1.23 | 0.0029 | 0.0026 | 7.17 | -| 20 | 0.045 | 7.02 | 0.0042 | 0.97 | 0.0023 | 0.002 | 7.15 | -| 24 | 0.039 | 7.012 | 0.0034 | 0.8 | 0.0019 | 0.0016 | 7.12 | - -server thread num : 8 - -| client thread num | prepro | client infer | op0 | op1 | op2 | postpro | total | -| ------------------ | ------ | ------------ | ------ | ----- | ------ | ------- | ----- | -| 1 | 1.02 | 28.9 | 0.096 | 20.64 | 0.047 | 0.036 | 31.51 | -| 4 | 0.22 | 7.83 | 0.021 | 5.08 | 0.012 | 0.01 | 8.45 | -| 8 | 0.11 | 4.44 | 0.01 | 2.5 | 0.0059 | 0.0051 | 4.73 | -| 12 | 0.074 | 4.11 | 0.0069 | 1.65 | 0.0039 | 0.0029 | 4.31 | -| 16 | 0.057 | 4.2 | 0.0052 | 1.24 | 0.0029 | 0.0024 | 4.35 | -| 20 | 0.046 | 4.05 | 0.0043 | 1.01 | 0.0024 | 0.0021 | 4.18 | -| 24 | 0.038 | 4.02 | 0.0034 | 0.81 | 0.0019 | 0.0015 | 4.13 | - -server thread num : 12 - -| client thread num | prepro | client infer | op0 | op1 | op2 | postpro | total | -| ------------------ | ------ | ------------ | ------ | ----- | ------ | ------- | ----- | -| 1 | 1.02 | 29.47 | 0.098 | 20.95 | 0.048 | 0.038 | 31.96 | -| 4 | 0.21 | 7.36 | 0.022 | 5.01 | 0.011 | 0.0081 | 7.95 | -| 8 | 0.11 | 4.52 | 0.011 | 2.58 | 0.0061 | 0.0051 | 4.83 | -| 12 | 0.072 | 3.25 | 0.0076 | 1.72 | 0.0042 | 0.0038 | 3.45 | -| 16 | 0.059 | 3.93 | 0.0055 | 1.26 | 0.0029 | 0.0023 | 4.1 | -| 20 | 0.047 | 3.79 | 0.0044 | 1.01 | 0.0024 | 0.0021 | 3.92 | -| 24 | 0.041 | 3.76 | 0.0036 | 0.83 | 0.0019 | 0.0017 | 3.87 | - server thread num : 16 +测试中,client共发送2500条测试样本,图中数据为单个线程的耗时,时间单位为秒。可以看出,client端多线程的预测速度相比单线程有明显提升,在16线程时预测速度是单线程的8.7倍。 + | client thread num | prepro | client infer | op0 | op1 | op2 | postpro | total | | ------------------ | ------ | ------------ | ------ | ----- | ------ | ------- | ----- | | 1 | 1.09 | 28.79 | 0.094 | 20.59 | 0.047 | 0.034 | 31.41 | @@ -71,26 +35,6 @@ server thread num : 16 | 20 | 0.049 | 3.77 | 0.0047 | 1.03 | 0.0025 | 0.0022 | 3.91 | | 24 | 0.041 | 3.86 | 0.0039 | 0.85 | 0.002 | 0.0017 | 3.98 | -server thread num : 20 - -| client thread num | prepro | client infer | op0 | op1 | op2 | postpro | total | -| ------------------ | ------ | ------------ | ------ | ----- | ------ | ------- | ----- | -| 1 | 1.03 | 28.42 | 0.085 | 20.47 | 0.046 | 0.037 | 30.98 | -| 4 | 0.22 | 7.94 | 0.022 | 5.33 | 0.012 | 0.011 | 8.53 | -| 8 | 0.11 | 4.54 | 0.01 | 2.58 | 0.006 | 0.0046 | 4.84 | -| 12 | 0.079 | 4.54 | 0.0076 | 1.78 | 0.0042 | 0.0039 | 4.76 | -| 16 | 0.059 | 3.41 | 0.0057 | 1.33 | 0.0032 | 0.0027 | 3.58 | -| 20 | 0.051 | 4.33 | 0.0047 | 1.06 | 0.0025 | 0.0023 | 4.48 | -| 24 | 0.043 | 4.51 | 0.004 | 0.88 | 0.0021 | 0.0018 | 4.63 | - -server thread num :24 +预测总耗时变化规律如下: -| client thread num | prepro | client infer | op0 | op1 | op2 | postpro | total | -| ------------------ | ------ | ------------ | ------ | ---- | ------ | ------- | ----- | -| 1 | 0.93 | 29.28 | 0.099 | 20.5 | 0.048 | 0.028 | 31.61 | -| 4 | 0.22 | 7.72 | 0.023 | 4.98 | 0.011 | 0.0095 | 8.33 | -| 8 | 0.11 | 4.77 | 0.012 | 2.65 | 0.0062 | 0.0049 | 5.09 | -| 12 | 0.081 | 4.22 | 0.0078 | 1.77 | 0.0042 | 0.0033 | 4.44 | -| 16 | 0.062 | 4.21 | 0.0061 | 1.34 | 0.0032 | 0.0026 | 4.39 | -| 20 | 0.5 | 3.58 | 0.005 | 1.07 | 0.0026 | 0.0023 | 3.72 | -| 24 | 0.043 | 4.27 | 0.0042 | 0.89 | 0.0022 | 0.0018 | 4.4 | +![total cost](../../../doc/imdb-benchmark-server-16.png) diff --git a/python/examples/util/README.md b/python/examples/util/README.md new file mode 100644 index 00000000..94dbd563 --- /dev/null +++ b/python/examples/util/README.md @@ -0,0 +1,23 @@ +## Timeline工具使用 + +serving框架中内置了预测服务中各阶段时间打点的功能,通过环境变量来控制是否开启。 +``` +export FLAGS_profile_client=1 #开启client端各阶段时间打点 +export FLAGS_profile_server=1 #开启server端各阶段时间打点 +``` +开启该功能后,client端在预测的过程中会将对应的日志信息打印到标准输出。 + +为了更直观地展现各阶段的耗时,提供脚本对日志文件做进一步的分析处理。 + +使用时先将client的输出保存到文件,以profile为例。 +``` +python show_profile.py profile ${thread_num} +``` +脚本将计算各阶段的耗时,并除以线程数做平均,打印到标准输出。 + +``` +python timeline_trace.py profile trace +``` +脚本将日志中的时间打点信息转换成json格式保存到trace文件,trace文件可以通过chrome浏览器的tracing功能进行可视化。 + +具体操作:打开chrome浏览器,在地址栏输入chrome://tracing/,跳转至tracing页面,点击load按钮,打开保存的trace文件,即可将预测服务的各阶段时间信息可视化。 -- GitLab