使用 vLLM 和 Amazon EC2

使用 vLLM 和 AWS AI 芯片在 Amazon EC2 实例上部署大型语言模型

作者:Omri Shiv 和 Pinak Panigrahi
发布日期:2024 年 11 月 26 日
相关文章 :,,,,



关键要点

  • 大语言模型(LLMs)和生成式 AI 在过去一年中迅速增长。
  • 使用 vLLM 和 AWS 架构 可实现高性能推理并支持大规模部署。
  • 本文教你如何在 Amazon EC2 Inf2 实例上快速部署 Meta 的 Llama 模型
  • 提供步骤指导,包括 EC2 实例设置、Docker 容器创建和在线、离线推理演示。

引言

大型语言模型(LLMs)和生成式 AI 的使用近年来已迅速增长。随着强大基础模型的发布,训练、微调和托管自己的 LLM 工具也变得更为便捷。利用 在 AWS 的 和 上,可以实现高效的 LLM 部署和扩展。

在这篇文章中,我们将带你了解如何快速在 上使用 vLLM 部署 。我们将使用 1B 版本,但也可以使用类似步骤部署其它尺寸和流行的 LLM 模型。

在 AWS Trainium 和 Inferentia EC2 实例上部署 vLLM

接下来的部分,我们将指导你如何在 AWS Inferentia EC2 实例上使用 vLLM 部署 Meta 最新的 Llama 3.2模型。你将学习如何请求模型访问、创建 Docker 容器以使用 vLLM 部署模型,以及如何进行在线和离线推理。同时,我们将讨论推理图的性能调优。

前提条件: Hugging Face 帐户和模型访问权限

要使用 meta-llama/Llama-3.2-1B 模型,你需要一个 Hugging Face 帐户并请求对该模型的访问权限。请访问 注册,并同意模型许可证。你将需要一个 Hugging Face 令牌,可以通过 获取。在保存访问令牌 的页面上,请确保复制该令牌,因为它不会再次显示。

删除)

创建 EC2 实例

你可以通过以下 创建 EC2 实例。请注意以下几点:

  1. 如果这是你第一次使用 Inferentia / Trainium 实例,需要 。
  2. 实例类型将使用 inf2.xlargeinf2.xlarge 实例仅在 可用。
  3. 将 gp3 卷增加到 100G。
  4. Deep Learning AMI Neuron (Ubuntu 22.04) 作为你的 AMI,如下图所示。

![创建 EC2删除)

实例启动后,你可以

以访问命令行。在下一步中,你将使用 Docker(在此 AMI 上预安装)运行 vLLM 的 。

启动 vLLM 服务器

你将使用 Docker 创建一个包含所有运行 vLLM 所需工具的容器。使用以下命令创建 Dockerfile:


# 默认基础镜像

ARG BASE_IMAGE="public.ecr.aws/neuron/pytorch-inference-neuronx:2.1.2-neuronx-
py310-sdk2.20.0-ubuntu20.04" FROM $BASE_IMAGE RUN echo "基础镜像为 $BASE_IMAGE"

# 安装基础实用工具

RUN apt-get update && \ apt-get install -y \ git \ python3 \ python3-pip \
ffmpeg libsm6 libxext6 libgl1

### 挂载点

# 启动容器时,将代码目录挂载到 /app

