Apidog

Nền tảng phát triển API hợp tác tất cả trong một

Thiết kế API

Tài liệu API

Gỡ lỗi API

Giả lập API

Kiểm thử API tự động

Cách Chạy Workflow Flux ComfyUI Như Một API

中村 拓也

中村 拓也

Updated on tháng 3 28, 2025

Flux là một mô hình chuyển đổi văn bản thành hình ảnh hiện đại được phát triển bởi Black Forest Labs, có khả năng tạo hình ảnh tiên tiến. ComfyUI, mặt khác, là một giao diện mô hình khuếch tán mạnh mẽ và linh hoạt với hệ thống quy trình làm việc dựa trên nút. Khi kết hợp lại, chúng tạo ra một giải pháp mạnh mẽ cho việc tạo hình ảnh chất lượng cao mà có thể truy cập một cách có hệ thống.

Kết hợp sức mạnh của các mô hình Flux với tính linh hoạt của ComfyUI có thể nâng cao đáng kể quy trình làm việc tạo hình ảnh AI của bạn. Hướng dẫn này sẽ hướng dẫn bạn qua quy trình chạy Flux trên ComfyUI dưới dạng một API, mở ra khả năng tự động hóa và tích hợp với các hệ thống khác.

💡
Trước khi bắt đầu thiết lập API Flux ComfyUI của chúng ta, hãy nói về các công cụ kiểm tra. Khi làm việc với các API, việc có một nền tảng kiểm tra đáng tin cậy là rất cần thiết, và Apidog nổi bật như một lựa chọn thay thế Postman hàng đầu trong lĩnh vực này. 

Apidog cung cấp một hệ sinh thái phát triển API toàn diện với các tính năng như kiểm tra tự động, máy chủ giả lập và sinh tài liệu chi tiết tất cả trong một nền tảng thống nhất.

button

Không giống như Postman, Apidog cung cấp quản lý vòng đời API liền mạch với các công cụ gỡ lỗi tích hợp được tối ưu hóa đặc biệt cho các quy trình làm việc phức tạp như trong ComfyUI. Giao diện trực quan của nó giúp việc kiểm tra các điểm cuối của Flux ComfyUI của bạn trở nên hiệu quả hơn đáng kể, với các tính năng cộng tác cho phép các thành viên trong nhóm chia sẻ và hoàn thiện các cấu hình API cùng nhau.

Nếu bạn nghiêm túc về phát triển và kiểm tra API, giải pháp tất cả trong một của Apidog sẽ tiết kiệm đáng kể quy trình làm việc của bạn.

button

Thiết Lập Môi Trường Flux ComfyUI Của Bạn

Trước khi đi vào triển khai API, chúng ta cần thiết lập môi trường cần thiết. Chúng tôi sẽ sử dụng Modal, một nền tảng đám mây giúp dễ dàng chạy các ứng dụng không máy chủ với quyền truy cập GPU.

Các yêu cầu cần có cho Flux ComfyUI

  • Một tài khoản Modal (tạo một tài khoản tại modal.com)
  • Python 3.11 trở lên
  • Git được cài đặt trên máy tính cục bộ của bạn
  • Kiến thức cơ bản về Python và các khái niệm API

Xây Dựng Hình Ảnh Container Flux ComfyUI

Bước đầu tiên của chúng ta là tạo một hình ảnh container bao gồm tất cả các thành phần cần thiết để chạy Flux trên ComfyUI. Hãy cùng phân tích quy trình này:

import json
import subprocess
import uuid
from pathlib import Path
from typing import Dict

import modal

# Tạo hình ảnh cơ bản với các phụ thuộc cần thiết
image = (
    modal.Image.debian_slim(python_version="3.11")
    .apt_install("git")  # Cài đặt git để sao chép ComfyUI
    .pip_install("fastapi[standard]==0.115.4")  # Các phụ thuộc web
    .pip_install("comfy-cli==1.3.5")  # Công cụ CLI của ComfyUI
    .run_commands(
        "comfy --skip-prompt install --nvidia --version 0.3.10"  # Cài đặt ComfyUI
    )
)

Mã code này tạo một hình ảnh Modal dựa trên Debian Slim với Python 3.11, sau đó cài đặt Git, FastAPI và comfy-cli. Công cụ comfy-cli sau đó được sử dụng để cài đặt ComfyUI.

Nâng Cao Flux ComfyUI Của Bạn Với Các Nút Tùy Chỉnh

Để mở khóa các chức năng bổ sung, chúng tôi sẽ thêm các nút tùy chỉnh vào cài đặt ComfyUI của chúng tôi:

image = (
    image.run_commands(
        "comfy node install was-node-suite-comfyui@1.0.2"  # Cài đặt WAS Node Suite
    )
    # Thêm nhiều nút tùy chỉnh khác nếu cần
)

