一句话定义:超时(Timeout)是调用方给一次请求设的最晚等待期限,到点就不等了;取消(Cancellation)是主动告诉对方“这次计算不用继续了”。
打个比方。你在餐厅点了份慢炖菜,等半小时还没上,起身走了——这是超时。厨房并不知道你走了,菜照炖,服务员还在摆盘。另一种做法是你中途告诉服务员“那道菜取消吧”,这是取消。前者只是你不等了,后者才是让对方停下来。
在 AI 应用里,这个区别很值钱。一次大模型推理往往是几秒到几十秒的长任务,输出是逐块(token)吐出来的。用户关掉浏览器标签页,连接断了,但服务端的生成循环不一定知道,它可能把剩下的内容全部生成完,GPU 时间照烧。于是出现典型浪费:日志里一堆“没人在等”的请求,账单照涨。
为什么不能默认“断开就是停止”
在很多编程模型里,客户端断开只是一个网络事件,不等于业务层的取消指令。要让推理真正停下,需要把取消信号一路传下去:网关 → 应用服务 → 推理调度 → 生成循环。生成循环在每个 token 或每若干个 token 之间检查一次“是否已取消”。如果框架不支持中断,或请求已经和其他任务捆在同一个批次里,停下的粒度就会变粗。
超时要分几层
- 连接超时:连不上就别死等。
- 首 token 超时:模型迟迟不吐第一个字,通常说明排队或过载。
- 总时长超时:再长的任务也要有天花板。
超时之后是否重试要谨慎。重试适合幂等的读操作;对又慢又贵的生成任务,盲目重试等于把成本翻倍,而用户可能早已离开。
从业者的四个动作
1. 把连接断开当取消信号,向上游传递,不要只停在网关。
2. 在生成循环里埋检查点,发现已取消就尽早返回、释放资源。
3. 区分“用户主动取消”和“超时放弃”:前者通常不该按完整任务计费,具体计费规则以官方页面为准。
4. 监控“无人在等却仍在跑”的请求数,这是最直接的止损指标。
超时 vs 取消
| 维度 | 超时 | 取消 |
|---|---|---|
| 谁发起 | 调用方等不下去 | 调用方主动不要了 |
| 对方知道吗 | 通常不知道 | 明确收到信号 |
| 止损效果 | 取决于服务端自己有没有超时 | 更好,但需服务端配合 |
| 典型场景 | 网络卡、下游慢 | 用户关页面、点“停止生成” |
对普通人:看到“生成中”就关页面,后台不一定停;涉及扣费的产品,规则以官方说明为准。对从业者:超时保底,取消止损,两者搭配才能既不让人干等,也不让机器白跑。
