拓冰建站拓冰建站
首页 / 资讯中心 / 正文

从Hot Chips规格到LLM推理延迟仿真:TTFT/TPOT建模与校准实践

1. 一次仿真的起点为什么从 Hot Chips 公开规格入手手里没有 Jalapeño 的真卡只有一份 Hot Chips 上公开的规格表却要回答跑 7B 模型首 token 延迟到底多少毫秒、单用户吞吐多少这种问题我的做法很直接先把规格整理成参数模型再丢进 SimLLM 做端到端仿真最后用 TTFT 和 TPOT 验收结论。这篇文章记录的就是我从 Hot Chips 规格出发完成 Jalapeño 参数模型研究并用 SimLLM 仿真拿到端到端延迟指标的完整链路。Hot Chips 是每年一届的 IEEE 高性能芯片研讨会GPU、AI 加速器厂商都会在大会上公开自家芯片的微架构、峰值算力、HBM 带宽、片上缓存、互联拓扑和功耗等关键数字。对系统工程师来说这些 slide 上的数字不是拿来收藏的而是建模的全部输入。Jalapeño 的规格表里值得关注的指标通常包括BF16/FP16 峰值 TFLOPS、HBM 世代与总带宽、内存容量、片上 SRAM 大小、多 die 或多卡互联带宽、TDP。问题在于这些数字只是静态上限真正决定推理体验的是它们在真实负载下的表现也就是 TTFT 和 TPOT 这两个指标。1.1 Hot Chips 规格表里到底有什么很多人第一次拿到规格表的时候习惯先看算力觉得 TFLOPS 越高越快。但做过推理系统的人都知道LLM 推理里有两笔账一笔是算力账一笔是内存账。规格表恰恰把这两笔账的本钱都标了出来算力账看峰值 TFLOPS内存账看 HBM 带宽。Jalapeño 的规格表上我一般会先把下面这几项单独抄出来峰值算力包括 BF16、FP16、INT8/FP8 三种精度下的数值注意区分稀疏算力和稠密算力很多厂商报的是稀疏值直接拿来建模会把结果乐观 20% 以上。HBM 总带宽单位是 GB/s 或 TB/s这是 decode 阶段的命脉也是决定 TPOT 的核心参数。内存总容量决定能塞下多大的 KV cache、能支撑多大并发直接影响调度策略。片上 SRAM 或缓存容量决定算子融合和权重重用的空间上限在小 batch 下影响很大。互联带宽与拓扑多卡推理时跨卡通信会成为 hidden bottleneck。TDP 功耗墙持续满载时会不会降频会体现在长尾延迟上。把这些数字从 PDF 或 slide 里抄出来本身不复杂但一定要带上精度、单位、是否稀疏这几个附加属性否则后面建参数模型时容易混淆。我习惯直接用 CSV 保存原始规格一行一个参数后面所有建模都从这份 CSV 出发避免反复翻原始资料。1.2 为什么在拿到真实芯片前就要做参数模型这其实是预研阶段最常见的问题芯片还没到货甚至还在流片但需求方已经要求给出在 7B 模型、128 并发下的 TTFT 和 TPOT 预估用来做容量规划和采购决策。没有硬件的条件下参数模型就是唯一的桥梁。参数模型做的事情是把规格表里的静态数字翻译成计算规则。比如看到峰值 512 TFLOPS 和 4 TB/s 带宽就能立刻估算出 prefill 阶段 512 token 输入的理论下限也能估算出 decode 阶段每个 token 读取权重的理论下限。有了这两个基础数字才能接着配置 SimLLM让仿真器在更真实的请求流、调度策略和 KV cache 管理下给出端到端的 TTFT/TPOT 分布。我个人的经验是参数模型做得越细后面仿真调试越省事。如果只填一个算力一个带宽就开跑得到的仿真结果会过于平滑完全体现不出真实系统中的排队、抢占和带宽竞争。这也是为什么我坚持先把规格拆成可计算变量再进入仿真环节。2. Jalapeño 参数模型的骨架把规格表拆成可计算变量参数模型听起来很玄落到实际就是把规格表里的每一项映射成仿真器认识的一个字段同时补上从这些字段推导行为的关键公式。下面以我整理的 Jalapeño 公开规格为例演示整套映射过程。注意以下数字是按公开资料整理的示例值具体以官方最终数据为准方法本身不受影响。2.1 参数清单与映射关系我在 SimLLM 配置文件里给硬件建模时通常会建一张这样的映射表规格项参数模型字段计算公式/说明主要影响指标BF16 峰值算力compute_tflops_bf16若报稀疏值需乘 0.8 稠密系数TTFTprefill 上限HBM 带宽memory_bandwidth_gbps多 HBM stack 求和TPOTdecode 下限内存容量memory_capacity_gb总容量减去运行时开销最大并发、KV cache 容量片上 SRAMsram_capacity_mb影响 kernel fusion 与权重重用小 batch 时的 TTFT互联带宽interconnect_bandwidth_gbps多卡时按拓扑折算多卡 TPOT 的通信损耗TDPpower_limit_w持续负载的降频阈值p99 长尾延迟这张表的核心逻辑是每个规格项都要落到它限制了哪个阶段的哪个指标。算力只影响计算密集的 prefill带宽决定 decode 的理论下限容量决定能不能扛住目标并发。建模的时候如果漏掉 SRAM 或者 TDP仿真结果在低并发短请求下可能看不出问题一旦跑长尾 trace偏差就会很刺眼。2.2 计算强度与 LLM 推理的三段式定性把规格表变成参数模型之后下一步是理解这些参数如何决定推理行为。这里最有效的工具是计算强度也就是每个字节的数据搬运对应多少次浮点运算单位是 FLOP/byte。它的临界点由硬件本身的算力带宽比决定也就是 compute_tflops 除以 memory_bandwidth_gbps再乘以 1e3 换算成统一单位。以示例规格 512 TFLOPS、4 TB/s 带宽为例硬件的算力带宽比是 128 FLOP/byte。也就是说如果某个算子每读一个字节却要做超过 128 次浮点运算它就被算力上限卡住反过来如果每读一个字节只需要做很少的运算它就撞上带宽上限这就是经典 roofline 模型的双上限判断。LLM 推理恰好把这两个区间都占了。prefill 阶段要对整段输入做大批量矩阵乘算术强度通常高于硬件临界点属于计算密集decode 阶段每个 token 都要把全部权重从 HBM 读一遍算术强度极低属于内存密集。因为这两个阶段的行为完全不同所以 TTFT 和 TPOT 必须分开建模这也是 SimLLM 这类仿真器把 prefill kernel 和 decode kernel 分别设置时间模型的原因。3. SimLLM 端到端仿真链路拆解请求、调度、算子级时间模型参数模型解决的是单个算子要多久的问题但用户真正关心的是整个请求从发起到完成要多久。这中间的差距需要仿真器来补SimLLM 这类端到端仿真器的价值就在于把请求到达、排队、调度、KV cache 分配、kernel 执行、内存竞争这些环节全部串起来。3.1 SimLLM 各模块职责我用 SimLLM 时会先把它当成一整条流水线来理解而不是一个黑盒。流水线的前端是请求生成器负责从真实 trace 或合成分布里产生请求接着是调度器模拟连续批处理怎么拼 batch、KV cache 满了怎么抢占、排队中的请求优先级怎么处理再往下是算子时间模型根据 roofline 双上限估算每个 prefill 或 decode kernel 的执行时长最后是内存与互联模型统计 HBM 带宽竞争和跨卡通信开销。这里最关键的一点是调度模块和时间模型是互相影响的。同一批请求如果调度策略激进排队延迟就低但可能因为 batch 太大拖慢每个 kernel如果保守kernel 时间稳定但排队延迟会吃掉 TTFT。所以单纯用公式手算的理论延迟和仿真器给出的 TTFT 分布差距往往就在调度层面。3.2 一份 Jalapeño YAML 配置怎么写SimLLM 的配置通常分三段模型定义、硬件定义、负载定义。我给 Jalapeño 建的第一份配置长这样model: name: llama-7b num_params: 7.2e9 dtype_bits: 16 hardware: compute_tflops_bf16: 512 memory_bandwidth_gbps: 4096 memory_capacity_gb: 192 sram_capacity_mb: 64 interconnect_bandwidth_gbps: 900 scheduler: max_batch_size: 128 preemption: true kv_cache_capacity_gb: 160 workload: trace: ./traces/arxiv_sample.json max_concurrent_requests: 256 input_len_p50: 512 output_len_p50: 128每个字段背后都有建模选择。dtype_bits 填 16意味着权重每参数占 2 字节7.2B 参数的模型权重就是 14.4 GB这个数字直接影响 decode 阶段每 token 要从 HBM 读多少数据。memory_capacity 填 192 GB减去权重占用的 14.4 GB 和其他运行时开销剩下的容量基本都用作 KV cache这也是 max_batch 大小的重要约束。我在第一次配置时犯过的错误是把 kv_cache_capacity 填得和 memory_capacity 一样大结果 KV cache 可以无限分配调度器永远不会触发抢占仿真出来的 TTFT 异常乐观。后来改为容量减去权重再乘 0.9 的可用系数才和实机行为对得上。这类经验只能靠仿真和实机反复对照积累规格表上是看不出来的。3.3 TTFT/TPOT 在仿真里是怎么算出来的在 SimLLM 这类仿真器的内部TTFT 被定义为请求到达时间到第一个输出 token 生成时间之间的间隔它由三部分累加而成调度器排队等待的时间、prefill kernel 的实际执行时间、以及可能的抢占恢复时间。TPOT 则是 decode 阶段相邻两个输出 token 之间的时间间隔在连续批处理下还要考虑共享 batch 中的带宽竞争。仿真器计算 kernel 时间时用的还是那条 roofline 公式只是更精细。prefill kernel 的时间取两个候选值的较大者FLOPs 除以有效算力、需要读写的字节数除以有效带宽。这里有效两个字很关键因为仿真器还要考虑 kernel 的实际利用率通常不会以峰值算力直接计算而是乘一个 0.6 到 0.9 不等的利用系数这个系数也是后期参数校准的核心对象之一。仿真跑完会输出一份 CSV每一行是一个请求字段包括请求 ID、到达时间、prefill 开始时间、首 token 时间、完成时间、TTFT、TPOT 序列等。后面所有统计平均延迟、p99 延迟、吞吐的图表都是从这份 CSV 里算出来的。4. TTFT 与 TPOT 的瓶颈诊断数字背后的物理拿到仿真输出后最关键的步骤不是看平均值而是诊断每一个数字背后的瓶颈来源。TTFT 慢了到底是排队慢还是 prefill 慢TPOT 高了是带宽不够还是 batch 太大这些问题用规格表里的参数就能推出来不需要猜。4.1 TTFT 由什么决定prefill 阶段的算力账先看 TTFT 里的计算部分。对输入长度为 L token 的请求prefill 阶段需要的浮点运算量大约是 2 × N × L其中 N 是模型参数量。以 7.2B 模型、512 token 输入为例这个值大约是 7.37 TFLOP。假如 Jalapeño 的有效算力达到 450 TFLOPS按 512 峰值乘 0.88 的利用率估算那么 prefill 的计算时间下限大约是 16 毫秒。再看同一阶段的内存账。prefill 需要读取的权重仍然是 14.4 GB按 4 TB/s 带宽计算只需要约 3.6 毫秒。两个候选值一比prefill 明显被算力卡住所以 TTFT 的物理下限由算力决定。但仿真里的 TTFT 通常比这个下限高不少多出来的部分来自调度排队和 batch 效应。当多个请求同时到达调度器把它们拼成一个 batch 做 prefill单个请求的等待时间就会上升这是 TTFT 在负载升高时恶化的主要原因。4.2 TPOT 由什么决定decode 阶段的内存账decode 阶段是完全不同的账本。每生成一个 token理论上要把全部权重从头读一遍7.2B 参数 FP16 就是 14.4 GB再加上读取对应位置的 KV cache。按 4 TB/s 带宽计算光读权重的时间就是 3.6 毫秒。而计算量只有 2 × N 也就是约 14.4 GFLOP按 512 TFLOPS 算只要 0.028 毫秒。两个候选值差了两个数量级这就是典型的内存墙。TPOT 的物理下限基本由权重大小除以带宽决定算力再高也帮不上忙。理解了这一点就不会被一片厂商宣传的峰值算力误导也不会在看到 TPOT 偏高时去优化计算 kernel因为瓶颈根本不在这里。真正有效的优化方向是减少每 token 读取的数据量比如用更低位宽的量化格式或者把权重驻留在更大的片上缓存里。4.3 用 roofline 双上限理解内存墙把 prefill 和 decode 放在同一张 roofline 图里看会更直观。prefill 阶段的算术强度大约是几百 FLOP/byte落在计算密集区decode 阶段每 token 的算术强度只有一两 FLOP/byte远远落在内存密集区。同一颗芯片同一个模型在两段推理中分别被算力和带宽卡住这是 LLM 推理性能建模里最容易让人困惑、也最容易解释清楚的一点。这也是为什么我建议做系统评估的同学一定要把 TTFT 和 TPOT 分开看。用同一份 Hot Chips 规格评估两颗芯片时可能 A 芯片算力高导致 TTFT 好看B 芯片带宽高导致 TPOT 好看如果只用一个综合分数根本没法指导选型。把两个指标分开建模、分别诊断才能定位到真正的瓶颈。5. 从规格到报告的实战记录复现我跑通的全过程前面讲的都是方法论这节把从规格到 TTFT/TPOT 报告的完整流程按步骤写一遍方便直接照着操作。整个过程不需要真机只需要一份公开规格、一台能跑仿真的机器、以及一点耐心。5.1 把 slide 变成 CSV第一步永远是把原始规格整理成结构化数据。我建立了一个最小可用的 CSV 文件字段包括参数名、值、单位、精度、来源页码方便后面追查任何数字的出处。以下是示例内容param,value,unit,precision,source peak_bf16_tflops,512,TFLOPS,bf16,hotchips_p24 peak_fp8_tflops,1024,TOPS,fp8,hotchips_p24 hbm_bandwidth,4096,GB/s,,hotchips_p25 hbm_capacity,192,GB,,hotchips_p25 sram_capacity,64,MB,,hotchips_p26 interconnect_bandwidth,900,GB/s,,hotchips_p27 tdp,350,W,,hotchips_p28整理这个 CSV 的时候最重要的工作是甄别数字口径。比如公开展示的算力常常包含稀疏加速建模时必须先转换成稠密口径HBM 带宽在部分资料里写的是单 stack 的值需要乘以 stack 数量。这些口径误差如果不处理会直接带偏后面所有仿真结论。5.2 跑仿真并解析输出配置文件按 3.2 节写好之后我习惯先跑一轮小规模冒烟测试确认配置能跑通再上完整 trace。命令大致是这样simllm run --config jalapeno.yaml --output results/q512.csv跑完后的输出 CSV 每一行是一个请求包含 ttft 和 tpot 列。我通常直接用一段简短的 Python 脚本算统计量import pandas as pd df pd.read_csv(results/q512.csv) for col in [ttft, tpot]: print(col, p50%.2fms p99%.2fms % ( df[col].quantile(0.50) * 1000, df[col].quantile(0.99) * 1000, ))第一轮跑出来的数据通常不会和理论手算值完全一致这是正常的因为有排队和调度开销。我拿到结果后第一步是核对prefill 部分的均值是否接近理论下限的 1.2 到 1.5 倍如果差太远说明配置里有效算力系数或带宽竞争模型需要调整。这一步核对是参数校准的起点不要跳过。5.3 多配置对比的观察规格的敏感性分析是这个流程里最有价值的部分。我会固定模型和负载只改动硬件带宽或容量观察 TTFT 和 TPOT 如何变化。以下是我在一次对比中得到的大致趋势配置TPOT 理论下限TTFT 理论下限观察到的瓶颈512 TFLOPS / 4 TB/s3.6 ms16.4 msdecode 内存墙512 TFLOPS / 2 TB/s7.2 ms16.4 msdecode 更明显800 TFLOPS / 4 TB/s3.6 ms10.5 msdecode 不变512 TFLOPS / 8 TB/s1.8 ms16.4 ms带宽改善 TPOT 明显从这张表能清楚看到提高算力只改善 TTFT提高带宽只改善 TPOT。如果业务场景是长对话、高并发比如聊天机器人那应该优先投资带宽如果场景是长文档摘要、短并发比如学术论文总结算力更关键。这种结论直接指导选型比任何平均值都更有说服力。6. 参数校准与长尾分布从 Merton 模型校准思路说起仿真毕竟是仿真跑出的 p50 通常挺准但 p99 和实机对不上这种情况我在多个项目里都遇到过。仿真结果的均值漂亮不代表长尾可信。这一节说清楚问题出在哪以及我从 Merton 模型参数校准里借鉴来的校准思路。6.1 仿真 p99 对不上实机问题出在哪仿真器默认的假设是硬件状态稳定没有热降频、没有中断、没有邻居流量干扰、没有内存分配碎片。但真实系统不是这样的尤其是长时间跑高负载之后温度上来触发 TDP 降频某些 kernel 会被硬件调度器插队KV cache 分配器可能因为碎片化多走几步。这些事件单独看概率不高但一旦发生延迟会突然跳高一个量级形成长尾。仿真器里的 kernel 时间模型通常是连续平滑的它天然缺少这种突然跳变的能力。所以在校准阶段单纯调大有效算力系数能把均值拟合好但 p99 依然偏小。反过来为了拟合 p99 把所有 kernel 时间都调大均值又会失真。这个矛盾的本质是均值对应的是系统的常规状态p99 对应的是系统里的异常跳跃事件两者需要两套参数分别建模。6.2 跳-扩散思路与校准启发这里我想提一个从金融领域借鉴来的思路。Merton 模型在金融里做信用风险定价时把资产价格的变化拆成两块一块是常规的连续扩散过程负责日常的小幅波动另一块是罕见的跳跃项负责突发的大幅变动。模型校准的任务就是分别拟合这两块的参数比如跳跃强度和跳跃幅度而不是试图用一个均匀分布去覆盖两种差异极大的行为。这个思路用在性能仿真校准上恰好对症。常规 TTFT/TPOT 的波动可以用一个相对较小的正态或对数正态抖动来模拟对应扩散部分而真正的高延迟长尾比如热降频导致的 100 毫秒级停顿、调度器罕见的抢占总延迟单独作为一个低概率高幅度的跳跃事件加入模型对应跳跃部分。这样校准的好处是均值由常规项决定p99 由跳跃项决定调整一个不会破坏另一个。当然这是一个思路层面的借鉴不是把金融公式直接套到系统性能上。核心启发是面对均值容易拟合、长尾对不上的问题不要试图用一个参数修正所有误差而应该把误差来源分解成常规波动和罕见跳跃两类分别校准。6.3 一段实用的两阶段校准流程把上面思路落地我的校准流程分成两步。第一步用 p50 附近的常规数据校准基础参数比如有效算力系数和带宽竞争系数。具体做法是调整 compute_tflops_bf16 后面的利用率系数让仿真输出的 p50 TTFT 和实机测量值偏差控制在 5% 以内。第二步用 p99 和 p999 数据校准跳跃参数在仿真器的延迟模型里增加一个低概率的额外耗时项代表降频或抢占等异常事件。实测现象对应校准参数调整方向p50 TTFT 整体偏高有效算力系数调高利用率p50 TPOT 整体偏高有效带宽系数调大带宽利用率p99 远高于 p50 且偶发尖刺跳跃强度/幅度增加低概率额外耗时高并发下 p99 恶化明显调度器排队模型检查抢占与公平策略这套流程的好处是每个参数都有明确的物理含义不会出现为了拟合而拟合的玄学调参。我通常在仿真环境里跑一轮基准记录校准前的 p50/p99然后按上述流程调整再跑一轮验证通常两三轮就能收敛。最后把校准记录连同配置一起提交到版本库后续任何人拿到这份配置都能理解每个数字是怎么定出来的。7. 跑完这轮仿真之后我的几点习惯仿真项目做多了我养成了几个固定习惯分享出来供参考。第一个习惯是把所有建模假设写进配置文件的注释里比如稀疏算力按 0.8 折算稠密KV cache 可用容量按总容量减权重再乘 0.9这样三个月后回头再看还能想起来当时为什么这么定不至于对着一个数字发呆。第二个习惯是永远保留一份最小复现集。一份 Jalapeño 的 YAML 配置、一个小规模 trace、一段解析脚本三者放在同一个目录确保任何人在任何机器上都能十分钟内复现整套仿真结果。这比一份精美的分析报告更有价值因为报告只能证明结论复现集才能验证结论。第三个习惯和校准有关仿真结果和实机数据对齐这件事不是一次性的而是每次硬件驱动版本更新或者模型权重变化后都要重做的。参数模型是活的不是一份提交完就归档的文档。我个人的体会是用 Merton 模型那种常规波动加罕见跳跃的思路去理解性能分布能少走很多弯路尤其是当你需要向团队解释为什么 p99 总是比 p50 差十倍的时候。希望这套从 Hot Chips 规格到 TTFT/TPOT 的流程能帮你把下一颗芯片的性能问题提前看清楚。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门