RNN 在线推理为什么可能延迟较高?
简化版
RNN 解码时间维有严格依赖,单序列难以并行;在线延迟主要由序列长度、层数、hidden size、beam 和每步 kernel/内存访问决定。优化要区分首包延迟、单步延迟与总生成时长。
详细版
-
输入编码可按 batch 并行,递归时间步不可一次展开推理。
-
动态 batching 提高吞吐但增加排队。
-
bucketing 减少 padding 无效步。
-
量化、蒸馏和减少 beam 可降单步成本。
-
stateful 流式服务可复用状态但增加会话管理。
完整版教学
一、串行关键路径随有效步数增长
每个 h_t 依赖 h_(t-1),GPU 再强也不能同时计算同一序列所有递归步。
batch 能并行不同请求,但最慢序列和 padding 会拖住整个批次。
因此 FLOPs 之外,kernel launch、小矩阵利用率和调度等待常主导 P99。
二、底层机制与公式
total_latency≈queue+T*(cell_latency)+decode_overhead
beam cost roughly scales with B
三、带数字的推演
单步 0.4ms、生成 100 步,纯循环至少约 40ms;beam 从 1 调到 4 后候选与状态规模近似 4 倍,实际延迟还受并行利用率影响。
四、方案对比
| 方案/对象 | 核心特点 | 代价或边界 |
|---|---|---|
| 静态 batch | 吞吐高 | 等待与 padding 多 |
| 动态 batch | 聚合短窗口请求 | 调度复杂 |
| Stateful streaming | 增量响应低延迟 | 状态/容错成本 |
五、执行流程
分解 queue/encode/step/decode -> 按长度分桶 -> 目标并发压测
-> 优化 batch/beam/量化 -> 测 P50/P99 与吞吐 -> 故障/状态清理
六、边界条件与工程代价
平均序列长度不能代表尾延迟,必须对长度分位与 beam 终止步分别统计。
状态缓存若在重试或迁移时丢失,会重复计算或生成不一致,需要幂等会话协议与快照策略。
记忆钩子:RNN 服务延迟可拆成“排队 + T 个串行 cell + 搜索”。
七、常见误区与追问
-
误区:GPU 能把 RNN 全时间步并行。 同序列递归依赖形成串行链。
-
追问:batch 越大越好吗? 吞吐升但排队和最慢样本拖累延迟。
-
误区:只看模型 FLOPs 即可估延迟。 小 kernel 和调度开销可能主导。
-
追问:如何减少 padding? 长度 bucketing 或活跃序列动态压缩。
-
追问:上线报什么? 首包、每步、总延迟、P99、吞吐和状态内存。
八、加强记忆
RNN 服务延迟可拆成“排队 + T 个串行 cell + 搜索”。
优化 batch 提吞吐,缩 T/beam 才直接缩关键路径。