ComfyUI 模型加载慢:能调的几个开关
现象长什么样
一个视频或大模型工作流,点了运行之后进度条一直不动,控制台停在 Requested to load <模型类名> 这一行,风扇不转、GPU 占用也没上去,过好几十秒甚至更久才开始出采样进度。换个 prompt 再跑一遍,同样的等待又来一次。
这类「慢」和「跑不动」是两码事。跑不动通常伴随报错或 OOM,而这里是没有任何报错、只是慢。ComfyUI 在 2026 年这几个版本里对加载路径做了不小的改造,能调的开关不少,但相当一部分开关的语义反直觉——有的只在特定磁盘上才划算,有的名字看着像一对、实际管的是两种完全不同的文件格式。
下面的参数与源码结论都以 ComfyUI v0.31.0(2026-08-08)的 comfy/cli_args.py 和 comfy/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 把详细日志同时写到文件里,方便回看时间线。合法等级是 DEBUG、DETAIL、INFO、WARNING、ERROR、CRITICAL,控制台默认 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.py 里 MAX_PINNED_MEMORY 初始为 -1(小于等于 0 视为不启用),随后按平台赋值:
- Windows:
ram * 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 的实际输出为准。真要调,一次只加一个参数,别一口气把上面全堆上——堆上去之后你分不清是哪个起的作用。
第三步:改完怎么验证
- 对日志行。 改了
--disable-pinned-memory就去看Enabled pinned memory这行是不是消失了;改了--async-offload的流数就去看Using async weight offloading with {N} streams里的 N 变没变。开关有没有真的生效,日志比感觉可靠。顺带一提,--async-offload的 help 写明在 NVIDIA 上默认启用,不带参数时是 2 个流,所以 N 卡用户看到这行是正常的,不是你加的。 - 对
Set vram state to:这一行。 加了--highvram之类的参数后,这行的取值会变(源码枚举里是DISABLED/NO_VRAM/LOW_VRAM/NORMAL_VRAM/HIGH_VRAM/SHARED)。确认自己以为的模式和实际状态一致。 - 跑两次同一个图对照。 README 的执行规则写得很清楚:只有相对上次执行发生变化的部分会被执行;提交两次完全相同的图,只有第一次会真正执行。所以第二次跑同一个图应该是几乎瞬间完成的。如果第二次仍然重新加载模型,那问题不在你调的这些参数上,往下看。
- 看
{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 的五个注意力实现参数怎么选,以及 xformers 在里面扮演什么角色
- ComfyUI 报 CUDA OOM 时的排查顺序
- ComfyUI 在无 swap 分区的 Linux 上 pin 太多内存:v0.31.0 之前怎么判定与规避
本文依据 ComfyUI 官方仓库(github.com/Comfy-Org/ComfyUI)的 README、comfy/cli_args.py、
release notes 与官方安全公告整理,核对日 2026-08-09,对应版本 v0.31.0;
文中引用的 issue 状态为该日期的快照。本文内容为官方文档与源码口径,非本机实测。
参数、默认值与功能随版本变动,请以官方文档与 python main.py --help 的实际输出为准。