ComfyUI 有 CPU 模式,随便一台 VPS 都能把它跑起来。但真拿它出图就知道,CPU 模式下跑一张 1024×1024 的图要十几分钟,等一张图的时间够你泡杯茶再回来。想拿到能用的速度,机器上必须得有 NVIDIA 显卡。
所以这篇讲的"VPS",实际是带 GPU 的云主机。装驱动、跑容器、挂模型、开 HTTPS、批量出图,从头到尾走一遍。
如果卡在"该买哪张卡"这一步,先看 GPU VPS 推荐 2026,那篇讲选型;这篇讲买完之后怎么把它跑起来。
我自己是从本地开始的。笔记本 4060 8GB,跑 SDXL 没问题,一碰 Flux 就 OOM。后来想着干脆租台卡跑,结果发现——如果一周只出几十张图,本地凑合其实更划算。
云上跑图贵。一张 4090 的按量实例,一个月 7×24 开着大概要 3000 元人民币上下(各家差很多)。真正适合上云的是这几种情况:
- 本地显卡显存不够,跑 Flux、SD3.5、视频模型这种吃显存的
- 要挂机跑批量任务,比如几百张图的 LoRA 数据集生成
- 团队共用一套工作流和模型库,不想每人本地存一份
- 临时项目,用完就关,不想为此买卡
反过来说,如果你只是偶尔出几张图玩玩,本地装一个 ComfyUI 就够了,别花这个钱。
| 本地显卡 | GPU 云按量计费 | GPU VPS / 独立 GPU 服务器 | |
|---|---|---|---|
| 计费 | 一次性买卡 | 按秒/小时 | 按月 |
| 关机后 | — | 停止计费(磁盘可能另算) | 照常收费 |
| 显存 | 固定 | 可选 | 固定 |
| 数据 | 本地 | 停机后可能丢,看是否挂云盘 | 一直在 |
| 适合 | 轻度使用 | 批量任务、临时验证 | 常驻服务、长期跑图 |
| 价格量级 | — | 4090 约 ¥2-4/小时 | 4090 约 ¥2000-4000/月 |
关键区别是关机后还算不算钱。按量计费适合"跑完就关",但停机时模型和输出得存到云盘或对象存储,不然实例一释放全没了。包月适合常驻,代价是不跑的时候钱照样在烧。
我一般建议:先按量租几小时验证环境和速度合不合预期,确认要长期用了再转包月。
显存排第一位,其他都往后排。ComfyUI 出图的速度瓶颈是显存带宽,而能不能跑起来取决于显存容量。参考量级:
| 模型 | 文件大小 | 大约吃多少显存 | 什么卡能跑 |
|---|---|---|---|
| SD 1.5 | ~2GB | 4GB | 6GB 卡就够 |
| SDXL | ~6.9GB | 7-8GB | 8GB 勉强,12GB 舒服 |
| Flux.1 dev fp16 | ~23GB | 20GB+ | 24GB(3090 / 4090) |
| Flux.1 dev fp8 | ~12GB | 11GB | 12GB 可以 |
| Flux GGUF Q5_K_S | ~8.5GB | 7.5GB | 8GB 极限、12GB 舒服 |
| Flux GGUF Q4_K_S | ~6.8GB | 6.5GB | 6-8GB 极限 |
硬盘比你想的能吃。 一个 SDXL 主模型 6.9GB,Flux fp16 23GB,再加几个 VAE、ControlNet、放大模型、LoRA 各几百 MB 到几个 GB,100GB 很快就满了。预算允许就上 NVMe,模型加载速度差一倍以上(机械盘加载 23GB 的 Flux 能让你等到怀疑人生)。
内存 32GB 起步。 ComfyUI 会把装不下的权重卸载到内存,内存不够就变成频繁读写 swap,速度直接崩。
下载带宽很重要。 从 Hugging Face 拉模型,国际线路的机器能跑满百兆,国内线路的可能只有几百 KB/s。一个 23GB 的模型,慢的时候能下一天。
拿到机器先确认显卡在不在:
nvidia-smi
能打印出显卡型号、显存、CUDA 版本就行。如果提示 command not found,说明机器没装驱动 —— 大多数 GPU 云主机是预装好的,碰到没预装的先找服务商装驱动,别自己硬来(黑屏一次就知道疼了)。
接下来装容器工具包,让 Docker 能看见显卡:
sudo apt update
sudo apt install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
验证一下:
docker run --rm --gpus all nvidia/cuda:12.8.0-base-ubuntu24.04 nvidia-smi
容器里能打印出同样的显卡信息,环境就算通了。这一步失败后面全是白搭,所以别跳过。
先建目录,模型和输出都挂到宿主机上,容器删了重建数据还在:
mkdir -p ~/comfyui/{models,custom_nodes,input,output,user}
cd ~/comfyui
docker-compose.yml:
services:
comfyui:
image: yanwk/comfyui-boot:cu130-slim-v2
container_name: comfyui
restart: unless-stopped
ports:
- "127.0.0.1:8188:8188"
volumes:
- ./models:/root/ComfyUI/models
- ./custom_nodes:/root/ComfyUI/custom_nodes
- ./input:/root/ComfyUI/input
- ./output:/root/ComfyUI/output
- ./user:/root/ComfyUI/user
environment:
- NVIDIA_VISIBLE_DEVICES=all
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
shm_size: "8gb"
几个点解释一下:
端口写成 127.0.0.1:8188:8188,不是 8188:8188。ComfyUI 没有任何登录功能,谁都能访问就等于把显卡和队列交到别人手上。绑到本地回环,外面通过反代进来,后面会讲。
shm_size: "8gb" 别省。Docker 默认共享内存只有 64MB,加载大模型时 PyTorch 的多进程会直接报错崩掉,这个坑很多人踩过。
镜像 tag 选 CUDA 13.0 的版本。ComfyUI 的性能库现在按 CUDA 13.0 开发,用老 CUDA 镜像会出现装不上加速包的情况。镜像里已经带了 ComfyUI 本体和 ComfyUI-Manager,省了手动装节点管理器。
启动:
docker compose up -d
docker compose logs -f
日志里能看到监听 8188,以及 Total VRAM 那一行 —— 确认数字跟你买的卡对得上。
ComfyUI 的 models 目录分得很细,放错位置会出现"加载器里找不到模型":
| 目录 | 放什么 |
|---|---|
checkpoints/ | 完整大包(SD1.5、SDXL、Flux 一体化文件) |
unet/ | 单独下载的 UNet,GGUF 量化模型也放这 |
clip/ | 文本编码器(Flux 需要 t5xxl + clip_l 两个) |
vae/ | VAE 文件 |
loras/ | LoRA |
controlnet/ | ControlNet 模型 |
embeddings/ | Textual Inversion |
upscale_models/ | ESRGAN 之类的放大模型 |
下载直接扔进去就行,容器不需要重启(ComfyUI 点一下 Refresh 就能扫到新模型)。国内机器拉 Hugging Face 慢的话设个镜像:
export HF_ENDPOINT=https://hf-mirror.com
pip install -U "huggingface_hub[cli]"
hf download black-forest-labs/FLUX.1-schnell \
--include "*.safetensors" \
--local-dir ~/comfyui/models/checkpoints
Civitai 上的模型通常要登录才能下,在网页上拿到直链后用 wget -c 断点续传更稳:
wget -c -O ~/comfyui/models/checkpoints/model.safetensors "复制的直链"
刚开始别贪多。装一个 SDXL 基础模型 + 一两个 LoRA,能出图了再加。我见过有人一口气下了 200GB 模型,结果工作流还没跑通。
ComfyUI 官方到现在都没有内置密码保护(社区一直在提这个需求,核心版本还没有)。想从外面访问,标准做法是反代 + 认证。
用 Caddy 很省事,自动申请证书、自动处理 WebSocket 升级:
comfy.example.com {
encode gzip
basicauth {
admin $2a$14$这里换成你的密码哈希
}
reverse_proxy 127.0.0.1:8188
}
密码哈希这样生成:
caddy hash-password --plaintext '你的密码'
WebSocket 这一环必须对。ComfyUI 的实时进度、预览图都靠 WebSocket 推,代理不支持升级的话,界面能打开但一直卡在"执行中",看不到进度。
如果连公网端口都不太想开,还有两个选择:Cloudflare Tunnel(源站不暴露 IP),或者干脆 SSH 隧道:
ssh -L 8188:127.0.0.1:8188 user@你的服务器
本地浏览器打开 http://127.0.0.1:8188,流量全走 SSH 加密,什么反代认证都不需要。自己一个人用,这个方案最省心。
ComfyUI 的界面在浏览器里跑,但真正好用的是它的 HTTP API。手动点几百次不如写个脚本。
先拿到 API 格式的工作流:在界面右上角菜单里开 Developer Mode Options,然后 Export (API),导出的 JSON 就是能直接提交的格式。
import json, time, uuid, urllib.request
SERVER = "http://127.0.0.1:8188"
CLIENT_ID = str(uuid.uuid4())
with open("workflow_api.json") as f:
wf = json.load(f)
# 改掉节点里的提示词和随机种子
wf["6"]["inputs"]["text"] = "a cat sitting on a server rack, cinematic lighting"
wf["3"]["inputs"]["seed"] = 12345
payload = json.dumps({"prompt": wf, "client_id": CLIENT_ID}).encode()
req = urllib.request.Request(
f"{SERVER}/prompt", data=payload,
headers={"Content-Type": "application/json"},
)
prompt_id = json.loads(urllib.request.urlopen(req).read())["prompt_id"]
while True:
with urllib.request.urlopen(f"{SERVER}/history/{prompt_id}") as r:
history = json.loads(r.read())
if prompt_id in history:
break
time.sleep(1)
for node in history[prompt_id]["outputs"].values():
for img in node.get("images", []):
print(img["filename"], img.get("subfolder", ""))
几个容易踩的点:
节点 ID 是字符串。 /prompt 收到的图里,节点之间的引用必须是 ["4", 1] 这种形式(字符串 ID + 输出序号),写成 [4, 1] 会直接报 invalid node reference。
/history 不返回排队中的任务。 提交后立刻查很可能查不到,这不代表失败,只是还没开始跑。轮询间隔别设太短,100 毫秒一次会把服务端拖住,1 秒起步比较合理。
/history 在 ComfyUI 重启后清空。 批量任务的 prompt_id 自己存一份到文件里,脚本崩了可以接着跑,不然得从头再来。
/prompt 对错误的容忍度很高。 JSON 语法错或者缺字段返回 400,但工作流逻辑有毛病照样返回 200,然后在执行阶段悄悄失败。提交前可以用 /object_info 检查节点是否存在。
一次提交多个任务不用等 —— /prompt 是排队式的,连发十个请求,ComfyUI 会自己排着跑。
OOM(CUDA out of memory)是跑 ComfyUI 最常见的报错。思路是逐级降显存,不是一上来就 --lowvram:
默认 → --normalvram → --lowvram → --novram → --cpu
新版 ComfyUI 默认就有动态显存管理,会把装不下的部分自动丢到内存,很多时候不用手动加参数。真正需要手动干预的是这几种:
- 12GB 跑 SDXL 偶发 OOM:加
--reserve-vram 2,给系统留点余量 - 切换模型时卡住或反复 OOM:加
--cache-none,不缓存节点结果 - 老卡(10 系、20 系)跑 Flux:
--use-split-cross-attention配合--lowvram - 显存碎片化:试试
--disable-dynamic-vram让它按老方式卸载
除了启动参数,换量化模型往往更有效:
| 方案 | 文件大小 | 显存 | 说明 |
|---|---|---|---|
| Flux fp16 | ~23GB | 20GB+ | 质量最好,24GB 卡专属 |
| Flux fp8 | ~12GB | 11GB | 12GB 卡的主流选择 |
| GGUF Q5_K_S | ~8.5GB | 7.5GB | 接近 fp16,速度慢一点 |
| GGUF Q4_K_S | ~6.8GB | 6.5GB | 8GB 卡的极限,细节有损失 |
GGUF 模型需要装 ComfyUI-GGUF 节点,然后用 Unet Loader (GGUF) 加载,模型放 models/unet/ 而不是 checkpoints/。
还有几个不花钱的办法:分辨率从 1024 降到 768,显存能省两三成;batch size 从 4 降到 1;工作流里那些同时加载两个大模型的节点,拆开跑。
GPU 机器贵,几个容易漏钱的点:
按量实例记得关。 跑完批量任务忘了关机,第二天早上看到账单会很清醒。设个定时任务,或者干脆用服务商的自动关机策略。
停机后模型还在不在。 有些按量实例停止后本地盘会保留(继续收存储费),有些释放了数据就没了。23GB 的 Flux 重新下一遍是真的难受,重要模型记得备份到对象存储。
网络流量另算钱。 下载模型、往外传图都可能计费,尤其是按量实例。查清楚流量单价再决定要不要在上面直接下大模型。
别在 GPU 机器上跑无关服务。 见过有人把 GPU 机器当普通 VPS 用,跑网站、跑数据库,等于用买跑车的钱去拉货。
界面能打开但一直不动:八成是 WebSocket 没通。检查反代有没有正确转发升级请求,浏览器控制台会报连接失败。
容器重启后自定义节点没了:custom_nodes 目录没挂载到宿主机。用 ComfyUI-Manager 装的节点都在里面,丢了得重装。
上传图片报 413:反代的请求体大小限制。Caddy 默认没这个问题,Nginx 要改 client_max_body_size。
出图速度比别人测评慢很多:先 nvidia-smi -l 1 看 GPU 利用率。如果利用率长期跑不满,多半是模型在内存和显存之间倒腾,加内存或者换量化模型。如果显卡型号跟测评不一样,那没什么好比的。
容器起来就退出:看 docker compose logs,最常见的是显存被其他进程占了,或者镜像的 CUDA 版本和驱动对不上。
ComfyUI 上云的真正门槛不在安装,Docker 那几十行配置照着抄就行。麻烦的是三件事:显存够不够、模型往哪放、外面怎么安全地访问。这三件事想清楚了,剩下的都是体力活。
如果是第一次弄,建议顺序是:先按量租一小时验证显卡和驱动,再跑通最小工作流出第一张图,然后才是加模型、配 HTTPS、写 API 脚本。一上来就搭全套,出问题的时候根本不知道是哪一层坏了。
延伸阅读:
