Dual server architecture actual combat propeller deployment - Automatic coloring and old photo repair

Posted by icicleman on Sat, 20 Nov 2021 09:25:55 +0100

Dual server architecture actual combat propeller deployment - Automatic coloring and old photo repair

Song Zhu Xi's poem No. 2 of "I have a bosom to send Yan Fu Zhong Zong's two brothers" said: "I heard that the double flying oars came down to Guangjin lightly.

The paddle has powerful functions and is very simple and convenient to deploy (not for me, an unskilled person). Coupled with the appropriate web service, that is, "is the golden scale a thing in the pool that turns into a dragon in case of wind and cloud?"

Here, due to time constraints, we use paddlehub to deploy to the back-end (instead of paddeserving). We use the Pyramid framework to write web servers and provide front-end web services. The front-end and back-end are physically independent and use one server respectively. This can improve security and load capacity.

The sample project has been deployed to the public network and can be accessed through http://w2.airoot.org:5000/aipic.html Visit. Deploy to the virtual machine of Pengcheng lab after November 10. The access address is: http://decs.pcl.ac.cn:3625/aipic.html

The back-end of the example project uses a 4-core 16G Ubuntu server to start the propeller hub server service. The paddy serving service can be used for industrial landing to improve the load capacity. The back-end server uses intranet ip 192.168.0.3 and cannot be accessed from the public network to protect the security of the server operating system and propeller code. The front-end uses a 4-core 8G FreeBSD server, which provides Web services through the Pyramid framework Service. When the industry is launched, a layer of Nginx proxy service can be added to improve the load capacity. The intranet ip of the front-end server is 192.168.0.2, which is used to communicate with the back-end, and a public ip is configured to provide public web services.

The two servers of the sample project are provided by China Mobile Suzhou company. I would like to express my thanks. Because the service is only available until November 12. Let's hurry up and test it.

Since November 10, the server has been provided by Pengcheng lab. Pengcheng lab adopts a single host architecture, but it is also divided into front-end and back-end.

The back end of the sample project is the cpu server, so it takes about 28 seconds to complete the picture coloring at one time. In AIStudio, the high-end version only takes about 200ms because of the blessing of Tesla v100 GPU. In Pengcheng Kunpeng cloud server, it takes about 3 minutes to color the picture at one time.

The project is still being edited.
1.0 finalization.
1.1 correct several spelling mistakes. 2021.11.5
1.2 add cloud service deployment address of Pengcheng laboratory. November 10, 2021

First, we demonstrate it in the AIStudio environment.

AIStudio environment demonstration deployment process

Propeller backend server configuration

Construction of propeller deployment environment

For simplicity and convenience, PaddleHub is selected for deployment.
First, install the third-party software, mainly PaddleHub and OpenCV. In the AIStudio environment, they are installed by default. Therefore, we don't need any pip commands.

By the way, build the front-end web environment as well. You only need two python libraries: pyramid and pyramid_chameleon

# It takes about 20 seconds
# !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: pip
  Found existing installation: pip 19.2.3
    Uninstalling 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

Start the coloring model service of PaddleHub Serving

The reason for using PaddleHub Serving is that it is simple and convenient. We can also use PaddleHub Serving, but there is no ready-made coloring model. In that case, we need to turn the model ourselves, which is not as convenient as this.
PaddleHub Serving run startup command:

$hub serving start -m deoldify

After startup, the display is as follows:

   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)

In the AIStudio environment, we use os.system to start (os.system("nohop hub serving start -m deoldify &"). If you are in the command line window, you can directly use the above start command, that is, hub serving start -m deoldify.

Note: each time the project runs, when the PaddleHub is started for the first time, it takes a long time to download the model file. However, using os.system to start does not output information, which is not conducive to observing the progress of model download and will not wait for the model to download before running the next step. Therefore, when "run all" is executed for the first time, an error will be reported in the later part.

The solution is to execute the following commands later. You can also manually execute $hub serving start -m deoldify in the command line window, or remove the following comments for execution (you need to interrupt the execution after downloading the model, and then start the service and test later).

# When downloading the model file for the first time, you can remove the comments and run it once. After downloading, you should manually "interrupt", otherwise the subsequent cell s cannot be executed in sequence.
# !hub serving start -m deoldify
# Start the paddle PaddleHub service. It takes more than 20 seconds to start successfully.
import os
os.system("nohup hub serving start -m deoldify &") # &For background execution, nohup is not stopped due to terminal exit.
0
# To stop the Hub service, use hub serving stop
# os.system("hub serving stop")

Check whether the hub service is started successfully

If such an output occurs, the hub service is started. The default service port of the propeller hub is 8866

tcp        0      0 0.0.0.0:8866            0.0.0.0:*               LISTEN  

If it is not shown here, it proves that the hub service is still starting (downloading the model). Repeat this sentence (about 20 seconds). Until the above sentence appears, it proves that the hub server is started successfully. At this time, you can execute the following code, such as local connection test.

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

Local connection test

According to the case provided on the official website, modify the location of the test image in the code. The path of the test image is: work/beautysmall.jpg

Test run time:
The cpu takes about 20 seconds
It takes about 200 milliseconds under gpu

Because it takes a while for the hub server to start and download the model from the official website, the following code may run incorrectly. You can wait until the previous step "check whether the hub service is started successfully" verifies that the propeller hub service is started.
After the program runs successfully, the colored beauty.jpg file will be generated in the root directory.

import requests
import json
import base64

import cv2
import numpy as np

def 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

# Send HTTP request
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)

