日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

AI視頻生成-ComfyUI部署

EAS提供了場景化部署方式,您只需配置幾個參數,即可一鍵部署基于ComfyUIStable Video Diffusion模型的AI視頻生成服務,幫助您完成社交平臺短視頻內容生成、動畫制作等任務。本文為您介紹如何基于ComfyUI鏡像部署服務和幾種常用的調用方式。

背景信息

隨著AIGC的廣泛應用,AI視頻生成已成為當前熱門應用之一。目前市面上有許多開源視頻生成大模型可供選擇,它們在不同領域展現了各自獨特的性能。與此同時,AIGC開源工具ComfyUI也迅速在市場上嶄露頭角。作為一個基于節點流程式的AIGC生成工具WebUI,ComfyUIAIGC流程拆分成工作節點,實現了精準的工作流定制和可復現性。您可以一鍵部署基于ComfyUIAI視頻生成服務,支持以下四種版本:

  • 標準版:僅適用于單用戶使用WebUI,或使用一個實例調用API場景。支持以下兩種調用方式:

    • WebUI:請求發送時,會繞過EAS接口,前端直接將請求傳遞給后端服務器,所有請求均由同一個后端實例進行處理。建議您只部署1個實例,當您需要多臺實例時,需選擇集群版。

    • API:通過EAS接口發送請求給后端實例進行處理。建議您只部署1個實例,當您需要多臺實例時,需選擇API版本。

  • API版:系統將自動轉換服務為異步模式,適用于高并發場景。該模式僅支持API異步調用。基于其異步特性,系統會創建隊列服務實例,因此需要分配額外的CPU實例。

  • 集群版:適合多用戶同時在WebUI頁面進行操作。僅支持通過WebUI進行調用,不提供API服務。主要適用于設計組或教學場景,通過分時復用的設計來提升推理集群的利用率,降低成本。由于Proxy負責處理WebUI請求,因此需要分配額外的CPU實例。參考集群版服務原理介紹,了解集群版服務的實現原理。該版本優勢如下:

    • 系統為每個用戶提供獨立的后端環境。當開啟了多個實例時,單個用戶的任務會按順序執行,而多用戶環境下的任務則在不同實例之間分配,實現高效的GPU共享。

    • 系統為每個用戶分配獨立的工作目錄,便于管理和存儲模型、輸出圖像或視頻等文件。

  • Serverless版:目前,僅華東2(上海)、華東1(杭州)地域支持部署Serverless版服務。 Serverless版本服務部署完全免費,只根據使用出圖的時長進行計費,并會根據您的服務請求量自動彈性伸縮。

具體使用流程如下:

  1. 部署EAS服務

    根據您的具體使用場景,選擇部署標準版、API版、集群版或Serverless版的服務。

  2. 調用EAS服務

    根據部署的服務版本,支持以下三種調用方式:

    • 通過WebUI調用EAS服務

      使用WebUI發送服務請求,僅標準版、集群版和Serverless版服務支持使用該方式。

    • 在線調試EAS服務

      EAS的在線調試頁面發送同步調用請求,只有標準版服務支持同步調用功能。

    • 通過API調用EAS服務

      只有標準版和API版服務支持通過API發送服務請求。其中,標準版服務僅支持同步調用,而API版服務僅支持異步調用。

前提條件

在部署微調模型、安裝ComfyUI插件、使用API調用服務時,您必須掛載NASOSS存儲,以便上傳微調模型、插件和獲取推理結果。請提前準備NASOSS存儲空間:

  • 已創建OSS存儲空間和空目錄,例如:oss://bucket-test/data-oss/,其中:bucket-testOSS存儲空間名稱;data-oss為該存儲空間下的空目錄。關于如何創建OSS存儲空間,請參見創建存儲空間;關于如何創建空目錄,請參見管理目錄

  • 已創建NAS文件系統和空目錄。具體操作,請參見創建文件系統

部署EAS服務

支持以下兩種部署方式:

方式一:場景化模型部署(推薦)

  1. 登錄PAI控制臺,在頁面上方選擇目標地域,并在右側選擇目標工作空間,然后單擊進入EAS

  2. 模型在線服務(EAS)頁面,單擊部署服務,在場景化模型部署區域,單擊AI視頻生成-ComfyUI部署

  3. AI視頻生成-ComfyUI部署頁面,配置以下關鍵參數。

    參數

    描述

    基本信息

    服務名稱

    自定義模型服務名稱。

    版本選擇

    支持選擇以下版本:

    • 標準版:適用于單用戶使用WebUI或使用一個實例調用API場景。支持通過WebUI生成視頻,也可通過API進行調用。

    • API:系統將自動轉換服務為異步模式,適用于高并發場景。僅支持通過API進行調用。

    • 集群版WebUI:適合多用戶同時在WebUI頁面進行操作。僅支持通過WebUI進行調用,不提供API服務。關于該版本的實現原理介紹,請參見集群版服務原理介紹

    • Serverless:Serverless版本服務部署完全免費,只根據使用出圖的時長進行計費。

    更多關于每個版本的使用場景說明,請參見背景信息

    模型配置

    當部署微調模型、安裝ComfyUI插件,或選擇API標準版并通過API進行調用時,您需要單擊添加按鈕,進行模型配置,以便上傳微調模型、插件和獲取推理結果。支持以下幾種配置類型:

    • 對象存儲(OSS):單擊image選擇已創建的OSS存儲目錄。

    • 文件存儲(NAS):配置NAS掛載點和NAS源路徑。

    后續,您可以將自定義模型和ComfyUI插件上傳至指定的OSSNAS路徑,以便加載和使用這些資源。具體操作,請參見如何掛載自定義模型和ComfyUI插件?

    資源配置

    實例數

    當版本選擇標準版時,建議將實例數配置為1。

    資源配置選擇

    資源規格推薦使用GU30、A10T4卡型。系統默認選擇GPU > ml.gu7i.c16m60.1-gu30,性價比高。

    說明

    ComfyUI僅支持單卡(單機單卡或多機單卡)運行,不支持多卡并發操作。

  4. 單擊部署

