首页优化地图方法索引基础概念
返回技术汇总表 ↗

M023 · 独立详解

异步调度与CPU/设备重叠:谁能提前做,谁必须等待

从三个独立批次的时间线出发,再回到自回归生成,区分主机返回、输入就绪、设备完成与结果消费。

调度与并行详解已编写
视频讲解待制作

这篇文章的小视频尚未制作;可以先阅读下方文字详解。

本页目录

01 · 每做完一件事就等待,会留下空档

假设每批数据要CPU准备2 ms,设备计算6 ms。若CPU等设备完全做完才准备下一批,三批需要24 ms;若下一批的准备不依赖当前设备结果,CPU可以在设备计算时提前准备,三批在20 ms结束。

异步指发出任务后调用方可继续工作;重叠指两段实际执行时间同时发生。前者给后者创造机会,但需要独立依赖、足够资源和正确生命周期。

02 · 用时间线找出可重叠部分

CPU准备与设备计算,怎样错开推进

一个资源负责一个阶段,批次独立,缓冲充足;未计复制,下一批准备不依赖当前计算结果。无运行时开销与争用,不代表实测。

本例CPU依次在0–2、2–4、4–6 ms准备三批;设备依次在2–8、8–14、14–20 ms执行。并没有让同一批数据尚未准备好就开始计算,也没有假设设备同时执行三份计算。

在足够缓冲、固定耗时和独立批次下,先支付一次准备与计算的填充成本,再由较慢阶段决定稳态速度。CPU准备变成8 ms、设备仍6 ms时,三批总计30 ms,瓶颈转为CPU;单独让设备更快无法消除它。

03 · 一次调用有四个不同的完成点

状态含义能否消费结果
调用已返回主机已下发或排队任务不能据此断言设备结果就绪。
输入已就绪设备可读到本任务所需数据还需执行计算。
设备计算已完成设备输出已产生CPU读取前可能还需结果复制。
结果复制/处理完成CPU可按接口约定读取并反馈之后再更新相关请求状态。

例如异步D2H是设备到主机的结果复制。在复制完成前就遍历CPU结果,可能读到未完成内容。正确做法是等待这个结果的完成通知,不一定要阻塞所有无关工作。

依据:PyTorch · pin_memory与non_blocking使用指南 ↗ · PyTorch 2.14 · CUDA stream、等待与内存生命周期 ↗

04 · stream与event,让等待落在真正的依赖上

CUDA stream可理解为有序任务队列;event是某个位置的完成标记。复制队列完成批次2输入后记录事件,计算队列等这个事件,再使用批次2。这是设备依赖,不等同于CPU把所有工作都等完。

教学示意 · 不代表硬件实测
copy_queue:复制输入2 → 记录ready_2
compute_queue:计算输入1 → 等待ready_2 → 计算输入2
CPU:准备输入3、处理已完成的输入0结果

复用输入1槽位前:确认使用它的计算完成
CPU读取结果1前:确认D2H复制完成

不同队列只是允许并行,不保证硬件一定能同时执行。分配器回收与用户缓冲池还要遵守使用队列的生命周期约定;等待事件保证就绪,与保留内存不被回收是相关但不同的问题。

依据:PyTorch 2.14 · CUDA stream、等待与内存生命周期 ↗

05 · 自回归下一token,哪些工作不能提前

同一个请求,第n步生成的token决定第n+1步的输入。所以第n+1步不能用尚不存在的token做真正计算。可以提前分配容量、整理不依赖新token的元数据,或者处理其他独立请求。

后续工作是否可与当前步重叠条件
另一个独立请求的分词/解析可能CPU资源和服务调度允许。
准备固定缓冲与不变元数据可能不读取本步尚未生成的结果。
同请求下一步实际token输入计算必须等待token依赖设备上采样后保留token可以减少CPU往返。
CPU停止检查/响应处理与后续设备工作特定引擎可支持必须处理停止、取消和可能多算一步的状态。

TensorRT-LLM的Overlap Scheduler描述了设备当前计算与CPU处理前一轮结果的流水组织。它用引擎管理的设备输出和异步状态衔接,不是把未知token预测为已知输入。

