全部产品
Search
文档中心

Platform For AI:Pembuatan video AI - Penerapan ComfyUI

更新时间:Dec 19, 2025

ComfyUI adalah antarmuka pengguna berbasis node untuk Stable Diffusion yang memungkinkan Anda membangun alur kerja AIGC kompleks untuk tugas seperti pembuatan konten video pendek dan produksi animasi. Topik ini menjelaskan cara menerapkan dan menggunakan ComfyUI di Elastic Algorithm Service (EAS).

Panduan Edisi

Skenario

Metode pemanggilan

Standard Edition

  • WebUI atau panggilan API untuk pengguna tunggal, cocok untuk mulai dan untuk pengembangan serta pengujian.

  • Kami menyarankan Anda menerapkan satu instans karena kemampuan konkurensi terbatas.

  • WebUI

  • Debugging online

  • Panggilan API (sinkron)

API Edition

  • Konkurensi tinggi, cocok untuk lingkungan produksi.

  • Penerapan relatif kompleks dan memerlukan resource CPU tambahan untuk membuat instans layanan antrian.

Panggilan API (asinkron)

Cluster Edition WebUI

  • Banyak pengguna menggunakan WebUI secara bersamaan dengan isolasi lingkungan, cocok untuk kolaborasi tim atau pengajaran.

  • Konsumsi resource tinggi. Untuk informasi lebih lanjut tentang prinsip kerja, lihat Pengenalan prinsip kerja layanan Edisi Kluster.

WebUI

Serverless Edition

  • Penerapan gratis dan penagihan berdasarkan durasi pembuatan citra. Biayanya sangat rendah, cocok untuk permintaan yang fluktuatif.

  • Anda tidak dapat menggunakan model atau plug-in kustom. Penerapan hanya didukung di wilayah China (Shanghai) dan China (Hangzhou).

WebUI

Catatan

Jenis panggilan API—sinkron atau asinkron—bergantung pada penggunaan layanan antrian EAS:

  • Panggilan sinkron: Langsung meminta instans inferensi tanpa menggunakan layanan antrian EAS.

  • Panggilan asinkron: Menggunakan layanan antrian EAS untuk mengirim permintaan ke antrian input dan mengambil hasil melalui langganan.

Karena ComfyUI memiliki sistem antrian asinkron internal, panggilan sinkron tetap diproses secara asinkron. Setelah mengirim permintaan, sistem mengembalikan ID prompt. Anda harus menggunakan ID prompt tersebut untuk melakukan polling terhadap hasil inferensi.

Penagihan

  • Serverless Edition: Penerapan gratis. Anda ditagih berdasarkan durasi inferensi aktual.

  • Edisi lainnya: Anda ditagih untuk resource yang diterapkan dan durasi waktu proses. Biaya berlaku setelah layanan berhasil diterapkan, bahkan jika tidak sedang digunakan.

Untuk informasi lebih lanjut tentang penagihan, lihat Penagihan Elastic Algorithm Service (EAS).

Terapkan layanan

Serverless Edition hanya dapat diterapkan menggunakan metode penerapan model berbasis skenario. Edisi Standard, Cluster, dan API dapat diterapkan menggunakan metode penerapan model berbasis skenario sederhana atau metode penerapan model kustom, yang mendukung lebih banyak fitur.

Penting
  • ComfyUI hanya mendukung mode single-card (single-machine single-card atau multi-machine single-card) dan tidak mendukung operasi konkuren multi-kartu. Karena instans EAS hanya memiliki satu proses ComfyUI, jika Anda memilih instans dengan spesifikasi GPU ganda, seperti 2 × A10, selama penerapan hanya satu GPU yang digunakan. Satu tugas pembuatan citra tidak dipercepat.

  • Load balancing: Anda harus menerapkan API Edition dan mengonfigurasi load balancing menggunakan antrian asinkron.

Metode 1: Penerapan model berbasis skenario (disarankan)

  1. Masuk ke Konsol PAI. Pilih wilayah di bagian atas halaman, lalu pilih ruang kerja yang diinginkan dan klik Elastic Algorithm Service (EAS).

  2. Pada halaman Elastic Algorithm Service (EAS), klik Deploy Service. Di bawah Scenario-based Model Deployment, klik AI Video Generation: ComfyUI-based Deployment.

  3. Pada halaman AI Video Generation: ComfyUI-based Deployment, konfigurasikan parameter berikut.

    • Edition: Pilih edisi berdasarkan Panduan Edisi.

    • Mount storage: Anda harus mengonfigurasi penyimpanan jika ingin menggunakan model sendiri, menginstal node kustom, atau melakukan panggilan API. Misalnya, jika Anda menggunakan Object Storage Service (OSS), pilih bucket dan direktori. Setelah penerapan berhasil, sistem secara otomatis membuat direktori ComfyUI yang diperlukan di dalam bucket tersebut. Pastikan bucket berada di wilayah yang sama dengan layanan EAS.

    • Resource Configuration: Kami menyarankan menggunakan tipe GPU GU30, A10, atau T4. Sistem secara default menggunakan GPU > ml.gu7i.c16m60.1-gu30, yang merupakan opsi hemat biaya.

  4. Klik Deploy. Penerapan memakan waktu sekitar 5 menit. Penerapan berhasil ketika Service Status berubah menjadi Running.