方式二:自定義模型部署

  1. 登錄PAI控制臺,在頁面上方選擇目標地域,并在右側選擇目標工作空間,然后單擊進入EAS

  2. 單擊部署服務,然后在自定義模型部署區域,單擊自定義部署

  3. 自定義部署頁面,配置以下關鍵參數。

    參數

    描述

    基本信息

    服務名稱

    自定義服務名稱。本案例使用的示例值為:comfyui_svd_demo

    環境信息

    部署方式

    選擇鏡像部署,并選中開啟Web應用復選框。

    鏡像配置

    官方鏡像列表中選擇comfyui>comfyui:1.7,其中:

    • x.x:表示標準版。

    • x.x-api:表示API版。

    • x.x-cluster:表示集群版。

    說明
    • 由于版本迭代迅速,部署時鏡像版本選擇最高版本即可。

    • 更多關于每個版本的使用場景說明,請參見背景信息

    模型配置

    當部署微調模型、安裝ComfyUI插件,或選擇API標準版并通過API進行調用時,您需要進行模型配置,以便上傳微調模型、插件和獲取推理結果。支持以下幾種配置類型:

    • OSS

      • OSS:單擊image選擇已創建的OSS存儲目錄。例如oss://bucket-test/data-oss/

      • 掛載路徑:配置為/code/data-oss,表示將您配置的OSS文件目錄掛載到鏡像的/code/data-oss路徑下。

    • 通用型NAS

      • 選擇文件系統:選擇NAS文件系統。

      • 文件系統掛載點:選擇NAS掛載點,EAS服務通過掛載點來訪問NAS文件系統。

      • 文件系統路徑:需要掛載的NAS中的源路徑,即NAS實例內部的文件系統路徑。例如/data-oss

      • 掛載路徑:配置為/code/data-oss,表示將您配置的NAS源路徑掛載到鏡像的/code/data-oss路徑下。

    后續,您可以將自定義模型和ComfyUI插件上傳至指定的OSSNAS路徑,以便加載和使用這些資源。具體操作,請參見如何掛載自定義模型和ComfyUI插件?

    運行命令

    • 配置鏡像版本后,系統自動配置運行命令python main.py --listen --port 8000

    • 端口號為:8000。

    當您進行模型配置后,您需要在運行命令中增加--data-dir掛載目錄,其中掛載目錄需要與模型配置中的掛載路徑一致。例如python main.py --listen --port 8000 --data-dir /code/data-oss

    資源部署

    資源類型

    選擇公共資源

    實例數

    當鏡像版本標準版時,建議將實例數配置為1。

    部署資源

    資源規格必須選擇GPU類型,推薦使用ml.gu7i.c16m60.1-gu30(性價比最高)。如庫存不足可選擇ecs.gn6i-c16g1.4xlarge

    說明

    ComfyUI僅支持單卡(單機單卡或多機單卡)運行,不支持多卡并發操作。

  4. 單擊部署

    服務狀態運行中時,表明服務已成功部署。

調用EAS服務

通過WebUI調用EAS服務

通過WebUI,您可以調用標準版、集群版和Serverless版的EAS服務。在標準版服務中,所有請求都由同一個后端實例處理。而集群版服務則適合多用戶同時操作,它能夠在多個實例間分配并處理各用戶的任務。具體操作步驟如下:

  1. 單擊目標服務的服務方式列下的查看Web應用

    說明

    訪問WebUI時,大約需要1分鐘的加載時間,之后您將能看到完整的初始工作流界面。

  2. WebUI頁面的默認語言切換為中文

  3. WebUI頁面進行模型推理驗證。

    根據您自己的業務需要,選擇文生圖的模型和圖生視頻的模型,本方案使用默認配置。然后在CLIP文本編碼器中輸入Prompts,例如:Rocket takes off from the ground, fire, sky, airplane,單擊添加提示詞隊列, 等待工作流運行完成即可獲得AI生成的視頻。85453c9fcadd222fbb087c5acddb6e90.png

  4. 右鍵單擊生成的視頻,選擇保存圖像,即可將生成的視頻保存到本地。image.png

    生成的視頻示例如下所示:

在線調試EAS服務