After execution, output True to prove that the code is executed correctly. A newly colored beauty.jpg file will be generated in the root directory. Let's compare it. Well, sure enough, the black-and-white photos turn into color, and the effect is quite good!

[the external chain picture transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-AUtYANnz-1637365769714)(work/beautysmall.jpg)] [the external chain picture transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-t55OijEX-1637365769715)(beauty.jpg)]

web side development and testing

Set up a web server and write the front-end web code. The client uses the browser to communicate with the web, and then the web communicates with the hub server at the back end of the propeller. After the picture is colored, the hub = > Web = > browser will complete the whole process of picture coloring. The generated color picture will be presented in front of the client, and you can right-click to download the picture locally.

Because the web page cannot be operated in the notebook, this step can only demonstrate curl connecting to the web server, sending pictures and receiving processed pictures. This part will be omitted first. Later, the code will be given in the actual deployment, and you can go to the Coloring deployment practice Experience.

The web server needs to install piramid and piramid_ Chameleon has two libraries, which have been installed using pip.

Start the web server

Here, we use the pyramid web framework to implement a web server with only one. Py file and one. Pt template file, which is very simple and convenient. Put these two files in the work directory, namely piramidweb.py and aipic.pt. You can view the code content through file browsing or vi/cat commands. The last part of this project gives the contents of these two documents.

Use the following sentence to open the web server. Of course, you can also directly execute CD work & & Python piramidweb.py in the terminal interface

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

Verify that the web server started successfully

The default port of the web site built by pyroid is 6543. Use the netstat - an grep 6543 command to see if the service of 6543 port is started successfully. If it is started, the output should be as follows:

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

After confirming that the web service is started successfully, let's use the curl command to see the source code of the page returned by the server. Because the browser cannot be used in the notebook, the execution of the web page cannot be tested, but it is OK to look at the source code on that page:

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

Now the simulation deployment on the whole AIStudio has been completed. We have opened the PaddleHub service and web service respectively. The web is responsible for providing front-end web pages, the web server communicates with the Hub server internally, and the Hub service handles the AI picture coloring processing part.
Let's start with the actual environment deployment. You can test on the same machine or two machines according to the actual situation.

Actual combat dual server propeller deployment

Install the propeller back-end server

The deployment process is basically the same as that demonstrated in the previous AIStudio environment, except that you may need to install the PaddleHub library yourself.
Installing PaddleHub for the first time may encounter various problems. For example, some servers may need to install opencv packages, and sometimes the installation is not smooth. However, as long as you debug carefully, you should be able to install successfully. If you have any problems, you can mention issue on the github of PaddleHub

  • Install paddlehub
pip install pip -U
pip install paddlehub

The intranet ip address of the server is 192.168.0.3. You can define your own network address. When doing experiments, you can use the same machine at the front and back ends.

  • Start the paddlehub service
    Start command
hub serving start -m deoldify &

Similarly, conduct local test first, conduct local debugging, and then proceed to the next step.
The test propeller hub is started successfully. Use this command:

netstat -an |grep 8866
  • Native test
    The local test is the same as that in the previous section: AIStudio environment demonstration deployment process. Just execute with that code.

Install front-end server

The front-end web service adopts Python+Pyramid+Kotti. The intranet ip address of the server is 192.168.0.2. Here, you can use the same computer as the front-end server. Maybe you don't know much about the web framework Pyramid. It's a web framework between django and flask. It's not as complex as django or as simple as flask, and it's flexible. Complex websites can do it, and simple websites can do it. Later, we use Pyramid to make a simple single file web server program.

Kotti is a CMS content management system framework based on Pyramid, which can greatly reduce the workload of developing websites from scratch.

The installation of Pyramid+Kotti is not complicated

  • Install Pyramid station building related libraries
    Use these two commands:
pip install pyramid pyramid_chameleon
pip install kotti

