ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

原计算AI:从GPU利用率到KV Cache,重构大模型推理的计算底座

原计算AI:从GPU利用率到KV Cache,重构大模型推理的计算底座 今年上半年我接到好几段线上求助现象几乎一模一样GPU采购审批单越批越多单次推理的响应却越来越慢集群利用率稳定在20%上下谁也说不清算力到底跑哪去了。折腾一圈后所有人都会落到同一个追问——现在的计算体系到底是不是真正为AI准备的这个问题背后牵扯的东西就是我在实际项目里反复验证过的判断把传统云计算的容器、调度、网络方案照搬到AI场景再把GPU当普通加速卡插进去这条路已经很难走通了。真正能解决问题的思路是围绕模型本身的张量流、显存层级和生命周期重新设计一套计算底座也就是标题里写的“原计算AI”。这篇文章不是概念科普而是把这几个月在推理部署、性能调优、故障排查里踩过的坑、得出的结论、能直接抄的参数表格都整理出来。适合正在搞AI应用开发、模型部署、算力平台建设的工程师也适合刚接触AI工程化、想知道GPU买回来该怎么用的技术负责人。我会把能落地的估算公式、选型建议、排查链路全部摊开讲。1. GPU越加越多业务越来越难跑传统计算地基与AI负载的错位1.1 传统云计算的三个关键假设在AI负载面前全部失效大多数公司的AI服务底层还是那套为Web应用设计的计算体系容器调度、微服务、负载均衡、弹性伸缩。这套体系有三个根深蒂固的假设在传统业务里是优点到了AI推理场景反而成了包袱。第一个假设是“请求无状态、随时可迁移”。传统Web服务里一个请求过来容器重启、实例迁移影响很小。AI推理完全不是这样大模型推理进程一旦启动显存里就是几个GB到几十GB的权重和KV Cache迁移一次意味着先把模型重新加载一遍冷启动时间相当于重新拉起一个重型服务。我们实测过一个13B模型从文件系统加载到显存并完成预热的耗时接近三分钟这在传统弹性伸缩体系里几乎不可接受。第二个假设是“横向扩展总能线性提升性能”。传统服务靠增加副本撑住QPS因为每个副本之间互不依赖。AI推理不一样它不仅吃算力更吃显存容量。同一个模型要在多卡之间做张量并行卡间通信频率极高网络拓扑稍差性能就断崖式下跌。盲目加副本最后往往是显存碎片一堆、通信拥堵整集群利用率反而更低。第三个假设是“调度对象是进程粒度越小越灵活”。Kubernetes的最小调度单位是容器但在AI推理里真正的调度对象应该是张量和算子。同一个容器里不同层的算子对算力和带宽的需求差异极大传统调度器完全没有这个感知维度。1.2 “原计算AI”到底在讲什么我理解的“原计算AI”不是某个单一产品而是一套围绕模型执行特征重新构建的计算架构。它把原先隐藏在加速卡背后的那些问题比如张量并行时的通信模式、KV Cache的内存管理、连续批处理的排队逻辑、推理引擎和调度系统的适配关系全部上升为一等公民来设计。可以这样区分传统AI基础设施和原计算AI传统方案是“先有通用计算平台再把模型硬塞进去”原计算AI则是“从模型运行规律出发反过来设计计算平台”。概念落到工程上有三个具体变化。第一资源模型从“请求并发数”变成“令牌流速率”因为生成式推理的核心不是处理无状态请求而是持续产生、消费token的数据流。第二调度单元从“容器实例”下钻到“模型算子”调度器需要考虑算子的显存亲和性、通信拓扑甚至算子间的依赖关系才能避免频繁的显存换入换出。第三存储体系从“本地盘对象存储”变成“权重分级存储显存友好布局”热权重常驻HBM冷权重放CPU内存滚动热载入而不是每次冷启动都从对象存储拖一次模型文件。1.3 一句话判断你需不需要走向原计算判断标准其实很简单如果你的推理服务GPU利用率长期低于30%或者响应时间方差大得离谱又或者每次模型更新都要为冷启动和显存碎片收拾烂摊子那问题大概率不在模型本身而在计算底座。这个时候应该去看推理引擎、调度策略、显存管理这些偏底层的环节而不是急着加卡。2. 部署推理服务前先算清一张“显存与吞吐”的账2.1 模型权重、KV Cache、激活值显存的三座大山很多团队第一次部署大模型以为只要把模型权重塞进显存就行结果一上真实业务就OOM。显存占用远不止权重一项它有三座大山权重、KV Cache、激活值。权重这部分最好算参数量乘以每个参数的字节数。FP16格式下一个7B模型的权重大约是14GB13B模型大约是26GB70B模型就是140GB。INT8量化能砍一半INT4量化再砍一半这是最直观的显存优化手段。KV Cache是生成阶段最容易被低估的部分。它的计算方式是2 × 层数 × KV头数 × 头维度 × 序列长度 × batch大小 × 每个元素字节数。我拿Llama-3-8B来算32层8个KV头每个头128维如果序列长度是2048batch是32FP16存储KV Cache就是2×32×8×128×2048×32×2字节约等于8GB。这还只是单序列2048长度一旦上下文窗口拉到32K或者128K这个数字会翻十几倍。长上下文场景下KV Cache很容易超过模型权重本身的显存占用。激活值在推理阶段看起来不起眼但在较深的网络或者动态batch很大时同样会占据可观空间。只不过现在主流推理引擎会做算子融合把激活值的占用压得比较低所以权重和KV Cache才是主要矛盾。2.2 带宽才是生成速度的隐形天花板显存容量决定能不能跑起来显存带宽决定跑得快不快。很多开发同学第一次看NVIDIA的规格表都会被FP16的TFLOPS数字震撼到实际跑起来却发现远达不到标称值的零头。核心原因在于生成阶段是内存带宽瓶颈计算密集度并不高。自回归生成时每生成一个token都要把整个模型的权重从HBM读到计算单元里跑一遍前向。假设一个7B模型采用FP16权重14GB单张A100的HBM带宽大约是2TB/s那么理论上每生成一个token光是读取权重就要用掉14GB÷2TB/s约7毫秒。也就是说单张A100跑7B模型在权重加载这个环节上就被限制在每秒最多140个token左右这还是理想状态叠加KV Cache读取、激活计算和框架开销实际单卡吞吐有80到100 tok/s已经是相当不错的成绩。这个估算解释了为什么模型一变大速度掉得特别快。70B模型的FP16权重有140GB即使H100有3.35TB/s的带宽每token读取权重也需要大约42毫秒理论最高吞吐也就24 tok/s左右。想提速要么量化压权重体积要么上多卡并行分担带宽压力。很多人觉得多卡并行是为了拼算力其实在生成阶段多卡更大的意义是把权重分摊到多张卡的显存控制器上把带宽翻上去。2.3 显存估算的实操公式我在给团队做容量规划时一般先按下面这个公式快速估算单实例需求显存需求 ≈ 权重占用 KV Cache预算 推理引擎开销 系统预留权重占用 参数量 × bits/8。KV Cache预算 2×层数×KV头数×头维度×目标序列长度×目标并发数×bits/8。推理引擎和CUDA context通常预留2到4GB。系统预留看驱动和部署环境一般1到2GB。举个真实例子。要在一批24GB显存的显卡上部署7B模型FP16权重14GB如果目标并发是16路、每路上下文8KKV Cache的预算就先按8K长度算一遍2×32×8×128×8192×16×2字节约32GB。这就超出了24GB显存直接方案就是两条路把batch压到8或者INT8量化。我们的选择是INT8权重加KV Cache量化权重降到7GBKV Cache的FP16转INT8后约16GB加引擎开销和预留正好压在23GB左右跑得很稳。做容量评估时如果不先把这层账算清楚就会陷入“买了卡、部署不了、再买卡”的循环。3. 推理引擎选型与核心加速机制不是起个TGI就万事大吉3.1 推理引擎的分工与选择原计算AI的架构里推理引擎是最接近模型的一层也是优化空间最大的一层。现在主流的选择有三个阵营vLLM、TensorRT-LLM、SGLang另外还有MindIE之类的商业优化引擎。vLLM是我个人用得最多的。它的核心优势是PagedAttention和连续批处理兼容性极好新模型出来基本几天内就能支持吞吐表现也很稳。SGLang适合需要复杂结构化输出的场景它对多轮对话时的前缀复用有额外优化在Agent类任务里能省不少重复计算。TensorRT-LLM是NVIDIA官方路线性能压得最狠但编译和部署流程也最重适合模型结构固定、流量稳定的生产环境。不要一开始就追求最强性能引擎。我见过不少团队把TensorRT-LLM的编译调优时间算进项目预算后发现自己根本耗不起。更现实的做法是先用vLLM把业务跑通等流量模型稳定下来后再考虑用TensorRT-LLM把性能榨干。3.2 连续批处理与PagedAttention为什么这么关键传统批处理有个低效点必须等人凑齐一批才开始推理不同请求的长度差异又很大短的干等长的结束GPU利用率自然上不去。连续批处理把这个逻辑改掉了它可以在一个batch内部动态插入新请求已经生成的token完成就立刻释放算力给新请求让位。这个机制把GPU的空转时间大幅压缩也是vLLM吞吐能比朴素批处理高出一两个数量级的主要原因。PagedAttention解决的是KV Cache的内存碎片问题。传统实现里KV Cache是按请求预先分配一块连续内存不同请求长短不一碎片浪费很严重。PagedAttention借鉴操作系统虚拟内存的思路把KV Cache切成固定大小的块不要求物理连续按需分配。效果就是同样的显存能多塞不少并发请求长上下文的请求也不会因为一次性分配太大块内存而被拒绝。这两个机制说明一个道理AI推理的许多性能问题不是算力不够而是算力被调度策略和内存管理卡住了。这也是原计算AI里“计算体系要适配模型运行规律”最直观的例子。3.3 投机解码的适用边界如果带宽是生成速度的硬约束能不能少读几遍权重投机解码的思路是让小模型先草稿生成一批token再由大模型并行验证修正。如果草稿模型和真实模型的分布接近一段草稿里大部分token能一次通过那么大模型原本需要逐个生成5个token的时间现在只需一个前向验证就能确定5个token带宽被有效摊薄。这个方案很诱人但我实际测试下来的经验是它极度依赖草稿模型质量。目标模型越强草稿模型越难模仿接受率掉到50%以下后加速效果就明显缩水。另一个前提是目标模型本身有冗余吞吐如果线上流量已经把卡打满了新增验证计算量反而会拖垮整体延迟。所以投机解码比较适合单路低延迟、目标模型大而GPU算力有余的场景比如70B模型挂在A100集群里但并发量不高的服务。4. 多卡扩展的真实瓶颈互联带宽、并行策略与性能指标4.1 张量并行和流水线并行怎么选模型大到单卡放不下时多数人会做模型并行也就是把模型切到多卡上。并行方式主要分张量并行和流水线并行两者都有资源开销选择依据也不一样。张量并行是按层内切分同一个Transformer层里的矩阵计算拆到多张卡上每张卡算一部分计算出结果后用集合通信同步。它的通信频率特别高每一层都要做AllReduce所以对卡间互连带宽极其敏感。NVLink畅通的时候性能很好一旦跨节点走以太网通信延迟会直接把收益吃掉。实测经验是单节点内8卡张量并行度设8是安全选择如果不得不在多个节点间拆张量并行网卡带宽没有400G以上性能基本别指望。流水线并行是按层切分模型按层切成几段卡1算完前几层把中间结果传给卡2接着算。通信频率比张量并行低很多但对网络不太敏感适合跨节点。代价是会有流水线气泡也就是某一段算的时候下一段在空等。所以流水线并行通常是和张量并行叠加使用比如8卡节点内用张量并行节点间用流水线并行这个组合在70B级别模型上是主流部署形态。4.2 从TTFT、TPOT到MFU怎么读性能数据做推理性能优化不能只看接口P99要看三个核心指标。TTFT首个Token生成时间反映的是“用户多久能看到第一个字”和前处理、模型加载、调度排队都有关系。它对交互式体验影响最大通常要求控制在1秒以内。TPOT每Token生成时间反映的是“生成一个Token要多久”它直接决定打字速度体验一般希望小于50毫秒。MFU模型浮点利用率是所有指标里最容易误导人的生成阶段因为带宽瓶颈MFU能有5%已经不错不代表引擎有问题它主要用来衡量预训练和微调阶段的计算效率。我建议每套推理服务上线前先建一套基准固定模型、固定并发、固定输入输出长度把TTFT、TPOT、吞叶量和GPU利用率打一次底。后面每次调参、换引擎、改显存配置都拿这个基线对比而不是凭感觉判断“好像变快了”。4.3 一个典型7B模型卡间通信开销估算多卡部署时卡间通信其实占着一笔不小的隐形成本。以7B模型、4卡张量并行、每次AllReduce通信量约150MB为例如果走PCIe每秒约25GB理论上一次AllReduce也要几十毫秒这在单token生成只有50到80毫秒的节奏里相当致命。如果换成NVLink单向约100GB/s以上通信时间能压到个位数毫秒。这也是为什么NVIDIA的服务器会把8张卡全部用NVLink互联起来——对推理服务来说卡间互连带宽高低往往比GPU算力高低更影响最终体验。5. 上线排查实录五个比模型精度更致命的隐藏瓶颈5.1 冷启动吞噬SLA有一回我们把新模型从数仓拖到推理服务测试接口返回正常后直接切流量。结果用户反馈前半小时的请求全在超时。查了半天原因是数十GB的模型权重要从对象存储拉到本地再把文件读入显存整个过程超过10分钟而容器健康检查在进程起起来的瞬间就判定“就绪”流量进来时模型权重还没加载完推理请求全部卡在加载环节。之后我们做了三处修改模型镜像里预留本地缓存目录权重文件首次加载后不清理健康检查改为探测真正的推理接口确认权重加载完成后才返回就绪新增预热流程部署完成后先跑一个短请求把KV Cache结构和算子跑热再把实例挂到负载均衡后面。这一套下来冷启动阶段的超时基本绝迹。5.2 流量突刺带来的排队雪崩推理服务和传统接口的一大区别是并发处理能力上限极其僵硬。模型在显存里占用的空间决定了最大同时处理多少个请求多出来的只能在队列里等。某次活动流量翻倍后我们的推理服务直接雪崩队列堆积TTFT飙到几十秒后面进来的请求全部超时客户端重试又把队列压得更死。排查后发现瓶颈不在算力而在队列容量上限和请求超时策略。我们限制单实例最大排队数量超出的请求直接返回503让负载均衡甩到其他实例同时把客户端重试改成指数退避。推理服务的容量是刚性的与其在队列里耗死不如快速失败让流量重新分配。5.3 显存碎片化与长稳运行性能衰减推理服务跑了两周后我们发现响应速度比刚上线时慢了近一倍而且吞吐还在继续恶化。第一反应是服务出问题重启后立刻恢复。反复出现后我们盯上了显存。跑长稳测试用nvidia-smi跟踪显存占用发现可用显存从最初的3GB慢慢掉到几百MB明显是显存碎片和缓存残留。这个问题有两个解法一是给容器配置合适的显存请求和上限让推理引擎自己有足够空间做KV Cache分配同时依赖PagedAttention这类机制缓解碎片二是建立定期巡检跟踪可用显存指标降到阈值以下就主动滚动重启。后来切换了更新版本的推理引擎碎片问题大幅缓解但还是保留了这个监控策略毕竟线上出现显存问题往往是渐进的不会像CPU那样迅速崩溃。5.4 多租户QoS隔离比想象中更难同一个GPU集群里跑多个模型时最大的坑是“吵邻居”。一个高并发的7B服务可以把节点的卡间带宽占满旁边一个70B服务哪怕只在同一台机器上用NVLink通信延迟也会明显波动。我们后来给每个工作负载打了明确的资源标签分模型、分优先级配置了节点亲和性重要模型独占整卡不要和别的模型共享同一张GPU。这看起来浪费但能避免很多不可控的延迟抖动。如果非要共享卡至少把推理引擎并发上限调低并为每个租户设定显存和带宽配额。5.5 一个真实的逐层定位案例有一次线上反馈个别接口特别慢表现为时快时慢。我们按下面这个顺序排查从业务层一路钻到算子层先看接口调用链确认慢的请求都落在同一个推理服务。接着看推理引擎日志发现这些请求的排队时间正常但执行时间波动很大。再看GPU指标发现显存使用率接近上限nvidia-smi显示温度也不低。继续用性能分析工具抓采样定位到部分算子在构造KV Cache时出现较长的显存分配停顿。最终根因是老版本推理引擎在显存碎片较多时KV Cache的分配路径存在较长的线性扫描逻辑。升级引擎并开启内存预分配后波动消失。这个案例里每个环节都有现成工具难的是按顺序把嫌疑范围一步步缩小。AI推理的性能问题往往横跨网络、内存、调度、算子多个层级没有一套通用的排查流程最好的方式是从请求路径出发一层一层往下查。6. Agent与多模态会把原计算AI推向哪里6.1 Agent推理调用模式的改变Agent应用和数据中心当前典型的单轮短请求模式完全不一样。一个稍稍像样的Agent任务背后可能是几十次甚至上百次模型调用每次调用都在做推理生成而且经常要反复携带之前的对话历史和工具返回结果。这意味着单次任务的token消耗量成倍上升KV Cache的复用和释放频率也成倍增加。传统负载均衡面对的是“请求快进快出”Agent服务则要长时间保持对话上下文有大量会话可能处于“挂起等工具结果”的状态。这对推理服务的显存管理提出了更高要求那些挂起的会话不能占着KV Cache不放否则很快就把显存吃光。我在原计算架构上的应对思路是增加上下文卸载机制把不活跃会话的KV Cache导出到CPU内存等下次调用时再重新载入而不是任它占用GPU显存。6.2 长上下文与KV Cache复用长上下文是Agent类应用最常见的新压力。以前一个请求的上下文可能就几千token现在动辄几十万token。如果每次调用都把整个历史重新计算一遍前向成本是不可接受的。所以原计算体系里会越来越看重“前缀缓存”能力相同前缀的历史Prompt算过一次就不再重复算直接复用之前算好的KV Cache块。vLLM等引擎已经支持自动前缀缓存但它在多实例部署时有一个坑每个实例的缓存是独立的请求被负载均衡打到不同实例前缀缓存就命中不了。优化方向是让路由层感知每个实例的缓存内容把带相同上下文的请求尽量路由到同一个实例。这类调度逻辑传统负载均衡完全不会考虑只有真正进入原计算AI的思路才会发现它有多重要。6.3 多模态输入的token爆炸多模态模型带来的压力更直接一张普通图片进入VLM后可能被切成几百个甚至上千个视觉token一段视频更是成千上万。这会让输入处理的TTFT明显变长前处理阶段的计算和显存需求都会飙升。实际部署多模态模型时需要单独评估视觉编码器的算力消耗和显存占用不能只看语言模型部分的参数。音频流任务也更消耗实时性要求推理延迟低到几十毫秒以内这个容错区间很小就对推理引擎的流式输出和并行调度能力提出了很高要求。6.4 原计算下一步从加速卡走向计算架构这些变化指向一个共同方向未来AI计算系统的瓶颈会从单卡算力慢慢转移到整个体系对token流、对上下文、对调度策略的综合管理能力上。所以在做算力规划时不能只盯着GPU型号和数量要同时关注推理引擎选型、显存分级策略、节点互联拓扑、调度系统对KV Cache的感知程度。我自己在多个项目里的体感是模型能力还在快速迭代明天可能换一个更强的模型今天专门为某个网络结构做的深度定制明天可能全部作废。因此在原计算AI的架构设计上要尽量保持调度层、资源层和模型层解耦模型随便换底层缓存、显存管理、路由机制还能继续复用。这个权衡比单纯追求单次推理峰值性能更重要。最后分享一条个人经验如果你的团队正准备把AI服务推向生产环境先不要急着买更多GPU。拿一周时间把当前服务的队列深度、显存碎片、带宽利用率、KV Cache命中率这些指标摸一遍很多性能问题自己就浮现出来了。算力加得再快也追不上调度和内存管理混乱带来的浪费速度。
返回列表