部署初始化#
serve.llm 部署的初始化阶段涉及多个步骤,包括模型权重准备、引擎(vLLM)初始化以及 Ray Serve 副本自动扩缩容的开销。下面详细介绍了使用 serve.llm 和 vLLM 的步骤。
启动分解#
配置节点:如果 GPU 节点不可用,则必须配置新实例。
镜像下载:将镜像下载到目标实例会产生与镜像大小相关的延迟。
固定 Ray/节点初始化:Ray/vLLM 在启动新进程以处理新副本时会产生一些固定开销,包括导入大型库(如 vLLM)、准备模型和引擎配置等。
模型加载:从 Hugging Face 或云存储检索模型,包括下载模型并将其移至 GPU 内存所花费的时间。
Torch 编译:Torch 编译是 vLLM 设计不可或缺的一部分,默认启用。
内存分析:vLLM 对模型运行一些推理,以确定可用于 KV 缓存的可用内存量。
CUDA 图捕获:vLLM 会提前捕获不同输入大小的 CUDA 图。更多详细信息请参见此处。
预热:初始化 KV 缓存,运行模型推理。
本文档将概述自定义部署初始化的多种方法。
从 Hugging Face 加载模型#
默认情况下,Ray Serve LLM 从 Hugging Face Hub 加载模型。使用 model_source 指定模型来源。
from ray import serve
from ray.serve.llm import LLMConfig, build_openai_app
llm_config = LLMConfig(
model_loading_config=dict(
model_id="llama-3-8b",
model_source="meta-llama/Meta-Llama-3-8B-Instruct",
),
accelerator_type="A10G",
)
app = build_openai_app({"llm_configs": [llm_config]})
serve.run(app, blocking=True)
加载受限模型#
受限的 Hugging Face 模型需要身份验证。通过 runtime_env 传递您的 Hugging Face 令牌。
from ray import serve
from ray.serve.llm import LLMConfig, build_openai_app
import os
llm_config = LLMConfig(
model_loading_config=dict(
model_id="llama-3-8b-instruct",
model_source="meta-llama/Meta-Llama-3-8B-Instruct",
),
deployment_config=dict(
autoscaling_config=dict(
min_replicas=1,
max_replicas=2,
)
),
accelerator_type="A10G",
runtime_env=dict(
env_vars={
"HF_TOKEN": os.environ["HF_TOKEN"]
}
),
)
app = build_openai_app({"llm_configs": [llm_config]})
serve.run(app, blocking=True)
您也可以通过传递给 ray.init 的方式在整个集群范围内设置环境变量。
import ray
ray.init(
runtime_env=dict(
env_vars={
"HF_TOKEN": os.environ["HF_TOKEN"]
}
),
)
从 Hugging Face 快速下载#
使用 Hugging Face 的 hf_transfer 库启用快速下载。
安装库
pip install hf_transfer
设置
HF_HUB_ENABLE_HF_TRANSFER环境变量。
from ray import serve
from ray.serve.llm import LLMConfig, build_openai_app
llm_config = LLMConfig(
model_loading_config=dict(
model_id="llama-3-8b",
model_source="meta-llama/Meta-Llama-3-8B-Instruct",
),
accelerator_type="A10G",
runtime_env=dict(
env_vars={
"HF_HUB_ENABLE_HF_TRANSFER": "1"
}
),
)
app = build_openai_app({"llm_configs": [llm_config]})
serve.run(app, blocking=True)
从远程存储加载模型#
从 S3 或 GCS 存储桶加载模型,而不是从 Hugging Face 加载。这对于以下情况很有用:
未在 Hugging Face 上托管的私有模型
在同一区域从云存储更快地加载
自定义模型格式或微调模型
S3 存储桶结构#
您的 S3 存储桶应包含 Hugging Face 兼容结构中的模型文件。
$ aws s3 ls air-example-data/rayllm-ossci/meta-Llama-3.2-1B-Instruct/
2025-03-25 11:37:48 1519 .gitattributes
2025-03-25 11:37:48 7712 LICENSE.txt
2025-03-25 11:37:48 41742 README.md
2025-03-25 11:37:48 6021 USE_POLICY.md
2025-03-25 11:37:48 877 config.json
2025-03-25 11:37:48 189 generation_config.json
2025-03-25 11:37:48 2471645608 model.safetensors
2025-03-25 11:37:53 296 special_tokens_map.json
2025-03-25 11:37:53 9085657 tokenizer.json
2025-03-25 11:37:53 54528 tokenizer_config.json
配置 S3 加载 (YAML)#
在 model_loading_config 中使用 bucket_uri 参数。
# config.yaml
applications:
- args:
llm_configs:
- accelerator_type: A10G
engine_kwargs:
max_model_len: 8192
model_loading_config:
model_id: my_llama
model_source:
bucket_uri: s3://anonymous@air-example-data/rayllm-ossci/meta-Llama-3.2-1B-Instruct
import_path: ray.serve.llm:build_openai_app
name: llm_app
route_prefix: "/"
使用以下命令部署
serve deploy config.yaml
配置 S3 加载 (Python API)#
您还可以使用 Python 配置 S3 加载。
from ray import serve
from ray.serve.llm import LLMConfig, build_openai_app
llm_config = LLMConfig(
model_loading_config=dict(
model_id="my_llama",
model_source=dict(
bucket_uri="s3://my-bucket/path/to/model"
)
),
accelerator_type="A10G",
engine_kwargs=dict(
max_model_len=8192,
),
)
app = build_openai_app({"llm_configs": [llm_config]})
serve.run(app, blocking=True)
配置 GCS 存储桶加载 (YAML)#
对于 Google Cloud Storage,使用 gs:// 协议。
model_loading_config:
model_id: my_model
model_source:
bucket_uri: gs://my-gcs-bucket/path/to/model
S3 凭证#
对于私有 S3 存储桶,请配置 AWS 凭证。
选项 1:环境变量
llm_config = LLMConfig(
model_loading_config=dict(
model_id="my_model",
model_source=dict(
bucket_uri="s3://my-private-bucket/model"
)
),
runtime_env=dict(
env_vars={
"AWS_ACCESS_KEY_ID": os.environ["AWS_ACCESS_KEY_ID"],
"AWS_SECRET_ACCESS_KEY": os.environ["AWS_SECRET_ACCESS_KEY"],
}
),
)
选项 2:IAM 角色(生产环境推荐)
使用具有适当 S3 读取权限的 EC2 实例配置文件或 EKS 服务账户。
S3 和 RunAI Streamer#
S3 可以与 RunAI Streamer 结合使用,RunAI Streamer 是 vLLM 中的一个扩展,可实现直接从远程云存储流式传输模型权重到 GPU 内存,从而提高模型加载延迟。更多详细信息请参见此处。
llm_config = LLMConfig(
...
model_loading_config={
"model_id": "llama",
"model_source": "s3://your-bucket/Meta-Llama-3-8B-Instruct",
},
engine_kwargs={
"tensor_parallel_size": 1,
"load_format": "runai_streamer",
},
...
)
模型分片#
现代 LLM 模型的大小通常会超出单个 GPU 的内存容量,需要使用张量并行在多个设备之间分割计算。在此范例中,每个 GPU 仅存储一部分权重,模型分片可确保每个设备仅加载模型的相关部分。通过提前分片模型文件,我们可以显着减少加载时间,因为 GPU 避免加载不必要的权重。vLLM 为此目的提供了一个实用脚本:save_sharded_state.py。
保存分片权重后,将其上传到 S3,并使用带有新标志的 RunAI Streamer 来加载分片权重。
llm_config = LLMConfig(
...
engine_kwargs={
"tensor_parallel_size": 4,
"load_format": "runai_streamer_sharded",
},
...
)
附加优化#
Torch 编译缓存#
Torch.compile 在初始化期间会产生一些延迟。可以通过保留 torch 编译缓存来缓解此问题,该缓存由 vLLM 自动生成。要检索 torch 编译缓存,请运行 vLLM 并查找类似以下的日志。
(RayWorkerWrapper pid=126782) INFO 10-15 11:57:04 [backends.py:608] Using cache directory: /home/ray/.cache/vllm/torch_compile_cache/131ee5c6d9/rank_1_0/backbone for vLLM's torch.compile
在此示例中,缓存文件夹位于 /home/ray/.cache/vllm/torch_compile_cache/131ee5c6d9。将此目录上传到您的 S3 存储桶。现在可以在启动时检索缓存文件夹。我们提供了一个自定义实用程序,用于从云存储下载编译缓存。在 LLMConfig 中指定 CloudDownloader 回调,并提供相关参数。确保在 compilation_config 中正确设置 cache_dir。
llm_config = LLMConfig(
...
callback_config={
"callback_class": "ray.llm._internal.common.callbacks.cloud_downloader.CloudDownloader",
"callback_kwargs": {"paths": [("s3://samplebucket/llama-3-8b-cache", "/home/ray/.cache/vllm/torch_compile_cache/llama-3-8b-cache")]},
},
engine_kwargs={
"tensor_parallel_size": 1,
"compilation_config": {
"cache_dir": "/home/ray/.cache/vllm/torch_compile_cache/llama-3-8b-cache",
}
},
...
)
检索编译缓存的其他选项(分布式文件系统、块存储)也可以使用,只要将缓存路径设置在 compilation_config 中即可。
自定义初始化行为#
我们提供了通过 CallbackBase 定义的 API 来创建自定义节点初始化行为的能力。该类中定义的 callback 函数会在初始化过程的特定部分被调用。一个例子是上面提到的 CloudDownloader,它会重写 on_before_download_model_files_distributed 函数,将下载任务分布到各个节点。要启用您的自定义 callback,请在 LLMConfig 中指定类名。
from user_custom_classes import CustomCallback
config = LLMConfig(
...
callback_config={
"callback_class": CustomCallback,
# or use string "user_custom_classes.CustomCallback"
"callback_kwargs": {"kwargs_test_key": "kwargs_test_value"},
},
...
)
注意: Callbacks 是一个新功能。随着我们继续开发此功能,我们可能会更改 callback API 并整合用户反馈。
最佳实践#
模型来源选择#
使用 Hugging Face 获取公开可用的模型和快速原型开发。
使用远程存储存储私有模型、自定义微调模型,或在与计算资源共置时使用。
启用快速下载以从 Hugging Face 下载大型模型。
安全性#
切勿将令牌提交到版本控制。使用环境变量或秘密管理。
在 AWS 上进行生产部署时,请使用 IAM 角色而不是访问密钥。
将权限范围限定为只读访问以加载模型。
性能#
将存储和计算资源共置于同一云区域,以减少延迟和出口成本。
对于大于 10GB 的模型,使用快速下载(
HF_HUB_ENABLE_HF_TRANSFER)。如果您反复部署相同的模型,请将模型缓存在本地。
请参见基准测试此处,了解有关优化的详细信息。
故障排除#
从 Hugging Face 下载速度慢#
安装
hf_transfer:pip install hf_transfer。在
runtime_env中设置HF_HUB_ENABLE_HF_TRANSFER=1。考虑将模型移动到您云区域中的 S3/GCS 并使用 RunAI Streamer,并对大型模型使用分片。
S3/GCS 访问错误#
验证存储桶 URI 格式(例如,
s3://bucket/path或gs://bucket/path)。检查 AWS/GCP 凭证和区域是否已正确配置。
确保您的 IAM 角色或服务账户具有
s3:GetObject或storage.objects.get权限。验证存储桶是否存在且可从您的部署区域访问。
未找到模型文件#
验证模型结构是否与 Hugging Face 格式匹配(必须包含
config.json、分词器文件和模型权重)。检查存储桶中是否包含所有必需文件。
另请参阅#
快速入门 - 基本 LLM 部署示例。