双服务器架构实战飞桨部署-自动上色和老相片修复

宋 朱熹 《即事有怀寄彦辅仲宗二兄》诗之二:“闻说双飞桨,翩然下广津。

飞桨功能强大,部署非常简单方便(对我这个不熟练的人,并不是),再配上合适的web服务,那就是“金鳞岂是池中物,一遇风云便化龙”

在这里因为时间关系,使用paddlehub部署到后端(而没有使用PaddleServing),使用Pyramid框架写web服务器,提供前端web服务。前端和后端物理独立,分别各用一台服务器。这样可以提高安全性和负载能力。

示例项目已经部署到公网,可以通过http://w2.airoot.org:5000/aipic.html访问 。11.10日之后部署到鹏城实验室云主机,访问地址是:http://decs.pcl.ac.cn:3625/aipic.html

示例项目后端采用的是4核 16G Ubuntu服务器,启动飞桨hub server服务,工业落地可以用Paddle Serving服务以提高负载能力。后端服务器使用内网ip 192.168.0.3,不能从公网访问,保护服务器操作系统和飞桨代码的安全。前端采用的是4核 8G FreeBSD服务器,通过Pyramid框架提供web服务,工业落地的时候可以加上一层Nginx代理服务,以提高负载能力。前端服务器内网ip为192.168.0.2 ,用来与后端通信,再配一个公网ip,以提供公网web服务。

示例项目的两台服务器由中移动苏州公司提供,在此表示感谢。因为服务只提供到11.12日。大家抓紧进行测试哈。

从11.10日开始服务器由鹏城实验室提供,在此表示感谢。鹏城实验室采用单主机构架,但是内部也分了前端和后端。

示例项目后端是cpu服务器,所以一次图片上色完成需要28秒左右。在AIStudio用高端版,因为特斯拉v100 GPU的加持,只需要200ms左右。在鹏城鲲鹏云服务器,一次图片上色大约需要3分钟。

项目还在编辑中。
1.0定稿。
1.1 修改几个拼写错误。 2021.11.5
1.2 增加鹏城实验室云服务部署地址 。2021.11.10

首先我们在AIStudio环境下进行演示。

AIStudio环境演示部署流程

飞桨后端服务器配置

飞桨部署环境搭建

为了简单方便,这里选用了PaddleHub来进行部署。
首先把第三方软件都装好,主要是PaddleHub和OpenCV。在AIStudio环境里,默认都已经安装好了。所以我们什么pip命令都不需要。

顺便把前端web环境也搭建好吧,只需要两个python库: pyramid 和 pyramid_chameleon