如果CPU的EOS/自定义停止判断尚未完成就推进后续工作,系统可能多算一部分。这需要引擎处理结果丢弃、KV释放、取消和请求状态,不应把可能多算的token发给用户。

依据:TensorRT-LLM · Overlap Scheduler ↗

06 · 训练能提前加载数据,但不能越过更新边界

下一批的读取、解压与分词通常不依赖当前权重更新,因而可以提前。但下一次前向究竟应使用更新前还是更新后的参数,是训练算法的要求。数据预取不授权改变参数版本。

梯度归约、裁剪、优化器更新及分片参数就绪也有依赖。能重叠哪一段,应由并行/分片框架管理,而不是在不同线程任意调用同一个模型。流水线训练的microbatch排程见M040。

07 · 常见的“异步却没有收益”与状态错误

  • 每下发一次就全设备同步:把可独立部分又串起来。
  • 频繁读取设备标量到CPU:例如热点里的.item()或结果转列表,可能触发等待。
  • 同队列顺序复制/计算:主机提前返回,不代表设备时间重叠。
  • 多队列争用同一带宽或执行资源:单独工作时的耗时不能直接套用。
  • 取消后立刻回收缓冲:仍在执行的任务可能继续读写。
  • 结果处理乱序却用相同请求编号:可能把内容发给错误请求。

同步也有必要用途,例如真实计时、检查设备错误和CPU消费结果。目标是把等待放在需要结果的边界,保留其他独立工作推进,而不是删掉全部同步。

08 · 用就绪队列组织可独立的工作

调度器教学伪代码 · 请求状态、事件与释放必须按实际框架实现
while service_has_work:
    retire_completed_tasks_and_safe_buffers()
    prepare_jobs_whose_inputs_do_not_need_pending_results()
    submit_ready_device_tasks_with_dependencies()
    process_completed_results_with_request_ids()
    # 没有可推进的工作时,等待对应完成事件;避免无界忙轮询。

下方CPU脚本验证两/三阶段流水的依赖,故意尝试过早覆盖缓冲和在结果就绪前使用它,检查这些行为被拒绝。它不启动异步设备工作。

NVIDIA可从CUDA stream语义和TensorRT-LLM引擎实现检查依赖;昇腾可从ACL异步复制及相应框架的队列/完成机制核对。相同“异步”概念不等于相同支持组合或API。

依据:PyTorch 2.14 · CUDA stream、等待与内存生命周期 ↗ · TensorRT-LLM · Overlap Scheduler ↗ · CANN Community 9.1.0 · aclrtMemcpyAsync与Host内存约束 ↗

09 · 用端到端时间线验证,而非只计调用返回

  • 记录CPU准备、设备提交、计算、结果复制和响应处理时间。
  • 沿真实依赖找关键路径,确认设备空档因哪一步造成。
  • 检查队列长度、在途任务与内存峰值,限制预取和排队。
  • 服务测TTFT、生成间隔、吞吐与尾延迟;批次更满未必单请求更快。
  • 测试EOS、自定义停止、取消、异常和长短请求混合,确认输出归属及缓冲释放。

自查:调用返回与任务完成为什么不是同一时刻?为什么CPU可以准备下一批数据,却不能提前得到同请求的下一个token?为什么“多一个stream”不保证重叠或正确结果?

流程位置与关联方法

这个方法可能出现在多个位置;计算线包含模型计算与算子实现,执行线包含运行时、内存和通信。

资料与核查范围

原理依据以原始论文和官方文档为主;算例与时间线是教学推导。文档核查日期:2026-10-10。引用 main / latest 文档时,实际接口以安装版本为准。

代码为接入片段或教学伪代码;本页没有声称完成 NVIDIA / 昇腾硬件实测。

← 返回总表中的 M023继续阅读:并行策略与设备映射 →
AI Infra 知识库 · 总览 → 独立讲解网站更新 2026-10-08
搜索知识库

搜索方法与基础概念 · Esc 关闭