“当 AI 走上春晚”——这句话放在工程人眼里,其实是一个特别贴切的比喻。春晚讲究的是海量用户同时在线、节奏分秒不差、容错率无限趋近于零。AI 应用从 demo 到真正面向线上流量,面临的几乎是同一种“春晚级考验”:拿一两个测试用例把模型跑通很容易,但当真实用户涌进来,高并发、实时响应、异常输入、基础设施抖动,每一个变量都可能让系统当场翻车。这篇文章不聊晚会内容本身,而是借“全民直播级考验”这个视角,把 AI 从模型到落地之间的工程真相拆开讲讲,重点覆盖模型部署、推理优化、稳定性保障、故障排障,以及 AI Agent、本地化部署这些正在普及的工程方向。不管你是做 AI 应用开发、AI Agent,还是正准备把模型私有化部署,这篇文章都值得读完,很多坑我替你踩过了。
1. 舞台搭建:AI 从模型训练到生产部署,到底差在哪
1.1 训练是“彩排”,推理是“直播”,两者为什么不能混着用
拿春晚来打比方最直观:训练阶段好比彩排,面对的是固定剧本,可以反复迭代、随时重来,演员状态不好就再来一条;推理阶段就是正式直播,用户发来什么就是什么,回答慢了、错了、卡了,没有重来机会,损失的全是真实体验。
技术层面的差异更明显。训练阶段追求的是吞吐量,几千条样本拼成一个大 batch 扔给 GPU,跑个几小时也没关系,反正离线任务,断了还能断点续跑。推理阶段恰恰相反,用户丢过来一句话,恨不得 300 毫秒内就有反应,一个请求慢了两秒,用户可能直接就刷新页面走人了。也就是说,训练要的是“总产量”,推理要的是“单次实时性”,这两个目标天然冲突,工程架构上必须分开处理。
还有一个常被忽略的点:训练能容忍故障。GPU 掉卡、显存溢出、某个节点挂了,重启任务继续跑,最多损失一点时间。推理服务不行,线上系统讲究 7x24 小时可用,一个节点挂掉,如果没有自动摘除和流量切换,整个服务就瘫痪了。我见过不少团队图省事,直接把训练代码包装一下就当成推理服务上线,结果一遇流量波动就各种超时和 OOM,本质就是没搞明白训练和推理是两个系统。
1.2 模型瘦身三板斧:量化、蒸馏、剪枝怎么选怎么避坑
大模型训练完,量级动辄 7B 参数起步,往上还有 70B 甚至千亿参数。直接部署,显存和算力成本非常惊人。所以在工程上,第一步通常是想办法让模型“瘦身”。目前主流方案有三条路:
- 量化:把 FP16 的权重转成 INT8 或 INT4。原理是把连续浮点数映射到整数网格,精度损失有限,但显存占用直接减半甚至减到四分之一,推理速度也会明显提升。我实际部署 7B 模型时,FP16 大约占 14GB 显存,转成 INT4 之后只要 4GB 左右,消费级显卡就能跑起来。
- 蒸馏:让大模型当老师,把能力迁移给小模型。常见做法是用 70B 模型生成大量高质量数据,拿这些数据去微调一个 7B 模型,很多场景下小模型能力可以逼近大模型,但推理开销小一个数量级。
- 剪枝:去掉网络中重要性低的参数或结构。传统 CV 模型上用得比较多,LLM 因为结构特殊,使用相对少,但在特定业务场景仍然有效果。
这里必须重点提醒一个坑:量化不是所有模型都适合。我遇到过数学推理模型,原版正确率 85%,INT4 量化后直接掉到 68%,基本不可用。原因是数学任务对数值精度极其敏感,量化压缩后推理链路的中间结果偏差被放大。所以在决定量化方案前,一定要准备一套业务侧的高价值评测集,把量化前后的表现跑一遍对比。经验上,泛化能力强的开源基座模型比较耐量化,但某些领域微调模型,权重分布一旦偏移,量化后损失会非常明显。必要时可以考虑混合量化:敏感层保持高精度,非敏感层用低精度,虽然实现复杂一些,但能在成本和效果之间找到更好的平衡。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 模型部署与服务化:推理引擎、关键参数与流式输出的实战心得
2.1 推理引擎选型:vLLM、TensorRT-LLM、TGI 怎么选
模型选定、瘦身完成,下一步就面临选型:用什么引擎把模型跑起来。这个选择直接决定服务性能上限和运维复杂度。目前社区主流推理引擎大致有下面几类:
| 引擎 | 核心优势 | 适用场景 |
|---|---|---|
| vLLM | PagedAttention 显存管理,吞吐高,API 兼容 OpenAI | 大规模在线推理服务,社区活跃 |
| TensorRT-LLM | NVIDIA 深度优化,单卡性能极限 | GPU 型号统一、性能要求极高的场景 |
| TGI | Hugging Face 官方出品,部署简单 | 中小团队快速上线,性能要求中等 |
| llama.cpp | 纯 CPU/混合设备运行,内存占用低 | 本地部署、边缘设备、开发调试 |
选型逻辑其实很直白:对外提供高并发在线 API,vLLM 基本是首选。它的 PagedAttention 机制有点像操作系统里的虚拟内存,把 KV Cache 拆成固定大小的块,按需分配,大幅减少显存碎片,吞吐能力自然就上去了。我最早用 Transformers 库直接部署,并发一上到 20 就开始超时,换 vLLM 之后同配置轻松扛到 100 并发,这个差距非常直观。
如果团队 GPU 资源充足,对单请求延迟有极致要求,比如要压到几十毫秒级别,TensorRT-LLM 更值得投资。但代价是工程复杂度高,不少算子要按特定 GPU 架构编译,换一个型号的显卡可能就要重新优化一遍。TGI 的优势是上手快,不折腾,适合团队规模不大、不想在推理引擎上花太多精力的场景。llama.cpp 则适合本地部署和边缘设备,苹果芯片的 MacBook 上也能跑出不错的效果。
2.2 三个最容易被忽略的服务化关键参数
引擎装好、模型加载成功,只是第一步。真正影响线上表现的,往往是几个看起来不起眼的参数。我见过太多人忽略这些参数,服务一上线就被打爆。
- max_num_seqs:决定一个推理批次里最多塞多少个请求。值设大,GPU 吞吐高,但单个请求排队时间变长,延迟上升;值设小,延迟低,但吞吐不足。实际调优就是找平衡点,我一般从 64 起步,压测后逐步上调,同时观察 P99 延迟变化。
- max_model_len:也就是上下文最大长度。这个参数直接决定 KV Cache 的预分配空间。如果业务用不到超长上下文,就不要把值设得很大。比如 4096 够用就设 4096,盲目设成 32K,显存会预留给大量你永远用不到的 KV Cache,白白浪费。
- gpu_memory_utilization:控制 GPU 显存里有多少比例用于模型权重和 KV Cache。默认值通常是 0.9,但如果同一张卡上还要跑其他进程,记得调低到 0.7 左右,否则很容易 OOM。
这里放一个 vLLM 的启动命令示例,方便参考:
bash复制vllm serve ./qwen2-7b-int4 \
--host 0.0.0.0 \
--port 8000 \
--max-model-len 4096 \
--gpu-memory-utilization 0.85 \
--max-num-seqs 256
另外有个特性叫连续批处理,一定留意别被关掉。传统批处理要等一个 batch 全部生成完才接收新请求,连续批处理是只要有请求生成完毕,空出来的位置马上让给排队的请求。这个机制对在线服务吞吐提升非常显著,vLLM 默认开启,但如果用了某些自定义封装,要确认它没有被禁用。
2.3 流式输出:让用户感觉“快”的工程手段
大模型生成内容是逐 token 输出的。如果等整段内容生成完再一次性返回,用户等待时间会非常漫长。以 7B 模型为例,生成 300 个 token,普通 GPU 上可能要 3 到 8 秒。所有成熟的 AI 对话应用都会用流式输出:第一个 token 尽快到达用户端,后续内容边生成边传输,用户感知到的等待时间大幅缩短。
工程上最常用的方案是 SSE(Server-Sent Events)。服务端通过 HTTP 长连接,把生成的 token 按顺序推送给前端。相比 WebSocket,SSE 走标准 HTTP 协议,实现简单,对中间代理、日志系统友好很多。需要注意:用户中途停止生成时,前端要主动关闭连接,服务端也得有中断机制,否则 GPU 还在一刻不停地生成没人看的内容,纯粹浪费算力。
流式场景下另一个隐蔽问题是超时。长文本生成请求可能耗时几十秒,普通 HTTP 网关默认超时往往只有 30 到 60 秒,长文章或长视频脚本生成到一半就被网关掐断。我踩过一个具体的坑:Nginx 默认 proxy_read_timeout 只有 60 秒,有次长文生成任务跑了 2 分钟还没结束,Nginx 直接返回 504。后来统一调成 300 秒,问题才彻底消失。如果你用的是云厂商的 API 网关或负载均衡器,第一件事就是确认默认超时时间。
3. 从“彩排”到“直播”:AI 服务的稳定性与可靠性工程
3.1 高可用架构:多副本、负载均衡与优雅降级
春晚直播要有主备链路、随时切换,AI 系统也同理:不能只部署一个推理实例,否则 GPU 故障、网络波动、机房断电,任何一个环节出问题,整个服务就没了。高可用架构最核心的是两层。
第一层是多副本。同一个模型部署多个实例,前面挂负载均衡,把请求分散到不同实例。单实例挂了,其他实例继续扛流量。副本数怎么定?我一般按峰值 QPS、单实例吞吐、可用性要求来反推。比如单实例能扛 50 QPS,业务峰值 300 QPS,那至少需要 6 个实例,再加 20% 到 30% 冗余,防止流量突刺时没有弹性空间。这里要注意,GPU 实例成本高,扩副本要花钱,但省这个钱的代价就是事故时用户流失,哪个更贵,账要算清楚。
第二层是优雅降级。模型服务如果依赖外部资源,比如数据库、向量检索、外部 API,任何一环挂掉都要有预案。最理想的表现是:系统不崩溃,给用户返回兜底回答或明确提示“服务繁忙”,而不是直接卡死或抛 500。电梯坏了还能走楼梯,服务降级就是这个思路。
3.2 限流、降级与缓存,缺一不可的三件套
高并发场景下,没有限流的服务就像没有闸门的水库,流量稍微一冲就垮。限流方案选型:常规业务量用令牌桶算法就足够了,基于 Redis 的 Lua 脚本实现成本很低。下面是一个简单的限流脚本示例:
lua复制local key = KEYS[1]
local limit = tonumber(ARGV[1])
local current = tonumber(redis.call('INCR', key))
if current == 1 then
redis.call('PEXPIRE', key, ARGV[2])
end
if current > limit then
return 0
end
return 1
流量极大且要求极低延迟的场景,可以考虑在网关层做分布式限流,把限流逻辑前置到入口,避免请求打到模型服务才被拒绝,白白消耗网络和 GPU 资源。
降级策略这里多说一句:模型服务是链路中延迟最高的环节。如果一个请求还要依次调用其他服务,任何一个环节变慢都会拖垮整体响应。降级有两种常用思路。一是设定超时时间,超过就放弃非核心能力,只返回核心回答。二是准备一个小模型作为兜底,大模型集群压力过大时,把一部分流量切给回答质量稍低但算力开销小的小模型,保证服务不中断。这个机制有点像电影院的备用发电机,平时不用,停电时它就是救命稻草。
缓存这件事,传统 Web 服务人人都会做,AI 服务却经常被忽略。热门问题重复率其实不低,把完全相同的提问做一层 Key-Value 缓存,命中直接返回,能省下大量 GPU 算力。更进一步可以做语义缓存:用向量检索判断新问题和缓存里的旧问题语义是否相近,相近就复用历史答案。代价是语义检索本身有开销,还多了一个数据库依赖和故障点,所以要看业务场景取舍。如果问题泛化程度很高,很少一模一样,那语义缓存就值得做;如果用户提问五花八门但都指向同一类操作,纯 KV 缓存就够用了。
3.3 盯住 TTFT 和 TPOT:AI 服务监控指标的打开方式
AI 服务的监控体系和传统 Web 服务差异很大。除了常规的 QPS、错误率、CPU、内存,一定要重点盯两个延迟指标。
| 指标 | 全称 | 含义 | 正常参考值 | 异常信号 |
|---|---|---|---|---|
| TTFT | Time To First Token | 从请求发出到返回第一个 token 的时间 | 500ms 以内 | 超过 1.5s,说明排队严重或模型加载慢 |
| TPOT | Time Per Output Token | 生成每个 token 的平均耗时 | 30-80ms 区间(视硬件) | 超过 100ms,体验明显变卡 |
监控上还要记住一条:P99 比平均值重要得多。平均值会被大量快速请求拉低,掩盖尾部延迟恶化。比如平均延迟 300ms 看起来挺好,P99 可能已经到 3 秒了,说明正有一批用户遭受明显卡顿。我习惯把优化重心放在 P99 上,逐步缩小它与均值的差距。具体做法是:给 TTFT 和 TPOT 分别建立分位线报警,P99 一旦连续 5 分钟超过阈值,立刻介入排查,不要等用户投诉才发现问题。
4. 实战排障:AI 服务上线后最常见的四个事故现场
4.1 显存溢出(OOM):三个常见成因与排查路径
AI 推理服务最常见的故障就是 OOM。总结下来,原因不外乎三个:并发请求太多,KV Cache 占满显存;max_model_len 设得太大,预分配了过多显存;显存碎片化严重,明明总量够,但连续空间不足。
排查第一步永远是看 nvidia-smi 确认显存实际占用。如果并发过高导致,调低 max_num_seqs;如果是 max_model_len 太大,收窄上下文长度,或者用 vLLM 的 per-request 参数动态限制;如果是碎片化,考虑启用量化、调低 gpu_memory_utilization,或者错峰部署多个模型,避免同时拉高显存。
还有一个隐蔽的坑:直接用 Hugging Face Transformers 库加载模型后跑推理,框架在默认情况下会预分配大量显存,而且 torch.cuda.empty_cache() 不及时代码里显存无法及时回收。换用 vLLM 这类推理优化引擎,通常能绕开这个问题。另外,服务刚启动时显存占用数据参考意义不大,一定要在运行一段时间、负载稳定后再看真实水位。
4.2 推理延迟抖动:真凶往往不在模型本身
有时候服务看起来一切正常,但就是有个别请求特别慢。我排查过很多次延迟抖动,发现元凶往往不是模型,而是下面这些因素。
GPU 时钟降频。散热不好、长时间高负载,GPU 会自动降频,推理速度断崖下跌。这种情况在云厂商的共享型实例上特别常见,邻居业务毛刺会直接拉高你的延迟。应用层没有完美解法,要么换独享实例,要么接受一定波动,同时加强温度监控,超过阈值时减少并发。
冷启动问题。新扩容的实例加载模型需要时间,如果在模型还没有完全 Ready 时就接入流量,会频繁超时。我见过一个线上事故:自动扩缩容配置没做好,新实例一启动就被负载均衡注册,结果模型还在加载,所有打到新实例的请求全部 504。解决方案是服务注册中心做好健康检查,确认模型加载完成、探活通过后,再标记实例可用。
输入长度带来的延迟波动。长上下文请求的推理耗时远高于短文本,如果不对输入长度做限制或差异化处理,个别超长请求就会拉高 P99。工程上可以做超长文本预检,超过阈值时提示用户截断或分批处理。
4.3 模型幻觉:没法根除,但可以用工程手段管理
模型幻觉是大模型普及中最受关注的问题之一。模型“一本正经地胡说八道”,本质原因是语言模型优化的目标是“生成下一个最可能的 token”,而不是“保证事实正确”。模型不确定时,倾向编一个听起来合理的答案,这是一种统计特性,不是简单的 bug。
工程上的缓解手段,按优先级整理如下:
- 引入检索增强(RAG)。把业务知识放到外部知识库,生成时先检索相关片段,再让模型基于这些片段回答。这是目前最主流、见效最快的方案。实际项目中,在客服问答场景接入 RAG 后,幻觉率大概能下降一半以上。
- 调整推理参数。temperature 调低到 0.1-0.3,减少随机性;必要时配合 top_p 收窄采样空间。代价是回答多样性下降,但事实类任务稳定性明显提升。
- 提示词约束。明确要求“若不确定请直接说不知道”,可以在一定程度上减少编造,但无法根除。
- 后置校验。结合规则或另一个校验模型,对生成内容做事实核查。适合医疗、金融这类对准确性要求极高的场景,缺点是成本和链路复杂度明显上升。
最需要认清的现实是:幻觉问题没有银弹,只能通过组合手段降低发生概率。做 AI 应用时,把这条写进产品预期里,比上线后被打个措手不及要好得多。
5. AI Agent 与本地化部署:全民智能时代的工程延伸
5.1 Agent 落地的关键:工具调用设计与循环控制
AI Agent 是现在绕不开的方向。Agent 的本质是让大模型具备行动能力:不只回答问题,而是根据任务拆解步骤、调用外部工具、观察结果、继续行动,直到完成任务。Curser AI 编程、Spring AI、Agent 开发这些热词,本质上都在沿着这个方向演进。
工程上,Agent 系统最关键的点是工具调用(Function Calling)。模型需要知道有哪些工具、每个工具的参数长什么样。设计函数 schema 时,描述要足够清晰,因为模型是通过描述来理解“这个工具帮我做什么”的。我实际踩过坑:工具描述写得太笼统,模型经常选错工具;把描述细化到“当用户想查询天气时必须用此工具,参数 city 使用中文城市名称”之后,选工具准确率明显提升。下面是一个工具描述示例:
json复制{
"name": "get_weather",
"description": "查询指定城市当前天气,必须使用中文城市名称",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "中文城市名称"}
},
"required": ["city"]
}
}
Agent 循环的超时和重试机制同样重要。Agent 会进行多轮“思考-行动-观察”循环,一次任务可能触发好几次工具调用,任何一环卡住都会拖垮整体响应。我的经验是:给每轮工具调用设独立超时(比如 10 秒),累计超时后整体放弃,返回当前结果或明确提示用户稍后重试。同时要设置最大步数限制,防止模型在一个问题上无限循环,白白烧算力。还要做好调用链路的日志追踪,否则 Agent 报错时,你根本不知道它卡在哪一步。
5.2 本地部署 AI:硬件选型与版本管理要务实
“本地部署 AI”正从开发者圈走向更广泛的企业场景。很多团队希望把模型部署在自己的服务器上,不依赖外部 API,核心诉求通常有三点:数据隐私安全、调用成本可控、定制性更强。
硬件选型一定要务实。7B 级别模型,INT4 量化后,一张 12GB 显存的显卡就能跑起来,适合对响应速度要求不高的内部工具场景。要更流畅的体验,建议 24GB 以上显存,可以跑 FP16 或更高精度,同时给 KV Cache 预留空间。目标如果是 70B 量级模型,单卡基本不够,要上多卡模型并行,部署复杂度也跟着上去。我建议团队都从小模型起步,先把链路走通、流程理顺,再评估是否升级模型尺寸。一上来就追求最强模型,硬件、运维、调优成本很容易把项目拖垮。
版本管理是本地部署最容易忽略的一环。模型文件动辄几个 GB,不同版本行为差异很大,不做好版本管理,出了问题很难定位。建议用专门的对象存储或模型仓库存放模型文件,记录版本号、量化方式、基准评测结果。上线时按版本号发布,效果异常能迅速回滚到之前版本。这里的教训来自一次线上事故:模型团队更新了一版模型,没有记录变更,结果对话效果明显变差,排查了半天才发现是静默替换了模型权重。从这个角度看,模型和普通软件包的版本管理同等重要。
最后再分享一个心得:AI 工程的本质,是让不确定的模型跑在确定的系统里。模型有幻觉、有波动、有退化,但系统工程可以把这些不确定性控制在一定范围内。从选型到部署,从监控到排障,每个环节都是在为这种确定性添砖加瓦。现在各种 AI 工具、框架层出不穷,但底层那套工程方法论不会变:先想清楚最坏情况,再设计系统;先保证系统可用,再追求模型效果。这个顺序,我建议所有做 AI 应用的同学都亲自实践一遍。