WAS Node Suite cung cấp các chức năng bổ sung cho việc tạo và thao tác hình ảnh, điều này có thể đặc biệt hữu ích khi làm việc với các mô hình Flux.

Thiết Lập Tải Mô Hình Flux ComfyUI

Quản lý mô hình hiệu quả là rất quan trọng để trải nghiệm mượt mà. Chúng tôi sẽ tạo một hàm để tải mô hình Flux và lưu trữ nó trong một khối lượng bền bỉ:

def hf_download():
    from huggingface_hub import hf_hub_download

    flux_model = hf_hub_download(
        repo_id="Comfy-Org/flux1-schnell",
        filename="flux1-schnell-fp8.safetensors",
        cache_dir="/cache",
    )

    # Tạo liên kết mô hình tới thư mục ComfyUI
    subprocess.run(
        f"ln -s {flux_model} /root/comfy/ComfyUI/models/checkpoints/flux1-schnell-fp8.safetensors",
        shell=True,
        check=True,
    )

# Tạo một khối lượng bền bỉ cho lưu trữ mô hình
vol = modal.Volume.from_name("hf-hub-cache", create_if_missing=True)

# Thêm hàm tải mô hình vào hình ảnh của chúng tôi
image = (
    image.pip_install("huggingface_hub[hf_transfer]==0.26.2")
    .env({"HF_HUB_ENABLE_HF_TRANSFER": "1"})
    .run_function(
        hf_download,
        volumes={"/cache": vol},
    )
)

# Thêm tệp JSON quy trình làm việc của chúng tôi vào container
image = image.add_local_file(
    Path(__file__).parent / "workflow_api.json", "/root/workflow_api.json"
)

Mã code này định nghĩa một hàm để tải mô hình Flux Schnell từ Hugging Face và tạo một liên kết tới thư mục mô hình của ComfyUI. Chúng tôi cũng tạo một Modal Volume để duy trì các mô hình đã tải xuống giữa các lần chạy.

Phát Triển Flux ComfyUI Tương Tác

Trước khi triển khai dưới dạng một API, thật hữu ích khi kiểm tra một cách tương tác quy trình làm việc Flux ComfyUI của bạn:

app = modal.App(name="example-comfyui", image=image)

@app.function(
    allow_concurrent_inputs=10,  # Cần thiết cho khởi động UI
    max_containers=1,  # Giới hạn một container cho việc sử dụng tương tác
    gpu="L40S",  # GPU mạnh cho suy diễn mô hình Flux
    volumes={"/cache": vol},  # Gắn kết các mô hình cache của chúng tôi
)
@modal.web_server(8000, startup_timeout=60)
def ui():
    subprocess.Popen(
        "comfy launch -- --listen 0.0.0.0 --port 8000",
        shell=True
    )

Bạn có thể chạy điều này với modal serve your_file.py và truy cập UI trong trình duyệt của bạn để thiết kế và thử nghiệm các quy trình làm việc của bạn trước khi triển khai API.

Triển Khai API Flux ComfyUI

Giờ đến phần chính - biến ComfyUI thành một điểm cuối API cho suy diễn mô hình Flux:

@app.cls(
    allow_concurrent_inputs=10,  # Cho phép nhiều cuộc gọi API đồng thời
    scaledown_window=300,  # Giữ cho các container sống sót trong 5 phút sau khi sử dụng
    gpu="L40S",
    volumes={"/cache": vol},
)
class ComfyUI:
    @modal.enter()
    def launch_comfy_background(self):
        # Khởi động máy chủ ComfyUI trong nền
        cmd = "comfy launch --background"
        subprocess.run(cmd, shell=True, check=True)

    @modal.method()
    def infer(self, workflow_path: str = "/root/workflow_api.json"):
        # Kiểm tra tình trạng của máy chủ ComfyUI
        self.poll_server_health()

        # Chạy quy trình với comfy-cli
        cmd = f"comfy run --workflow {workflow_path} --wait --timeout 1200 --verbose"
        subprocess.run(cmd, shell=True, check=True)

        # Tìm tệp hình ảnh đầu ra
        output_dir = "/root/comfy/ComfyUI/output"
        workflow = json.loads(Path(workflow_path).read_text())
        file_prefix = [
            node.get("inputs")
            for node in workflow.values()
            if node.get("class_type") == "SaveImage"
        ][0]["filename_prefix"]

        # Trả về hình ảnh dưới dạng byte
        for f in Path(output_dir).iterdir():
            if f.name.startswith(file_prefix):
                return f.read_bytes()

    @modal.fastapi_endpoint(method="POST")
    def api(self, item: Dict):
        from fastapi import Response

        # Tải tệp mẫu quy trình
        workflow_data = json.loads(
            (Path(__file__).parent / "workflow_api.json").read_text()
        )

        # Chèn lời nhắc
        workflow_data["6"]["inputs"]["text"] = item["prompt"]

        # Tạo ID duy nhất cho yêu cầu này
        client_id = uuid.uuid4().hex
        workflow_data["9"]["inputs"]["filename_prefix"] = client_id

        # Lưu quy trình làm việc đã sửa đổi
        new_workflow_file = f"{client_id}.json"
        json.dump(workflow_data, Path(new_workflow_file).open("w"))

        # Chạy suy diễn
        img_bytes = self.infer.local(new_workflow_file)

        return Response(img_bytes, media_type="image/jpeg")

    def poll_server_health(self) -> Dict:
        import socket
        import urllib

        try:
            # Kiểm tra xem máy chủ có khỏe mạnh không
            req = urllib.request.Request("")
            urllib.request.urlopen(req, timeout=5)
            print("Máy chủ ComfyUI khỏe mạnh")
        except (socket.timeout, urllib.error.URLError) as e:
            # Dừng container nếu máy chủ không khỏe mạnh
            print(f"Kiểm tra tình trạng máy chủ thất bại: {str(e)}")
            modal.experimental.stop_fetching_inputs()
            raise Exception("Máy chủ ComfyUI không khỏe mạnh, dừng container")

