@keigohtr: 来自Netflix。他们的内部LLM服务方法。In-House LLM Serving at Netflix https://netflixtechblog.com/in-house-l…

X AI KOLs Timeline 新闻

摘要

Netflix分享了他们的内部LLM服务方法,使用vLLM和Triton推理服务器,提供兼容OpenAI的API,并详细介绍了部署策略和生产权衡。

来自Netflix。他们的内部LLM服务方法。 In-House LLM Serving at Netflix https://netflixtechblog.com/in-house-llm-serving-at-netflix-a5a8e799ea2c… 以下各项都有说明。 - 使用vLLM和Triton服务器。 - 提供兼容OpenAI的API。 - 组织部署策略。 他们还利用自己的工程专业知识,给人一种处于前沿的印象。 就我个人而言,我对统一服务系统的细节很好奇。
查看原文
查看缓存全文

缓存时间: 2026/07/20 13:26

Netflix 内部大语言模型服务

来源:https://netflixtechblog.com/in-house-llm-serving-at-netflix-a5a8e799ea2c?gi=7d93391898b8
Netflix 技术博客 (https://netflixtechblog.medium.com/?source=post_page—byline–a5a8e799ea2c—————————————)
作者:AI 平台模型运行时团队与推理团队

引言

大多数组织通过托管 API 来使用大语言模型(LLM)。Netflix 走得更远——我们完全自行运行整个技术栈,从模型部署到推理,都在现有生产环境内完成,而不是单独构建一个 ML 孤岛。其中一些决策并非显而易见,而另一些则是在生产负载下才显露出其权衡。

本文重点介绍那些曾经过慎重考虑替代方案的选择:引擎选择、模型打包、API 表面设计、部署策略以及输出约束执行。目标不仅是分享我们构建了什么,更是说明为什么这样选择,以及生产环境揭示了哪些设计阶段未能预见的问题。

架构概览

Netflix 面向会员规模的 ML 由一个统一的基于 JVM 的服务系统承载,该系统为下游消费者处理端到端流程:路由和 A/B 测试逻辑、候选生成、特征获取、推理、后处理以及各阶段的日志记录。同时支持实时和缓存的批量路径。图 1 展示了目前调用者访问推理的两种方式:通过该服务系统的 gRPC 路径,以及由较新的 LLM 驱动应用使用的直接 HTTP 路径。

推理在哪里运行取决于模型。小型 CPU 模型在进程内运行,避免了远程调用开销。较大的模型需要 GPU——服务系统在本地处理前处理和后处理,但将推理委托给远程服务 Model Scoring Service (MSS)。MSS 是共享的推理后端,在统一接口下支持 XGBoost、TensorFlow、PyTorch 和 LLM,底层由 NVIDIA Triton 推理服务器管理模型加载、批处理和 GPU 调度。

在 Triton 之上是一个 Java 控制平面,负责部署、版本管理、健康检查、自动扩缩容以及多区域发布。模型作者打包其工件并配置部署;控制平面会预配置 GPU 实例、配置 Triton,并编排零停机升级。

点击或按回车查看全尺寸图片

图 1. 服务架构概览

设计决策与实现

四个决策塑造了该平台——引擎、打包、API 表面和发布——按依赖顺序呈现,因为每个决策都会约束下一个。

vLLM 作为默认引擎

该平台最初基于 TensorRT-LLM,这是当时性能出色的推理引擎,并且已与 Triton(MSS 中使用的计算后端)集成。

到 2025 年夏季,两件事发生了变化:开源引擎已基本缩小了与专用技术栈的性能差距;我们的工作负载范围已扩大到包括嵌入生成、用于排序和检索的 prefill 仅推理、自回归解码,以及具有非平凡每步约束逻辑的自定义模型。我们针对这一混合负载重新进行了基准测试,并选择 vLLM 作为默认引擎,基于以下操作适配性:

  • 无需多步编译流水线即可加载自定义模型架构——对于非标准模型迭代更快。
  • 为自定义解码逻辑提供扩展性钩子——对于后面描述的约束解码工作至关重要。
  • 可调试性——与早期 TensorRT-LLM 中编译的引擎相比,更易于检查故障和中间状态。
  • 熟悉度——许多 ML 从业者已经在研究中使用 vLLM,这降低了从研究到生产的交接成本。

将 vLLM 集成到 Triton

选定 vLLM 后,下一步是决定如何为其打包模型。Triton 支持两种方式,而这一选择对可维护性有重大影响——具体而言,模型工件与前端的耦合程度。

  • Python 后端。 作者在打包时定义显式的输入/输出张量规范。这些规范固定在工件中,必须与第三方供应商前端的请求构建器所期望的相匹配,因此每次涉及 I/O 规范的升级都需要对打包代码进行协调更改;否则请求会在运行时失败。
  • vLLM 后端。 工件只是一个指向模型权重和分词器的 JSON 配置。Triton 的 vLLM 后端读取此配置,并在部署时动态生成 I/O 张量规范——作者无需定义它们。模型和前端可以独立演进。

vLLM 后端是架构上正确的默认选择。但在生产中我们遇到了两个问题:

  • Triton/vLLM 版本不匹配。 Triton 的 vLLM 后端是针对特定 vLLM API 表面编译的。当两者发生偏移时——例如,Triton 25.09 导入 vllm.engine.metrics,而该模块在 vLLM 0.11.2 中已被移除——后端会完全无法加载。平台必须在构建服务镜像时锁定兼容版本,并阻止模型作者在打包时覆盖 vLLM 版本。
  • 自定义模型逻辑。 vLLM 后端期望使用标准的 HuggingFace 兼容模型,并处理完整的推理生命周期。需要自定义预处理、后处理或非标准执行(集成流水线、自定义分词化)的模型必须使用 Python 后端,后者提供对 execute() 的完全控制。对于某些模型,这种逃生口可能仍然是必要的。

生态系统兼容的 HTTP 前端

在引擎和打包确定后,下一个问题是调用者如何访问系统。我们系统的一个关键设计目标是 LLM 不应是特殊的雪花。每个模型——无论是 XGBoost 集成还是大规模的 LLM——都通过相同的 gRPC 调用进行评分,因此我们复用相同的客户端库、健康检查和部署流水线。鉴于 OpenAI 兼容 API 接口已成为 LLM 生态系统的事实标准——推理引擎、编排框架、评估工具和客户端库都使用它——因此我们将 OpenAI 兼容 API 作为 gRPC 之外的附加前端进行暴露

这样做的好处体现在从实验到生产的路径中:从托管模型过渡到经过微调的自托管模型——出于质量、延迟、成本或数据隐私原因——几乎是无缝的。相同的 API,最小的代码更改。

获取 Netflix 技术博客的最新故事

免费加入 Medium 即可收到该作者的最新更新。

记住我以加快登录速度

在 API 背后,实现复用了 NVIDIA 的 Triton OpenAI 兼容前端 (https://docs.nvidia.com/deeplearning/triton-inference-server/user-guide/docs/client_guide/openai_readme.html)。它启动一个嵌入式 Triton 服务器,将其包装在 TritonLLMEngine 中,将请求模式转换为 Triton 推理请求,并通过 FastAPI 提供响应。同时启用 KServe HTTP/gRPC 前端,因此可以通过 gRPC 访问同一个 Triton 实例,供 Java 控制平面使用。直接采用 Triton 的前端暴露了一个间隙:response_format——模式接受的参数——在到达 vLLM 之前被静默丢弃,因此请求 JSON 输出的调用者会在没有引导解码约束的情况下继续执行,并可能收到格式错误的 JSON,而平台不会报错。我们通过 git-subtree 方式获取并修补了前端,在请求时将其转换为 vLLM 的引导解码参数。

部署策略

在 API 表面和引擎就绪后,剩下的问题是如何在不丢失请求的情况下推出新版本。GPU 部署的启动时间比 CPU 服务更长,并且模型版本之间的 I/O 模式可能发生变化——这增加了协调问题。平台提供两种策略:

  • 红黑部署 将新版本与当前版本并行部署。一旦新实例通过健康检查,流量将分阶段切换——新版本扩容,同时旧版本以相同速率缩容。如果任何步骤失败,系统会触发原子回滚。当模型接口稳定时,红黑部署是正确的选择。生产环境暴露了一个协调缺口:当新版本需要 I/O 模式变更(例如新的张量维度)时,上游消费者在新模型完全上线之前无法更新其配置,因此在迁移窗口期间不可避免地会将“旧”请求发送到“新”部署,导致失败。
  • 版本化部署 通过为每个 (modelId, modelVersion) 对维护独立的部署来解决这个缺口。多个版本同时提供服务,将模型部署与消费者更新解耦:消费者等待新版本完全就绪后再切换其配置,而旧版本继续为遗留流量提供服务。平台会在不活动后清理旧部署,但始终保留最新版本。权衡之处是在过渡重叠期间 GPU 成本暂时增加

我们建议将变量配置(例如张量形状)直接嵌入到推理模型中,使其与版本无关,从而可以使用更便宜的红黑路径。版本化部署 仅保留给无法避免的接口变更这种罕见情况。

运维注意事项

除了上述四个决策外,还有两个运维细节值得指出——它们都触及了设计阶段未能预见的生产缺口。

启动顺序

启动一个 vLLM-on-Triton 实例涉及几个协调步骤,之后 gRPC 端口才会打开。有两个步骤是非例行的。

  • 模型缓存。 在启动时直接从 S3 或 Hugging Face 下载大型 LLM 速度很慢,足以将冷启动延迟放大到调度器无法容忍的程度。我们在模型发布时就将模型物化到 Amazon FSx 上,因此热启动访问的是高性能文件系统而不是对象存储。
  • 嵌入式 vs 独立 Triton。 当消费者需要 OpenAI 兼容 API 时,Triton 作为嵌入式服务器运行在 OpenAI 兼容前端进程中;否则,它独立运行。这是在打包时按部署配置的。

其余启动步骤是机械性的:解压模型包,通过 Python entry_points 安装自定义 vLLM 插件,清理 Prometheus 多进程目录,并在引擎就绪之前保持 gRPC 端口关闭。

统一监控端点

上面提到的 Prometheus 清理暗示了一个更广泛的监控缺口。vLLM 将监控指标写入 PROMETHEUS_MULTIPROC_DIR 的 .db 文件;Triton 通过自己的 Prometheus 端点报告服务器级别的指标。两者互不知晓,而 Triton 的内置桥接仅暴露了 40 多个 vLLM 指标中的 9 个——缺少关键的指标,例如 token 吞吐量、KV 缓存利用率以及前缀缓存命中率。

我们添加了一个轻量级 HTTP 代理,将两者合并到单个 /metrics 端点:它通过 HTTP 获取 Triton 指标,使用 Prometheus 的 MultiProcessCollector 从磁盘读取 vLLM 指标,并返回合并后的输出。现有的仪表板和告警无需修改即可工作。

深度剖析:大规模约束解码

Netflix 的一些生产工作负载高度依赖对 token 生成的细粒度控制。我们不是在推理后应用业务逻辑——为无效生成买单,然后重试或修复——而是将约束推入解码循环内部,使模型生成的输出天然符合要求。我们通过 vLLM 的自定义 logits 处理器接口实现这一点,将每个约束建模为一个状态机,该状态机随生成的 token 历史演变,并在每一步发出 token 可用性掩码。每个请求都有自己配置的处理器,因为不同请求应用不同的规则。

使这一方案扩展到大规模经历了两个引擎版本:我们最初部署在 vLLM V0 上(V1 存在功能缺口),然后在 2025 年第四季度迁移到 V1,当时它已经成熟。接下来的两个小节是“之前”和“之后”。

为什么第一版无法扩展

我们最初的纯 Python 实现功能上可行,但在扩展性上遇到了瓶颈。在 vLLM V0 中,自定义 logits 处理器是每个请求运行的:GPU 为整个批次生成 logits,CPU 将它们复制过来并等待传输完成,然后约束逻辑对每个请求顺序运行——顺序执行是因为 GIL 阻止 Python 并行化每个请求的工作。因此,logit 处理中的 CPU 时间随批次大小线性增长,导致尾延迟膨胀。端到端延迟变为 CPU 瓶颈,即使模型的前向传播在 GPU 上高效地批处理。这是一个在单请求基准测试中不可见,只有在实际并发下才显现的瓶颈。图 2 展示了这种串行模式。

点击或按回车查看全尺寸图片

图 2. vLLM V0 中 logits 处理器在 CPU 上的串行执行

vLLM V1 实现了批次级别设计

结构性的修复在 vLLM V1 中到来,它将 logits 处理移到了批次级别。我们重写了自定义处理器,使其在批次级别的数据结构上操作,一起计算多个请求的掩码,并用 C++ 多线程重新实现了热路径以绕过 GIL。V1 API 要求通过 update_state(batch_update) 显式跟踪批次成员关系的变更——比 V0 的每请求接口更复杂,但对于在动态演变的批次中保持正确状态是必要的。图 3 显示 logits 处理时间随批次大小增长而保持平稳。

点击或按回车查看全尺寸图片

图 3. vLLM V1 中批处理的 logits 处理器在 CPU 上的执行

运维加固

现在,性能不再是瓶颈。但解码循环中的有状态约束逻辑引入了两个设计阶段未能预见到的问题:

  • 部分预填充。 V1 执行分块预填充,因此一个请求可能跨多个引擎步骤进行预填充。BatchUpdate 缺乏区分请求是完全预填充还是部分预填充的粒度,因此我们添加了内部跟踪。
  • 抢占。 在内存压力下,vLLM 可能逐出一个部分完成的请求的 KV 缓存,并在稍后使用不同的提示和输出 token 列表重新调度它。这会破坏状态机关于输出 token 列表单调增长的假设。我们检测 token 历史在解码步骤之间何时缩短,重置状态机,并从新的提示重新初始化。

总结

我们着手构建一个 LLM 服务平台,以满足广泛的生产 ML 需求——低延迟、深度定制以及与现有基础设施的集成。结果是一个基于 vLLM 和 Triton 的系统,统一在一致的 API 背后,旨在为 ML 从业者提供从实验到生产的快速路径。

经验教训往往来自细节——版本锁定、静默 API 缺口、打包权衡——但解决这些问题使平台更健壮,开发者体验更顺畅。下一阶段的投资反映了我们预期的摩擦点:

  • 系统提示压缩,在不牺牲质量的情况下减少提示长度。
  • vLLM V1 的异步调度
  • 向量化 logits 处理器,作为融合的 GPU 内核运行,而不是 CPU 代码。
  • 更低精度的模型变体,以减少内存占用并提高吞吐量。

我们将继续与这些领域密切合作

相似文章

@yoheinakajima: Netflix的技术栈

X AI KOLs Following

Netflix使用vLLM和NVIDIA Triton构建了一个内部LLM服务平台,通过统一的gRPC和兼容OpenAI的API将自托管模型集成到生产基础设施中,并分享了生产经验。

大语言模型与本地AI硬件的推理引擎(2026版)

X AI KOLs

本文提供了一份全面的指南,针对2026年本地AI硬件上的大语言模型推理引擎,解释了如何根据硬件策略、工作负载和服务模型进行选择,并涵盖了诸如llama.cpp、MLX、ExLlamaV2/3、vLLM、SGLang、TensorRT-LLM和NVIDIA Dynamo等引擎。