To use the Kotti framework in the actual environment, you need to create a Kotti project, install the Kotti project, and change the code in the Kotti project. The operation is still complex. In order to simplify the operation, the example here does not use Kotti's code, but only a single file of piramid, which contains the complete web code and the code of demo web page, plus a template file aipic.pt, a concise website with AI coloring is OK. Will work
Download the piramidweb.py and aipic.pt in the directory to the local area, and install the relevant library file PIP install piramid piramid_ After chameleon,
Just execute python, piramidweb.py to start the web server.

  • Start the web server
python pyramidweb.py

The home page of this simple web server is: http://127.0.0.1:6543 , you can click the link from the home page to enter the AI coloring page, or you can directly open the AI coloring page with a browser: http://127.0.0.1:6543/aipic.html

Front end website code

For the convenience of viewing the code,%% writefile is used here. Press these two keys and put them in the work directory. Download the two files locally and put them in the same directory, and then execute python, piramidweb.py in this directory. At the same time, the project work directory also provides black-and-white photos for testing, which can also be downloaded locally. If there is infringement, please inform and it will be deleted.

The following code is for the case where the front end and the back end use the same server, that is, the paddle PaddleHub and the web site are on the same machine, and the code points to the local address url =“ http://127.0.0.1:8866/predict/deoldify ", if it is a different machine, you can modify the ip address inside.

%%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_response


import requests
import json
import base64
import os


@view_config(name='aipic.html', renderer="pyramidweb:aipic.pt")
def aipic_view(request):
    # AI black and white photo coloring page

    if 'picture' not in request.POST: # Initial return empty template
        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'].file
    data = 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_file

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


def hello_world(request):
    return Response('Hello World! Welcome to the test<a href="aipic.html">Photo coloring procedure</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()

Content of template file:

%%writefile work/aipic.pt
<form action="/aipic.html" method="post" accept-charset="utf-8"
      enctype="multipart/form-data">

    <label for="picture">Please upload pictures</label>
    <input id="picture" name="picture" type="file" value="" />

    <label >Click to upload the picture and color it</label><input type="submit" value="submit" />
    </form>

    <img style="width:180px" src="data:image/jpg;base64,${img_stream}">
    <label >You can right-click to save the picture</label>

Download the piramidweb.py and aipic.pt in the work directory locally and put them in the same directory. After executing Python piramidweb.py,
You can browse this web page with a browser: http://127.0.0.1:6543 perhaps http://127.0.0.1:6543/aipic.html
If the web site has an ip address that can be accessed, it can be changed to this ip address.

You can access public network cases through this link: http://w2.airoot.org:5000/aipic.com
Click "select file", select a black-and-white picture locally, and then click the "submit" button. After waiting patiently for more than 20 seconds, you can see that the black-and-white picture becomes a color picture! You can right-click the photo and select store locally.

ps, the cpu is still very slow. It takes more than 20 seconds, so you must be patient.

Well, the actual combat deployment of our dual server architecture is a complete success!

summary

By separating and decoupling the reasoning service deployment of the propeller from the web service of the website, we can concentrate on studying and debugging the corresponding parts, improve the load capacity of the server and reduce the network security risk.

The reasoning service deployment of the flying oar is simple and convenient, which is in the same vein as the flying oar code. The AI project is "enjoy silk sliding"! Pyramid Web framework has excellent performance, and the combination of the two is a perfect match: Jinlin is a thing in the pool and turns into a dragon in case of wind and cloud!

Debugging error report, etc

Rewrite the coloring project composed of the original two servers into a stand-alone implementation, and rewrite the Kotti project into a new project with a single piramid file
report errors:

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

After checking, @ view has been written in the code_ config(name='aipic.html', renderer="aipic.pt")

Modify to test code and report error:

    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

It is found that the path of template adjustment is the path of this pyramid, which is wrong here.
Rewrite the sentence of the template as:
@view_config(name='aipic.html', renderer="pyramidweb:aipic.pt")

Now report an error

  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.pt
               renderer_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: 1
               bar: 2
               target_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

This proves that the template path is correct. The returned data is incorrect. It is found that the return code is incorrect. Change the return part of the code back to

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

Conclusion

Let's paddle and ride the wind and waves in the ocean of AI!

Propeller official website: https://www.paddlepaddle.org.cn

Because of the limited level, there are inevitably deficiencies. Please help us a lot.

Author: Duan Chunhua, a powerful and unconstrained style of skywalk, AI architect of Jining fast software technology Co., Ltd., Baidu PaddlePaddle PPDE.

I got the supreme level in AI Studio and lit 10 badges to interact with each other~ https://aistudio.baidu.com/aistudio/personalcenter/thirdview/141218

Topics: Computer Vision image processing paddlepaddle