Metode 2: Penerapan model kustom

  1. Masuk ke Konsol PAI. Pilih wilayah di bagian atas halaman, lalu pilih ruang kerja yang diinginkan dan klik Elastic Algorithm Service (EAS).

  2. Klik Deploy Service. Di bagian Custom Model Deployment, klik Custom Deployment.

  3. Pada halaman Custom Deployment, konfigurasikan parameter utama berikut. Untuk informasi lebih lanjut, lihat Deskripsi Parameter Penerapan Kustom.

    • Atur Deployment Method ke Image Deployment, dan centang kotak pilihan Enable Web Application.

    • Image Configuration: Dalam daftar Official Images, pilih comfyui > comfyui:1.9. Dalam tag gambar, x.x menunjukkan Standard Edition, x.x-api menunjukkan API Edition, dan x.x-cluster menunjukkan Cluster Edition.

      Catatan
      • Karena versi diiterasi dengan cepat, Anda dapat memilih versi gambar terbaru selama penerapan.

      • Untuk informasi lebih lanjut tentang skenario tiap versi, lihat Panduan Edisi.

    • Storage Mount: Untuk menggunakan model sendiri, menginstal node kustom, atau melakukan panggilan API, Anda harus memasang penyimpanan. Misalnya, saat menggunakan Object Storage Service (OSS), pilih bucket dan direktori. Setelah penerapan selesai, direktori ComfyUI yang diperlukan secara otomatis dibuat di direktori yang dipilih. Pastikan bucket berada di wilayah yang sama dengan layanan EAS.

      • Uri: Klik image untuk memilih direktori penyimpanan OSS yang sudah ada. Misalnya, oss://bucket-test/data-oss/.

      • Mount Path: Atur ke /code/data-oss. Ini memasang direktori file OSS yang dikonfigurasi ke path /code/data-oss dalam gambar.

    • Run Command:

      • Setelah Anda mengonfigurasi versi gambar, sistem secara otomatis mengatur perintah run ke python main.py --listen --port 8000. Nomor port adalah 8000.

      • Jika Anda telah memasang penyimpanan, Anda harus menambahkan parameter --data-dir ke Startup Command dan mengatur nilainya ke direktori mount. Direktori mount ini harus sama dengan Mount Path. Misalnya, python main.py --listen --port 8000 --data-dir /code/data-oss.

    • Atur Resource Type ke Public Resources.

    • Deployment Resources: Spesifikasi resource harus berupa tipe GPU. Kami menyarankan ml.gu7i.c16m60.1-gu30, yang merupakan opsi paling hemat biaya. Jika stok tidak mencukupi, Anda dapat memilih ecs.gn6i-c16g1.4xlarge.

  4. Klik Deploy. Penerapan layanan memakan waktu sekitar 5 menit. Layanan berhasil diterapkan ketika Service Status berubah menjadi Running.

Panggil layanan

Gunakan WebUI

Penting

Edisi Standard, Cluster, dan Serverless mendukung WebUI.

Klik nama layanan target untuk membuka halaman ikhtisarnya, lalu klik Web applications di pojok kanan atas.

Jika halaman dimuat lambat, lihat Halaman hang atau membutuhkan waktu lama untuk refresh.

1. Gunakan alur kerja template

WebUI mendukung konfigurasi alur kerja kustom dan menyediakan beberapa template preset. Anda dapat memilih template di halaman Workflow > Browse Templates. Topik ini menggunakan template alur kerja Wan VACE Text to Video sebagai contoh.

Catatan

Untuk Serverless Edition, alur kerja ini tidak termasuk dalam template. Anda dapat menggunakan template lain atau memilih Workflow > Open untuk memuat alur kerja dari sistem file lokal Anda.

image

Setelah alur kerja dimuat, Anda dapat mengabaikan pesan error tentang model yang hilang. Kami menyarankan Anda mencentang kotak pilihan untuk mencegah pesan ini muncul lagi.

Karena perubahan path, menjalankan alur kerja secara langsung dapat menyebabkan error berikut.

image.png

Pertama, pilih ulang model wan2.1_vace_14B_fp16.safetensors dan Wan21_CausVid_14B_T2V_lora_rank32.safetensors di area Load models here.

image

Setelah alur kerja berhasil dijalankan, video yang dihasilkan ditampilkan di area Save Video.image

2. Gunakan model pihak ketiga dan instal node kustom (plug-in ComfyUI)

  1. Pastikan versi ComfyUI yang diterapkan bukan Serverless Edition. Serverless Edition hanya dapat menggunakan model dan node bawaan.

  2. Mount penyimpanan harus dikonfigurasi untuk layanan. Untuk penerapan kustom, tambahkan parameter --data-dir ke field Startup Command untuk memasang direktori. Untuk informasi lebih lanjut, lihat Metode 2: Penerapan Model Kustom.

    Setelah layanan diterapkan, sistem secara otomatis membuat struktur direktori berikut di penyimpanan OSS atau NAS yang dipasang.

    image

    Di mana:

    • custom_nodes: Direktori ini digunakan untuk menyimpan file node.

    • models: Direktori ini digunakan untuk menyimpan file model.

  3. Unggah file model atau node. Sebagai contoh menggunakan OSS, Anda dapat mengunggah file ke OSS di konsol. Untuk file besar, lihat Cara mengunggah file besar ke OSS.

    • Unggah file model: Unggah model ke subdirektori yang sesuai dari models berdasarkan petunjuk di proyek sumber node yang menggunakan model tersebut. Misalnya:

      • Untuk Checkpoint loader, model harus diunggah ke models/checkpoints.

      • Untuk style model loader, model harus diunggah ke models/styles.

    • Unggah file node: Kami menyarankan Anda mengunggah node kustom ke direktori custom_nodes dari penyimpanan yang dipasang.

  4. Muat model baru atau restart proses.

    Setelah Anda mengunggah model ke bucket yang dipasang, klik PaiCustom > Load New Model. Jika Anda masih tidak dapat menemukan model tersebut, klik Restart Process. Setelah proses direstart, refresh halaman.

    Setelah Anda mengunggah file node, klik Restart Process. Setelah proses direstart, refresh halaman browser.

3. Ekspor alur kerja

Setelah Anda melakukan debugging alur kerja, klik Workflow > Export (API) untuk menyimpan alur kerja sebagai file JSON. Anda kemudian dapat menggunakan file ini untuk panggilan API.

image

Panggilan API