僅標準版服務支持在線調試,具體操作步驟如下:

  1. 生成請求體。具體操作,請參見如何生成請求體

  2. 模型在線服務(EAS)頁面,單擊目標服務操作列下的在線調試,進入在線調試頁面。

  3. 發送POST請求,獲取Prompt ID。

    1. 在調試頁面的在線調試請求參數區域的Body處填寫已準備好的請求體。并在請求URL文本編輯框中添加/promptimage

    2. 單擊發送請求,即可在調試信息區域查看預測結果,示例如下。image

  4. 發送GET請求,根據Prompt ID獲取推理結果。

    1. 在線調試請求參數區域中,將請求方法修改為GET,并在文本框中配置/history/<prompt id>,示例如下。image

      其中<prompt id>需要替換為步驟3獲取的Prompt ID。

    2. 單擊發送請求,即可獲取推理結果。

      您可以在掛載存儲的output目錄中,查看生成的推理結果。

通過API調用EAS服務

標準版和API版服務支持API調用。API調用支持同步調用和異步調用兩種方式:

  • 同步調用

    標準版服務僅支持同步調用方式,即客戶端發送一個請求,同步等待結果返回。

  • 異步調用

    API版服務僅支持異步調用方式,即客戶端使用EAS的隊列服務向輸入隊列發送請求,并通過訂閱的方式從輸出隊列查詢結果。

由于ComfyUI本身具有異步隊列系統,即使發起同步調用,實質上也是異步進行的。即當用戶提交請求后,系統會返回一個Prompt ID,您需要使用該ID輪詢以獲取推理結果。

