EAS提供了場景化部署方式,您只需配置幾個參數,即可一鍵部署基于ComfyUI和Stable Video Diffusion模型的AI視頻生成服務,幫助您完成社交平臺短視頻內容生成、動畫制作等任務。本文為您介紹如何基于ComfyUI鏡像部署服務和幾種常用的調用方式。
背景信息
隨著AIGC的廣泛應用,AI視頻生成已成為當前熱門應用之一。目前市面上有許多開源視頻生成大模型可供選擇,它們在不同領域展現了各自獨特的性能。與此同時,AIGC開源工具ComfyUI也迅速在市場上嶄露頭角。作為一個基于節點流程式的AIGC生成工具WebUI,ComfyUI將AIGC流程拆分成工作節點,實現了精準的工作流定制和可復現性。您可以一鍵部署基于ComfyUI的AI視頻生成服務,支持以下四種版本:
標準版:僅適用于單用戶使用WebUI,或使用一個實例調用API場景。支持以下兩種調用方式:
WebUI:請求發送時,會繞過EAS接口,前端直接將請求傳遞給后端服務器,所有請求均由同一個后端實例進行處理。建議您只部署1個實例,當您需要多臺實例時,需選擇集群版。
API:通過EAS接口發送請求給后端實例進行處理。建議您只部署1個實例,當您需要多臺實例時,需選擇API版本。
API版:系統將自動轉換服務為異步模式,適用于高并發場景。該模式僅支持API異步調用。基于其異步特性,系統會創建隊列服務實例,因此需要分配額外的CPU實例。
集群版:適合多用戶同時在WebUI頁面進行操作。僅支持通過WebUI進行調用,不提供API服務。主要適用于設計組或教學場景,通過分時復用的設計來提升推理集群的利用率,降低成本。由于Proxy負責處理WebUI請求,因此需要分配額外的CPU實例。參考集群版服務原理介紹,了解集群版服務的實現原理。該版本優勢如下:
系統為每個用戶提供獨立的后端環境。當開啟了多個實例時,單個用戶的任務會按順序執行,而多用戶環境下的任務則在不同實例之間分配,實現高效的GPU共享。
系統為每個用戶分配獨立的工作目錄,便于管理和存儲模型、輸出圖像或視頻等文件。
Serverless版:目前,僅華東2(上海)、華東1(杭州)地域支持部署Serverless版服務。 Serverless版本服務部署完全免費,只根據使用出圖的時長進行計費,并會根據您的服務請求量自動彈性伸縮。
具體使用流程如下:
根據您的具體使用場景,選擇部署標準版、API版、集群版或Serverless版的服務。
根據部署的服務版本,支持以下三種調用方式:
使用WebUI發送服務請求,僅標準版、集群版和Serverless版服務支持使用該方式。
在EAS的在線調試頁面發送同步調用請求,只有標準版服務支持同步調用功能。
只有標準版和API版服務支持通過API發送服務請求。其中,標準版服務僅支持同步調用,而API版服務僅支持異步調用。
前提條件
在部署微調模型、安裝ComfyUI插件、使用API調用服務時,您必須掛載NAS或OSS存儲,以便上傳微調模型、插件和獲取推理結果。請提前準備NAS或OSS存儲空間:
已創建OSS存儲空間和空目錄,例如:
oss://bucket-test/data-oss/
,其中:bucket-test為OSS存儲空間名稱;data-oss為該存儲空間下的空目錄。關于如何創建OSS存儲空間,請參見創建存儲空間;關于如何創建空目錄,請參見管理目錄。已創建NAS文件系統和空目錄。具體操作,請參見創建文件系統。
部署EAS服務
支持以下兩種部署方式:
方式一:場景化模型部署(推薦)
登錄PAI控制臺,在頁面上方選擇目標地域,并在右側選擇目標工作空間,然后單擊進入EAS。
在模型在線服務(EAS)頁面,單擊部署服務,在場景化模型部署區域,單擊AI視頻生成-ComfyUI部署。
在AI視頻生成-ComfyUI部署頁面,配置以下關鍵參數。
參數
描述
基本信息
服務名稱
自定義模型服務名稱。
版本選擇
支持選擇以下版本:
標準版:適用于單用戶使用WebUI或使用一個實例調用API場景。支持通過WebUI生成視頻,也可通過API進行調用。
API版:系統將自動轉換服務為異步模式,適用于高并發場景。僅支持通過API進行調用。
集群版WebUI:適合多用戶同時在WebUI頁面進行操作。僅支持通過WebUI進行調用,不提供API服務。關于該版本的實現原理介紹,請參見集群版服務原理介紹。
Serverless版:Serverless版本服務部署完全免費,只根據使用出圖的時長進行計費。
更多關于每個版本的使用場景說明,請參見背景信息。
模型配置
當部署微調模型、安裝ComfyUI插件,或選擇API版、標準版并通過API進行調用時,您需要單擊添加按鈕,進行模型配置,以便上傳微調模型、插件和獲取推理結果。支持以下幾種配置類型:
對象存儲(OSS):單擊選擇已創建的OSS存儲目錄。
文件存儲(NAS):配置NAS掛載點和NAS源路徑。
后續,您可以將自定義模型和ComfyUI插件上傳至指定的OSS或NAS路徑,以便加載和使用這些資源。具體操作,請參見如何掛載自定義模型和ComfyUI插件?。
資源配置
實例數
當版本選擇標準版時,建議將實例數配置為1。
資源配置選擇
資源規格推薦使用GU30、A10或T4卡型。系統默認選擇
,性價比高。說明ComfyUI僅支持單卡(單機單卡或多機單卡)運行,不支持多卡并發操作。
單擊部署。
方式二:自定義模型部署
登錄PAI控制臺,在頁面上方選擇目標地域,并在右側選擇目標工作空間,然后單擊進入EAS。
單擊部署服務,然后在自定義模型部署區域,單擊自定義部署。
在自定義部署頁面,配置以下關鍵參數。
參數
描述
基本信息
服務名稱
自定義服務名稱。本案例使用的示例值為:comfyui_svd_demo。
環境信息
部署方式
選擇鏡像部署,并選中開啟Web應用復選框。
鏡像配置
在官方鏡像列表中選擇comfyui>comfyui:1.7,其中:
x.x:表示標準版。
x.x-api:表示API版。
x.x-cluster:表示集群版。
說明由于版本迭代迅速,部署時鏡像版本選擇最高版本即可。
更多關于每個版本的使用場景說明,請參見背景信息。
模型配置
當部署微調模型、安裝ComfyUI插件,或選擇API版、標準版并通過API進行調用時,您需要進行模型配置,以便上傳微調模型、插件和獲取推理結果。支持以下幾種配置類型:
OSS
OSS:單擊選擇已創建的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插件上傳至指定的OSS或NAS路徑,以便加載和使用這些資源。具體操作,請參見如何掛載自定義模型和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僅支持單卡(單機單卡或多機單卡)運行,不支持多卡并發操作。
單擊部署。
當服務狀態為運行中時,表明服務已成功部署。
調用EAS服務
通過WebUI調用EAS服務
通過WebUI,您可以調用標準版、集群版和Serverless版的EAS服務。在標準版服務中,所有請求都由同一個后端實例處理。而集群版服務則適合多用戶同時操作,它能夠在多個實例間分配并處理各用戶的任務。具體操作步驟如下:
單擊目標服務的服務方式列下的查看Web應用。
說明訪問WebUI時,大約需要1分鐘的加載時間,之后您將能看到完整的初始工作流界面。
在WebUI頁面進行模型推理驗證。
根據您自己的業務需要,選擇文生圖的模型和圖生視頻的模型,本方案使用默認配置。然后在CLIP文本編碼器中輸入Prompts,例如:
Rocket takes off from the ground, fire, sky, airplane
,單擊添加提示詞隊列, 等待工作流運行完成即可獲得AI生成的視頻。右鍵單擊生成的視頻,選擇保存圖像,即可將生成的視頻保存到本地。
生成的視頻示例如下所示:
在線調試EAS服務
僅標準版服務支持在線調試,具體操作步驟如下:
生成請求體。具體操作,請參見如何生成請求體。
在模型在線服務(EAS)頁面,單擊目標服務操作列下的在線調試,進入在線調試頁面。
發送POST請求,獲取Prompt ID。
在調試頁面的在線調試請求參數區域的Body處填寫已準備好的請求體。并在請求URL文本編輯框中添加
/prompt
。單擊發送請求,即可在調試信息區域查看預測結果,示例如下。
發送GET請求,根據Prompt ID獲取推理結果。
在在線調試請求參數區域中,將請求方法修改為GET,并在文本框中配置
/history/<prompt id>
,示例如下。其中
<prompt id>
需要替換為步驟3獲取的Prompt ID。單擊發送請求,即可獲取推理結果。
您可以在掛載存儲的
output
目錄中,查看生成的推理結果。
通過API調用EAS服務
標準版和API版服務支持API調用。API調用支持同步調用和異步調用兩種方式:
同步調用
標準版服務僅支持同步調用方式,即客戶端發送一個請求,同步等待結果返回。
異步調用
API版服務僅支持異步調用方式,即客戶端使用EAS的隊列服務向輸入隊列發送請求,并通過訂閱的方式從輸出隊列查詢結果。
由于ComfyUI本身具有異步隊列系統,即使發起同步調用,實質上也是異步進行的。即當用戶提交請求后,系統會返回一個Prompt ID,您需要使用該ID輪詢以獲取推理結果。
同步調用
查看調用信息。
在服務列表中,單擊標準版服務名稱,然后在基本信息區域,單擊查看調用信息。
在調用信息對話框的公網地址調用頁簽,獲取服務訪問地址和Token。
獲取Prompt ID。
生成請求體。具體操作,請參見如何生成請求體。
發送請求,獲取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
配置為請求體,例如:
重要請求體中的布爾值(true和false)首字母需要小寫。
{ "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
配置為請求體,例如:
重要請求體中的布爾值(True和False)首字母需要大寫。
{ "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。
發送請求,獲取推理結果。
支持以下兩種方式:
Curl
HTTP請求方式:
GET
請求URL:
<service_url>/history/<prompt_id>
請求頭部:
代碼示例:
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。
頭部
值
描述
Authorization
<token>
授權密鑰
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路徑。
查看調用信息。
單擊API版服務的服務方式列下的調用信息,在調用信息對話框的異步調用頁簽,查看服務訪問地址和Token。
推送請求。
代碼示例如下:
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文件,請參見如何生成請求體。
重要文件中的布爾值(True和False)首字母需要大寫。
{ "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": "合并為視頻" } } }
訂閱結果。
執行以下命令安裝eas_prediction SDK。
pip install eas_prediction --user
執行以下代碼,獲取返回結果。
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
目錄中,查看推理結果文件。
相關文檔
ComfyUI的API版本啟用了異步隊列,關于異步調用的原理介紹,請參見部署異步推理服務。
通過EAS,您還可以完成以下場景化部署:
部署支持WebUI和API調用的LLM大語言模型,并在部署LLM應用后,利用LangChain框架集成企業知識庫,實現智能問答和自動化功能。詳情請參見5分鐘使用EAS一鍵部署LLM大語言模型應用。
部署集成了大語言模型(LLM)和檢索增強生成(RAG)技術的對話系統服務,適用于問答、摘要生成和依賴外部知識的自然語言處理任務。詳情請參見大模型RAG對話系統。
附錄
如何生成請求體
您需要在WebUI頁面設置滿足業務需求的工作流,然后構建相應的請求體。具體操作步驟如下:
在模型在線服務(EAS)頁面,單擊目標服務的服務方式列下的查看Web應用,進入WebUI頁面。
說明訪問WebUI時,大約需要1分鐘的加載時間,之后您將能看到完整的初始工作流界面。
在WebUI頁面,單擊按鈕,并在Settings對話框中選中啟用開發模式選項復選框。
在WebUI頁面,根據您的業務需求配置工作流。
您可以在Checkpoint加載器區域選擇模型,在CLIP文本編碼器中輸入正向和反向提示詞、調整采樣器配置等。完成這些操作后,單擊添加提示詞隊列以獲取AI生成的視頻,并確保所有配置都符合您的需求。
確定工作流符合預期后,請單擊保存(API格式),下載該工作流對應的JSON文件。
其中:
同步調用和在線調試的請求體需要將下載的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文件內容。
集群版服務原理介紹
實現原理圖如下:
集群版服務主要針對多用戶場景,實現了客戶端和后端推理實例解耦,以便多用戶可以分時復用后端推理實例,提升實例的利用率和降低推理成本。
Proxy代理主要負責客戶端進程和推理實例的管理。用戶的所有操作都在自己的進程中進行處理,相關的文件操作僅限于公共目錄和個人目錄,從而實現了用戶間工作目錄的有效隔離。當用戶需要使用推理實例來處理請求時,Proxy代理會從后端推理實例中找到可用的空閑實例來處理該推理請求。
加速圖片生成速度
xFormers是基于Transformer的開源加速工具,能夠有效縮短圖片和視頻生成時長,節省顯存使用。ComfyUI鏡像部署默認已開啟xFormers加速。
如何使用自己的工作流
如下圖可打開本地文件系統中的工作流進行使用。
如何掛載自定義模型和ComfyUI插件?
服務部署后,系統會自動在已掛載的OSS或NAS存儲空間中創建以下目錄結構:
其中:
custom_nodes:該目錄用來存儲ComfyUI插件。
models:該目錄用來存放模型文件。
如果您從開源社區獲取了ComfyUI的第三方插件,或自行訓練生成了自定義模型,您應將這些插件或模型文件存放于上述指定目錄中,以便加載使用新的模型和插件。具體操作步驟如下:
服務部署成功后,單擊目標服務的服務方式列下的查看Web應用。
在WebUI界面中,您可以瀏覽并查看當前可用的模型文件和ComfyUI插件列表。
對于ComfyUI默認工作流,您需要在相應節點查看該節點可用的模型文件,例如在Checkpoint加載器的下拉列表中查看當前可用的模型文件。
右鍵單擊WebUI頁面,在快捷菜單中單擊新建節點,查看所有已安裝的ComfyUI插件。
加載模型文件。
請將模型文件上傳至掛載存儲的
models
目錄下的相應子目錄中,具體操作,請參見步驟二:上傳文件。請參考對應節點的開源項目庫的使用說明,確定模型上傳至哪個子目錄。例如,對于Checkpoint加載器節點,對應的模型應上傳至models/checkpoints
。在WebUI頁面中,單擊刷新按鈕,然后在Checkpoint加載器的下拉列表中查看模型文件是否加載成功。
如果未加載成功,您需要單擊Process Restart,以重新加載模型文件。
此過程將持續大約5分鐘,在此期間服務會自動重啟并恢復正常運行。重啟完成后,您可以訪問WebUI頁面,以確認模型文件是否已成功加載。
加載ComfyUI插件,支持以下兩種方式:
自行上傳并加載ComfyUI插件(推薦)。
請將ComfyUI第三方插件上傳至掛載存儲的
custom_nodes
目錄。在WebUI頁面中,單擊Process Restart。
此過程將持續大約5分鐘,在此期間服務會自動重啟并恢復正常運行。重啟完成后,您可以訪問WebUI頁面,以確認插件是否已成功加載。
在管理器中直接安裝插件。由于需要從GitHub等平臺拉取代碼,有可能存在網絡連接失敗的問題。
在WebUI頁面,單擊管理器,然后在ComfyUI管理器對話框中安裝節點。
如何將WebUI頁面的默認語言切換為中文?
在模型在線服務(EAS)頁面,單擊目標服務的服務方式列下的查看Web應用,進入WebUI頁面。
說明訪問WebUI時,大約需要1分鐘的加載時間,之后您將能看到完整的初始工作流界面。
在WebUI頁面,待工作流加載成功后,單擊按鈕。
在Settings對話框中,將AGLTranslation-langualge修改為中文[Chinese Simplified]。
參數設置完成后,系統將自動切換至中文界面,大約需要1分鐘的加載時間,之后您將能看到完整的初始工作流界面。
EAS與函數計算在部署ComfyUI Serverless版的主要區別
EAS:適合有狀態、長周期運行的服務,支持一鍵部署模型為在線推理服務或AI-Web應用,具備彈性擴縮容、藍綠部署等功能。例如,您可以通過EAS的場景化模型部署或自定義模型部署方式來部署ComfyUI。
函數計算:基于Serverless架構,提供按需付費、彈性伸縮等優勢,適合需要高質量圖像生成功能的場景,可自定義ComfyUI模型及安裝插件。例如,您可以在函數計算3.0控制臺創建應用、選擇ComfyUI模板、設置配置項并創建應用。