LiteLLM Proxy - 在 locust 上进行 1K RPS 负载测试
如何在 locust 上使用 LiteLLM Proxy 达到 1K+ RPS 的教程
测试前的检查清单
- 确保你使用的是 最新版本的
-stable
的 litellm - 确保你遵循了 所有 生产环境的最佳实践
- Locust - 确保你的 Locust 实例能够每秒创建 1K+ 请求
- 👉 你可以使用我们维护的 Locust 实例
- 如果你自己托管 Locust
- 使用这个 运行 litellm proxy 的机器规格
- 企业版 LiteLLM - 在你的
proxy_config.yaml
中使用prometheus
作为回调,以便在负载测试中获取指标 设置litellm_settings.callbacks
以监控成功/失败/所有类型的错误litellm_settings:
callbacks: ["prometheus"] # 仅限企业版 LiteLLM - 使用 prometheus 获取负载测试指标
负载测试 - 假的 OpenAI 端点
预期性能
指标 | 数值 |
---|---|
每秒请求数 | 1174+ |
中位响应时间 | 96ms |
平均响应时间 | 142.18ms |
运行测试
- 在你的 proxy config.yaml 中添加
fake-openai-endpoint
并启动你的 litellm proxy litellm 提供了一个可以进行负载测试的托管fake-openai-endpoint
model_list:
- model_name: fake-openai-endpoint
litellm_params:
model: openai/fake
api_key: fake-key
api_base: https://exampleopenaiendpoint-production.up.railway.app/
litellm_settings:
callbacks: ["prometheus"] # 仅限企业版 LiteLLM - 使用 prometheus 获取负载测试指标
pip install locust
在你的本地机器上创建一个名为
locustfile.py
的文件。从 litellm 负载测试中复制内容,位于 这里启动 locust 在与步骤 2 中的
locustfile.py
相同的目录中运行locust
locust -f locustfile.py --processes 4
在 locust 上运行负载测试
前往 locust UI,地址为 http://0.0.0.0:8089
设置 用户数=1000, 用户增长数=1000,主机=你的 LiteLLM Proxy 的基本 URL
预期结果
负载测试 - 带速率限制的端点
在每个有 10K RPM 配额的 2 个 LLM 部署上运行负载测试。预计会看到 ~20K RPM
预期性能
- 我们预计在 1 分钟内看到 20,000+ 次成功响应
- 剩余的请求 失败是因为端点超过了其 10K RPM 配额限制 - 来自 LLM API 提供商
指标 | 数值 |
---|---|
1 分钟内成功响应数 | 20,000+ |
每秒请求数 | ~1170+ |
中位响应时间 | 70ms |
平均响应时间 | 640.18ms |
运行测试
- 在你的 config.yaml 中添加 2 个
gemini-vision
部署。每个部署可以处理 10K RPM。(我们在/v1/projects/bad-adroit-crow
路由下设置了一个速率限制为 1000 RPM 的假端点)
info
所有带有 model="gemini-vision"
的请求将在这 2 个部署之间平均负载均衡。
model_list:
- model_name: gemini-vision
litellm_params:
model: vertex_ai/gemini-1.0-pro-vision-001
api_base: https://exampleopenaiendpoint-production.up.railway.app/v1/projects/bad-adroit-crow-413218/locations/us-central1/publishers/google/models/gemini-1.0-pro-vision-001
vertex_project: "adroit-crow-413218"
vertex_location: "us-central1"
vertex_credentials: /etc/secrets/adroit_crow.json
- model_name: gemini-vision
litellm_params:
model: vertex_ai/gemini-1.0-pro-vision-001
api_base: https://exampleopenaiendpoint-production-c715.up.railway.app/v1/projects/bad-adroit-crow-413218/locations/us-central1/publishers/google/models/gemini-1.0-pro-vision-001
vertex_project: "adroit-crow-413218"
vertex_location: "us-central1"
vertex_credentials: /etc/secrets/adroit_crow.json
litellm_settings:
callbacks: ["prometheus"] # 仅限企业版 LiteLLM - 使用 prometheus 获取负载测试指标
pip install locust
在你的本地机器上创建一个名为
locustfile.py
的文件。从 litellm 负载测试中复制内容,位于 这里启动 locust 在与步骤 2 中的
locustfile.py
相同的目录中运行locust
locust -f locustfile.py --processes 4
locust -f locustfile.py --processes 4 -t 60
在locust上运行负载测试
前往位于 http://0.0.0.0:8089 的locust UI,并使用以下设置
预期结果
- 1分钟内成功的响应 = 19,800 = (69415 - 49615)
- 每秒请求数 = 1170
- 中位响应时间 = 70ms
- 平均响应时间 = 640ms
用于调试负载测试的Prometheus指标
指标名称 | 描述 |
---|---|
litellm_deployment_failure_responses | 特定LLM部署的LLM API调用失败总数。标签: "requested_model", "litellm_model_name", "model_id", "api_base", "api_provider", "hashed_api_key", "api_key_alias", "team", "team_alias", "exception_status", "exception_class" |
litellm_deployment_cooled_down | LiteLLM负载均衡逻辑冷却部署的次数。标签: "litellm_model_name", "model_id", "api_base", "api_provider", "exception_status" |
运行Locust的机器规格
指标 | 值 |
---|---|
locust --processes 4 | 4 |
负载测试机器上的vCPUs | 2.0 vCPUs |
负载测试机器上的内存 | 450 MB |
负载测试机器的副本数 | 1 |
运行LiteLLM代理的机器规格
👉 LiteLLM代理的副本数=20 以达到1K+ RPS
服务 | 规格 | CPU | 内存 | 架构 | 版本 |
---|---|---|---|---|---|
服务器 | t2.large | 2vCPUs | 8GB | x86 |
用于测试的Locust文件
import os
import uuid
from locust import HttpUser, task, between
class MyUser(HttpUser):
wait_time = between(0.5, 1) # 请求之间的随机等待时间
@task(100)
def litellm_completion(self):
# 这个不会命中缓存
payload = {
"model": "fake-openai-endpoint",
"messages": [{"role": "user", "content": f"{uuid.uuid4()} This is a test there will be no cache hits and we'll fill up the context" * 150 }],
"user": "my-new-end-user-1"
}
response = self.client.post("chat/completions", json=payload)
if response.status_code != 200:
# 将错误记录在error.txt中
with open("error.txt", "a") as error_log:
error_log.write(response.text + "\n")
def on_start(self):
self.api_key = os.getenv('API_KEY', 'sk-1234')
self.client.headers.update({'Authorization': f'Bearer {self.api_key}'})