ComfyUI 模型加载慢:能调的几个开关

2026-08-09

现象长什么样

一个视频或大模型工作流,点了运行之后进度条一直不动,控制台停在 Requested to load <模型类名> 这一行,风扇不转、GPU 占用也没上去,过好几十秒甚至更久才开始出采样进度。换个 prompt 再跑一遍,同样的等待又来一次。

这类「慢」和「跑不动」是两码事。跑不动通常伴随报错或 OOM,而这里是没有任何报错、只是慢。ComfyUI 在 2026 年这几个版本里对加载路径做了不小的改造,能调的开关不少,但相当一部分开关的语义反直觉——有的只在特定磁盘上才划算,有的名字看着像一对、实际管的是两种完全不同的文件格式。

下面的参数与源码结论都以 ComfyUI v0.31.0(2026-08-08)的 comfy/cli_args.pycomfy/model_management.py 为准。ComfyUI 大约每两周发一个 major stable 版本,参数、默认值都会变,隔几个版本回头看这篇要重新对一遍 --help

第一步:先确认瓶颈真的在加载

不要凭感觉。先看这几处,都是源码里实打实会打印的东西。

看启动日志的这几行。 ComfyUI 启动与运行时会打印下面这些格式串,它们都是源码里写死的文案:

日志文案说明
Total VRAM {:0.0f} MB, total RAM {:0.0f} MB显存与内存总量
Set vram state to: {vram_state.name}当前 VRAM 状态机取值
Enabled pinned memory {}(单位 MB)pinned memory 已启用及其上限
Using async weight offloading with {} streams异步权重卸载已启用及流数
Requested to load {模型类名}开始加载某个模型
{N} models unloaded.卸载了 N 个模型

判定动作很简单:如果卡顿发生在 Requested to load 打印之后、采样进度出现之前,那它就在加载路径上,本文这些开关才有讨论价值;如果 Requested to load 打完很快就进采样,只是采样本身慢,那改加载开关一个字都不会帮到你。

