init wiki (#2)
* init the wiki (tutorials, node references) * add simple nodes: ConvertToAny, ResolutionToDims
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
# Node reference
|
||||
|
||||
**[Output Config (Load / Retrieve)](./output%20config.md)**
|
||||
|
||||
**[XY Plot](./xy%20plot/)**:
|
||||
|
||||
- [00 - Core concepts](./xy%20plot/00%20-%20core%20concepts.md)
|
||||
|
||||
**[Format (String / Multiline)](./format.md)**
|
||||
@@ -0,0 +1,58 @@
|
||||
# Node reference: Format (String / Multiline)
|
||||
|
||||
**[>> Link to the tutorials](../tutorials/Format/)**
|
||||
|
||||
## Overview
|
||||
|
||||
The `Format` nodes are very simple yet powerful nodes, that are based on the **standard Python string `format()` method**.\
|
||||
They exist in 2 flavors: `String` or `Multiline`.
|
||||
|
||||
They are useful to create a string from a template, and **any number of inputs**.\
|
||||
Inputs can be of the following ConfyUI types: `STRING`, `INT`, `FLOAT`, `BOOLEAN`.
|
||||
|
||||
## How to use
|
||||
|
||||
Here we will just cover the most basic usage, but please note that Python string `format()` allows to do very interesting things, beyond the standard string replacement: padding, truncating, ...
|
||||
|
||||
### Simple usage
|
||||
|
||||
The node takes any number of inputs, that are automatically incremented: `arg0`, `arg1`, ...
|
||||
|
||||
Given the following template: `first arg by name: {arg0}, second by index: {1}`, and 2 input string (`tata` and `toto`), we will get the resulting string: `first arg by name: tata, second by index: toto`.
|
||||
|
||||
Here we see that **we can reference the inputs either by their name (`argN`), or by their index (starting at 0)**.\
|
||||
Straightforward, isn't it?
|
||||
|
||||
This way, it's **very simple to concatenate 2 strings, append text to a string, ... many operations in one single node!**
|
||||
|
||||
And last but not least: at stated above, it can take **other types than strings: integer, float, boolean** (and surely others).
|
||||
|
||||
### Going further
|
||||
|
||||
For more details and advanced techniques, you can check:
|
||||
|
||||
- [the tutorials of the `Format` nodes](../tutorials/Format/)
|
||||
- [a guide with different possible techniques (padding, ...)](https://pyformat.info/)
|
||||
- [the official page on python.org](https://docs.python.org/3/tutorial/inputoutput.html#the-string-format-method)
|
||||
|
||||
## Inputs / Widgets / Outputs
|
||||
|
||||
### Inputs (unlimited)
|
||||
|
||||
| input name | type | description | comment |
|
||||
| :--------: | :-------------------------: | :---------: | :--------------------------------- |
|
||||
| arg0 | STRING, INT, FLOAT, BOOLEAN | input value | can also be referenced by index: 0 |
|
||||
| ... | | | |
|
||||
| argN | STRING, INT, FLOAT, BOOLEAN | input value | can also be referenced by index: N |
|
||||
|
||||
### Widgets
|
||||
|
||||
| widget name | type | description | comment |
|
||||
| :---------: | :----: | :-------------: | :------ |
|
||||
| format | STRING | template string | |
|
||||
|
||||
### Outputs
|
||||
|
||||
| output name | type | description | comment |
|
||||
| :---------: | :----: | :------------------------: | :------ |
|
||||
| formatted | STRING | result string after format | |
|
||||
@@ -0,0 +1,79 @@
|
||||
# Node reference: Output Config
|
||||
|
||||
**[>> Link to the tutorials](../tutorials/Output%20Config/)**
|
||||
|
||||
## Overview
|
||||
|
||||
The `Output Config: Load` (and its backend counterpart, `Output Config: Retrieve`) is very different from other nodes: it allows you to load config files and **dynamically create any number of custom outputs**, that you can later connect to other nodes before executing the workflow.
|
||||
|
||||
It opens a whole range of use cases: whether you need to standardize tests (LoRA, ...), store a collection of usual use cases, or just share your configs with others, this node can certainly prove very useful.\
|
||||
**You can define any number of outputs in it, to match your specific needs**.
|
||||
|
||||
A config file is a simple text file in one of the following formats: **JSON, JSON5 or YAML** (and also the unofficial JSONC, aka 'json with comments').
|
||||
|
||||
A config can be very simple:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"seed": 618896223111156, // value can be set directly
|
||||
"cfg": {
|
||||
"value": 7.5, // or inside a dictionary, with the 'value' key
|
||||
},
|
||||
"steps": 40,
|
||||
// add all the outputs you need, name them as you wish
|
||||
}
|
||||
```
|
||||
|
||||
But it can be extended, **to customize the label, color, shape, and even the type of the output**.\
|
||||
Here a more advanced example (written in YAML):
|
||||
|
||||
```yaml
|
||||
seed:
|
||||
value: 618896223111156
|
||||
shape: box
|
||||
color_off: '#FF0000' # when not connected
|
||||
color_on: '#00FF00' # when connected
|
||||
cfg:
|
||||
value: 7.5
|
||||
shape: circle # default shape
|
||||
color_off: blue # we can set colors by name
|
||||
steps:
|
||||
value: 40
|
||||
shape: arrow
|
||||
color_off: '#dcb21a'
|
||||
prompt:
|
||||
value: illuminated pirate ship sailing on a sea with a galaxy in the sky
|
||||
label: a basic prompt but a custom label
|
||||
shape: grid
|
||||
color_off: '#28cfcd'
|
||||
checkpoint:
|
||||
value: sd_xl_base_1.0.safetensors
|
||||
type: '*' # '*' means any type, use it as a last resort
|
||||
```
|
||||
|
||||
## Load vs Retrieve: which one should I choose?
|
||||
|
||||
The `Output Config: Load` and `Output Config: Retrieve` are very similar.\
|
||||
The only difference is that the latter allows you to get a file located in the backend machine, while the former is to load a file where the browser is running.
|
||||
|
||||
**If your frontend (browser) is running on the same machine as the backend (as probably many of us), you certainly should choose the `Load` version**: it is more interactive and easier to use.\
|
||||
The `Retrieve` version is probably only useful in some rare cases, but it's here if needed.
|
||||
|
||||
## Widgets
|
||||
|
||||
### Output Config: Load
|
||||
|
||||
| widget label | type | description | comment |
|
||||
| :----------------: | :----: | :---------------------------------------------------: | :------------------------------------------------------------------------------------------------ |
|
||||
| Load output config | button | get and validate the file<br/>then create the outputs | |
|
||||
| display errors | combo | how to display errors | available options:<br/>- in browser console (F12)<br/>- in a popup (default)<br/>- do not display |
|
||||
| show config | toggle | show / hide the file preview | |
|
||||
|
||||
### Output Config: Retrieve (backend)
|
||||
|
||||
| widget label | type | description | comment |
|
||||
| :-------------------------: | :----: | :---------------------------------------------------: | :------------------------------------------------------------------------------------------------ |
|
||||
| JSON or YAML file (backend) | text | full path to the config file<br/>in backend machine | |
|
||||
| Retrieve output config | button | get and validate the file<br/>then create the outputs | |
|
||||
| display errors | combo | how to display errors | available options:<br/>- in browser console (F12)<br/>- in a popup (default)<br/>- do not display |
|
||||
| show config | toggle | show / hide the file preview | |
|
||||
@@ -0,0 +1,73 @@
|
||||
# Node reference / XY Plot: 00 - Core concepts
|
||||
|
||||
As a minimum, to use the `XY Plot`, you need to integrate 2 nodes, `XY Plot: Queue` and `XY Plot: Render`: the first one will organize the queue, the second one will render the grid(s).
|
||||
|
||||

|
||||
|
||||
They must be connected by the specific `XY plot data` link : that is the way the queue can inform the render node about the current processing state.
|
||||
|
||||
What is processed between them (from `dim1 value` / `dim2 value` outputs of `Queue` to `image` input in `Render`) is for you to choose: as such, **the ComfyLab's XY Plot approach is totally process-independent**.
|
||||
|
||||
## XY Plot: Queue
|
||||
|
||||
As you can see in the screenshot, there is no concept of row / column or X / Y here, as in many other plot / grid implementations:
|
||||
|
||||
- instead, we talk about `dim1` and `dim2` (dimensions 1 & 2)
|
||||
- this is intended, to improve performance: but we'll talk about that later
|
||||
- just remember this rule: **for a given `dim1` value, we process all values of `dim2` before switching to the next `dim1` value**
|
||||
- whether `dim1` and `dim2` are rows or columns is configured later, in the `Render` node (`direction` toggle)
|
||||
- `dim1` and `dim2` (optional) **take lists as inputs**
|
||||
- in ComfyUI, a LIST is a LIST, but we cannot know if it's a list of strings, numbers, images, ...
|
||||
- so another important rule: **what you send is what you get**
|
||||
- said differently: if you send a list of numbers, you will get number values in output
|
||||
- or one could say: sh\*t in, sh\*t out...
|
||||
- for the reason above, the `Queue` node cannot determine what it will get in input, so the type of the outputs is set to `"*"` (Any)
|
||||
- this makes the `dim1 value` and `dim2 value` outputs very flexible, as you can basically connect them anywhere
|
||||
- but it comes at a price: **you must ensure that the data in input correspond to the expected data in output**
|
||||
- for example: if you connect `dim1 value` to the `cfg` input of `KSampler`, you must ensure that the input list is a list of floats. If you send strings, you will obviously get an error when running the workflow
|
||||
- one of the main features of the `Queue` node is **auto-queuing**
|
||||
- no need to reset a counter, or manually increase the batch size
|
||||
- **the `Queue` node will take care of that for you**
|
||||
- in fact, you should definitely **not set the batch size to anything else than `1`**
|
||||
|
||||
## XY Plot: Render
|
||||
|
||||
The `Render` node, in its default configuration is easier to understand:
|
||||
|
||||
- it takes an `image` as input, for example the result of the `KSampler` processing
|
||||
- <ins>important</ins>: you are not limited to KSampler
|
||||
- in fact **you can do what you want between the `Queue` node and the `Render` one**
|
||||
- it could be loading the image from a folder, doing some image transformations... you decide
|
||||
- it has 2 outputs:
|
||||
- `image` is the single image, as received in input
|
||||
- `grid` is the generated grid, when it has received enough images
|
||||
- obviously, you can generate multiple grids, if you configure pagination in the `Queue` node
|
||||
|
||||
## dim1 vs dim2, which one should I choose? (or the Performance Question)
|
||||
|
||||
As seen above, connecting an input list on either `dim1` or `dim2` doesn't determine if data will be displayed as rows or columns: you can simply switch the `direction` in the `Render` node.
|
||||
|
||||
So, what does it change?\
|
||||
In the most simple cases, for example if you plot `CFG` vs `seed`, it should not have any visible impact.
|
||||
|
||||
But now, imagine a more advanced case: I want to plot a given list of 3 seeds vs a list of 3 checkoints with the default `KSampler` workflow.\
|
||||
Let's recall the rule above: **for a given `dim1` value, we process all values of `dim2` before switching to the next `dim1` value**.\
|
||||
That means that, if I set the list of seeds in `dim1`, the process will work as follows:
|
||||
|
||||
- get seed #1, get checkpoint #1 > <ins>load checkpoint #1</ins> > render image
|
||||
- **keep** seed #1, get checkpoint #2 > <ins>load checkpoint #2</ins> > render image
|
||||
- **keep** seed #1, get checkpoint #3 > <ins>load checkpoint #3</ins> > render image
|
||||
- get seed #2, get checkpoint #1 > <ins>load checkpoint #1</ins> > render image
|
||||
- ...
|
||||
|
||||
Loading a checkpoint is a costly operation, in terms of performance: we don't want to load a new checkpoint at each and every iteration.\
|
||||
So let's switch, connecting the list of checkpoints to `dim1`, and the list of seeds to `dim2`:
|
||||
|
||||
- get checkpoint #1, get seed #1 > <ins>load checkpoint #1</ins> > render image
|
||||
- **keep** checkpoint #1, get seed #2 > _do not load checkpoint #1_ (it's in memory) > render image
|
||||
- **keep** checkpoint #1, get seed #3 > _do not load checkpoint #1_ (it's in memory) > render image
|
||||
- ...
|
||||
|
||||
By doing so, we optimize the performance as much as possible.\
|
||||
So as a general rule: **if you need to vary models (checkpoint, LoRA, ...), ensure these values are connected to `dim1`**.\
|
||||
(And if you vary 2 lists of models, obviously choose the slowest as `dim1`).
|
||||
@@ -0,0 +1,21 @@
|
||||
# Node reference / XY Plot: 01 - Queue and Render
|
||||
|
||||
**Work in Progress**
|
||||
|
||||
## Node overview
|
||||
|
||||

|
||||
|
||||
### XY Plot: Render
|
||||
|
||||
As per the widgets:
|
||||
|
||||
- `dim1: header format` and `dim2: header format`
|
||||
- enter here a template string, following the syntax of Python string `format()` method
|
||||
- the `{dim1}` and `{dim2}` placeholders will be replaced by the current dim1 / dim2 value
|
||||
- very handy if you want to prefix the row / column headers, for example:
|
||||
- if you have CFG values in dim1, by default the headers will be `7.5`, `8`, ...
|
||||
- just change the dim1 header format to `CFG: {dim1}` and you will get: `CFG: 7.5`, `CFG: 8`, ...
|
||||
- there are plenty of advanced techniques, but you will probably not use them here
|
||||
- however if you want to learn more, you can check the [`Format` node reference](../format.md)
|
||||
- `direction`: whether dim1 values are displayed as rows, or columns
|
||||
@@ -0,0 +1,3 @@
|
||||
# Node reference / XY Plot: 02 - Config nodes
|
||||
|
||||
**Work in Progress**
|
||||
@@ -0,0 +1,3 @@
|
||||
# Node reference / XY Plot
|
||||
|
||||
[00 - Core concepts](./00%20-%20core%20concepts.md)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 37 KiB |
Reference in New Issue
Block a user