首页 / 文章 / LiteLLM 无法看到的内容:对网关下 GPU 服务的监控

LiteLLM 无法看到的内容:对网关下 GPU 服务的监控

LiteLLM 需要 Prometheus、vLLM 指标、cAdvisor 以及追踪功能来监控请求和处理量、队列等待时间、预填充与解码过程、容器重启情况以及主机负载。

975 词

从手动编写的FastAPI网关转向LiteLLM集中式请求日志管理、令牌与虚拟密钥核算功能,同时减少了自定义网关代码的编写。网关仍然只能处理穿过其边界的数据流。生产环境中的服务带来了许多LiteLLM无法单独解答的问题——比如队列管理、预填充与解码方式的选择、容器重启以及主机负载情况,这些因素决定了时长为11秒的调用是正常运行还是出现了故障。

背景

LiteLLM位于请求处理的最前端。它能够记录调用的到达情况、负责处理的模型、令牌使用量、支付费用的虚拟密钥,以及调用的成功或失败状态。对于日常成本追踪而言,这已经满足了财务部门与产品团队的大部分需求。

在那个临界点之下,情况就会发生变化。11秒的请求在负载过重的GPU上可能只是排队等待,而在运行正常的系统中则可能是生成较长回复的时间。从网关层面看两者似乎相同,但实际处理方式却不同。若将它们视为同一指标,就会让值班人员采取错误的应对措施。

在网关之下还有三层结构,每层都需要独立的衡量标准:

  • 模型运行时,即决定延迟的时间。从第一个标记出现到生成结果的时间不仅包括排队等待和预填充时间,还包括解码时间。预填充与解码的吞吐量瓶颈也各不相同。这些数据来自服务引擎自身的/metrics接口(例如vLLM),而非网关。
  • 容器,通过cAdvisor来监控:哪些进程正在占用大量内存,以及哪个容器在夜间被重启过。
  • 主机,通过node-exporter来查看:运行GPU的主机上CPU、内存和磁盘的总使用情况。

之所以需要四个数据来源,是因为没有哪个收集器能够查看所有层面的信息。仅有网关日志而缺乏运行时指标只能呈现部分情况;仅有运行时指标而没有主机和容器的上下文信息,则无法发现那些在凌晨三点重启的“干扰源”。

完整架构

在一台本地GPU服务器上,两个Docker Compose项目被刻意分开以处理不同的功能。

网关相关组件:LiteLLM,用于存储虚拟密钥和交易记录的PostgreSQL数据库,以及用于速率限制缓存的Redis。

监控相关组件:Prometheus、Grafana、node-exporter和cAdvisor。vLLM进程通常在两个组件之外的主机上运行,每个被服务的模型对应一个进程。Prometheus会从这四个目标中采集数据,涵盖与网关相关的指标以及模型本身的指标。这种分离并非出于美观考虑——而是为了让可选的基础设施真正保持其“可选”属性。

关键决策

1. 使用两个compose文件,而非一个。在添加监控功能时,LiteLLM已经在为其他团队提供服务。若将Prometheus整合到同一个compose文件中,那么每次对scrape-config的修改都会影响到生产环境中的网关配置。分开处理可以实现故障隔离:可以自由重建监控系统,而LiteLLM不会受到影响。两者之间的依赖关系是单向的。在不同架构组件之间建立网络连接虽然需要一次性投入,但能降低后续可能出现的风险。即便监控系统出现故障,模型依然可以正常响应;而如果网关失效,监控系统仍能记录主机状态以便后续分析。

2. 默认不包含postgres-exporter或redis-exporter。主机完全可以正常运行这些组件,但它们仍被暂缓使用:

  • 只要LiteLLM运行正常,数据库和缓存的内部状态通常无需通过仪表板查看;故障首先会在网关层面显现。
  • node-exporter、cAdvisor以及/metrics接口已经能够覆盖关键层面。
  • 额外的导出工具只会增加版本数量和运行内存消耗。
  • 未使用的控制面板只会带来维护成本而无实际收益。当与PostgreSQL的连接错误频繁出现、虚拟密钥认证因查询竞争而变慢,或是Redis内存压力成为现实问题时,再重新考虑是否添加导出工具——并在那周内将其加入。把停止使用的标准写下来,这样避免添加工具的决定就不会因遗忘而被忽略。

    3. 保持 Langfuse 的使用。LiteLLM 虽然能统一管理请求的可见性,但单个产品操作往往涉及多次模型调用:检索、总结、后续处理。共享的会话 ID 可以在 LiteLLM 中对这些调用进行分组,但用户体验和留存情况的追踪方式有所不同。网关日志并非用于长期存储的档案。较旧的追踪数据可用于模型更换时的评估,也有助于调试前几周产生的报告。指标可以汇总,而追踪数据则能还原真实情况。前者无论如何都无法完全替代后者——正因如此两者都需要保留。

    实际应用中的操作

    1. 仅在 config.yaml 中声明模型十分不便。属于文件形式的模型会在界面中显示配置标识,若不修改挂载设置并重新加载繁忙的代理,就无法对其进行编辑或删除。而通过管理 API 注册的模型则存储在 PostgreSQL 中,因此系统重启后依然存在:

    curl -X POST <http://localhost:4000/model/new> \
      -H "Authorization: Bearer$LITELLM_MASTER_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "model_name": "CHAT_MODEL",
        "litellm_params": {
          "model": "openai/CHAT_MODEL",
          "api_base": "<http://host.docker.internal:8001/v1>",
          "api_key": "dummy"
        }
      }'
    

    建议将设置配置与模型目录的数据库分开管理。这样的设计能让操作员添加实验性模型,而不会影响其他团队正在使用的网关流程。

    2. Node-Exporter控制面板几乎未被使用。随着工作负载趋于稳定且部署频率降低,主机总数已无法提供有价值的信息。可以保留数据抓取功能,但无需在未被使用的控制面板上投入过多资源。cAdvisor和vLLM控制面板因能反映用户可观察到的延迟情况,而更受关注。

    3. 有用的Grafana模板

    • vLLM社区控制面板(例如公共平台grafana.com上的编号为23991的控制面板)
    • cAdvisor(编号14282)
    • Node Exporter Full(编号1860)

    可将它们作为基准导入,然后删除那些从未被打开的控制面板。

    总结

    警报功能存在明显缺陷:虽然有相关指标,但当阈值被突破时却没有触发任何页面响应。将应用程序的邮件 API 与 GPU 主机相连会混淆不同功能模块,下次应选择更安全的通知方式。从概念上讲,Prometheus 和 Grafana 用于回答那些早已明确需要解答的问题;而 Langfuse 则能追踪某项用户操作在多次调用中的影响。聚合与重构是相辅相成的。如果没有监控计划就进行网关迁移,只会将隐患向下层转移而已。