1. 从零搭建AI Infra知识全景:一个后端老兵的学习路线复盘
这两年AI应用层卷得飞起,但真正把模型跑起来、跑稳、跑便宜的那批人,反而越来越稀缺。我自己是从传统后端转过来的,刚开始以为"不就是调个API嘛",结果第一次上手部署推理服务就被显存、吞吐、并发这几个词按在地上摩擦。后来花了小半年时间,把AI Infra这条链路从下到上捋了一遍,才算摸到点门道。这篇笔记就是把我踩过的坑、整理的知识地图、以及实际动手验证过的方案,完整地摊开讲一遍。
所谓AI Infra,说白了就是"让模型能稳定、高效、低成本地对外提供服务"这一整套工程体系。它不像算法那样天天上头条,但它是所有AI产品的地基。你看到的每一次对话、每一张生成图,背后都有推理引擎、显存管理、请求调度、监控告警在默默干活。这篇文章适合三类人:一是像我这样从后端/运维转过来的工程师,二是想搞懂"模型部署到底难在哪"的算法同学,三是需要做技术选型的技术负责人。我会尽量用大白话把每个环节讲透,让你看完能自己动手搭一套最小可用的推理服务。
整篇内容我按"知识全景"的思路来组织,从最底层的硬件与显存,到中间的推理引擎与调度,再到上层的服务化与可观测性,最后聊聊成本与选型。每一块我都会说清楚"为什么这么设计""实际怎么操作""哪里容易翻车"。
2. AI Infra知识全景的整体拆解思路
2.1 为什么先画地图再动手
我一开始的学习方式是"哪疼医哪",结果就是知识全是碎片。今天学了个量化,明天看了个批处理,但脑子里串不起来。后来我强迫自己先画一张全景图,把AI Infra拆成几个层次,再逐层填坑,效率一下子高了很多。
我的拆解逻辑是这样的:从下往上分四层——硬件资源层、推理执行层、服务调度层、应用接入层。每一层解决的核心问题不同,但层与层之间的接口和约束是强耦合的。比如硬件层的显存大小,直接决定了执行层能开多大的批;执行层的吞吐能力,又决定了调度层怎么排队。
提示:画地图的时候不要追求一次画全,先画出主干,再在实践过程中不断补充枝叶。我第一版地图只有五个框,现在已经细化到三十多个知识点了。
2.2 四层结构的核心职责划分
硬件资源层管的是GPU、CPU、内存、网络、存储这些物理资源。这一层的关键词是"显存"和"带宽"。很多人忽略的是,推理性能瓶颈往往不在算力,而在显存带宽和数据搬运。
推理执行层是真正跑模型的地方,核心是推理引擎(比如常见的几种开源推理框架)和模型格式。这一层要解决的是"怎么把模型高效地跑在一次前向计算里",涉及算子融合、量化、KV Cache等。
服务调度层负责把一堆请求合理地分配给底层的推理实例,涉及批处理、排队、限流、扩缩容。这一层是后端工程师最熟悉也最容易上手的地方,但AI场景下的调度逻辑和传统Web服务差别很大。
应用接入层就是对外暴露的API、网关、鉴权、计费等。这一层看起来简单,但要做好流式输出、超时控制、多租户隔离,坑也不少。
2.3 学习顺序上的取舍
我的建议是自下而上打基础,自上而下做验证。先花时间搞懂显存和推理引擎,因为这是AI Infra区别于传统后端的分水岭;然后从应用层往下倒推,看看一个请求到底经过了哪些环节,这样能快速建立全局感。
不要一上来就啃调度框架的源码,那会让你怀疑人生。先把一个最小模型跑起来,观察它的显存占用、首token延迟、吞吐量,再逐步加复杂度。
3. 硬件与显存:绕不开的第一道坎
3.1 显存到底被谁吃掉了
新手最常问的问题就是"我这个模型要多大显存"。很多人以为参数量乘以精度就是全部,其实差得远。显存占用大致分四块:模型权重、KV Cache、激活值、框架开销。
模型权重好算,比如一个70亿参数的模型,用FP16存储就是14GB左右。但KV Cache是动态的,它跟批大小、序列长度、层数、注意力头数都相关。序列越长、批越大,KV Cache就越恐怖,很多时候它比权重还占地方。
激活值和框架开销相对固定,但也不容忽视,尤其是用了某些优化库之后,会预留一部分显存做缓存池。
3.2 显存估算的实操方法
我一般用这个粗略公式来估:
总显存 ≈ 权重显存 + KV Cache + 激活值 + 预留开销 权重显存 = 参数量 × 每参数字节数 KV Cache = 2 × 层数 × 注意力头数 × 头维度 × 序列长度 × 批大小 × 每元素字节数举个实际例子,某70亿参数模型,FP16权重约14GB,32层,32个注意力头,头维度128,序列长度2048,批大小8。KV Cache算下来大概是 2×32×32×128×2048×8×2 字节,约8.6GB。加上激活值和预留,整体奔着26GB去了。所以一张24GB的卡跑这个配置会非常紧张。
注意:这个公式是估算,实际还要看推理引擎的实现。有的引擎会做KV Cache量化,能省一半以上;有的会做分页管理,碎片更少。
3.3 显存不够时的几种应对策略
显存不够是常态,我总结了几条实用路径,按推荐优先级排:
| 策略 | 效果 | 代价 | 适用场景 |
|---|---|---|---|
| 量化权重 | 显存降30%-50% | 精度略降 | 对精度不敏感的场景 |
| KV Cache量化 | 显存降40%-60% | 长文本质量略降 | 长对话场景 |
| 减小批大小 | 显存线性下降 | 吞吐下降 | 低并发场景 |
| 缩短最大序列 | 显存明显下降 | 长文本被截断 | 短文本场景 |
| 多卡切分 | 显存翻倍 | 通信开销增加 | 大模型必备 |
我个人的经验是,先量化权重,再考虑KV Cache量化,最后才动批大小。因为批大小直接关系到吞吐和成本,能不动就不动。
3.4 多卡并行的基本认知
单卡放不下的时候,就得上多卡。多卡并行主要分两种:张量并行和流水线并行。张量并行是把单层切开分到多卡,通信频繁但延迟低;流水线并行是把不同层分到不同卡,通信少但有气泡。
实际部署里,单机多卡常用张量并行,跨机常用流水线并行,两者也可以混合。但要注意,并行度不是越高越好,通信开销会吃掉收益。我实测下来,单机内张量并行度控制在2到4之间比较划算。
4. 推理引擎:AI Infra的心脏
4.1 推理引擎到底在优化什么
很多人把推理引擎当成"跑模型的工具",其实它的核心价值在于把一次前向计算压榨到极致。它做的优化包括算子融合、内存复用、批处理调度、量化支持、KV Cache管理等。
打个比方,模型是一道菜谱,推理引擎就是那个经验丰富的大厨。同样的食材,新手做出来又慢又难吃,大厨能同时炒好几锅还保证火候。推理引擎的差距,在并发高的时候能拉开好几倍。
4.2 主流推理引擎的选型对比
市面上常见的开源推理引擎各有侧重,我按自己的使用体验做个对比:
| 引擎类型 | 优势 | 劣势 | 适合谁 |
|---|---|---|---|
| 通用型A | 生态好、上手快 | 极致性能一般 | 快速验证 |
| 高性能型B | 吞吐高、优化深 | 配置复杂 | 生产环境 |
| 轻量型C | 依赖少、易嵌入 | 功能有限 | 边缘设备 |
| 编译型D | 图优化强 | 动态shape支持弱 | 固定输入场景 |
选型的时候不要只看benchmark,要看你的实际场景。如果你的请求序列长度变化很大,那对动态shape支持好的引擎就更合适;如果你追求极致吞吐且输入固定,编译型引擎可能更香。
4.3 批处理:吞吐和延迟的跷跷板
批处理是推理引擎最核心的优化手段之一。把多个请求攒在一起算,能大幅提升GPU利用率。但批越大,单个请求的等待时间就越长,首token延迟就越高。
这里有个关键概念叫连续批处理。传统批处理要等一批凑齐了才开始算,算完才能接下一批,中间GPU会空转。连续批处理则是动态地把新请求插进正在计算的批次里,让GPU一直有活干。这个机制对吞吐的提升非常明显,尤其是请求长度参差不齐的时候。
我实测过一个场景,固定批处理下GPU利用率只有40%左右,换成连续批处理后能到75%以上。代价是实现复杂度高,调参也更麻烦。
4.4 量化:用精度换显存和速度
量化是把模型权重从高精度(如FP16)压到低精度(如INT8、INT4)的过程。它同时带来两个好处:显存占用下降、计算速度提升。因为低精度运算在硬件上通常更快。
但量化不是免费的午餐。INT8量化一般精度损失很小,可以放心用;INT4量化就要小心了,某些任务上质量下降明显。我的做法是先在验证集上跑一遍量化前后的对比,确认质量可接受再上线。
提示:量化分训练后量化和量化感知训练两种。前者简单但精度损失大,后者复杂但效果好。生产环境如果对质量要求高,建议用后者。
5. 服务化与调度:让模型真正对外干活
5.1 从单实例到服务集群
把模型跑起来只是第一步,让它稳定地对外服务才是真正的挑战。单实例的问题很明显:没有冗余、无法扩缩容、扛不住突发流量。所以生产环境一定要做服务集群。
集群化的核心是请求路由和负载均衡。但AI场景下的负载均衡和传统Web不一样,因为每个请求的计算量差异巨大。一个短请求可能几十毫秒,一个长请求可能几十秒。如果按请求数平均分配,很容易出现某些实例被长请求拖死的情况。
我的做法是按token数或预估计算量来加权分配,而不是简单轮询。这样能让各实例的负载更均衡。
5.2 排队、限流与超时控制
高并发下,请求排队是必然的。关键是怎么排、排多久、排不下怎么办。
我一般设置三级保护:队列长度上限、单请求超时、整体限流。队列满了就直接拒绝新请求,返回明确的错误码;单请求超过阈值就中断,避免拖垮整个实例;整体限流则是在网关层控制入口流量。
这里有个容易忽略的点:流式输出的超时控制和普通请求不一样。流式请求一旦开始返回,就不能简单按总时长来掐,而要看token之间的间隔。如果两个token之间超过一定时间没动静,才判定为卡死。
5.3 扩缩容的触发逻辑
扩缩容不能只看CPU和GPU利用率,因为AI推理的瓶颈往往是显存或队列长度。我一般综合这几个指标来触发扩容:队列等待时长、GPU显存占用率、单位时间吞吐量。
缩容要更保守,因为频繁启停实例的代价很高,模型加载一次可能要几十秒。我通常设置一个较长的冷却期,确认流量确实降下来了再缩。
5.4 多租户隔离的实践
如果服务要给多个业务方用,隔离就很重要。隔离分几个层次:资源隔离、配额隔离、优先级隔离。
资源隔离是给不同租户分配不同的实例;配额隔离是限制每个租户的调用量;优先级隔离是让重要租户的请求优先被处理。我一般用配额加优先级的方式,成本可控又能保证关键业务。
6. 可观测性:看不见的问题最致命
6.1 必须监控的核心指标
AI推理服务的监控和传统服务有重叠也有差异。我列一下我必看的指标:
- 首token延迟:用户感知最明显的指标
- 每token输出延迟:影响流式体验
- 吞吐量:每秒处理的token数或请求数
- GPU利用率与显存占用:判断资源瓶颈
- 队列长度与等待时长:判断是否需要扩容
- 错误率与超时率:判断服务健康度
这些指标要能按模型、按实例、按租户维度下钻,否则出了问题很难定位。
6.2 日志与追踪的落地方式
日志我一般分三类:访问日志、错误日志、性能日志。访问日志记录每个请求的基本信息,错误日志记录异常堆栈,性能日志记录各阶段耗时。
追踪方面,我会在请求入口打一个trace id,一路透传到推理引擎,这样能看清一个请求到底在哪个环节慢。很多时候你以为慢在推理,其实慢在排队或者网络。
6.3 告警策略的制定
告警最怕两件事:漏报和误报。漏报会让故障扩大,误报会让人麻木。我的经验是分级告警加动态阈值。
分级就是按严重程度分P0、P1、P2,不同级别走不同通道。动态阈值是根据历史数据自动调整,避免业务高峰期正常波动触发告警。比如队列长度,白天和夜里的正常范围完全不同,用固定阈值肯定误报。
7. 成本控制与选型:算清楚这笔账
7.1 推理成本的构成
推理成本主要分三块:硬件成本、电力成本、人力成本。硬件是大头,尤其是GPU。电力在规模化之后也不容忽视。人力则是运维和调优的投入。
很多人只算硬件账,忽略了调优带来的人力成本。实际上,一个好的推理配置能把硬件成本降一半,但需要投入不少调优时间。这笔账要综合算。
7.2 单位成本的计算方法
我一般用每百万token成本来衡量。算法是:实例每小时成本除以每小时处理的token数,再乘以一百万。
这个指标能横向对比不同模型、不同引擎、不同配置的经济性。比如同样一个任务,用大模型跑和小模型跑,单位成本可能差十倍,但质量也差很多。所以要结合质量来综合判断。
7.3 选型时的几个关键问题
做技术选型时,我一般先问自己几个问题:
- 这个场景对延迟的要求是什么?首token延迟和总延迟哪个更重要?
- 请求的序列长度分布是怎样的?是短文本为主还是长文本为主?
- 并发量大概多少?峰值和均值差多少?
- 对精度的容忍度如何?能不能接受量化?
- 团队的技术栈和运维能力如何?
把这些想清楚,选型基本就不会跑偏。最怕的是上来就比benchmark,结果选了个不适合自己场景的方案。
8. 常见问题与排查技巧实录
8.1 显存溢出(OOM)的排查路径
OOM是最常见的问题。我的排查顺序是:先看是不是权重加载就超了,再看是不是KV Cache涨太快,最后看是不是有内存泄漏。
如果是权重加载就超,那只能量化或者换卡。如果是KV Cache涨太快,那要检查序列长度和批大小配置。如果是泄漏,那要看是不是有请求没被正确释放,或者缓存池没回收。
提示:有些框架会预留显存做缓存,看起来占用很高但其实是可用的。判断真实可用显存要看框架自己的指标,不能只看系统层面的数字。
8.2 吞吐上不去的几个原因
吞吐上不去,我一般按这个顺序查:批大小是不是太小、GPU利用率是不是没打满、是不是卡在数据预处理、是不是有锁竞争。
批大小太小是最常见的,很多人为了降延迟把批设得很小,结果吞吐惨不忍睹。数据预处理也容易被忽略,尤其是图像、音频类模型,预处理可能比推理还慢。
8.3 延迟毛刺的定位方法
延迟毛刺指的是偶尔出现的超高延迟。这种问题最难查,因为它不稳定。我的方法是看分位数而不是平均值,P99和P50的差距能反映毛刺的严重程度。
定位的时候,我会把请求按时间对齐,看毛刺是不是集中在某些时刻。如果集中在扩容、模型加载、GC这些时刻,那基本就能锁定原因。
8.4 常见问题速查表
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| OOM | 权重/KV Cache过大 | 量化、减批、缩序列 |
| 吞吐低 | 批太小、预处理慢 | 调批、优化预处理 |
| 延迟毛刺 | 扩容、GC、锁竞争 | 看分位数、对齐时间 |
| 首token慢 | 排队久、预填充慢 | 看队列、优化预填充 |
| 输出中断 | 超时、显存不足 | 查超时配置、显存 |
| 质量下降 | 量化过度、精度损失 | 对比量化前后 |
8.5 几个我踩过的坑
第一个坑是盲目追求大batch。我一开始觉得批越大越好,结果延迟高得没法用。后来才明白,批大小要根据延迟要求来定,不是越大越好。
第二个坑是忽略预热。模型第一次加载和第一次推理特别慢,如果不预热就直接接流量,前几个请求会超时。后来我加了预热逻辑,服务启动后先跑几个假请求。
第三个坑是监控只看平均值。平均值好看不代表服务健康,P99才是真相。自从我把告警改成基于P99之后,问题发现得早多了。
9. 学习路径与资源组织建议
9.1 分阶段的学习计划
我把学习分成三个阶段。第一阶段打基础,搞懂显存、推理引擎、批处理这些核心概念,能跑通一个最小服务。第二阶段做优化,学量化、连续批处理、多卡并行,把性能压上去。第三阶段做工程化,搞监控、扩缩容、多租户,让服务能上生产。
每个阶段大概一到两个月,不要贪快。我见过太多人跳过第一阶段直接搞优化,结果基础不牢,出了问题根本不知道从哪查。
9.2 动手实践的最小闭环
光看文档没用,一定要动手。我建议的最小闭环是:选一个开源小模型,用推理引擎跑起来,写个简单的API服务,压测一下,看看各项指标。
这个闭环走一遍,你对AI Infra的理解会超过看十篇文章。然后再逐步加复杂度:加量化、加批处理、加监控、加扩缩容。
9.3 知识管理的个人方法
我习惯用一张大图加一堆笔记来管理这块知识。大图就是前面说的四层结构,笔记则按主题分类,每个主题记录"是什么、为什么、怎么做、踩过什么坑"。
定期回顾很重要。AI Infra这块发展快,半年前的方案可能已经过时了。我一般每季度把笔记过一遍,把过时的内容标记出来,补充新的实践。
10. 我在这条路上的一些真实体会
说实话,AI Infra这块知识密度很高,刚开始学的时候我经常有种"每个字都认识但连起来看不懂"的感觉。后来发现,问题出在我总想一次搞懂所有细节。其实更好的方式是先建立框架,再填充细节,允许自己暂时不理解某些点,等实践到了自然会懂。
另一个体会是,不要迷信benchmark。网上那些对比数据都是在特定条件下测的,跟你的场景可能差很远。真正靠谱的做法是自己压测,用自己的数据说话。
还有就是,工程和算法要互相理解。做Infra的不懂模型结构,很难做针对性优化;做算法的不懂工程约束,容易提出不切实际的需求。两边多沟通,很多问题其实在需求阶段就能避免。
最后分享一个小技巧:遇到性能问题,先别急着调参,先用工具把瓶颈定位出来。是计算瓶颈、显存瓶颈还是通信瓶颈,定位准了再动手,能省下大量试错时间。我早期就是瞎调,调了半天发现方向都错了,那种挫败感真的很打击人。后来养成先测量再优化的习惯,效率高了很多。