一块 GPU,零 API 账单:ComfyUI 现在能跑本地大语言模型,不再报显存溢出错误
动态显存和交接节点,让一块 24GB 的卡同时跑大语言模型和扩散模型,不花一分 API 费用

长期以来,在同一块 GPU 上既跑一个本地大语言模型、又跑一整套图像生成流水线,一直是个让人抓狂的事。把 Flux 或 SDXL 加载进显存,再启动 Ollama 来生成提示词,结果可以预见:显存溢出崩溃。标准的建议很直白:再买一块 GPU,或者花钱用 API。这笔账,现在变了。
ComfyUI 在 2026 年 3 月的发布版本里,悄悄默认启用了Dynamic VRAM——一个自定义的内存分配器,让 GPU 能在不同工作负载之间协作共享自己的物理显存。配合一整套成熟的、由社区构建的显存交接节点,从业者现在可以在单块消费级显卡上,跑完整套本地 AI 流水线——用大语言模型生成提示词,再用扩散模型生成图像——不花一分钱推理 API 的费用。
为什么一块 GPU 以前永远不够用
这种冲突发生在硬件层面。一块 24GB 的 GPU 看起来空间充裕,直到两个「竞争者」同时出现:一个 4 位量化的 70 亿参数大语言模型,大约占用 4 到 5GB 显存;一个 fp8 精度的 Flux Dev 模型,再占用 10 到 16GB。当两个模型都常驻显存时,它们没法共存在同一块卡上,而标准的 GPU 显存管理,也没有提供一种优雅的方式来在它们之间仲裁。结果就是反复出现的显存溢出崩溃,逼得用户在大语言模型和扩散模型步骤之间重启 ComfyUI,或者干脆用两台机器。
动态显存如何解决分配问题
这个架构层面的修复,出现在 2026 年 3 月初,当时Comfy.org把动态显存设为了默认的内存模式。这套系统引入了一个名为aimdo(AI 模型动态卸载器)的组件,用一套为生成式工作负载量身定制的按需分页模型,取代了 PyTorch 标准的显存分配器。
每个被加载的模型,都会拿到一个VBAR (Virtual Base Address Register):一段 GPU 虚拟地址空间的预留,在加载时不占用任何物理显存。一个 VBAR 内部的模型权重,一开始是未分配状态;只有当某一层真正需要它们时,才会通过一次执行时的fault()调用,把它们提升到物理显存里。如果显存还有空间,这一层就会保持常驻,让后续运行也能受益。如果分配器承受压力,它就会驱逐优先级较低的权重腾出空间,用的是一套水位线系统,其中最近活跃的模型拥有最高的内存保留优先级,是最后才会被释放物理页面的那个。GPU 永远不会因为显存溢出而崩溃;相反,它会临时拷贝一层所需的权重,执行完运算,再释放或复用这份拷贝。
这对「大语言模型加扩散模型」工作流的实际效果是:当大语言模型在占用 GPU 时,ComfyUI 的扩散模型可以在名义上继续保持「已加载」状态,因为扩散模型的权重,在虚拟空间里本来就是未提交的。操作系统把模型文件做内存映射,但不把它读进内存,使用的是一种由磁盘支撑的内存,只在真正需要时才被回收,并在需要时透明地从存储设备重新加载。
Comfy.org 发布的基准测试Comfy.org显示,在新系统下,RTX 5060 和 RTX Blackwell 6000 Pro 上的生成性能都有所提升,不过这些数字是公司自报的,尚未经过独立复现。目前动态显存只支持 Windows 和 Linux 上的英伟达 GPU;对 AMD GPU 的支持,被列为路线图上的一项计划,WSL 也暂不支持。
让这一切变得实用的交接节点生态
动态显存处理的是被动共存,但主动交接——在一个应用启动之前,明确释放另一个应用的显存——能带来更干净、更可靠的结果。围绕这个具体用例,一整套社区生态的专用节点已经发展起来。
Setmaster 的 comfyui-llamacpp代表的是架构上最完整的方案:它让大语言模型运行在一个独立的llama-server进程里,而不是在 ComfyUI 自己的 Python 运行时内部,这让它具备确定性的生命周期控制。这种双向交接两个方向都支持——一个可选的unload_comfy_models_before_start开关,能在大语言模型分配 GPU 显存之前,驱逐 ComfyUI 托管的模型;而一个与之配对的Release llama.cpp VRAM节点,会在图像生成开始时停止这个服务器进程。这套节点包支持跨 CUDA、Vulkan、ROCm 和 Metal 后端的 GGUF 模型,视觉模型则通过匹配的 mmproj 投影器来处理。如果生成仍在进行,这次释放会被推迟,等所有租约到期之后才真正释放内存,避免出现那种会引发级联显存溢出错误的「半释放」状态。
对那些运行外部 Ollama 或 vLLM 服务器的用户来说,zyd232 的 LLM Unload 节点会向正在运行的服务器发送一个明确的卸载信号,并阻塞等待,直到模型真正从内存中消失——而不只是等到 HTTP 请求返回为止。ComfyUI-llamacpp-Unloader对独立运行的 llama.cpp 服务器,采用了类似的方法,它调用/models端点来识别已加载的模型,并对每一个都发出有针对性的卸载调用。
对那些更看重简单性、而不是精细控制的工作流来说,SeanScripts/ComfyUI-Unload-Model提供了直通式的「Unload Model」和「Unload All Models」节点,可以放进计算图里的任何位置,在一个自然的交接点上释放显存——比如在一个 CLIP 编码器步骤之后、主扩散采样器之前。
对那些偏好容器化方案的用户,llmc把 llama.cpp、ComfyUI 和 Open WebUI 封装在一个反向代理后面,把兼容 OpenAI 格式的请求路由给大语言模型,把图像请求路由给 ComfyUI,并自动强制实现 GPU 的互斥使用——同一时间只有一个服务在运行,通过一条 CLI 命令切换模式。
单 GPU 工作流现在是什么样子
这套此前在消费级硬件上不可能实现的实用流水线,如今已经有了详尽的文档:一个 ComfyUI 工作流,通过一个 llama.cpp 节点加载一个 GGUF 量化的大语言模型,从一段简单描述或一张输入图片生成一段详细的文生图提示词,然后执行一次交接——卸载这个大语言模型,并可选地触发 ComfyUI 的内部缓存清理——之后,扩散采样器再加载 Flux 或 SDXL,生成最终图像。
一个像 Qwen2.5-7B 这样 4 位量化的 70 亿参数模型(大约占用 4 到 5GB 显存),可以生成一段提示词、卸载,再交接给一个 fp8 精度的 Flux Dev 模型(大约 10 到 16GB),全程在单块 RTX 3090 或 RTX 4090 上完成,不会崩溃。延迟上的代价是真实存在的——每次运行时模型的重新加载都要花上几秒钟——但它彻底消除了按词元反复计费的成本,并让所有数据都留在本地。
局限性,以及尚未解决的问题
几项限制依然存在。动态显存的显存占用模式发生了变化:因为权重是按需被提升到物理内存的,而且可能在多次运行之间保持常驻,表面上看到的显存占用,可能会比以前的行为更高,这有时会让那些不了解新分配器语义、只是在监控 GPU 显存的用户感到担忧。
节点摆放错误,也是一种持续存在的失效模式。如果在一个工作流里,把一个大语言模型卸载节点放在了大语言模型步骤的上游,就会导致这个模型在还没执行完之前就被驱逐——这是一种接线错误,这些节点在设计上无法阻止。正在学习「大语言模型加 ComfyUI」这种模式的用户,需要理解交接节点是输出,不是输入:它们是在大语言模型步骤完成之后才触发的,不是之前。
AMD GPU 用户目前仍然享受不到动态显存带来的好处。对于显式的交接工作流,这套社区节点生态可以独立于动态显存运作,但 aimdo 提供的被动共存层,在进一步的硬件支持上线之前,仅支持英伟达。
更宏观的问题是,这种顺序式的 GPU 分时复用——不管实现得多好——是不是正确的长期架构,还是说,专门打造的统一流水线(在共享内存上联合设计、同时处理文本和图像生成的模型)终将让这种交接方案变得过时。眼下,这套交接生态,用现有的硬件交出了实用的结果,而这一点,对那些把单块消费级显卡当作自己全部生产基础设施的独立创作者或小型工作室来说,意义重大。