在 AWS Inferentia 上使用

在 AWS Inferentia 上使用 Amazon EKS 和 vLLM 部署 Meta Llama 3.1-8B

作者 : Maurits de Groot,Dmitri Laptev,Jianying Lang,Ziwen Ning
发布日期 : 2024 年 11 月 26 日
原文连结 :

关键要点

  • 随着大型语言模型(LLMs)如 Meta Llama 3.1 的崛起,部署和提供这些模型的需求日益增长。
  • 本文将详细介绍如何在 AWS 环境中使用 Amazon EKS 部署 Meta Llama 3.1-8B 模型的完整步骤。
  • 这个解决方案着重于使用 Inferentia 2 实例以高效、经济的方式运行大型语言模型。
  • 文章还涵盖了测试、监控性能,以及扩展和多租户选项的信息。

大型语言模型(LLMs)如 Meta Llama 3.1 的出现,催生了对可扩展、可靠和成本有效的解决方案的日益需求。结合 和 的实例,以及 (AmazonEKS),可以在容器化环境中高效且低成本地运行 LLM。

本文将逐步介绍如何在 Inferentia 2 实例上使用 Amazon EKS 部署 模型。

解决方案概览

实施此解决方案的步骤如下:

  1. 创建 EKS 集群。
  2. 设置 Inferentia 2 节点组。
  3. 安装 Neuron 设备插件和调度扩展。
  4. 准备 Docker 镜像。
  5. 部署 Meta Llama 3.1-8B 模型。

我们还将演示如何测试解决方案和监控性能,并讨论扩展与多租户选项。

前提条件

在开始之前,请确保您在本地计算机或开发环境中安装了以下工具。如果尚未安装,请按照每个工具提供的说明进行操作。

  • (AWS CLI)

在本文示例中,使用一个 inf2.48xlarge 实例;请确保您有足够的服务配额来使用此实例。有关如何查看和增加配额的信息,请参见 。

创建 EKS 集群

如果您没有现有的 EKS 集群,可以使用 eksctl 创建一个。请根据您的需求调整以下配置,如 Amazon EKS 版本、集群名称和 AWS区域。在运行以下命令之前,请确保您已 :

bash export AWS_REGION=us-east-1 export CLUSTER_NAME=my-cluster exportEKS_VERSION=1.30 export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --queryAccount --output text)

然后完成以下步骤:

  1. 创建一个名为 eks_cluster.yaml 的新文件:

* * *

apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig

metadata: name: $CLUSTER_NAME region: $AWS_REGION version: "$EKS_VERSION"

addons: \- name: vpc-cni version: latest

cloudWatch: clusterLogging: enableTypes: 。
  * **addons.vpc-cni** – 指定要使用的 Amazon VPC CNI(容器网络接口)附加组件的版本。将其设置为 `latest` 将安装最新的可用版本。
  * **cloudWatch.clusterLogging** – 启用集群日志记录,将控制平面的日志发送到 。
  * **iam.withOIDC** – 启用集群的 OpenID Connect(OIDC)提供者,这对于某些 AWS 服务与集群的交互是必要的。

  * 创建 `eks_cluster.yaml` 文件后,可以通过运行以下命令创建 EKS 集群:

`bash eksctl create cluster --config-file eks_cluster.yaml`

此命令将根据 `eks_cluster.yaml` 文件中指定的配置创建 EKS 集群。该过程大约需要 15-20 分钟完成。

在集群创建过程中,`eksctl` 还将创建一个默认的节点组,并使用建议的实例类型和配置。但是,在下一部分中,我们将创建一个单独的节点组,专门用于运行
Meta Llama 3.1-8B 模型。

  1. 完成 `kubectl` 的设置,运行以下代码:

`bash aws eks update-kubeconfig --region $AWS_REGION --name $CLUSTER_NAME`

## 设置 Inferentia 2 节点组

要运行 Meta Llama 3.1-8B 模型,您需要创建一个 Inferentia 2 节点组。完成以下步骤:

  1. 首先,检索最新的  ID:

`bash export ACCELERATED_AMI=$(aws ssm get-parameter \ --name
/aws/service/eks/optimized-ami/$EKS_VERSION/amazon-
linux-2-gpu/recommended/image_id \ --region $AWS_REGION \ --query
"Parameter.Value" \ --output text)`

  1. 使用 `eksctl` 创建 Inferentia 2 节点组:

