ComfyUI 改一次提示词就重载一次模型:缓存模式与局部重执行的排查路径

2026-08-09

改一个形容词,点 Ctrl + Enter,然后眼睁睁看着终端又滚出一遍 Requested to load ...,等模型重新灌进显存。这个体感很差,尤其是在调提示词的时候——调词本来是要快速迭代的,结果每次迭代都被加载环节吃掉。

这篇不打算给你一个”加这个参数就好了”的答案,因为在官方口径里它压根就不是一个已确认的 bug。官方仓库 issue #14618 反映了「改动 prompt 后每次都重新加载模型」这一现象,该 issue 创建于 2026-06-24,标签为 Potential Bug,截至 2026-08-09 仍为 open,评论数 118,是当前评论数最高的开放 issue。这里要说清两件事:Potential Bug 的字面含义是「疑似 bug」,不是官方已确认;issue 处于 open 状态,也就没有官方给出的修复方案。我们只取到了这条 issue 的编号、标题、日期、标签和状态,没有读过它的正文与任何一条评论,所以下面不会出现”issue 里说要怎么怎么改”这种话。

能给的是另一样东西:一条基于 comfy/cli_args.py(v0.31.0,核对日 2026-08-09)与 README 原文的判定路径,让你先分清自己遇到的到底是缓存策略问题,还是图确实变了、按设计就该重跑。

一、先确认重载是真的在发生

别凭感觉。ComfyUI 的启动与运行日志里有几行是可以直接对照的:

日志文案含义
Total VRAM {:0.0f} MB, total RAM {:0.0f} MB启动时报告的显存与内存总量
Set vram state to: {名字}当前 VRAM 状态机取值
Requested to load {模型类名}开始加载某个模型
{N} models unloaded.卸载了 N 个模型

做三个动作:

动作一,数 Requested to load 的出现次数。 只改提示词里的一个词,重新排队,看这一行是不是又打了一遍,以及前面有没有配套的 {N} models unloaded.。如果两行成对出现,那就是真的在卸载再加载,不是错觉;如果日志里根本没有新的 Requested to load,那你的慢是慢在别处(采样本身、VAE、磁盘写出),跟这篇没关系。

动作二,提交两次完全相同的图。 README 的「Notes」章节写得很直白:只有相对上一次执行发生变化的部分会被执行,提交两次相同的图,只有第一次会真正执行。所以第二次排队应该几乎立刻完成。如果连”一个字都没改”的第二次也重新加载模型,那说明”图变了才重跑”这条规则在你这台机器上没有兑现,值得往缓存策略上查;如果第二次是秒回的,那说明执行层的判定是正常的,问题出在”你改的那一处到底触发了多少下游”。

动作三,去掉所有启动参数,用裸的 python main.py 起一次做基线。 很多人的启动脚本是从两年前的教程抄来的,里面塞了一堆当年有用、现在语义已变的开关。基线跑一次,比对现象是否还在,能省掉后面一大半猜测。

二、五种缓存模式,先搞清楚默认值是什么

comfy/cli_args.py(v0.31.0)里缓存是一个互斥组,一共五个选项:

参数help 原意
--cache-ram [GB [GB]]RAM 压力缓存,这是默认缓存模式。第一个值设 active-cache 阈值,可选的第二个值设 inactive-cache/pin 阈值
--cache-classic使用旧式(aggressive)缓存
--cache-lru NLRU 缓存,最多缓存 N 个节点结果。可能占用更多 RAM/VRAM
--cache-none降低 RAM/VRAM 占用,代价是每次运行都重新执行每个节点
--high-ram在高内存机器、或偏好用页面文件而非重新加载模型的系统上可略微提升性能

默认阈值是按系统 RAM 的百分比算出来的,这一点比参数名本身更值得记:不给值时,active 为系统 RAM 的 10%(最小 2GB、最大 10GB),inactive 为系统 RAM 的 100%(最大 128GB)。也就是说,一台 32GB 内存的机器,active-cache 默认大约在 3GB 出头;而 active 阈值封顶 10GB,内存再大也不会自动往上涨。你机器上的缓存行为,是被这两个数字框住的,不是无限的。

源码里还有两条硬逻辑,容易踩:

  • --cache-ram 最多接受两个值,多给会直接报错 --cache-ram accepts at most two values: active GB and inactive GB
  • --high-ram 会把 cache_classic 置真,也就是加了 --high-ram 就隐含切到了旧式缓存。这条从参数名上完全看不出来,属于典型的反直觉设计。

另外要把两层东西分开:--cache-* 这一组在 help 里描述的对象是「节点结果」,而模型权重留不留在显存/内存,走的是另一套机制(VRAM 状态机、smart memory、pinned memory、async offload)。两套会互相影响,但它们不是同一个开关,排查时别混着调。

三、处置:按官方参数语义能做的三件事

第一件,别上 --cache-none 它的 help 原文就写着代价是「每次运行都重新执行每个节点」——这恰恰是你现在抱怨的现象的加强版。它的用途是压 RAM/VRAM 占用,不是提速。有些人看到”缓存有问题”就顺手把缓存关了,方向是反的。顺带一提,官方仓库 issue #9250 反映了「希望增加 --no-cache-models 启动开关」这一诉求,该 issue 创建于 2025-08-08,标签为 Feature 与 bug-cop:triaged,截至 2026-08-09 仍为 open。需要提醒的是:一条 feature request 还开着,并不能直接推出「官方还没做」;判断某个开关到底存不存在,要以 v0.31.0 的 comfy/cli_args.pypython main.py --help 的实际输出为准——本文核对的 v0.31.0 参数表里没有它,所以别照着 issue 标题往启动脚本里抄。

