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

将 AI Docker 容器部署到云端

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2021 年 5 月 25 日

CPOL

5分钟阅读

viewsIcon

6693

downloadIcon

78

在本文中,我们将通过 Azure 容器实例将我们的 NLP API 服务发布到 Azure。

引言

Docker 等容器技术简化了依赖管理,并提高了软件的可移植性。在本系列文章中,我们将探讨 Docker 在机器学习 (ML) 场景中的用法。

本系列假定您熟悉 AI/ML、容器化(一般)以及 Docker(具体)。

上一篇文章中,我们使用 FastAPI 和 Gunicorn 调试了一个通过 REST API 服务公开的 NLP 模型。

在本文(本系列的最后一篇)中,我们将使用 Azure 容器实例将我们的 REST API 服务部署到云端。欢迎下载 本文使用的代码

应用程序代码

我们将使用与前几篇文章相同的应用程序代码和容器定义。为了保持解决方案的简洁和专注,附加的代码存档仅包含将我们的示例发布到 Azure 所需的文件。如果您想挑战一下,可以从最后两篇文章中的一个解决方案开始,并添加我们在这里将要讨论的代码片段(而不是使用本文的代码下载)。

准备 Azure 资源

如果您还没有 Azure 订阅,可以 创建免费帐户

首先,让我们设置正确的 Azure AD 目录和订阅

$ az login --tenant <your_tenant_uri>
$ az account set --subscription <your_subscription_guid>

请确保将 <your_tenant_uri><your_subscription_guid> 占位符替换为正确的值(例如,your_directory_name@onmicrosoft.com 和 222aaa2a-a2a2-22aa-a222-2aaaa2a22a22)。请注意,如果您只有一个 Azure Active Directory 和一个 Azure 订阅,那么不带任何额外参数的 az login 命令就足够了。

要发布我们的应用程序,我们需要设置一些 Azure 资源,即:一个带有文件共享的存储帐户和一个容器注册表。我们可以通过 Azure 门户或命令行创建它们。我们将使用后者,通过 bash 和 azure-cli

LOCATION='westeurope'
BASE_NAME='mld10api'
RG_NAME='rg-'$BASE_NAME
STORAGE_NAME=$BASE_NAME'store'
SHARE_NAME=$BASE_NAME'share'
ACR_NAME=$BASE_NAME'acr'

az group create --name $RG_NAME --location $LOCATION
STORAGE_ID=$(az storage account create -n $STORAGE_NAME --resource-group $RG_NAME --location $LOCATION --sku Standard_LRS --query 'id')
STORAGE_KEY=$(az storage account keys list --resource-group $RG_NAME --account-name $STORAGE_NAME --query '[0].value' --output tsv)
az storage share create --name $SHARE_NAME --account-name $STORAGE_NAME  --account-key $STORAGE_KEY
ACR_ID=$(az acr create -n $ACR_NAME --resource-group $RG_NAME --sku 'Basic' --admin-enabled --query 'id')
ACR_KEY=$(az acr credential show --name $ACR_NAME --query 'passwords[0].value' --output tsv)

请确保在所有步骤中使用单个控制台会话,因为我们需要在后续语句中访问新定义的变量(包括 STORAGE_IDSTORAGE_KEYACR_IDACR_KEY)。

构建容器映像并推送到 Azure 容器注册表

要构建容器映像并将其推送到我们新创建的 Azure 容器注册表,我们需要一个简单的命令

$ IMAGE_TAG=$BASE_NAME'img:v1'
$ az acr build --registry $ACR_NAME --image $IMAGE_TAG .

请注意,您甚至不需要安装 Docker 即可使用此命令,因为构建在云端运行。或者,如果您希望使用本地 Docker 安装构建映像,可以使用以下序列

$ docker login $ACR_NAME.azurecr.io
$ docker build -t $IMAGE_TAG .
$ docker tag $IMAGE_TAG $ACR_NAME.azurecr.io/$IMAGE_TAG
$ docker push $ACR_NAME.azurecr.io/$IMAGE_TAG

创建和运行容器

现在我们只剩一步了——在 Azure 上创建并运行容器实例。我们可以使用 az container create 命令来实现。最简单的形式是直接指定所有必需的参数。例如

