Skip to content

Commit

Permalink
Add JSON snippets and screenies for ComfyUI
Browse files Browse the repository at this point in the history
  • Loading branch information
ceruleandeep committed Nov 26, 2024
1 parent 306c37b commit a9409b1
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 10 deletions.
197 changes: 187 additions & 10 deletions extensions/Stable-Diffusion.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,20 +229,175 @@ You can add the API-format JSON file directly to the `data/default-user/user/wor
Retain the original JSON file. If you need to open the workflow again in ComfyUI to make changes, it is much more convenient to edit the original file than the one with all the placeholders.
!!!

#### Pre-defined placeholders
### Placeholders

The editor provides a list of predefined placeholders that can be used in your workflow JSON. These placeholders are replaced with dynamic values when the workflow is executed in SillyTavern.

Placeholders marked with ✅ are present in your workflow JSON. Placeholders marked with ❌ are not present in your workflow JSON. You can add these placeholders to your workflow JSON as needed. You do not need to add all the placeholders, only the ones that your workflow uses and you want to replace dynamically.

#### Prompts

The `%prompt%` and `%negative_prompt%` placeholders are used to insert the image generation prompts into the workflow. These contain the final prompts generated by SillyTavern, including the generated prompt for your chosen `/sd` mode, the common prompt prefix, negative prompt, and character-specific prompt prefix.

The `%model` placeholder will insert the value of the selected model in the image generation settings.
For example, you may have tested your workflow with a prompt like "forest elf" in ComfyUI. To use this workflow in SillyTavern, you can replace the "forest elf" prompt with the `%prompt%` placeholder:

+++ JSON with placeholder
```json
{
"class_type": "CLIPTextEncode",
"inputs": {
"clip": ["4", 1],
"text": "%prompt%"
}
}
```
+++ Original JSON
```json
{
"class_type": "CLIPTextEncode",
"inputs": {
"clip": ["4", 1],
"text": "forest elf"
}
}
```
+++

Notice that the placeholder is wrapped in double quotes. This is important for the JSON format, and required by SillyTavern's placeholder replacement system. Even for numbers, you must use double quotes in the template JSON.

Sometimes the prompt (or other value) doesn't appear where you might expect. ComfyUI will remove nodes from the API version of the workflow if they are not necessary for the workflow to function in API mode.

For instance, this workflow uses a [LoRA tag loader node](https://github.com/badjeff/comfyui_lora_tag_loader) with a prompt primitive so the workflow is clearer in UI mode:

![Prompt primitive and LoRA loader](/static/extensions/sd-comfy-prompt-primitive.png)

The prompt primitive node will be removed from the API version of the workflow, so you insert the placeholder in the LoraTagLoader node. Find the text "apple tree" in the workflow and replace it with the `%prompt%` placeholder:

+++ JSON with placeholder
```json
{
"inputs": {
"text": "%prompt%",
"model": ["112", 0],
"clip": ["112", 1]
},
"class_type": "LoraTagLoader",
"_meta": {"title": "Load LoRA Tag"}
}
```
+++ Original JSON
```json
{
"inputs": {
"text": "apple tree",
"model": ["112", 0],
"clip": ["112", 1]
},
"class_type": "LoraTagLoader",
"_meta": {"title": "Load LoRA Tag"}
}
```
+++

In some cases you may need to make several replacements in the workflow JSON, even if the prompt appears only once in the UI.

#### Model

The `%model%` placeholder will insert the value of the selected model in the image generation settings.

An example from the default text-to-image workflow:

+++ JSON with placeholder
```json
{
"class_type": "CheckpointLoaderSimple",
"inputs": {
"ckpt_name": "%model%"
}
}
```
+++ Original JSON
```json
{
"class_type": "CheckpointLoaderSimple",
"inputs": {
"ckpt_name": "sd15.safetensors"
}
}
```
+++

To load GGUF-quantized UNets, use a [UNet Loader (GGUF)](https://github.com/city96/ComfyUI-GGUF) node in your workflow,
choose a `GGUF` model in the SillyTavern model dropdown, and use the `%model%` placeholder in the node's settings like this:

+++ JSON with placeholder
```json
{
"inputs": {
"unet_name": "%model%"
},
"class_type": "UnetLoaderGGUF",
"_meta": {
"title": "Unet Loader (GGUF)"
}
}
```
+++ Original JSON
```json
{
"inputs": {
"unet_name": "flux1-dev-Q4_0.gguf"
},
"class_type": "UnetLoaderGGUF",
"_meta": {
"title": "Unet Loader (GGUF)"
}
}
```
+++

!!! info Non-standard model types
Stable Diffusion checkpoints, SD UNets, and GGUF-quantized UNets all appear in the Model dropdown. You must ensure that your chosen workflow has the correct loader node for your chosen model type. If not, the error message from ComfyUI will indicate a problem with the loader node, but will not be particularly helpful apart from that.
!!! info If you have model types other than the usual SD checkpoints in ComfyUI
Stable Diffusion checkpoints, SD UNets, and GGUF-quantized UNets all appear in the Model dropdown.
Models of one type will not work with workflows/loader nodes expecting another type.
If you choose an incompatible model type in ST, ComfyUI will report a problem with the loader node.
!!!

#### Avatar images

Use the `%user_avatar%` and `%char_avatar%` placeholders to include the user and character avatars in the workflow. These placeholders are replaced with the PNG data of the avatars when the workflow is executed. The image data is encoded in base64 format, so you must decode it in your workflow. A popular choice for this task is the [Load image (Base64)](https://github.com/Acly/comfyui-tooling-nodes) node.

In this example, the character avatar is loaded with a `Load Image (Base64)` node. It also uses an Image Resize node to rescale the image to whatever size is specified in the image generation settings:

![Load image from base64 string and resize](/static/extensions/sd-comfy-load-b64.png)

Insert the `%char_avatar%`, `%width%`, and `%height%` placeholders into the JSON for the Load Image (Base64) and Image Resize nodes:

```json
{
"97": {
"inputs": {
"image": "%char_avatar%"
},
"class_type": "ETN_LoadImageBase64",
"_meta": {"title": "Load Image (Base64)"}
},
"98": {
"inputs": {
"mode": "resize",
"resize_width": "%width%",
"resize_height": "%height%",
"image": ["97", 0]
},
"class_type": "Image Resize",
"_meta": {"title": "Resize image"}
}
}
```

To get a base64-encoded image string for testing your workflow in ComfyUI, use any online tool that converts images to base64 strings. Here's an example string you can use for initial testing: [sd-base64-test-string.txt](/static/extensions/sd-comfy-base64-test-string.txt).

#### Other placeholders

Most other placeholders use the values of the corresponding controls in image generation settings, or the values that you specify with the `/sd` command:

- `%vae%`, but most SD models include a VAE so the default workflows do not use this placeholder. Use it with custom workflows to load a VAE alongside a UNet, override the default VAE, etc.
Expand All @@ -257,8 +412,6 @@ Most other placeholders use the values of the corresponding controls in image ge

The `%seed%` placeholder will insert the seed value from the control if you have specified one. If you set the seed to `-1`, SillyTavern will generate a new random seed for each image in `%seed%`.

Use the `%user_avatar%` and `%char_avatar%` placeholders to include the user and character avatars in the workflow. These placeholders are replaced with the PNG data of the avatars when the workflow is executed. The image data is encoded in base64 format, so you must decode it in your workflow. A popular choice for this task is the [Load image (Base64)](https://github.com/Acly/comfyui-tooling-nodes) node.

#### Custom placeholders

You can add custom placeholders to your workflow:
Expand All @@ -270,23 +423,47 @@ You can add custom placeholders to your workflow:

Custom placeholders will appear in a separate list below the predefined ones.

For example, you could replace the "SillyTavern" prefix for saved image filenames in the default workflow with a custom placeholder. Add a new custom placeholder with `find` set to `filename_prefix` and `replace` set to `ServiceTesnor`. Insert the new `%filename_prefix%` placeholder into your workflow JSON. Now you can change the filename prefix from SillyTavern to ServiceTesnor by changing the value of the custom placeholder.

+++ JSON with placeholder
```json
{
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "%filename_prefix%",
"images": ["8", 0]
}
}
```
+++ Original JSON
```json
{
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "SillyTavern",
"images": ["8", 0]
}
}
```
+++

### Comfy tricks

Read all the general information on this page so you're familiar with the image generation options. Options such as switchable styles and common prompt prefixes, when combined wih the total flexibility of ComfyUI workflows, allow you to create a wide variety of image generation setups.

#### Loading LoRAs

Use a LoRA tag loader node (such as [Load LoRA Tag](https://github.com/badjeff/comfyui_lora_tag_loader)) to load any LoRAs specified in the prompt. Now you can add as many LoRAs as you like to your prompt with tags like `<lora:CroissantStyle:0.8>`, and they will be loaded into your workflow.
Use a LoRA tag loader node (such as [Load LoRA Tag](https://github.com/badjeff/comfyui_lora_tag_loader)) to load any LoRAs specified in the prompt. Now you can add as many LoRAs as you like to your prompt with tags like `<lora:CroissantStyle:0.8>`, and they will be loaded into your workflow. This will also make the "pro-tip" of using LoRAs in [character-specific prompt prefixes](#character-specific-prompt-prefix) work with ComfyUI.

#### Setting workflow values from styles or slash-commands**
#### Setting workflow values from styles or slash-commands

You can use macros in custom placeholder values. As a practical example, let's say you sometimes want to generate images without a background, and you'd like this to be switchable with a slash-command or image style. Here's how you could do it:

1. Make a ComfyUI workflow that removes the image background, or not, depending on the value of an input
2. Use a custom placeholder to set the value of that input, but use `{{getvar::remove_background}}` as the replace value
2. Use a custom placeholder to set the value of that input, but use <code>\{\{getvar::remove_background}}</code> as the replace value
3. Now you can set the value of `remove_background` with `/setvar key=remove_background true` or `/setvar key=remove_background false` before generating an image
4. The workflow will use the value you set to determine whether to remove the background
5. Make an image style "No background" with common prompt prefix `{{setvar::remove_background::true}}{prompt}`
5. Make an image style "No background" with common prompt prefix <code>\{\{setvar::remove_background::true{prompt}}}</code>
6. Use the style control or `/imagine-style No background` to set the value of `remove_background` to `true` before generating an image


1 change: 1 addition & 0 deletions static/extensions/sd-comfy-base64-test-string.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
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
Binary file added static/extensions/sd-comfy-load-b64.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/extensions/sd-comfy-prompt-primitive.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a9409b1

Please sign in to comment.