ARG APP_MOUNT=/app VOLUME [ ${APP_MOUNT} ] WORKDIR ${APP_MOUNT}/vllm RUNpython3 -m pip install --upgrade pip RUN python3 -m pip install --no-cache-dirfastapi ninja tokenizers pandas RUN python3 -m pip install sentencepiecetransformers==4.36.2 -U RUN python3 -m pip install transformers-neuronx
--extra-index-url=https://pip.repos.neuron.amazonaws.com -U RUN python3 -m pipinstall --pre neuronx-cc==2.15.* --extra-index-
url=https://pip.repos.neuron.amazonaws.com -U ENV VLLM_TARGET_DEVICE neuronRUN git clone https://github.com/vllm-project/vllm.git && \ cd vllm && \ gitcheckout v0.6.2 && \ python3 -m pip install -U \ cmake>=3.26 ninja packagingsetuptools-scm>=8 wheel jinja2 \ -r requirements-neuron.txt && \ pip install
--no-build-isolation -v -e . && \ pip install --upgrade triton==3.0.0 CMD
["/bin/bash"] EOF ```

然后运行:

`bash docker build . -t vllm-neuron`

构建此镜像大约需要 10 分钟。完成后,使用新的 Docker 镜像(将 `YOUR_TOKEN_HERE` 替换为 Hugging Face 的令牌):

`bash export HF_TOKEN="YOUR_TOKEN_HERE" docker run \ -it \ -p 8000:8000 \
--device /dev/neuron0 \ -e HF_TOKEN=$HF_TOKEN \ -e NEURON_CC_FLAGS=-O1 \ vllm-
neuron`

现在可以使用以下命令启动 vLLM 服务器:

`bash vllm serve meta-llama/Llama-3.2-1B --device neuron --tensor-parallel-
size 2 --block-size 8 --max-model-len 4096 --max-num-seqs 32`

此命令以以下参数运行 vLLM:

  * `serve meta-llama/Llama-3.2-1B`: 部署进行推理的模型的 Hugging Face `modelID`。
  * `--device neuron`: 配置 vLLM 在神经设备上运行。
  * `--tensor-parallel-size 2`: 设置张量并行的划分数。inf2.xlarge 有 1 个神经设备,每个神经设备有 2 个神经核心。
  * `--max-model-len 4096`: 设置要编译的模型的最大序列长度(输入标记加上输出标记)。
  * `--block-size 8`: 对于神经设备,这个值会被内部设置到最大模型长度。
  * `--max-num-seqs 32`: 设置硬件批处理大小或模型服务器需要处理的期望并发级别。

首次加载模型时,如果没有先前编译的模型,则需要进行编译。可以选择保存此编译的模型,以便在重新创建容器时无须再次编译。完成所有步骤后,模型服务器应该会开始运行,你应该会看到以下日志:

`bash Avg prompt throughput: 0.0 tokens/s ...`

这意味着模型服务器正在运行,但尚未处理请求,因为尚未收到任何请求。你可以通过按下 `ctrl + p` 和 `ctrl + q` 来分离容器。

### 推理

启动 Docker 容器时,你使用了命令 -p 8000:8000。这告诉 Docker 将容器的 8000 端口转发到本地机器的 8000端口。当你运行以下命令时,你应该会看到 `meta-llama/Llama-3.2-1B` 模型服务器正在运行。

`bash curl localhost:8000/v1/models`

这应该返回类似如下内容:

`json {"object":"list","data":[{"id":"meta-
llama/Llama-3.2-1B","object":"model","created":1732552038,"owned_by":"vllm","root":"meta-
llama/Llama-3.2-1B","parent":null,"max_model_len":4096,"permission":[{"id":"modelperm-6d44a6f6e52447eb9074b13ae1e9e285","object":"model_permission","created":1732552038,"allow_create_engine":false,"allow_sampling":true,"allow_logprobs":true,"allow_search_indices":false,"allow_view":true,"allow_fine_tuning":false,"organization":"*","group":null,"is_blocking":false}]}]}`

现在,发送一个提示:

`bash curl localhost:8000/v1/completions \ -H "Content-Type: application/json" \ -d '{"model": "meta-llama/Llama-3.2-1B", "prompt": "What is Gen AI?", "temperature":0, "max_tokens": 128}' | jq '.choices[0].text'`

你应该会收到 vLLM 返回的类似响应:

`bash " How does it work?\nGen AI is a new type of artificial intelligencethat is designed to learn and adapt to new situations and environments. It isbased on the idea that the human brain is a complex system that can learn andadapt to new situations and environments. Gen AI is designed to be able tolearn and adapt to new situations and environments in a way that is similar tohow the human brain does.\nGen AI is a new type of artificial intelligencethat is designed to learn and adapt to new situations and environments. It isbased on the idea that the human brain is a complex system that can learn andadapt to new situations and environments."`

### 使用 vLLM 进行离线推理

使用 vLLM 的另一种方式是在脚本中同时发送多个请求。这在自动化中非常有用,或者当你有一批提示想要一次发送时。

你可以重新连接到 Docker 容器,并使用以下命令停止在线推理服务器:

`bash docker attach $(docker ps --format "{{.ID}}")`

此时,你应该会看到一个空光标,按 `ctrl + c` 停止服务器,并返回到容器中的 bash 提示符。创建一个用于离线推理引擎的文件:

```bash cat > offline_inference.py <<EOF from vllm.entrypoints.llm import LLMfrom vllm.sampling_params import SamplingParams

# 示例提示。

prompts = [ "Hello, my name is", "The president of the United States is", "Thecapital of France is", "The future of AI is", ]

# 创建一个采样参数对象。

sampling_params = SamplingParams(temperature=0.8, top_p=0.95)

# 创建一个 LLM 实例。

llm = LLM(model="meta-llama/Llama-3.2-1B", max_num_seqs=32,
max_model_len=4096, block_size=8, device="neuron", tensor_parallel_size=2)

# 从提示生成文本。输出是包含提示、生成文本及其他信息的 RequestOutput 对象的列表。

outputs = llm.generate(prompts, sampling_params)

# 输出结果。

for output in outputs: prompt = output.prompt generated_text =
output.outputs[0].text print(f"Prompt: {prompt!r}, Generated text:
{generated_text!r}")

EOF ```

现在运行脚本 `python offline_inference.py`,你应该会收到四个提示的响应。这可能需要一点时间,因为模型需要重新启动。

`bash Processed prompts:
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████|
4/4 ,以避免额外的费用。

## 处理可变序列长度的性能调优

在 LLM 推理中,你可能需要处理可变长度的序列。神经 SDK会生成桶和一个与桶的形状和大小相匹配的计算图。为了根据推理请求中输入和输出标记的长度优化性能,你可以通过以下环境变量设置两种类型的桶,作为整型列表:

  * `NEURON_CONTEXT_LENGTH_BUCKETS` 对应于上下文编码阶段。设置此值为推理过程中估计的提示长度。
  * `NEURON_TOKEN_GEN_BUCKETS` 对应于标记生成阶段。设置此值为生成长度范围内的 2 的幂次。

你可以在启动 vLLM 服务器时使用 Docker run 命令设置环境变量(记得用你的 Hugging Face 令牌替换
`YOUR_TOKEN_HERE`):

`bash export HF_TOKEN="YOUR_TOKEN_HERE" docker run \ -it \ -p 8000:8000 \
--device /dev/neuron0 \ -e HF_TOKEN=$HF_TOKEN \ -e NEURON_CC_FLAGS=-O1 \ -eNEURON_CONTEXT_LENGTH_BUCKETS="1024,1280,1536,1792,2048" \ -eNEURON_TOKEN_GEN_BUCKETS="256,512,1024" \ vllm-neuron`

你可以使用相同的命令启动服务器:

`bash vllm serve meta-llama/Llama-3.2-1B --device neuron --tensor-parallel-
size 2 --block-size 8 --max-model-len 4096 --max-num-seqs 32`

由于模型图已更改,模型需要重新编译。如果容器终止,将再次下载模型。然后可以通过按 `ctrl + p` 和 `ctrl + q`
从容器中分离,并使用以下相同命令发送请求:

`bash curl localhost:8000/v1/completions \ -H "Content-Type: application/json" \ -d '{"model": "meta-llama/Llama-3.2-1B", "prompt": "What is Gen AI?", "temperature":0, "max_tokens": 128}' | jq '.choices。请注意,`NEURON_CONTEXT_LENGTH_BUCKETS` 在文档中对应于
`context_length_estimate`,而 `NEURON_TOKEN_GEN_BUCKETS` 对应于文档中的 `n_positions`。

## 结论

你刚刚了解到如何在 Amazon EC2 Inf2 实例上使用 vLLM 部署 `meta-llama/Llama-3.2-1B`。如果你有兴趣部署

Leave a Reply

Required fields are marked *