Penting

Layanan Standard Edition hanya mendukung panggilan sinkron dan menyediakan fitur debugging online.

Layanan API Edition hanya mendukung panggilan asinkron dan hanya path api_prompt.

Badan permintaan API untuk ComfyUI bergantung pada konfigurasi alur kerja. Anda harus terlebih dahulu menyiapkan dan mengekspor file JSON alur kerja dari WebUI.

  • Panggilan sinkron: Badan permintaan harus membungkus konten file JSON alur kerja dengan kunci prompt.

  • Panggilan asinkron: Badan permintaan adalah konten file JSON alur kerja.

Karena alur kerja Wan VACE Text to Video memakan waktu lama, alur kerja berikut disediakan untuk pengujian. Waktu eksekusinya sekitar 3 menit.

Klik untuk melihat contoh badan permintaan untuk alur kerja pengujian

Panggilan sinkron

{
    "prompt": {
        "3": {
            "inputs": {
                "seed": 423988542100860,
                "steps": 40,
                "cfg": 7,
                "sampler_name": "dpmpp_sde_gpu",
                "scheduler": "karras",
                "denoise": 1,
                "model": [
                    "4",
                    0
                ],
                "positive": [
                    "6",
                    0
                ],
                "negative": [
                    "7",
                    0
                ],
                "latent_image": [
                    "5",
                    0
                ]
            },
            "class_type": "KSampler",
            "_meta": {
                "title": "K Sampler"
            }
        },
        "4": {
            "inputs": {
                "ckpt_name": "LandscapeBING_v10.safetensors"
            },
            "class_type": "CheckpointLoaderSimple",
            "_meta": {
                "title": "Checkpoint Loader (Simple)"
            }
        },
        "5": {
            "inputs": {
                "width": 720,
                "height": 1280,
                "batch_size": 1
            },
            "class_type": "EmptyLatentImage",
            "_meta": {
                "title": "Empty Latent"
            }
        },
        "6": {
            "inputs": {
                "text": "Rocket takes off from the ground, fire, sky, airplane",
                "speak_and_recognation": {
                    "__value__": [
                        false,
                        true
                    ]
                },
                "clip": [
                    "4",
                    1
                ]
            },
            "class_type": "CLIPTextEncode",
            "_meta": {
                "title": "CLIP Text Encoder"
            }
        },
        "7": {
            "inputs": {
                "text": "",
                "speak_and_recognation": {
                    "__value__": [
                        false,
                        true
                    ]
                },
                "clip": [
                    "4",
                    1
                ]
            },
            "class_type": "CLIPTextEncode",
            "_meta": {
                "title": "CLIP Text Encoder"
            }
        },
        "8": {
            "inputs": {
                "samples": [
                    "3",
                    0
                ],
                "vae": [
                    "4",
                    2
                ]
            },
            "class_type": "VAEDecode",
            "_meta": {
                "title": "VAE Decode"
            }
        },
        "9": {
            "inputs": {
                "filename_prefix": "ComfyUI",
                "images": [
                    "8",
                    0
                ]
            },
            "class_type": "SaveImage",
            "_meta": {
                "title": "Save Image"
            }
        },
        "13": {
            "inputs": {
                "seed": 788620942678235,
                "steps": 40,
                "cfg": 2.5,
                "sampler_name": "euler_ancestral",
                "scheduler": "karras",
                "denoise": 1,
                "model": [
                    "17",
                    0
                ],
                "positive": [
                    "16",
                    0
                ],
                "negative": [
                    "16",
                    1
                ],
                "latent_image": [
                    "16",
                    2
                ]
            },
            "class_type": "KSampler",
            "_meta": {
                "title": "K Sampler"
            }
        },
        "14": {
            "inputs": {
                "samples": [
                    "13",
                    0
                ],
                "vae": [
                    "18",
                    2
                ]
            },
            "class_type": "VAEDecode",
            "_meta": {
                "title": "VAE Decode"
            }
        },
        "15": {
            "inputs": {
                "filename_prefix": "ComfyUI",
                "fps": 10.000000000000002,
                "lossless": false,
                "quality": 85,
                "method": "default",
                "images": [
                    "14",
                    0
                ]
            },
            "class_type": "SaveAnimatedWEBP",
            "_meta": {
                "title": "Save WEBP"
            }
        },
        "16": {
            "inputs": {
                "width": 512,
                "height": 768,
                "video_frames": 35,
                "motion_bucket_id": 140,
                "fps": 15,
                "augmentation_level": 0.15000000000000002,
                "clip_vision": [
                    "18",
                    1
                ],
                "init_image": [
                    "8",
                    0
                ],
                "vae": [
                    "18",
                    2
                ]
            },
            "class_type": "SVD_img2vid_Conditioning",
            "_meta": {
                "title": "SVD_Image to Video_Conditioning"
            }
        },
        "17": {
            "inputs": {
                "min_cfg": 1,
                "model": [
                    "18",
                    0
                ]
            },
            "class_type": "VideoLinearCFGGuidance",
            "_meta": {
                "title": "Linear CFG Guidance"
            }
        },
        "18": {
            "inputs": {
                "ckpt_name": "svd_xt.safetensors"
            },
            "class_type": "ImageOnlyCheckpointLoader",
            "_meta": {
                "title": "Checkpoint Loader (Image Only)"
            }
        },
        "19": {
            "inputs": {
                "frame_rate": 10,
                "loop_count": 0,
                "filename_prefix": "comfyUI",
                "format": "video/h264-mp4",
                "pix_fmt": "yuv420p",
                "crf": 20,
                "save_metadata": true,
                "trim_to_audio": false,
                "pingpong": false,
                "save_output": true,
                "images": [
                    "14",
                    0
                ]
            },
            "class_type": "VHS_VideoCombine",
            "_meta": {
                "title": "Combine to Video"
            }
        }
    }
}

Pemanggilan asinkron

{
    "3": {
        "inputs": {
            "seed": 423988542100860,
            "steps": 40,
            "cfg": 7,
            "sampler_name": "dpmpp_sde_gpu",
            "scheduler": "karras",
            "denoise": 1,
            "model": [
                "4",
                0
            ],
            "positive": [
                "6",
                0
            ],
            "negative": [
                "7",
                0
            ],
            "latent_image": [
                "5",
                0
            ]
        },
        "class_type": "KSampler",
        "_meta": {
            "title": "K Sampler"
        }
    },
    "4": {
        "inputs": {
            "ckpt_name": "LandscapeBING_v10.safetensors"
        },
        "class_type": "CheckpointLoaderSimple",
        "_meta": {
            "title": "Checkpoint Loader (Simple)"
        }
    },
    "5": {
        "inputs": {
            "width": 720,
            "height": 1280,
            "batch_size": 1
        },
        "class_type": "EmptyLatentImage",
        "_meta": {
            "title": "Empty Latent"
        }
    },
    "6": {
        "inputs": {
            "text": "Rocket takes off from the ground, fire, sky, airplane",
            "speak_and_recognation": {
                "__value__": [
                    false,
                    true
                ]
            },
            "clip": [
                "4",
                1
            ]
        },
        "class_type": "CLIPTextEncode",
        "_meta": {
            "title": "CLIP Text Encoder"
        }
    },
    "7": {
        "inputs": {
            "text": "",
            "speak_and_recognation": {
                "__value__": [
                    false,
                    true
                ]
            },
            "clip": [
                "4",
                1
            ]
        },
        "class_type": "CLIPTextEncode",
        "_meta": {
            "title": "CLIP Text Encoder"
        }
    },
    "8": {
        "inputs": {
            "samples": [
                "3",
                0
            ],
            "vae": [
                "4",
                2
            ]
        },
        "class_type": "VAEDecode",
        "_meta": {
            "title": "VAE Decode"
        }
    },
    "9": {
        "inputs": {
            "filename_prefix": "ComfyUI",
            "images": [
                "8",
                0
            ]
        },
        "class_type": "SaveImage",
        "_meta": {
            "title": "Save Image"
        }
    },
    "13": {
        "inputs": {
            "seed": 788620942678235,
            "steps": 40,
            "cfg": 2.5,
            "sampler_name": "euler_ancestral",
            "scheduler": "karras",
            "denoise": 1,
            "model": [
                "17",
                0
            ],
            "positive": [
                "16",
                0
            ],
            "negative": [
                "16",
                1
            ],
            "latent_image": [
                "16",
                2
            ]
        },
        "class_type": "KSampler",
        "_meta": {
            "title": "K Sampler"
        }
    },
    "14": {
        "inputs": {
            "samples": [
                "13",
                0
            ],
            "vae": [
                "18",
                2
            ]
        },
        "class_type": "VAEDecode",
        "_meta": {
            "title": "VAE Decode"
        }
    },
    "15": {
        "inputs": {
            "filename_prefix": "ComfyUI",
            "fps": 10.000000000000002,
            "lossless": false,
            "quality": 85,
            "method": "default",
            "images": [
                "14",
                0
            ]
        },
        "class_type": "SaveAnimatedWEBP",
        "_meta": {
            "title": "Save WEBP"
        }
    },
    "16": {
        "inputs": {
            "width": 512,
            "height": 768,
            "video_frames": 35,
            "motion_bucket_id": 140,
            "fps": 15,
            "augmentation_level": 0.15000000000000002,
            "clip_vision": [
                "18",
                1
            ],
            "init_image": [
                "8",
                0
            ],
            "vae": [
                "18",
                2
            ]
        },
        "class_type": "SVD_img2vid_Conditioning",
        "_meta": {
            "title": "SVD_Image to Video_Conditioning"
        }
    },
    "17": {
        "inputs": {
            "min_cfg": 1,
            "model": [
                "18",
                0
            ]
        },
        "class_type": "VideoLinearCFGGuidance",
        "_meta": {
            "title": "Linear CFG Guidance"
        }
    },
    "18": {
        "inputs": {
            "ckpt_name": "svd_xt.safetensors"
        },
        "class_type": "ImageOnlyCheckpointLoader",
        "_meta": {
            "title": "Checkpoint Loader (Image Only)"
        }
    },
    "19": {
        "inputs": {
            "frame_rate": 10,
            "loop_count": 0,
            "filename_prefix": "comfyUI",
            "format": "video/h264-mp4",
            "pix_fmt": "yuv420p",
            "crf": 20,
            "save_metadata": true,
            "trim_to_audio": false,
            "pingpong": false,
            "save_output": true,
            "images": [
                "14",
                0
            ]
        },
        "class_type": "VHS_VideoCombine",
        "_meta": {
            "title": "Combine to Video"
        }
    }
}

Debugging online

Pada halaman Elastic Algorithm Service (EAS), temukan layanan target dan klik Online Debugging di kolom Actions.

  1. Kirim permintaan POST untuk mendapatkan Prompt ID.

    1. Pada halaman debug, di bagian Online Debugging Request Parameters, masukkan badan permintaan di field Body. Lalu, tambahkan /prompt ke kotak teks URL permintaan.image

    2. Klik Send Request untuk melihat respons di area Debugging Information, seperti yang ditunjukkan pada gambar berikut.image

  2. Kirim permintaan GET untuk mengambil hasil inferensi berdasarkan Prompt ID.

    1. Di area Online API Debugging Request Parameters, atur metode permintaan ke GET dan masukkan /history/<prompt id> ke kotak teks, seperti yang ditunjukkan pada gambar berikut.image

      Ganti <prompt id> dengan Prompt ID yang Anda peroleh pada langkah sebelumnya.

    2. Klik Send Request untuk mendapatkan hasil inferensi.

      Anda dapat melihat hasil inferensi yang dihasilkan di direktori output dari penyimpanan yang dipasang.

