1. 项目概述:LiteLLM 是什么,它解决的到底是什么问题?
LiteLLM 这个名字乍一听容易让人误以为是某个轻量级大模型,但其实它压根不训练模型、不推理模型,它是个“协议翻译器”——更准确地说,是一个统一的 API 网关层。我第一次在某跨平台 AI 工具开发中遇到它,是在把本地部署的 Ollama 模型、云上托管的 Groq 推理服务、还有公司私有化部署的某国产大模型 SDK 全部接入同一个前端时,被各家接口的参数命名、错误码格式、流式响应结构、token 计费逻辑搞到崩溃。比如 OpenAI 的messages字段是数组,而某国产模型要求叫chat_history;Groq 返回的usage里带prompt_tokens,Ollama 却只返回total_duration,根本没 token 数;更别提流式响应里,有的用data: {...},有的直接返回 JSON 数组,前端解析起来像在解谜。LiteLLM 就是为这种“多源异构 LLM 接入混乱”而生的——它不碰模型权重,只做一件事:把所有下游模型的千奇百怪的 API 行为,统一成 OpenAI 兼容的接口标准。你只要会调 OpenAI 的/v1/chat/completions,就能无缝切换后端是本地 CPU 跑的 Phi-3、是云端 GPU 跑的 Llama-3-70B,还是某企业私有知识库增强的定制模型。它不是替代模型,而是让模型“可插拔”的操作系统层。对开发者而言,这意味着:写一次调用逻辑,就能对接 100+ 种模型后端;对运维而言,意味着灰度发布新模型时,前端完全无感;对产品而言,意味着用户提问时,系统能自动路由到响应最快、成本最低、或合规性最强的那个模型实例。它解决的从来不是“模型好不好”,而是“怎么让好模型用得不累”。
2. 核心设计思路与方案选型逻辑
2.1 为什么不是自己写个适配器?LiteLLM 的不可替代性在哪?
很多人第一反应是:“这不就是个 if-else 转发器?我自己写个中间件不就完了?”我试过——真写了,而且写了三版。第一版用 Python Flask 写了个简易路由,支持 OpenAI 和 Anthropic;第二版加了缓存和重试,支持了 5 家;第三版想加 token 统计和负载均衡,代码开始失控:每个模型的异常处理逻辑不同(有的超时抛TimeoutError,有的返回{"error": "rate_limit"}),重试策略要单独配置,token 计算得查每家文档再硬编码公式……两周后,这个“简易中间件”变成了 800 行难以维护的胶水代码,且新增一个模型平均要花 4 小时。LiteLLM 的核心价值,恰恰在于它把这种“重复造轮子”的痛苦,转化成了标准化的工程实践。它的设计不是堆功能,而是分层解耦:
- 协议层:严格遵循 OpenAI REST API 规范(包括路径、HTTP 方法、请求/响应字段、状态码语义),连
X-RateLimit-Remaining这种细节都模拟到位; - 适配层:每个模型后端(如
anthropic,groq,ollama,together_ai)都有独立的 adapter 模块,只负责“输入转输入”(把 OpenAI 格式转成本地模型能懂的)和“输出转输出”(把本地模型原始响应映射回 OpenAI 标准字段); - 治理层:内置重试(指数退避)、熔断(失败率阈值)、超时控制(per-request/per-model)、token 预估(基于 prompt 长度 + 模型 tokenizer)、甚至简单的负载均衡(round-robin / least-used)。
这种分层让扩展性极强:新增一个模型,你只需要实现两个函数——convert_to_model_input()和convert_from_model_response(),其余治理能力开箱即用。我后来给 LiteLLM 提交了一个国产模型的 adapter PR,从 fork 到测试通过,只用了 90 分钟,其中 60 分钟花在读对方文档确认字段含义上,代码本身不到 100 行。这才是它碾压自研方案的关键:它不是工具,而是生态基础设施。
2.2 为什么选 Python?性能瓶颈如何应对?
LiteLLM 用 Python 实现,常被质疑“高并发下性能不行”。这确实是个真问题,但它的定位决定了这不是致命伤。我们来算笔账:假设你有个客服系统,QPS 峰值 200,平均每次请求耗时 1.2 秒(含模型推理),那么 LiteLLM 层实际承担的只是请求转发、JSON 解析/序列化、日志记录这些操作,耗时通常在 5~15ms 之间。用uvicorn启动 4 个 worker,轻松扛住 200 QPS。真正卡脖子的是模型推理本身,LiteLLM 只是“快递员”,不负责“生产货物”。如果你的场景是毫秒级低延迟(比如实时语音转文字后接 LLM),那 LiteLLM 确实不适合——你应该用 Rust 或 Go 写更轻量的网关。但绝大多数业务场景(Web 应用、内部工具、数据分析助手),LiteLLM 的 Python 实现反而成了优势:生态丰富(httpx异步 HTTP 客户端、pydantic数据校验、litellm自己的ModelResponse类型系统)、调试友好(pdb 直接进源码)、扩展成本低(Python 写 adapter 比 Rust 快 3 倍)。我们线上环境用gunicorn + uvicorn部署,配合nginx做负载均衡和 SSL 终止,单节点稳定支撑 500+ QPS,CPU 使用率常年低于 30%。性能优化的优先级永远是:先确保模型推理快,再考虑网关快;LiteLLM 把前者留给专业模型服务,专注把后者做到“足够好且足够简单”。
2.3 为什么兼容 OpenAI 而非其他标准?
OpenAI API 已成为事实上的行业标准。这不是因为技术最优,而是生态最大:LangChain、LlamaIndex、Dify、Cursor、CodeWhisperer……几乎所有主流 AI 开发框架和 IDE 插件,都默认对接 OpenAI 接口。LiteLLM 选择兼容它,本质是拥抱生态,降低迁移成本。想象一下:如果你的团队已经在用 LangChain 的ChatOpenAI类,现在想把后端从gpt-4-turbo切到本地qwen2-7b,传统做法是重写所有llm = ChatOpenAI(model="gpt-4-turbo")为llm = QwenChat(...),并修改所有提示词模板(因为 Qwen 的 system message 处理逻辑不同)。而用 LiteLLM,你只需改一行环境变量:export OPENAI_API_BASE="http://localhost:4000",然后保持ChatOpenAI(model="qwen2-7b")不变——因为 LiteLLM 在/v1/chat/completions接口里,已经把qwen2-7b的行为“伪装”成了 OpenAI。这种零代码改造的平滑迁移,是任何自定义协议都无法提供的商业价值。它不试图定义新标准,而是成为旧标准的“万能转接头”。
3. 核心细节解析与实操要点
3.1 最小可行部署:从零启动一个 LiteLLM 服务
部署 LiteLLM 的门槛极低,但“能跑”和“能用”是两回事。下面是我验证过的最小可行方案,包含关键配置和避坑点:
# 1. 创建虚拟环境(强烈建议,避免依赖冲突) python -m venv litellm-env source litellm-env/bin/activate # Linux/Mac # litellm-env\Scripts\activate # Windows # 2. 安装核心包(注意:liteLLM 本身不包含模型,只管调度) pip install litellm # 3. 启动服务(最简命令,监听本地 4000 端口) litellm --host 0.0.0.0 --port 4000此时,你的 LiteLLM 服务已运行,但后端是空的——它默认不连接任何模型。你需要通过环境变量或配置文件告诉它“谁来干活”。最常用的是环境变量方式:
# 启动前设置环境变量(示例:同时接入 Ollama 和 Groq) export OLLAMA_API_BASE="http://localhost:11434" export GROQ_API_KEY="gsk_xxx" # 替换为你的 Groq Key # 再次启动(自动加载 Ollama 和 Groq 的 adapter) litellm --host 0.0.0.0 --port 4000提示:LiteLLM 启动时会自动扫描所有已设置的
*_API_KEY或*_API_BASE环境变量,并为对应模型启用 adapter。无需额外配置文件,适合快速验证。
但生产环境绝不能这么干。原因有三:一是密钥明文暴露在进程环境里,不安全;二是无法精细化控制每个模型的超时、重试等参数;三是多模型共存时,路由策略不明确。所以,必须用配置文件:
# config.yaml model_list: - model_name: gpt-3.5-turbo litellm_params: model: "openai/gpt-3.5-turbo" api_key: "sk-xxx" # 生产环境应使用 secrets manager api_base: "https://api.openai.com/v1" timeout: 60 max_retries: 2 - model_name: qwen2-7b litellm_params: model: "ollama/qwen2:7b" api_base: "http://localhost:11434" timeout: 120 max_retries: 1 - model_name: llama3-70b litellm_params: model: "groq/llama3-70b-8192" api_key: "gsk_xxx" timeout: 90 max_retries: 0 # Groq 本身稳定性高,关闭重试启动命令变为:
litellm --config config.yaml --host 0.0.0.0 --port 4000注意:
model_name是你对外暴露的模型标识符(如前端调用时传model="qwen2-7b"),litellm_params.model才是 LiteLLM 内部识别的真实后端模型名(格式为<provider>/<model-id>)。这个分离设计让你可以自由映射,比如把model_name: "prod-chat"指向litellm_params.model: "groq/llama3-70b-8192",而测试环境指向ollama/phi-3-mini,前端代码完全不用改。
3.2 关键参数详解:超时、重试、熔断如何协同工作?
LiteLLM 的健壮性,全靠这几个参数的精细配合。它们不是孤立的,而是一套故障应对流水线:
timeout(单请求超时):这是第一道防线。它定义了从 LiteLLM 发出请求到收到完整响应的最长等待时间。注意:这不是模型推理时间,而是整个 HTTP 请求周期。设得太短(如 10s),会导致正常慢模型(如本地 7B 模型在 CPU 上跑)频繁超时;设得太长(如 300s),会让用户等待体验极差。我的经验是:对云端模型(Groq/OpenAI),设 60~90s;对本地 Ollama,根据硬件设 120~300s。计算依据很简单:本地 7B 模型在 16GB RAM 的 Mac M1 上,首 token 延迟约 800ms,生成 500 字符需 15~25s,加上网络抖动,留 3 倍余量(75s)比较稳妥。max_retries(重试次数):超时后触发。LiteLLM 默认使用指数退避(Exponential Backoff):第一次重试等 1s,第二次等 2s,第三次等 4s……总等待时间 = 2^n - 1 秒。设max_retries=2,最坏情况要等 7s 才放弃。这里的关键是:只对可重试错误重试。LiteLLM 内置了智能判断——对503 Service Unavailable、429 Too Many Requests、连接超时等网络层错误重试;对400 Bad Request(参数错误)、401 Unauthorized(密钥失效)这类客户端错误,直接返回,绝不重试。这点比自己写重试逻辑靠谱得多。circuit_breaker(熔断器):这是最高阶的保护。当某个模型连续失败(如 5 次请求中 4 次超时),LiteLLM 会将其“熔断”——在接下来 60 秒内,所有发往该模型的请求直接返回503,不再转发。这防止了故障扩散:比如 Ollama 服务崩溃,前端不断重试,导致 LiteLLM 线程池被占满,进而拖垮其他正常模型(如 Groq)。熔断参数在配置文件中这样写:model_list: - model_name: qwen2-7b litellm_params: model: "ollama/qwen2:7b" # ... 其他参数 circuit_breaker: threshold: 0.8 # 失败率阈值(80%) cooldown: 60 # 熔断冷却时间(秒) min_sample_size: 5 # 最小采样请求数(至少5次才评估)
这三者的关系是:timeout控制单次请求生死,max_retries给偶然故障一次补救机会,circuit_breaker则是系统级的自我保护。我在线上环境把timeout设为 90s,max_retries设为 1(重试一次),circuit_breaker.threshold设为 0.75,这套组合拳让服务可用性从 99.2% 提升到 99.95%。
3.3 Token 统计与成本监控:如何让“看不见的消耗”变得可量化?
LiteLLM 最被低估的能力之一,是它对 token 消耗的精准预估和统计。很多团队只关注“模型能不能用”,却忽略了“用了多少”。而 token 是 AI 服务真正的成本单元。LiteLLM 在两个层面提供支持:
请求前预估(Estimation):当你发送一个
chat/completions请求时,LiteLLM 会根据messages内容,调用对应模型的 tokenizer(如tiktoken对 OpenAI,transformers对 HuggingFace 模型)计算prompt_tokens和max_tokens(如果指定了max_tokens参数)。这个预估结果会写入日志,并可通过litellm.success_callback钩子捕获。例如,你调用qwen2-7b,传入 300 字中文 prompt,LiteLLM 会告诉你prompt_tokens: 420,estimated_completion_tokens: 150(基于max_tokens=150的设定)。响应后精确统计(Actual Count):对于支持返回 token 数的模型(如 OpenAI、Groq、Anthropic),LiteLLM 会原样透传
usage字段;对于不返回的模型(如 Ollama),它会在响应返回后,用相同 tokenizer 对content字段进行二次计算,生成completion_tokens。最终合并为标准的usage对象:"usage": { "prompt_tokens": 420, "completion_tokens": 187, "total_tokens": 607 }
要开启详细日志和回调,启动时加参数:
litellm --config config.yaml --debug --log-level debug --success-callback "langfuse" --failure-callback "sentry"注意:
--debug会打印所有请求/响应的原始 JSON,包括 token 统计,但会显著增加日志体积,生产环境建议用--log-level info并配合success_callback。我们用langfuse作为 callback,所有 token 消耗、延迟、模型路由信息自动入库,BI 看板上就能看到“今天 Qwen2-7b 消耗了 240 万 tokens,占总成本的 63%”,这比拍脑袋优化有效十倍。
4. 实操过程与核心环节实现
4.1 场景实战:构建一个“自动模型路由”的智能问答服务
我们以一个真实需求为例:某内部知识库问答系统,需要根据问题复杂度、用户权限、实时负载,动态选择最合适的模型。规则如下:
- 简单查询(< 50 字,含“怎么”、“什么是”)→ 用本地
phi-3-mini(快、便宜); - 中等复杂(50~200 字,含“分析”、“对比”)→ 用
qwen2-7b(平衡); - 高复杂(> 200 字,或含“代码”、“SQL”)→ 用
groq/llama3-70b(强但贵); - VIP 用户 → 所有问题强制走
groq/llama3-70b; - 当
qwen2-7b熔断时,自动降级到phi-3-mini。
实现这个路由,不需要改 LiteLLM 源码,只需利用它的dynamic_model_routing功能和litellm.Router类:
from litellm import Router import re # 1. 初始化 Router(传入配置文件) router = Router(config_file_path="config.yaml", num_retries=1) # 2. 定义路由函数 def route_model(user_query: str, user_role: str = "user") -> str: # 规则1:VIP用户强制走高端模型 if user_role == "vip": return "llama3-70b" # 规则2:按字数和关键词判断复杂度 query_len = len(user_query) if query_len < 50 and re.search(r"(怎么|什么是|如何)", user_query): return "phi-3-mini" elif 50 <= query_len <= 200 and re.search(r"(分析|对比|优劣)", user_query): return "qwen2-7b" elif query_len > 200 or re.search(r"(代码|SQL|写一个)", user_query): return "llama3-70b" else: # 默认兜底 return "qwen2-7b" # 3. 调用时动态指定模型 def ask_question(user_query: str, user_role: str = "user"): model_name = route_model(user_query, user_role) try: response = router.completion( model=model_name, messages=[{"role": "user", "content": user_query}], temperature=0.3, max_tokens=512 ) return response.choices[0].message.content except Exception as e: # 如果目标模型不可用(如熔断),Router 会自动 fallback 到其他可用模型 # 但我们也可以手动降级 if model_name == "qwen2-7b": fallback_model = "phi-3-mini" response = router.completion( model=fallback_model, messages=[{"role": "user", "content": user_query}], temperature=0.3, max_tokens=512 ) return f"[降级] {fallback_model}: " + response.choices[0].message.content raise e # 测试 print(ask_question("Python中如何用pandas读取CSV文件?", user_role="vip")) # 输出:[使用 groq/llama3-70b 生成的详细代码]这个例子展示了 LiteLLM 的核心价值:它把复杂的模型治理逻辑,从“硬编码在业务里”变成了“可配置、可插拔、可降级”的服务。你甚至可以把route_model函数换成一个小型 LLM(比如用phi-3-mini自己判断问题复杂度),形成“LLM 调度 LLM”的递归架构。
4.2 高级技巧:用 LiteLLM 实现“模型微调效果的 A/B 测试”
A/B 测试是验证模型改进效果的黄金标准。但传统做法是部署两套服务,流量分流,成本高、周期长。LiteLLM 提供了更轻量的方案——model_group和routing_strategy。
假设你微调了一个qwen2-7b的变体qwen2-7b-finetuned,想和原版对比效果。步骤如下:
在配置文件中定义模型组:
model_list: - model_name: qwen2-7b-base litellm_params: model: "ollama/qwen2:7b" api_base: "http://localhost:11434" - model_name: qwen2-7b-finetuned litellm_params: model: "ollama/qwen2-finetuned:latest" api_base: "http://localhost:11434" # 定义一个模型组,包含两个候选模型 model_group: - group_name: "qwen2-7b-abtest" models: ["qwen2-7b-base", "qwen2-7b-finetuned"] routing_strategy: "least-busy" # 或 "simple-shuffle"(随机) # 支持权重分配:models: [{"model_name": "qwen2-7b-base", "weight": 0.7}, {"model_name": "qwen2-7b-finetuned", "weight": 0.3}]前端调用时,直接请求模型组名:
curl http://localhost:4000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "qwen2-7b-abtest", "messages": [{"role": "user", "content": "解释量子纠缠"}] }'
LiteLLM 会自动根据routing_strategy选择一个模型执行,并在响应头中返回x-litellm-model-group和x-litellm-chosen-model,方便你记录日志:
x-litellm-model-group: qwen2-7b-abtest x-litellm-chosen-model: qwen2-7b-finetuned你只需在日志系统里过滤这两个 header,就能分别统计两组回答的用户满意度(如点赞率)、平均响应时间、token 消耗,一周内就能得出“微调是否真的提升了效果”的结论。我们做过一次测试:微调后qwen2-7b在内部技术文档问答的准确率从 68% 提升到 79%,但 token 消耗增加了 12%,综合 ROI 评估后决定上线。整个 A/B 测试过程,没有动一行业务代码,也没有新增服务器资源。
4.3 安全加固:生产环境必须做的 5 件事
LiteLLM 开箱即用,但默认配置绝不能直接上生产。以下是我在三个不同客户项目中总结出的、必须落地的 5 项安全加固措施:
API 密钥绝不硬编码:配置文件中的
api_key必须替换为环境变量引用。LiteLLM 支持${ENV_VAR_NAME}语法:model_list: - model_name: openai-gpt4 litellm_params: model: "gpt-4-turbo" api_key: "${OPENAI_API_KEY}" # 从环境变量读取启动前执行
export OPENAI_API_KEY="sk-xxx",密钥不会出现在配置文件或进程命令行中。强制 HTTPS 和身份认证:LiteLLM 本身不提供 TLS 终止,必须前置
nginx或cloudflare。同时,用--api_key参数启用基础认证:litellm --config config.yaml --api_key "sk-litellm-prod-xxx" --host 0.0.0.0 --port 4000所有请求必须带
Authorization: Bearer sk-litellm-prod-xxx,否则 401 拒绝。限制请求大小和频率:通过
--max_request_size和--rate_limit参数防滥用:litellm --config config.yaml \ --max_request_size 10485760 \ # 10MB,防超大 prompt --rate_limit 100 \ # 每分钟最多 100 次请求 --rate_limit_type "user" # 按 Authorization header 中的 user id 限流禁用危险模型和功能:在配置文件中显式禁用不信任的模型:
# 禁用所有未在 model_list 中声明的模型 general_settings: allow_unknown_models: false # 禁用执行代码的模型(如某些支持 code interpreter 的模型) model_list: - model_name: "disabled-code-model" litellm_params: model: "openai/gpt-4-turbo" # 但不配置 api_key,使其无法调用审计日志全量留存:启用
--log-file并配置日志轮转:litellm --config config.yaml \ --log-file "/var/log/litellm/access.log" \ --log-level info \ --log-rotate-interval "daily" \ --log-rotate-backup-count 30日志包含:时间戳、IP、模型名、prompt 长度、响应时间、token 数、状态码。我们用 ELK 栈收集,设置告警:当
5xx错误率 > 1% 或平均延迟 > 10s 时,立即通知。
提示:这 5 件事做完,你的 LiteLLM 服务就达到了金融级应用的基本安全水位。少做任何一项,都可能在某次安全审计中被一票否决。
5. 常见问题与排查技巧实录
5.1 典型问题速查表
| 问题现象 | 可能原因 | 排查命令/方法 | 解决方案 |
|---|---|---|---|
调用返回404 Not Found | LiteLLM 服务未启动,或端口被占用 | curl -v http://localhost:4000/health;netstat -tuln | grep 4000 | 检查服务进程;改用其他端口启动--port 4001 |
调用返回400 Bad Request,错误信息"model xxx not found" | model_name在配置文件中拼写错误,或未在model_list中声明 | litellm --config config.yaml --debug查看启动日志,搜索"Loaded model" | 核对配置文件中model_name和调用时传入的model参数是否完全一致(区分大小写) |
| 调用长时间无响应(> 2min),日志无报错 | 后端模型服务(如 Ollama)崩溃,或网络不通 | curl -v http://localhost:11434/api/tags(测试 Ollama);telnet localhost 11434 | 重启 Ollama;检查防火墙规则 |
usage字段中completion_tokens为 0 | 后端模型未返回 token 数,且 LiteLLM 未能成功调用 tokenizer 计算 | litellm --debug查看原始响应体,确认是否含usage;检查模型是否在litellm.supported_models列表中 | 对于 Ollama,确保ollama show qwen2:7b --modelfile显示 tokenizer 正确;或手动在配置中指定tokenizer: "qwen" |
503 Service Unavailable频繁出现 | 某个模型被熔断,或max_retries耗尽 | litellm --config config.yaml --debug查看熔断日志;检查circuit_breaker配置 | 临时提高cooldown时间;或在配置中为该模型设circuit_breaker: null(禁用熔断,仅用于排障) |
5.2 我踩过的 3 个深坑与独家修复技巧
坑1:Ollama 模型加载后,首次请求极慢(> 30s)
现象:Ollama 服务启动后,第一次调用qwen2-7b,LiteLLM 等 35 秒才返回,后续请求正常(< 2s)。日志显示Loading model...。
原因:Ollama 的 lazy loading 机制——模型文件在首次请求时才从磁盘加载到 GPU/CPU 内存。LiteLLM 的timeout设置为 90s,虽然没超时,但用户体验极差。
修复技巧:在 LiteLLM 启动后,主动“预热”模型。写一个简单的预热脚本,在服务启动后立即调用:
# warmup.py import requests import time # 等 LiteLLM 启动完成 time.sleep(5) response = requests.post( "http://localhost:4000/v1/chat/completions", headers={"Authorization": "Bearer sk-litellm-prod-xxx"}, json={ "model": "qwen2-7b", "messages": [{"role": "user", "content": "hi"}], "max_tokens": 1 } ) print("Pre-warmed:", response.status_code)把这个脚本加入你的部署流程(如 systemd service 的ExecStartPost),确保每次重启后自动预热。我们还给qwen2-7b配置了timeout: 180,专门应对预热期。
坑2:Groq API 返回429,但 LiteLLM 不重试
现象:Groq 的 rate limit 是每分钟 30 次,当 QPS 达到 30,部分请求返回429 Too Many Requests,但 LiteLLM 日志显示max_retries=1却没重试。
原因:LiteLLM 的重试逻辑默认只对429的Retry-Afterheader 大于 0 时才重试。而 Groq 的429响应中Retry-After是空的,导致 LiteLLM 认为“不可重试”。
修复技巧:强制开启对429的重试。在配置文件中添加:
general_settings: # 强制对 429 错误重试,即使没有 Retry-After retry_429: true或者启动时加参数--retry_429。这个参数在 LiteLLM 1.40+ 版本中引入,但文档里藏得很深,很多用户不知道。
坑3:中文 prompt 被 tokenizer 错误截断,导致回答不完整
现象:传入 1000 字中文 prompt,模型只回复了前 200 字,usage.total_tokens显示 512(刚好是max_tokens设定值),但实际 prompt 很短。
原因:LiteLLM 默认用tiktoken的cl100k_base编码(OpenAI 用的),但中文在该编码下每个字占 2~3 token,导致max_tokens=512实际只能容纳 200 字左右。而qwen2的 tokenizer 是qwen,一个中文字符 ≈ 1 token。
修复技巧:为每个模型显式指定 tokenizer。在配置文件中:
model_list: - model_name: qwen2-7b litellm_params: model: "ollama/qwen2:7b" # 指定正确的 tokenizer tokenizer: "qwen" max_tokens: 2048 # 根据 tokenizer 调整LiteLLM 支持的 tokenizer 列表在官方文档litellm.tokenizers下,qwen、llama、phi都有。不指定时,它会尝试自动推断,但中文场景下推断经常出错。
5.3 性能调优 checklist:从 100 QPS 到 1000 QPS
当你的 LiteLLM 服务需要支撑更高并发时,光靠加机器不够,必须做针对性调优。这是我整理的 checklist,按优先级排序:
升级到最新版 LiteLLM:1.45+ 版本对
httpx异步客户端做了深度优化,QPS 提升 40%。命令:pip install --upgrade litellm。用
uvloop替代默认 event loop:pip install uvloop litellm --config config.yaml --uvloop # 启动时加 --uvloop 参数在我们的压测中,
uvloop让单核 QPS 从 220 提升到 310。**调整 `gunicorn