# 大约需要20秒左右
# !apt install python3-opencv
!pip install pip -U
!pip install paddlehub pyramid pyramid_chameleon -U -q
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Collecting pip
[?25l  Downloading https://pypi.tuna.tsinghua.edu.cn/packages/a4/6d/6463d49a933f547439d6b5b98b46af8742cc03ae83543e4d7688c2420f8b/pip-21.3.1-py3-none-any.whl (1.7MB)
[K     |████████████████████████████████| 1.7MB 8.2MB/s eta 0:00:01
[?25hInstalling collected packages: pipFound existing installation: pip 19.2.3Uninstalling pip-19.2.3:Successfully uninstalled pip-19.2.3
Successfully installed pip-21.3.1
[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
blackhole 1.0.1 requires numpy<=1.19.5, but you have numpy 1.21.4 which is incompatible.[0m

启动PaddleHub Serving的上色模型服务

使用PaddleHub Serving的原因是简单方便,我们也可以使用PaddleServing,不过没有现成的上色模型,那样需要自己转模型,不如这个方便。
PaddleHub Serving运行启动命令:

$hub serving start -m deoldify

启动后显示如下:

   Use a production WSGI server instead.* Debug mode: off* Running on all addresses.WARNING: This is a development server. Do not use it in a production deployment.* Running on http://192.168.0.3:8866/ (Press CTRL+C to quit)

在AIStudio环境下,我们使用os.system来启动(os.system(“nohup hub serving start -m deoldify &”))。如果在命令行窗口,直接用上面的启动命令即可,即hub serving start -m deoldify。

注意:每次项目运行,第一次启动启动PaddleHub的时候,因为要下载模型文件,需要较长时间,而使用os.system启动没有输出信息,不利于观察模型下载的进度情况,也不会等待模型下载完再运行下一步,因此第一次执行“运行全部”,后面部分会报错。

解决的方法就是等一会儿再去执行下面的命令即可。也可以先到命令行窗口手工执行一下$hub serving start -m deoldify 。或者把下面的注释去掉执行一下(下载完模型后需要中断执行,然后执行后面的启动服务和测试)。

# 第一次下载模型文件,可以把注释去掉运行一次,下载完成之后要手工“中断”,不然后面的cell无法顺序执行。
# !hub serving start -m deoldify
# 启动飞桨PaddleHub服务,大约要20多秒才能启动成功。
import os
os.system("nohup hub serving start -m deoldify &") # &为后台执行,nohup为不因终端退出而停止。
0
# 如需停止Hub服务,用hub serving stop
# os.system("hub serving stop")

查看一下hub的服务是否启动成功

若出现这样的输出,证明hub服务启动了。飞桨Hub的默认服务端口是8866

tcp        0      0 0.0.0.0:8866            0.0.0.0:*               LISTEN

如果这里没有显示,就证明hub服务还在启动(下载模型)中。反复执行这一句(大约要等待20多秒),一直到出现上面这句话,证明hub服务器才启动成功,这时候才可以执行后面的代码,比如本地连接测试。

!netstat -an |grep 8866
tcp        0      0 0.0.0.0:8866            0.0.0.0:*               LISTEN

本地连接测试

根据官网提供的案例,修改代码里测试图片的位置。测试图片路径为:work/beautysmall.jpg

测试运行时间:
cpu下大约耗时20多秒
gpu下大约耗时200毫秒

因为hub服务器启动并从官网下载模型需要一段时间,所以下面代码运行可能出错。可以等前面那步“查看一下hub的服务是否启动成功 ”验证飞桨Hub服务启动之后再来尝试。
程序运行成功后,会在根目录生成上色之后的beauty.jpg文件。

import requests
import json
import base64import cv2
import numpy as npdef cv2_to_base64(image):data = cv2.imencode('.jpg', image)[1]return base64.b64encode(data.tobytes()).decode('utf8')
def base64_to_cv2(b64str):data = base64.b64decode(b64str.encode('utf8'))data = np.frombuffer(data, np.uint8)data = cv2.imdecode(data, cv2.IMREAD_COLOR)return data# 发送HTTP请求
org_im = cv2.imread('work/beautysmall.jpg')
data = {'images':cv2_to_base64(org_im)}
headers = {"Content-type": "application/json"}
url = "http://127.0.0.1:8866/predict/deoldify"
r = requests.post(url=url, headers=headers, data=json.dumps(data))
img = base64_to_cv2(r.json()["results"])
cv2.imwrite('beauty.jpg', img)

执行完毕后,输出True证明代码执行无误,在根目录会新生成上色过的beauty.jpg文件,我们来对比看一下。嗯,果然黑白照片变成彩色的了,效果相当不错!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AUtYANnz-1637365769714)(work/beautysmall.jpg)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t55OijEX-1637365769715)(beauty.jpg)]

web端开发和测试

设置一个web服务器,并写前端web代码。客户使用浏览器与web通信,web再与飞桨后端的hub服务器通信,图片上色后,再hub=〉web=〉浏览器,这样就完成了图片上色的全流程,生成的彩色图片会在客户面前呈现出来,并可以右键下载图片到本地。

因为notebook里面无法操作网页,所以这步就只能演示curl连接到web服务器,发送图片以及接收处理之后的图片这部分就先省略了,后面会在实战部署里给出代码,并且可以到上色部署实践体验。

web服务器需要安装pyramid 和 pyramid_chameleon 两个库,前面已经使用pip安装好了。

启动web服务器

这里使用pyramid web框架,只用一个.py文件和一个.pt模版文件,就能实现一个web服务器,非常简单方便。将这两个文件放在work目录里,分别为pyramidweb.py和aipic.pt,可以通过文件浏览或者vi/cat等命令来看代码内容。本项目的最后部分给出了这两个文件的内容。

使用下面这句话打开web服务器,当然也可以在终端界面,直接执行cd work && python pyramidweb.py

os.system("cd work && python pyramidweb.py &")

验证web服务器启动成功

pyramid搭建的web网站默认端口是6543,使用netstat -an |grep 6543命令看看6543这个端口的服务是否启动成功,如果启动了,输出应该是这样的:

tcp        0      0 0.0.0.0:6543            0.0.0.0:*               LISTEN
!netstat -an |grep 6543

确认web服务启动成功后,让我们用curl命令看看服务器返回页面的源代码。因为notebook里面无法使用浏览器,所以无法测试网页的执行情况,但是看看那个页面里的源代码还是可以的:

!curl http://127.0.0.1:6543/aipic.html

现在整个AIStudio上的仿真部署就完成了,我们分别开启了PaddleHub服务和web服务,web负责提供前端网页,web服务器内部跟Hub服务器通信,Hub服务处理AI图片上色处理部分。
下面开始讲述实际环境部署,大家可以在根据实际情况,在同一台机器上测试,也可以用两台机器来测试。

实战双服务器飞桨部署

安装飞桨后端服务器

与前面AIStudio环境演示部署流程基本一样,只是可能需要自己安装PaddleHub库。
第一次安装PaddleHub可能会碰到各种各样的问题,比如有些服务器可能需要安装opencv的包,并且有些时候安装不太顺利。不过只要仔细调试,应该都可以安装成功,再有问题可以在PaddleHub的github上面提issue

  • 安装paddlehub
pip install pip -U
pip install paddlehub

服务器内网ip地址为192.168.0.3 。大家可以自己定义自己的网络地址,做实验的时候,可以前后端使用同一台机器。

  • 启动paddlehub服务
    启动命令
hub serving start -m deoldify &

同样先进行本地测试,本地调通再进行下一步。
测试飞桨hub启动成功用这个命令:

netstat -an |grep 8866
  • 本机测试
    本地测试同上一节:AIStudio环境演示部署流程一样。就用那个代码执行即可。

安装前端服务器

前端web服务采用的是Python+Pyramid+Kotti。服务器内网ip地址为192.168.0.2,这里大家可以使用同一台电脑作为前端服务器。可能大家对Pyramid这个web框架不太了解,这是一个介于django和flask之间的web框架,不像django那么复杂,也不像flask那样太简单,而且它的弹性很好,复杂的网站能做,简单的网站也能做。后面我们就是用Pyramid做一个简单的单文件的web服务器程序。

Kotti是基于Pyramid的一个主打CMS内容管理系统的框架,可以大大减轻从头开发网站的工程量。

Pyramid+Kotti安装并不复杂

  • 安装Pyramid建站相关库
    使用这两条命令:
pip install pyramid pyramid_chameleon
pip install kotti

实际环境中使用Kotti框架,需要创建kotti项目,安装kotti项目,并在kotti项目里面改代码,操作还是较复杂的。为了操作的简洁,这里的例子就不用Kotti的代码了,只用一个pyramid的单文件,这个单文件包含了完整的web代码和demo网页的代码,再加上一个模版文件aipic.pt,一个AI上色的简洁网站就OK了。将work
目录里的pyramidweb.py和aipic.pt下载到本地,安装相关库文件pip install pyramid pyramid_chameleon之后,
只需要执行python pyramidweb.py即可启动web服务器。

  • 启动web服务器
python pyramidweb.py

这个简单的web服务器主页为:http://127.0.0.1:6543 ,可以从这个主页再点链接进入AI上色页面,也可以用浏览器直接打开该AI上色页面:http://127.0.0.1:6543/aipic.html

前端网站代码

为了便于观看代码,这里使用%%writefile 来展示。这两个摁键都放入了work目录,这两个文件下载到本地,放到同一个目录,然后在该目录里执行python pyramidweb.py即可。同时项目work目录里还提供了测试用的黑白照片,也可以下载到本地使用。若有侵权请告知,必会删除。

下面代码是针对前端和后端使用同一台服务器的情况,也就是飞桨PaddleHub和web网站在同一台机器,代码里指向本机地址url = "http://127.0.0.1:8866/predict/deoldify" ,如果是不同的机器,修改里面的ip地址即可。

%%writefile work/pyramidweb.py
from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.view import view_config
from pyramid.renderers import render_to_responseimport requests
import json
import base64
import os@view_config(name='aipic.html', renderer="pyramidweb:aipic.pt")
def aipic_view(request):# AI黑白照片上色页面if 'picture' not in request.POST: # 初始返回空模版with open(os.path.join('aipic.pt'), 'rb') as f:_index = f.read()_index_response = Response(content_type='text/html',body=_index)return(_index_response)input1_file = request.POST['picture'].filedata = base64.b64encode(input1_file.read()).decode('utf8')data = {"images": data}headers = {"Content-type": "application/json", "Connection": "close"}url = "http://127.0.0.1:8866/predict/deoldify"r = requests.post(url=url, headers=headers, data=json.dumps(data))input_file = r.json()["results"]img_stream = input_filereturn render_to_response('pyramidweb:aipic.pt',{'img_stream': img_stream})def hello_world(request):return Response('Hello World! 欢迎测试<a href="aipic.html">照片上色程序</a>')if __name__ == '__main__':with Configurator() as config:config.include('pyramid_chameleon')config.add_route('hello', '/')config.add_route('aipic', '/aipic.html')config.add_view(hello_world, route_name='hello')config.add_view(aipic_view, route_name='aipic')app = config.make_wsgi_app()server = make_server('0.0.0.0', 6543, app)server.serve_forever()

模版文件内容:

%%writefile work/aipic.pt
<form action="/aipic.html" method="post" accept-charset="utf-8"enctype="multipart/form-data"><label for="picture">请上传图片</label><input id="picture" name="picture" type="file" value="" /><label >点击上传图片并进行上色处理</label><input type="submit" value="submit" /></form><img style="width:180px" src="data:image/jpg;base64,${img_stream}"><label >可以右键保存图片</label>

将work目录里的pyramidweb.py和aipic.pt下载到本地,放到同一个目录即可。执行python pyramidweb.py之后,
即可用浏览器浏览这个网页:http://127.0.0.1:6543 或者http://127.0.0.1:6543/aipic.html
如果web网站有ip可以访问,改成该ip即可。

可以通过这个链接访问公网案例:http://w2.airoot.org:5000/aipic.com
点击“选取文件”,从本地选取一个黑白图片,然后点击“submit”按钮,后面耐心的等待20多秒,就可以看到黑白照片变成彩色照片啦!可以右键点击照片选择存储到本地。

ps,cpu下还是很慢的,要20多秒呢,所以一定要有耐心哦。

好啦,咱们的双服务器架构实战飞桨部署就圆满成功啦!

总结

将飞桨的推理服务部署和网站web服务分开并解耦,使我们可以专心的钻研和调试相应部分,并能提高服务器的负载能力,降低网络安全风险。

飞桨的推理服务部署简单方便,跟飞桨代码一脉相承,AI项目落地“纵享丝滑”! Pyramid Web框架性能优异,两者结合真是珠联璧合:金麟岂是池中物,一遇风云便化龙!

调试报错等

将原来两台服务器组成的上色项目,改写成单机实现,并将Kotti项目改写成单pyramid文件新项目
报错:

You may have forgotten to define a renderer in the view configuration.

经检查,代码里已经写了 @view_config(name='aipic.html', renderer="aipic.pt")

修改成测试代码,报错:

    raise ValueError(
ValueError: Missing template asset: aipic.pt (/Users/skywalk/py38/lib/python3.8/site-packages/pyramid/aipic.pt)
127.0.0.1 - - [03/Nov/2021 11:10:04] "POST /aipic.html HTTP/1.1" 500 59

发现调模版的路径是这个pyramid苦的路径,这里不对啊。
将模版那句改写成:
@view_config(name=‘aipic.html’, renderer=“pyramidweb:aipic.pt”)

现在报错

  File "/Users/skywalk/py38/lib/python3.8/site-packages/chameleon/utils.py", line 415, in __getitem__raise NameError(key)
NameError: img_stream- Expression: "img_stream"- Filename:   ... alk/web/mysite/kotti_mysite/kotti_mysite/static/aipic.pt- Location:   (line 10: col 58)- Source:     ... rc="data:image/jpg;base64,${img_stream}">^^^^^^^^^^- Arguments:  view: <NoneType ('None',) at 0x103b4caf8>renderer_name: pyramidweb:aipic.ptrenderer_info: <RendererHelper ('None',) at 0x7f8a9fce8910>context: <DefaultRootFactory ('None',) at 0x7f8a9fce8eb0>request: <Request ('None',) at 0x7f8a9fce8d30>req: <Request ('None',) at 0x7f8a9fce8d30>get_csrf_token: <partial ('None',) at 0x7f8a9fd50bd0>foo: 1bar: 2target_language: <NoneType ('None',) at 0x103b4caf8>repeat: <RepeatDict ('None',) at 0x7f8a9fce88e0>
127.0.0.1 - - [03/Nov/2021 11:24:20] "POST /aipic.html HTTP/1.1" 500 59

这样就证明模版路径正确了。返回来的数据不对,发现是return 代码不对,将代码返回部分改回成

    return render_to_response('pyramidweb:aipic.pt',{'img_stream': img_stream})

结束语

让我们荡起双桨,在AI的海洋乘风破浪!

飞桨官网:https://www.paddlepaddle.org.cn

因为水平有限,难免有不足之处,还请大家多多帮助。

作者:段春华, 网名skywalk 或 天马行空,济宁市极快软件科技有限公司的AI架构师,百度飞桨PPDE。

我在AI Studio上获得至尊等级,点亮10个徽章,来互关呀~ https://aistudio.baidu.com/aistudio/personalcenter/thirdview/141218

双服务器架构实战飞桨部署-自动上色和老相片修复相关推荐

  1. 【游戏开发】《Java游戏服务器架构实战》项目在windows上部署

    [游戏开发]<Java游戏服务器架构实战>项目在windows上部署 文章目录 [游戏开发]<Java游戏服务器架构实战>项目在windows上部署 一.配置项目基础环境 二. ...

  2. 【阅读笔记】Java游戏服务器架构实战

    [阅读笔记]Java游戏服务器架构实战 书籍链接:Java游戏服务器架构实战 作者提供的源码链接:kebukeYi / book-code 这里对书籍中比较重要的知识点(精华部分)进行摘录(总结) 文 ...

  3. 【二】分布式训练---参数服务器训练(飞桨paddle1.8)

    1.参数服务器训练简介 参数服务器训练是分布式训练领域普遍采用的编程架构,主要解决以下两类问题: 模型参数过大:单机内存空间不足,需要采用分布式存储. 训练数据过多:单机训练太慢,需要加大训练节点,来 ...

  4. 互联网的双中台架构实战

    我们需要对中台架构进行一番详细的介绍,阿里巴巴的Aliware 团队曾经给中台下过这样的定义: 将企业的核心能力随着业务不断发展以数字化形式沉淀到平台,形成以服务为中心,由业务中台和数据中台构建起数据 ...

  5. python图片自动上色_老旧黑白片修复机——使用卷积神经网络图像自动着色实战(附PyTorch代码)...

    摘要: 照片承载了很多人在某个时刻的记忆,尤其是一些老旧的黑白照片,尘封于脑海之中,随着时间的流逝,记忆中对当时颜色的印象也会慢慢消散,这确实有些可惜.技术的发展会解决一些现有的难题,深度学习恰好能够 ...

  6. 性能领先,即训即用,快速部署,飞桨首次揭秘服务器端推理库

    允中 发自 凹非寺 量子位 编辑 | 公众号 QbitAI 假如问在深度学习实践中,最难的部分是什么?猜测80%的开发者都会说: "当然是调参啊." 为什么难呢?因为调参就像厨师根 ...

  7. output怎么用_性能领先,即训即用,快速部署,飞桨首次揭秘服务器端推理库

    允中 发自 凹非寺 量子位 编辑 | 公众号 QbitAI 假如问在深度学习实践中,最难的部分是什么?猜测80%的开发者都会说: "当然是调参啊." 为什么难呢?因为调参就像厨师根 ...

  8. 飞桨模型保存_飞桨对话模型工具箱(二):对话自动评估模块ADE

    1. 对话自动评估 随着对话系统的不断发展和成熟,如何评价对话系统的回复质量,成为了一个新的研究方向. 对话自动评估技术,能够帮助企业或个人快速评估对话系统的回复质量,减少人工评估成本,具有重要的商业 ...

  9. 揭晓飞桨平台提速秘诀:INT8量化加速实现“事半功倍”

    为帮助广大企业和开发者更加便捷和快速地创建深度学习应用,百度飞桨正不断地提升平台的训练和推理能力,并与英特尔紧密合作,在至强® 平台集成的AI加速能力的支持下,以 INT8 量化方案,在不影响预测准确 ...

最新文章

  1. kettle读取不到oracle,kettle链接Oracle数据库,百试不爽!
  2. hbase2.0.0-安装部署
  3. Spring Cloud Config 集中式配置
  4. 编辑器性能测试:Atom 、VS Code、Sublime Text
  5. 一起用C#做个五子棋的小游戏 增加了程序对战功能
  6. java 正则 小数_详解Java判断是否是整数,小数或实数的正则表达式
  7. 完整全面的Java资源库(包括构建、操作、代码分析、编译器、数据库、社区等等)...
  8. [蓝桥杯][2014年第五届真题]稍大的串(STL)
  9. linux cd是什么目录,linux-cd命令
  10. 1.2、安装Django-1.5.1及所需要的Python2.74环境
  11. 结对-贪吃蛇-开发过程
  12. 开课吧:常见的数据可视化分析工具有哪些?
  13. leetcode331. Verify Preorder Serialization of a Binary Tree
  14. XEN虚拟机修改系统时间
  15. WebLogic部署项目成功后,访问Error 404
  16. 用计算机实测技术研究声波和拍内容,基础物理实验/面向21世纪课程教材
  17. 如何将pdf文件转换成图片格式,插入到word中
  18. apple开发者账号区别
  19. 分享50款漂亮的免费经典英文复古字体(上)
  20. canvas教程14-资源管理器

热门文章

  1. IDEA中写代码间距变大报红,报错Cannot resolve symbol
  2. 用R制作gif动态图以及从gif中提取图片
  3. 用python实现颜值打分,还能测测自己的颜值
  4. linux磁盘扩空间,Linux磁盘空间扩容(LVM)
  5. 上市公司股利分红数据(1991-2020)
  6. 速腾rs16激光雷达安装驱动使用方法
  7. 科普类:什么是量子霸权?
  8. 第19章 Linux电源管理的系统架构和驱动之CPUFreq驱动
  9. java 用户登录界面代码_求JAVA实现用户登录界面代码?
  10. springboot考研规划系统 毕业设计-附源码541230