在当今的软件开发领域,将机器学习模型转化为服务并使其易于消费者使用是一项重要任务。这正是将模型投入生产的实质。因此,模型部署成为了机器学习生命周期中不可或缺的一部分。本文将指导完成一个模型部署过程,即将一个包含简单Flask应用的容器部署到云平台Heroku上。尽量保持过程简单,以便为提供涉及的顺序的基本理解。
文章的范围大致分为以下几个部分:
Flask是一个Python的Web框架。Web框架是一系列库和模块的集合,它使得Web应用开发者能够编写应用程序而不必担心低层次的细节,例如协议、线程管理等。Flask通常因其非常符合Python风格且学习曲线平缓而受到青睐。
要开始项目,选择一个工作环境来开发项目是很好的。Visual Studio Code提供了一个优秀的平台,可以有效地交互和开发应用程序。有许多替代品,可以自由选择感到舒适的一个。开发应用程序时,使用虚拟环境是一个好习惯。假设同时在两个项目上工作,一个需要TensorFlow v1.5,另一个需要TensorFlow v2.0。虚拟环境为提供了一个工具,可以将项目及其依赖项彼此隔离。建议在任何基于Python的项目中使用虚拟环境。virtualenv、pipenv、poetry等是创建虚拟环境的一些流行工具。开始时,使用了WSL(Windows子系统用于Linux)和Ubuntu 18.04作为项目的环境。发现WSL中的Linux环境是一个良好且易于开发的界面。以下代码将为项目启动一个名为demo的虚拟环境:
$ pip install virtualenv
$ mkdir demo
$ virtualenv demo
$ source activate demo/bin/activate
$ which python
上述代码创建了一个名为demo的虚拟环境,命令which python显示正在使用来自虚拟环境的Python(它将显示当前目录加上/demo/bin/python)。要停用环境,请输入deactivate。现在可以编写一个简单的Flask应用,并将其称为main.py。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def demo():
return "Hello World"
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000, debug=True)
main.py代码从Flask包中导入Flask对象,并创建了一个名为app的Flask应用程序实例,并传递变量(__name__)给它。@app.route('/')是一个Python装饰器,它将Python函数转换为视图函数,将函数返回值转换为HTTP响应,可以由Web浏览器显示。“/”表示该函数将在主URL处响应。index函数返回字符串“Hello World”。
默认情况下,main.py在localhost上运行,host='0.0.0.0'告诉它在机器的所有IP地址上运行,端口告诉应用程序将在机器的5000端口上运行。
让在本地机器上运行这个应用,
$ pip install flask
$ python3 main.py
将看到类似于这样的输出。可以通过在浏览器中输入显示的IP地址或在终端中使用命令$ curl localhost:5000来查看main.py的输出。
应用似乎在本地机器上运行。终端抛出了一个警告:“WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.”让理解这意味着什么……
简而言之,如果想要让应用投入生产,应该选择一个生产服务器,如unicorn、waitress等。正如Flask文档中所述,“虽然轻量级且易于使用,但Flask的内置服务器不适合生产,因为它不能很好地扩展,并且默认情况下一次只能服务一个请求。”。将使用gunicorn,WSGI生产服务器来部署应用,如果使用的是Windows,gunicorn可能无法工作,而waitress是首选。使用control+C停止早期运行的应用,并在终端执行以下命令,
$ pip install gunicorn
$ gunicorn --bind 0.0.0.0:5000 main:app
这表示应用正在运行,可以像以前一样使用浏览器或curl命令进行检查。太好了!让继续。
让继续容器化应用。虽然Docker容器本身就是一个主题,但会尽量简略介绍。Docker是部署应用程序的热门Dev-Ops工具之一。可以将容器与应用程序及其所有依赖项一起打包并发货,而不必担心兼容性问题或机器依赖性。使用Docker,无论应用程序在哪里,都可以运行。
一个Docker镜像就像一个容器的蓝图。上面的图表描述了过程,编写一个Docker文件来创建一个自定义镜像,并使用容器帮助运行应用程序。Docker最初是在Linux环境中开发的,但随后也适用于Windows和Mac机器。需要WSL2在Windows上使用Docker,并且有许多在线资源可以帮助为机器下载Docker环境。假设机器上有Docker环境,让继续。
$ docker --version
这将告诉Docker是否正确安装。在构建镜像和运行容器之前创建requirements.txt。
$ pip freeze > requirements.txt
这会创建一个包含当前目录所需包的文本文件。在当前目录中创建一个文件,并命名为Dockerfile,内容如下:
FROM docker.io/python:3.7
WORKDIR /app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
ENTRYPOINT ["gunicorn","","--bind","0.0.0.0:5000",main:app"]
该文件使用Python 3.7镜像作为构建应用程序的基础镜像。要执行的命令是WORKDIR、COPY、RUN,创建一个工作目录,复制文件,并在requirements.txt中运行pip安装包。特别在requirements.txt中使用了gunicorn==19.9.0,因为更高版本会出现错误。最后,ENTRYPOINT告诉容器将如何运行,这里将在localhost的5000端口上使用gunicorn服务器运行应用程序。一旦Dockerfile准备好,可以构建并运行容器(确保在项目目录中!)
$ docker build -t demo-app .
This should get the image building process going and the following command should show our image,
$ docker images
Run the container in localhost with the following commands in sequence,
$ docker run -dit -p 5000:5000 demo-app
$ docker ps
上述命令应该显示容器成功运行,Docker分配容器ID和名称(如果没有明确命名),在运行命令期间将容器端口5000映射到机器端口5000。现在容器正在运行,可以再次使用浏览器或curl命令进行验证。
在本地成功运行应用程序后,让将其部署到云端供其他人使用。使用Heroku来部署应用程序。Heroku是一个平台即服务(PaaS),它使开发人员能够在云端完全构建、运行和操作应用程序。他们还提供免费账户来托管一些应用程序。因此,注册一个账户,并下载Heroku CLI进行部署。
This will confirm Heroku CLI installation. The following sequence of commands will build the container on the Heroku cloud platform.
$ heroku login
This will give a “Logging in… done” message
$ heroku container:login
$ heroku create
This will create an app and Heroku will give a name (if we don’t specify a particular name) and corresponding link for the app. Note this app name for further commands,
$ heroku container:push web --app
This builds the container and pushes it to the cloud and gives a message “Your image has been successfully pushed. You can now release it with the ‘container: release’ command.”
$ heroku container:release web --app
“You don’t learn to walk by following rules. You learn by doing, and by falling over.” ― Richard Branson