同步調用

  1. 查看調用信息。

    1. 在服務列表中,單擊標準版服務名稱,然后在基本信息區域,單擊查看調用信息

    2. 調用信息對話框的公網地址調用頁簽,獲取服務訪問地址和Token。image

  2. 獲取Prompt ID。

    1. 生成請求體。具體操作,請參見如何生成請求體

    2. 發送請求,獲取Prompt ID。

      支持以下兩種方式:

      Curl

      • HTTP請求方式:POST

      • 請求URL:<service_url>/prompt

      • 請求頭部:

        頭部

        描述

        Authorization

        <token>

        授權密鑰

        Content-Type

        application/json

        指定請求體格式

      • 代碼示例

        curl --location --request POST '<service_url>/prompt' \
        --header 'Authorization: <token>' \
        --header 'Content-Type: application/json' \
        --data-raw '{
            "prompt":
            ...省略
        }'

        其中關鍵配置項如下:

        配置項

        描述

        <service_url>

        替換為步驟1中獲取的服務訪問地址。您需要將訪問地址末尾的/刪除。例如http://comfyui****.175805416243****.cn-beijing.pai-eas.aliyuncs.com

        <token>

        替換為步驟1中獲取的Token。例如ZGJmNzcwYjczODE1MmVlNWY1NTNiNGYxNDkzODI****NzU2NTFiOA==

        data-raw

        配置為請求體,例如:

        重要

        請求體中的布爾值(truefalse)首字母需要小寫。

        單擊此處查看請求體示例

        {
            "prompt": {
                "3": {
                    "inputs": {
                        "seed": 367490676387803,
                        "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采樣器"
                    }
                },
                "4": {
                    "inputs": {
                        "ckpt_name": "LandscapeBING_v10.safetensors"
                    },
                    "class_type": "CheckpointLoaderSimple",
                    "_meta": {
                        "title": "Checkpoint加載器(簡易)"
                    }
                },
                "5": {
                    "inputs": {
                        "width": 720,
                        "height": 1280,
                        "batch_size": 1
                    },
                    "class_type": "EmptyLatentImage",
                    "_meta": {
                        "title": "空Latent"
                    }
                },
                "6": {
                    "inputs": {
                        "text": "Rocket takes off from the ground, fire,sky, airplane",
                        "clip": [
                            "4",
                            1
                        ]
                    },
                    "class_type": "CLIPTextEncode",
                    "_meta": {
                        "title": "CLIP文本編碼器"
                    }
                },
                "7": {
                    "inputs": {
                        "text": "",
                        "clip": [
                            "4",
                            1
                        ]
                    },
                    "class_type": "CLIPTextEncode",
                    "_meta": {
                        "title": "CLIP文本編碼器"
                    }
                },
                "8": {
                    "inputs": {
                        "samples": [
                            "3",
                            0
                        ],
                        "vae": [
                            "4",
                            2
                        ]
                    },
                    "class_type": "VAEDecode",
                    "_meta": {
                        "title": "VAE解碼"
                    }
                },
                "9": {
                    "inputs": {
                        "filename_prefix": "ComfyUI",
                        "images": [
                            "8",
                            0
                        ]
                    },
                    "class_type": "SaveImage",
                    "_meta": {
                        "title": "保存圖像"
                    }
                },
                "13": {
                    "inputs": {
                        "seed": 510424455529432,
                        "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采樣器"
                    }
                },
                "14": {
                    "inputs": {
                        "samples": [
                            "13",
                            0
                        ],
                        "vae": [
                            "18",
                            2
                        ]
                    },
                    "class_type": "VAEDecode",
                    "_meta": {
                        "title": "VAE解碼"
                    }
                },
                "15": {
                    "inputs": {
                        "filename_prefix": "ComfyUI",
                        "fps": 10,
                        "lossless": false,
                        "quality": 85,
                        "method": "default",
                        "images": [
                            "14",
                            0
                        ]
                    },
                    "class_type": "SaveAnimatedWEBP",
                    "_meta": {
                        "title": "保存WEBP"
                    }
                },
                "16": {
                    "inputs": {
                        "width": 512,
                        "height": 768,
                        "video_frames": 35,
                        "motion_bucket_id": 140,
                        "fps": 15,
                        "augmentation_level": 0.15,
                        "clip_vision": [
                            "18",
                            1
                        ],
                        "init_image": [
                            "8",
                            0
                        ],
                        "vae": [
                            "18",
                            2
                        ]
                    },
                    "class_type": "SVD_img2vid_Conditioning",
                    "_meta": {
                        "title": "SVD_圖像到視頻_條件"
                    }
                },
                "17": {
                    "inputs": {
                        "min_cfg": 1,
                        "model": [
                            "18",
                            0
                        ]
                    },
                    "class_type": "VideoLinearCFGGuidance",
                    "_meta": {
                        "title": "線性CFG引導"
                    }
                },
                "18": {
                    "inputs": {
                        "ckpt_name": "svd_xt_image_decoder.safetensors"
                    },
                    "class_type": "ImageOnlyCheckpointLoader",
                    "_meta": {
                        "title": "Checkpoint加載器(僅圖像)"
                    }
                },
                "19": {
                    "inputs": {
                        "frame_rate": 10,
                        "loop_count": 0,
                        "filename_prefix": "comfyUI",
                        "format": "video/h264-mp4",
                        "pix_fmt": "yuv420p",
                        "crf": 20,
                        "save_metadata": true,
                        "pingpong": false,
                        "save_output": true,
                        "images": [
                            "14",
                            0
                        ]
                    },
                    "class_type": "VHS_VideoCombine",
                    "_meta": {
                        "title": "合并為視頻"
                    }
                }
            }
        }

      Python

      代碼示例如下:

      import requests
      
      url = "<service_url>/prompt"
      
      payload = {
          "prompt":
          ...省略
      }
      
      session = requests.session()
      session.headers.update({"Authorization":"<token>"})
      
      
      response = session.post(url=f'{url}', json=payload)
      if response.status_code != 200:
          raise Exception(response.content)
      
      data = response.json()
      print(data)

      其中關鍵配置項如下:

      配置項

      描述

      <service_url>

      替換為步驟1中獲取的服務訪問地址。您需要將訪問地址末尾的/刪除,例如http://comfyui****.175805416243****.cn-beijing.pai-eas.aliyuncs.com

      <token>

      替換為步驟1中獲取的Token。ZGJmNzcwYjczODE1MmVlNWY1NTNiNGYxNDkzODI****NzU2NTFiOA==

      payload

      配置為請求體,例如:

      重要

      請求體中的布爾值(TrueFalse)首字母需要大寫。

      單擊此處查看請求體示例

      {
          "prompt": {
              "3": {
                  "inputs": {
                      "seed": 367490676387803,
                      "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采樣器"
                  }
              },
              "4": {
                  "inputs": {
                      "ckpt_name": "LandscapeBING_v10.safetensors"
                  },
                  "class_type": "CheckpointLoaderSimple",
                  "_meta": {
                      "title": "Checkpoint加載器(簡易)"
                  }
              },
              "5": {
                  "inputs": {
                      "width": 720,
                      "height": 1280,
                      "batch_size": 1
                  },
                  "class_type": "EmptyLatentImage",
                  "_meta": {
                      "title": "空Latent"
                  }
              },
              "6": {
                  "inputs": {
                      "text": "Rocket takes off from the ground, fire,sky, airplane",
                      "clip": [
                          "4",
                          1
                      ]
                  },
                  "class_type": "CLIPTextEncode",
                  "_meta": {
                      "title": "CLIP文本編碼器"
                  }
              },
              "7": {
                  "inputs": {
                      "text": "",
                      "clip": [
                          "4",
                          1
                      ]
                  },
                  "class_type": "CLIPTextEncode",
                  "_meta": {
                      "title": "CLIP文本編碼器"
                  }
              },
              "8": {
                  "inputs": {
                      "samples": [
                          "3",
                          0
                      ],
                      "vae": [
                          "4",
                          2
                      ]
                  },
                  "class_type": "VAEDecode",
                  "_meta": {
                      "title": "VAE解碼"
                  }
              },
              "9": {
                  "inputs": {
                      "filename_prefix": "ComfyUI",
                      "images": [
                          "8",
                          0
                      ]
                  },
                  "class_type": "SaveImage",
                  "_meta": {
                      "title": "保存圖像"
                  }
              },
              "13": {
                  "inputs": {
                      "seed": 510424455529432,
                      "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采樣器"
                  }
              },
              "14": {
                  "inputs": {
                      "samples": [
                          "13",
                          0
                      ],
                      "vae": [
                          "18",
                          2
                      ]
                  },
                  "class_type": "VAEDecode",
                  "_meta": {
                      "title": "VAE解碼"
                  }
              },
              "15": {
                  "inputs": {
                      "filename_prefix": "ComfyUI",
                      "fps": 10,
                      "lossless": False,
                      "quality": 85,
                      "method": "default",
                      "images": [
                          "14",
                          0
                      ]
                  },
                  "class_type": "SaveAnimatedWEBP",
                  "_meta": {
                      "title": "保存WEBP"
                  }
              },
              "16": {
                  "inputs": {
                      "width": 512,
                      "height": 768,
                      "video_frames": 35,
                      "motion_bucket_id": 140,
                      "fps": 15,
                      "augmentation_level": 0.15,
                      "clip_vision": [
                          "18",
                          1
                      ],
                      "init_image": [
                          "8",
                          0
                      ],
                      "vae": [
                          "18",
                          2
                      ]
                  },
                  "class_type": "SVD_img2vid_Conditioning",
                  "_meta": {
                      "title": "SVD_圖像到視頻_條件"
                  }
              },
              "17": {
                  "inputs": {
                      "min_cfg": 1,
                      "model": [
                          "18",
                          0
                      ]
                  },
                  "class_type": "VideoLinearCFGGuidance",
                  "_meta": {
                      "title": "線性CFG引導"
                  }
              },
              "18": {
                  "inputs": {
                      "ckpt_name": "svd_xt_image_decoder.safetensors"
                  },
                  "class_type": "ImageOnlyCheckpointLoader",
                  "_meta": {
                      "title": "Checkpoint加載器(僅圖像)"
                  }
              },
              "19": {
                  "inputs": {
                      "frame_rate": 10,
                      "loop_count": 0,
                      "filename_prefix": "comfyUI",
                      "format": "video/h264-mp4",
                      "pix_fmt": "yuv420p",
                      "crf": 20,
                      "save_metadata": True,
                      "pingpong": False,
                      "save_output": True,
                      "images": [
                          "14",
                          0
                      ]
                  },
                  "class_type": "VHS_VideoCombine",
                  "_meta": {
                      "title": "合并為視頻"
                  }
              }
          }
      }

      返回結果示例如下:

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

      您可以從返回結果中獲取Prompt ID。

  3. 發送請求,獲取推理結果。

    支持以下兩種方式:

    Curl

    • HTTP請求方式:GET

    • 請求URL:<service_url>/history/<prompt_id>

    • 請求頭部:

    • 頭部

      描述

      Authorization

      <token>

      授權密鑰

    • 代碼示例:

      curl --location --request GET '<service_url>/history/<prompt_id>' \
           --header 'Authorization: <token>'

      其中關鍵配置項如下:

      配置項

      描述

      <service_url>

      替換為步驟1中獲取的服務訪問地址。您需要將訪問地址末尾的/刪除。例如http://comfyui****.175805416243****.cn-beijing.pai-eas.aliyuncs.com

      <token>

      替換為步驟1中獲取的Token。例如ZGJmNzcwYjczODE1MmVlNWY1NTNiNGYxNDkzODI****NzU2NTFiOA==

      <prompt_id>

      替換為步驟2中獲取的prompt_id。

    Python

    代碼示例如下:

    import requests
    
    # 構造請求URL。
    url = "<service_url>/history/<prompt_id>"
    
    session = requests.session()
    session.headers.update({"Authorization":"<token>"})
    
    response = session.get(url=f'{url}')
    
    if response.status_code != 200:
        raise Exception(response.content)
    
    data = response.json()
    print(data)

    其中關鍵配置項如下:

    配置項

    描述

    <service_url>

    替換為步驟1中獲取的服務訪問地址。您需要將訪問地址末尾的/刪除,例如http://comfyui****.175805416243****.cn-beijing.pai-eas.aliyuncs.com

    <token>

    替換為步驟1中獲取的Token。例如ZGJmNzcwYjczODE1MmVlNWY1NTNiNGYxNDkzODI****NzU2NTFiOA==

    <prompt_id>

    替換為步驟2中獲取的prompt_id。

    返回結果示例如下:

    {
        "130bcd6b-5bb5-496c-9c8c-3a1359a0****": {
            "prompt": ...省略,
            "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": ...省略,
            }
        }
    }
    

    在本示例返回的outputs中提供了prompt生成的圖像、webp文件和mp4視頻,您可以在掛載存儲的output目錄中,根據文件名稱來查找這些文件。

