PyTorch CUDA Graph 怎样固定输入形状复用推理流程
如果同一个 PyTorch 推理模型被高频重复调用,而每个请求的输入形状基本稳定,CUDA Graph 可以把已经捕获的 GPU 工作整体重放,减少 Python、C++ 和 CUDA 驱动层的调度开销。关键不是把每个新批次重新建图,而是让新数据复制进一组长期存活、形状固定的 Tensor,再调用 replay()。
官方地址:https://docs.pytorch.org/docs/stable/notes/cuda.html
这篇只讨论 CUDA Graph 的输入形状、虚拟内存地址和推理流程复用。代码是结构示例,不代表已经在本机运行;配图也是静态说明图,不是截图或性能证据。
这个问题的直接答案
把请求按固定形状分组,为每个形状准备一组静态输入和静态输出:先在旁路流上完成几次预热,再用 torch.cuda.graph 捕获模型调用。运行时只把新批次复制到 static_input,随后调用 graph.replay(),读取或复制 static_output。
CUDA Graph 不适合任意动态输入。捕获期间不能依赖会改变形状的控制流,不能在图中做 .item() 这类 CPU-GPU 同步,也不能让每次 replay 换一组输入输出地址。变长请求应使用多个形状桶,无法归桶时回退 eager 执行。
为什么 CUDA Graph 要求输入形状稳定
PyTorch 官方文档把 CUDA Graph 描述为对 CUDA stream 工作的记录:捕获后可以重复启动同一组 kernel 和参数。指针参数意味着每次 replay 使用相同的内存地址,因此图复用的是一条固定的 GPU 工作路径,而不是一段可以自由改变输入尺寸的普通 Python 函数。
捕获前至少要确认三件事:
- 模型输入、输出以及中间张量的尺寸和布局在同一张图的 replay 中保持一致。
- 控制流不能由 CPU 或不受支持的动态数据分支决定;捕获期间不能调用会把 GPU 值同步回 CPU 的操作。
- 预热、捕获和 replay 使用同一设备,并保留静态输入、静态输出和图对象的引用。

最小配方:静态输入、预热、捕获和 replay
下面的示例把批量大小和特征维度固定下来。旁路流只负责预热,捕获阶段由 torch.cuda.graph 管理流;真正的请求数据在 replay 前通过 copy_ 写入已经存在的输入 Tensor。
import torch
# 用固定形状的模型示例说明一张图对应一类输入桶
model = torch.nn.Sequential(
torch.nn.Linear(128, 256),
torch.nn.ReLU(),
torch.nn.Linear(256, 10),
).cuda().eval()
batch_shape = (8, 128)
static_input = torch.empty(batch_shape, device="cuda")
graph = torch.cuda.CUDAGraph()
# 先在旁路流上预热,让分配和库状态稳定下来
warmup_stream = torch.cuda.Stream()
warmup_stream.wait_stream(torch.cuda.current_stream())
with torch.cuda.stream(warmup_stream), torch.inference_mode():
for _ in range(3):
model(static_input)
torch.cuda.current_stream().wait_stream(warmup_stream)
# 捕获固定形状的前向路径;输出 Tensor 要长期保留
with torch.inference_mode(), torch.cuda.graph(graph):
static_output = model(static_input)
def infer_one_bucket(batch: torch.Tensor) -> torch.Tensor:
# 只替换固定地址中的内容,不替换 Tensor 本身
if tuple(batch.shape) != batch_shape:
raise ValueError(f"需要形状 {batch_shape},实际得到 {tuple(batch.shape)}")
static_input.copy_(batch)
graph.replay()
# 复制结果,避免下一次 replay 覆盖调用方正在使用的输出
return static_output.clone()
这段代码的核心约束是“内容可变,地址不变”。batch 可以来自不同请求,但它的形状必须匹配;static_input 和 static_output 则由图对象持有并跨请求复用。若调用方允许直接消费固定输出,也可以不做 clone(),但必须明确下一次 replay 会覆盖它。
固定地址怎样承载不同批次数据
每次请求的真实批次不是 CUDA Graph 的新输入指针。更稳定的关系是:真实批次把内容复制到 static_input,图按照捕获时记录的地址读取它,执行固定的模型路径,再把结果写到 static_output。PyTorch 的 CUDA caching allocator 会为捕获分配图私有内存池,图和捕获期间创建的 Tensor 存活时,这组地址才有稳定的生命周期。

