- ComfyUI là editor node-based mạnh nhất hiện nay cho Stable Diffusion, FLUX, SDXL, Wan.
- Self-host trên VPS có GPU (NVIDIA tối thiểu 12 GB VRAM cho SDXL, 24 GB cho FLUX dev).
- Workflow JSON tái sử dụng được, export ra API call gen ảnh hàng loạt cho marketing, e-commerce.
- Tích hợp LoRA, ControlNet, IPAdapter để khoá style brand, không cần Midjourney mỗi tháng.
- Cost rẻ hơn SaaS khi đạt 1k+ ảnh/tháng, đặc biệt khi đã có sẵn VPS GPU cho mục đích khác.
E-commerce store 200 SKU mỗi tháng cần lifestyle photo cho banner Facebook, ảnh detail trang web, mockup TikTok. Thuê studio: 80k/ảnh, 1k ảnh là 80 triệu. Mua Midjourney 30 USD/tháng cũng OK nhưng không kiểm soát style, không lưu LoRA brand, không workflow lặp được. Câu trả lời cho team có technical capability: self-host ComfyUI trên VPS GPU, gen theo workflow JSON cố định, mỗi ảnh chỉ tốn vài cent điện.
Bài này hướng dẫn từng bước: chọn GPU phù hợp, cài ComfyUI, tải model SDXL/FLUX, build workflow text-to-image cơ bản, mở rộng với LoRA và ControlNet, export workflow ra API để app khác gọi gen tự động. Phù hợp marketer, founder e-commerce, designer freelancer.
Vì sao ComfyUI thay vì Automatic1111?
- Node-based: rõ ràng dòng dữ liệu, debug từng node, reuse subgraph.
- Hỗ trợ FLUX, SD3, Wan video, các model mới nhanh nhất.
- Workflow JSON portable, gửi cho người khác chỉ cần import file.
- Built-in API server, gen ảnh hàng loạt qua HTTP, không cần plugin thêm.
- Memory management tốt hơn A1111, chạy được model lớn trên VRAM hạn chế.
- Cộng đồng custom node phong phú: ControlNet, IPAdapter, AnimateDiff, video upscale.
Chọn cấu hình GPU phù hợp
| Model | VRAM tối thiểu | VRAM khuyên dùng | Use case |
|---|---|---|---|
| SD 1.5 | 4 GB | 8 GB | Sample task, học workflow |
| SDXL base + refiner | 10 GB | 16 GB | Production marketing, e-commerce |
| FLUX.1 schnell | 16 GB | 24 GB | Tốc độ + chất lượng cân bằng |
| FLUX.1 dev (full) | 24 GB | 32 GB | Chất lượng cao nhất hiện tại |
| Wan 2.2 video | 32 GB | 48 GB+ | Video ngắn 5-10s |
VPS GPU cho gen ảnh ổn định: NVIDIA RTX 4090 (24 GB), L40S (48 GB), A100 (40-80 GB). Với e-commerce, RTX 4090 là sweet spot: gen 1 ảnh SDXL 1024 mất 4-6 giây, đủ throughput 600 ảnh/giờ. Khi cần FLUX dev quality cao, cần L40S hoặc A100.
Nếu chưa muốn đầu tư VPS GPU full-time, có thể dùng VPS CPU thường để chạy frontend ComfyUI, nối qua VPN tới GPU server (Runpod, Vast.ai, Tensordock spot). Setup phức tạp hơn nhưng giảm cost khi workload thấp.
Cài driver và CUDA
# Ubuntu 22 LTS
sudo apt update
sudo apt install -y build-essential git python3.11 python3.11-venv python3.11-dev
# NVIDIA driver
sudo apt install -y nvidia-driver-550 nvidia-utils-550
sudo reboot
# Verify
nvidia-smi
# CUDA 12.4 (ComfyUI hợp PyTorch 2.4+ với CUDA 12.4)
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb
sudo apt update
sudo apt install -y cuda-toolkit-12-4
Một số provider VPS GPU đã có pre-installed driver + CUDA, kiểm tra trước, đỡ mất nửa ngày setup.
Cài ComfyUI
# Tạo user comfy
sudo useradd -m comfy
sudo su - comfy
# Clone repo
git clone https://github.com/comfyanonymous/ComfyUI.git
cd ComfyUI
# Venv + dependencies
python3.11 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install torch==2.4.1 torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
pip install -r requirements.txt
# Test chạy
python main.py --listen 127.0.0.1 --port 8188
Mở browser ssh tunnel: ssh -L 8188:127.0.0.1:8188 [email protected] rồi vào http://localhost:8188 sẽ thấy ComfyUI canvas. Khi muốn truy cập production, đặt Caddy/Nginx trước port 8188 với basic auth + Cloudflare WAF.
Tải model vào đúng folder
cd ~/ComfyUI/models
# SDXL base
cd checkpoints
wget https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/main/sd_xl_base_1.0.safetensors
# SDXL refiner
wget https://huggingface.co/stabilityai/stable-diffusion-xl-refiner-1.0/resolve/main/sd_xl_refiner_1.0.safetensors
# VAE
cd ../vae
wget https://huggingface.co/stabilityai/sdxl-vae/resolve/main/sdxl_vae.safetensors
# Realistic Vision LoRA mẫu
cd ../loras
# wget
FLUX.1 dev license gating: cần đăng nhập HuggingFace, accept license, dùng huggingface-cli login + access token mới download được. SDXL thì download free.
Workflow cơ bản: Text to Image SDXL
Mở ComfyUI canvas, drag các node sau và nối lại:
- Load Checkpoint -> chọn sd_xl_base_1.0.safetensors
- CLIPTextEncode (Positive Prompt) -> "photo of premium leather backpack, urban background, golden hour"
- CLIPTextEncode (Negative Prompt) -> "blurry, low quality, watermark, text, logo"
- EmptyLatentImage -> width 1024, height 1024, batch 4
- KSampler -> seed random, steps 30, cfg 7.5, sampler dpmpp_2m_sde, scheduler karras
- VAEDecode
- SaveImage
Bấm "Queue Prompt", chờ 20-30 giây cho batch 4 ảnh. Lưu workflow vào file workflows/sdxl-basic.json. Lần sau load lại, đổi prompt là gen tiếp.
Mở rộng với LoRA brand
Train LoRA cho brand mất 30-60 phút trên 4090 với 30 ảnh sản phẩm. Sau khi có file brand-balo.safetensors đặt vào models/loras/, thêm node LoraLoader vào sau Load Checkpoint với strength 0.7-0.9. Prompt thêm trigger word "brnd" (token bạn đặt khi train). Ảnh ra sẽ giữ đặc trưng brand: phối màu, texture, kiểu dáng đặc trưng.
Khi cần style mới cho campaign khác, load LoRA khác, không động đến model base. 1 con VPS GPU có thể chứa hàng trăm LoRA, mỗi cái 100-300 MB.
ControlNet để giữ pose, depth, edge
E-commerce: bạn có ảnh balo gốc trên nền trắng, muốn gen lifestyle scene mà balo giữ nguyên hình dạng, position. ControlNet canny edge giải quyết:
- Load Image -> ảnh gốc balo
- Canny -> tạo edge map
- ControlNetLoader -> control_sd_xl_canny
- ControlNetApply -> conditioning + edge map -> conditioning mới
- Nối conditioning mới vào KSampler thay vì conditioning gốc
Strength ControlNet 0.6-0.8 là tốt nhất. Cao quá ảnh cứng, thấp quá mất edge gốc. Tương tự có ControlNet depth (giữ chiều sâu), openpose (giữ pose người), tile (upscale chi tiết).
Export workflow sang API call
ComfyUI có endpoint POST /prompt nhận workflow JSON format API. Cách export: trong UI ComfyUI, mở Settings, bật "Enable Dev mode Options". Sau đó nút "Save (API Format)" xuất hiện. Lưu file workflow_api.json.
Code Python gọi gen ảnh:
import json
import requests
import uuid
import websocket
SERVER = "127.0.0.1:8188"
CLIENT_ID = str(uuid.uuid4())
def queue_prompt(workflow):
p = {"prompt": workflow, "client_id": CLIENT_ID}
r = requests.post(f"http://{SERVER}/prompt", json=p)
return r.json()["prompt_id"]
def wait_image(prompt_id):
ws = websocket.WebSocket()
ws.connect(f"ws://{SERVER}/ws?clientId={CLIENT_ID}")
while True:
msg = ws.recv()
if isinstance(msg, str):
d = json.loads(msg)
if d["type"] == "executing" and d["data"].get("node") is None
and d["data"]["prompt_id"] == prompt_id:
break
hist = requests.get(f"http://{SERVER}/history/{prompt_id}").json()
images = []
for node_id, node_out in hist[prompt_id]["outputs"].items():
if "images" in node_out:
for img in node_out["images"]:
url = f"http://{SERVER}/view?filename={img['filename']}&type=output"
images.append(url)
return images
# Load workflow template
wf = json.load(open("workflow_api.json"))
# Override prompt
wf["6"]["inputs"]["text"] = "photo of red sneakers in studio, soft light"
wf["3"]["inputs"]["seed"] = 42
pid = queue_prompt(wf)
urls = wait_image(pid)
for u in urls:
print(u)
Số "6" và "3" là ID node trong workflow_api.json. Mở file json để biết ID nào tương ứng node nào. Khi tự động hoá, viết wrapper class lưu mapping node_id -> field name cho dễ maintain.
Tích hợp queue cho gen hàng loạt
Một workflow phổ biến cho team marketing:
- Spreadsheet Google Sheet có cột SKU, product_name, prompt_template, brand_lora.
- n8n hoặc cronjob đọc sheet mỗi giờ, gen list job.
- Push job vào Redis queue.
- Python worker pull job, gọi ComfyUI API gen 4 variations.
- Upload kết quả lên R2/S3.
- Ghi URL trở lại sheet.
- PM duyệt, chọn ảnh đẹp nhất, publish lên Shopify/WooCommerce.
Throughput 1 RTX 4090: ~600-900 ảnh SDXL 1024 trong 1 giờ. Đủ cho store 100-500 SKU mỗi tháng với 4 variations mỗi SKU.
Cost so sánh self-host vs SaaS
| Phương án | Cost ban đầu | Cost/ảnh | Throughput | Brand control |
|---|---|---|---|---|
| Midjourney Pro | 30 USD/tháng | ~0.03 USD | 500-1000 ảnh/tháng cap | Thấp |
| Stable Diffusion API SaaS | 0 | ~0.01-0.02 USD | Unlimited (pay-per-use) | Trung bình |
| VPS GPU RTX 4090 self-host | 15-30M VND/tháng thuê | ~0.002 USD (chỉ điện) | 15-20k ảnh/tháng | Cao (LoRA + ControlNet riêng) |
| VPS GPU shared time | 1-5 USD/giờ on-demand | ~0.005 USD | Theo nhu cầu | Cao |
Self-host lợi nhất khi đạt 5k+ ảnh mỗi tháng và cần brand control chặt. Dưới mức đó, SaaS vẫn tiện hơn. Một số team xài Cloud VPS thường (4-8 GB RAM) làm frontend + queue + storage, kết hợp Runpod GPU instance bật theo nhu cầu để tiết kiệm.
Bảo mật và quản lý truy cập
- Không expose port 8188 public, luôn đặt sau Caddy + basic auth.
- Bật firewall chỉ cho IP văn phòng + Cloudflare Tunnel cho remote.
- Backup folder workflows/ và models/loras/ (LoRA train mất công, không nên mất).
- Disable directory listing và HF token để tránh leak model có license.
- Nếu cấp truy cập cho team, dùng Authelia/Authentik SSO đứng trước (xem bài SSO).
- Audit log ai gen ảnh gì, dùng custom node hoặc proxy log request.
Bẫy thường gặp
| Triệu chứng | Nguyên nhân | Cách fix |
|---|---|---|
| OutOfMemoryError | VRAM không đủ cho model | Thêm flag --lowvram hoặc --normalvram, hoặc dùng model q4 |
| Ảnh ra mờ, nhiễu | Sai sampler hoặc cfg quá cao | Đổi sampler dpmpp_2m, cfg 6-8 |
| Workflow API gọi 400 | Thiếu node mặc định hoặc class_type sai | Re-export workflow API từ UI mới nhất |
| LoRA không có tác dụng | Quên trigger word hoặc strength quá thấp | Thêm trigger trong prompt, strength 0.7+ |
| Tốc độ chậm bất thường | Model VAE chạy CPU | Set --bf16-vae hoặc kéo VAE vào GPU |
VPS làm frontend + queue + storage cho ComfyUI GPU cluster
Cloud VPS TND sẵn AlmaLinux 9, Ubuntu 22/24, Debian 12/13. SSD CEPH, snapshot 1-click, backup hằng ngày, network 200Mbps trong nước. Dùng làm node điều phối job ComfyUI, lưu workflow, host gallery, đỡ phải chạy gì khác trên con GPU đắt tiền.
Xem 8 cấu hình Cloud VPS →FAQ
VPS không có GPU thì có chạy ComfyUI được không?
Có nhưng cực chậm. SDXL gen 1 ảnh trên CPU tốt nhất cũng 5-10 phút, không thực tế. Nếu chỉ có VPS CPU, dùng nó làm web frontend + queue + storage, gọi GPU server (Runpod, Vast.ai) qua API. Hoặc xét chạy SD 1.5 quantized rất nhỏ trên CPU cho test, không production.
Có thể chạy nhiều workflow song song không?
ComfyUI queue tuần tự để tận dụng tối đa GPU. Khi cần parallel, chạy nhiều instance ComfyUI trên nhiều GPU (multi-GPU setup) hoặc nhiều VPS GPU sau load balancer. Job được gửi tới instance rỗi đầu tiên. Code wrapper khá đơn giản với HAProxy + leastconn.
Train LoRA brand mất bao lâu?
Trên RTX 4090: 30-60 phút cho 30-50 ảnh sản phẩm với kohya_ss hoặc OneTrainer. Yêu cầu dataset: ảnh sản phẩm chất lượng, đa góc, caption mô tả ngắn. LoRA size 100-300 MB. Có thể train trực tiếp trong ComfyUI bằng custom node ComfyUI-LoRA-Tuner, không cần script riêng.
Output ảnh có dùng được thương mại không?
Phụ thuộc license model. SDXL base license cho phép commercial use. FLUX.1 dev cấm commercial trừ khi mua license riêng, FLUX.1 schnell free commercial. LoRA bạn train từ ảnh sản phẩm của chính mình thì OK. LoRA tải từ Civitai có license riêng, đọc kỹ trước khi xài cho client.
ComfyUI có generate được video không?
Có. Tích hợp AnimateDiff, Stable Video Diffusion, CogVideoX, Wan 2.2 qua custom node. Yêu cầu VRAM cao (32 GB+ cho video 720p 5 giây). Output là chuỗi frame, có node ghép thành MP4 bằng ffmpeg. Tốc độ render 1 clip 5 giây mất 3-8 phút trên A100. Phù hợp cho social ads ngắn, không thay được production studio.