Lớp này định nghĩa các chức năng API cốt lõi:

  1. launch_comfy_background khởi động máy chủ ComfyUI khi container được khởi động
  2. infer chạy một quy trình và trả về hình ảnh được tạo ra
  3. api là điểm cuối FastAPI nhận một lời nhắc, sửa đổi quy trình làm việc và trả về hình ảnh
  4. poll_server_health đảm bảo máy chủ ComfyUI phản hồi

Kiểm Tra API Flux ComfyUI Của Bạn

Để kiểm tra API của bạn, bạn có thể tạo một tập lệnh khách đơn giản:

import requests
import base64
from PIL import Image
import io
import argparse

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--prompt", default="Một cảnh quan siêu thực với các hòn đảo bay và ánh sáng huyền ảo")
    parser.add_argument("--endpoint", default="")
    args = parser.parse_args()

    # Gửi yêu cầu đến API
    response = requests.post(
        f"{args.endpoint}/api",
        json={"prompt": args.prompt}
    )

    # Xử lý phản hồi
    if response.status_code == 200:
        # Lưu và hiển thị hình ảnh
        image = Image.open(io.BytesIO(response.content))
        image.save("flux_output.jpg")
        print(f"Hình ảnh đã được tạo và lưu dưới dạng flux_output.jpg")

        # Tùy chọn: hiển thị hình ảnh nếu trong môi trường phù hợp
        try:
            image.show()
        except:
            pass
    else:
        print(f"Lỗi: {response.status_code}, {response.text}")

if __name__ == "__main__":
    main()

Tối Ưu Hiệu Suất Flux ComfyUI

Để đảm bảo API của bạn vẫn phản hồi và tiết kiệm, hãy xem xét thực hiện các tối ưu hóa sau:

1. Chụp Bộ Nhớ Để Khởi Động Lạnh Flux ComfyUI Nhanh Hơn

Các khởi động lạnh có thể là một nút thắt cổ chai cho các ứng dụng không máy chủ. Modal cung cấp chụp bộ nhớ có thể giảm đáng kể thời gian khởi động:

@app.cls(
    allow_concurrent_inputs=10,
    gpu="L40S",
    volumes={"/cache": vol},
    memory_snapshot=modal.MemorySnapshot(
        snapshot_path="/root/comfy-snapshot",
        boot_command="comfy launch --background",
    ),
)
class ComfyUI:
    # Phần còn lại của việc triển khai lớp

2. Gộp Yêu Cầu Cho Flux ComfyUI

Đối với các tình huống xử lý nhiều thông lượng, việc thực hiện gộp yêu cầu có thể cải thiện hiệu quả:

@modal.method()
def batch_inference(self, prompts: list[str]):
    results = []
    for prompt in prompts:
        # Tạo quy trình cho từng lời nhắc
        client_id = uuid.uuid4().hex
        workflow_data = json.loads(
            (Path(__file__).parent / "workflow_api.json").read_text()
        )
        workflow_data["6"]["inputs"]["text"] = prompt
        workflow_data["9"]["inputs"]["filename_prefix"] = client_id

        # Lưu và xử lý quy trình
        new_workflow_file = f"{client_id}.json"
        json.dump(workflow_data, Path(new_workflow_file).open("w"))
        img_bytes = self.infer.local(new_workflow_file)
        results.append(img_bytes)

    return results

