ARTICLE DETAIL

资讯详情

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

Infra Agent 与 RSI:推理基础设施调优的自动化实践

Infra Agent 与 RSI:推理基础设施调优的自动化实践 1. 从一条内部实验记录说起Infra Agent 到底在做什么1.1 一个让我坐不住的实验结论前阵子我在跟进 GLM 系列模型的推理侧优化工作团队里有人丢过来一份内部实验记录标题很直白用 Infra Agent 做 RSIRecursive Self-Improvement递归自我改进探索。我一开始没太当回事毕竟“Agent 优化基础设施”这个方向这两年喊的人多、落地的人少大部分演示都停留在“帮你写个 YAML”这种程度。但看完那份记录之后我的判断变了——不是因为它多惊艳而是因为它暴露了一个很现实的问题推理基础设施Inference Infrastructure里那些高度依赖人工经验的调优环节正在被 Agent 用密集反馈的方式一点点啃下来。先把概念说清楚避免有人看到标题就慌。这里的 Infra 不是指机房、服务器、网络设备这些硬件层面的东西而是指推理服务栈里那一层“承上启下”的软件基础设施模型加载与显存管理、KV Cache 调度、批处理策略continuous batching、请求路由、量化配置、算子选择、并行策略TP/PP/EP、以及围绕这些环节的性能调优。这一层过去是资深工程师的“手艺活”靠的是看 profiling、读 trace、调参数、压测、再调循环往复。而 RSI 探索的核心思路是让 Agent 自己去做这个循环并且每一轮都比上一轮更好。我之所以说“被替代也不远了”不是说 Infra 工程师明天就要失业而是说这个岗位里“纯靠经验试参数”的那部分价值正在快速贬值。下面我把这套东西拆开讲包括它为什么能成立、技术上怎么实现、实操中会踩哪些坑以及作为从业者该怎么应对。1.2 为什么是“密集反馈”而不是“一次性生成”很多人对 Agent 做 Infra 优化的第一反应是不就是让大模型读配置文件然后改吗这个理解偏差很大。一次性生成配置的方案早就有了效果普遍一般原因是推理性能优化是一个强反馈、强耦合的问题不是写代码那种“语法对了就能跑”的场景。举个具体例子。你把max_num_seqs从 256 调到 512吞吐可能涨了但 P99 延迟可能直接崩掉你把 KV Cache 的 block size 从 16 改成 32显存碎片少了但某些长序列请求的调度效率反而下降。这些参数之间是相互影响的而且影响方向和幅度取决于你的实际流量分布——是长 prompt 多还是短 prompt 多是并发高还是单请求大是 prefill 密集还是 decode 密集。一次性生成方案的问题在于模型没有“试错”的机会它只能基于训练数据里的统计规律给一个“平均意义上还行”的配置。但真实生产环境的性能曲线是非凸的、有局部最优陷阱的平均配置往往离最优很远。密集反馈Dense Feedback解决的就是这个问题。它的做法是Agent 每做一次修改就立刻跑一轮压测或 profiling拿到真实的性能指标吞吐、延迟、显存占用、GPU 利用率把这些指标作为反馈信号喂回给 Agent让它基于“这次改动的实际后果”决定下一步怎么调。这个循环可以跑几十轮甚至上百轮逐步逼近当前硬件和流量条件下的较优解。提示密集反馈的关键不在于“反馈”本身而在于反馈的粒度和延迟。如果一轮压测要跑半小时那 RSI 循环的效率会低到无法接受。所以真正能跑起来的方案压测环节一定是被高度工程化、缩短到分钟级甚至秒级的。1.3 这套东西适合谁来关注我把话说得直接一点如果你现在的工作内容里有超过一半时间花在“看 profiling 图、猜哪个参数是瓶颈、改完再压测”这个循环上那这套 RSI 探索值得你认真研究。它不一定马上替代你但它会改变你这个岗位的价值构成——从“会调参”变成“会设计调参的反馈系统和约束条件”。如果你是做推理服务部署、模型上线、性能优化的工程师或者你在团队里负责推理成本控制那这篇文章里的思路和实操细节应该对你有直接参考价值。如果你只是刚入门、还在学怎么把模型跑起来那可以先理解思路具体参数调优的部分等你有了一定压测经验再回来看会更顺。2. RSI 在 Infra 场景下的技术拆解为什么它能跑通2.1 RSI 的基本闭环感知、决策、执行、评估RSI 这个词听起来很玄但落到 Infra 优化场景它的闭环其实很朴素就是四个环节反复转感知Perceive采集当前系统的状态包括硬件配置、模型结构、当前参数、实时性能指标、瓶颈定位信息。决策Decide基于感知到的状态和历史反馈决定下一步改哪个参数、往哪个方向改、改多少。执行Act把决策落地成实际的配置变更重启服务或热更新然后触发一轮压测。评估Evaluate收集压测结果计算目标函数比如吞吐/延迟的加权组合判断这次改动是变好还是变差把结果存入历史。这个闭环本身不新鲜AutoML 和贝叶斯优化早就在做类似的事。RSI 的新意在于决策环节由大模型驱动而不是固定的搜索算法。这带来两个关键差异第一大模型可以理解“语义”。比如它知道gpu_memory_utilization调太高会导致 OOM 风险知道enable_chunked_prefill和max_num_batched_tokens之间有耦合关系这些先验知识让它不需要像随机搜索那样盲目试。第二大模型可以处理非数值的决策比如“要不要换一个 attention 后端”“要不要开启某个实验性特性”这些是传统超参搜索覆盖不到的。2.2 密集反馈为什么比稀疏反馈更适合 Infra在强化学习里稀疏反馈只在最终结果给奖励和密集反馈每一步都给奖励的差别是决定性的。Infra 优化场景天然适合密集反馈原因有三个第一性能指标是连续可测的。吞吐tokens/s、延迟TTFT、TPOT、显存占用GB、GPU 利用率%这些都是数值型指标每轮压测都能拿到不需要等到“最终上线”才知道好坏。这比很多 RL 任务比如只在游戏结束时给胜负的反馈密度高得多。第二单步改动的因果链相对短。你改了一个参数性能变化基本能归因到这个参数上虽然有多参数耦合但通过控制变量可以部分解耦。这意味着反馈信号的信噪比高Agent 能从中学到“这个方向对、那个方向错”。第三试错成本可控。在测试环境里跑一轮压测的成本远低于在生产环境里出一次事故的成本。所以可以放心让 Agent 大量试错只要把压测环境隔离好、把危险操作比如显存超限导致 OOM拦住就行。我实测下来的感受是密集反馈让 Agent 的调优效率比人工高一个数量级但前提是反馈系统本身要足够快、足够稳。如果压测脚本本身不稳定指标波动比参数改动带来的差异还大那 Agent 学到的东西全是噪声。2.3 目标函数设计别只盯着吞吐这是我在实操中踩过的最大的坑。一开始我们让 Agent 单纯优化吞吐结果它很快找到了一个“作弊解”把 batch size 拉到极大吞吐确实上去了但延迟惨不忍睹线上根本没法用。后来我们改成多目标加权score w1 * throughput_norm - w2 * ttft_p99_norm - w3 * tpot_p99_norm - w4 * memory_penalty其中memory_penalty是显存占用超过阈值后的惩罚项。权重的选择取决于业务场景如果是离线批处理吞吐权重可以高如果是在线对话延迟权重要压过吞吐。注意目标函数一旦定下来就不要在 RSI 循环中途随意改。Agent 会基于目标函数做决策你中途改权重它之前学到的“哪个方向好”就全乱了。如果确实要调整建议重启一轮新的探索而不是在旧的历史上继续。还有一个细节归一化很重要。吞吐可能是几千的量级延迟可能是几百毫秒的量级如果不做归一化量级大的指标会主导目标函数量级小的指标形同虚设。我们的做法是用基线配置的指标做分母把所有指标都归一到“相对基线的倍数”这样不同指标之间可比。2.4 搜索空间的定义哪些参数该放进去不是所有参数都适合交给 Agent 调。我的经验是分三类第一类数值型连续/离散参数适合 Agent 调。比如max_num_seqs、max_num_batched_tokens、gpu_memory_utilization、block_size、swap_space。这些参数有明确的取值范围改动效果可测是 RSI 的主战场。第二类枚举型配置适合 Agent 选。比如 attention 后端flash-attn / flashinfer / xformers、量化方式fp16 / int8 / fp8、调度策略FCFS / priority。这些是“选哪个”的问题Agent 可以通过对比实验来决策。第三类结构性变更谨慎交给 Agent。比如并行策略TP2 还是 TP4、是否启用 pipeline parallelism。这类改动涉及服务重启、资源重新分配试错成本高而且往往和硬件拓扑强相关。我的建议是这类参数由人先定一个大方向Agent 只在小范围内微调。把搜索空间定义好之后还要给每个参数设好边界。比如gpu_memory_utilization不能超过 0.95否则容易 OOMmax_num_seqs不能低于某个值否则并发能力太差。这些边界是“安全护栏”Agent 不能越过。3. 实操搭一套能跑的 Infra RSI 循环3.1 环境准备与工具选型先说环境。你需要一台或几台带 GPU 的测试机和线上环境的硬件配置尽量一致——如果测试机是 A100 而线上是 H800那调出来的参数迁移过去大概率失效。模型也要一致包括权重版本、tokenizer、推理框架版本。推理框架方面我主要用 vLLM 和 SGLang 这两个它们都支持大部分关键参数的运行时配置而且有比较完善的 metrics 输出。选哪个取决于你的模型和场景vLLM 的 PagedAttention 和 continuous batching 比较成熟SGLang 在结构化生成和 RadixAttention 上有优势。Agent 本身可以用 GLM 系列模型来驱动因为它在代码理解和结构化输出上表现稳定而且 API 调用成本可控。压测工具我用的是自己写的一套脚本核心是固定流量分布。这一点很关键如果每轮压测的请求分布都不一样那指标波动就无法归因到参数改动上。我的做法是预先准备好几组固定的请求集比如“短 prompt 高并发”“长 prompt 低并发”“混合分布”每轮压测用同一组保证可比性。# 压测脚本的核心逻辑伪代码 for config in candidate_configs: apply_config(config) restart_service() wait_for_ready() result run_benchmark(fixed_workload) record(config, result)3.2 Agent 的提示词设计把领域知识喂进去Agent 能不能调好很大程度上取决于提示词里塞了多少领域知识。我试过纯靠“你是一个性能优化专家”这种泛泛的提示效果很差Agent 会瞎改。后来我把提示词改成结构化的包含四部分第一部分系统描述。告诉 Agent 当前用的是什么框架、什么模型、什么硬件、什么流量特征。这部分是“背景知识”。第二部分参数说明。把每个可调参数的含义、取值范围、影响方向、和其他参数的耦合关系列清楚。比如“max_num_batched_tokens增大通常提升吞吐但增加 TTFT和max_num_seqs共同决定单批的计算量”。第三部分历史反馈。把之前每一轮的配置和结果按时间顺序喂进去让 Agent 看到“改了什么、结果如何”的完整轨迹。第四部分当前任务。明确告诉它这一轮要做什么基于历史提出下一个候选配置并说明理由。这个提示词模板我迭代了七八版才稳定下来。早期版本的问题是信息太多、太杂Agent 抓不住重点后来我做了精简只保留和当前瓶颈相关的参数说明效果明显好转。3.3 一轮完整的 RSI 循环实录我拿一个真实跑过的例子来说明。基线配置是 vLLM 默认参数模型是 7B 级别的 dense 模型硬件是单卡 80G流量是混合分布70% 短 prompt、30% 长 prompt。第 0 轮基线吞吐 1850 tokens/sTTFT P99 是 420msTPOT P99 是 38ms显存占用 62G。第 1 轮Agent 观察到显存还有余量决定把gpu_memory_utilization从 0.90 提到 0.93同时把max_num_seqs从 256 提到 320。结果吞吐涨到 2010TTFT P99 涨到 455ms显存占用 68G。目标函数算下来略好于基线保留。第 2 轮Agent 注意到 TTFT 涨得有点多决定开启enable_chunked_prefill把max_num_batched_tokens设为 2048。结果吞吐 1980TTFT P99 降到 380msTPOT P99 微涨到 40ms。目标函数进一步改善保留。第 3 轮Agent 尝试把block_size从 16 改成 32。结果吞吐 1995TTFT P99 375ms但显存占用涨到 71G接近阈值。目标函数因为显存惩罚项得分反而下降回滚。第 4 到第 12 轮Agent 在max_num_seqs、max_num_batched_tokens、block_size三个参数上做了更细粒度的搜索最终稳定在max_num_seqs288、max_num_batched_tokens1792、block_size16。最终吞吐 2060TTFT P99 372msTPOT P99 39ms显存 69G。整个循环跑了大概 40 分钟其中大部分时间花在服务重启和压测上。如果纯人工调我估计要花大半天才能达到类似效果而且不一定能找到这个组合。3.4 关键参数的计算与选择过程这里展开说一下几个核心参数是怎么算的因为 Agent 的决策虽然由模型给出但背后的约束是人设定的。gpu_memory_utilization的上限怎么定。这个参数控制 vLLM 预分配的显存比例。设太高会 OOM设太低浪费显存。我的经验公式是max_util (total_mem - model_mem - activation_mem - safety_margin) / total_mem其中model_mem是模型权重占用的显存7B fp16 约 14Gactivation_mem是前向传播的激活值和 batch size 相关通常留 4-8Gsafety_margin留 2-4G 防止碎片和峰值。80G 卡上7B 模型大概能设到 0.93-0.94。max_num_seqs和max_num_batched_tokens的关系。前者限制同时处理的序列数后者限制单批的 token 总数。如果max_num_batched_tokens太小长序列会被截断或排队如果太大单批计算量过大TTFT 会涨。经验值是让max_num_batched_tokens约等于max_num_seqs * 平均序列长度再留 20% 余量。block_size的取舍。PagedAttention 的 block size 影响显存碎片和调度效率。小 block16碎片少但管理开销大大 block32管理简单但内部碎片多。对于长短序列混合的流量16 通常更稳对于纯长序列32 可能更好。这个没有万能解得压测。4. 踩坑记录与常见问题排查4.1 指标波动比参数影响还大怎么办这是最常见的问题。你改了个参数吞吐从 2000 变成 1950你以为参数变差了结果再跑一次又变成 2030。这种波动主要来自三个源头源头一压测流量不稳定。如果请求是实时生成的每次的 prompt 长度分布可能不同。解决办法是预生成固定请求集每轮复用。源头二GPU 热状态和频率波动。GPU 在冷启动和热稳定状态下的性能不一样频率也会因为温度墙而波动。解决办法是每轮压测前先跑一段 warmup让 GPU 进入稳定状态。源头三服务启动后的缓存状态。有些框架在首次请求时会做 JIT 编译或缓存预热导致前几轮指标偏低。解决办法是压测前先跑一轮 discard 的请求把缓存热起来。我的做法是每轮压测跑三次取中位数。这样能过滤掉大部分随机波动。如果三次的差异超过 5%说明环境不稳定这一轮结果直接丢弃不喂给 Agent。4.2 Agent 陷入局部最优怎么破RSI 循环跑久了Agent 容易在一个局部最优附近来回微调不再探索新方向。这是搜索类算法的通病。我的应对策略有三个策略一定期注入随机扰动。每隔 N 轮强制 Agent 做一个“非贪心”的改动比如随机选一个参数往反方向调一点。这能帮它跳出局部最优。策略二维护一个“多样性池”。不只保留当前最优配置还保留几个“次优但差异大”的配置。当 Agent 在当前方向卡住时从池子里换一个起点重新探索。策略三分阶段优化。不要一次性优化所有参数而是分阶段先优化显存相关参数稳定后再优化吞吐相关最后优化延迟相关。每个阶段的目标更聚焦Agent 不容易迷路。4.3 常见问题速查表问题现象可能原因排查方向解决建议吞吐突然暴跌显存不足触发 swap看显存占用和 swap 日志降低gpu_memory_utilization或max_num_seqsTTFT 异常高prefill 阶段计算量过大看max_num_batched_tokens设置开启 chunked prefill降低单批 token 数TPOT 波动大调度策略不适合当前流量看请求队列长度和调度日志调整调度策略或max_num_seqs压测结果不可复现流量或环境不稳定检查请求集是否固定、GPU 是否预热固定请求集增加 warmup 和多次取中位数Agent 反复回滚同一参数目标函数对该参数不敏感检查目标函数权重和归一化调整权重或暂时移除该参数服务重启后指标差异大缓存或 JIT 状态不同对比重启前后的日志统一 warmup 流程确保启动状态一致4.4 几个我踩过的具体坑坑一忘了关掉日志的 debug 级别。有一轮压测吞吐怎么都上不去排查了半天发现是 debug 日志把 IO 打满了。后来把日志级别统一设成 warning吞吐立刻恢复正常。这个坑很蠢但很常见。坑二Agent 把swap_space设得过大。它发现增大 swap 能缓解显存压力就把 swap 设到 32G。结果虽然不 OOM 了但请求频繁在显存和内存之间换入换出延迟爆炸。后来我给 swap 设了硬上限 8G。坑三多轮循环后配置漂移。跑了 50 多轮之后我发现最终配置和基线的差异已经很大有些参数被改得面目全非。虽然指标确实好了但可解释性很差线上出问题时不好排查。后来我加了一个约束每轮改动幅度不超过基线的 30%保证配置不会漂太远。提示RSI 循环的产物不只是一个“最优配置”还包括整个探索轨迹。这个轨迹本身就是宝贵的知识——它告诉你哪些参数敏感、哪些方向有效、哪些组合有坑。建议把轨迹完整记录下来作为团队的知识资产。5. 这对 Infra 从业者意味着什么5.1 被替代的是“调参”这个动作不是“理解系统”这个能力我把话说透RSI 能替代的是那种“看指标、猜参数、试一下、再看指标”的机械循环。这个循环过去占了 Infra 工程师大量时间而且经验壁垒高——老师傅调得快新手调得慢。现在 Agent 用密集反馈把这个循环自动化了而且它不知疲倦、可以 7x24 跑试错次数远超人类。但 RSI 替代不了的是理解系统为什么这样设计、瓶颈到底在哪一层、业务需求如何映射到性能目标。Agent 能告诉你“把 A 参数从 256 调到 288 吞吐涨了 3%”但它说不清“为什么这个模型在这个硬件上对 A 参数这么敏感”。后者需要人来做因为那涉及对模型结构、硬件特性、框架实现的深层理解。所以我的判断是Infra 岗位不会消失但会分化。会用 RSI 工具、能设计反馈系统、能定义目标函数和约束的人价值会上升只会手动调参、不理解底层原理的人价值会下降。这个分化在未来一两年会越来越明显。5.2 从“调参工程师”到“反馈系统设计者”如果你认可上面的判断那接下来的问题就是怎么转型。我的建议是从三个方向入手。第一把调参经验显式化。你脑子里那些“这个参数不能设太高”“这两个参数要一起调”的经验过去是隐性的现在要写成 Agent 能理解的规则和约束。这个过程本身就是对你知识的梳理和升华。第二学会设计目标函数。目标函数是 RSI 的“指挥棒”它决定了 Agent 往哪个方向优化。设计目标函数需要你理解业务需求、理解指标之间的权衡、理解什么情况下该牺牲什么。这是纯工程判断Agent 替代不了。第三掌握反馈系统的工程化。压测怎么跑得快、指标怎么采得准、环境怎么隔离、异常怎么处理这些是 RSI 能跑起来的基础设施。这部分工作过去不被重视现在成了核心竞争力。5.3 一个务实的行动清单如果你现在就想动手试试我建议按这个顺序来先手动跑通一轮完整的调优循环把每个环节的时间成本摸清楚。这一步是为了让你理解瓶颈在哪。把压测脚本工程化做到固定流量、自动采集、多次取中位数。这一步是 RSI 的地基。定义搜索空间和目标函数从 3-5 个核心参数开始不要贪多。接入 Agent 驱动决策用 GLM 这类模型做提示词工程把领域知识喂进去。跑 20-30 轮循环观察 Agent 的决策质量迭代提示词和约束。把探索轨迹沉淀成文档作为团队的知识库。这套流程我自己跑过一遍从零到能稳定产出优化配置大概花了两周。其中大部分时间花在第 2 步和第 4 步上——压测工程化和提示词迭代是最耗时的但也是最值得投入的。最后分享一个我个人的体会RSI 探索最有价值的产出往往不是那个“最优配置”而是探索过程中暴露出来的系统认知盲区。有好几次Agent 的决策让我意识到“原来这个参数和那个参数是耦合的”“原来这个瓶颈不在我以为的那一层”。这些认知更新比省下来的那点调参时间值钱得多。
返回列表