news 2026/10/21 9:34:51

LiteLLM:统一LLM API网关的原理与工程实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LiteLLM:统一LLM API网关的原理与工程实践

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 的健壮性,全靠这几个参数的精细配合。它们不是孤立的,而是一套故障应对流水线:

  1. 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)比较稳妥。

  2. 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(密钥失效)这类客户端错误,直接返回,绝不重试。这点比自己写重试逻辑靠谱得多。

  3. 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,想和原版对比效果。步骤如下:

  1. 在配置文件中定义模型组:

    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}]
  2. 前端调用时,直接请求模型组名:

    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 项安全加固措施:

  1. 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",密钥不会出现在配置文件或进程命令行中。

  2. 强制 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 拒绝。

  3. 限制请求大小和频率:通过--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 限流
  4. 禁用危险模型和功能:在配置文件中显式禁用不信任的模型:

    # 禁用所有未在 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,使其无法调用
  5. 审计日志全量留存:启用--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 FoundLiteLLM 服务未启动,或端口被占用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,按优先级排序:

  1. 升级到最新版 LiteLLM:1.45+ 版本对httpx异步客户端做了深度优化,QPS 提升 40%。命令:pip install --upgrade litellm。

  2. 用uvloop替代默认 event loop:

    pip install uvloop litellm --config config.yaml --uvloop # 启动时加 --uvloop 参数

    在我们的压测中,uvloop让单核 QPS 从 220 提升到 310。

  3. **调整 `gunicorn

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 9:34:51

C++入门四件套:命名空间、缺省参数、函数重载、引用详解

学完C语言刚迈进C的第一周&#xff0c;大多数人的感受是“语法怎么突然变多了”&#xff1a;namespace、缺省参数、函数重载、引用&#xff0c;每个词单独看都认识&#xff0c;组合在一起就开始混乱。这篇文章不打算把这些概念挨个背一遍&#xff0c;而是把它们当成C在设计时给…

作者头像 李华
网站建设 2026/10/21 9:33:42

Selenide实战指南:告别Selenium等待痛点,构建稳定UI自动化测试

不知道你有没有过这种经历&#xff1a;兴冲冲写了个UI自动化测试用例&#xff0c;跑了一遍通过了&#xff0c;结果再跑一次就挂在元素点击上&#xff0c;报错信息又长又绕&#xff0c;翻代码找了半天&#xff0c;最后发现不过是因为页面加载慢了几百毫秒。我一开始用原生Seleni…

作者头像 李华
网站建设 2026/10/21 9:33:38

三菱FX3U十六仓位称重配料配方程序设计与实现

16仓位配方程序&#xff0c;三菱FX3U&#xff0c;这两个词放在一起&#xff0c;基本就是配料线、多仓称重设备或包装机的控制核心。这台设备一共16个料仓&#xff08;仓位&#xff09;&#xff0c;每个仓位对应一种物料&#xff0c;生产不同产品时&#xff0c;PLC按配方把对应仓…

作者头像 李华
网站建设 2026/10/21 9:32:39

期货量化交易信号加密:独立网关防篡改防重放实践

你在深夜打开交易日志&#xff0c;发现某个回撤异常&#xff0c;反复排查之后&#xff0c;定位到原因不在策略逻辑&#xff0c;而在信号传输环节被“污染”了。这种事在期货量化圈不算罕见。策略本身再优秀&#xff0c;信号在下发执行端的过程中一旦被窃取、篡改或者重放&#…

作者头像 李华
网站建设 2026/10/21 9:29:09

artcraft项目组织思路:轻量分离视觉与逻辑的独立开发实践

1. 从“artcraft”这个名字说起&#xff1a;它到底想解决什么问题第一次看到“artcraft”这个标题&#xff0c;我脑子里蹦出来的第一反应是“艺术”加“手艺”&#xff0c;一个把创意和动手能力揉在一起的东西。后来跟几个做独立开发的朋友聊&#xff0c;发现大家对这个词的理解…

作者头像 李华
网站建设 2026/10/21 9:28:44

飞轮储能与永磁同步电机Simulink仿真:参数计算、控制策略与工程实践

最近在做一个飞轮储能系统的仿真项目&#xff0c;电机端用的是永磁同步电机&#xff08;PMSM&#xff09;&#xff0c;任务是把从物理储能、电机控制到Simulink仿真的整条链路打通。飞轮储能这个概念并不新&#xff0c;但真正能把模型搭到能用的状态、并且波形和能量流都对得上…

作者头像 李华