用于AI对象检测的多阶段Docker构建
容器技术(例如Docker)可简化依赖关系管理并提高软件的可移植性。在本系列文章中,我们探讨了Docker在机器学习(ML)场景中的用法。

本系列假定您熟悉AI/ML,一般的容器化,尤其是Docker。
在上一篇文章中,我们利用NvidiaGPU的功能来减少简单TensorFlow模型的训练和推理时间。在本文中,我们将基于已实现的解决方案。我们将使用多阶段构建来创建容器以使用TensorFlowObjectDetectionAPI进行推理。欢迎您下载本文中使用的代码。
在本系列的后续文章中,我们将使用PyTorch和Transformers处理涉及自然语言处理(NLP)任务的大型模型。首先,我们将运行推理,然后通过RestAPI服务于推理模型。接下来,我们将调试在容器中运行的RestAPI服务。最后,我们将使用Azure容器实例在云中发布创建的容器。
为什么要进行多阶段构建?
在许多情况下,容器构建过程比简单的软件包安装或文件复制包含更多复杂的步骤。它可能涉及代码编译,有时还需要先从诸如GitHub的外部存储库下载该代码。
通常,应避免在所创建的容器中包含构建工具,以减小容器映像的大小并提高其安全性。如果仅在使用这些工具后将其删除,它们可能仍存在于一个容器层中,因此最终尺寸将不会减小。
在这种情况下,Docker的最佳实践之一是使用多阶段构建。
对象检测API
TensorFlow对象检测API驻留在TensorFlowModelGarden存储库的研究文件夹中。该文件夹包含选定的代码实现和用于检测图像中对象的预训练模型,例如DeepMAC和ContextR-CNN。这些模型可能是最先进的,但它们还不是官方的TensorFlow模型。
对象检测API的安装涉及多个步骤,其中有些步骤比较繁琐,因此在这里使用Docker可能会有所帮助。从理论上讲,我们可以使用TensorFlow存储库中提供的Dockerfile(例如,此文件)。不过,我们将创建自己的,因为TensorFlow提供的Dockerfile创建了一个大型Docker映像,其中保留了所有构建工具和资源。
Dockerfile的第一个共享阶段
第一阶段将安装构建和推断所需的所有共享依赖项:
FROM tensorflow/tensorflow:2.4.1-gpu AS buildimg_base ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get -y install --no-install-recommends python3-cairocffi python3-pil python3-lxml python3-tk && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*12345678复制代码类型:[python]
请注意该ASbuildimg_base语句中的子句FROM。它定义了内部映像名称,我们将在以下步骤中使用它。
Dockerfile第二阶段(构建)
现在,我们将需要下载对象检测API存储库并进行构建。我们首先扩展引用buildimg_base内部映像的先前创建的Dockerfile:
FROM buildimg_base AS buildimg ARG DEBIAN_FRONTEND=noninteractive12复制代码类型:[python]
接下来,我们指示Docker安装构建工具,下载存储库并构建库:
RUN apt-get update && apt-get -y install --no-install-recommends protobuf-compiler git WORKDIR /tmp/odsetup RUN git clone https://github.com/tensorflow/models.git && cd /tmp/odsetup/models && git checkout fea1bf9d622f07638767deeb0acd742d3a5d8af7 && (cd /tmp/odsetup/models/research/ && protoc object_detection/protos/*.proto --python_out=.) WORKDIR /tmp/odsetup/models/research/ RUN cp object_detection/packages/tf2/setup.py ./ && python -m pip install -U pip && pip install .1234567891011121314复制代码类型:[python]
请注意如何使用gitcheckout以确保使用特定版本的对象检测API代码。不幸的是,我们不能在这里依赖标记,因为该存储库在标记的(正式)发行版中未包含研究文件夹。
Dockerfile推理的第三阶段
现在,我们指示Docker从相同的共享buildimg_base映像开始,然后复制上一步中安装的Python库:
FROM buildimg_base COPY --from=buildimg /usr/local/lib/python3.6 /usr/local/lib/python3.612复制代码类型:[python]
为简单起见,我们复制了所有库(包括新库)object_detection以及100多个其他依赖项。
最后,我们添加一个用户以确保该容器不会以root用户身份执行:
ARG USERNAME=mluser ARG USERID=1000RUN useradd --system --create-home --shell /bin/bash --uid $USERID $USERNAME USER $USERNAME WORKDIR /home/$USERNAME12345复制代码类型:[python]
建筑形象
使用Dockerfile中的所有代码,我们可以构建映像:
$ docker build --build-arg USERID=$(id -u) -t mld06_gpu_tfodapi .1复制代码类型:[python]
--build-argUSERID在Windows主机上运行时,可以跳过该属性。实际上,您不希望在没有GPU支持的机器上运行对象检测API。由于仅在Linux主机上才提供GPU支持,因此在本文中我们将重点介绍Linux命令。
运行对象检测推断
准备好图像后,我们可以使用容器对样本图像进行预测。
描述如何使用对象检测API进行推理超出了本文的讨论范围-下载我们的代码以继续进行。
除了我们讨论的内容之外,我们的Dockerfile还包含一个Python脚本:app/prediction_tutorial.py。该脚本处理样本图像和对象检测模型的下载,然后在这些样本图像上运行预测。该代码改编自“对象检测API”教程。
在所有组件就绪之后,我们可以使用我们的容器运行此代码。为了便于测试,我们将本地文件夹映射为容器卷。
在具有GPU支持的LinuxDocker上,执行:
$ docker run -v $(pwd)/.keras:/home/mluser/.keras -v $(pwd)/app:/home/mluser/app --rm --user $(id -u):$(id -g) --gpus "device=0" mld06_gpu_tfodapi python app/prediction_tutorial.py123复制代码类型:[python]
要在没有GPU的机器上运行相同的容器,请删除该--gpus"device=0"属性。
如果一切顺利,您应该期待类似于以下内容的日志:

因为我们已将容器文件夹/home/mluser/.keras映射到我们的本地路径,所以我们还可以使用保存在.keras/predictions文件夹中的预测来检查图像。
概括
在本文中,我们在中等复杂的情况下使用了Docker。我们使用容器化的ObjectDetectionAPI环境在TensorFlow上对示例图像进行了推断。在本系列的后续文章中,我们将继续处理大型模型。这些模型将通过PyTorch和Transformers处理自然语言处理(NLP)任务。敬请关注!