ComfyUI 多卡机器上的设备参数:`--cuda-device` 与 `--default-device` 到底差在哪
买第二张卡的人,装完驱动第一件事都是问同一个问题:ComfyUI 怎么让它用 1 号卡,而不是死盯着 0 号?
这个问题在 ComfyUI 里其实只对应四个命令行参数,数量少得有点出乎意料。但其中两个参数长得很像、名字都带 device,语义却是相反的方向——而这个差别只写在 help 文本的半句话里,不看源码基本不会注意到。本文只讲这四个参数,依据是 ComfyUI v0.31.0(2026-08-08)时点 comfy/cli_args.py 里的 help 原文。参数会随版本变动,请以你本机 python main.py --help 的实际输出为准。
一、核心差别:一个让别的卡消失,一个只是换个默认
先把两条 help 原意摆出来,这是全文的地基:
| 参数 | 取值 | help 原意 |
|---|---|---|
--cuda-device DEVICE_ID | 逗号分隔,如 0 或 0,1 | 指定使用的设备,其它设备将不可见 |
--default-device DEFAULT_DEVICE_ID | int,单个 id | 设置默认设备 id,其它设备仍然可见 |
差别就在最后那半句。--cuda-device 是做「隔离」:没被点名的卡,对这个 ComfyUI 进程来说等于不存在。--default-device 是做「排序」:它只改变默认落到哪张卡上,其余的卡仍然在进程视野里。
这条差别反直觉的地方在于命名。按字面直觉,--cuda-device 1 像是「用 1 号卡」,--default-device 1 像是「默认用 1 号卡,必要时还能用别的」——但只有后半句是 help 明说的,前半句里「其它设备不可见」这个副作用,字面上完全看不出来。它带来的实际后果是:一旦你用了 --cuda-device,任何试图访问未点名设备的代码路径都不再有机会拿到那张卡。这既是它的价值(干净、彻底、适合多实例分卡),也是它的代价(想在同一个进程里灵活调度多张卡时,你自己把门关上了)。
另一处容易写错的细节:--cuda-device 的 help 明确写了逗号分隔,示例是 0 或 0,1;--default-device 在源码里是 int 类型,只接受单个 id。所以 --default-device 0,1 这种写法不是「效果差一点」,而是类型就不对。写多卡启动脚本时,逗号只属于 --cuda-device。
二、非 NVIDIA 的两个入口
comfy/cli_args.py 的设备选择这一组里,除了上面两个,另有两个是给非 CUDA 路线准备的(同组还有 --cuda-malloc / --disable-cuda-malloc,那是分配器开关,和「用哪张卡」不是一回事,本文不展开):
--oneapi-device-selector SELECTOR_STRING:设置本实例使用的 oneAPI 设备。注意它接受的是一个 selector 字符串,不是设备序号。--directml [DEVICE]:使用 torch-directml,不带参数时值为-1。
这两个参数 help 给出的信息就这么多。selector 字符串的具体语法、DirectML 下设备编号与物理卡的对应关系,cli_args.py 里都没写——那属于 oneAPI 与 torch-directml 各自的文档范畴,本文不替它们推断。
三、命令怎么写:一卡一实例是最省心的形态
多卡机器上最常见、也最容易验收的用法,是每张卡起一个独立的 ComfyUI 进程,各自占一个端口。Linux / macOS 下这样写:
# 0 号卡,8188 端口
python main.py --cuda-device 0 --port 8188 \
--base-directory /srv/comfy/gpu0 \
--output-directory /srv/comfy/gpu0/output
# 1 号卡,8189 端口
python main.py --cuda-device 1 --port 8189 \
--base-directory /srv/comfy/gpu1 \
--output-directory /srv/comfy/gpu1/output
Windows 下同样两条,只是路径与换行符不同:
python main.py --cuda-device 0 --port 8188 --base-directory D:\comfy\gpu0
python main.py --cuda-device 1 --port 8189 --base-directory D:\comfy\gpu1
逐个说明每个选项为什么在这里:
--cuda-device:按 help 里「其它设备将不可见」这条语义把两个进程分开,未被点名的卡不会出现在该进程的视野里。--port:cli_args.py里端口默认是8188,两个实例不改端口必然撞车。--base-directory:help 的说明是一次性设置 models、custom_nodes、input、output、temp、user 六类目录的基准目录。两个实例共用一套 user 目录容易互相覆盖设置,分开更干净。--output-directory:这个参数的 help 里写明 Overrides--base-directory。也就是说上面第一条命令里两者同时给,最终产出目录以--output-directory为准。--temp-directory、--input-directory、--user-directory、--models-directory都是同一个「单项覆盖一把抓」的关系。如果你只是想让两个实例共享同一份模型库、只分开输出,那就是给一个共同的--models-directory、再各给各的--output-directory。
以上为按官方参数语义组合的示例,未逐项实测,以官方文档与 --help 输出为准。
四、产出物长什么样
这套命令跑起来之后,你能看到的「产出物」有两类,都不需要等到出图。
第一类是目录:两个实例各自有一套 gpu0 / gpu1 的六类目录,出图落点在各自的 --output-directory 下(因为它覆盖基准目录)。至于会生成哪些子目录名、里面的文件怎么命名,cli_args.py 没写,本文也不替它编——按上面的参数起一次,看目录自己长成什么样,比读任何文章都准。这里唯一要核的是:两个实例的输出路径确实不同,没有一个悄悄写到了另一个的目录里。
第二类是启动日志。ComfyUI 源码里有这么两行日志格式串,是我们有依据可以拿来对照的:
| 日志文案(格式串) | 含义 |
|---|---|
Total VRAM {:0.0f} MB, total RAM {:0.0f} MB | 启动时报告显存与内存总量 |
Set vram state to: {vram_state.name} | 当前 VRAM 状态机取值 |
五、怎么验收:三步,都在启动阶段
- 看
Total VRAM那一行。 两张卡显存规格不一样时,这行报出来的总量本身就是身份标识——它报的容量对不上你点名的那张卡,说明参数没生效或者 id 指错了。 - 两张卡型号、显存完全相同时,这一行分辨不出来。 别在日志里硬看,去系统侧的显卡监控里确认哪张卡上挂着这个进程更可靠。这不是 ComfyUI 的功能,只是绕开歧义的常规做法。
- 顺带扫一眼
Set vram state to:那行,确认状态机取值符合预期。这一行反映的是显存策略,和设备选择是两码事,但它在同一屏日志里,一起看不费事;两个实例这一行不一致时,说明你给它们的显存类参数不同,而不是设备选错了。
顺序上有个前置条件:端口那一关得先过。第二个实例如果漏了 --port,它和第一个抢的是同一个默认端口,进程都没起来,谈设备验收没有意义。
最容易出错的一步是把 id 认错。 设备 id 由驱动与运行时决定,未必等于你插槽的物理顺序,也未必和某个监控工具里的编号一致。先确认编号,再写参数,比反复改命令快。其次就是第一节说过的那个类型陷阱:逗号只属于 --cuda-device。
六、官方没给的部分:多卡并行推理
必须把话说明白:comfy/cli_args.py 的这四个参数,解决的都是「这个进程用哪张(哪些)卡」,而不是「一次生成如何拆到多张卡上并行跑」。后者涉及的策略——模型分片、文本编码器与 UNet 分卡放置、跨卡张量搬运——在这张参数表里没有对应的开关,help 文本里也没有任何说明。所以本文不猜,也建议你不要拿 --cuda-device 0,1 去反推「传两个 id 就等于两卡并行」:help 只写了「其它设备不可见」,写了什么就是什么。
跨厂商多卡这条路上,官方仓库 issue #4170 反映了「Cross-Vendor Multi-GPU Support via Vulkan Backend」这一诉求,该 issue 创建于 2024-08-02,标签为 User Support,截至 2026-08-09 仍为 open。这里只陈述编号、标题、创建日期与状态——我们没有读过这条 issue 的正文与评论,不清楚里面讨论了什么、有没有替代做法,也不打算据此判断官方的规划。issue 处于 open,既不代表功能不存在,也不代表官方已经确认要做。
七、什么情况别这么干
- 想让单次生成变快,多卡帮不上忙。 上面那套一卡一实例,提升的是同时能跑几条队列,不是单条队列的速度。如果你的诉求是单张图/单段视频更快出来,设备参数这一层给不了答案。
- 显存不够想靠第二张卡凑。
--cuda-device、--default-device都没有「把一个模型摊到两张卡上」的语义。显存吃紧属于另一套参数(缓存与 VRAM 策略那一组)的范畴,别在设备参数里找解法。 - 两个实例共享一套 user 目录。 尤其在 Windows 上手动开两个窗口时最容易忘。共用会不会出问题,官方文档没有明说,但把它们分开的成本几乎为零,没必要赌。
- 自动化脚本里省掉 id 确认。 设备编号在换卡、换驱动、加装第三张卡之后都可能变。写进 systemd / 计划任务的启动命令,重装驱动后应当重新核一遍启动日志,而不是默认它还对。
- 非 NVIDIA 设备照抄
--cuda-device。 DirectML 走--directml,oneAPI 走--oneapi-device-selector,取值形态各不相同,不能互相套用。
多卡这件事,ComfyUI 给的抓手确实朴素:隔离用 --cuda-device,换默认用 --default-device,其余靠端口和目录参数把实例分干净。搞清楚「不可见」和「仍可见」这半句差别,多卡机器上八成的困惑就散了。
延伸阅读
本文依据 ComfyUI 官方仓库(github.com/Comfy-Org/ComfyUI)的 README、comfy/cli_args.py、
release notes 与官方安全公告整理,核对日 2026-08-09,对应版本 v0.31.0;
文中引用的 issue 状态为该日期的快照。本文内容为官方文档与源码口径,非本机实测。
参数、默认值与功能随版本变动,请以官方文档与 python main.py --help 的实际输出为准。