
搞大模型推理集群这一年多我最大的感受是从单卡能跑通到几十卡稳定服务再到奔着千卡规模去设计中间隔着的不是算力卡的数量而是对分布式系统、调度策略和资源开销的认知差。单卡推理是“一个人把活干完”千卡推理则是“一百个人协作还要不让活碎掉”。这篇文章想把我在这条路上反复折腾出来的经验整理清楚从单卡推理的天花板讲起一直到千卡集群的负载均衡与落地细节。如果你是正在做大模型推理服务的研发、运维或者正准备把本地验证完的模型推向多卡环境这篇文章应该能帮你在动手前把架构思路捋顺——包括硬件拓扑、并行策略、调度设计、容量估算以及那些只有实际踩过坑才知道的细节。1. 从单卡推理到集群先搞清楚问题在哪里1.1 单卡推理的上限与隐性瓶颈先说单卡。很多人第一反应是“显存放得下就能跑”但推理的瓶颈从来不只是显存容量而是计算、显存带宽和调度效率三者的叠加。以现在主流的 27B 级别模型为例纯 FP16 权重大约需要 54GB 显存单张 80GB 的 H100 或 A100 是能放下的甚至还能挤出一部分空间给 KV Cache。但从实际业务角度看单卡能支撑的并发吞吐非常有限。我用 Qwen 系列 27B 模型的实测数据来看单卡 H100 在在线推理场景下prefill 阶段每秒能处理几万到十几万个 tokendecode 阶段大概在每秒 3000 到 5000 个 token 之间浮动。这个数字看起来不小可一旦并发上来每请求都独占一部分 KV Cache 显存能同时跑的任务数会被显存硬卡住吞吐曲线很快就从线性变成了平台期。还有一个很多人忽略的问题单卡推理的“输入输出长度”是动态的。如果业务里混着长文档 Summary 和短对话显存分配完全没法提前固定。请求里的长上下文会瞬间把 KV Cache 撑爆而短请求又把算力闲置。这就意味着单卡方案在服务形态稳定的前提下还不错一旦流量波动大波动本身就成了一种开销。所以单卡推理不是“能不能跑”的问题而是“能稳定服务多大流量”的问题。想往上走就需要把请求拆分到多张卡、多个节点上去。这一步才真正进入集群架构的范畴。1.2 从单卡到多卡为什么不能简单复制我的一个朋友踩过这样一个坑第一版上线时单卡能扛住日均几万请求老板说“那再来三台服务器不就行了”。结果把模型文件复制到四台机器上前面挂一个 Nginx 做轮询不到半天就发现问题了——每张卡都在独立服务但不同请求的响应时间差异极大有的请求 300 毫秒返回有的却要等 3 秒。原因很简单没有全局调度Nginx 根本不知道后端哪张卡已经排了长队也不会考虑每张卡当前是否在处理长上下文。简单粗暴复制多卡本质上是把单卡的问题重复了一遍并没有解决资源利用率、负载均衡和失败处理这三件核心事。从架构上来讲多卡之后至少要面对三个新问题请求该由哪张卡处理路由策略从“只此一家”变成了“全局最优选择”需要感知当前节点负载、KV Cache 余量、队列长度等实时状态。模型本身是否要切分发如果模型超过单卡显存或者单个请求的 prefill 计算压力过大就需要把模型切成多份放在多张卡上并行计算这就是张量并行和流水线并行要解决的。单点故障怎么处理某张卡 OOM、某个节点网络抖动系统如何把流量摘掉而不影响整体服务。我一般把推理集群的演进分成三个阶段单机单卡、单机多卡/多机小集群、千卡规模集群。前两个阶段可以用相对简单的方案过渡但到了千卡级别纯粹的“加机器改路由”就行不通了必须把调度、并行、容量和多层负载均衡放在一起重新设计。下面会把这三个阶段的关键决策逐个拆开。2. 集群架构基础算力层、网络层与调度层2.1 算力层的选择从 27B 模型反推硬件需求我先讲一个通用的反推思路毕竟很多团队包括我选型第一步不是“买什么卡”而是“模型多大、QPS 多少、SLA 多高”。以 27B 模型为例我们来算算要几张卡。假设上线目标是 2000 QPS 峰值单请求平均输入 500 token、输出 800 token那么每秒要处理的 token 总量大约是 2000 ×500 800 260 万 token/s。其中 prefill 占比按 500/1300 算decode 占比约 800/1300前者大约 100 万 token/s后者约 160 万 token/s。单张 H100 实测 decode 能到 4000 token/s 左右其他算力卡可能只有 1000~2000 token/s 的水平那就按单卡 1500 估算单纯 decode 就需要 160 万 / 1500 ≈ 1067 张卡的 decode 能力这还不算 KV Cache 压力。所以说千卡也不是拍脑袋定的如果模型更大、输出更长这个数字还会继续往上涨。这也解释了为什么很多团队对 27B 级别的模型选型时第一反应是“量化 更经济的卡”而不是无脑上 H100。我的经验是先用一个粗粒度公式估算再留 30% 左右的冗余最后用真实的压测确定最终规模。算力层还有一个细节不同卡的显存带宽差别很大。推理 decode 阶段是典型的显存带宽密集型任务权重和 KV Cache 都要反复读取。H100 的显存带宽在 3TB/s 左右普通一点儿的推理卡可能只有 1TB/s 上下单卡吞吐差距能拉出三倍。所以选卡时别只看显存够不够带宽和算力比例得更关注。2.2 网络层集群的血管也是容易被低估的瓶颈到了多机集群网络就变成了第一瓶颈。推理请求里的 prefill 阶段尤其是长上下文需要把输入序列完整送入模型如果模型采用了张量并行卡与卡之间每层都要做 AllReduce 通信数据量很大。而 decode 阶段虽然每步计算量小但 TP 组内依然有同步通信开销网络延迟稍微抖一下整组吞吐都会掉。我的建议是同节点内的 8 卡走 NVLink/NVSwitch跨节点走 InfiniBand 或 RoCE。尤其是千卡规模低延迟、无损网络是必须的不要在这个地方省钱。我们当时从千兆以太网切到 RoCE同一个推理服务端到端延迟下降了 40%这还只是单机内部通信的改善。如果是纯数据并行也就是每个节点各自放一份完整模型卡间通信少很多网络压力主要集中在请求分发和结果回传上。这是一种很“省心”的架构也是很多业务早期能跑得稳的原因。我在实际设计里偏爱“数据并行为主 小规模张量并行提升单实例吞吐”的组合方式后面会细说。2.3 调度层Kubernetes 与推理引擎之间的一层“胶水”调度层负责两件事模型实例生命周期管理和请求级路由。模型实例管理可以用 Kubernetes把部署、滚动更新、故障重启都交给平台。请求级路由则要更细腻得多因为 Kubernetes Service 的默认负载均衡策略round-robin根本不感知推理引擎的后端状态。业内主流的做法是Kubernetes 只负责把 Pod 跑起来、健康检查做掉请求路由交给推理网关层。网关要么自己收集每个实例的 metrics要么从推理引擎暴露的接口拿到实时排队长度和 KV Cache 使用率然后决定把请求发给谁。这一层也是可观测性最容易缺失的地方。我的习惯是在网关层把以下指标全部暴露出来每实例已用 KV Cache 比例、当前排队请求数、最近 30 秒平均 decode 速度、prefill 队列长度、GPU 利用率。没有这些数据讨论负载均衡就是盲人摸象。3. 分布式推理的核心技术拆解并行度与显存博弈3.1 数据并行、张量并行、流水线并行怎么组合大模型推理的并行方式主要有三种分别解决不同问题数据并行DP是最常见也最实用的。每张卡或每组卡放一份完整模型请求被分发到不同的副本上。它不加速单个请求但能线性扩展整体吞吐是推理集群的基本盘。张量并行TP把一层网络里的矩阵乘法切到多张卡上每张卡只算一部分然后通过 AllReduce 合并结果。它能让单请求的显存和计算压力分散到多卡但通信开销大一般建议 TP 不超过 4 到 8。流水线并行PP按层把模型切开前一层算完传给后一层。推理场景里它的效率通常不高因为请求是串行流过各段的空闲等待明显除非配合微批次micro-batch把流水线填满但那样又引入额外复杂度。我在实际项目里最常用的组合是每台物理机内部用 TP4 或 TP8 处理大模型单实例各机之间用 DP 模式横向扩展。响应时间敏感的请求可以享受 TP 的加速效果容量扩展则交给 DP 增加副本数。不要一上来就追求“一张卡放不下所以 TP16”跨节点 TP 的通信延迟会让你怀疑人生。3.2 显存分配KV Cache 才是真正的“隐形杀手”很多初次接触推理集群的人有个误区显存主要被模型权重占着。真相是长上下文场景下KV Cache 的显存占用甚至能超过权重。以 27B 模型为例FP16 权重约 54GB。如果并发 32 个请求、平均上下文长度 4096每个 token 的 KV Cache 大小乘以模型层数和注意力头数以后每位请求至少还要占几个 GB。32 路并发就是上百 GB 的额外显存这还是中等长度。随便一个 32K 上下文的长文任务就够把一张 80GB 的卡打满。所以推理引擎的设计里KV Cache 管理是核心。vLLM 的 PagedAttention、TensorRT-LLM 的 KV Cache 池、以及各种带“显存推理优化”的引擎本质上都在做同一件事把显存切成小块按需分配避免预分配浪费同时通过 continuous batching 让多个请求交替地占住空闲显存。我在生产环境里对新手的建议是先别改算法先把“KV Cache 使用率”列为仅次于 GPU 利用率的关键指标。KV Cache 使用率到 90% 以上就意味着并发基本到顶再压请求只会排队。3.3 推理引擎选型vLLM 与 TensorRT-LLM 的取舍推理引擎选型直接影响架构能承载的上限。目前最主流的两个开源方向vLLM 和 TensorRT-LLM。vLLM 开发迭代快、生态广尤其适合快速上线和动态请求。它自带的连续批处理和 PagedAttention 对显存利用率帮助很大运维上也很方便OpenAI 兼容接口现成。缺点是极端吞吐下不如 TensorRT-LLM 压得狠且在部分量化算子上会有兼容问题。TensorRT-LLM 更像“手工优化后的赛道车”预编译内核、图优化、FP8 支持都做得更激进。跑同样模型TensorRT-LLM 在固定输入长度下经常能比 vLLM 高出 20%~30% 的吞吐代价是模型编译时间长、显存分配更静态、部署灵活性差一些。我的实际选择逻辑是这样的如果业务特征非常稳定例如固定 batch 的离线批量推理选 TensorRT-LLM如果是面向在线用户、请求长度波动大的场景选 vLLM再把 vLLM 的调度参数调好。两个引擎也可以混布长尾请求走 vLLM 实例大流量走 TensorRT-LLM 实例由网关层的路由策略统一分发。4. 千卡规模负载均衡从轮询到感知状态的完整方案4.1 为什么要做感知型负载均衡千卡规模下后端实例可能有几十上百个副本每个副本的状态差异非常大有的 GPU 利用率 90% 但排队很短有的利用率 40% 但正处理一堆超长上下文。传统的轮询、随机、连接数最少这些静态策略在此时基本失效。生产环境里我实作过的方案是“两阶段分发”第一层是全局网关router负责接收外部请求并做整体容量控制第二层是每个物理机或每个机柜内的本地分发器dispatcher负责把全局网关转发来的请求具体分配到某张卡上的某个模型实例。两层之间用带权重的负载均衡策略权重由实时上报的指标动态调整。为什么不能全部用一个中心节点分发因为请求到达速率高一个网关处理不过来单点故障的风险也大。拆成两层后全局网关只做粗粒度流量分配和熔断本地分发器做细粒度调度整体可用性和扩展性都会好很多。4.2 等开销负载均衡一个朴素但有效的目标所谓“等开销”是我从成本优化角度吸收过来的概念。字面理解就是让每个后端实例处理请求的开销尽可能相等这里的“开销”不是单纯指请求数量而是算上显存占用、计算时长、排队时延后的综合成本。举一个容易理解的反例假设一张卡正在处理一个输入 4000 token 的请求另一张卡空着。如果网关只看请求数把新请求发给第一张卡那第一张卡的 prefill 压力会瞬间飙高影响当前请求的响应。正确做法是把新请求发给空卡因为空卡处理它的“等开销代价”更低。实现上要用到“预估成本”和“实时反馈”两个信号。预估成本可以由请求的输入长度估算通常 token 数乘以一个系数实时反馈则来自引擎上报的平均 decode 速度和请求排队长度。网关把这些因素加权计算出一个综合分分越低越优先调度。下面是我用过的一个简化公式实例得分 当前排队长度 × 1.0 预估请求 token 数 × 0.3 KV Cache 已用比例 × 0.2 最近 5 分钟平均 decode 时延 × 0.5谁的分低谁优先。这个公式不一定最优但足够在千卡规模下把各实例的负载均衡到非常接近的水平。它最大的好处是好理解和好调参出问题时不用推倒重来。4.3 一次请求的完整旅程结合前面的设计来看一次请求从进入到返回都经过了什么外部请求到达全局网关网关做鉴权、限流、协议转换并根据请求输入长度估算 token 数。网关从心跳维护的“实例状态表”里选出综合分最低的本地分发器转发请求。本地分发器再次检查当前节点各模型实例的 Kv Cache 余量和队列做最后一级路由落到具体 Pod。模型实例执行 prefill 和解码期间 vLLM 或 TensorRT-LLM 会动态分配 KV Cache 显存、和其他请求共享 GPU 算力。返回结果后引擎把本次请求的 token 数、耗时、显存使用情况上报给指标系统指标系统再异步更新网关和分发器的权重表。这套链路里最容易被忽略的是第 5 步的“异步”属性。调度决策用的数据一定是毫秒级之前的不必强求实时状态完全一致只要趋势对、整体均衡就行。我见过有人为了追求“绝对最新”的状态把 metrics 上报频率调到 100ms 一次结果网关消耗大量 CPU 处理状态更新反而拖慢了转发这就是过度设计。5. 容量规划与 SLA一个 27B 模型的千卡实战推演5.1 从吞吐需求反推卡量再到成本账单前文我们粗算过2000 QPS、平均输入 500 输出 800 token 的场景decode 需求大约 160 万 token/s。如果单卡 H100 实测 decode 4000 token/s需要约 400 张卡的 decode 能力再加上 prefill 的算力杯赛以及 KV Cache 显存的多余消耗实际可能需要 600~800 张卡。但如果换成单卡 decode 只有 1500 token/s 的推理卡同样的目标就要 1000 多张卡数量逼近“千卡部署”这个说法。两者背后的成本差不是在卡单价而是在电力、机柜、网络交换机和运维复杂度。很多团队最后选择“用便宜卡堆量”反而总成本更高因为网络和机房设备占了大头。所以我的建议是在容量规划阶段就把每一张卡的“每 token 成本”算出来。公式很简单单卡折旧率 电力 机房分摊 网络分摊 运维人力分摊除以单卡每秒实际产出 token 数。哪张卡的“单位 token 成本”低才是真正更优的解而不是只看采购价。5.2 SLA 指标设计与监控矩阵在线推理场景有三个核心 SLA 指标TTFT首 token 延迟影响体感、TPOT每个输出 token 的间隔影响“流畅感”、整体尾延迟P95/P99。架构设计的每个选择最终都要落到这几个指标上。TP8 降低 TTFT 和 TPOT但增加通信开销DP 副本增多降低排队等待但增加模型总显存。我可以给出一个通用的监控矩阵方便你照着搭指标健康阈值个人经验关键报警点KV Cache 使用率 80% 90% 时排查并发是否过载平均 decode 速度与单卡基线偏差 20%持续 30% 下滑检查网络和邻位任务排队请求数各实例间差异 30%某实例排队数持续飙高检查均衡策略P99 端到端延迟满足业务 SLA连续 5 分钟超标触发扩容或熔断prefill 队列深度 10持续 30大概率是长请求打满节点这套监控我从几十卡一直用到几百卡越到后面越觉得“先保证没有节点过热再谈模型优化”是对的。大部分事故的根因不是模型算不快而是某个节点的资源被长请求吃掉了调度又没来得及摘流量。5.3 扩容与缩容策略千卡规模的集群不是静态的扩容缩容策略直接影响成本和服务稳定性。我的做法是每 5 分钟评估一次全局平均 KV Cache 使用率和 P99 延迟如果连续两轮都超过 80% 或 SLA 红线就触发扩容。用到的技术栈是 Kubernetes HPA 加自定义 Metrics API网关侧再做一次“新增副本预热”处理避免刚拉起的 Pod 被大量流量瞬间打满。这里有个特容易出错的地方推理引擎启动后要加载模型权重27B 模型加载权重可能要几十秒到几分钟而且加载完还不能立刻上量。所以我在网关里设计了一个“新 Pod 冷启动保护”新 Pod 只接收 10% 的流量逐步上调到 100%。否则刚扩容的副本会因为 prefill 大量集中而假死。反向缩容也一样要谨慎。模型推理集群的缩容不能只看 CPU 利用率因为 GPU 利用率高但请求量低缩卡反而影响尾部时延。我一般只在自己确认未来 1 小时不会出现流量高峰时才做缩容宁可多留 20% 冗余。6. 常见问题与排查技巧实录6.1 最高频的五个线上故障我在维护推理集群的过程中把遇到最多的问题整理成了速查表希望能帮你少走弯路。现象初步判断方向我的排查路径某节点响应突然变慢网络拥塞或跨节点 TP 通信抖动查 RoCE/IB 的丢包和重传其次查邻居节点是否跑满带宽部分请求超时报错网关状态表过期把请求发给已满实例调状态上报频率、增加重试逻辑前端网关加熔断GPU 利用率高但吞吐低TP 通信开销过大或 decode 阶段带宽触顶检查 TP 组规模考虑降 TP 增加 DP 副本KV Cache 使用率飙升后 OOM请求上下文长度超过预留池上限检查预填充策略在网关层按输入长度分流到不同池子新扩容 Pod 加载后流量冲垮冷启动保护失效新副本直接接受全量流量检查网关的权重预热逻辑和就绪探针设置这些问题的共性在于大部分不是“卡不够”而是调度信息不准确或者保护机制不到位。上生产前把这几项检查一遍能省掉无数次半夜起来看日志的体验。6.2 我踩过的一些坑专门写出来第一个坑是关于模型加载时间的。曾经把一个 27B 模型部署在 Kubernetes 上Pod 启动时从共享存储加载权重每次要 3 分多钟。K8s 的 readiness probe 判存活但流量网关不等 Pod 加载完成就把请求发进去了结果新 Pod 一边加载一边推理直接 OOM。后来我把“加载完成”才打开监听端口作为标准做法网关从也只在端口通后开始转发。第二个坑是关于长请求的饿死问题。在线服务里 90% 是短对话但 10% 是长文档摘要每个长请求的 KV Cache 占用可能是短请求的 20 倍。如果不加区分地做连续批处理长请求会长时间霸占显存池导致短请求排队的 P99 抖动非常大。我们的解法是给模型实例挂两组队列短请求队列和长请求队列用严格优先级加权重轮转来调度长请求最多占用 30% 的算力配额。这样一来长尾任务没有被饿死短请求的尾延迟也稳了下来。第三个坑是关于监控数据打架的。某些推理引擎暴露的 GPU 利用率指标是整卡的但一个实例可能跑在一张卡的 MIG 实例里也可能和另一个模型实例共享一张物理卡。按整卡指标做调度会产生严重误判。现在我的标准做法是所有调度决策数据必须来自推理引擎内部的请求级指标排队数、KV Cache 已用比例、prefill 时间而不是 GPU 层的物理指标。物理指标留给告警和机房看不参与路由决策。最后说两句我个人的体会是大模型推理集群的架构设计和写业务代码完全是两种思维。业务代码要搞定的是功能逻辑集群架构要搞定的是资源分配与不确定性。千卡集群真正难的不是堆机器而是让每一张卡都明白自己该干什么让流量永远知道去哪里最划算。从单卡推理到千卡负载均衡这条路不是一步登天的改造而是一轮一轮压测、排障、调参堆出来的。如果你正准备动手我的建议是先拿一张卡把瓶颈测透再扩到两台机器把网络摸清最后才谈得上千卡规模的整体架构。祝你少踩坑多跑通。