Panggilan sinkron

  1. Lihat informasi titik akhir.

    1. Pada tab Inference Services, klik nama layanan target untuk membuka halaman Overview-nya. Di bagian Basic Information, klik View Endpoint Information.

    2. Di panel Invocation Method, dapatkan titik akhir dan token. Pilih titik akhir Internet atau VPC berdasarkan kebutuhan Anda. Contoh berikut menggunakan <EAS_ENDPOINT> dan <EAS_TOKEN> sebagai placeholder untuk nilai-nilai ini.

      image

  2. Kirim permintaan POST untuk mendapatkan Prompt ID.

    • Metode permintaan HTTP: POST.

    • URI permintaan (URL): <EAS_ENDPOINT>/prompt. Jika <EAS_ENDPOINT> diakhiri dengan garis miring (/), hapus garis miring tersebut. URL akhir harus mirip dengan contoh berikut: http://comfyui****.175805416243****.cn-beijing.pai-eas.aliyuncs.com/prompt.

    • Header permintaan (Headers):

      Header

      Nilai

      Deskripsi

      Authorization

      <EAS_TOKEN>

      Kunci lisensi.

      Content-Type

      application/json

      Menentukan format badan permintaan.

    Kode contoh:

    cURL

    curl --location --request POST '<EAS_ENDPOINT>/prompt' \
    --header 'Authorization: <EAS_TOKEN>' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "prompt":
        ...omitted
    }'

    Dalam kasus ini, --data-raw adalah badan permintaan.

    Python

    Kode contoh:

    import requests
    import json
    
    # Ganti <EAS_ENDPOINT> dan <EAS_TOKEN> dengan titik akhir dan token yang diperoleh di Langkah 1.
    service_url = "<EAS_ENDPOINT>"
    token = "<EAS_TOKEN>"
    
    if service_url[-1] == "/":
        service_url = service_url[:-1]
    
    # Badan permintaan. Konfigurasikan nilai prompt dalam muatan sebagai konten file JSON yang sesuai dengan alur kerja.
    payload = """{
        "prompt":
        ...omitted
    }"""
    payload = json.loads(payload)
    
    session = requests.session()
    session.headers.update({"Authorization": token})
      
    response = session.post(url=f'{service_url}/prompt', json=payload)
    if response.status_code != 200:
        raise Exception(response.content)
    
    data = response.json()
    print(data)

    Contoh respons:

    {
        "prompt_id": "021ebc5b-e245-4e37-8bd3-00f7b949****",
        "number": 5,
        "node_errors": {}
    }

    Anda dapat memperoleh Prompt ID dari hasil yang dikembalikan.

  3. Kirim permintaan untuk mendapatkan hasil inferensi.

    • Metode permintaan HTTP: GET

    • URL permintaan: <EAS_ENDPOINT>/history/<prompt_id>. Ganti <prompt_id> dengan prompt_id yang diperoleh pada langkah sebelumnya.

    • Header permintaan:

      Header

      Nilai

      Deskripsi

      Authorization

      <EAS_TOKEN>

      Kunci lisensi, yang diperoleh di Langkah 1.

    Kode contoh:

    cURL

    curl --location --request GET '<EAS_ENDPOINT>/history/<prompt_id>' \
         --header 'Authorization: <EAS_TOKEN>'

    Python

    import requests
    
    # Ganti <EAS_ENDPOINT> dan <EAS_TOKEN> dengan titik akhir dan token yang diperoleh di Langkah 1.
    # Ganti <prompt_id> dengan prompt_id yang diperoleh di Langkah 2.
    service_url = "<EAS_ENDPOINT>"
    token = "<EAS_TOKEN>"
    prompt_id = "<prompt_id>"
    
    if service_url[-1] == "/":
        service_url = service_url[:-1]
    
    session = requests.session()
    session.headers.update({"Authorization": token})
    
    response = session.get(url=f'{service_url}/history/{prompt_id}')
    
    if response.status_code != 200:
        raise Exception(response.content)
    
    data = response.json()
    print(data)

    Contoh respons:

    Klik untuk melihat contoh respons

    {
        "130bcd6b-5bb5-496c-9c8c-3a1359a0****": {
            "prompt": ...omitted,
            "outputs": {
                "9": {
                    "images": [
                        {
                            "filename": "ComfyUI_1712645398_18dba34d-df87-4735-a577-c63d5506a6a1_.png",
                            "subfolder": "",
                            "type": "output"
                        }
                    ]
                },
                "15": {
                    "images": [
                        {
                            "filename": "ComfyUI_1712645867_.webp",
                            "subfolder": "",
                            "type": "output"
                        }
                    ],
                    "animated": [
                        true
                    ]
                },
                "19": {
                    "gifs": [
                        {
                            "filename": "comfyUI_00002.mp4",
                            "subfolder": "",
                            "type": "output",
                            "format": "video/h264-mp4"
                        }
                    ]
                }
            },
            "status": {
                "status_str": "success",
                "completed": true,
                "messages": ...omitted,
            }
        }
    }
    

    outputs dalam contoh respons ini menyediakan citra, file webp, dan video mp4 yang dihasilkan oleh prompt. Anda dapat menemukan file-file ini berdasarkan nama file di direktori output dari penyimpanan yang dipasang.

Pemanggilan asinkron

Penting

Panggilan asinkron hanya mendukung path api_prompt. Parameter task_id adalah penanda kunci yang digunakan untuk mengidentifikasi permintaan dan hasil. Anda harus memberikan nilai unik untuk setiap permintaan agar sesuai dengan hasil yang sesuai dari antrian. Path permintaan adalah sebagai berikut:

{service_url}/api_prompt?task_id={nilai unik harus diberikan}

  1. Pada tab Inference Service, klik nama layanan target untuk membuka halaman Overview. Di bagian Basic Information, klik View Invocation Information. Di kotak dialog Invocation Information, pada tab Asynchronous Invocation, Anda dapat melihat titik akhir layanan dan token.

    image

  2. Dorong permintaan.

    Kode contoh:

    import requests,io,base64
    from PIL import Image, PngImagePlugin
    import json
    
    service_url = "<EAS_ENDPOINT>"
    token = "<EAS_TOKEN>"
    
    if service_url[-1] == "/":
        service_url = service_url[:-1]
    
    session = requests.session()
    session.headers.update({"Authorization":token})
    
    # Badan permintaan, yaitu konten file JSON alur kerja. Gunakan """ """ untuk mendefinisikannya sebagai string multi-baris. Jika tidak, Anda perlu mengubah huruf pertama nilai Boolean (true dan false) dalam JSON alur kerja menjadi kapital.
    payload = """{
        '3': 
        ...omitted
      }
      """
    payload = json.loads(payload)
    
    for i in range(5):
      # task_id adalah penanda kunci untuk mengidentifikasi permintaan dan hasil. Berikan nilai unik untuk setiap permintaan agar sesuai dengan hasil antrian berikutnya.
      response = session.post(url=f'{service_url}/api_prompt?task_id=txt2img_{i}', json=payload)
      if response.status_code != 200:
        exit(f"send request error:{response.content}")
      else:
        print(f"send {i} success, index is {response.content}")
  3. Berlangganan hasil.

    1. Jalankan perintah berikut untuk menginstal SDK eas_prediction.

      pip install eas_prediction  --user
    2. Jalankan kode berikut untuk mendapatkan hasil yang dikembalikan.

      from eas_prediction import QueueClient
      from urllib.parse import urlparse, urlunparse
      
      service_url     = "<EAS_ENDPOINT>"
      token           = "<EAS_TOKEN>"
      
      def parse_service_url(service_url):
          parsed = urlparse(service_url)
          service_domain = f"{parsed.scheme}://{parsed.netloc}"
          path_parts = [p for p in parsed.path.strip('/').split('/') if p]
          service_name = path_parts[-1]
          return service_domain, service_name
      
      service_domain, service_name = parse_service_url(service_url)
      print(f"service_domain: {service_domain}, service_name: {service_name}.")
          
      sink_queue = QueueClient(service_domain, f'{service_name}/sink')
      sink_queue.set_token(token)
      sink_queue.init()
      
      watcher = sink_queue.watch(0, 5, auto_commit=False)
      for x in watcher.run():
          if 'task_id' in x.tags:
              print('index {} task_id is {}'.format(x.index, x.tags['task_id']))
          print(f'index {x.index} data is {x.data}')
          sink_queue.commit(x.index)

      Contoh respons:

      index 42 task_id is txt2img_0
      index 42 data is b'[{"type": "executed", "data": {"node": "9", "output": {"images": [{"filename": "ComfyUI_1712647318_8e7f3c93-d2a8-4377-92d5-8eb552adc172_.png", "subfolder": "", "type": "output"}]}, "prompt_id": "c3c983b6-f92b-4dd5-b4dc-442db4d1736f"}}, {"type": "executed", "data": {"node": "15", "output": {"images": [{"filename": "ComfyUI_1712647895_.webp", "subfolder": "", "type": "output"}], "animated": [true]}, "prompt_id": "c3c983b6-f92b-4dd5-b4dc-442db4d1736f"}}, {"type": "executed", "data": {"node": "19", "output": {"gifs": [{"filename": "comfyUI_00001.mp4", "subfolder": "", "type": "output", "format": "video/h264-mp4"}]}, "prompt_id": "c3c983b6-f92b-4dd5-b4dc-442db4d1736f"}}, {"9": {"images": [{"filename": "ComfyUI_1712647318_8e7f3c93-d2a8-4377-92d5-8eb552adc172_.png", "subfolder": "", "type": "output"}]}, "15": {"images": [{"filename": "ComfyUI_1712647895_.webp", "subfolder": "", "type": "output"}], "animated": [true]}, "19": {"gifs": [{"filename": "comfyUI_00001.mp4", "subfolder": "", "type": "output", "format": "video/h264-mp4"}]}}]'
      index 43 task_id is txt2img_1
      index 43 data is b'[{"9": {"images": [{"filename": "ComfyUI_1712647318_8e7f3c93-d2a8-4377-92d5-8eb552adc172_.png", "subfolder": "", "type": "output"}]}, "15": {"images": [{"filename": "ComfyUI_1712647895_.webp", "subfolder": "", "type": "output"}], "animated": [true]}, "19": {"gifs": [{"filename": "comfyUI_00001.mp4", "subfolder": "", "type": "output", "format": "video/h264-mp4"}]}}]'
      index 44 task_id is txt2img_2
      index 44 data is b'[{"9": {"images": [{"filename": "ComfyUI_1712647318_8e7f3c93-d2a8-4377-92d5-8eb552adc172_.png", "subfolder": "", "type": "output"}]}, "15": {"images": [{"filename": "ComfyUI_1712647895_.webp", "subfolder": "", "type": "output"}], "animated": [true]}, "19": {"gifs": [{"filename": "comfyUI_00001.mp4", "subfolder": "", "type": "output", "format": "video/h264-mp4"}]}}]'
      index 45 task_id is txt2img_3
      index 45 data is b'[{"9": {"images": [{"filename": "ComfyUI_1712647318_8e7f3c93-d2a8-4377-92d5-8eb552adc172_.png", "subfolder": "", "type": "output"}]}, "15": {"images": [{"filename": "ComfyUI_1712647895_.webp", "subfolder": "", "type": "output"}], "animated": [true]}, "19": {"gifs": [{"filename": "comfyUI_00001.mp4", "subfolder": "", "type": "output", "format": "video/h264-mp4"}]}}]'
      index 46 task_id is txt2img_4
      index 46 data is b'[{"9": {"images": [{"filename": "ComfyUI_1712647318_8e7f3c93-d2a8-4377-92d5-8eb552adc172_.png", "subfolder": "", "type": "output"}]}, "15": {"images": [{"filename": "ComfyUI_1712647895_.webp", "subfolder": "", "type": "output"}], "animated": [true]}, "19": {"gifs": [{"filename": "comfyUI_00001.mp4", "subfolder": "", "type": "output", "format": "video/h264-mp4"}]}}]'

      Anda dapat melihat file hasil inferensi di direktori output dari penyimpanan yang dipasang.

