Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@
"pages": [
"documentation/serverless/vllm",
"documentation/serverless/text-generation-inference-tgi",
"documentation/serverless/comfy-ui"
"documentation/serverless/comfy-ui",
"documentation/serverless/comfyui-wan-2.2",
"documentation/serverless/comfyui-acestep"
]
}
]
Expand Down
282 changes: 115 additions & 167 deletions documentation/serverless/comfy-ui.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -106,27 +106,8 @@ The primary endpoint for submitting ComfyUI workflows. This endpoint accepts com

### Request Structure

First, get worker routing information:

```bash
curl -X POST https://run.vast.ai/route/ -d '{
"endpoint": "comfyui-json",
"api_key": "your-endpoint-api-key",
"cost": 100
}'
```

Then send your workflow request to the worker URL:

### Inputs

`auth_data`:

- `signature`(string): A cryptographic string that authenticates the url, cost, and reqnum fields in the response, proving they originated from the server. Clients can use this signature, along with the server's public key, to verify that these specific details have not been tampered with.
- `cost`(float): The estimated compute resources for the request. The units of this cost are defined by the PyWorker.
- `endpoint`(string): Name of the Endpoint.
- `reqnum`(int): The request number corresponding to this worker instance. Note that workers expect to receive requests in approximately the same order as these reqnums, but some flexibility is allowed due to potential out-of-order requests caused by concurrency or small delays on the proxy server.
- `url`(string): The address of the worker instance to send the request to.
### Input

`payload`:

Expand All @@ -149,116 +130,130 @@ Then send your workflow request to the worker URL:

**Example Request:**

```json JSON icon="js"
{
"auth_data": {
"cost": 100.0,
"endpoint": "comfyui-json",
"reqnum": 2,
"signature": "signature_from_route_endpoint",
"url": "https://worker-address:port"
},
"payload": {
"input": {
"request_id": "",
"workflow_json": {
"3": {
"inputs": {
"seed": 588445435278533,
"steps": 20,
"cfg": 8,
"sampler_name": "euler",
"scheduler": "normal",
"denoise": 1,
"model": ["4", 0],
"positive": ["6", 0],
"negative": ["7", 0],
"latent_image": ["5", 0]
},
"class_type": "KSampler",
"_meta": {
"title": "KSampler"
}
},
"4": {
"inputs": {
"ckpt_name": "v1-5-pruned-emaonly-fp16.safetensors"
<CodeGroup>
```python vastai-sdk icon=python
from vastai import Serverless
import asyncio

ENDPOINT_NAME="comfyui-json"

async def main():
async with Serverless() as client:
endpoint = await client.get_endpoint(name=ENDPOINT_NAME)

# ComfyUI API compatible json workflow
workflow = {
"3": {
"inputs": {
"seed": "__RANDOM_INT__",
"steps": 20,
"cfg": 8,
"sampler_name": "euler",
"scheduler": "normal",
"denoise": 1,
"model": ["4", 0],
"positive": ["6", 0],
"negative": ["7", 0],
"latent_image": ["5", 0]
},
"class_type": "KSampler",
"_meta": {
"title": "KSampler"
}
},
"class_type": "CheckpointLoaderSimple",
"_meta": {
"title": "Load Checkpoint"
}
},
"5": {
"inputs": {
"width": 512,
"height": 512,
"batch_size": 1
"4": {
"inputs": {
"ckpt_name": "v1-5-pruned-emaonly-fp16.safetensors"
},
"class_type": "CheckpointLoaderSimple",
"_meta": {
"title": "Load Checkpoint"
}
},
"class_type": "EmptyLatentImage",
"_meta": {
"title": "Empty Latent Image"
}
},
"6": {
"inputs": {
"text": "beautiful scenery nature glass bottle landscape, purple galaxy bottle",
"clip": ["4", 1]
"5": {
"inputs": {
"width": 512,
"height": 512,
"batch_size": 1
},
"class_type": "EmptyLatentImage",
"_meta": {
"title": "Empty Latent Image"
}
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"7": {
"inputs": {
"text": "text, watermark",
"clip": ["4", 1]
"6": {
"inputs": {
"text": "beautiful scenery nature glass bottle landscape, purple galaxy bottle",
"clip": ["4", 1]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"8": {
"inputs": {
"samples": ["3", 0],
"vae": ["4", 2]
"7": {
"inputs": {
"text": "text, watermark",
"clip": ["4", 1]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"9": {
"inputs": {
"filename_prefix": "ComfyUI",
"images": ["8", 0]
"8": {
"inputs": {
"samples": ["3", 0],
"vae": ["4", 2]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
"9": {
"inputs": {
"filename_prefix": "ComfyUI",
"images": ["8", 0]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
}
}
},
"s3": {
"access_key_id": "",
"secret_access_key": "",
"endpoint_url": "",
"bucket_name": "",
"region": ""
},
"webhook": {
"url": "",
"extra_params": {
"user_id": "12345",
"project_id": "abc-def"

payload = {
"input": {
"request_id": "",
"workflow_json": workflow,
"s3": {
"access_key_id": "",
"secret_access_key": "",
"endpoint_url": "",
"bucket_name": "",
"region": ""
},
"webhook": {
"url": "",
"extra_params": {
"user_id": "12345",
"project_id": "abc-def"
}
}
}
}
}
}
}
}

response = await endpoint.request("/generate/sync", payload)

# Response contains status, output, and any errors
print(response["response"])

if __name__ == "__main__":
asyncio.run(main())
```
</CodeGroup>


### Outputs

Expand All @@ -281,53 +276,6 @@ Then send your workflow request to the worker URL:
- `output_type`(string): Type of output (e.g., "images")
- `timings`(object): Timing information for the request

**Example Response:**

```json JSON icon="js"
{
"id": "6c5b3d85-cc99-49eb-af39-eb545cf7c7a8",
"message": "Processing complete.",
"status": "completed",
"comfyui_response": {
"e193ab60-ee90-44bb-bb5d-eaef5d025b70": {
"prompt": [4, "e193ab60-ee90-44bb-bb5d-eaef5d025b70", {...}, {...}, ["9"]],
"outputs": {
"9": {
"images": [
{
"filename": "ComfyUI_00001_.png",
"subfolder": "",
"type": "output"
}
]
}
},
"status": {
"status_str": "success",
"completed": true,
"messages": [
["execution_start", {"prompt_id": "e193ab60-ee90-44bb-bb5d-eaef5d025b70", "timestamp": 1759420703596}],
["execution_cached", {"nodes": ["4", "5"], "prompt_id": "e193ab60-ee90-44bb-bb5d-eaef5d025b70", "timestamp": 1759420703598}],
["execution_success", {"prompt_id": "e193ab60-ee90-44bb-bb5d-eaef5d025b70", "timestamp": 1759420704651}]
]
}
}
},
"output": [
{
"filename": "ComfyUI_00001_.png",
"local_path": "/workspace/ComfyUI/output/6c5b3d85-cc99-49eb-af39-eb545cf7c7a8/ComfyUI_00001_.png",
"type": "output",
"subfolder": "",
"node_id": "9",
"output_type": "images",
"url": "https://s3-presigned-url-to-generated-asset"
}
],
"timings": {}
}
```

<Warning>
Ensure that any models and nodes referenced in your workflow are already installed before sending a request. Use the Provisioning Script or build a custom Docker image to pre-install required models and nodes.
</Warning>
Expand Down
Loading