第二件,内存够的话,显式把 --cache-ram 的阈值提上去。 默认 active 封顶 10GB,如果你的机器远不止这点内存,显式给值是有意义的:

python main.py --cache-ram 8 64

第一个值 8 是 active-cache 阈值(GB),第二个值 64 是 inactive-cache/pin 阈值(GB)。这两个值请按自己机器的实际内存来定,别照抄——它们是内存预算,不是魔法数字。以上为按官方参数语义组合的示例,未逐项实测,以官方文档与 python main.py --help 的实际输出为准。

第三件,--cache-lru N 可以试,但要知道代价。 它的 help 明确写了「可能占用更多 RAM/VRAM」。在一张显存本来就紧张的卡上,为了少重载而多缓存节点结果,很可能换来 OOM。适合的场景是内存与显存都有富余、且工作流节点数不多、你反复只调末端某几个节点的情况。

还有一个顺手要查的:你的启动命令里有没有 --highvram--gpu-only--novram--cpu。源码里 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 关掉,退回基于估算的模型加载。不少人为了”多占点显存提速”加了 --highvram,结果连带改变了加载路径。同理,--disable-smart-memory 的 help 是「强制积极地卸载到常规内存,而不是能留在显存时就留着」——它会让卸载更频繁,如果你的目标是少重载,它是反向的;日志里出现 Disabling smart memory management 就是它生效了。

四、改完怎么验证

按这个顺序看,别一次改三个参数:

  1. 重启后先看 Total VRAM {} MB, total RAM {} MB 那一行,确认 ComfyUI 读到的 RAM 总量和你以为的一致——默认缓存阈值是按这个数字算百分比的。
  2. Set vram state to: 打出来的是哪个状态(源码枚举是 DISABLED / NO_VRAM / LOW_VRAM / NORMAL_VRAM / HIGH_VRAM / SHARED),确认你的参数改动有没有把它挪到你没预期的档位。
  3. 重复第一节的动作二:提交两次完全相同的图,第二次应当几乎立刻结束。
  4. 再重复动作一:只改提示词末端的一个词排一次队,数 Requested to load 有没有减少一次。
  5. 想看更细的过程,用 --verbose 提高日志等级(合法等级是 DEBUG / DETAIL / INFO / WARNING / ERROR / CRITICAL,不带值时等价于 DEBUG,控制台默认 INFO)。

第 3、4 步都过了,才算改对了。只有”感觉快了一点”不算。

五、什么情况说明不是缓存策略的问题

这一节比前面几节更重要,因为最容易出现的浪费是:明明图真的变了,却在缓存参数上来回折腾一晚上。

你改的不是末端。 README 的规则是:只有相对上次执行发生变化的部分,以及依赖它的部分会重新执行。如果你动的是 checkpoint 加载、LoRA、模型精度类参数这些位于图上游的东西,下游全部要重跑、模型要重新加载,这是设计使然,不是缺陷。判断方法很简单:把改动限制在最末端的一两个节点,再看现象是否消失。

提示词里有动态提示语法。 README 明写 {day|night} 这类通配语法是「由前端在每次排队提交时」随机替换的。也就是说,只要你的 CLIPTextEncode 里存在 {wild|card|test} 这样的写法,每次排队送到后端的提示词就真的不一样,图当然每次都变。同理,seed 变了、或者你按过 Ctrl + B bypass 掉某个节点——README 对 bypass 给的解释是「行为等同于该节点被移除、连线从中穿过重连」,那图的结构就是真的变了。顺带说一句,Ctrl + M 是静音,和 bypass 是两个快捷键,README 只解释了 bypass 的语义,没给静音的,所以别把两者当同一回事去反推执行结果。这类”输入或结构真的变了”的情况下,每次重跑是正确行为。

日志里出现内存泄漏告警。 源码里有两条:Potential memory leak detected with model {类名}, doing a full garbage collect, ... 以及更严重的 WARNING, memory leak with model {类名}. Please make sure it is not being referenced from somewhere.。官方文案给的方向是「避免循环引用 / 检查谁还在引用它」,这几乎总是指向某个自定义节点抓着模型不放。这时候该做的是拿 --disable-all-custom-nodes 起一次做二分,再用 --whitelist-custom-nodes 逐个放回来定位,而不是调缓存。

日志里出现的是 OOM。 显存本来就装不下这套模型的话,卸载与重载是资源不够的结果而不是原因,此时把缓存开大只会更糟。

只在某几个第三方节点参与的工作流里出现。 那更像是那个节点自身的行为,跟核心的缓存策略是两回事。

最后提醒一句:ComfyUI 的迭代节奏很快(README 里写的是主仓库中的前端每两周更新一次,独立的前端仓库还有每日发布),参数默认值与加载路径这几个版本一直在改(v0.23.0 引入多线程从磁盘加载与 offload 到磁盘,v0.30.0 改用 pinning 基础设施以 MRU 策略把权重加载到进程 RAM,v0.31.0 在 2026-08-08 修了 Linux 无 swap 分区时 pin 太多内存的问题)。所以任何”某某参数能治这个”的结论都请带上版本号看,包括这篇。

延伸阅读


本文依据 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?报名体系课或加入会员,照着学、照着用。