Catatan

Citra atau video yang dihasilkan disimpan di direktori output yang dipasang. Hasil panggilan API mengembalikan nama file dan nama subdirektori. Untuk OSS, Anda harus menyusun path file lengkap untuk mengunduh file tersebut. Untuk informasi lebih lanjut, lihat Gunakan SDK Alibaba Cloud untuk mengunduh file dari OSS.

FAQ

Model dan node

1. Error WebUI: Missing model

Deskripsi masalah: Error berikut dilaporkan:

image.png

Solusi: Pemeriksaan ini tidak valid untuk ComfyUI yang diterapkan di PAI. Error runtime lebih diutamakan. Kami menyarankan Anda mencentang kotak pilihan Do not show this message again atau menonaktifkan validasi model di pengaturan.

image

2. Saya mengunggah model baru, tetapi tidak dapat menemukannya

Pertama, periksa apakah Anda menggunakan Serverless Edition, yang tidak mendukung pengunggahan model sendiri. Gunakan Standard Edition atau Cluster Edition sebagai gantinya. Jika Anda menggunakan versi yang didukung, lakukan langkah-langkah berikut:

  1. Pada halaman, klik PaiCustom dan pilih Load New Model.image

  2. Jika masih tidak berhasil, klik Restart Process.image

3. Pemuat model menampilkan "undefined"

Pertama, pastikan direktori model benar. Direktori yang diperlukan bergantung pada pemuat model.

Jika file model diperbarui setelah layanan dimulai, restart layanan.

4. Tidak dapat menemukan node

5. ComfyUI Manager gagal mengunduh model atau menginstal node

Kami menyarankan Anda tidak menggunakan ComfyUI Manager dalam penerapan ComfyUI di EAS. Hal ini karena konektivitas jaringan dapat gagal saat Anda mengunduh model langsung dari internet atau menginstal plug-in yang memerlukan pengambilan kode dari platform seperti GitHub.

Kami menyarankan Anda mengunggah file model atau node ke penyimpanan yang dipasang pada layanan. Untuk informasi lebih lanjut, lihat Gunakan model pihak ketiga dan instal node kustom (plug-in ComfyUI).

6. Bagaimana cara melihat daftar file model dan node (plug-in ComfyUI) yang tersedia?

  • File model: Lihat di node pemuat model yang sesuai. Misalnya, Anda dapat melihat file model yang tersedia di daftar drop-down Checkpoint loader.

  • Node: Untuk melihat node dari semua plug-in ComfyUI yang diinstal, klik kanan halaman WebUI dan klik Add Node dari menu pintasan.

Citra dan dependensi

1. Bagaimana cara menginstal paket wheel?

  1. Pastikan konfigurasi mount lengkap. Contoh berikut mengasumsikan bahwa path OSS Uri adalah oss://examplebucket/comfyui.image

  2. Unggah paket wheel ke oss://examplebucket/comfyui/models/whl di OSS yang dipasang. Jika folder whl tidak ada, buatlah.

  3. Dalam contoh ini, path mount OSS adalah /mnt/data. Tambahkan perintah pip install /mnt/data/models/whl/xxx.whl sebelum perintah run. Dalam perintah ini, /mnt/data adalah path mount OSS Anda dan xxx.whl adalah nama paket wheel Anda.

    image

2. Bagaimana cara memperbarui versi gambar dan tetap menyimpan model kustom yang diinstal?

Anda tidak dapat memperbarui gambar ComfyUI untuk versi Serverless. Namun, untuk versi lain dengan penyimpanan OSS atau NAS yang dipasang, model kustom Anda tetap disimpan. Hal ini memungkinkan Anda memperbarui Official Image dalam konfigurasi layanan tanpa memengaruhi model kustom Anda. Untuk melakukannya, lakukan langkah-langkah berikut:

  1. Pada halaman detail layanan, klik Update di pojok kanan atas.

    image

  2. Jika layanan diterapkan menggunakan metode berbasis skenario, beralihlah ke penerapan kustom. Di sebelah kanan, klik Service Configuration, edit file JSON, dan perbarui field image dari containers. Misalnya, ubah 1.9 dalam pai-eas/comfyui:1.9 ke versi yang diperlukan.

    image

  3. Di jendela pengeditan, klik Direct Update.

3. Library dependensi yang hilang dalam gambar

Instal dependensi yang hilang dengan mengonfigurasi library pihak ketiga. Langkah-langkahnya sebagai berikut:

  1. Pada halaman detail layanan, klik Update di pojok kanan atas.

    image

  2. Jika layanan diterapkan menggunakan metode berbasis skenario, beralihlah ke penerapan kustom. Di sebelah kanan, klik Environment Context. Di bagian More Configurations, temukan konfigurasi library pihak ketiga dan masukkan dependensi yang diperlukan dalam format yang ditentukan.

    image

    image

  3. Klik tombol Update di bagian bawah halaman untuk menyelesaikan pembaruan layanan.

Exception waktu proses

1. Halaman hang atau membutuhkan waktu terlalu lama untuk refresh

  • Refresh halaman, bersihkan cache browser, atau gunakan mode incognito atau privasi browser Anda untuk mengakses halaman.

  • Jika penyimpanan dipasang, bersihkan file di folder input, output, dan temp di direktori mount.

  • Coba restart layanan.

