65.9K
CodeProject 正在变化。 阅读更多。
Home

为 AI 和机器学习创建 Docker 容器

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2021 年 4 月 26 日

CPOL

4分钟阅读

viewsIcon

9449

downloadIcon

148

在本文中,我们将开始应用我们基本的 Docker 知识,同时在各种 MLng 场景中创建和运行容器。

引言

容器技术,例如 Docker,显著简化了您软件的依赖项管理和可移植性。在本系列文章中,我们将探讨 Docker 在机器学习 (ML) 场景中的用法。

本系列假设您熟悉机器学习、一般的容器化以及特别是 Docker。 欢迎下载项目代码

在本系列的上一篇文章中,我们讨论了 Docker 基础知识。 在本文中,我们将开始应用这些知识,同时在各种 ML 场景中创建和运行容器。 首先,我们将创建一个通用的容器,用于实验和训练。

基础镜像

在考虑镜像大小和安全性时,Alpine Linux 看似是基础镜像的明显选择。 但是,对于 Python 应用程序,情况并非如此简单。 Alpine 使用 musl – 一个不同于 glib 的 C 库,而 glib 是大多数标准 Linux 发行版使用的库。 这使得大多数已编译的 Pip wheels 不兼容,因此在安装期间需要编译。 实际上,在 Alpine 上设置任何重要的 Python 环境(具有多级依赖项)比在 Debian 或 Ubuntu 等更流行的发行版上花费更多的时间。 不仅如此,生成的镜像可能更大,并且代码的运行速度可能更慢!

有关更多详细信息,请查看这篇文章。 为了避免上述问题,我们将选择构建在 Debian 10 (Buster) 之上的官方 Python 镜像的最小版本作为基础:python:3.8.8-slim-buster。

创建 Dockerfile

我们需要一个包含基本 ML 库和 Jupyter Notebooks 的镜像来处理实验。 我们将所有必需的库存储在 app/requirements.txt 文件中

numpy==1.19.5
pandas==1.2.2
scikit-learn==0.24.1
matplotlib==3.3.4
jupyter==1.0.0
opencv-python==4.5.1.48
tensorflow-cpu==2.4.0

现在,让我们开始创建我们的 Dockerfile

FROM python:3.8.8-slim-buster
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get -y install --no-install-recommends ffmpeg libsm6 libxext6 \
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*

首先,在切换到非交互模式后,我们安装 Python 库所需的所有系统依赖项,然后在之后进行清理以限制镜像大小。 请注意,如果您更改 requirements.txt,这些依赖项可能会有所不同。

接下来,我们在运行容器时使用非 root 用户

ARG USERNAME=mluser
ARG USERID=1000
RUN useradd --system --create-home --shell /bin/bash --uid $USERID $USERNAME

使用 USERNAMEUSERID 值的参数将允许我们在构建和执行期间根据需要替换它们。

然后,让我们配置一个 Python 环境

COPY app/requirements.txt /tmp/requirements.txt
RUN pip3 install --no-cache-dir -r /tmp/requirements.txt \
&& rm /tmp/requirements.txt

最后,如果没有指定其他命令,我们切换到新用户并默认启动 Jupyter Notebook

USER $USERNAME
WORKDIR /home/$USERNAME/app
EXPOSE 9000
CMD ["jupyter", "notebook", "--ip", "0.0.0.0", "--port", "9000"]

构建镜像

在 Linux 上,我们应该始终使用预定的用户来运行容器。 这确保了容器的内部进程以及保存到映射主机驱动器的文件将具有预期的所有者。 在以下示例中,我们确保当前用户对构建 image mld02_cpu_experiment 时创建的所有文件具有适当的权限

$ docker build --build-arg USERID=$(id -u) -t mld02_cpu_experiment .

提供的 --build-arg USERID 参数将用提供的值替换 Dockerfile 的预定义 USERID 参数。

实际上,您只需要在 Linux 上本地运行容器时才需要这样做。 镜像中的默认值 (1000) 可能会在主机上造成麻烦,并且容器需要对镜像中包含的用户文件夹或文件具有写入权限。 在任何其他情况下,您可以跳过此步骤。

运行容器

构建容器后,我们可以尝试一下。 假设我们已经下载并提取了示例代码,我们运行我们的 Jupyter Notebook 实例

$ docker run -p 9000:9000 -v $(pwd)/app:/home/mluser/app -v $(pwd)/data:/home/mluser/data --rm --user $(id -u):$(id -g) mld02_cpu_experiment

在 Windows 上

$ docker run -p 9000:9000 -v %cd%/app:/home/mluser/app -v %cd%/data:/home/mluser/data --rm mld02_cpu_experiment

这里的参数是:-p 将容器端口映射到主机端口,-v 将主机的 app 和 data 文件夹映射到容器文件夹(绝对路径),以及 --user 确保我们在当前主机用户的上下文中执行容器代码(以便为映射文件夹中的文件拥有正确的所有者)。 --rm 标志确保在容器停止后立即自动删除所有容器数据。

如果一切顺利,我们应该看到我们的 Jupyter Notebook 启动的日志

由于映射的端口,我们应该能够使用 https://:9000(或来自上述日志的 URL)在 Web 浏览器中打开笔记本。

Simple Training.ipynb 包含我们使用简单的 TensorFlow 模型训练我们的示例 MNIST 模型所需的一切。 在执行完所有单元格后,我们应该期望以下确认,确认模型的预测是正确的

我们将在以下文章中使用此笔记本保存的训练模型进行推理。

摘要

在本文中,我们创建了一个用于实验的基本容器。 在下一篇文章中,我们将创建一个容器来在训练的模型上运行 CPU 推理。

© . All rights reserved.