Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.7.1 - Auto-restart, non-fatal file conversion errors #16

Merged
merged 54 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
155a96e
version bump, support frames for batchSize
shawnrushefsky Dec 30, 2024
e2f3e4f
handle case of local image paths
shawnrushefsky Dec 30, 2024
47c0d18
fix installation of sharp
shawnrushefsky Jan 6, 2025
5e2d7ec
animatediff works
shawnrushefsky Jan 6, 2025
095fd24
zod hates to base64 validate huge stuff. fair enough
shawnrushefsky Jan 6, 2025
a02f39b
start outlining tests
shawnrushefsky Jan 7, 2025
9950df8
ignore model files
shawnrushefsky Jan 7, 2025
dfac8fb
scaffolding tests
shawnrushefsky Jan 7, 2025
0d02a42
controlnet frames
shawnrushefsky Jan 7, 2025
8f539d6
ignore model directory
shawnrushefsky Jan 7, 2025
e1bff99
rip out filewatcher, just use comfy apis
shawnrushefsky Jan 7, 2025
02a3777
first passing test
shawnrushefsky Jan 7, 2025
a71a7d6
fixes based on testing
shawnrushefsky Jan 7, 2025
607ee95
sync tests passing
shawnrushefsky Jan 7, 2025
41b758b
remove dependency on recipes repo
shawnrushefsky Jan 7, 2025
4303d25
create test utils, do webhook tests
shawnrushefsky Jan 8, 2025
b30a2ca
sd1.5 tests
shawnrushefsky Jan 8, 2025
3508fdb
ltx video tests
shawnrushefsky Jan 8, 2025
9b84420
fix webhook test issue
shawnrushefsky Jan 8, 2025
d8c9b91
flux tests
shawnrushefsky Jan 8, 2025
6dadbd4
sd3.5 tests
shawnrushefsky Jan 8, 2025
868415b
sdxl tests
shawnrushefsky Jan 8, 2025
ce79ad7
workaround testing race condition
shawnrushefsky Jan 8, 2025
617f01b
document required models
shawnrushefsky Jan 8, 2025
58d5ab6
remove unused
shawnrushefsky Jan 8, 2025
1e1d1dc
hunyuan video
shawnrushefsky Jan 8, 2025
8483eaa
add hunyuan to supported models
shawnrushefsky Jan 8, 2025
eab9b80
more testing instructions
shawnrushefsky Jan 8, 2025
5b99669
make body size configurable, little cleanup in server
shawnrushefsky Jan 9, 2025
ad9f193
remove commented out code in workflow loader
shawnrushefsky Jan 9, 2025
16e0fb5
shorten that test
shawnrushefsky Jan 9, 2025
504556c
document location of all models used for testing
shawnrushefsky Jan 9, 2025
f635e8c
cogvideo works
shawnrushefsky Jan 9, 2025
fd90d5f
cogvideox 2b works
shawnrushefsky Jan 10, 2025
225b576
configurable restart policy
shawnrushefsky Jan 10, 2025
60baaeb
document config change
shawnrushefsky Jan 10, 2025
45366db
no longer treat image conversion as a fatal error, just send the unc…
shawnrushefsky Jan 10, 2025
a4df175
fix
shawnrushefsky Jan 10, 2025
ebe6840
mochi support
shawnrushefsky Jan 10, 2025
cf316c6
remove .only
shawnrushefsky Jan 10, 2025
a568655
build scripts for docker images for ghcr
shawnrushefsky Jan 10, 2025
344a62f
move more env into base
shawnrushefsky Jan 13, 2025
38990cb
specify mochi video in readme
shawnrushefsky Jan 13, 2025
ace7fa4
document cogvideox and mochi model sources
shawnrushefsky Jan 13, 2025
ed75c36
version bump
shawnrushefsky Jan 13, 2025
636f391
comments
shawnrushefsky Jan 13, 2025
ccd6071
Merge branch 'main' into cogvideox
shawnrushefsky Jan 13, 2025
1028f18
await workflow generation. allows for async prompt generations
shawnrushefsky Jan 13, 2025
61e978f
label the event in the webhook
shawnrushefsky Jan 13, 2025
ae4fca1
Merge branch 'main' into cogvideox
shawnrushefsky Jan 13, 2025
7e517cb
readme note about timeouts
shawnrushefsky Jan 14, 2025
5154db4
update workflows
shawnrushefsky Jan 14, 2025
22054ed
nah, didn't like that
shawnrushefsky Jan 14, 2025
12657e7
more readme update
shawnrushefsky Jan 14, 2025
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
2 changes: 2 additions & 0 deletions .github/workflows/create-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ jobs:

- name: Get the PR that was merged into main
id: pr-output
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
info=$(gh pr list --state merged --limit 1 --json title --json body)
echo "title=$(echo $info | jq -r '.title')" >> $GITHUB_OUTPUT
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/pr-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ on:
branches:
- main
paths-ignore:
- ".github/**"
- "**.md"
- "**.png"
- ".gitignore"
- "generate-workflow"
- "**.yml"
- "test/**"
- "example-workflows/**"

Expand Down
35 changes: 29 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,26 @@ A simple wrapper that facilitates using ComfyUI as a stateless API, either by re
- [Generating New Workflow Endpoints](#generating-new-workflow-endpoints)
- [Automating with Claude 3.5 Sonnet](#automating-with-claude-35-sonnet)
- [Prebuilt Docker Images](#prebuilt-docker-images)
- [Considerations for Running on SaladCloud](#considerations-for-running-on-saladcloud)
- [Contributing](#contributing)
- [Testing](#testing)
- [Required Models](#required-models)
- [Running Tests](#running-tests)

## Download and Usage

Download the latest version from the release page, and copy it into your existing ComfyUI dockerfile. Then, you can use it like this:
Either use a [pre-built Docker image](#prebuilt-docker-images), or build your own.

Download the latest version from the release page, and copy it into your existing ComfyUI dockerfile.
You can find good base dockerfiles in the [docker](./docker) directory.
There are also example dockerfiles for popular models in the [SaladCloud Recipes Repo](https://github.com/SaladTechnologies/salad-recipes/tree/master/src).

If you have your own ComfyUI dockerfile, you can add the comfyui-api server to it like so:

```dockerfile
# Change this to the version you want to use
ARG api_version=1.7.0
ARG api_version=1.7.1


# Download the comfyui-api binary, and make it executable
ADD https://github.com/SaladTechnologies/comfyui-api/releases/download/${api_version}/comfyui-api .
Expand All @@ -41,7 +49,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. 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. 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 @@ -60,8 +68,8 @@ The server hosts swagger docs at `/docs`, which can be used to interact with the

The server has two probes, `/health` and `/ready`.

- The `/health` probe will return a 200 status code once the warmup workflow has complete.
- The `/ready` probe will also return a 200 status code once the warmup workflow has completed, and the server is ready to accept requests.
- The `/health` probe will return a 200 status code once the warmup workflow has completed. It will stay healthy as long as the server is running, even if ComfyUI crashes.
- The `/ready` probe will also return a 200 status code once the warmup workflow has completed. It will return a 503 status code if ComfyUI is not running, such as in the case it has crashed, but is being automatically restarted.

Here's a markdown guide to configuring the application based on the provided config.ts file:

Expand Down Expand Up @@ -91,6 +99,7 @@ The default values mostly assume this will run on top of an [ai-dock](https://gi
| WARMUP_PROMPT_FILE | (not set) | Path to warmup prompt file (optional) |
| WORKFLOW_DIR | "/workflows" | Directory for workflow files |
| BASE | "ai-dock" | There are different ways to load the comfyui environment for determining config values that vary with the base image. Currently only "ai-dock" has preset values. Set to empty string to not use this. |
| ALWAYS_RESTART_COMFYUI | "false" | If set to "true", the ComfyUI process will be automatically restarted if it exits. Otherwise, the API server will exit when ComfyUI exits. |

### Configuration Details

Expand Down Expand Up @@ -155,10 +164,13 @@ const ComfyNodeSchema = z.object({
});

type ComfyNode = z.infer<typeof ComfyNodeSchema>;
type ComfyPrompt = Record<string, ComfyNode>;

interface Workflow {
RequestSchema: z.ZodObject<any, any>;
generateWorkflow: (input: any) => ComfyPrompt;
generateWorkflow: (input: any) => Promise<ComfyPrompt> | ComfyPrompt;
description?: string;
summary?: string;
}

// This defaults the checkpoint to whatever was used in the warmup workflow
Expand Down Expand Up @@ -374,6 +386,11 @@ The tag pattern is `saladtechnologies/comfyui:comfy<comfy-version>-api<api-versi
- `<api-version>` is the version of the comfyui-api server
- `<model|base>` is the model used. There is a `base` tag for an image that contains ComfyUI and the comfyui-api server, but no models. There are also tags for specific models, like `sdxl-with-refiner` or `flux-schnell-fp8`.

## Considerations for Running on SaladCloud

- **SaladCloud's Container Gateway has a 100s timeout.** It is possible to construct very long running workflows, such for video generation, with ComfyUI 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.

## Contributing

Contributions are welcome! Please open an issue or a pull request if you have any suggestions or improvements.
Expand Down Expand Up @@ -402,6 +419,9 @@ Automated tests for this project require model files to be present in the `./tes
- `llava_llama3_fp8_scaled.safetensors` - https://huggingface.co/Comfy-Org/HunyuanVideo_repackaged/tree/main/split_files/text_encoders
- `hunyuan_video_vae_bf16.safetensors` - https://huggingface.co/Comfy-Org/HunyuanVideo_repackaged/tree/main/split_files/vae
- `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


They should be in the correct comfyui directory structure, like so:

Expand All @@ -413,6 +433,7 @@ They should be in the correct comfyui directory structure, like so:
│ ├── dreamshaper_8.safetensors
│ ├── flux1-schnell-fp8.safetensors
│ ├── ltx-video-2b-v0.9.1.safetensors
| ├── mochi_preview_fp8_scaled.safetensors
│ ├── sd3.5_medium.safetensors
│ ├── sd_xl_base_1.0.safetensors
│ └── sd_xl_refiner_1.0.safetensors
Expand All @@ -421,6 +442,8 @@ They should be in the correct comfyui directory structure, like so:
│ ├── clip_l.safetensors
│ ├── t5xxl_fp16.safetensors
│ └── t5xxl_fp8_e4m3fn.safetensors
├── CogVideo
│ └── CogVideo2B/
├── controlnet
│ ├── openpose-sd1.5-1.1.safetensors
├── diffusion_models
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
services:
comfyui:
image: saladtechnologies/comfyui:comfy0.3.10-test-image
image: ghcr.io/saladtechnologies/comfyui-api:comfy0.3.10-test-image
volumes:
- ./bin:/app/bin
- ./test/docker-image/models:/opt/ComfyUI/models
Expand Down
14 changes: 14 additions & 0 deletions docker/api.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
ARG base=runtime
ARG comfy_version=0.3.10
ARG pytorch_version=2.5.0
ARG cuda_version=12.1
FROM ghcr.io/saladtechnologies/comfyui-api:comfy${comfy_version}-torch${pytorch_version}-cuda${cuda_version}-${base}

ENV WORKFLOW_DIR=/workflows
ENV STARTUP_CHECK_MAX_TRIES=30

ARG api_version=1.7.1
ADD https://github.com/SaladTechnologies/comfyui-api/releases/download/${api_version}/comfyui-api .
RUN chmod +x comfyui-api

CMD ["./comfyui-api"]
23 changes: 23 additions & 0 deletions docker/build-api-images
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#! /usr/bin/bash

usage="Usage: $0 [comfy_version] [torch_version] [cuda_version] [api_version]"

comfy_version=${1:-0.3.10}
torch_version=${2:-2.5.0}
cuda_version=${3:-12.1}

current_api_version=$(cat ../package.json | jq -r '.version')
api_version=${4:-$current_api_version}

bases=("runtime" "devel")

for base in "${bases[@]}"; do
docker build -t ghcr.io/saladtechnologies/comfyui-api:comfy$comfy_version-api$api_version-torch$torch_version-cuda$cuda_version-$base \
-f api.dockerfile \
--build-arg comfy_version=$comfy_version \
--build-arg base=$base \
--build-arg pytorch_version=$torch_version \
--build-arg cuda_version=$cuda_version \
--build-arg api_version=$api_version \
.
done
16 changes: 16 additions & 0 deletions docker/build-comfy-base-images
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#! /usr/bin/bash

comfy_version=${1:-0.3.10}
torch_version=${2:-2.5.0}
cuda_version=${3:-12.1}
bases=("runtime" "devel")

for base in "${bases[@]}"; do
docker build -t ghcr.io/saladtechnologies/comfyui-api:comfy$comfy_version-torch$torch_version-cuda$cuda_version-$base \
-f comfyui.dockerfile \
--build-arg comfy_version=$comfy_version \
--build-arg base=$base \
--build-arg pytorch_version=$torch_version \
--build-arg cuda_version=$cuda_version \
.
done
32 changes: 32 additions & 0 deletions docker/comfyui.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
ARG base=runtime
ARG pytorch_version=2.5.0
ARG cuda_version=12.1
FROM pytorch/pytorch:${pytorch_version}-cuda${cuda_version}-cudnn9-${base}
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y \
curl \
git \
unzip \
wget \
&& rm -rf /var/lib/apt/lists/*

# Install comfy-cli, which makes it easy to install custom nodes and other comfy specific functionality.
RUN pip install --upgrade pip
RUN pip install comfy-cli
WORKDIR /opt
ARG comfy_version=0.3.10
RUN git clone --depth 1 --branch v${comfy_version} https://github.com/comfyanonymous/ComfyUI.git
WORKDIR /opt/ComfyUI
RUN pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu121
RUN pip install -r requirements.txt
ENV COMFY_HOME=/opt/ComfyUI
RUN comfy --skip-prompt tracking disable
RUN comfy --skip-prompt set-default ${COMFY_HOME}
ENV MODEL_DIR=${COMFY_HOME}/models
ENV OUTPUT_DIR=${COMFY_HOME}/output
ENV INPUT_DIR=${COMFY_HOME}/input
ENV CMD="comfy --workspace ${COMFY_HOME} launch -- --listen *"
ENV BASE=""

CMD ["comfy", "--workspace", "${COMFY_HOME}", "launch", "--", "--listen", "*"]
17 changes: 17 additions & 0 deletions docker/push-all
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#! /usr/bin/bash

usage="Usage: $0 [comfy_version] [torch_version] [cuda_version] [api_version]"

comfy_version=${1:-0.3.10}
torch_version=${2:-2.5.0}
cuda_version=${3:-12.1}

current_api_version=$(cat package.json | jq -r '.version')
api_version=${4:-$current_api_version}

bases=("runtime" "devel")

for base in "${bases[@]}"; do
docker push ghcr.io/saladtechnologies/comfyui-api:comfy$comfy_version-torch$torch_version-cuda$cuda_version-$base
docker push ghcr.io/saladtechnologies/comfyui-api:comfy$comfy_version-api$api_version-torch$torch_version-cuda$cuda_version-$base
done
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "comfyui-api",
"version": "1.7.0",
"version": "1.7.1",
"description": "Wraps comfyui to make it easier to use as a stateless web service",
"main": "dist/src/index.js",
"scripts": {
Expand Down
10 changes: 8 additions & 2 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const {
MARKDOWN_SCHEMA_DESCRIPTIONS = "true",
BASE = "ai-dock",
MAX_BODY_SIZE_MB = "100",
ALWAYS_RESTART_COMFYUI = "false",
} = process.env;

fs.mkdirSync(WORKFLOW_DIR, { recursive: true });
Expand All @@ -34,8 +35,7 @@ const port = parseInt(PORT, 10);
const startupCheckInterval = parseInt(STARTUP_CHECK_INTERVAL_S, 10) * 1000;
const startupCheckMaxTries = parseInt(STARTUP_CHECK_MAX_TRIES, 10);
const maxBodySize = parseInt(MAX_BODY_SIZE_MB, 10) * 1024 * 1024;

// type for {string: string}
const alwaysRestartComfyUI = ALWAYS_RESTART_COMFYUI.toLowerCase() === "true";

const loadEnvCommand: Record<string, string> = {
"ai-dock": `source /opt/ai-dock/etc/environment.sh \
Expand Down Expand Up @@ -71,6 +71,11 @@ interface ComfyDescription {
schedulers: string[];
}

/**
* This function uses python to import some of the ComfyUI code and get the
* description of the samplers and schedulers.
* @returns ComfyDescription
*/
function getComfyUIDescription(): ComfyDescription {
const temptComfyFilePath = path.join(comfyDir, "temp_comfy_description.json");
const pythonCode = `
Expand Down Expand Up @@ -131,6 +136,7 @@ const config = {
comfyHost: DIRECT_ADDRESS,
comfyPort: COMFYUI_PORT_HOST,
comfyURL,
alwaysRestartComfyUI,
wsClientId,
comfyWSURL,
startupCheckInterval,
Expand Down
Loading
Loading