異步調用

API版的服務支持異步調用,且僅支持api_prompt路徑。

  1. 查看調用信息。

    單擊API版服務的服務方式列下的調用信息,在調用信息對話框的異步調用頁簽,查看服務訪問地址和Token。image

  2. 推送請求。

    代碼示例如下:

    import requests,io,base64
    from PIL import Image, PngImagePlugin
    
    url = "<service_url>"
    session = requests.session()
    session.headers.update({"Authorization":"<token>"})
    
    work_flow = {
        '3': 
        ...省略
      }
    
    for i in range(5):
      payload = work_flow
      response = session.post(url=f'{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}")

    其中關鍵配置項如下:

    配置項

    描述

    <service_url>

    替換為步驟1獲取的服務訪問地址。您需要將訪問地址末尾的/刪除,例如http://175805416243****.cn-beijing.pai-eas.aliyuncs.com/api/predict/comfyui_api

    <token>

    替換為步驟1獲取的Token。例如ZTJhM****TBhMmJkYjM3M2U0NjM1NGE3OGNlZGEyZTdjYjlm****Nw==

    work_flow

    配置為工作流對應的JSON文件內容,示例如下。如何獲取工作流JSON文件,請參見如何生成請求體

    重要

    文件中的布爾值(TrueFalse)首字母需要大寫。

    單擊此處查看JSON文件示例

    {
      "3": {
        "inputs": {
          "seed": 1021224598837526,
          "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采樣器"
        }
      },
      "4": {
        "inputs": {
          "ckpt_name": "LandscapeBING_v10.safetensors"
        },
        "class_type": "CheckpointLoaderSimple",
        "_meta": {
          "title": "Checkpoint加載器(簡易)"
        }
      },
      "5": {
        "inputs": {
          "width": 720,
          "height": 1280,
          "batch_size": 1
        },
        "class_type": "EmptyLatentImage",
        "_meta": {
          "title": "空Latent"
        }
      },
      "6": {
        "inputs": {
          "text": "Rocket takes off from the ground, fire, sky, airplane",
          "clip": [
            "4",
            1
          ]
        },
        "class_type": "CLIPTextEncode",
        "_meta": {
          "title": "CLIP文本編碼器"
        }
      },
      "7": {
        "inputs": {
          "text": "",
          "clip": [
            "4",
            1
          ]
        },
        "class_type": "CLIPTextEncode",
        "_meta": {
          "title": "CLIP文本編碼器"
        }
      },
      "8": {
        "inputs": {
          "samples": [
            "3",
            0
          ],
          "vae": [
            "4",
            2
          ]
        },
        "class_type": "VAEDecode",
        "_meta": {
          "title": "VAE解碼"
        }
      },
      "9": {
        "inputs": {
          "filename_prefix": "ComfyUI",
          "images": [
            "8",
            0
          ]
        },
        "class_type": "SaveImage",
        "_meta": {
          "title": "保存圖像"
        }
      },
      "13": {
        "inputs": {
          "seed": 1072245043382649,
          "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采樣器"
        }
      },
      "14": {
        "inputs": {
          "samples": [
            "13",
            0
          ],
          "vae": [
            "18",
            2
          ]
        },
        "class_type": "VAEDecode",
        "_meta": {
          "title": "VAE解碼"
        }
      },
      "15": {
        "inputs": {
          "filename_prefix": "ComfyUI",
          "fps": 10,
          "lossless": False,
          "quality": 85,
          "method": "default",
          "images": [
            "14",
            0
          ]
        },
        "class_type": "SaveAnimatedWEBP",
        "_meta": {
          "title": "保存WEBP"
        }
      },
      "16": {
        "inputs": {
          "width": 512,
          "height": 768,
          "video_frames": 35,
          "motion_bucket_id": 140,
          "fps": 15,
          "augmentation_level": 0.15,
          "clip_vision": [
            "18",
            1
          ],
          "init_image": [
            "8",
            0
          ],
          "vae": [
            "18",
            2
          ]
        },
        "class_type": "SVD_img2vid_Conditioning",
        "_meta": {
          "title": "SVD_圖像到視頻_條件"
        }
      },
      "17": {
        "inputs": {
          "min_cfg": 1,
          "model": [
            "18",
            0
          ]
        },
        "class_type": "VideoLinearCFGGuidance",
        "_meta": {
          "title": "線性CFG引導"
        }
      },
      "18": {
        "inputs": {
          "ckpt_name": "svd_xt_image_decoder.safetensors"
        },
        "class_type": "ImageOnlyCheckpointLoader",
        "_meta": {
          "title": "Checkpoint加載器(僅圖像)"
        }
      },
      "19": {
        "inputs": {
          "frame_rate": 10,
          "loop_count": 0,
          "filename_prefix": "comfyUI",
          "format": "video/h264-mp4",
          "pix_fmt": "yuv420p",
          "crf": 20,
          "save_metadata": True,
          "pingpong": False,
          "save_output": True,
          "images": [
            "14",
            0
          ]
        },
        "class_type": "VHS_VideoCombine",
        "_meta": {
          "title": "合并為視頻"
        }
      }
    }
  3. 訂閱結果。

    1. 執行以下命令安裝eas_prediction SDK。

      pip install eas_prediction  --user
    2. 執行以下代碼,獲取返回結果。

      from eas_prediction import QueueClient
      
      sink_queue = QueueClient('<service_domain>', '<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)
      

      其中關鍵配置說明如下:

      配置項

      描述

      <service_domain>

      請替換為步驟1查詢的服務訪問地址中的調用信息。例如139699392458****.cn-hangzhou.pai-eas.aliyuncs.com

      <service_name>

      請替換為EAS服務名稱。

      <token>

      請替換為步驟1查詢的Token。

      返回結果示例如下:

      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"}]}}]'

      您可以在掛載存儲的output目錄中,查看推理結果文件。

相關文檔

  • ComfyUIAPI版本啟用了異步隊列,關于異步調用的原理介紹,請參見部署異步推理服務

  • 通過EAS,您還可以完成以下場景化部署:

    • 部署支持WebUIAPI調用的LLM大語言模型,并在部署LLM應用后,利用LangChain框架集成企業知識庫,實現智能問答和自動化功能。詳情請參見5分鐘使用EAS一鍵部署LLM大語言模型應用

    • 部署集成了大語言模型(LLM)和檢索增強生成(RAG)技術的對話系統服務,適用于問答、摘要生成和依賴外部知識的自然語言處理任務。詳情請參見大模型RAG對話系統

附錄

如何生成請求體

您需要在WebUI頁面設置滿足業務需求的工作流,然后構建相應的請求體。具體操作步驟如下:

  1. 模型在線服務(EAS)頁面,單擊目標服務的服務方式列下的查看Web應用,進入WebUI頁面。

    說明

    訪問WebUI時,大約需要1分鐘的加載時間,之后您將能看到完整的初始工作流界面。

  2. WebUI頁面,單擊image按鈕,并在Settings對話框中選中啟用開發模式選項復選框。image

  3. WebUI頁面,根據您的業務需求配置工作流。

    您可以在Checkpoint加載器區域選擇模型,在CLIP文本編碼器中輸入正向和反向提示詞、調整采樣器配置等。完成這些操作后,單擊添加提示詞隊列以獲取AI生成的視頻,并確保所有配置都符合您的需求。

  4. 確定工作流符合預期后,請單擊保存(API格式),下載該工作流對應的JSON文件。image

    其中:

    • 同步調用和在線調試的請求體需要將下載的JSON文件內容置于prompt鍵下進行包裝。例如,上述工作流對應的請求體為:

      {
          "prompt": {
              "3": {
                  "inputs": {
                      "seed": 367490676387803,
                      "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采樣器"
                  }
              },
              "4": {
                  "inputs": {
                      "ckpt_name": "LandscapeBING_v10.safetensors"
                  },
                  "class_type": "CheckpointLoaderSimple",
                  "_meta": {
                      "title": "Checkpoint加載器(簡易)"
                  }
              },
              "5": {
                  "inputs": {
                      "width": 720,
                      "height": 1280,
                      "batch_size": 1
                  },
                  "class_type": "EmptyLatentImage",
                  "_meta": {
                      "title": "空Latent"
                  }
              },
              "6": {
                  "inputs": {
                      "text": "Rocket takes off from the ground, fire,sky, airplane",
                      "clip": [
                          "4",
                          1
                      ]
                  },
                  "class_type": "CLIPTextEncode",
                  "_meta": {
                      "title": "CLIP文本編碼器"
                  }
              },
              "7": {
                  "inputs": {
                      "text": "",
                      "clip": [
                          "4",
                          1
                      ]
                  },
                  "class_type": "CLIPTextEncode",
                  "_meta": {
                      "title": "CLIP文本編碼器"
                  }
              },
              "8": {
                  "inputs": {
                      "samples": [
                          "3",
                          0
                      ],
                      "vae": [
                          "4",
                          2
                      ]
                  },
                  "class_type": "VAEDecode",
                  "_meta": {
                      "title": "VAE解碼"
                  }
              },
              "9": {
                  "inputs": {
                      "filename_prefix": "ComfyUI",
                      "images": [
                          "8",
                          0
                      ]
                  },
                  "class_type": "SaveImage",
                  "_meta": {
                      "title": "保存圖像"
                  }
              },
              "13": {
                  "inputs": {
                      "seed": 510424455529432,
                      "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采樣器"
                  }
              },
              "14": {
                  "inputs": {
                      "samples": [
                          "13",
                          0
                      ],
                      "vae": [
                          "18",
                          2
                      ]
                  },
                  "class_type": "VAEDecode",
                  "_meta": {
                      "title": "VAE解碼"
                  }
              },
              "15": {
                  "inputs": {
                      "filename_prefix": "ComfyUI",
                      "fps": 10,
                      "lossless": false,
                      "quality": 85,
                      "method": "default",
                      "images": [
                          "14",
                          0
                      ]
                  },
                  "class_type": "SaveAnimatedWEBP",
                  "_meta": {
                      "title": "保存WEBP"
                  }
              },
              "16": {
                  "inputs": {
                      "width": 512,
                      "height": 768,
                      "video_frames": 35,
                      "motion_bucket_id": 140,
                      "fps": 15,
                      "augmentation_level": 0.15,
                      "clip_vision": [
                          "18",
                          1
                      ],
                      "init_image": [
                          "8",
                          0
                      ],
                      "vae": [
                          "18",
                          2
                      ]
                  },
                  "class_type": "SVD_img2vid_Conditioning",
                  "_meta": {
                      "title": "SVD_圖像到視頻_條件"
                  }
              },
              "17": {
                  "inputs": {
                      "min_cfg": 1,
                      "model": [
                          "18",
                          0
                      ]
                  },
                  "class_type": "VideoLinearCFGGuidance",
                  "_meta": {
                      "title": "線性CFG引導"
                  }
              },
              "18": {
                  "inputs": {
                      "ckpt_name": "svd_xt_image_decoder.safetensors"
                  },
                  "class_type": "ImageOnlyCheckpointLoader",
                  "_meta": {
                      "title": "Checkpoint加載器(僅圖像)"
                  }
              },
              "19": {
                  "inputs": {
                      "frame_rate": 10,
                      "loop_count": 0,
                      "filename_prefix": "comfyUI",
                      "format": "video/h264-mp4",
                      "pix_fmt": "yuv420p",
                      "crf": 20,
                      "save_metadata": true,
                      "pingpong": false,
                      "save_output": true,
                      "images": [
                          "14",
                          0
                      ]
                  },
                  "class_type": "VHS_VideoCombine",
                  "_meta": {
                      "title": "合并為視頻"
                  }
              }
          }
      }
    • 異步調用的請求體不需要prompt鍵值。上述工作流對應的請求體即為已下載的JSON文件內容。

集群版服務原理介紹

實現原理圖如下:

image
  • 集群版服務主要針對多用戶場景,實現了客戶端和后端推理實例解耦,以便多用戶可以分時復用后端推理實例,提升實例的利用率和降低推理成本。

  • Proxy代理主要負責客戶端進程和推理實例的管理。用戶的所有操作都在自己的進程中進行處理,相關的文件操作僅限于公共目錄和個人目錄,從而實現了用戶間工作目錄的有效隔離。當用戶需要使用推理實例來處理請求時,Proxy代理會從后端推理實例中找到可用的空閑實例來處理該推理請求。

加速圖片生成速度

xFormers是基于Transformer的開源加速工具,能夠有效縮短圖片和視頻生成時長,節省顯存使用。ComfyUI鏡像部署默認已開啟xFormers加速。

如何使用自己的工作流

如下圖可打開本地文件系統中的工作流進行使用。

comfyui使用自己的workflow

如何掛載自定義模型和ComfyUI插件?

服務部署后,系統會自動在已掛載的OSSNAS存儲空間中創建以下目錄結構:image

其中:

  • custom_nodes:該目錄用來存儲ComfyUI插件。

  • models:該目錄用來存放模型文件。

如果您從開源社區獲取了ComfyUI的第三方插件,或自行訓練生成了自定義模型,您應將這些插件或模型文件存放于上述指定目錄中,以便加載使用新的模型和插件。具體操作步驟如下:

  1. 服務部署成功后,單擊目標服務的服務方式列下的查看Web應用

  2. WebUI界面中,您可以瀏覽并查看當前可用的模型文件和ComfyUI插件列表。

    • 對于ComfyUI默認工作流,您需要在相應節點查看該節點可用的模型文件,例如在Checkpoint加載器的下拉列表中查看當前可用的模型文件。

    • 右鍵單擊WebUI頁面,在快捷菜單中單擊新建節點,查看所有已安裝的ComfyUI插件。image

  3. 加載模型文件。

    1. 請將模型文件上傳至掛載存儲的models目錄下的相應子目錄中,具體操作,請參見步驟二:上傳文件。請參考對應節點的開源項目庫的使用說明,確定模型上傳至哪個子目錄。例如,對于Checkpoint加載器節點,對應的模型應上傳至models/checkpoints

    2. WebUI頁面中,單擊刷新按鈕,然后在Checkpoint加載器的下拉列表中查看模型文件是否加載成功。image

    3. 如果未加載成功,您需要單擊Process Restart,以重新加載模型文件。image

      此過程將持續大約5分鐘,在此期間服務會自動重啟并恢復正常運行。重啟完成后,您可以訪問WebUI頁面,以確認模型文件是否已成功加載。

  4. 加載ComfyUI插件,支持以下兩種方式:

    • 自行上傳并加載ComfyUI插件(推薦)。

      1. 請將ComfyUI第三方插件上傳至掛載存儲的custom_nodes目錄。

      2. WebUI頁面中,單擊Process Restart

        此過程將持續大約5分鐘,在此期間服務會自動重啟并恢復正常運行。重啟完成后,您可以訪問WebUI頁面,以確認插件是否已成功加載。

    • 在管理器中直接安裝插件。由于需要從GitHub等平臺拉取代碼,有可能存在網絡連接失敗的問題。

      WebUI頁面,單擊管理器,然后在ComfyUI管理器對話框中安裝節點。image

如何將WebUI頁面的默認語言切換為中文?

  1. 模型在線服務(EAS)頁面,單擊目標服務的服務方式列下的查看Web應用,進入WebUI頁面。

    說明

    訪問WebUI時,大約需要1分鐘的加載時間,之后您將能看到完整的初始工作流界面。

  2. WebUI頁面,待工作流加載成功后,單擊image按鈕。image

  3. Settings對話框中,將AGLTranslation-langualge修改為中文[Chinese Simplified]image

    參數設置完成后,系統將自動切換至中文界面,大約需要1分鐘的加載時間,之后您將能看到完整的初始工作流界面。

EAS與函數計算在部署ComfyUI Serverless版的主要區別

  • EAS:適合有狀態、長周期運行的服務,支持一鍵部署模型為在線推理服務或AI-Web應用,具備彈性擴縮容、藍綠部署等功能。例如,您可以通過EAS的場景化模型部署或自定義模型部署方式來部署ComfyUI。

  • 函數計算:基于Serverless架構,提供按需付費、彈性伸縮等優勢,適合需要高質量圖像生成功能的場景,可自定義ComfyUI模型及安裝插件。例如,您可以在函數計算3.0控制臺創建應用、選擇ComfyUI模板、設置配置項并創建應用。