读懂 DynamicVRAM:它什么时候会被悄悄关掉
很多人对 ComfyUI 显存机制的第一个误解是:以为 dynamic VRAM 有个独立的开关,不打开就用不上。实际上在 ComfyUI v0.31.0(2026-08-08)里,它更像一个推算出来的状态——你没有显式声明的时候,源码会看你有没有用别的几个参数,再倒推出该不该启用。于是就出现了这种局面:你为了「多占点显存跑快点」加了一个 --highvram,同时也把 dynamic VRAM 关掉了,而命令行里没有任何一个字提到它。
这篇就把这段判定逻辑拆开,顺便讲清楚跟它绑在一起的三个独立参数。以下参数名、默认值与 help 语义均以 v0.31.0 的 comfy/cli_args.py 为准,ComfyUI 大约每两周一个版本,参数会变。
一、判定函数长什么样
comfy/cli_args.py(v0.31.0)里这段判定是这样写的:
def enables_dynamic_vram():
if args.enable_dynamic_vram:
return True
return not args.disable_dynamic_vram and not args.highvram and not args.gpu_only and not args.novram and not args.cpu
逐条读下来其实只有两层:
第一层是「一票通过」。 只要你显式写了 --enable-dynamic-vram,函数直接返回 True,后面那一长串条件根本不会被检查。这个参数的 help 原文说的是「在默认不启用 dynamic VRAM 的系统上启用它」——注意它的定位是给那些默认不开的系统用的兜底手段,而不是给所有人加的常规参数。
第二层是「一票否决」。 没写 --enable-dynamic-vram 时,要五个条件同时成立才返回 True:没有 --disable-dynamic-vram、没有 --highvram、没有 --gpu-only、没有 --novram、没有 --cpu。任意一个中招,整个表达式就是 False。
由此可以放心得出的第一条结论是:什么参数都不加的时候,dynamic VRAM 是开着的。 大多数人从图标或者一键包直接启动 ComfyUI,落在的就是这一侧。
二、四个「看起来跟它无关」的开关
真正容易踩的是判定式里那四个显存模式开关。它们各自的 help 原意(v0.31.0)如下:
| 参数 | help 原意 | 对 dynamic VRAM 的连带效果 |
|---|---|---|
--gpu-only | 所有东西(含文本编码器/CLIP 模型等)都存放并运行在 GPU | 关闭 |
--highvram | 默认模型用完后会卸载到 CPU 内存,此选项让它们留在 GPU 内存 | 关闭 |
--novram | 当 --lowvram 还不够时用 | 关闭 |
--cpu | 全部用 CPU(慢) | 关闭 |
--lowvram | 如果启用了 dynamic vram,这个选项不做任何事;没用 dynamic vram 时,它让文本编码器跑在 CPU 上 | 不影响 |
这张表右边那一列,在这四个参数各自的 help 文本里一个字都没写——它只体现在 enables_dynamic_vram() 的实现里。所以读这张表的正确姿势是:左边两列是官方对你承诺的行为,右边一列是你得自己从源码里读出来的副作用。
最反直觉的一格是 --highvram。它的字面意思是「显存大,模型别卸载」,听上去是加速手段,但它同时把加载策略退回到了非 dynamic 的那一侧。如果你是大显存用户、加了 --highvram 之后反而觉得某些工作流的表现和以前不一样,先想到这条连带效果,而不是去怀疑模型文件。
另一格值得单独说的是 --lowvram。按 help 原文,只要 dynamic VRAM 是启用的,它「不做任何事」。也就是说,默认启动的情况下,老教程里那句流传甚广的「显存小就加 --lowvram」在当前版本已经不成立了——加上去不报错、不提示、也不生效。这是很多人跨版本升级后最容易困惑的地方:命令没变,行为变了。反过来,如果你确实想让 --lowvram 恢复作用,前提是 dynamic VRAM 处于关闭状态,比如你已经用了 --disable-dynamic-vram。
--disable-dynamic-vram 的 help 写得很直白:关闭 dynamic VRAM,改用基于估算(estimate based)的模型加载。这是「退回旧行为」的正门。相比之下用 --highvram 顺手把它关掉,属于走了侧门还不知道。
三、怎么确认自己现在是开还是关
先说个不太好听的实话:在我们能对照到的 v0.31.0 启动日志文案里,找不到「dynamic VRAM enabled / disabled」这样一行直白的状态输出。所以最可靠的判定方式不是翻日志,是看你自己的启动方式。
第一步,把真正生效的启动命令找出来。 用一键包或者桌面快捷方式启动的人,命令行参数常常藏在 .bat / .sh 脚本或者快捷方式属性里,而不是你记忆中的那条。找到之后按上面那个五条件清单对一遍:有没有 --disable-dynamic-vram、--highvram、--gpu-only、--novram、--cpu。命中任意一个就是关的;一个都没有就是开的;写了 --enable-dynamic-vram 则无条件是开的。这一步就能给出确定答案。
第二步,日志只能当旁证。 comfy/model_management.py(v0.31.0)在启动时会打印这么几行:
Total VRAM {:0.0f} MB, total RAM {:0.0f} MB
Set vram state to: {vram_state.name}
Enabled pinned memory {}
Using async weight offloading with {} streams
Set vram state to: 后面的名字来自源码里的 VRAMState 枚举,取值是 DISABLED、NO_VRAM、LOW_VRAM、NORMAL_VRAM、HIGH_VRAM、SHARED 之一。这些名字和几个开关名字对得上,但源码里的注释只写到「哪个状态大致意味着什么」为止,并没有给出「哪个启动参数一定落到哪个状态」的完整映射,所以它只能提示你「启动参数可能不是你以为的那样,回去核对一遍」,不能直接当作 dynamic VRAM 开关状态的判据。同理,Enabled pinned memory 和 Using async weight offloading with N streams 这两行说明的是 pinned memory 与异步卸载各自的状态——它们是独立的机制,有各自的关闭开关(--disable-pinned-memory、--disable-async-offload),跟 dynamic VRAM 不是一回事,别看到它们出现就认为 dynamic VRAM 一定开着。
四、开着的时候,能调的三个旋钮
确认自己在 dynamic VRAM 这一侧之后,才轮到下面这三个独立参数。它们不在互斥的 VRAM 模式组里,是单独给的。
--vram-headroom GB,默认 0。 help 原意是:让 DynamicVRAM 在默认之上额外保持这么多空闲显存,ComfyUI 会尽量保持这么多显存完全空闲,即使是被其它应用占用的显存也计入。最后那半句是这个参数最容易被误读的地方——它的目标不是「在 ComfyUI 自己的用量之外再留一块」,而是「整张卡上空着的显存要够这个数」。这意味着你后台开着的浏览器硬件加速、另一个推理进程、显示器本身的占用,都会消耗掉这个额度。同一个 --vram-headroom 数值,在干净的专用卡上和在你日常办公的主力卡上,代价完全不同。要不要调它,判断依据就是这一点:如果这台机器上除了 ComfyUI 还有别的东西在吃显存,先想清楚你是不是在为别人的占用买单。
--reserve-vram GB,默认 None。 help 原意是「给操作系统/其它软件保留的显存量,默认会按操作系统保留一定量」。这个「按操作系统保留一定量」在源码里是常量 EXTRA_RESERVED_VRAM:默认 400MB,Windows 上是 600MB,源码注释原文写的是 #Windows is higher because of the shared vram issue,另外在某条件下还会再加 100MB。
关键在于:一旦你指定了 --reserve-vram,源码就直接把这个值换算成 args.reserve_vram * 1024**3——这是覆盖,不是叠加。你写的那个数字会整个顶掉上面那套默认逻辑,包括 Windows 那 200MB 的额外保留。所以 Windows 用户尤其要注意:默认值本来就比 Linux 高,是官方针对 shared vram 有意留的余量,你随手写个 --reserve-vram 0.2 其实是在把它往下压。反过来,如果你的机器上确实有别的程序需要吃显存,往上给也是这个参数的正当用法。至于「压低之后能多跑多大的图」这类量化收益,官方没有给数据,我们也不做估计。
顺带把这两个参数的区别定死:--reserve-vram 改的是保留量的基准值,--vram-headroom 是在默认之上额外要求的空闲量。名字都带 vram、语义都跟「留多少」有关,但不是一个东西,同时给的时候别指望它们能互相抵消。
--disable-nvml-pressure,flag。 help 原意是:DynamicVRAM 的内存压力判断用 CUDA 而不是 NVML。这个参数名的杀伤力在 disable 三个字上——很容易被读成「关掉内存压力控制」。它不是。它关掉的是 NVML 这个数据来源,压力判断本身照做,只是改从 CUDA 侧取数。help 的主语是 DynamicVRAM,所以在 dynamic VRAM 已经关闭的场景下讨论它没有意义。什么时候可能用得上?当你怀疑 NVML 报的数跟实际对不上、或者环境里 NVML 本身有问题的时候,把它当成一个换口径的排查手段试试,而不是当成常驻的性能参数。
五、什么时候该主动关掉
社区里确实有为了绕开具体问题而关掉它的情况,但这些都只是 issue,不是官方结论。
官方仓库 issue #13730 反映了「LTX 2.3 FP8/Q4KM 在 RX 7900 XTX + ROCm 上会停在 Requested to load LTXAV 处,除非把 dynamic VRAM / pinned memory / async offload 关掉」这一现象,创建于 2026-05-06,标签为 Potential Bug,截至 2026-08-09 仍为 open。这里要说清两件事:Potential Bug 的字面含义是「疑似 bug」,不等于官方已确认;issue 处于 open 状态也意味着没有官方修复结论。我们没有读过这条 issue 的正文与评论,因此不复述任何复现步骤或根因。它对你的价值只有一条:如果你正好在 AMD + ROCm 环境上遇到卡在 Requested to load 那一行的现象,「把 dynamic VRAM 关掉试一次」是一个有人提过的方向,值得作为二分排查的一步,仅此而已。
另有一条 issue #14029,创建于 2026-05-21,标签为 Feature,标题是「It is strongly recommended to permanently save --disable-dynamic-vram」——从标题能读出的信息就是「有用户希望把这个开关持久化保存」,除此之外的内容我们同样没有读过,不做延伸。
所以决策路径可以简化成这样:默认就用开着的状态跑,不需要为它做任何配置;遇到具体的卡死或加载异常时,把 --disable-dynamic-vram 当成一个排查用的对照组加上去跑一次,看现象是否消失,而不是一上来就把它写进常驻启动脚本。同理,如果你正打算加 --highvram,先意识到你顺手做了两件事,而不是一件。
如果要写一条用于排查的临时命令,按上面的参数语义组合大致是这样:
python main.py --disable-dynamic-vram --disable-pinned-memory --disable-async-offload
以上为按官方参数语义组合的示例,未逐项实测,以官方文档与 python main.py --help 的实际输出为准。三个开关一起关是为了对齐前面那条 issue 描述的组合;如果现象消失了,再逐个加回来定位到底是哪一个,别停在「关了就好」这一步。
延伸阅读
- ComfyUI 的五个注意力实现参数怎么选,以及 xformers 在里面扮演什么角色
- ComfyUI 五种缓存模式该选哪个:从
--cache-ram的默认阈值倒推启动参数 - ComfyUI 报 CUDA OOM 时的排查顺序
本文依据 ComfyUI 官方仓库(github.com/Comfy-Org/ComfyUI)的 README、comfy/cli_args.py、
release notes 与官方安全公告整理,核对日 2026-08-09,对应版本 v0.31.0;
文中引用的 issue 状态为该日期的快照。本文内容为官方文档与源码口径,非本机实测。
参数、默认值与功能随版本变动,请以官方文档与 python main.py --help 的实际输出为准。