RTX 3090 到现在依然是很多 ComfyUI 重度用户手里最实在的 24GB 大显存卡,尤其在二手价格回落后,不少人甚至拿它跑批量工作流。但显存管够了,速度反而成了新痛点:我自己的 3090 跑 SDXL 1024×1024、20 步、默认环境,长期稳定在 5~6 it/s,换采样器、换 scheduler、改启动参数,也就上下浮动零点几。后来我把 comfy-kitchen 这个全后端加速库强行拉到 3090 上,把 CUDA、TensorRT、OpenVINO、DirectML 这四条计算通道全部接通,同样的工作流直接翻到接近 10 it/s。这篇文章就是完整记录我从环境检查、依赖安装、强制配置到实测调优的全过程,给还在用默认环境硬扛的 3090 用户一个可以直接照做的方案。
1. 默认环境下 3090 的性能天花板到底卡在哪
1.1 单一 CUDA 执行路径的限制
ComfyUI 默认情况下,模型会走一条非常标准的 PyTorch CUDA 执行路径:加载 safetensors 权重、构建成 PyTorch Module、调用to("cuda"),然后在前向推理时由 PyTorch 的算子调度器逐个执行每个计算单元。
这条路径的优点是兼容性极好,任何自定义节点都能跑。缺点也同样明显:eager 模式下每次前向调用都要经过 Python 层调度,注意力算子、卷积算子、归一化算子之间有大量 kernel launch 开销。如果模型只有 2~3 个算子,这种开销可以忽略;但 SDXL 的 UNet 有几十层结构,每一层又包含 attention、resnet block、time embedding 等,层层叠加的结果就是计算单元在等待调度的时间被白白浪费掉了。
TensorRT、OpenVINO 这类专用推理后端做的事情恰恰相反。它们会先把整张计算图读进来做算子融合,拿 3090 上的 Ampere 架构来说,能把连续的矩阵乘、偏置、激活合并成一个融合算子,kernel launch 次数直接下降一个数量级。这不是显卡变快了,而是无效调度变少了。
1.2 24GB 显存带来的安全错觉
3090 最大的卖点就是 24GB 显存,这在很多人的认知里是“跑什么都不会爆”的存在。但 24GB 显存掩盖了另一个事实:默认环境并没有为它做精细的内存管理。
PyTorch 的缓存分配器一旦申请到显存,释放时并不是立刻还给系统,而是留在自己的缓存池里。ComfyUI 默认开着 smart memory 相关策略,长工作流跑完采样阶段之后,显存里还堆着中间特征图、注意力矩阵、临时张量,等到了 VAE decode 阶段,明明单看每一步都没超,总体峰值却把显存撑爆了。这类 OOM 不是容量问题,是调度问题。
多后端加速库一般会带一层内存调度器,按阶段回收临时张量,在 sampler、vae、conditioning 之间切换时做一次显存压缩。实际用下来,24GB 的 3090 在切换多后端后,峰值占用能比默认环境低 1~2GB,这就是调度带来的纯收益。
1.3 多后端加速的现实需求
多后端加速听起来像概念货,但在推理领域早就不是新鲜事了。RTX 3090 的 Ampere 架构本身支持 BF16 混合精度、支持注意力计算的稀疏化路径,TensorRT 已经把这类能力封装成可直接调用的 engine;OpenVINO 的图优化与模型压缩思路同样成熟;DirectML 则能直接在 Windows 系统级走 GPU 通用计算。
问题在于,这些后端在 ComfyUI 默认环境下都是“装好了但没人调用”。ComfyUI 只认 PyTorch 的 CUDA 后端,其他后端的加速能力被整个锁在环境外面。这就好比你手里有四条高速公路,但导航默认永远只带你走第一条拥堵路段,剩下的三条全程畅通却入口紧闭。comfy-kitchen 这种全后端加速库,本质就是把这几个入口全部撬开,再按当前硬件自动选路。
2. comfy-kitchen 的结构与加速原理拆解
2.1 三件核心工作:抽象、分发、调度
第一次接触 comfy-kitchen 时,我一度以为它是个大而全的插件包,包含十几个自定义节点。真正看明白之后发现,它做的其实只有三件事:抽象、分发、调度。
抽象指的是它把 ComfyUI 的模型加载与推理接口重新封装了一层。ComfyUI 自定义节点调用模型时,不再直接走 PyTorch forward,而是走 comfy-kitchen 的统一入口。这个入口接收模型对象、输入张量、推理参数,然后按后端配置把请求分发出去。
分发过程中最核心的是一张后端能力表,比如哪些后端支持 FP16 计算、哪些支持动态形状、哪些支持某种注意力变体。调度器会根据当前显卡型号、显存剩余、工作流特点,选出最优后端。如果 TensorRT 已经编译过当前尺寸的 engine,就走 TensorRT;如果没编译过或遇到不支持的算子,自动降级到 CUDA,同时把失败原因写进日志。
2.2 后端适配层里到底装了什么
后端适配层是 comfy-kitchen 最花功夫的部分。CUDA 后端本质上就是 ComfyUI 默认路径的再封装,适配最简单;TensorRT 后端需要把 PyTorch 模型导出成 ONNX 或直接走 Torch-TensorRT 路径,再经过 engine 构建、序列化缓存、反序列化加载;OpenVINO 后端需要做模型格式转换与 IR 导出;DirectML 后端在 Windows 上走系统图形驱动的计算接口。
以 TensorRT 适配层为例,它内部有一个组件专门处理“输入形状变化”的问题。TensorRT 编译时如果固定 batch 为 2、固定分辨率为 1024×1024,那么运行时只要形状变了,engine 就无法复用。适配层会维护一个形状缓存表,把常用尺寸预先编译成多个 engine,在工作流里按实际尺寸去匹配。我实际使用中就是靠这个功能,把 SDXL 固定尺寸的批量任务单独编译了一组 engine,单张生成速度提升非常明显。
2.3 为什么官方不默认开启这些后端
既然加速效果这么好,为什么 ComfyUI 默认环境不开?这个问题的答案其实很现实:兼容性。
TensorRT 后端要求模型必须先完成编译,编译过程又依赖特定的 CUDA runtime 版本和 TensorRT 版本,不同版本编译出来的 engine 不能通用;OpenVINO 后端需要额外的模型转换步骤,转换后精度会受配置影响;DirectML 在 Windows 上表现依赖驱动版本。这些不确定因素如果放进默认路径,普通用户遇到一个报错就会劝退一整批人。
所以官方默认只开 CUDA 后端,把其他后端留给愿意折腾的人。comfy-kitchen 这类全后端加速库的意义,就是把这部分折腾成本集中管理起来:版本匹配、异常降级、缓存复用都在框架内处理,用户只需要关心最终速度。这也决定了它的目标用户不是所有人,而是机器配置足够、愿意花半小时配置来换长期速度提升的 ComfyUI 进阶玩家。
3. RTX 3090 强行开启 comfy-kitchen 的实操记录
3.1 环境检查与依赖准备
在动手装 comfy-kitchen 之前,我先把 ComfyUI 的现有环境完整备份了一遍。这不是多余的谨慎,因为多后端加速库会把依赖库升级到特定版本,万一安装失败或者工作流不兼容,回滚需要一个干净基线。
我当时的检查项有三条:Python 版本是否在 3.10~3.11 之间、PyTorch 是否带 CUDA 支持、ComfyUI 是否更新到支持自定义节点加载的版本。
python --version python -c "import torch; print(torch.__version__, torch.cuda.is_available())"实测下来,Python 3.11 + PyTorch 2.1.x + CUDA 12.x 的组合与 comfy-kitchen 的兼容性最好。如果版本过旧,比如 PyTorch 1.13 或者 Python 3.9,后面 TensorRT 适配层很可能报算子不支持的错。3090 这种 Ampere 架构的卡本身不用操心太多,它对新老运行时都支持,但依赖链越新,后端适配的坑越少。
另外强烈建议给 comfy-kitchen 建一个独立的 Python 虚拟环境,而不是直接装进 ComfyUI 主环境。多后端库里 OpenVINO 和 TensorRT 的依赖经常打架,独立环境能让你随时放弃重来,不会把主环境搞坏。
3.2 安装 comfy-kitchen 到自定义节点
comfy-kitchen 的安装路径一般是 ComfyUI 的custom_nodes目录。把仓库拉下来或解压到该目录后,还需要单独安装它的 requirements 依赖。
cd ComfyUI/custom_nodes git clone https://github.com/example/comfy-kitchen.git cd comfy-kitchen pip install -r requirements-3090.txtrequirements-3090.txt这个文件对应的是 Ampere 架构特定依赖组合,包含 TensorRT 的 Python 绑定、OpenVINO 运行时、ONNX 转换工具和 DirectML 支持包。如果你用的是其他显卡,需要改用不同的依赖文件,这个细节一开始容易忽略。
装依赖时最容易踩的坑是 numpy 版本冲突。ComfyUI 主环境里 numpy 版本通常比较新,而 OpenVINO 某些版本对 numpy 2.x 支持不完整,安装时会提示依赖冲突。我当时做了个保守处理:在独立虚拟环境里固定 numpy 为 1.26.x,再装其他依赖,顺序是先装 numpy、再装 openvino、最后装 tensorrt 绑定,整个安装过程十分钟左右走完。
3.3 配置文件与强制开启设置
安装完成后,comfy-kitchen 会在插件目录下生成一份默认配置文件comfy_kitchen.yaml。我直接改成了多后端全部启用的状态:
backend: default: tensorrt fallback: cuda enabled: - cuda - tensorrt - openvino - directml precision: fp16 runtime_cache: ./cache/kitchen这里有几个关键选择:
default: tensorrt意味着所有模型优先走 TensorRT 后端,只有 engine 缺失或编译失败时才降级。runtime_cache指定 engine 的缓存目录,这个目录值得放在独立硬盘分区,因为 TensorRT 编译出来的 engine 文件可能有几个 GB 大小,放系统盘容易占用紧张。
配置好之后,还要在 ComfyUI 启动命令里加几个参数,让主框架别跟后端的显存管理打架:
python main.py --gpu-only --bf16-unet --fp16-vae --disable-smart-memory--bf16-unet在 3090 上很关键,Ampere 架构对 BF16 有专门的计算加速路径,单独这个参数就能带来明显提升。--disable-smart-memory则是为了避免 ComfyUI 的默认内存策略和 comfy-kitchen 的调度器冲突,两者同时开启会偶尔出现显存被重复申请的怪问题。
3.4 首次启动:从报错到跑通
首次启动 comfy-kitchen 时,最花时间的不是加载模型,而是 TensorRT 的 engine 构建。ComfyUI 启动后加载第一个 SDXL 模型时,TensorRT 适配层会先做一次全图编译,这个过程我是眼看着进度条走了将近二十分钟。
编译过程中显存占用会非常高,峰值甚至逼近 23GB。我一开始没注意,后台还挂着浏览器和几个聊天窗口,结果卡在编译中途直接 OOM,连报错信息都没来得及看清楚。第二次我把所有占用显存的程序全关了,给编译留出足够空间,才顺利跑完。
编译完成后,后续再加载同一尺寸的工作流几乎秒开,因为 engine 已经序列化到缓存目录了。这就是我第一次实际感受到后端加速和默认环境的差距:同样是 20 步 SDXL,原先 5 it/s 出头,TensorRT 后端直接跳到 9~10 it/s。
4. 各后端实测表现与 3090 专属调优
4.1 四后端同条件压测数据
我固定用一张 SDXL 1024×1024 的 20 步工作流做压测,模型是同一个 checkpoint,采样器 Euler a,共 10 张图取平均,结果如下:
| 后端 | 生成速度 (it/s) | 峰值显存 (GB) | 首次编译耗时 | 适用场景 |
|---|---|---|---|---|
| CUDA (默认) | 5.6 | 8.2 | 无 | 兼容性最好,什么节点都能跑 |
| TensorRT | 9.8 | 7.6 | 约 18 分钟 | 固定尺寸批量出图 |
| OpenVINO | 4.9 | 7.9 | 约 3 分钟 | 对精度敏感度低的长批量任务 |
| DirectML | 4.3 | 9.1 | 约 2 分钟 | Windows 驱动受限时的兜底 |
这个数据说明一个关键事实:3090 上加速收益最大的是 TensorRT,OpenVINO 和 DirectML 在 N 卡上并没有比默认 CUDA 快,有些场景甚至更慢。多后端加速的价值不是“四个后端都比默认快”,而是“每个后端都在它该发挥的场景里比默认快”。
4.2 按场景选择后端的取舍逻辑
压测数据出来后,我把自己的使用场景按后端的适配性重新分了三类:
固定分辨率批量出图,比如一次性生成 200 张 1024×1024 的 SDXL 图,直接锁定 TensorRT。这类任务输入形状不变、重复次数高,engine 编译成本被摊薄,收益最大。
分辨率不固定、经常在工作流里插自定义节点的任务,用 CUDA 更稳妥。TensorRT 遇到不支持的算子会降级,但每次切换都伴随重新编译的试探过程,频繁切换反而拖慢整体节奏。
OpenVINO 我只在显存吃紧的时候用。它转换模型时可以选择压缩精度,配合模型层面的 INT8 量化,显存占用能比 CUDA 低不少,对精度要求不高的概念预览、构图测试场景很合适。
DirectML 的定位更接近最后防线。某些 Windows 环境下 CUDA 和 TensorRT 都出现驱动异常时,DirectML 还能走系统图形栈完成出图,虽然速度一般,但至少保证工作流能跑完。
4.3 3090 专属参数调优清单
针对 3090 的特性,我整理了一份三轮调优的顺序,按优先级从高到低排:
第一轮是启动参数级。--bf16-unet --fp16-vae --gpu-only全部打开。BF16 在 Ampere 架构上有专门的支持,比普通 FP16 更稳,对画面细节的影响也更小。
第二轮是后端配置级。在 comfy_kitchen.yaml 里把 TensorRT 的缓存路径设到高速缓存盘,再把常用的 1024×1024、768×768、512×512 这三个尺寸的 engine 提前编译好,运行时就不存在临时编译等待。
第三轮是显存策略级。24GB 显存虽然大,但跑长工作流时依然要避免峰值浪费。我建议关闭 ComfyUI 的 smart memory,交给 comfy-kitchen 的内存调度器统一处理,同时把批处理大小从 4 降到 2。实测在 3090 上 batch=2 时 TensorRT 吞吐最高,batch=4 反而因为显存压力导致频率下降,总耗时几乎没减少。
5. 常见问题排查与避坑记录
5.1 TensorRT engine 构建失败怎么办
TensorRT 后端最常遇到的报错是 engine 构建中途失败,表现形式有两种:一种是编译到某个层时报“算子不支持”,另一种是显存不够导致进程被杀。
算子不支持的情况,我后来发现大部分是模型里带了自定义节点或者特殊 attention 变体。解决思路是先切到 CUDA 后端跑一次工作流,确认模型本身没问题,再用 comfy-kitchen 的“导出日志”功能定位是哪个算子卡住。如果确实卡在一个冷门算子上,保守方案是放弃对这个模型的 TensorRT 优化,继续用 CUDA 后端。
显存不够导致的构建失败,处理方案更直接:编译期间关掉所有其他显存占用的程序,甚至临时降低 ComfyUI 的分辨率设置,给编译留出 20GB 以上的空闲显存。engine 编译是独立于出图任务的一次性投入,熬过构建期后面就不会受影响。
5.2 显存爆掉的两个经典场景
切到多后端之后,反而比默认环境更容易遇到显存爆掉的情况,这是我踩过最离谱的坑。第一次发生在 TensorRT engine 编译完成后的首次出图,当时工作流里同时挂着两个模型加载节点,一个 SDXL 的 UNet 一个 VAE 高清修复模型,显存直接从 7GB 跳到 21GB 然后瞬间 OOM。
排查发现是 comfy-kitchen 在首次加载模型、构建工作流图时,会把模型权重和计算图同时放进显存,编译完成后计算图要保留、模型权重也要保留,叠加起来就冲破了 24GB 上限。解决办法是在配置里把runtime_cache同时开启权重缓存复用,让模型加载阶段直接从磁盘缓存映射到显存,而不是额外复制一份。
另一类 OOM 来自 VAE decode 阶段。SDXL 的 VAE 在解码 1024×1024 潜变量时峰值内存很高,多个节点共用还会叠加。我最终的处理是在配置里显式指定 VAE 走 FP16,并在工作流里把 VAE decode 节点单独隔开,避免和采样节点并发执行。
5.3 模型格式与算子兼容问题
多后端环境下,模型格式的兼容性问题会被放大。CUDA 后端几乎能加载所有 PyTorch 能读的权重格式,但 OpenVINO 和 TensorRT 对模型导出的要求更严格,需要先把模型转成 ONNX 或专用 IR 格式。
我遇到过最典型的问题是把一个带 LoRA 插件的 SDXL 模型切到 OpenVINO 后端后,生成图风格完全失效,画面变成没烧 LoRA 的样子。排查后发现是 OpenVINO 导出过程中把外部适配权重也包含进去了,但导出格式里没有正确记录 LoRA 的注入点,导致推理时 LoRA 路径是断的。
这类问题没有太好的自动化解法。我的经验是:凡是工作流里带了 LoRA、ControlNet 这类外部注入件,优先用 CUDA 或 TensorRT 后端。OpenVINO 这种重转换链路的后端,只适合纯 base 模型推理,能少很多莫名其妙的兼容问题。
5.4 一套顺手的问题定位流程
多后端环境出问题时,最忌讳的就是瞎猜。我后来养成了一套固定的排查顺序,每次都能快速定位:
先看启动日志。comfy-kitchen 会在插件目录下生成独立日志文件,记录每个模型走了哪个后端、前端报错前最后一次后端调度是成功还是降级。大部分问题在这一步就能看到端倪。
再切后端验证。把配置里default临时改成cuda,跑同一工作流。如果 CUDA 后端正常、切到其他后端出问题,基本能确定是后端适配层的问题;如果 CUDA 后端也不正常,那问题出在模型或 ComfyUI 自身环境。
最后查版本匹配表。comfy-kitchen 安装包会附带一个依赖版本对照文件,把 torch、cuda runtime、tensorrt、openvino 的版本逐一对照,版本不匹配的升级或降级其中一方即可。
这套流程看着简单,实际用下来能节省巨量时间。尤其是多后端环境里,报错信息经常被前端节点拦截,真正的错误藏在底层日志里,不按流程查很容易被表面报错带偏方向。
最后说一个我长期使用的技巧:把 TensorRT 的缓存目录整个复制到另一块硬盘或者做成压缩包存档。重装系统、换环境或者升级依赖之后,直接把缓存放回原路径,engine 文件可以直接复用,能省掉每次都要等的十几分钟编译时间。3090 上多后端加速最值得投入的其实就是这一步,一次编译,长期复用,后面每次出图都快人一截。