无论是第一次设置TensorFlow的新手数据科学爱好者,还是使用TB级数据的经验丰富的AI工程师,安装库、软件包或者框架总是一个困难又繁琐的过程。但是像Docker这样的集装箱化工具正在彻底改变着软件的可重复性,只不过它们还没有在数据科学和人工智能社区中流行起来。但随着机器学习框架和算法的不断发展,我们将很难花时间专注于学习所有相关的开发人员工具,尤其是那些与模型构建过程没有直接关联的工具。
在这篇文章中,我将展示如何使用docker和python工具包 datmo 为任何流行的数据科学和AI框架快速配置环境。

一. Docker

1. docker是什么

该软件于2013年由dotCloud 公司推出,发布以来一直备受关注和讨论,被认为可能会改变软件行业。

 

2. 为什么使用docker

如果让你说出软件开发最烦人的事情,那么环境配置必然是其中之一。例如开始编写Python应用程序,那么你的第一个步骤就是在您的计算机上安装Python。软件运行时,你不仅需要让自己计算机上的环境需适合你的应用程序按预期运行,并且还需要与生产环境相匹配。这就是所谓的环境一致性问题。这里面大量的重复劳动不说,还经常出现系统不兼容等莫名其妙的问题,非常令人崩溃。很可能再自己机器上跑通了,但放到用户的环境里,或者服务器上就出问题了。

 

那么可不可以在软件安装的时候把软件需要的环境一并复制过去呢?虚拟机(virtual machine)就是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统,但它的缺点很多:资源占用多、冗余步骤多、启动慢等等。

 

Docker是一种全新的虚拟化方式。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。在这样的前提下,它跟传统的虚拟化方式相比具有众多优势:

高效的利用系统资源。
启动速度快。容器里面的应用,直接就是底层系统的一个进程,而不是虚拟机内部的进程。由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。
确保了应用运行环境一致性。
可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。
容器只要包含用到的组件即可,而虚拟机是整个操作系统的打包,所以容器文件比拟机文件要小很多。
3. 如何使用docker

首先要理解Docker的三个概念:镜像、容器、仓库。

 

镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。镜像是只读的,可以用来创建Docker容器,容器看做是一个简易版的Linux环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

 

Docker Registry 是集中存放镜像文件的场所,提供集中的存储、分发镜像的服务。一个 Docker Registry中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。

 

最常使用的 Registry 公开服务是官方的 Docker Hub,这也是默认的 Registry,并拥有大量的高质量的官方镜像。

 

这里以TensorFlow机器学习框架搭建为例讲解如何利用docker快速搭建环境。

 

首先你需要安装并启动Docker。如果要使用GPU则安装nvidia-docker。

1) 直接使用别人做好的镜像

在命令行输入以下两条命令:

docker image pull tensorflow/tensorflow
docker run -it  -p 8888:8888  -v /$(pwd)/notebooks:/notebooks  tensorflow/tensorflow

第一行命令在Docker Hub上拉取tensorflow官方镜像的cpu版本。

 

第二行则由此镜像创建一个容器,并在容器里运行jupyter服务。 在你的浏览器上打开http://localhost:8888/,就可以在jupyter里导入TensorFlow包了。

 

-v 参数的作用是将宿主机当前目录下的notebook目录挂载到容器内的/notebooks目录,不添加这个参数的话,当结束 container 的时候,jupyter notebook 里的内容也会随之消失。

我们还可以进入到容器里查看容器的环境配置信息:

docker run -it -p 8888:8888 tensorflow/tensorflow bash

解释一下参数含义:

-i:以交互模式运行容器,通常与 -t 同时使用

-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用