变长请求怎样落地
最常见的工程做法是建立形状桶,例如把序列长度分成若干档,每一档各自维护 static_input、输出 Tensor 和 CUDAGraph。请求先按形状选择图,再把有效数据复制进对应缓冲区;超出最大长度或需要完全不同控制流的请求,直接走 eager 路径。
不要为了“复用一张图”把不同长度强行塞入同一 Tensor 后再在图内动态判断。这样通常会把 padding、掩码和输出裁剪混在一起,既增加内存占用,也可能违反捕获时的静态形状约束。更合理的边界是:少量稳定形状用多张图,形状高度离散则评估图维护成本是否值得。
常见误区与速查
| 现象 | 原因 | 处理方式 |
|---|---|---|
| replay 后结果像被覆盖 | 多次调用共用 static_output | 在交给异步调用方前 clone 或完成消费 |
| 换长度后捕获路径失效 | 同一张图不支持动态形状 | 按长度分桶,或回退 eager |
| 捕获时出现同步错误 | 调用了 item 等 CPU-GPU 同步操作 | 把判断移到图外,或改用支持的 GPU 控制流 |
| 多张图互相影响内存 | 共享内存池但 replay 顺序或并发条件不满足 | 默认使用独立池,只有能保证顺序时才共享 |
归纳起来,CUDA Graph 的复用单位不是“任意输入的一次函数调用”,而是“固定形状、固定地址、固定控制流的一段 GPU 工作”。先把请求形状整理成少量稳定桶,再为每桶建立长生命周期的图对象,通常比在图内追逐动态输入更容易维护。
相关问题
CUDA Graph 一定比 eager 快吗?
不一定。它主要减少 CPU 侧的参数准备和 kernel dispatch 开销;如果模型本身已经被大算子占满 GPU,收益可能有限,应该用与业务负载匹配的基准数据评估。
为什么不能每次请求重新创建 static_input?
因为图记录的是指针参数。换 Tensor 通常也就换了虚拟地址,replay 仍会读捕获时的地址,导致数据没有进入图实际读取的位置,甚至触及非法访问风险。
Hugging Face Datasets 怎样用 map 批处理并保留列
- 上一篇
- Hugging Face Datasets 怎样用 map 批处理并保留列
- 下一篇
- Transformers generate 怎样读取每条序列的分数
-
- 科技周边 · 人工智能 | 43分钟前 |
- PyTorch autograd anomaly detection 怎样定位 NaN 梯度
- 248浏览 收藏
-
- 科技周边 · 人工智能 | 47分钟前 |
- OpenAI Responses API 的 tool call 状态怎样串联
- 253浏览 收藏
-
- 科技周边 · 人工智能 | 51分钟前 |
- LangChain structured output 怎样固定工具返回 schema
- 165浏览 收藏
-
- 科技周边 · 人工智能 | 52分钟前 |
- vLLM continuous batching 的请求调度观察点
- 211浏览 收藏
-
- 科技周边 · 人工智能 | 52分钟前 |
- ONNX Runtime IO Binding 怎样减少 GPU 张量拷贝
- 424浏览 收藏
-
- 科技周边 · 人工智能 | 54分钟前 |
- PyTorch DataLoader persistent_workers 的进程生命周期
- 435浏览 收藏
-
- 科技周边 · 人工智能 | 55分钟前 |
- PyTorch DataLoader 如何限制预取批次避免共享内存耗尽
- 265浏览 收藏
-
- 科技周边 · 人工智能 | 59分钟前 |
- Transformers generate 怎样读取每条序列的分数
- 249浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- Hugging Face Datasets 怎样用 map 批处理并保留列
- 329浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 | 人工智能 ·
- Transformers quantization picker 怎样按硬件选择量化方式
- 120浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- Transformers PEFT adapter 怎样只保存可训练权重
- 422浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- QLoRA 的 nf4 与 double quant 参数配置方法
- 284浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 819次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 811次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 903次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 873次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 695次使用
-
- 量化模型本地推理的显存估算方法
- 2026-10-17 501浏览
-
- 本地大模型反复输出同一句话怎么调整生成参数
- 2026-09-06 501浏览
-
- Python 调用大模型时如何用结构化输出校验 JSON:从解析失败到可重试
- 2026-08-29 501浏览
-
- AI写作工具免费版安装教程(含豆包Clawdbot)
- 2026-05-30 501浏览
-
- WPS AI能自动生成PPT吗?输入主题一键制作演示文稿
- 2026-05-27 501浏览

