为ML模型注入灵魂:基于MVP的超简单部署方案

作者: 读芯术 2020-06-02 08:22:18

本文转载自公众号“读芯术”(ID:AI_Discovery)

开发一个出色的机器学习模型是一件棘手的事,但即使开发完成也不意味着工作的结束。在部署之前,它仍然毫无用处,他人可以轻易访问。

部署模型的方法有很多,笔者想谈一种适用于基本MVP的非常简单的解决方案——使用Flask为模型编写API,将Gunicorn用于软件服务器,将Nginx用于网站服务器,并将其包装在Docker中,以便更轻松地在其他机器(特别是AWS和GCP)上进行部署。

设置服务器

笔者更喜欢用专门为此租用的服务器,而不是使用私人或工作硬件对新配置进行实验。这样,即使某些东西被严重损毁,也无关紧要。

因此笔者建议使用Linode,笔者本人就是用其来进行实验的,它们的硬件使用感不错。只要在Ubuntu18.04 LTS上,就可以随心所欲使用其他任何服务。

这一部分适合使用Linides的人借鉴。导航到Linodes,然后单击“添加Linode”。有些东西需要填写。在发行版中,笔者建议选择Ubuntu18.04 LTS映像:

  • 该区域——靠近你的区域(笔者用的是法兰克福,德国)
  • Linode计划——Nanode(每月仅需5美元,就需求而言足够了)
  • 根密码——你的密码

然后单击“创建”。大约几分钟后,可以转到“网络”,在这里能找到有关通过SSH访问服务器的信息。

为ML模型注入灵魂:基于MVP的超简单部署方案

下一步应连接服务器,并创建具有sudo特权的非根用户。这个操作背后的逻辑相当简单:你不想在服务器上把所有东西都作为根运行,因为这样更容易损坏东西。

  1. adduser usernameusermod -aG sudousername 

最终,切换到新用户。

  1. su — username 

创建应用容器

整个系统配置分为两部分:应用程序容器(Flask +Gunicorn)和Web容器(Nginx Web服务器)。

为ML模型注入灵魂:基于MVP的超简单部署方案
图源:unsplash

(1) 步骤0——安装Docker和Docker Compose

Docker和Docker-compose安装非常简单,分别在4行和2行内就能完成。

(2) 步骤1——创建FlaskApp和WSGI入口点

在主目录中创建flask app目录,并将以下文件放入其中。

  1. from flask importFlask 
  2.              server =Flask(__name__) 
  3.              @server.route('/') 
  4.       defhello_world(): 
  5.           return'hello world!' 

这是最基础的Flask应用,几乎没有任何功能,不用加载任何模型,不添加任何GET /POST请求和内容(这些将在下文出现)。现在,我们只有一个主页上显示着“ helloworld”的应用程序。

这部分极为简单——只需为Gunicorn创建一个在端口8000上运行的单独文件。

(3) 步骤2——为Flask创建一个Docker映像

现在,我们需要创建一个将运用这些文件的Dockerfile,并创建一个稍后能运行的映像。

  1. FROM python:3.6.7 
  2.              WORKDIRusr/src/flask_app 
  3.            COPYrequirements.txt . 
  4.            RUN pip install--no-cache-dir -r requirements.txt 
  5.            COPY . . 

对于不熟悉Docker的人而言,此脚本的功能如下:

  • 导入Python 3.6.7图像
  • 设置所有文件的工作目录
  • 复制包含Flask、Gunicorn和运行Flask应用程序需要的所有其他文件的需求文件。

然后,通过RUN命令安装所有必要安装包,最后将所有文件从flaskdir复制到容器内的usrscrflask 应用程序中。现在只需将此文件放在相同的flask_app目录中,并添加requirements.txt即可。

  1. flask 
  2.      gunicorn 

请记住,如果你对目录和内容感到困惑,只需在文章结尾处检查完整的项目结构,或访问GitHub存储库。

(4) 步骤3——创建Nginx文件