2. Alur kerja berjalan separuh jalan dan proses restart

Jika log instans berisi run.sh: line 54: 531285 Killed python -u main_run.py "$@", ini menunjukkan error kehabisan memori (OOM). Setelah error OOM terjadi, proses secara otomatis restart.

3. RuntimeError: CUDA error: out of memory

Error ini menunjukkan bahwa memori video telah melebihi batas. Jika Anda menggunakan model citra, kurangi resolusi citra atau ukuran batch. Jika Anda menggunakan model video, kurangi laju frame atau resolusi.

4. Error panggilan API: "url not found" atau "404 page not found"?

  1. Periksa apakah layanan yang diterapkan adalah Serverless Edition. Serverless Edition tidak mendukung panggilan API.

  2. Jika versi layanan benar, verifikasi bahwa URL tujuan API lengkap. Untuk panggilan sinkron, Anda harus menambahkan path /prompt.

5. Layanan selalu dalam status "Waiting" atau ComfyUI tidak dapat menghasilkan citra

Masalah ini biasanya disebabkan oleh spesifikasi resource yang tidak mencukupi. Periksa apakah gambar layanan dan spesifikasi resource dikonfigurasi dengan benar. Kami menyarankan menggunakan tipe GPU GU30, A10, atau T4. Tipe instans ml.gu7i.c16m60.1-gu30 adalah opsi hemat biaya.

6. Mengapa layanan berhenti secara otomatis setelah berjalan selama periode tertentu?

Jika layanan model di Serverless Edition tidak menerima permintaan atau tugas komputasi untuk periode yang lama, sistem dapat secara otomatis melepaskan resource-nya untuk mengurangi biaya.

Lainnya

1. Bagaimana cara memperpanjang periode validitas URL akses tanpa login?

Anda dapat menggunakan API untuk mendapatkan tautan akses web tanpa login dengan periode validitas yang ditentukan.

  1. Klik tautan DescribeServiceSignedUrl API untuk membuka halaman API.

  2. Pilih wilayah layanan.

image

  1. Masukkan wilayah tempat layanan berada dan nama layanan. Anda dapat memperoleh informasi ini dari halaman ikhtisar layanan EAS.

    image

  2. Parameter lainnya adalah sebagai berikut:

    • Tipe halaman: Pilih webview dari daftar drop-down.

    • Waktu kedaluwarsa: Untuk mengatur periode validitas panjang, masukkan 9007199254740991. Periode validitas maksimum saat ini adalah 12 jam.

      Jika tidak, masukkan nilai integer dalam detik.

    • Internal apakah ini tautan VPC: Jika ini bukan panggilan VPC, pilih false. Jika tidak, pilih true.

  3. Klik Initiate Call. SignedUrl dalam respons adalah tautan akses web tanpa login untuk layanan tersebut.

2. Efek akselerasi xFormers pada kecepatan pembuatan citra

xFormers adalah alat akselerasi open-source berbasis Transformer yang dapat secara signifikan mempersingkat waktu pembuatan citra dan video serta mengurangi penggunaan memori video. Secara default, akselerasi xFormers diaktifkan untuk penerapan citra ComfyUI. Efek akselerasi bergantung pada ukuran alur kerja. Peningkatan lebih signifikan untuk panggilan yang intensif GPU, terutama yang menggunakan kartu grafis NVIDIA.

3. Perbedaan utama antara EAS dan Function Compute dalam menerapkan Serverless Edition ComfyUI

  • EAS: Cocok untuk layanan stateful dan berjalan lama. Mendukung penerapan satu klik model sebagai layanan inferensi online atau aplikasi Web-AI dan mencakup fitur seperti skalabilitas elastis dan penyebaran biru-hijau. Misalnya, Anda dapat menerapkan ComfyUI menggunakan penerapan model berbasis skenario atau penerapan model kustom di EAS.

  • Function Compute: Berbasis arsitektur serverless, menyediakan keunggulan seperti penagihan bayar sesuai penggunaan dan skalabilitas elastis. Cocok untuk skenario yang memerlukan pembuatan citra berkualitas tinggi. Anda dapat menyesuaikan model ComfyUI dan menginstal plug-in. Misalnya, Anda dapat membuat aplikasi, memilih templat ComfyUI, dan mengatur item konfigurasi di konsol Function Compute 3.0.

4. Bagaimana cara mengganti bahasa default halaman WebUI?

  1. Pada halaman WebUI, klik tombol pengaturan image di pojok kiri bawah.

  2. Di kotak dialog Settings, atur bahasa di dua lokasi berikut. Setelah mengatur parameter, refresh halaman.

    • Di panel navigasi kiri, pilih Comfy. Di pengaturan wilayah kanan, pilih bahasa tujuan.image

    • Di panel navigasi kiri, pilih Language. Di bagian Locale kanan, pilih bahasa tujuan.image

Lampiran

Pengenalan prinsip kerja layanan Edisi Kluster

Gambar berikut menunjukkan prinsip implementasi:

image
  • Layanan Edisi Kluster dirancang untuk skenario multi-pengguna. Layanan ini memisahkan klien dari instans inferensi backend, yang memungkinkan banyak pengguna berbagi instans inferensi backend. Hal ini meningkatkan pemanfaatan instans dan mengurangi biaya inferensi.

  • Setiap pengguna memiliki lingkungan backend dan direktori kerja independen, yang memungkinkan berbagi GPU dan manajemen file yang efisien.

  • Proxy mengelola proses klien dan instans inferensi. Semua operasi pengguna diproses dalam proses mereka sendiri, dan operasi file dibatasi pada direktori publik dan pribadi. Hal ini secara efektif mengisolasi direktori kerja antar pengguna. Saat pengguna perlu memproses permintaan, proxy menemukan instans idle yang tersedia dari backend untuk memproses permintaan inferensi.