diff --git a/doc/FAQ.md b/doc/FAQ.md index 5571269a25811e8d4badfa1785ff7a1e17e3daac..00630bd67baef14cfcda18e47a4d5cf8596b6cd0 100644 --- a/doc/FAQ.md +++ b/doc/FAQ.md @@ -4,6 +4,35 @@ ## 基础知识 +#### Q: Paddle Serving 、Paddle Inference、PaddleHub Serving三者的区别及联系? + +**A:** paddle serving是远程服务,即发起预测的设备(手机、浏览器、客户端等)与实际预测的硬件不在一起。 paddle inference是一个library,适合嵌入到一个大系统中保证预测效率,paddle serving调用了paddle inference做远程服务。paddlehub serving可以认为是一个示例,都会使用paddle serving作为统一预测服务入口。如果在web端交互,一般是调用远程服务的形式,可以使用paddle serving的web service搭建。 + +#### Q: paddle-serving是否支持Int32支持 + +**A:** 在protobuf定feed_type和fetch_type编号与数据类型对应如下 + +​ 0-int64 + +​ 1-float32 + +​ 2-int32 + +#### Q: paddle-serving是否支持windows和Linux环境下的多线程调用 + +**A:** 客户端可以发起多线程访问调用服务端 + +#### Q: paddle-serving如何修改消息大小限制 + +**A:** 在server端和client但通过FLAGS_max_body_size来扩大数据量限制,单位为字节,默认为64MB + +#### Q: paddle-serving客户端目前支持哪些语言 + +**A:** java c++ python + +#### Q: paddle-serving目前支持哪些协议 + +**A:** http rpc ## 编译问题 @@ -46,7 +75,15 @@ InvalidArgumentError: Device id must be less than GPU count, but received id is: **A:** 目前(0.4.0)仅支持CentOS,具体列表查阅[这里](https://github.com/PaddlePaddle/Serving/blob/develop/doc/DOCKER_IMAGES.md) +#### Q: python编译的GCC版本与serving的版本不匹配 + +**A:**:1)使用[GPU docker](https://github.com/PaddlePaddle/Serving/blob/develop/doc/RUN_IN_DOCKER.md#gpunvidia-docker)解决环境问题 + +​ 2)修改anaconda的虚拟环境下安装的python的gcc版本[参考](https://www.jianshu.com/p/c498b3d86f77) +#### Q: paddle-serving是否支持本地离线安装 + +**A:** 支持离线部署,需要把一些相关的[依赖包](https://github.com/PaddlePaddle/Serving/blob/develop/doc/COMPILE.md)提前准备安装好 ## 预测问题 @@ -105,6 +142,19 @@ client端的日志直接打印到标准输出。 通过在部署服务之前 'export GLOG_v=3'可以输出更为详细的日志信息。 +#### Q: paddle-serving启动成功后,相关的日志在哪里设置 + +**A:** 1)警告是glog组件打印的,告知glog初始化之前日志打印在STDERR + +​ 2)一般采用GLOG_v方式启动服务同时设置日志级别。 + +例如: +``` +GLOG_v=2 python -m paddle_serving_server.serve --model xxx_conf/ --port 9999 +``` + + + #### Q: (GLOG_v=2下)Server端日志一切正常,但Client端始终得不到正确的预测结果 **A:** 可能是配置文件有问题,检查下配置文件(is_load_tensor,fetch_type等有没有问题) diff --git a/python/examples/unet_for_image_seg/unet_benchmark/README.md b/python/examples/unet_for_image_seg/unet_benchmark/README.md new file mode 100644 index 0000000000000000000000000000000000000000..edb2af5864db746dc3368423dd7414575ed7b675 --- /dev/null +++ b/python/examples/unet_for_image_seg/unet_benchmark/README.md @@ -0,0 +1,8 @@ +#UNET_BENCHMARK 使用说明 +## 功能 +* benchmark测试 +## 注意事项 +* 示例图片(可以有多张)请放置于与img_data路径中,支持jpg,jpeg +* 图片张数应该大于等于并发数量 +## TODO +* http benchmark diff --git a/python/examples/unet_for_image_seg/unet_benchmark/img_data/N0060.jpg b/python/examples/unet_for_image_seg/unet_benchmark/img_data/N0060.jpg new file mode 100644 index 0000000000000000000000000000000000000000..feac2837eaa5ae5db414d9769a0c5a830dde268d Binary files /dev/null and b/python/examples/unet_for_image_seg/unet_benchmark/img_data/N0060.jpg differ diff --git a/python/examples/unet_for_image_seg/unet_benchmark/launch_benckmark.sh b/python/examples/unet_for_image_seg/unet_benchmark/launch_benckmark.sh new file mode 100644 index 0000000000000000000000000000000000000000..59c2293e34b11dd2efd088c97a3c8de0dc62cf6f --- /dev/null +++ b/python/examples/unet_for_image_seg/unet_benchmark/launch_benckmark.sh @@ -0,0 +1,3 @@ +#!/bin/bash +python unet_benchmark.py --thread 1 --batch_size 1 --model ../unet_client/serving_client_conf.prototxt +# thread/batch can be modified as you wish diff --git a/python/examples/unet_for_image_seg/unet_benchmark/unet_benchmark.py b/python/examples/unet_for_image_seg/unet_benchmark/unet_benchmark.py new file mode 100644 index 0000000000000000000000000000000000000000..172643e364c5462aeed59ebe5e7b45bee7abf8ef --- /dev/null +++ b/python/examples/unet_for_image_seg/unet_benchmark/unet_benchmark.py @@ -0,0 +1,159 @@ +# -*- coding: utf-8 -*- +# +# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" + unet bench mark script + 20201130 first edition by cg82616424 +""" +from __future__ import unicode_literals, absolute_import +import os +import time +import json +import requests +from paddle_serving_client import Client +from paddle_serving_client.utils import MultiThreadRunner +from paddle_serving_client.utils import benchmark_args, show_latency +from paddle_serving_app.reader import Sequential, File2Image, Resize, Transpose, BGR2RGB, SegPostprocess +args = benchmark_args() + + +def get_img_names(path): + """ + Brief: + get img files(jpg) under this path + if any exception happened return None + Args: + path (string): image file path + Returns: + list: images names under this folder + """ + if not os.path.exists(path): + return None + if not os.path.isdir(path): + return None + list_name = [] + for f_handler in os.listdir(path): + file_path = os.path.join(path, f_handler) + if os.path.isdir(file_path): + continue + else: + if not file_path.endswith(".jpeg") and not file_path.endswith( + ".jpg"): + continue + list_name.append(file_path) + return list_name + + +def preprocess_img(img_list): + """ + Brief: + prepare img data for benchmark + Args: + img_list(list): list for img file path + Returns: + image content binary list after preprocess + """ + preprocess = Sequential([File2Image(), Resize((512, 512))]) + result_list = [] + for img in img_list: + img_tmp = preprocess(img) + result_list.append(img_tmp) + return result_list + + +def benckmark_worker(idx, resource): + """ + Brief: + benchmark single worker for unet + Args: + idx(int): worker idx ,use idx to select backend unet service + resource(dict): unet serving endpoint dict + Returns: + latency + TODO: + http benckmarks + """ + profile_flags = False + latency_flags = False + postprocess = SegPostprocess(2) + if os.getenv("FLAGS_profile_client"): + profile_flags = True + if os.getenv("FLAGS_serving_latency"): + latency_flags = True + latency_list = [] + client_handler = Client() + client_handler.load_client_config(args.model) + client_handler.connect( + [resource["endpoint"][idx % len(resource["endpoint"])]]) + start = time.time() + turns = resource["turns"] + img_list = resource["img_list"] + for i in range(turns): + if args.batch_size >= 1: + l_start = time.time() + feed_batch = [] + b_start = time.time() + for bi in range(args.batch_size): + feed_batch.append({"image": img_list[bi]}) + b_end = time.time() + if profile_flags: + sys.stderr.write( + "PROFILE\tpid:{}\tunt_pre_0:{} unet_pre_1:{}\n".format( + os.getpid(), + int(round(b_start * 1000000)), + int(round(b_end * 1000000)))) + result = client_handler.predict( + feed={"image": img_list[bi]}, fetch=["output"]) + #result["filename"] = "./img_data/N0060.jpg" % (os.getpid(), idx, time.time()) + #postprocess(result) # if you want to measure post process time, you have to uncomment this line + l_end = time.time() + if latency_flags: + latency_list.append(l_end * 1000 - l_start * 1000) + else: + print("unsupport batch size {}".format(args.batch_size)) + end = time.time() + if latency_flags: + return [[end - start], latency_list] + else: + return [[end - start]] + + +if __name__ == '__main__': + """ + usage: + """ + img_file_list = get_img_names("./img_data") + img_content_list = preprocess_img(img_file_list) + multi_thread_runner = MultiThreadRunner() + endpoint_list = ["127.0.0.1:9494"] + turns = 1 + start = time.time() + result = multi_thread_runner.run(benckmark_worker, args.thread, { + "endpoint": endpoint_list, + "turns": turns, + "img_list": img_content_list + }) + end = time.time() + total_cost = end - start + avg_cost = 0 + for i in range(args.thread): + avg_cost += result[0][i] + avg_cost = avg_cost / args.thread + print("total cost: {}s".format(total_cost)) + print("each thread cost: {}s. ".format(avg_cost)) + print("qps: {}samples/s".format(args.batch_size * args.thread * turns / + total_cost)) + if os.getenv("FLAGS_serving_latency"): + show_latency(result[1])