

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 自带容器指南
<a name="bring-own-container-recipe"></a>

在本节中，我们提供了 Braket Hybrid Jobs 所需内容的 step-by-step指南，包括脚本、文件和将它们组合在一起以启动和运行自定义Docker映像的步骤。bring your own container (BYOC)两种常见案例的诀窍：

1. 在 Docker 映像中安装其他软件，并在作业中仅使用 Python 算法脚本。

1. 使用非 Python 语言编写的算法脚本与 Hybrid Jobs 或 x86 之外的 CPU 架构搭配使用。

对于案例 2，定义*容器入口脚本*更为复杂。

当 Braket 运行您的混合任务时，它会启动所请求的数量和类型的 Amazon EC2 实例，然后按照映像 URI 中的输入内容运行指定的 Docker 映像，从而在这些实例上创建任务。使用 BYOC 功能时，您可以指定托管在您拥有读取权限的[私有 Amazon ECR 存储库](https://docs.aws.amazon.com/AmazonECR/latest/userguide/Repositories.html)中的映像 URI。Braket Hybrid Jobs 使用该自定义映像来运行作业。

构建可用于 Hybrid Jobs 的 Docker 映像所需的特定组件。如果您对编写和构建 `Dockerfiles` 不熟悉，请参阅 [Dockerfile 文档](https://docs.docker.com/reference/dockerfile/)和 [Amazon ECR CLI 文档](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html)。

**Topics**
+ [您的 Dockerfile 的基础映像](#base-image-dockerfile)
+ [（可选）修改后的容器入口点脚本](#modified-container-entry-point)
+ [使用 `Dockerfile` 安装所需的软件和容器脚本](#install-docketfile)

## 您的 Dockerfile 的基础映像
<a name="base-image-dockerfile"></a>

如果您使用的是 Python，并且想要在 Braket 提供的容器中提供的内容之上安装软件，那么基础映像的一个选项是托管在我们的[GitHub 存储库和 Amazon ECR 上的 Brake](https://github.com/amazon-braket/amazon-braket-containers) t 容器镜像。您需要向 [Amazon ECR 进行身份验证才能](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html#cli-authenticate-registry)提取映像并在其上进行构建。例如，您的 BYOC Docker 文件的第一行可能是：`FROM [IMAGE_URI_HERE]`

接下来，填写要安装的 Dockerfile 的其余部分，然后设置要添加到容器中的软件。预先构建的 Braket 映像已经包含了相应的容器入口点脚本，因此您无需担心包含该脚本。

如果您想使用非 Python 语言，如 C\$1\$1、Rust 或 Julia，或者您想为非 x86 CPU 架构（比如 ARM）构建映像，则可能需要在基本公共映像的基础上构建。您可在 [Amazon Elastic Container Registry 公共图库](https://gallery.ecr.aws/)中找到许多这样的图片。请务必选择适合 CPU 架构的 GPU，必要时还要选择要使用的 GPU。

## （可选）修改后的容器入口点脚本
<a name="modified-container-entry-point"></a>

**注意**  
如果您只是在预先构建的 Braket 映像中添加其他软件，则可以跳过本节。

要在混合作业中运行非 Python 代码，请修改定义容器入口点的 Python 脚本。例如，[Amazon Braket Github`braket_container.py` 上的 python 脚本](https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py)。这是 Braket 预先构建的映像用来启动算法脚本和设置相应环境变量的脚本。容器入口点脚本自身**必须**使用 Python，但可以启动非 Python 脚本。在预先构建的示例中，您可以看到 Python 算法脚本要么作为 [Python 子进程](https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py#L274)启动，要么作为[全新的进程](https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py#L257)启动。通过修改此逻辑，您可以启用入口点脚本来启动非 Python 算法脚本。例如，您可以修改 [https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py#L139](https://github.com/amazon-braket/amazon-braket-containers/blob/main/src/braket_container.py#L139) 函数来启动 Rust 进程，具体取决于文件扩展名的结尾。

您还可以选择写入一个全新 `braket_container.py`。它应将输入数据、源档案和其他必要文件从 Amazon S3 复制到容器中，并定义相应的环境变量。

## 使用 `Dockerfile` 安装所需的软件和容器脚本
<a name="install-docketfile"></a>

**注意**  
如果您使用预先构建的 Braket 映像作为 Docker 基础映像，则容器脚本已经存在。

如果您在上一步中创建了修改后的容器脚本，则需要将其复制到容器中，**然后**将环境变量 `SAGEMAKER_PROGRAM` 定义为 `braket_container.py`，或者定义您为新容器入口点脚本命名的变量。

以下是可在 GPU 加速任务实例上使用 Julia 的 `Dockerfile` 的示例：

```
FROM nvidia/cuda:12.2.0-devel-ubuntu22.04

    
 ARG DEBIAN_FRONTEND=noninteractive
 ARG JULIA_RELEASE=1.8
 ARG JULIA_VERSION=1.8.3


 ARG PYTHON=python3.11 
 ARG PYTHON_PIP=python3-pip
 ARG PIP=pip


 ARG JULIA_URL = https://julialang-s3.julialang.org/bin/linux/x64/${JULIA_RELEASE}/
 ARG TAR_NAME = julia-${JULIA_VERSION}-linux-x86_64.tar.gz


 ARG PYTHON_PKGS = # list your Python packages and versions here


 RUN curl -s -L ${JULIA_URL}/${TAR_NAME} | tar -C /usr/local -x -z --strip-components=1 -f -


 RUN apt-get update \

    && apt-get install -y --no-install-recommends \

    build-essential \

    tzdata \

    openssh-client \

    openssh-server \

    ca-certificates \

    curl \

    git \

    libtemplate-perl \

    libssl1.1 \

    openssl \

    unzip \ 

    wget \

    zlib1g-dev \

    ${PYTHON_PIP} \

    ${PYTHON}-dev \




 RUN ${PIP} install --no-cache --upgrade ${PYTHON_PKGS}


 RUN ${PIP} install --no-cache --upgrade sagemaker-training==4.1.3


 # Add EFA and SMDDP to LD library path
 ENV LD_LIBRARY_PATH="/opt/conda/lib/python${PYTHON_SHORT_VERSION}/site-packages/smdistributed/dataparallel/lib:$LD_LIBRARY_PATH"
 ENV LD_LIBRARY_PATH=/opt/amazon/efa/lib/:$LD_LIBRARY_PATH


 # Julia specific installation instructions
 COPY Project.toml /usr/local/share/julia/environments/v${JULIA_RELEASE}/
 RUN JULIA_DEPOT_PATH=/usr/local/share/julia \

    julia -e 'using Pkg; Pkg.instantiate(); Pkg.API.precompile()'
 # generate the device runtime library for all known and supported devices
 RUN JULIA_DEPOT_PATH=/usr/local/share/julia \

    julia -e 'using CUDA; CUDA.precompile_runtime()'


 # Open source compliance scripts
 RUN HOME_DIR=/root \

 && curl -o ${HOME_DIR}/oss_compliance.zip https://aws-dlinfra-utilities.s3.amazonaws.com/oss_compliance.zip \

 && unzip ${HOME_DIR}/oss_compliance.zip -d ${HOME_DIR}/ \

 && cp ${HOME_DIR}/oss_compliance/test/testOSSCompliance /usr/local/bin/testOSSCompliance \

 && chmod +x /usr/local/bin/testOSSCompliance \

 && chmod +x ${HOME_DIR}/oss_compliance/generate_oss_compliance.sh \

 && ${HOME_DIR}/oss_compliance/generate_oss_compliance.sh ${HOME_DIR} ${PYTHON} \

 && rm -rf ${HOME_DIR}/oss_compliance*


 # Copying the container entry point script
 COPY braket_container.py /opt/ml/code/braket_container.py
 ENV SAGEMAKER_PROGRAM braket_container.py
```

此示例下载并运行提供的脚本 AWS ，以确保符合所有相关的开源许可证。例如，通过正确归因任何受 MIT license 控制的已安装代码。

如果您需要包含非公开代码，例如托管在私有代码 GitHub 或 GitLab 存储库中的代码，**请不要**在Docker映像中嵌入 SSH 密钥来访问它。相反，请在构建时使用 Docker Compose，以帮助 Docker 在其构建的主机上访问 SSH。有关更多信息，请参阅 [Securely using SSH keys in Docker to access private Github repositories](https://www.fastruby.io/blog/docker/docker-ssh-keys.html) 指南。

**创建和上传 Docker 映像**

有了正确定义的 `Dockerfile`，您现在就可以按照步骤[创建私有 Amazon ECR 存储库](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-create.html)了（如果尚不存在）。您也可以构建、标记容器图片并将其上传到存储库。

您已准备好构建、标记和推送映像。有关 `docker build` 选项的完整说明和一些示例，请参阅 [Docker 构建文档](https://docs.docker.com/reference/cli/docker/buildx/build/)。

对于上面定义的示例文件，您可以运行：

```
aws ecr get-login-password --region ${your_region} | docker login --username AWS --password-stdin ${aws_account_id}.dkr.ecr.${your_region}.amazonaws.com
 docker build -t braket-julia .
 docker tag braket-julia:latest ${aws_account_id}.dkr.ecr.${your_region}.amazonaws.com/braket-julia:latest
 docker push ${aws_account_id}.dkr.ecr.${your_region}.amazonaws.com/braket-julia:latest
```

**分配相应的 Amazon ECR 权限**

Braket Hybrid Jobs Docker 映像必须托管在私有 Amazon ECR 存储库中。默认情况下，私有 Amazon ECR 存储库**不**向 Braket Hybrid Jobs IAM role 或任何其他想要使用您的映像的用户（如合作者或学生）提供读取权限。您必须将[存储库策略](https://docs.aws.amazon.com/AmazonECR/latest/userguide/set-repository-policy.html)设置为授予相应的权限。通常，仅向您想要访问映像的特定用户和 IAM 角色授予权限，而不是帮助使用 image URI 提取映像。