Using Docker to Share Your Software 使用Docker来分享你的软件

      最后更新:2022-08-01 11:53:32 手机定位技术交流文章

      Containers For Collaboration(协作容器)

      Using Docker to Share Your Software

      Eric Kerfoot , School of Biomedical Engineering & Imaging Sciences, King’s College London

      本文翻译为英文如下:

      复杂软件在许多科学领域越来越重要,科学的重复部分是使用软件的传播。对于更复杂的系统,挑战是建立合适的环境,让其他科学家和合作者运行软件。要想找到一份工作,任何人都必须和一个包经理玩几个小时,知道这会多么痛苦!

      这个笔记本是关于多克在基于图像的深度学习模型中的应用的一个简短的教程,这包括应用推理所需的所有环境和库。目标是将模型装入一个可移动和可复制的软件单元,你的同事可以轻松下载和打电话,不需要担心安装在Docker之外的平台配置。

      虽然这个笔记本的例子是基于Pytorch的网络,用于4DMR图像中的心脏分裂,但是,创建多克图像并使用它来进行推理的概念可以应用到许多其他应用程序中。这里的许多单元包括可以运行的代码来与多克进行交互或执行一个构建过程,请随心所欲尝试一下这张笔记本.
      我们将涵盖:

      • What is Docker 什么是 Docke
      • Running Docker 运行 Docker
      • Building Images 构建镜像
      • Model Inference 模型推理
      • Sharing Your Image 分享你的镜像

      多克是什么?

      多克是一个工具和应用程序的集合,用于将软件系统包成可移动部署的单元,称为镜像。容器代表一个运行的视频实例,它们取决于图片中所包含的图书馆和环境,不是主机系统上的库和环境。本质上,多克镜是一个完整的Linux系统,减少核心和其他低级组件,可以根据你的任务配置,当运行时,它只依赖主机内核和驱动程序。

      由于是独立的图像,这样你就可以很容易地分配它给其他更方便的软件单位。研讨会和会议(如MICCAI)的挑战有时要求参加者以图像的形式提交软件,这样,组织者可以将它应用于隐藏的测试数据。具体而言,在科学领域内,另一个常见的应用领域是集群计算系统,用户的工作被作为图像提交,它包含任务所需的设置和环境。与提供一套图书馆的系统相比,这具有优势,你可以建立基于这些图书馆的软件,但是,维护您为编译软件所引入的新库可能很困难。容器化允许您将软件包封入集群可以使用的包中,而兼容性问题则更小。

      对整个环境进行封装的最常见的替代机制是虚拟化。 在虚拟机中,“用户”操作系统显示显示显示正在运行的计算机的实际硬件。但事实上,它是“家庭机器”提供的软件环境。 然后,客人必须提供所有运行实际机器所需的设备,这包括定义指导机制、格式化必要的文件系统、提供内核和提供硬件接口所需的服务。右图说明了这一点,将虚拟机与本地应用程序和多克容器进行比较.
      在这里插入图片描述

      相比之下,Docker和其他容器化方案使用主机内核及其功能,它提供了比VM更高的抽象水平。这创建了一个较轻的环境和较小的分布文件,以及接收器与主机或其他接收器容器之间的更简单的接口。通过包括几乎所有所需的软件基础设施,相信多克视频中的程序与错误配置的系统不冲突,就像正常本地程序一样。作为软件的使用者,你不需要设置一个库,依赖项目,配置或安装其他以外的任何东西来使用该程序。

      Installation安装

      Docker can be installed by following these instructions:

      Linux : Ubuntu is a popular distribution so follow the instructions here . Other distros are supported but might be harder to trouble shoot.
      Windows : Instructions are here . This should be a simple application installation, just be sure to switch to Linux containers.
      macOS: Instructions are here. This should also be straight-forward.
      让我们以Ubuntu为例

      1. Set up the repository 设置存储库
        Update the apt package index and install packages to allow apt to use a repository over HTTPS:
      1. Add Docker’s official GPG key:
      1. Use the following command to set up the repository:

      Install Docker Engine

      1. Update the apt package index, and install the latest version of Docker Engine, containerd, and Docker Compose, or go to the next step to install a specific version:

      Running Docker 运行Docker

      Docker 容器可以使用 docker 命令后跟参数和图像标签名称来实例化。多克使用一个叫做注册的服务存储图像。默认是DockerHub(https://hub.Docker.com/),当我们请求下载图像时,拉动命令将查看它:
      1.

      输出

      1. 运行自己上方的网格以查看命令的实际行动。下载后,我们现在可以使用运行运行容器:

      输出

      1. 我们可以使用多克命令查看我们所拥有的镜子和容器:

      输出

      输出

      再举一个例子,我们可以运行基础 Python 3.7 映像(Jupyter 单元不喜欢交互式终端,所以我将输出放在这里):

      这将从 Docker Hub 下载镜像,然后使用指定的内部命令运行它,即 python 交互式 shell。 参数 -ti --rm 表示分配一个伪 TTY,使用交互模式,并在容器退出时移除容器。

      对于这个图像,我们可以提供一个替换运行Python的命令,在这种情况下,bash将得到命令提示:

      我们可以看到,我们使用的 Python 映像在内部本质上是一个 Debian 10 系统,并且使用 bash 命令我们可以与它进行交互,就像它是一个正在运行的 Linux 系统一样。

      Building Images 构建镜像

      到目前为止,我们看到的是使用Docker来从图像中建模容器,并把它们当作运行程序。通过包含几乎整个Linux系统,它们不需要在客户端上安装或配置,因此,通过创造自己的形象,我们可以把自己的代码包成一个单元,我们可以向我们的合作伙伴和公众分发。

      Docker 镜像是使用 Dockerfile 构建的,Dockerfile 本质上是一个脚本文件,其中包含定义创建配方的特殊命令。 通常,图像基于初始现有图像,并为特定目的添加了调整。

      让我们根据我们已经看到的图像创建一个基于 Python 的“Hello, world”图像。 运行接下来的四个单元以创建一个工作目录(通常是 Docker 在构建期间复制目录的好做法)、一个脚本文件、Dockerfile 与之一起运行,然后构建并运行它:

      Writing hellopy/hello.py

      Writing hellopy/Dockerfile

      Sending build context to Docker daemon 3.072kB
      Step 1/3 : FROM python:3.7
      —> 22c70bba8283
      Step 2/3 : COPY hello.py /
      —> f83a218e13aa
      Step 3/3 : CMD [“python”,“hello.py”]
      —> Running in 183b7a43cd94
      Removing intermediate container 183b7a43cd94
      —> 4c79f534cadf
      Successfully built 4c79f534cadf
      Successfully tagged hellopy:latest
      Hello, world!

      我们所做的最重要的事情是在Dockkerfile上。 如前所述,这是把新的镜子结合起来的办法。在这种情况下,我们从 python 中取出: 3.7 图像(从行)开始,欢迎当前目录中的文件.py复制到与主机文件系统(COPY行)不同的图像文件系统根目录中,然后设置运行命令到Python hello.py(CMD行)。前一个单元的输出将打印下一个消息。

      我们可以通过一个交互式终端运行图像并宣布程序bash应该运行:

      现在CMD线上的命令被任何参数在图像的标签(名称)之后向我们传递的替换。如果我们想在容器中运行程序或脚本,并且能够将参数传递给它,我们需要使用ENTRYPOINT而不是CMD。这将迫使命令运行,在CMD或命令行中提供的任何内容都会成为一个参数,我们很快就会知道为什么这很重要。

      文件夹可以包含许多其他命令来执行其他设置任务。这张笔记本还附有另一张Docker Cheatsheet.ipynb,它包含了关于一般命令的更详细的信息。然而,重要的是,我们以后将使用RUN,它在视频中运行命令,就像一个运转的容器。该命令之后的视频状态是下一个运行或其他需要使用的命令的状态,因此,它被用来运行设置操作,根据我们的喜好配置视频。最后我们得到的是,我们用这些命令来建造它,其他方法也可以用来修改环境。

      模型ference模型的预测

      这个笔记本包含了Pytorch1.5神经网络,用于MRI图像中的心脏分裂,它叫做 net.zip。这是UNet对ACDC数据集进行培训的,用于识别短轴方向的左心室池、左心室心肌和右心室。

      它还包括我们将应用推理到名称 seg_sax_3label. py Nifti文件的脚本。该脚本将读取命令行上传递的Nifti文件(如果不提供,则通过标准输入),使用网络应用推理,然后将结果保存到提供的输出文件名(如果没有提供,保存到标准输出)。 您现在可以使用从 SCD 数据集生成的提供的 test.nii.gz 文件自己运行此脚本。

      如果我们把脚本和网络交给合作者,所以现在,他们应该正确配置环境来运行它,包括安装Python、Python、Nibabel和其他库的正确版本。 如今,Python的魔术还没有尝试过太多,但更复杂的软件可能难以正确安装。

      我们现在需要创建一个包含这个设置的多克视频,它还使用Nvidia Container Toolkit来提供GPU加速。 需要注意的是,这些视频要求您在Linux上运行它们,具有足够的内存和计算能力的NVIDIA GPU,Docker版本19.03以上,或者安装了nvidia-docker2.如欲获得更多安装资料,请参阅链接。

      我们的镜像必须包含网络和脚本文件,但还必须通过 Dockerfile 命令安装 Pytorch 和 Nibabel。 运行以下单元来创建我们的分割图像 seg_sax:

      Overwriting seg_sax/Dockerfile

      (Overly long output omitted)

      File Redirection 文件重定向

      Now our image is built and stored locally. We’ve used the Nvidia CUDA image which is rather large but comes with all the libraries we need to use GPU acceleration. Now we can segment our Nifti file with IO redirection without having to install anything except Docker:

      A few important things on what’s going on here:

      • We’re using IO redirection with the < and > operators to send the contents of test.nii.gz to stdin and stdout to out.nii. In our script if we don’t have arguments for the input and output files the stdin/stdout streams are used instead.

      • We’ve selected to give access to all GPU devices with --gpus=all, without this CUDA will not be available when performing network inference. If we wanted to allow access to a specific card, eg. card 1, we would use an argument like --gpus “device=1”.

      • -i is used to run in interactive mode, without it stdin/stdout for the running container won’t be connected to the terminal and so redirection wouldn’t work.

      Let’s visualize some of our results. If you have Nibabel and Matplotlib installed you can run the following cell to see one segmented slice:

      在这里插入图片描述

      Direct File Access

      上述图像的例子使用文件转导来与容器通信。如果我们想直接访问主机文件系统上的文件,我们必须将虚拟目录上传到当前运行的容器中.安全或其他原因,Docker容器的文件系统与主机文件系统断开,其他容器技术, 例如 Singularity, 不这样做.

      可以通过 docker run 命令挂载这个虚拟目录:

      There’s a lot going on here:

      • -v “$(pwd):/data:rw” states that we want to mount the current directory (the path to which is returned by the program pwd) and map it to /data in the container with read/write access.
      • -u $(id -u U S E R ) : {USER}): U SER ) : (id -g ${USER}) states that we want to run the container as the current user, the program id returns user and group ID numbers to do this. If we don’t have this the container will run and produce files owned by root which isn’t convenient, this way the files will be owned by you instead.
      • /data/test.nii.gz /data/out_local.nii are arguments to the script stating an input and an output file path, the script will read from paths when given instead of stdin/stdout. Note that these are paths to files within the running container, paths to files in your local file system will not be valid.
      • We don’t need -i anymore.
        Depending on what the task is it makes sense to use this method of accessing local files rather than the simpler file redirection, for our example segmentation image we can use either.

      Sharing Your Image

      通过建立和测试我们的图像,我们现在希望将它们分发给合作者和其他科学家。我们可以将图像输出到文件中并分享它,但它的大小将是许多GB:

      2.5G seg_sax.tgz
      这可以通过将多克的负载上传到本地存储库,但两个:在5GB上给您的用户提供它并不方便。 相反,我们将把照片上传到多克中心,这是为 Docker 提供的注册表服务,我们一直在用它从整个笔记本上提取图片。

      为此,首先 https://hub.Docker.com创建一个使用DockerHub的帐户,然后使用 docker login 命令将您的本地系统与您的帐户相关联(将“dockerid”替换为您的 Docker Hub 帐户名称):

      Now we want to tag our image based on our docker ID and assign a tag “latest”:

      Tags can be used to identify different types or versions of an image, latest is the commonly used one for referring to the most recent release. Finally we push to the registry:

      You should be able to see your image now at https://hub.docker.com/repository/docker/dockerid/seg_sax (replacing “dockerid” with your username of course). The free account with Docker Hub permits one repository to be private so if you want more you will have to sign up for a pro account, otherwise whatever else is uploaded is publicly available.

      Now your collaborators can use your software just by specifying the full repository name of your image:

      As we’ve seen this will pull the image from Docker Hub and then run it. Your collaborators don’t need anything more now besides the image name.

      that’s it

      现在你的模型可以与其他合作者分享。我们在这个笔记本中使用了一个支持CUDA的Pytorch例子,但是当然,任何其他程序可以通过设置正确的设置存储在多克视频中。使用Nvidia视频会造成视频尺寸损失,因此,如果速度不是优先考虑,您可以更改 Dockerfile以使用较小的非CUDA兼容的基本图像,例如,阿尔卑斯山。

      网络服务是多克的一个非常常见的例子,它通过网络接口提供应用程序,例如。数据库。使用Python框架,如Flash,你可以把简单的网络服务器结合起来,通过内部网络提供功能,不仅在本地命令行(或者最好使用像BentoML这样的工具)。

      使用 X 窗口(Linux 中的所有功能)的图形应用程序也可以通过带有命令行选项的 Docker 提供,以转发正确的信息,这样程序就可以找到你的显示器。使用可以在macOS和Windows上使用的X服务器,你甚至可以向任何用户分发这样的应用程序,虽然他们需要做更多的设置。

      使用 Docker 打包软件系统有很多可能性。可重复性依赖于用于进行研究的所有工具的可用性,因此使用这项技术,您现在可以创建模块化和便携式软件单元,其他用户可以轻松地自行使用。

      然后到哪里去?查看包含的Docker备忘录,以获取指示和更多信息的链接。

      谢谢阅读!

      本文由 在线网速测试 整理编辑,转载请注明出处,原文链接:https://www.wangsu123.cn/news/31135.html

          热门文章

          文章分类