Skip to content

Commit

Permalink
1.8.1 - Greatly Longer Fetch Timeouts (#22)
Browse files Browse the repository at this point in the history
* update node version, remove unused chokidar

* use more verbose bind mounts

* update link script

* change fetch request timeouts to 20 hours from 300s

* document cosmos

* timeout and warmup fixes

* dangit node, why you be that way

* cosmos test case
  • Loading branch information
shawnrushefsky authored Jan 22, 2025
1 parent 51f8b75 commit ff2702f
Show file tree
Hide file tree
Showing 12 changed files with 339 additions and 60 deletions.
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v18.19.0
v20.18.1
17 changes: 12 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ The server hosts swagger docs at `/docs`, which can be used to interact with the
## Features

- **Full Power Of ComfyUI**: The server supports the full ComfyUI /prompt API, and can be used to execute any ComfyUI workflow.
- **Verified Model/Workflow Support**: Stable Diffusion 1.5, Stable Diffusion XL, Stable Diffusion 3.5, Flux, AnimateDiff, LTX Video, Hunyuan Video, CogVideoX, Mochi Video. My assumption is more model types are supported, but these are the ones I have verified.
- **Verified Model/Workflow Support**: Stable Diffusion 1.5, Stable Diffusion XL, Stable Diffusion 3.5, Flux, AnimateDiff, LTX Video, Hunyuan Video, CogVideoX, Mochi Video, Cosmos 1.0. My assumption is more model types are supported, but these are the ones I have verified.
- **Stateless API**: The server is stateless, and can be scaled horizontally to handle more requests.
- **Swagger Docs**: The server hosts swagger docs at `/docs`, which can be used to interact with the API.
- **"Synchronous" Support**: The server will return base64-encoded images directly in the response, if no webhook is provided.
Expand All @@ -75,6 +75,7 @@ The server hosts swagger docs at `/docs`, which can be used to interact with the
- **Bring Your Own Models And Extensions**: Use any model or extension you want by adding them to the normal ComfyUI directories `/opt/ComfyUI/`.
- **Works Great with SaladCloud**: The server is designed to work well with SaladCloud, and can be used to host ComfyUI on the SaladCloud platform. It is likely to work well with other platforms as well.
- **Single Binary**: The server is distributed as a single binary, and can be run with no dependencies.
- **Websocket Events Via Webhook**: The server can forward ComfyUI websocket events to a configured webhook, which can be used to monitor the progress of a workflow.
- **Friendly License**: The server is distributed under the MIT license, and can be used for any purpose. All of its dependencies are also MIT or Apache 2.0 licensed, except ComfyUI itself, which is GPL-3.0 licensed.

## Probes
Expand Down Expand Up @@ -651,7 +652,7 @@ All of SaladCloud's image and video generation [recipes](https://docs.salad.com/
## Considerations for Running on SaladCloud

- **SaladCloud's Container Gateway has a 100s timeout.** It is possible to construct very long running ComfyUI workflows, such as for video generation, that would exceed this timeout. In this scenario, you will need to either use a webhook to receive the results, or integrate with SaladCloud's [Job Queues](https://docs.salad.com/products/sce/job-queues/job-queues#job-queues) to handle long-running workflows.
- **SaladCloud's maximum container image size is 35GB(compressed).** The base [comfyui-api image](https://hub.docker.com/r/saladtechnologies/comfyui/tags) is around 3.25GB(compressed), so any models and extensions must fit in the remaining space.
- **SaladCloud's maximum container image size is 35GB(compressed).** The base [comfyui-api image](https://github.com/SaladTechnologies/comfyui-api/pkgs/container/comfyui-api) is around 3.25GB(compressed), so any models and extensions must fit in the remaining space.

## Contributing

Expand Down Expand Up @@ -683,6 +684,9 @@ Automated tests for this project require model files to be present in the `./tes
- `vae-ft-mse-840000-ema-pruned.ckpt` - https://huggingface.co/stabilityai/sd-vae-ft-mse-original/blob/main/vae-ft-mse-840000-ema-pruned.ckpt
- `THUDM/CogVideoX-2b` - https://huggingface.co/THUDM/CogVideoX-2b
- `mochi_preview_fp8_scaled.safetensors` - https://huggingface.co/Comfy-Org/mochi_preview_repackaged/blob/main/all_in_one/mochi_preview_fp8_scaled.safetensors
- `oldt5_xxl_fp8_e4m3fn_scaled.safetensors` - https://huggingface.co/comfyanonymous/cosmos_1.0_text_encoder_and_VAE_ComfyUI/tree/main/text_encoders
- `cosmos_cv8x8x8_1.0.safetensors` - https://huggingface.co/comfyanonymous/cosmos_1.0_text_encoder_and_VAE_ComfyUI/blob/main/vae/cosmos_cv8x8x8_1.0.safetensors
- `Cosmos-1_0-Diffusion-7B-Text2World.safetensors` - https://huggingface.co/mcmonkey/cosmos-1.0/blob/main/Cosmos-1_0-Diffusion-7B-Text2World.safetensors


They should be in the correct comfyui directory structure, like so:
Expand All @@ -709,15 +713,18 @@ They should be in the correct comfyui directory structure, like so:
├── controlnet
│ ├── openpose-sd1.5-1.1.safetensors
├── diffusion_models
│ └── hunyuan_video_t2v_720p_bf16.safetensors
│ ├── hunyuan_video_t2v_720p_bf16.safetensors
| └── Cosmos-1_0-Diffusion-7B-Text2World.safetensors
├── loras
│ ├── jump_V2.safetensors
├── text_encoders
│ ├── clip_l.safetensors
│ └── llava_llama3_fp8_scaled.safetensors
│ ├── llava_llama3_fp8_scaled.safetensors
| └── oldt5_xxl_fp8_e4m3fn_scaled.safetensors
├── vae
│ ├── hunyuan_video_vae_bf16.safetensors
│ └── vae-ft-mse-840000-ema-pruned.ckpt
│ ├── vae-ft-mse-840000-ema-pruned.ckpt
│ └── cosmos_cv8x8x8_1.0.safetensors
```

### Running Tests
Expand Down
8 changes: 6 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ services:
comfyui:
image: ghcr.io/saladtechnologies/comfyui-api:comfy0.3.12-test-image
volumes:
- ./bin:/app/bin
- ./test/docker-image/models:/opt/ComfyUI/models
- type: bind
source: ./bin
target: /app/bin
- type: bind
source: ./test/docker-image/models
target: /opt/ComfyUI/models
command: ["/app/bin/comfyui-api"]
build:
context: ./test/docker-image
Expand Down
46 changes: 32 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "comfyui-api",
"version": "1.8.0",
"version": "1.8.1",
"description": "Wraps comfyui to make it easier to use as a stateless web service",
"main": "dist/src/index.js",
"scripts": {
Expand All @@ -13,7 +13,6 @@
"license": "MIT",
"devDependencies": {
"@anthropic-ai/sdk": "^0.26.1",
"@types/chokidar": "^2.1.3",
"@types/mocha": "^10.0.10",
"@types/node": "^20.12.7",
"@types/ws": "^8.5.13",
Expand All @@ -29,11 +28,11 @@
"dependencies": {
"@fastify/swagger": "^8.15.0",
"@fastify/swagger-ui": "^4.1.0",
"chokidar": "^3.6.0",
"fastify": "^4.26.2",
"fastify-type-provider-zod": "^2.0.0",
"sharp": "^0.33.5",
"typescript": "^5.4.5",
"undici": "^7.2.3",
"ws": "^8.18.0",
"zod": "^3.23.8"
},
Expand All @@ -43,5 +42,8 @@
],
"outputPath": "bin",
"public": true
},
"engines": {
"node": ">=20.18.1"
}
}
12 changes: 10 additions & 2 deletions src/comfy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ import {
isExecutionInterruptedMessage,
isExecutionErrorMessage,
WebhookHandlers,
ComfyPromptResponse,
ComfyHistoryResponse,
} from "./types";
import path from "path";
import fsPromises from "fs/promises";
import WebSocket, { MessageEvent } from "ws";
import { fetch, Agent } from "undici";

const commandExecutor = new CommandExecutor();

Expand Down Expand Up @@ -76,6 +79,11 @@ export async function warmupComfyUI(): Promise<void> {
"Content-Type": "application/json",
},
body: JSON.stringify({ prompt: config.warmupPrompt }),
dispatcher: new Agent({
headersTimeout: 0,
bodyTimeout: 0,
connectTimeout: 0,
}),
});
if (!resp.ok) {
throw new Error(`Failed to warmup Comfy UI: ${await resp.text()}`);
Expand All @@ -94,7 +102,7 @@ export async function queuePrompt(prompt: ComfyPrompt): Promise<string> {
if (!resp.ok) {
throw new Error(`Failed to queue prompt: ${await resp.text()}`);
}
const { prompt_id } = await resp.json();
const { prompt_id } = (await resp.json()) as ComfyPromptResponse;
return prompt_id;
}

Expand All @@ -106,7 +114,7 @@ export async function getPromptOutputs(
if (!resp.ok) {
throw new Error(`Failed to get prompt outputs: ${await resp.text()}`);
}
const body = await resp.json();
const body = (await resp.json()) as ComfyHistoryResponse;
const allOutputs: Record<string, Buffer> = {};
const fileLoadPromises: Promise<void>[] = [];
if (!body[promptId]) {
Expand Down
Loading

0 comments on commit ff2702f

Please sign in to comment.