Các Tính Năng API Flux ComfyUI Nâng Cao

Tùy Chỉnh Các Tham Số Quy Trình

Mở rộng API của bạn để cho phép các tham số bổ sung ngoài chỉ lời nhắc:

@modal.fastapi_endpoint(method="POST")
def advanced_api(self, item: Dict):
    from fastapi import Response

    workflow_data = json.loads(
        (Path(__file__).parent / "workflow_api.json").read_text()
    )

    # Chèn lời nhắc
    workflow_data["6"]["inputs"]["text"] = item["prompt"]

    # Tùy chọn: Đặt thêm tham số nếu có
    if "negative_prompt" in item:
        workflow_data["7"]["inputs"]["text"] = item["negative_prompt"]

    if "cfg_scale" in item:
        workflow_data["3"]["inputs"]["cfg"] = item["cfg_scale"]

    if "steps" in item:
        workflow_data["3"]["inputs"]["steps"] = item["steps"]

    # Tạo ID duy nhất
    client_id = uuid.uuid4().hex
    workflow_data["9"]["inputs"]["filename_prefix"] = client_id

    # Lưu và xử lý quy trình
    new_workflow_file = f"{client_id}.json"
    json.dump(workflow_data, Path(new_workflow_file).open("w"))
    img_bytes = self.infer.local(new_workflow_file)

    return Response(img_bytes, media_type="image/jpeg")

Xử Lý Các Mô Hình Flux ComfyUI Khác Nhau

Cho phép chuyển đổi giữa các mô hình Flux khác nhau:

@modal.fastapi_endpoint(method="POST")
def model_selection_api(self, item: Dict):
    from fastapi import Response

    workflow_data = json.loads(
        (Path(__file__).parent / "workflow_api.json").read_text()
    )

    # Chèn lời nhắc
    workflow_data["6"]["inputs"]["text"] = item["prompt"]

    # Chọn mô hình nếu được chỉ định
    if "model" in item:
        if item["model"] == "flux-schnell":
            workflow_data["2"]["inputs"]["ckpt_name"] = "flux1-schnell-fp8.safetensors"
        elif item["model"] == "flux-turbo":
            workflow_data["2"]["inputs"]["ckpt_name"] = "flux1-turbo-fp8.safetensors"

    # Tạo ID duy nhất
    client_id = uuid.uuid4().hex
    workflow_data["9"]["inputs"]["filename_prefix"] = client_id

    # Lưu và xử lý quy trình
    new_workflow_file = f"{client_id}.json"
    json.dump(workflow_data, Path(new_workflow_file).open("w"))
    img_bytes = self.infer.local(new_workflow_file)

    return Response(img_bytes, media_type="image/jpeg")

Giám Sát API Flux ComfyUI Của Bạn

Thực hiện giám sát đúng cách là rất quan trọng cho các triển khai sản xuất:

@app.cls(
    # Các tham số khác
    monitor_agent=modal.MonitorAgent(),
)
class ComfyUI:
    # Triển khai hiện có

    def log_request(self, prompt, model, processing_time):
        # Triển khai ghi log tùy chỉnh
        print(f"Đã tạo hình ảnh cho lời nhắc: '{prompt}' sử dụng mô hình {model} trong {processing_time:.2f}s")

Kết Luận: Khai Thác Sức Mạnh Của Flux ComfyUI Như Một API

Bằng cách làm theo hướng dẫn này, bạn đã học được cách biến ComfyUI với các mô hình Flux thành một dịch vụ API có thể mở rộng và sẵn sàng cho sản xuất. Cách tiếp cận này mang lại nhiều lợi ích:

  1. Tính Mở Rộng: Xử lý nhiều yêu cầu đồng thời với khả năng tự động mở rộng container
  2. Tính Linh Hoạt: Tùy chỉnh quy trình làm việc dựa trên yêu cầu của người dùng
  3. Tích Hợp: Kết nối khả năng tạo hình ảnh của bạn với các ứng dụng khác
  4. Chi Phí Hiệu Quả: Chỉ trả tiền cho tài nguyên bạn sử dụng

Sự kết hợp giữa hạ tầng không máy chủ của Modal, hệ thống quy trình làm việc mạnh mẽ của ComfyUI và khả năng tạo hình ảnh tiên tiến của Flux tạo ra một giải pháp mạnh mẽ cho nhiều ứng dụng sáng tạo và kinh doanh.

Dù bạn đang xây dựng một công cụ sáng tạo, một hệ thống hình ảnh thương mại điện tử, hay một nền tảng tạo nội dung, việc chạy Flux trên ComfyUI dưới dạng một API cung cấp nền tảng cho những trải nghiệm hình ảnh được kích hoạt bởi AI đầy sáng tạo.

button