跳到内容

Llama 3.3 70B 在 vLLM 上的快速入门指南 - NVIDIA Blackwell & Hopper 硬件

简介

本快速入门指南提供了使用 vLLM 运行 Llama 3.3-70B Instruct 模型的分步说明,并支持 FP8 和 NVFP4 量化,针对 NVIDIA GPU(包括 Blackwell 和 Hopper 架构)进行了优化。它涵盖了完整的设置要求;从访问模型权重、准备软件环境到配置 vLLM 参数、启动服务器和验证推理输出。

本指南适用于寻求使用 NVIDIA 加速堆栈实现高吞吐量或低延迟推理的开发人员和实践者——构建一个包含 vLLM 的 Docker 镜像以进行模型服务,使用 FlashInfer 进行优化的 CUDA 内核,以及使用 ModelOpt 来启用 FP8 和 NVFP4 量化执行。

访问和许可

许可证

要使用 Llama 3.3-70B,您必须首先同意 Meta 的 Llama 3 社区许可 (https://ai.meta.com/resources/models-and-libraries/llama-downloads/)。NVIDIA 的量化版本(FP8 和 FP4)建立在基础模型之上,可在相同的许可下用于研究和商业用途。

模型权重

您只需下载一个模型权重版本,具体取决于使用的精度

下载这些模型权重不需要 Hugging Face 身份验证令牌。

关于量化选择的说明:对于 Hopper,FP8 在大多数工作负载中提供最佳性能。对于 Blackwell,NVFP4 提供了额外的内存节省和吞吐量提升,但可能需要进行调整以在某些任务中保持准确性。

先决条件

  • 操作系统:Linux
  • 驱动程序:CUDA 驱动程序 575 或更高版本
  • GPU:Blackwell 架构或 Hopper 架构
  • NVIDIA 容器工具包

部署步骤

拉取 Docker 镜像

拉取 vLLM v0.12.0 版本的 Docker 镜像。

pull_image.sh

# On x86_64 systems:
docker pull --platform linux/amd64 vllm/vllm-openai:v0.12.0
# On aarch64 systems:
# docker pull --platform linux/aarch64 vllm/vllm-openai:v0.12.0

docker tag vllm/vllm-openai:v0.12.0 vllm/vllm-openai:deploy

运行 Docker 容器

使用 Docker 镜像 vllm/vllm-openai:deploy 运行 Docker 容器。

run_container.sh

docker run -e HF_TOKEN="$HF_TOKEN" -e HF_HOME="$HF_HOME" --ipc=host --gpus all --entrypoint "/bin/bash" --rm -it vllm/vllm-openai:deploy

注意:如果需要,您可以使用 -v <local_path>:<path> 标志挂载其他目录和路径,例如挂载已下载的权重路径。

添加 -e HF_TOKEN="$HF_TOKEN" -e HF_HOME="$HF_HOME" 标志是为了使用您的 HuggingFace 令牌下载模型,并将下载的模型缓存到 $HF_HOME 中。有关这些环境变量的更多信息,请参阅 HuggingFace 文档;有关生成 HuggingFace 访问令牌的步骤,请参阅 HuggingFace 快速入门指南

准备配置文件

准备配置文件 YAML 文件以配置 vLLM。下面分别展示了 Blackwell 和 Hopper 架构的推荐配置文件。这些配置文件也已上传到 vLLM 食谱存储库。每个配置的解释将在“配置和参数”部分显示。

Llama3.3_Blackwell.yaml

kv-cache-dtype: fp8
compilation-config: '{"pass_config":{"fuse_allreduce_rms":true,"fuse_attn_quant":true,"eliminate_noops":true}}'
async-scheduling: true
no-enable-prefix-caching: true
max-num-batched-tokens: 8192

Llama3.3_Hopper.yaml

kv-cache-dtype: fp8
async-scheduling: true
no-enable-prefix-caching: true
max-num-batched-tokens: 8192

启动 vLLM 服务器

下面是一个启动 vLLM 服务器以及 Llama-3.3-70B-Instruct-FP4/FP8 模型的示例命令。

launch_server.sh

# Set up a few environment variables for better performance for Blackwell architecture.
# They will be removed when the performance optimizations have been verified and enabled by default.
COMPUTE_CAPABILITY=$(nvidia-smi -i 0 --query-gpu=compute_cap --format=csv,noheader)
if [ "$COMPUTE_CAPABILITY" = "10.0" ]; then
    # Use FP4 for Blackwell architecture
    # Change this to FP8 to run FP8 on Blackwell architecture
    DTYPE="FP4"
    # Select the config file for Blackwell architecture.
    YAML_CONFIG="Llama3.3_Blackwell.yaml"
else
    # Use FP8 for Hopper architecture
    DTYPE="FP8"
    # Select the config file for Hopper architecture.
    YAML_CONFIG="Llama3.3_Hopper.yaml"
fi

# Launch the vLLM server
vllm serve nvidia/Llama-3.3-70B-Instruct-$DTYPE \
  --config ${YAML_CONFIG} \
  --tensor-parallel-size 1 &

服务器设置完成后,客户端现在可以向服务器发送提示请求并接收结果。

配置与参数

您可以使用这些标志来指定服务器运行的 IP 地址和端口

  • host:服务器的 IP 地址。默认情况下,它使用 127.0.0.1。
  • port:服务器监听的端口。默认情况下,它使用端口 8000。

以下是我们不建议更改或调整的配置标志

  • kv-cache-dtype:KV 缓存数据类型。我们建议将其设置为 fp8 以获得最佳性能。
  • compilation-config:vLLM 编译阶段的配置。我们建议将其设置为 '{"pass_config":{"fuse_allreduce_rms":true,"fuse_attn_quant":true,"eliminate_noops":true}}' 以启用 Blackwell 架构上最佳性能所需的所有必要融合。然而,此功能目前尚不支持 Hopper 架构。
  • async-scheduling:启用异步调度以减少解码步骤之间的主机开销。我们建议始终添加此标志以获得最佳性能。
  • no-enable-prefix-caching 禁用前缀缓存。如果您使用合成数据集进行一致的性能测量,我们建议始终添加此标志。

以下是一些您可以根据您的服务要求修改的可调参数

  • tensor-parallel-size:张量并行大小。增加此值将增加用于推理的 GPU 数量。
  • 将其设置为 1 以实现每个 GPU 的最佳吞吐量,并将其设置为 248 以实现更好的每个用户延迟。
  • max-num-batched-tokens:每个批次的最大令牌数。
  • 我们建议将其设置为 8192。如果序列具有较长的输入序列长度,增加此值可能会略微提高性能。
  • max-num-seqs:每个批次的最大序列数。
  • 默认情况下,在具有大内存大小的 GPU 上,此值设置为 1024 等大数字。
  • 如果实际并发较小,将其设置为与最大并发匹配的较小数字可能会提高性能并改善每个用户的延迟。
  • max-model-len:每个请求的总令牌数(包括输入令牌和输出令牌)的最大值。
  • 默认情况下,此值设置为模型支持的最大序列长度。
  • 如果实际输入+输出序列长度短于默认值,将其设置为较小值可能会提高性能。
  • 例如,如果最大输入序列长度为 1024 令牌,最大输出序列长度为 1024,则可以将其设置为 2048 以获得更好的性能。

有关如何调整这些可调参数以满足您的部署要求,请参阅“平衡吞吐量和延迟”部分。

验证和预期行为

基本测试

在 vLLM 服务器设置完成并显示 Application startup complete 后,您可以向服务器发送请求

run_basic_test.sh

curl http://0.0.0.0:8000/v1/completions -H "Content-Type: application/json" -d '{ "model": "nvidia/Llama-3.3-70B-Instruct-FP4", "prompt": "San Francisco is a", "max_tokens": 20, "temperature": 0 }'

这是一个响应示例,显示 vLLM 服务器返回“一个以充满活力的文化、令人惊叹的建筑和令人惊叹的自然美景而闻名的城市。从标志性的...”,最多完成 20 个 token 的输入序列。

{"id":"cmpl-4493992056a146f0a65363462eee6218","object":"text_completion","created":1754989721,"model":"nvidia/Llama-3.3-70B-Instruct-FP4","choices":[{"index":0,"text":" city that is known for its vibrant culture, stunning architecture, and breathtaking natural beauty. From the iconic","logprobs":null,"finish_reason":"length","stop_reason":null,"prompt_logprobs":null}],"service_tier":null,"system_fingerprint":null,"usage":{"prompt_tokens":5,"total_tokens":25,"completion_tokens":20,"prompt_tokens_details":null},"kv_transfer_params":null}

验证准确性

当服务器仍在运行时,我们可以使用 lm_eval 工具运行准确性测试。

run_accuracy.sh

# Install lm_eval that is compatible with the latest vLLM
pip3 install lm-eval[api]==0.4.9.1

# Run lm_eval
lm_eval \
  --model local-completions \
  --tasks gsm8k \
  --model_args \
base_url=http://0.0.0.0:8000/v1/completions,\
model=nvidia/Llama-3.3-70B-Instruct-FP4,\
tokenized_requests=False,tokenizer_backend=None,\
num_concurrent=128,timeout=120,max_retries=5

这是一个在单个 B200 GPU 上使用 nvidia/Llama-3.3-70B-Instruct-FP4 模型的示例准确性结果

local-completions (base_url=http://0.0.0.0:8000/v1/completions,model=nvidia/Llama-3.3-70B-Instruct-FP4,tokenized_requests=False,tokenizer_backend=None,num_concurrent=128,timeout=120,max_retries=5), gen_kwa
rgs: (None), limit: None, num_fewshot: None, batch_size: 1
|Tasks|Version|     Filter     |n-shot|  Metric   |   |Value |   |Stderr|
|-----|------:|----------------|-----:|-----------|---|-----:|---|-----:|
|gsm8k|      3|flexible-extract|     5|exact_match|↑  |0.9272|±  |0.0072|
|     |       |strict-match    |     5|exact_match|↑  |0.6293|±  |0.0133|

性能基准测试

要进行性能基准测试,您可以使用 vllm bench serve 命令。

run_performance.sh

vllm bench serve \
  --host 0.0.0.0 \
  --port 8000 \
  --model nvidia/Llama-3.3-70B-Instruct-FP4 \
  --trust-remote-code \
  --dataset-name random \
  --random-input-len 1024 \
  --random-output-len 1024 \
  --ignore-eos \
  --max-concurrency 512 \
  --num-prompts 2560 \
  --save-result --result-filename vllm_benchmark_serving_results.json

标志的解释

  • --dataset-name:用于基准测试的数据集。我们这里使用 random 数据集。
  • --random-input-len:指定平均输入序列长度。
  • --random-output-len:指定平均输出序列长度。
  • --ignore-eos:当生成 eos(句尾)令牌时禁用提前返回。这确保了输出序列长度与我们的预期范围匹配。
  • --max-concurrency:最大并发请求数。我们建议将其与用于启动服务器的 --max-num-seqs 标志匹配。
  • --num-prompts:用于性能基准测试的提示总数。我们建议将其设置为 --max-concurrency 的至少五倍,以测量稳定状态性能。
  • --save-result --result-filename:性能基准测试结果的输出位置。

解读性能基准测试输出

vllm bench serve 命令的示例输出

============ Serving Benchmark Result ============
Successful requests:                     xxxxxx
Benchmark duration (s):                  xxx.xx
Total input tokens:                      xxxxxx
Total generated tokens:                  xxxxxx
Request throughput (req/s):              xxx.xx
Output token throughput (tok/s):         xxx.xx
Total Token throughput (tok/s):          xxx.xx
---------------Time to First Token----------------
Mean TTFT (ms):                          xxx.xx
Median TTFT (ms):                        xxx.xx
P99 TTFT (ms):                           xxx.xx
-----Time per Output Token (excl. 1st token)------
Mean TPOT (ms):                          xxx.xx
Median TPOT (ms):                        xxx.xx
P99 TPOT (ms):                           xxx.xx
---------------Inter-token Latency----------------
Mean ITL (ms):                           xxx.xx
Median ITL (ms):                         xxx.xx
P99 ITL (ms):                            xxx.xx
----------------End-to-end Latency----------------
Mean E2EL (ms):                          xxx.xx
Median E2EL (ms):                        xxx.xx
P99 E2EL (ms):                           xxx.xx
==================================================

关键指标的解释

  • Median Time to First Token (TTFT):从发送请求到生成第一个输出令牌的典型时间。
  • Median Time Per Output Token (TPOT):生成第一个令牌后生成每个令牌所需的典型时间。
  • Median Inter-Token Latency (ITL):一个输出令牌(或输出令牌)完成响应与下一个令牌完成响应之间的典型时间延迟。
  • Median End-to-End Latency (E2EL):从提交请求到收到响应的最终令牌的典型总时间。
  • Output token throughput:系统生成输出(已生成)令牌的速率。
  • Total Token Throughput:系统处理输入(提示)令牌和输出(已生成)令牌的总速率。

平衡吞吐量和延迟

在 LLM 推理中,“吞吐量”可以定义为每秒生成的令牌数(上面的 Output token throughput 指标)或每秒处理的令牌数(上面的 Total Token Throughput 指标)。这两个吞吐量指标高度相关。在比较不同的并行配置时,我们通常将吞吐量除以使用的 GPU 数量以获得“每 GPU 吞吐量”。每 GPU 吞吐量越高,服务相同数量的传入请求所需的 GPU 越少。

另一方面,“延迟”可以定义为从发送请求到生成第一个输出令牌的延迟(TTFT 指标),在生成第一个令牌后两个生成令牌之间的延迟(TPOT 指标),或者从发送请求到生成最终令牌的端到端延迟(E2EL 指标)。当输入(提示)序列长度远长于输出(生成)序列长度时,TTFT 对 E2EL 的影响更大,而在相反的情况下,TPOT 对 E2EL 的影响更大。

为了实现更高的吞吐量,来自多个请求的令牌必须批量处理,但这会增加延迟。因此,必须根据部署要求在吞吐量和延迟之间进行平衡。

Llama 3.3 70B 的两个主要可调配置是 --tensor-parallel-size (TP) 和 --max-num-seqs (BS)。它们如何影响吞吐量和延迟可以总结如下

  • 在相同的 BS 下,较高的 TP 通常会导致较低的延迟,但吞吐量也较低。
  • 在相同的 TP 大小下,较高的 BS 通常会导致较高的吞吐量,但延迟较差,但最大 BS 受加载权重后可用 GPU 内存(用于 kv-cache)的限制。
  • 因此,增加 TP(在相同 BS 下会降低吞吐量)可能允许运行更高的 BS(会增加吞吐量),净吞吐量增益/损失取决于模型和配置。

请注意,上述陈述假设客户端的并发设置(例如性能基准测试命令中的 --max-concurrency 标志)与服务器端的 --max-num-seqs (BS) 设置匹配。

以下是 B200 GPU 上不同吞吐量-延迟场景的推荐配置

  • 最大吞吐量:将 TP 设置为 1,并将 BS 增加到可能的最大值,同时不超过 KV 缓存容量。
  • 最小延迟:将 TP 设置为 4 或 8,并将 BS 设置为满足延迟要求的较小值(如 8)。
  • 平衡:将 TP 设置为 2,并将 BS 设置为 128。

最后,另一个次要可调配置是 --max-num-batched-tokens 标志,它控制在一个前向迭代中可以批量处理多少令牌。我们建议将其设置为 8192,这在大多数情况下效果很好。将其增加到 16384 可能会导致吞吐量略高,TTFT 延迟更低,但 TPOT 延迟的分布更不均匀,因为一些输出令牌可能会在同一批次中与更多预填充阶段令牌一起生成。