``."""
+ return '\n' + text + '\n'
+
+ def table(self, header, body):
+ """Rendering table element. Wrap header and body in it.
+
+ :param header: header part of the table.
+ :param body: body part of the table.
+ """
+ table = '\n.. list-table::\n'
+ if header and not header.isspace():
+ table = (table + self.indent + ':header-rows: 1\n\n' +
+ self._indent_block(header) + '\n')
+ else:
+ table = table + '\n'
+ table = table + self._indent_block(body) + '\n\n'
+ return table
+
+ def table_row(self, content):
+ """Rendering a table row. Like ``
``.
+
+ :param content: content of current table row.
+ """
+ contents = content.splitlines()
+ if not contents:
+ return ''
+ clist = ['* ' + contents[0]]
+ if len(contents) > 1:
+ for c in contents[1:]:
+ clist.append(' ' + c)
+ return '\n'.join(clist) + '\n'
+
+ def table_cell(self, content, **flags):
+ """Rendering a table cell. Like ```` `` | ``.
+
+ :param content: content of current table cell.
+ :param header: whether this is header or not.
+ :param align: align of current table cell.
+ """
+ return '- ' + content + '\n'
+
+ def double_emphasis(self, text):
+ """Rendering **strong** text.
+
+ :param text: text content for emphasis.
+ """
+ return '\ **{}**\ '.format(text)
+
+ def emphasis(self, text):
+ """Rendering *emphasis* text.
+
+ :param text: text content for emphasis.
+ """
+ return '\ *{}*\ '.format(text)
+
+ def codespan(self, text):
+ """Rendering inline `code` text.
+
+ :param text: text content for inline code.
+ """
+ if '``' not in text:
+ return '\ ``{}``\ '.format(text)
+ else:
+ # actually, docutils split spaces in literal
+ return self._raw_html(''
+ '{}'
+ ' '.format(text.replace('`', '`')))
+
+ def linebreak(self):
+ """Rendering line break like `` ``."""
+ if self.options.get('use_xhtml'):
+ return self._raw_html(' ') + '\n'
+ return self._raw_html(' ') + '\n'
+
+ def strikethrough(self, text):
+ """Rendering ~~strikethrough~~ text.
+
+ :param text: text content for strikethrough.
+ """
+ return self._raw_html('{}'.format(text))
+
+ def text(self, text):
+ """Rendering unformatted text.
+
+ :param text: text content.
+ """
+ return text
+
+ def autolink(self, link, is_email=False):
+ """Rendering a given link or email address.
+
+ :param link: link content or email address.
+ :param is_email: whether this is an email or not.
+ """
+ return link
+
+ def link(self, link, title, text):
+ """Rendering a given link with content and title.
+
+ :param link: href link for ```` tag.
+ :param title: title content for `title` attribute.
+ :param text: text content for description.
+ """
+ if self.anonymous_references:
+ underscore = '__'
+ else:
+ underscore = '_'
+ if title:
+ return self._raw_html(
+ '{text}'.format(
+ link=link, title=title, text=text))
+ if not self.parse_relative_links:
+ return '\ `{text} <{target}>`{underscore}\ '.format(
+ target=link, text=text, underscore=underscore)
+ else:
+ url_info = urlparse(link)
+ if url_info.scheme:
+ return '\ `{text} <{target}>`{underscore}\ '.format(
+ target=link, text=text, underscore=underscore)
+ else:
+ link_type = 'doc'
+ anchor = url_info.fragment
+ if url_info.fragment:
+ if url_info.path:
+ # Can't link to anchors via doc directive.
+ anchor = ''
+ else:
+ # Example: [text](#anchor)
+ link_type = 'ref'
+ doc_link = '{doc_name}{anchor}'.format(
+ # splittext approach works whether or not path is set. It
+ # will return an empty string if unset, which leads to
+ # anchor only ref.
+ doc_name=os.path.splitext(url_info.path)[0],
+ anchor=anchor)
+ return '\ :{link_type}:`{text} <{doc_link}>`\ '.format(
+ link_type=link_type, doc_link=doc_link, text=text)
+
+ def image(self, src, title, text):
+ """Rendering a image with title and text.
+
+ :param src: source link of the image.
+ :param title: title text of the image.
+ :param text: alt text of the image.
+ """
+ # rst does not support title option
+ # and I couldn't find title attribute in HTML standard
+ return '\n'.join([
+ '',
+ '.. image:: {}'.format(src),
+ ' :target: {}'.format(src),
+ ' :alt: {}'.format(text),
+ '',
+ ])
+
+ def inline_html(self, html):
+ """Rendering span level pure html content.
+
+ :param html: text content of the html snippet.
+ """
+ return self._raw_html(html)
+
+ def newline(self):
+ """Rendering newline element."""
+ return ''
+
+ def footnote_ref(self, key, index):
+ """Rendering the ref anchor of a footnote.
+
+ :param key: identity key for the footnote.
+ :param index: the index count of current footnote.
+ """
+ return '\ [#fn-{}]_\ '.format(key)
+
+ def footnote_item(self, key, text):
+ """Rendering a footnote item.
+
+ :param key: identity key for the footnote.
+ :param text: text content of the footnote.
+ """
+ return '.. [#fn-{0}] {1}\n'.format(key, text.strip())
+
+ def footnotes(self, text):
+ """Wrapper for all footnotes.
+
+ :param text: contents of all footnotes.
+ """
+ if text:
+ return '\n\n' + text
+ else:
+ return ''
+
+ """Below outputs are for rst."""
+
+ def image_link(self, url, target, alt):
+ """image_link"""
+ return '\n'.join([
+ '',
+ '.. image:: {}'.format(url),
+ ' :target: {}'.format(target),
+ ' :alt: {}'.format(alt),
+ '',
+ ])
+
+ def rest_role(self, text):
+ """rest_role"""
+ return text
+
+ def rest_link(self, text):
+ """rest_link"""
+ return text
+
+ def inline_math(self, math):
+ """Extension of recommonmark"""
+ return re.sub(r'\$(.*?)\$',
+ lambda x: '\ :math:`{}`\ '.format(x.group(1)), math)
+
+ def eol_literal_marker(self, marker):
+ """Extension of recommonmark"""
+ return marker
+
+ def directive(self, text):
+ """directive"""
+ return '\n' + text + '\n'
+
+ def rest_code_block(self):
+ """rest_code_block"""
+ return '\n\n'
+
+
+class M2R(mistune.Markdown):
+ """M2R"""
+
+ def __init__(self,
+ renderer=None,
+ inline=RestInlineLexer,
+ block=RestBlockLexer,
+ **kwargs):
+ if renderer is None:
+ renderer = RestRenderer(**kwargs)
+ super(M2R, self).__init__(
+ renderer, inline=inline, block=block, **kwargs)
+
+ def parse(self, text):
+ """parse"""
+ output = super(M2R, self).parse(text)
+ return self.post_process(output)
+
+ def output_directive(self):
+ """output_directive"""
+ return self.renderer.directive(self.token['text'])
+
+ def output_rest_code_block(self):
+ """output_rest_code_block"""
+ return self.renderer.rest_code_block()
+
+ def post_process(self, text):
+ """post_process"""
+ output = (text.replace('\\ \n', '\n').replace('\n\\ ', '\n')
+ .replace(' \\ ', ' ').replace('\\ ', ' ')
+ .replace('\\ .', '.'))
+ if self.renderer._include_raw_html:
+ return prolog + output
+ else:
+ return output
+
+
+class M2RParser(rst.Parser, object):
+ """M2RParser"""
+ # Explicitly tell supported formats to sphinx
+ supported = ('markdown', 'md', 'mkd')
+
+ def parse(self, inputstrings, document):
+ """parse"""
+ if isinstance(inputstrings, statemachine.StringList):
+ inputstring = '\n'.join(inputstrings)
+ else:
+ inputstring = inputstrings
+ config = document.settings.env.config
+ converter = M2R(no_underscore_emphasis=config.no_underscore_emphasis,
+ parse_relative_links=config.m2r_parse_relative_links,
+ anonymous_references=config.m2r_anonymous_references,
+ disable_inline_math=config.m2r_disable_inline_math)
+ super(M2RParser, self).parse(converter(inputstring), document)
+
+
+class MdInclude(rst.Directive):
+ """Directive class to include markdown in sphinx.
+
+ Load a file and convert it to rst and insert as a node. Currently
+ directive-specific options are not implemented.
+ """
+ required_arguments = 1
+ optional_arguments = 0
+ option_spec = {
+ 'start-line': int,
+ 'end-line': int,
+ }
+
+ def run(self):
+ """Most of this method is from ``docutils.parser.rst.Directive``.
+
+ docutils version: 0.12
+ """
+ if not self.state.document.settings.file_insertion_enabled:
+ raise self.warning('"%s" directive disabled.' % self.name)
+ source = self.state_machine.input_lines.source(
+ self.lineno - self.state_machine.input_offset - 1)
+ source_dir = os.path.dirname(os.path.abspath(source))
+ path = rst.directives.path(self.arguments[0])
+ path = os.path.normpath(os.path.join(source_dir, path))
+ path = utils.relative_path(None, path)
+ path = nodes.reprunicode(path)
+
+ # get options (currently not use directive-specific options)
+ encoding = self.options.get('encoding',
+ self.state.document.settings.input_encoding)
+ e_handler = self.state.document.settings.input_encoding_error_handler
+ tab_width = self.options.get('tab-width',
+ self.state.document.settings.tab_width)
+
+ # open the including file
+ try:
+ self.state.document.settings.record_dependencies.add(path)
+ include_file = io.FileInput(
+ source_path=path, encoding=encoding, error_handler=e_handler)
+ except UnicodeEncodeError as error:
+ raise self.severe('Problems with "%s" directive path:\n'
+ 'Cannot encode input file path "%s" '
+ '(wrong locale?).' %
+ (self.name, SafeString(path)))
+ except IOError as error:
+ raise self.severe('Problems with "%s" directive path:\n%s.' %
+ (self.name, ErrorString(error)))
+
+ # read from the file
+ startline = self.options.get('start-line', None)
+ endline = self.options.get('end-line', None)
+ try:
+ if startline or (endline is not None):
+ lines = include_file.readlines()
+ rawtext = ''.join(lines[startline:endline])
+ else:
+ rawtext = include_file.read()
+ except UnicodeError as error:
+ raise self.severe('Problem with "%s" directive:\n%s' %
+ (self.name, ErrorString(error)))
+
+ config = self.state.document.settings.env.config
+ converter = M2R(no_underscore_emphasis=config.no_underscore_emphasis,
+ parse_relative_links=config.m2r_parse_relative_links,
+ anonymous_references=config.m2r_anonymous_references,
+ disable_inline_math=config.m2r_disable_inline_math)
+ include_lines = statemachine.string2lines(
+ converter(rawtext), tab_width, convert_whitespace=True)
+ self.state_machine.insert_input(include_lines, path)
+ return []
+
+
+def setup(app):
+ """When used for sphinx extension."""
+ global _is_sphinx
+ _is_sphinx = True
+ app.add_config_value('no_underscore_emphasis', False, 'env')
+ app.add_config_value('m2r_parse_relative_links', False, 'env')
+ app.add_config_value('m2r_anonymous_references', False, 'env')
+ app.add_config_value('m2r_disable_inline_math', False, 'env')
+ app.add_source_parser('.md', M2RParser)
+ app.add_directive('mdinclude', MdInclude)
+ metadata = dict(
+ version=__version__,
+ parallel_read_safe=True,
+ parallel_write_safe=True, )
+ return metadata
+
+
+def convert(text, **kwargs):
+ """convert"""
+ return M2R(**kwargs)(text)
+
+
+def parse_from_file(file, encoding='utf-8', **kwargs):
+ """parse_from_file"""
+ if not os.path.exists(file):
+ raise OSError('No such file exists: {}'.format(file))
+ with _open(file, encoding=encoding) as f:
+ src = f.read()
+ output = convert(src, **kwargs)
+ return output
+
+
+def save_to_file(file, src, encoding='utf-8', **kwargs):
+ """save_to_file"""
+ target = os.path.splitext(file)[0] + '.rst'
+ if not options.overwrite and os.path.exists(target):
+ confirm = input('{} already exists. overwrite it? [y/n]: '.format(
+ target))
+ if confirm.upper() not in ('Y', 'YES'):
+ print('skip {}'.format(file))
+ return
+ with _open(target, 'w', encoding=encoding) as f:
+ f.write(src)
+
+
+def main():
+ """main"""
+ parse_options() # parse cli options
+ if not options.input_file:
+ parser.print_help()
+ parser.exit(0)
+ for file in options.input_file:
+ output = parse_from_file(file)
+ if options.dry_run:
+ print(output)
+ else:
+ save_to_file(file, output)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/doc/requirements.txt b/doc/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1560ebc5f9d74fbae773ac5bc45c5b42b044287a
--- /dev/null
+++ b/doc/requirements.txt
@@ -0,0 +1,4 @@
+sphinx==2.1.0
+mistune
+sphinx_rtd_theme
+paddlepaddle>=1.6
diff --git a/go/client_app/imdb_client.go b/go/client_app/imdb_client.go
index 079ddbbda50ce159b29b9835f947a47ce7d47791..aef823ed2c5209217d4f60f93d19006e67dca35d 100644
--- a/go/client_app/imdb_client.go
+++ b/go/client_app/imdb_client.go
@@ -28,7 +28,7 @@ func main() {
var config_file_path string
config_file_path = os.Args[1]
handle := serving_client.LoadModelConfig(config_file_path)
- handle = serving_client.Connect("127.0.0.1", "9393", handle)
+ handle = serving_client.Connect("127.0.0.1", "9292", handle)
test_file_path := os.Args[2]
fi, err := os.Open(test_file_path)
diff --git a/python/examples/imdb/benchmark_batch.py b/python/examples/imdb/benchmark_batch.py
index d36704a7631e963fd51220aa3c3d9a350515ebfd..99b8ec56ca74e72cb58d81f3a55b0fe7c19e4902 100644
--- a/python/examples/imdb/benchmark_batch.py
+++ b/python/examples/imdb/benchmark_batch.py
@@ -61,4 +61,7 @@ def single_func(idx, resource):
multi_thread_runner = MultiThreadRunner()
result = multi_thread_runner.run(single_func, args.thread, {})
-print(result)
+avg_cost = 0
+for cost in result[0]:
+ avg_cost += cost
+print("total cost of each thread".format(avg_cost / args.thread))
diff --git a/python/paddle_serving_client/__init__.py b/python/paddle_serving_client/__init__.py
index f3d6a9a661e494bbf8f3ea9995c8e9139fd102d5..ef1c2bfbfb63d40914bd5109380b96a607fc38e9 100644
--- a/python/paddle_serving_client/__init__.py
+++ b/python/paddle_serving_client/__init__.py
@@ -93,7 +93,7 @@ class Client(object):
lib_path = os.path.dirname(paddle_serving_client.__file__)
client_path = os.path.join(lib_path, 'serving_client.so')
lib_path = os.path.join(lib_path, 'lib')
- os.popen('patchelf --set-rpath {} {}'.format(lib_path, client_path))
+ os.system('patchelf --set-rpath {} {}'.format(lib_path, client_path))
def load_client_config(self, path):
from .serving_client import PredictorClient
diff --git a/python/paddle_serving_client/version.py b/python/paddle_serving_client/version.py
index e65b5b17784307b7121a0ec86c810612a78ff4b2..99322ee8280a66a54371b296905d54f0766b016d 100644
--- a/python/paddle_serving_client/version.py
+++ b/python/paddle_serving_client/version.py
@@ -12,6 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
""" Paddle Serving Client version string """
-serving_client_version = "0.1.3"
-serving_server_version = "0.1.3"
-module_proto_version = "0.1.3"
+serving_client_version = "0.2.0"
+serving_server_version = "0.2.0"
+module_proto_version = "0.2.0"
diff --git a/python/paddle_serving_server/__init__.py b/python/paddle_serving_server/__init__.py
index d893861e2b0cc1615701191a66aa6ff0bcb53305..08f3febc14ecd0d3c3cde7dc54f17bd143f9d5b3 100644
--- a/python/paddle_serving_server/__init__.py
+++ b/python/paddle_serving_server/__init__.py
@@ -211,6 +211,7 @@ class Server(object):
tar_name = floder_name + ".tar.gz"
bin_url = "https://paddle-serving.bj.bcebos.com/bin/" + tar_name
self.server_path = os.path.join(self.module_path, floder_name)
+
if not os.path.exists(self.server_path):
print('Frist time run, downloading PaddleServing components ...')
r = os.system('wget ' + bin_url + ' --no-check-certificate')
diff --git a/python/paddle_serving_server/version.py b/python/paddle_serving_server/version.py
index e65b5b17784307b7121a0ec86c810612a78ff4b2..99322ee8280a66a54371b296905d54f0766b016d 100644
--- a/python/paddle_serving_server/version.py
+++ b/python/paddle_serving_server/version.py
@@ -12,6 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
""" Paddle Serving Client version string """
-serving_client_version = "0.1.3"
-serving_server_version = "0.1.3"
-module_proto_version = "0.1.3"
+serving_client_version = "0.2.0"
+serving_server_version = "0.2.0"
+module_proto_version = "0.2.0"
diff --git a/python/paddle_serving_server_gpu/__init__.py b/python/paddle_serving_server_gpu/__init__.py
index 3dd330b18921c81cf17601ff7e52d860f0322f95..6f0ece74eeccc40eaf9676738e15e7b52b9da9ce 100644
--- a/python/paddle_serving_server_gpu/__init__.py
+++ b/python/paddle_serving_server_gpu/__init__.py
@@ -20,6 +20,7 @@ import google.protobuf.text_format
import tarfile
import socket
import paddle_serving_server_gpu as paddle_serving_server
+import time
from .version import serving_server_version
from contextlib import closing
import argparse
@@ -115,6 +116,7 @@ class Server(object):
self.reload_interval_s = 10
self.module_path = os.path.dirname(paddle_serving_server.__file__)
self.cur_path = os.getcwd()
+ self.check_cuda
self.use_local_bin = False
self.gpuid = 0
@@ -141,6 +143,13 @@ class Server(object):
self.use_local_bin = True
self.bin_path = os.environ["SERVING_BIN"]
+ def check_cuda(self):
+ r = os.system("whereis cuda")
+ if r != 0:
+ raise SystemExit(
+ "CUDA not found, please check your environment or use cpu version by \"pip install paddle_serving_server\""
+ )
+
def set_gpuid(self, gpuid=0):
self.gpuid = gpuid
@@ -215,11 +224,21 @@ class Server(object):
os.chdir(self.module_path)
need_download = False
device_version = "serving-gpu-"
- floder_name = device_version + serving_server_version
- tar_name = floder_name + ".tar.gz"
+ folder_name = device_version + serving_server_version
+ tar_name = folder_name + ".tar.gz"
bin_url = "https://paddle-serving.bj.bcebos.com/bin/" + tar_name
- self.server_path = os.path.join(self.module_path, floder_name)
+ self.server_path = os.path.join(self.module_path, folder_name)
+
+ download_flag = "{}/{}.is_download".format(self.module_path,
+ folder_name)
+ if os.path.exists(download_flag):
+ os.chdir(self.cur_path)
+ self.bin_path = self.server_path + "/serving"
+ return
+
if not os.path.exists(self.server_path):
+ os.system("touch {}/{}.is_download".format(self.module_path,
+ folder_name))
print('Frist time run, downloading PaddleServing components ...')
r = os.system('wget ' + bin_url + ' --no-check-certificate')
if r != 0:
@@ -318,4 +337,8 @@ class Server(object):
self.gpuid,)
print("Going to Run Comand")
print(command)
+ # wait for other process to download server bin
+ while not os.path.exists(self.server_path):
+ time.sleep(1)
+
os.system(command)
diff --git a/python/paddle_serving_server_gpu/version.py b/python/paddle_serving_server_gpu/version.py
index e65b5b17784307b7121a0ec86c810612a78ff4b2..99322ee8280a66a54371b296905d54f0766b016d 100644
--- a/python/paddle_serving_server_gpu/version.py
+++ b/python/paddle_serving_server_gpu/version.py
@@ -12,6 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
""" Paddle Serving Client version string """
-serving_client_version = "0.1.3"
-serving_server_version = "0.1.3"
-module_proto_version = "0.1.3"
+serving_client_version = "0.2.0"
+serving_server_version = "0.2.0"
+module_proto_version = "0.2.0"
diff --git a/python/paddle_serving_server_gpu/web_service.py b/python/paddle_serving_server_gpu/web_service.py
index db0db25d749728dc99dc1e65c278741d4b4bd5ae..5d507c9475047d6c7eb65a2b2c5799221cf194b5 100755
--- a/python/paddle_serving_server_gpu/web_service.py
+++ b/python/paddle_serving_server_gpu/web_service.py
@@ -66,6 +66,12 @@ class WebService(object):
return server
def _launch_rpc_service(self, service_idx):
+ if service_idx == 0:
+ self.rpc_service_list[service_idx].check_local_bin()
+ if not self.rpc_service_list[service_idx].use_local_bin:
+ self.rpc_service_list[service_idx].download_bin()
+ else:
+ time.sleep(3)
self.rpc_service_list[service_idx].run_server()
def prepare_server(self, workdir="", port=9393, device="gpu", gpuid=0):
@@ -160,15 +166,6 @@ class WebService(object):
if not isinstance(result, dict) and result == -1:
result = {"result": "Request Value Error"}
return result
- '''
- feed, fetch = self.preprocess(request.json, request.json["fetch"])
- if "fetch" in feed:
- del feed["fetch"]
- fetch_map = client.predict(feed=feed, fetch=fetch)
- fetch_map = self.postprocess(
- feed=request.json, fetch=fetch, fetch_map=fetch_map)
- return fetch_map
- '''
app_instance.run(host="0.0.0.0",
port=self.port,
diff --git a/tools/serving_build.sh b/tools/serving_build.sh
index fa7b98e4eb5dc470178360d0a7fbf81c2010a7af..14858bc710ba392ca1cc5e22dc2e14add5dee406 100644
--- a/tools/serving_build.sh
+++ b/tools/serving_build.sh
@@ -176,6 +176,7 @@ function python_run_criteo_ctr_with_cube() {
local TYPE=$1
yum install -y bc >/dev/null
cd criteo_ctr_with_cube # pwd: /Serving/python/examples/criteo_ctr_with_cube
+ export SERVING_BIN=${SERVING_WORKDIR}/build-server-${TYPE}/core/general-server/serving
case $TYPE in
CPU)
check_cmd "wget https://paddle-serving.bj.bcebos.com/unittest/ctr_cube_unittest.tar.gz"
@@ -191,6 +192,7 @@ function python_run_criteo_ctr_with_cube() {
sh cube_prepare.sh &
check_cmd "mkdir work_dir1 && cp cube/conf/cube.conf ./work_dir1/"
python test_server.py ctr_serving_model_kv &
+ sleep 5
check_cmd "python test_client.py ctr_client_conf/serving_client_conf.prototxt ./ut_data >score"
tail -n 2 score
AUC=$(tail -n 2 score | awk 'NR==1')
@@ -217,6 +219,7 @@ function python_run_criteo_ctr_with_cube() {
sh cube_prepare.sh &
check_cmd "mkdir work_dir1 && cp cube/conf/cube.conf ./work_dir1/"
python test_server_gpu.py ctr_serving_model_kv &
+ sleep 5
check_cmd "python test_client.py ctr_client_conf/serving_client_conf.prototxt ./ut_data >score"
tail -n 2 score | awk 'NR==1'
AUC=$(tail -n 2 score | awk 'NR==1')
@@ -235,6 +238,7 @@ function python_run_criteo_ctr_with_cube() {
exit 1
;;
esac
+ unset SERVING_BIN
echo "test criteo_ctr_with_cube $TYPE part finished as expected."
cd .. # pwd: /Serving/python/examples
}
|