RISC-V端侧推理时延分解机制解析:首Token时延、输出速率与算子级预算分配
1. 两个指标决定了两种优化方向
端侧推理的时延优化,第一个容易出错的地方是用单一数值衡量性能。"该模型耗时 80 ms"这样的描述缺少三个限定:处于哪个阶段、输入序列多长、并发几路。缺少限定条件的数字无法用于比较,也无法指导优化。
工程上应区分的两个核心指标是:
- 首Token时延(TTFT,Time To First Token):从请求提交到第一个Token输出的时间,由 prefill 阶段决定;
- 输出速率:后续Token的平均生成间隔,常以 TPOT 或 tokens/s 度量,由 decode 阶段决定。
二者对应的计算形态差异极大。prefill 一次性处理完整输入序列,参与矩阵乘的行数等于序列长度,算术强度高;decode 每步只处理一个新Token,参与计算的行数为 1,权重读取量与 prefill 相当而计算量下降数个数量级,算术强度低。
由此得到第一个结论:两个阶段的瓶颈类型不同,优化手段不可互换——把 decode 阶段的降字节数手段搬到 prefill,不会带来预期的收益。所有时延讨论都应先声明针对哪个指标。
2. 时延的分解式
把端到端时延写成分项之和,是后续所有定量分析的基础:
T_e2e = T_queue + T_pre + Σ T_op + T_sync + T_io + T_post
各项含义与端侧场景下的典型特征:
| 分项 | 含义 | 端侧特征 |
|---|---|---|
T_queue |
任务排队与调度延迟 | 多核划分与核间唤醒开销,受调度策略影响 |
T_pre |
输入预处理 | 分词、图像缩放与归一化、张量排布转换 |
Σ T_op |
算子执行总时间 | 通常占比最大,但不必然是瓶颈 |
T_sync |
层间与核间同步 | 屏障、归并、流水线气泡 |
T_io |
未与计算重叠的搬运 | 权重首次加载、DMA 拷贝 |
T_post |
输出后处理 | 采样、反量化、反归一化、解码拼装 |
分解式的价值在于强制列出全部环节。实践中"各部分耗时之和小于端到端实测值"的现象,几乎都源于遗漏某一项,而非计时工具出错。端侧常被低估的两项是 T_pre 与 T_post:小模型上分词与采样的固定开销未必小,串行执行的反量化与解码拼装同样会累积成可观比例。
3. 单算子的时延下界
判断某一算子是否已接近极限,需要两个下界值。
访存下界:算子执行期间需要搬运的字节数除以实际可达带宽。
T_mem = B_bytes / BW_eff
计算下界:浮点或整数运算量除以峰值算力与实际效率。
T_cmp = FLOPs / (Peak_ops × η)
取两者较大者即为该算子的时延下界,二者的比值由算术强度决定:
I = FLOPs / B_bytes
当 I 低于平台的平衡点(峰值算力与峰值带宽之比)时,算子受访存约束,反之受计算约束。端侧平台的算力带宽比通常低于数据中心平台,同一算子在两类平台上的瓶颈类型可能不同。
以矩阵乘为例:权重矩阵为 N × K,输入行数为 M。每读取一个权重元素参与 2M 次浮点运算,故 I ≈ 2M。M = 1 时(decode 阶段的 GEMV),I 仅为 2 左右,远低于任何平台的平衡点,必然受访存约束;M 增大到数百(prefill 阶段的 GEMM),I 升至数百,转为受计算约束。
由此可推出量化在两类算子上的不同作用:
- 对访存受限算子,权重字节数降至四分之一(INT8)或八分之一(INT4),
T_mem近似同比例下降,收益直接; - 对计算受限算子,量化主要降低的是访存侧的分量,若整数运算峰值与浮点峰值相当,计算项不会同比例下降;若解包与反量化未融合进主循环,计算项反而可能上升。
收益因此不能从位宽比例推算,必须实测。向量宽度的作用同理:加宽数据通路提高的是并行度上限,在访存受限区间内,带宽不变而计算更快,端到端时延不变。
4. prefill 与 decode 的结构性差异
将两个阶段的特征并列,可以看清哪些手段适用于哪一阶段:
| 维度 | prefill | decode |
|---|---|---|
| 每步输入 | 完整序列 | 单个 Token |
| 主要算子形态 | GEMM(M 较大) | GEMV(M = 1) |
| 算术强度 | 高 | 低 |
| 约束类型 | 算力与向量吞吐 | 访存带宽 |
| 可并行性 | 高,可按行或按列切分 | 低,步与步之间强依赖 |
| 主要优化方向 | 提高向量利用率、融合相邻算子、多核切分 | 降低权重字节数、提高带宽利用率、压缩 KV Cache |
| 加核的收益 | 明显 | 有限,受带宽总量约束 |
decode 阶段有一项 prefill 阶段不具备的访存开销:KV Cache 的读取量随已生成长度线性增长。单步的 KV 读取字节数近似为:
B_kv ≈ 2 × L × H_kv × d_head × seq_len × bytes_per_element
其中 L 为层数,H_kv 为 KV 头数(分组查询注意力下可远小于注意力头数),seq_len 为当前上下文长度。序列越长,该项占比越高,输出速率随之下降;这是结构性现象而非实现缺陷,应对方式为 KV 量化、窗口限制或前缀复用。
5. 预算分配方法
时延优化的目标通常不是"越快越好",而是在给定约束下满足要求。预算分配即把端到端目标拆成各环节的可执行指标,步骤有五:
- 确定目标与约束:端到端时延上限、输出速率下限、精度下限三者共同构成可行域;
- 测量基线:按第 2 节的分项逐项计时,得到实测分布;
- 计算敏感度:按
ΔT_e2e / T_e2e = (T_i / T_e2e) × ΔT_i / T_i排序,占比越大的环节在同等改进幅度下边际收益越高; - 按敏感度与代价排序投入:优先选择敏感度高且实现代价低的环节,避免投入到占比个位数却需要大幅改动的环节;
- 逐项验证:每改一项后重新测量,确认增益归因正确。多项同时改动会导致无法归因,这是性能工程中最常见的返工原因。
当某一环节的预算无法通过局部优化满足时,可选的调整路径只有三类,且各有代价:
- 降低精度:等比降低访存侧分量,代价是精度风险与可能的解包开销;
- 改变数据流:融合算子、调整分块以减少中间张量往返,代价是寄存器压力与实现复杂度;
- 增加并行度:多核切分,代价是同步开销,并在访存受限区间内迅速饱和。
这三条路径落到实现层面,依赖调度层与算子层同时具备可配置能力:调度侧决定任务如何划分到多个核、何时唤醒与同步,算子侧决定单个算子内部的向量化策略与数据布局。以玄铁端侧 AI 解决方案为例,其 AI 调度核、Titan 向量引擎与算子库/工具链的分工正对应这一层次划分,为预算分配提供可调的作用点。缺少任一层级的可配置性,前述调整路径都难以落地。
6. 实战:一次完整的时延分解
以下示例给出分解的执行流程与解读方法。数值为按带宽下界推得的结果,用于说明计算方法,不是实测值,不可外推至其他模型或平台。
步骤一:估算访存下界。 设某 0.5B 参数模型以 INT8 权重部署,权重大小约 500 MB。可达内存带宽取 10 GB/s(示例取值,实际应以目标平台实测为准),则完整读取一遍权重的理论时间为:
T_mem = 500 MB / 10 GB/s = 50 ms
decode 阶段每生成一个 Token 至少需要读取一遍全部权重,故单 Token 时延的下界为 50 ms,对应输出速率上限约 20 tokens/s。若实测输出速率为 12 tokens/s,则差值部分来自 KV Cache 读取、算子效率不足与同步开销,应逐项分解而非笼统归因为"算子慢"。
步骤二:分层计时。 在关键路径上插入单调时钟时间戳(clock_gettime(CLOCK_MONOTONIC)),按第 2 节的分项记录。端侧环境下应优先使用内核 tracepoint 或已有的时间戳机制,减少插桩本身的观测者效应。
步骤三:与下界对照,形成判断。 将实测值与估算下界并列,差值即为可优化空间:
| 环节 | 实测 | 下界估算 | 差值来源判断 |
|---|---|---|---|
| prefill 计算 | 实测值 | 2·M·N·K / Peak_ops |
向量利用率不足或算子未融合 |
| decode 权重读取 | 实测值 | 500 MB / BW_eff |
KV Cache 叠加或带宽未跑满 |
| 预处理 | 实测值 | 与输入规模成正比 | 常被忽略的固定开销 |
| 同步 | 实测值 | 随核数与划分层数增加 | 划分粒度不当或伪共享 |
步骤四:确认可重叠项。 T_io 中能与计算重叠的部分不应计入串行时延,需检查 DMA 是否与算子并行、权重是否在首次推理前预取。可重叠项若被误计为串行,预算会被错误地分配给它。
步骤五:修改单项并复测。 每次只改一处。若端到端时延改善幅度与按占比推算的预期不符,说明该环节并非其所在链路的实际约束,应回到步骤三重新核查。
7. 常见问题与成因
- 首Token时延远高于算力下界:prefill 阶段的并行度未充分利用,或权重首次加载未与计算重叠;
- 输出速率随上下文长度持续下降:KV Cache 读取量线性增长,属结构性现象,需采用 KV 量化或限制上下文窗口;
- 平均时延正常但 P99 偏高:调度抖动、其他任务抢占或频率调节所致,应从系统层面排查而非优化算子;
- 增加核数后首Token时延改善而输出速率不变:符合 decode 阶段受带宽约束的预期,加核对带宽总量无帮助;
- 量化后时延不降反升:解包或反量化未融合进主循环,导致计算项上升超过访存项的下降;
- 各分项耗时之和小于端到端实测值:存在未计入的环节,常见于预处理、后处理与同步。
8. 结语
端侧推理的时延问题,本质上是把端到端目标拆解为可测量的分项,再用带宽与算力下界判断各分项是否已接近极限,最后把优化预算投入到敏感度最高的环节。分解式、算术强度判据与 prefill/decode 二分,构成这套方法的三块基础。
下一篇将讨论端侧多模型并发场景下的内存争用与调度策略:当多个模型驻留同一设备时,权重常驻与激活峰值如何取舍、并发请求如何排队,以及内存不足时的降级路径。
浙公网安备 33010602011771号