kiri-art / docker-diffusers-api

Diffusers / Stable Diffusion in docker with a REST API, supporting various models, pipelines & schedulers.
https://kiri.art/
MIT License
203 stars 94 forks source link
bananaml diffusers docker serverless stable-diffusion

docker-diffusers-api ("banana-sd-base")

Diffusers / Stable Diffusion in docker with a REST API, supporting various models, pipelines & schedulers. Used by kiri.art, perfect for local, server & serverless.

Docker CircleCI semantic-release MIT License Open in Dev Containers

Copyright (c) Gadi Cohen, 2022. MIT Licensed. Please give credit and link back to this repo if you use it in a public project.

Features

Note: This image was created for kiri.art. Everything is open source but there may be certain request / response assumptions. If anything is unclear, please open an issue.

Important Notices

Official help in our dedicated forum https://forums.kiri.art/c/docker-diffusers-api/16.

This README refers to the in-development dev branch and may reference features and fixes not yet in the published releases.

v1 has not yet been officially released yet but has been running well in production on kiri.art for almost a month. We'd be grateful for any feedback from early adopters to help make this official. For more details, see Upgrading from v0 to v1. Previous releases available on the dev-v0-final and main-v0-final branches.

Currently only NVIDIA / CUDA devices are supported. Tracking Apple / M1 support in issue #20.

Installation & Setup:

Setup varies depending on your use case.

  1. To run locally or on a server, with runtime downloads:

    docker run --gpus all -p 8000:8000 -e HF_AUTH_TOKEN=$HF_AUTH_TOKEN gadicc/diffusers-api.

    See the guides for various cloud providers.

  2. To run serverless, include the model at build time:

    1. docker-diffusers-api-build-download ( banana, others)
    2. docker-diffusers-api-runpod, see the guide
  3. Building from source.

    1. Fork / clone this repo.
    2. docker build -t gadicc/diffusers-api .
    3. See CONTRIBUTING.md for more helpful hints.

Other configurations are possible but these are the most common cases

Everything is set via docker build-args or environment variables.

Usage:

See also Testing below.

The container expects an HTTP POST request to /, with a JSON body resembling the following:

{
  "modelInputs": {
    "prompt": "Super dog",
    "num_inference_steps": 50,
    "guidance_scale": 7.5,
    "width": 512,
    "height": 512,
    "seed": 3239022079
  },
  "callInputs": {
    // You can leave these out to use the default
    "MODEL_ID": "runwayml/stable-diffusion-v1-5",
    "PIPELINE": "StableDiffusionPipeline",
    "SCHEDULER": "LMSDiscreteScheduler",
    "safety_checker": true,
  },
}

It's important to remember that docker-diffusers-api is primarily a wrapper around HuggingFace's diffusers library. Basic familiarity with diffusers is indespensible for a good experience with docker-diffusers-api. Explaining some of the options above:

Examples and testing

There are also very basic examples in test.py, which you can view and call python test.py if the container is already running on port 8000. You can also specify a specific test, change some options, and run against a deployed banana image:

$ python test.py
Usage: python3 test.py [--banana] [--xmfe=1/0] [--scheduler=SomeScheduler] [all / test1] [test2] [etc]

# Run against http://localhost:8000/ (Nvidia Quadro RTX 5000)
$ python test.py txt2img
Running test: txt2img
Request took 5.9s (init: 3.2s, inference: 5.9s)
Saved /home/dragon/www/banana/banana-sd-base/tests/output/txt2img.png

# Run against deployed banana image (Nvidia A100)
$ export BANANA_API_KEY=XXX
$ BANANA_MODEL_KEY=XXX python3 test.py --banana txt2img
Running test: txt2img
Request took 19.4s (init: 2.5s, inference: 3.5s)
Saved /home/dragon/www/banana/banana-sd-base/tests/output/txt2img.png

# Note that 2nd runs are much faster (ignore init, that isn't run again)
Request took 3.0s (init: 2.4s, inference: 2.1s)

The best example of course is https://kiri.art/ and it's source code.

Help on Official Forums.

Adding other Models

You have two options.

  1. For a diffusers model, simply set MODEL_ID build-var / call-arg to the name of the model hosted on HuggingFace, and it will be downloaded automatically at build time.

  2. For a non-diffusers model, simply set the CHECKPOINT_URL build-var / call-arg to the URL of a .ckpt file, which will be downloaded and converted to the diffusers format automatically at build time. CHECKPOINT_CONFIG_URL can also be set.

Troubleshooting

Event logs / web hooks / performance data

Set SEND_URL (and optionally SIGN_KEY) environment variable(s) to send event and timing data on init, inference and other start and end events. This can either be used to log performance data, or for webhooks on event start / finish.

The timing data is now returned in the response payload too, like this: { $timings: { init: timeInMs, inference: timeInMs } }, with any other events (such a training, upload, etc).

You can go to https://webhook.site/ and use the provided "unique URL" as your SEND_URL to see how it works, if you don't have your own REST endpoint (yet).

If SIGN_KEY is used, you can verify the signature like this (TypeScript):

import crypto from "crypto";

async function handler(req: NextApiRequest, res: NextApiResponse) {
  const data = req.body;

  const containerSig = data.sig as string;
  delete data.sig;

  const ourSig = crypto
    .createHash("md5")
    .update(JSON.stringify(data) + process.env.SIGN_KEY)
    .digest("hex");

  const signatureIsValid = containerSig === ourSig;
}

If you send a callInput called startRequestId, it will get sent back as part of the send payload in most cases.

You can also set callInputs SEND_URL and SIGN_KEY to set or override these values on a per-request basis.

Acknowledgements