```bash cat > eks_nodegroup.yaml <<EOF

* * *

apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig

metadata: name: $CLUSTER_NAME region: $AWS_REGION version: "$EKS_VERSION"

managedNodeGroups: \- name: neuron-group instanceType: inf2.48xlargedesiredCapacity: 1 volumeSize: 512 ami: "$ACCELERATED_AMI" amiFamily:
AmazonLinux2 iam: attachPolicyARNs: \-
arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy \-
arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly \-
arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore \-
arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

    
    
    overrideBootstrapCommand: |
      #!/bin/bash
    
      /etc/eks/bootstrap.sh $CLUSTER_NAME
    

EOF ```

  1. 运行 `eksctl create nodegroup --config-file eks_nodegroup.yaml` 创建节点组。

这将需要大约 5 分钟。

## 安装 Neuron 设备插件和调度扩展

要使您的 EKS 集群适合运行 Inferentia 芯片上的工作负载,您需要安装两个关键组件: 和
Neuron 调度扩展。

Neuron 设备插件是基本配置,用于在 Kubernetes 中将 Neuron 核心和设备作为资源公开。Neuron 调度扩展则能优化调度需要多个
Neuron 核心或设备的 pod。

有关安装和验证这些组件的详细说明,请参阅 。遵循这些说明将帮助确保您的 EKS 集群正确配置,以调度和运行需要工作节点的工作负载,如 Meta Llama3.1-8B 模型。

## 准备 Docker 镜像

要运行模型,您需要准备一个包含所需依赖项的 Docker 镜像。我们使用以下代码创建一个  (Amazon ECR) 存储库,并基于 AWS深度学习容器(DLC)构建自定义 Docker 镜像。

  1. 设置环境变量:

`bash export ECR_REPO_NAME=vllm-neuron`

  1. 创建一个 ECR 存储库:

`bash aws ecr create-repository --repository-name $ECR_REPO_NAME --region
$AWS_REGION`

虽然基础 Docker 镜像已经包含了 TorchServe,但为了简化,这个实现使用了基于 FastAPI 的 vLLM存储库中提供的服务器。您可以在生产环境中将 TorchServe 连接到 vLLM,使用您自己的自定义处理程序。

  1. 创建 Dockerfile:

```bash cat > Dockerfile <<EOF FROM public.ecr.aws/neuron/pytorch-inference-
neuronx:2.1.2-neuronx-py310-sdk2.20.0-ubuntu20.04

# 克隆 vllm 存储库

RUN git clone https://github.com/vllm-project/vllm.git

# 设置工作目录

WORKDIR /vllm RUN git checkout v0.6.0

# 设置环境变量

ENV VLLM_TARGET_DEVICE=neuron

# 安装依赖

RUN python3 -m pip install -U -r requirements-neuron.txt RUN python3 -m pipinstall .

# 修改 arg_utils.py 文件以支持更大的 block_size 选项

RUN sed -i "/parser.add_argument('--block-size',/ {N;N;N;N;N;s/[8, 16, 32]/[8,
16, 32, 128, 256, 512, 1024, 2048, 4096, 8192]/}" vllm/engine/arg_utils.py

# 安装 ray

RUN python3 -m pip install ray RUN pip install -U triton>=3.0.0

# 设置入口点

ENTRYPOINT ["python3", "-m", "vllm.entrypoints.openai.api_server"] EOF ```

  1. 使用以下命令创建 ECR 存储库、构建 Docker 镜像,并将其推送到新创建的存储库。账户 ID 和区域通过 AWS CLI 命令动态设置,使过程更加灵活,避免硬编码值。

```bash

# 认证 Docker 到您的 ECR 注册表

aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com

# 构建 Docker 镜像

docker build -t ${ECR_REPO_NAME}:latest .

# 标记镜像

docker tag ${ECR_REPO_NAME}:latest
$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/${ECR_REPO_NAME}:latest

# 将镜像推送到 ECR

docker push
$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/${ECR_REPO_NAME}:latest ```

## 部署 Meta Llama 3.1-8B 模型