为ML模型注入灵魂:基于MVP的超简单部署方案
图源:unsplash

为运行Nginx,需要配置一些内容。但在迈出下一步之前,请在主目录内创建nginx目录(与flask_app处于同一级别)。之后,我们需要的第一个文件是nginx.conf,该文件几乎包含所有基本的Nginx信息和变量。

来看一个Nginx基本设置:

  1. # Define the user that will own and run theNginx server 
  2.       user  nginx; 
  3.       # Define the number of worker processes;recommended value is the number of 
  4.       # cores that are being used by yourserver 
  5.       worker_processes  1; 
  6.       # Define the location on the file systemof the error log, plus the minimum 
  7.       # severity to log messages for 
  8.       error_log  /var/log/nginx/error.log warn; 
  9.       # Define the file that will store theprocess ID of the main NGINX process 
  10.       pid        /var/run/nginx.pid; 
  11.              # events blockdefines the parameters that affect connection processing. 
  12.       events { 
  13.           # Define themaximum number of simultaneous connections that can be opened by a workerproce$ 
  14.           worker_connections  1024; 
  15.       } 
  16.              # http blockdefines the parameters for how NGINX should handle HTTP web traffic 
  17.       http { 
  18.           # Include thefile defining the list of file types that are supported by NGINX 
  19.           include       /etc/nginx/mime.types; 
  20.           # Define thedefault file type that is returned to the user 
  21.           default_type  text/html; 
  22.           # Define theformat of log messages. 
  23.           log_format main  '$remote_addr - $remote_user [$time_local] "$request" ' 
  24.                             '$status$body_bytes_sent "$http_referer" ' 
  25.                             '"$http_user_agent" "$http_x_forwarded_for"'; 
  26.                                 # Define thelocation of the log of access attempts to NGINX 
  27.           access_log  /var/log/nginx/access.log  main; 
  28.           # Define theparameters to optimize the delivery of static content 
  29.           sendfile        on; 
  30.           tcp_nopush     on; 
  31.           tcp_nodelay    on; 
  32.           # Define thetimeout value for keep-alive connections with the client 
  33.           keepalive_timeout  65; 
  34.           # Define the usageof the gzip compression algorithm to reduce the amount of data to transmit 
  35.           #gzip  on; 
  36.           # Includeadditional parameters for virtual host(s)/server(s) 
  37.           include/etc/nginx/conf.d/*.conf; 
  38.       } 

第二个文件——特定应用程序的配置。想要做到这一点有两种比较普遍的方法:

  • 在/ etc /nginx / sites-available / your_project中创建一个配置文件,然后创建到/ etc /nginx / sites-enabled / your_project的符号链接。
  • 只需在主要Nginx目录中创建一个project.conf。下述为第二种方法。
    1. server { 
    2.                  listen 80; 
    3.          server_name docker_flask_gunicorn_nginx; 
    4.                  location / { 
    5.              proxy_pass https://flask_app:8000; 
    6.                      # Do not change this 
    7.              proxy_set_header Host $host; 
    8.              proxy_set_header X-Real-IP $remote_addr; 
    9.              proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for; 
    10.          } 
    11.                  location /static { 
    12.              rewrite ^/static(.*) /$1 break; 
    13.              root /static; 
    14.          } 
    15.       } 

有几点需要注意:首先,请看一下listen80,该命令指定应用将在哪个端口运行。作为默认端口,我们选择80。其次,服务器名称。你可以指定从Linode获得的IP地址,也可以只使用docker映像名称。

最后,proxy pass命令,该命令应将Nginx配置指向flask项目。由于flask容器的名称为flask_app(将在后面介绍),因此只须使用容器的名称以及Flask项目中指定的端口。

(5) 步骤4——为Nginx创建一个Docker映像

该特定Docker映像非常简单。与Flask一样,它仅包含5行,且仅执行2件事:

  1. FROM nginx:1.15.8 
  2.              RUN rm/etc/nginx/nginx.conf 
  3.            COPY nginx.conf/etc/nginx/ 
  4.            RUN rm/etc/nginx/conf.d/default.conf 
  5.            COPY project.conf/etc/nginx/conf.d/ 

导入nginx图片,复制文件,并将其替换为默认文件。

(6) 步骤5——将Dockerfiles与docker-compose结合

现在已有2个Dockerfile:

  • 一个用于Flask + Gunicorn
  • 另一个用于Nginx。

现在是时候让它们交互,并运行整个系统了。为完成这一点,要用到docker-compose。我们只需要在主目录中创建docker-compose.yml文件。

  1. version: '3' 
  2.              services: 
  3.           flask_app: 
  4.            container_name: flask_app 
  5.            restart: always 
  6.            build: ./flask_app 
  7.            ports: 
  8.              - "8000:8000" 
  9.            command: gunicorn -w 1 -b 0.0.0.0:8000 wsgi:server 
  10.                nginx: 
  11.            container_name: nginx 
  12.            restart: always 
  13.            build: ./nginx 
  14.            ports: 
  15.              - "80:80" 
  16.            depends_on: 
  17.              - flask_app 

为了解其工作原理,我们来处理几个重要问题:

  • 首先,docker-compose分为2部分(2个服务):flask_app和nginx。正如从以下几行中看到的那样——flask_app容器执行运行Flask应用程序的Gunicorn,并用1个工作程序将其转换为8000端口。
  • 第二个容器仅在80端口上运行Nginx。另外,请注意depends_on部分,该部分命令docker-compose首先启动flask_app容器,然后才是——-nginx,因为这两个容器相互依赖。
为ML模型注入灵魂:基于MVP的超简单部署方案
图源:unsplash

此外,还应添加一件事,以便更轻松运行此Docker设置。那就是run_docker.sh文件。

  1. echo killing old dockerprocesses 
  2.         docker-compose rm -fs 
  3.              echo building dockercontainers 
  4.         docker-compose up --build -d 

该设置只是简单地运行docker-compose,但首先要确保此时旧的docker进程没有处于活动状态。

(7) 步骤6——将所有设置放在一起

当前的项目结构应如下所示:

  1. ├── flask_app 
  2. │   ├── app.py          
  3. │   ├── wsgi.py 
  4. │   └── Dockerfile 
  5. ├── nginx 
  6. │   ├── nginx.conf          
  7. │   ├── project.conf 
  8. │   └── Dockerfile 
  9. ├── docker-compose.yml 
  10. └── run_docker.sh 

在确保一切就绪之后,就能运行docker了。

  1. bash run_docker.sh 

并通过导航到从Linode获得的IP,然后在浏览器中查看主页面:

为ML模型注入灵魂:基于MVP的超简单部署方案

(8) 步骤7——没有得出任何成果,我该怎么办?

先在Linode上租用一个服务器,安装docker和docker-compose,接着克隆git存储库,然后运行bash run_docker.sh。

确保成功运行后,开始更改内容。尝试使用Flask,Dockerfiles或docker-compose,直到出现故障。之后,尝试找出问题所在,并着手解决。

(9) 步骤8-下一步呢?

为ML模型注入灵魂:基于MVP的超简单部署方案
图源:unsplash

接下来要添加的是支持FlaskApp中的POST请求。这样,可以将请求发送到模型并获得响应。

需满足两点:一个可以处理请求的模型,以及POST请求能够自我支持。

  1. from flask importFlask, request,jsonify 
  2.              server =Flask(__name__) 
  3.              defrun_request(): 
  4.            index =int(request.json['index']) 
  5.            list = ['red', 'green', 'blue', 'yellow', 'black'] 
  6.            return list[index] 
  7.              @server.route('/', methods=['GET', 'POST']) 
  8.         defhello_world(): 
  9.            if request.method =='GET': 
  10.                return'The model is up and running. Send a POST request' 
  11.            else: 
  12.                returnrun_request() 

为方便起见,在这种情况下,该模型仅返回颜色列表的第i个元素。但实际上,运行哪种模型都无关紧要,只需在所有方法上创建模型的实例(prettymuch where you have server = Flask(__name__))就可以了。

现在,如果导航到IP地址,将看到一条消息——“模型已启动,正在运行。发送POST请求”,因为只需转到IP就可将其视为GET请求。

但让我们试着使用包含模型索引的json文件发送POST请求。笔者使用Postman,但你可以视个人喜好而定(即Curl)。

为ML模型注入灵魂:基于MVP的超简单部署方案

行得通!现在,可以添加其它路径,以接收GET /POST请求。该想法背后的原因是可以通过加载多个模型,根据URL将请求发送到特定模型。

(10) 步骤9——进一步发展如何?

实际上,还有一个重要的步骤要做。为快速部署此Docker设置,将其部署在云空间是个不错的想法。这种方法的一个主要优势是:AWS将为群集管理基础架构提供保障。

你学会了吗?

ML 机器学习 MVP
上一篇:人工智能技术或成为未来网络安全的引爆点和驱动力 下一篇:机器学习的七原罪
评论
取消
暂无评论,快去成为第一个评论的人吧

更多资讯推荐

现代化机器学习工具,助数据科学家开展更多工程或业务功能

数据科学的发展日新月异,机器学习的角色正从数据科学的混合角色过渡到更多的工程或面向分析的角色,主要是以下的因素促成了这种变化。

云智时代 ·  1天前
Reddit高赞:机器学习领域「八宗罪」!同行评审变味,盲目崇拜盛行

近日,Reddit社区一篇批判机器学习领域的文章引发了热议,获得了3.1k的赞。作者细数了机器学习领域存在的「八宗罪」,让科研人员对机器学习大环境有了新的思考。

佚名 ·  1天前
人工智能开发者:如何选择人工智能领域?

机器学习算法可实时提供更广泛,更可靠的数据,目前很多领域都使用到智能算法。从常规的官方电子邮件到市场营销活动,智能算法已成为一种生活方式。企业可以通过机器学习技术来计算和量化其生产来源,而不会造成浪费。

SOWORD科技言 ·  2天前
7大分类,40多个关键概念,入门机器学习要掌握的概念都在这里了

不知道大家有没有这样的感觉:在我们学习的时候,经常学了就忘,忘了再学,彷佛进入了死循环。明明都学了,结果就是记不住。有时候都想往自己的脑袋里植入一个储存器,想学什么就往脑子里复制,这样多好。

为AI呐喊 ·  2天前
ML社区八大「毒瘤」:盲目崇拜、相互攻讦、重SOTA轻实效……

在本文中,一名 reddit 用户对机器学习社区存在的「毒瘤」进行了总结,希望可以警醒人们,促使社区沿着健康的方向发展。

机器之心 ·  3天前
如何在Python中创建线性回归机器学习模型?「入门篇」

线性回归和逻辑回归是当今很受欢迎的两种机器学习模型。本文将教你如何使用 scikit-learn 库在Python中创建、训练和测试你的第一个线性、逻辑回归机器学习模型,本文适合大部分的新人小白。

为AI呐喊 ·  4天前
案例详解 | 基于Embedding的特征安全计算

TalkingData 借助机器学习技术探索出一套新的方案,通过对原始数据进行分布式的隐含表征提取计算(一种数据变换方式),再将变换后的数据用于开放共享,既可以满足数据输出的安全性要求,又提升了大数据输出的处理速度。

TalkingData ·  4天前
机器学习背后的数学支柱,这5本书帮你搞定!

现如今,机器学习领域比以往任何时候都更容易上手。同时,这也助力了我们目前所经历的科技的疯狂发展。在本文中,我选择了五本对我最有帮助的书籍,希望对你也会有帮助。

读芯术 ·  2020-06-30 09:06:05
Copyright©2005-2020 51CTO.COM 版权所有 未经许可 请勿转载