把日志级别拉高。--verbose DEBUG 启动,或者用 --verbose DEBUG comfy.log 把详细日志同时写到文件里,方便回看时间线。合法等级是 DEBUGDETAILINFOWARNINGERRORCRITICAL,控制台默认 INFO--verbose 可以重复使用来增加输出目标;给了非法组合它会报 expects no values, a console LEVEL, or LEVEL FILE。顺带一提,DETAIL 这一级是 v0.30.0(2026-08-03)的「可配置 DETAIL 日志侧通道」(PR #15064)带来的,属于较新的等级。

跑一次裸启动做对照。 把自己攒的一长串参数全去掉,只用 python main.py 起一次,再跑同一个工作流。很多「加载慢」是自己加的参数造成的,而不是 ComfyUI 的默认行为。如果怀疑是自定义节点在作怪,用 --disable-all-custom-nodes 做一次二分;需要保留个别节点时配 --whitelist-custom-nodes

确认版本号。 加载路径上有三个关键版本节点,低于它们的话,先升级比调参数有用得多。

第二步:这几个开关分别管什么

版本本身就是最大的那个开关

v0.23.0(2026-06-01)的 release notes 里写了「多线程从磁盘加载模型:大幅加速加载时间,并支持 offload 到磁盘」(PR #13802,对应 CORE-43、CORE-152、CORE-164、CORE-165、CORE-117)。这条是整个加载路径改造的起点:多线程读盘,以及「offload 到磁盘」这条去路,都是从这个版本开始有的。

v0.30.0(2026-08-03)又加了一层:用 pinning 基础设施、以 MRU 策略把权重加载到进程 RAM(PR #15027)。这条 release note 就这么一句,具体怎么选留怎么淘汰没有公开细节,别顺着字面往下编。但有一点是明确的:它建在 pinned memory 之上,也就是说下一节要讲的 --disable-pinned-memory 关掉的是这套机制的地基,不是一个孤立的小开关。

v0.31.0(2026-08-08)修的是这套机制在特定环境下的副作用:「Linux 无 swap 分区时不再 pin 太多内存」(PR #15266)。也就是说,无 swap 的 Linux 机器如果停在 v0.30.x,pin 的量可能超出机器能承受的范围——这是官方在 v0.31.0 才处理的,不是你配置错了。

release notes 只写了「改了这个」,没写实现细节,所以别指望这里能给出更深的机制解释。但版本判断是明确的:还在 v0.23.0 以前的版本上抱怨加载慢,先升级。

pinned memory:上限是死在源码里的常量

comfy/model_management.pyMAX_PINNED_MEMORY 初始为 -1(小于等于 0 视为不启用),随后按平台赋值:

  • Windowsram * 0.40,源码注释原文写的是 # Windows limit is apparently 50%
  • 其它系统max(ram * 0.40, min(ram * 0.90, ram - 4 * 1024**3, ram + get_disk_swap_total() - 16 * 1024**3))

非 Windows 那条公式把 swap 总量也算进来了,并且留了 4GB 和 16GB 两道余量。源码里还有 Could not get amount of swap memory on system.Could not read Windows swap usage; falling back to RAM-pressure pin eviction: %s 两条告警——说明「拿不到 swap 信息」是官方预期内的情况,会退回按 RAM 压力做 pin 淘汰。看到这两条不用慌,但要知道此时的行为和正常路径不一样。

想关掉它就是 --disable-pinned-memory。什么时候该关?当日志里 Enabled pinned memory 报出来的数字大到你觉得机器整体开始换页的时候。Windows 用户尤其注意,0.40 这个系数是按机器的 RAM 总量算的:32GB 内存的机器,按公式算出来的上限就是 12.8GB。这个数字本身不代表一定会被用满,但它决定了上限落在哪里。

--fast-disk:前提写在 help 里,别忽略

--fast-disk 的 help 原意是:相比未 pin 的 RAM,优先用磁盘做动态加载与卸载,对拥有快速 NVME 磁盘的用户可能更快

注意这句话里的两个限定词。一是「可能」,二是「快速 NVME」。它和 v0.23.0 的「offload 到磁盘」是配套的:本质上是把 RAM 不够用时的去处从「未 pin 的内存」换成「盘」。如果你的模型和临时目录落在机械盘或者慢速 SATA 盘上,这个交换是亏的。这就是它反直觉的地方——名字叫 fast,但它只在你的盘确实快的时候才 fast。

--mmap-torch-files--disable-mmap 不是一对

这两个参数名长得像互斥开关,实际上管的是两种不同的文件格式,方向也相反

参数help 原意
--mmap-torch-files加载 ckpt/pt 文件时 mmap
--disable-mmap加载 safetensors 时不用 mmap

也就是说,safetensors 走 mmap 是默认行为,--disable-mmap 是关掉它;而 ckpt/pt 默认不走 mmap,--mmap-torch-files 是开启它。如果你的模型全是 safetensors,--mmap-torch-files 加了等于没加;反过来,一堆老的 .ckpt / .pt 权重才是 --mmap-torch-files 的目标。

至于什么时候该关 safetensors 的 mmap,help 没给判断标准,这里也不替它下结论——只提醒一点:当模型放在网络文件系统或者某些虚拟磁盘上时,mmap 的行为和本地盘不一样,这是通用的操作系统常识,不是 ComfyUI 官方文档里的内容。

缓存组:默认已经是 RAM 压力缓存

缓存参数是一个互斥组,默认模式就是 --cache-ram(RAM 压力缓存)。不给值时的默认是:active 为系统 RAM 的 10%(最小 2GB、最大 10GB),inactive 为系统 RAM 的 100%(最大 128GB)。第一个值设 active-cache 阈值,可选的第二个值设 inactive-cache/pin 阈值;给超过两个值时源码会直接 parser.error("--cache-ram accepts at most two values: active GB and inactive GB")

组里其它几个:--cache-classic 是旧式(aggressive)缓存;--cache-lru N 最多缓存 N 个节点结果,help 注明可能占用更多 RAM/VRAM--cache-none 降低 RAM/VRAM 占用,代价是每次运行都重新执行每个节点——如果你在排查「为什么每次都重来」,先确认自己没手滑加了这个。

还有个容易漏的连带效果:--high-ram 在源码里会把 cache_classic 置真,也就是说加了 --high-ram 等于隐含开了旧式缓存。它的 help 说的是「在高内存机器、或偏好用页面文件而非重新加载模型的系统上可略微提升性能」,注意是「略微」。

顺手提两个别乱加的开关

--lowvram 的 help 原文是「如果启用了 dynamic vram,这个选项不做任何事」。而源码里的判定函数是:

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

什么都不加时 dynamic VRAM 是开的,于是 --lowvram 在默认配置下就是个空操作。老教程里「显存小就加 --lowvram」这句话在当前版本已经不成立。

反过来,--highvram--gpu-only--novram--cpu 这四个会连带关掉 dynamic VRAM,退回基于估算的模型加载。为了「多占显存提速」而加 --highvram 的人,实际上把 v0.30.0 那套 pinning + MRU 的收益也一起让掉了一部分。这个连带效果 help 里没写,只能从上面那个函数读出来。

另外 --enable-asset-hashing 的 help 明确说了会增加启动开销以及大模型目录上的单次输出开销,默认关闭。如果你为了资产去重开过它,而抱怨的是启动慢而非单次加载慢,先把它关了再说。

一条组合示例

python main.py --fast-disk --mmap-torch-files --verbose DEBUG comfy.log

Windows portable 包在 <你的 ComfyUI 目录> 下改启动的 bat 文件,参数写法一样。以上为按官方参数语义组合的示例,未逐项实测,以官方文档与 python main.py --help 的实际输出为准。真要调,一次只加一个参数,别一口气把上面全堆上——堆上去之后你分不清是哪个起的作用。

第三步:改完怎么验证

  1. 对日志行。 改了 --disable-pinned-memory 就去看 Enabled pinned memory 这行是不是消失了;改了 --async-offload 的流数就去看 Using async weight offloading with {N} streams 里的 N 变没变。开关有没有真的生效,日志比感觉可靠。顺带一提,--async-offload 的 help 写明在 NVIDIA 上默认启用,不带参数时是 2 个流,所以 N 卡用户看到这行是正常的,不是你加的。
  2. Set vram state to: 这一行。 加了 --highvram 之类的参数后,这行的取值会变(源码枚举里是 DISABLED / NO_VRAM / LOW_VRAM / NORMAL_VRAM / HIGH_VRAM / SHARED)。确认自己以为的模式和实际状态一致。
  3. 跑两次同一个图对照。 README 的执行规则写得很清楚:只有相对上次执行发生变化的部分会被执行;提交两次完全相同的图,只有第一次会真正执行。所以第二次跑同一个图应该是几乎瞬间完成的。如果第二次仍然重新加载模型,那问题不在你调的这些参数上,往下看。
  4. {N} models unloaded. 如果每次执行前都在刷这行,说明模型在被反复卸载,缓存和显存策略需要重新审视。

第四步:什么情况说明不是这个原因

这一节比上面都重要,因为加载参数是最容易让人一条道走到黑的地方。

如果每改一次 prompt 就完整重载一遍模型,那不是本文这些开关能解的。官方仓库 issue #14618 反映了「改动 prompt 后每次都重新加载模型」这一现象,该 issue 创建于 2026-06-24,标签为 Potential Bug,截至 2026-08-09 仍为 open。注意 Potential Bug 的字面含义是「疑似 bug」,不是官方已确认的结论;这条 issue 目前也没有被标记为已修复。遇到这个现象,先按上面第三步的第 3 条自测一遍「提交两次相同的图」,把「参数确实变了导致重跑」和「什么都没变也重载」区分开。

如果只有首次运行慢、后续都正常,那很可能属于冷启动范畴而不是配置问题。官方仓库 issue #1992 反映了「加速首次运行」这一诉求,该 issue 创建于 2023-11-17,标签为 User Support,截至 2026-08-09 仍为 open。这条从 2023 年挂到现在都还开着。我们没有读过它的正文与评论,所以只把它当成「首次运行慢是个被长期讨论的话题」的一个佐证,而不是某个版本回归的证据。判定动作也简单:起服务后先跑一次小图把模型加载进来,再跑正式的图,如果第二次就顺了,那就别再折腾加载参数了。

如果日志里出现内存泄漏提示,方向完全不同。源码里的文案是 Potential memory leak detected with model {类名}, doing a full garbage collect, for maximum performance avoid circular references in the model code.,更严重时是 WARNING, memory leak with model {类名}. Please make sure it is not being referenced from somewhere.。官方文案给的方向是「避免循环引用 / 检查谁还在引用它」,这几乎总是指向自定义节点持有了模型引用。这时候该做的是用 --disable-all-custom-nodes 二分,而不是继续加 --fast-disk

如果加了 --fast-disk 之后反而更慢,说明你的磁盘不满足 help 里那个「快速 NVME」的前提,直接去掉即可。这个参数没有中间档位可调。

如果是彻底卡死而不是慢,比如停在 Requested to load 再也不动、最后以 OOM 收场,那属于另一类问题,加载速度的开关帮不上忙,应该往显存与 dynamic VRAM 那条线去查。

最后提一句版本纪律:ComfyUI 的 stable release tag 之外的 commit,README 自己写了「可能非常不稳定,会弄坏很多自定义节点」。为了追一个加载优化去跟 master,通常不划算。

延伸阅读


本文依据 ComfyUI 官方仓库(github.com/Comfy-Org/ComfyUI)的 README、comfy/cli_args.py、 release notes 与官方安全公告整理,核对日 2026-08-09,对应版本 v0.31.0; 文中引用的 issue 状态为该日期的快照。本文内容为官方文档与源码口径,非本机实测。 参数、默认值与功能随版本变动,请以官方文档与 python main.py --help 的实际输出为准。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。