资讯动态

ComfyUI 多工作流跑起来显存直接爆:Swap 策略实测省下 3GB

发布时间:2026/10/22 2:53:14 来源:尧图企业网站定制
本文摘要多工作流排队跑 ComfyUI 时显存峰值超限进程被系统 OOM 直接杀掉任务中断。把峰值拆成上下文、常驻权重、单步激活三段用 swap 搬走常驻权重并双口径采样验证。一、问题与结论在 Windows 单张 NVIDIA 卡上跑 Stable DiffusionComfyUI 的 GUI、API、后端共用同一套 graph/nodes 图结构同一个工作流既能手动点开跑也能丢给 API 排队。典型故障分两层——pip install自定义节点后启动报ImportError是启动期依赖冲突本篇只处理第二层能启动但队列一长就torch.cuda.OutOfMemoryError进程被杀。结论先给出把爆显存拆成三段——CUDA 上下文与碎片、常驻权重、单步中间激活——swap 只搬得动第二段。若瓶颈在第三段搬走再多权重OOM 仍落在同一个图节点。标题里的3GB是本机待复现的测量目标条件随文公开所列公开来源不含显存测试数据该数字标注为未验证。二、排查与选择依据先锁口径再谈数字。nvidia-smi读到的是驱动级memory.used含上下文与碎片torch.cuda.max_memory_allocated()读的是分配器级。两组对比必须用同一口径否则差值可能只是上下文或碎片造成的。排查顺序每步留记录缺一项结论就不可复现锁版本ComfyUI 目录里git rev-parse --short HEAD、nvidia-smi的驱动版本、python -c import torch; print(torch.__version__, torch.version.cuda)、Windows 页面文件落在 SSD 还是 HDD。取基线单工作流连跑 N 张记驱动级峰值与单张耗时。复现多工作流队列记录 OOM 触发的具体图节点名。归因把该节点峰值拆成常驻权重与单步激活两部分看哪一段占大头。替代方案与取舍方案选择条件代价不该用的场景单实例 API 串行队列多工作流只是排队不需同时在场总吞吐下降必须多实例同时产出拆分工作流为两次调用峰值来自两个可分离阶段结构改动、中间结果落盘单节点单步就触顶降分辨率 / 减 batch需要立刻压低峰值直接改变产出分辨率有硬性要求本文的 swap 搬常驻权重瓶颈在常驻权重、PCIe 充足回填耗时、抖动风险单步激活触顶或多实例并发表格读法当产出质量不可动、且峰值来自可分离的常驻块时才轮到 swap否则串行队列更省事它不引入任何新机制。三、关键原理swap一词先定义它至少指三件不同的事把常驻权重搬进系统内存、操作系统页面文件交换、某个节点自带的 offload 开关。本文只指第一种。所列来源未提供开关文档具体 flag 名需自行在检出的 commit 上核实本文不填猜测值。搬得走的是不参与单步峰值的常驻块搬不走的是采样循环里那一层最大的中间激活。代价有三项PCIe 回填时间、换入换出抖动、跨进程失效——多个 ComfyUI 实例各持 CUDA 上下文进程内 swap 对实例间争抢不起作用。异常捕获要同时接RuntimeError与torch.cuda.OutOfMemoryError不同 torch 版本抛出的类不同只接其一会在另一版本上静默失败。另一参考仓库 MoneyPrinterTurbo 自述为关键词 → 短视频的流水线描述中未涉及 ComfyUI 显存不作为本结论的旁证。四、可运行示例环境Windows 11、Python 3.10、带 CUDA 构建的torch、单卡、nvidia-smi在 PATH 中。输入无脚本自行占满显存后搬走一半。步骤python vr_swap_probe.py# vr_swap_probe.py —— 原创测量脚本非所列仓库代码importtime,subprocess,sysimporttorch MB1024**2BLOCK_MB512OOM(RuntimeError,getattr(torch.cuda,OutOfMemoryError,RuntimeError))defdriver_peak_mb(seconds30,interval0.5):peak,end0,time.time()secondswhiletime.time()end:outsubprocess.run([nvidia-smi,--query-gpumemory.used,--formatcsv,noheader,nounits],capture_outputTrue,textTrue,checkTrue)peakmax(peak,max(int(x)forxinout.stdout.split()))time.sleep(interval)returnpeakdeffill_until_oom():blocks[]whileTrue:try:blocks.append(torch.empty(BLOCK_MB*MB//2,dtypetorch.float16,devicecuda))exceptOOM:breakreturnblocksdefmain():ifnottorch.cuda.is_available():sys.exit(no cuda device)torch.cuda.reset_peak_memory_stats()blocksfill_until_oom()fulltorch.cuda.memory_allocated()/MBprint(fblocks{len(blocks)}alloc{full:.0f}MB fpeak{torch.cuda.max_memory_allocated()/MB:.0f}MB)t0time.time()movedblocks[:len(blocks)//2]forbinmoved:b.datab.data.to(cpu)torch.cuda.synchronize()torch.cuda.empty_cache()print(ffreed{full-torch.cuda.memory_allocated()/MB:.0f}MB fmove_cost{time.time()-t0:.2f}s)t1time.time()forbinmoved:b.datab.data.to(cuda)torch.cuda.synchronize()print(fswap_back_cost{time.time()-t1:.2f}s)print(fdriver_peak{driver_peak_mb()}MB)if__name____main__:main()预期输出示例值随显卡与驱动而异仅说明字段含义blocks24 alloc12288MB peak12288MB freed6144MB move_cost1.83s swap_back_cost1.76s driver_peak14320MB实际输出验证方法在目标机器复现后按下述格式逐行记录当前未验证不填占位数字blocksn allocMB peakMB freedMB move_costs swap_back_costs driver_peakMB常见失败一AttributeError: module torch.cuda has no attribute OutOfMemoryError原因是 torch 版本过旧except子句求值时即崩修复是用上面的getattr(..., RuntimeError)兜底。常见失败二Windows 上FileNotFoundError: nvidia-smi原因是该 exe 不在 PATH改为写全路径。五、验证结果与边界对照实验固定同 N 张、同分辨率、同采样步数只改 swap 开关三列同表记录组驱动级峰值单张耗时是否 OOM对照无 swap未验证未验证未验证实验启用 swap未验证未验证未验证判读规则峰值降了但单张耗时成倍增长同样算失败换入换出抖动两组 OOM 落在同一图节点、峰值差远小于搬运量说明瓶颈是单步激活swap 无收益单实例峰值降了但两实例同跑仍 OOM说明争抢在进程之间本方案不覆盖。另外页面文件若在机械盘或系统内存不足会出现持续无响应属抖动失败。标题的3GB只有在同表列出耗时代价时才成立当前未验证不构成对其他配置的承诺。参考资料ComfyUI — Comfy-Org/ComfyUIMoneyPrinterTurbo — harry0703/MoneyPrinterTurbo

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