## 注意 - KSampler或其他有randomize產出的 seed 要記得換,結果才會不一樣 ## 將workflow用api呼叫 1. 開啟ComfyUI的Dev Mode ![1-1](https://hackmd.io/_uploads/BkDX-WMf0.png) ![1-2](https://hackmd.io/_uploads/BJvmWWfzC.png) 2. 以API格式下載workflow ![2-1](https://hackmd.io/_uploads/Bkz2-WMM0.png) 3. 以[換臉workflow(點擊跳轉至json檔)](#換臉workflow)為例 1. 使用`POST /upload/image`上傳需要的圖檔 2. 將response.json['name']的檔名分別放入workflow中兩個LoadImage節點的輸入 - target: workflow['nodes'][0]['widgets_values'][0] - source: workflow['nodes'][1]['widgets_values'][0] 3. 根據需求,調整workflow中ReActorFaceSwap或SaveImage節點的輸入,所需輸入可透過以下API查看 - ReActorFaceSwap: /object_info/ReActorFaceSwap - SaveImage: /object_info/SaveImage 4. 使用`POST /prompt`開始執行workflow,body中需包含一個用於追蹤的client_id(自訂)和prompt(workflow) ```json { "client_id": "TESTING", "prompt": { ... } } ``` 5. 使用`WS /ws?clientId=TESTING`追蹤執行進度 1. 接上時收到佇列中的任務數 2. 收到type="execution_start"的訊息,代表該clientId送出的prompt被執行 3. 進入下一個工作節點時,會收到type="executing"的訊息 4. 收到type="executed"的訊息,代表執行完畢 - 輸出檔名: message['data']['output']['images'][0]['filename'] - 輸出類型: message['data']['output']['images'][0]['filename'] 6. 將5-4的filename和type作為參數,使用`GET /view?filename=xxx&type=xxx`取得輸出圖像 ## workflows ### 換臉workflow ```jsonld= { "last_node_id": 4, "last_link_id": 3, "nodes": [ { "id": 3, "type": "LoadImage", "pos": [ 34, -127 ], "size": { "0": 315, "1": 314 }, "flags": {}, "order": 0, "mode": 0, "outputs": [ { "name": "IMAGE", "type": "IMAGE", "links": [ 2 ], "shape": 3, "slot_index": 0 }, { "name": "MASK", "type": "MASK", "links": null, "shape": 3 } ], "properties": { "Node name for S&R": "LoadImage" }, "widgets_values": [ "target.jpg", "image" ] }, { "id": 2, "type": "LoadImage", "pos": [ 35, 248 ], "size": [ 315, 314.00000381469727 ], "flags": {}, "order": 1, "mode": 0, "outputs": [ { "name": "IMAGE", "type": "IMAGE", "links": [ 1 ], "shape": 3, "slot_index": 0 }, { "name": "MASK", "type": "MASK", "links": null, "shape": 3 } ], "properties": { "Node name for S&R": "LoadImage" }, "widgets_values": [ "source.jpg", "image" ] }, { "id": 1, "type": "ReActorFaceSwap", "pos": [ 422, 50 ], "size": { "0": 315, "1": 338 }, "flags": {}, "order": 2, "mode": 0, "inputs": [ { "name": "input_image", "type": "IMAGE", "link": 2 }, { "name": "source_image", "type": "IMAGE", "link": 1 }, { "name": "face_model", "type": "FACE_MODEL", "link": null } ], "outputs": [ { "name": "IMAGE", "type": "IMAGE", "links": [ 3 ], "shape": 3, "slot_index": 0 }, { "name": "FACE_MODEL", "type": "FACE_MODEL", "links": null, "shape": 3 } ], "properties": { "Node name for S&R": "ReActorFaceSwap" }, "widgets_values": [ true, "inswapper_128.onnx", "retinaface_resnet50", "none", 1, 0.5, "no", "no", "0", "0", 1 ] }, { "id": 4, "type": "SaveImage", "pos": [ 780, 61 ], "size": { "0": 315, "1": 58 }, "flags": {}, "order": 3, "mode": 0, "inputs": [ { "name": "images", "type": "IMAGE", "link": 3 } ], "properties": {}, "widgets_values": [ "ComfyUI" ] } ], "links": [ [ 1, 2, 0, 1, 1, "IMAGE" ], [ 2, 3, 0, 1, 0, "IMAGE" ], [ 3, 1, 0, 4, 0, "IMAGE" ] ], "groups": [], "config": {}, "extra": {}, "version": 0.4 } ``` ## ComfyUI WebSocket訊息 |type|data| |-|-| |訊息類型|實際資訊| ### meaning and data of each type #### status - 連線建立 ```json { "status": { "exec_info": { "queue_remaining": 2 // total prompts executing or waiting for execution } }, "sid": "testing" //clientID of this connection } ``` - queue有更新的通知訊息 ```json { "status": { "exec_info": { "queue_remaining": 2 // total prompts executing or waiting for execution } } } ``` #### execution_start - 開始執行由此clientID請求執行的prompt ```json { "prompt_id": "ef8136ac-4c7a-4181-aaec-2f75ae26ee11" // id of the executing prompt } ``` #### execution_cached - 上一個執行的prompt中,有某些output nodes的結果並未變化,使用cache可以減少節省執行的時間 ```json { "nodes": ["1", "2", "3"], // id of output nodes that can use cached result "prompt_id": "ef8136ac-4c7a-4181-aaec-2f75ae26ee11" // id of the executing prompt } ``` #### executing - 目前執行的節點 ```json { "node": "1", // id of the executing prompt "prompt_id": "ef8136ac-4c7a-4181-aaec-2f75ae26ee11" // id of the executing prompt } ``` - 執行完畢 ```json { "node": null, "prompt_id": "ef8136ac-4c7a-4181-aaec-2f75ae26ee11" // id of the executing prompt } ``` #### progress - 節點內部的執行進度 ```json { "value": 1, // current round "max": 20, // total rounds "node": "1", // id of the executing prompt "prompt_id": "ef8136ac-4c7a-4181-aaec-2f75ae26ee11" // id of the executing prompt } ``` ## API文件 [postman範例](https://www.postman.com/dark-firefly-849863/workspace/comfyui) ## 可能遇到的問題 ### 找不到節點 - [ComfyUI Manager](https://github.com/ltdrdata/ComfyUI-Manager) ### 找不到模型 - ~~[Install missing nodes and models](https://github.com/piyushK52/comfy_runner)~~: 執行時會再安裝另一套ComfyUI,不怎麼好(2024/05/27) ## 參考文件 [API documentation](https://gitee.com/BTYY/wailikeji-chatgpt/blob/master/comfyui-api.md) [簡體中文教程](https://blog.csdn.net/jjs15259655776/article/details/134388940) [comfyui-api](https://github.com/9elements/comfyui-api)