$ ACI_NAME=$BASE_NAME'aci'
$ ACI_DNS=$BASE_NAME'-nlp-api'
$ az container create \
    --resource-group $RG_NAME \
    --name $ACI_NAME \
    --image $ACR_NAME.azurecr.io/$IMAGE_TAG  \
   --dns-name-label $ACI_DNS \
   --ports 8000 \
   --cpu 1 \
   --memory 4.0 \
   --registry-username $ACR_NAME \
   --registry-password $ACR_KEY \
   --azure-file-volume-account-name $STORAGE_NAME \
   --azure-file-volume-account-key $STORAGE_KEY \
   --azure-file-volume-share-name $SHARE_NAME \
   --azure-file-volume-mount-path /home/mluser/.cache

最后四个 --azure-file-volume-* 属性将我们的 Azure 文件共享映射到容器中的一个卷。这样,即使我们停止、删除并重新创建容器,我们下载并在服务中使用的 NLP 模型也会得到保留。

几分钟后(我们这里指的是分钟——这需要一些时间),我们的容器应该就可以运行了

通过我们的容器服务的 FQDN 地址,后跟“:8000/docs”,我们可以访问我们服务的 OpenAPI 界面,就像之前一样。唯一的区别是现在它托管在 Azure 上

创建支持 GPU 的容器实例

您可能已经注意到 az container create 命令的配置选项非常少(CPU 和 RAM 的数量)。要向容器添加 GPU,我们需要使用配置文件,该文件可以实现为 YAMLAzure Resource Manager (ARM) 模板

有了这些知识,我们可以使用 YAML 配置重新创建我们的容器,这次添加了 GPU 支持

$ az container delete --name $ACI_NAME --resource-group $RG_NAME

$ echo "
apiVersion: '2018-10-01'
name: $ACI_NAME
properties:
  containers:
  - name: $ACI_NAME-1
    properties:
      image: $ACR_NAME.azurecr.io/$IMAGE_TAG
      ports:
      - protocol: TCP
        port: 8000
      resources:
        requests:
          cpu: 1.0
          memoryInGB: 4.0
          gpu:
            count: 1
            sku: K80
      volumeMounts: # Array of volume mounts for the instance
      - name: mluser-cache
        mountPath: /home/mluser/.cache
        readOnly: false
  imageRegistryCredentials: # Credentials to pull a private image
  - server: $ACR_NAME.azurecr.io
    username: $ACR_NAME
    password: $ACR_KEY
  osType: Linux
  restartPolicy: OnFailure
  ipAddress: # IP address configuration of container group
    ports:
    - protocol: TCP
      port: 8000
    type: Public
    dnsNameLabel: $ACI_DNS
  volumes: # Array of volumes available to the instances
  - name: mluser-cache
    azureFile:
      shareName: $SHARE_NAME
      readOnly: false
      storageAccountName: $STORAGE_NAME
      storageAccountKey: $STORAGE_KEY
" >> .containers.yml

$ az container create --resource-group $RG_NAME --file .containers.yml --location $LOCATION

请注意,生成的 .containers.yml 文件包含 Azure 容器注册表 ($ACR_KEY) 和存储帐户 ($STORAGE_KEY) 的密钥(密码)。这就是为什么您在处理它时应该非常小心。您绝不应将其添加到代码存储库中。

az container create 命令使用保存的配置文件来创建和启动容器(这次支持 GPU)。

如果一切顺利,我们的新预测时间应该会大大缩短。在我们的实验中,GPU 推理的速度大约是仅 CPU 部署的两倍。

容器实例限制

使用 Azure 容器实例是在 Azure 云上运行 Docker 容器的最简单方法。但通常,它仅推荐用于快速原型,而不是生产系统。主要原因是可用的可伸缩性选项非常有限,仅限于 CPU 数量、RAM 大小和 GPU 数量。要更改这些值中的任何一个,您都需要重新创建容器实例。如果您需要更高级的可伸缩性选项,例如水平或自动伸缩,您可能需要使用更健壮的工具,例如 Azure 机器学习服务Azure Kubernetes 服务

Azure 清理

为避免不可控的费用,您需要清理不再使用的 Azure 资源。当您使用昂贵的容器主机配置(例如,具有大量 CPU/RAM 或 GPU)时,这一点尤其重要。

最起码,当您不再打算使用容器实例时,应始终停止它

$ az container stop --name $ACI_NAME --resource-group $RG_NAME

如果您想摆脱所有相关资源,可以删除整个资源组

$ az group delete --name $RG_NAME

摘要

我们已成功将自然语言处理 REST API 服务发布到 Azure 云,使用了容器实例。在本系列文章中,我们探讨了将 Docker 容器应用于 ML 任务的几种场景。希望您能从我们的文章中找到有用的内容。如果您有任何疑问,请随时在评论区提问。

© . All rights reserved.