设置完成后,您可以使用 Kubernetes 部署来部署模型。以下是一个请求特定资源并设置多个副本的示例部署规范:

`bash cat > neuronx-vllm-deployment.yaml <<EOF apiVersion: apps/v1 kind:
Deployment metadata: name: neuronx-vllm-deployment labels: app: neuronx-vllmspec: replicas: 3 selector: matchLabels: app: neuronx-vllm template: metadata:
labels: app: neuronx-vllm spec: schedulerName: my-scheduler containers: -
name: neuronx-vllm image: **< 替换为您推送到 ECR 的 Docker 镜像 URL>** resources:
limits: cpu: 32 memory: "64G" aws.amazon.com/neuroncore: "8" requests: cpu: 32memory: "64G" aws.amazon.com/neuroncore: "8" ports: - containerPort: 8000 env:
- name: HF_TOKEN value: **< 您的 huggingface 令牌>** - name: FI_EFA_FORK_SAFEvalue: "1" args: - "--model" - "meta-llama/Meta-Llama-3.1-8B" - "--tensor-
parallel-size" - "8" - "--max-num-seqs" - "64" - "--max-model-len" - "8192" -
"--block-size" - "8192" EOF`

使用 `kubectl apply -f neuronx-vllm-deployment.yaml` 应用部署规范。

该部署配置设置了 Meta Llama 3.1-8B 模型的多个副本,利用 8 的张量并行度 (TP)。在当前设置中,我们在可用的 Neuron核心上托管三个模型副本。此配置允许有效利用硬件资源,同时支持多个并发推理请求。

使用 TP=8 有助于在多个 Neuron 核心之间分配模型,从而提高推理性能和吞吐量。根据具体的硬件设置和性能要求,所用的副本和核心数可能会有所不同。

要修改设置,请更新 `neuronx-vllm-deployment.yaml` 文件,调整部署规范中的 `replicas` 字段和容器规范中的
`NUM_NEURON_CORES` 环境变量。始终验证总的核心数(副本数 * 每个副本的核心数)不会超过可用的硬件资源,并且注意力头的数量应能被 TP度整除,以实现最佳性能。

该部署还包括 Hugging Face 令牌和 EFA fork 安全的环境变量。`args`
部分(见前面的代码)配置了模型及其参数,包括增加的最大模型长度和 8192 的块大小。

## 测试部署

在您部署模型后,重要的是监控其进度并验证其就绪状态。完成以下步骤:

  1. 检查部署状态:

`bash kubectl get deployments`

这将显示您所需的当前副本数和最新副本数。

  1. 监控 pods:

`bash kubectl get pods -l app=neuronx-vllm -w`

`-w` 标志将监控更改。您会看到 pods 从 `"Pending"` 转变为 `"ContainerCreating"`,再到 `"Running"`。

  1. 检查特定 pod 的日志:

`bash kubectl logs <pod-name>`

初始启动过程大约需要 15 分钟。在此期间,模型正在为 Neuron 核心进行编译。您将看到编译进度的日志。

为了支持 vLLM pods 的适当管理,您应该在部署中配置 Kubernetes 探测。这些探测帮助 Kubernetes 确定 pods何时准备好处理流量、何时存活以及何时已成功启动。

  1. 在部署 YAML 中的容器 spec 中添加以下探测配置:

`yaml spec: containers: - name: neuronx-vllm # ... 其他容器配置 ... readinessProbe:
httpGet: path: /health port: 8000 initialDelaySeconds: 1800 periodSeconds: 10livenessProbe: httpGet: path: /health port: 8000 initialDelaySeconds: 1800periodSeconds: 15 startupProbe: httpGet: path: /health port: 8000initialDelaySeconds: 1800 failureThreshold: 30 periodSeconds: 10`

该配置包含三个探测:

  * **就绪探测** – 检查 pod 是否准备好处理流量。它在 60 秒后开始检查,并每 10 秒重复一次。
  * **存活探测** – 验证 pod 是否仍在正常运行。它在 120 秒后开始,并每 15 秒检查一次。
  * **启动探测** – 给应用程序一定的启动时间。在考虑失败之前,它允许应用程序最多有 25 分钟的启动时间。

这些探测假定您的 vLL

Leave a Reply

Required fields are marked *