Commit Graph

285 Commits

Author SHA1 Message Date
Dmitry Parnas
aa82f9360c fix(ui): passing Promise into ClipboardItem to make it work in Safari
throwing Error in getBaseLayerBlob, instead of returning nil
using copyBlobToClipboard for both Canvas and Text2Image clipboard functionality
2023-09-21 23:36:05 +10:00
psychedelicious
9faa53ceb1
feat(ui): consolidate advanced params (#4599) 2023-09-21 00:19:31 +10:00
psychedelicious
32672cfeda
ui: misc small fixes (#4600)
* feat(ui): tweak queue UI components

* fix(ui): manually dispatch queue status query on queue item status change

RTK Query occasionally aborts the query that occurs when the tag is invalidated, especially if multples of them fire in rapid succession.

This resulted in the queue status and progress bar sometimes not reseting when the queue finishes its last item.

Manually dispatch the query now to get around this. Eventually should probably move this to a socket so we don't need to keep responding to socket with HTTP requests. Just send ti directly via socket

* chore(ui): remove errant console.logs

* fix(ui): do not accumulate node outputs in outputs area

* fix(ui): fix merge issue

---------

Co-authored-by: Kent Keirsey <31807370+hipsterusername@users.noreply.github.com>
2023-09-21 00:15:39 +10:00
psychedelicious
b7938d9ca9
feat: queued generation (#4502)
* fix(config): fix typing issues in `config/`

`config/invokeai_config.py`:
- use `Optional` for things that are optional
- fix typing of `ram_cache_size()` and `vram_cache_size()`
- remove unused and incorrectly typed method `autoconvert_path`
- fix types and logic for `parse_args()`, in which `InvokeAIAppConfig.initconf` *must* be a `DictConfig`, but function would allow it to be set as a `ListConfig`, which presumably would cause issues elsewhere

`config/base.py`:
- use `cls` for first arg of class methods
- use `Optional` for things that are optional
- fix minor type issue related to setting of `env_prefix`
- remove unused `add_subparser()` method, which calls `add_parser()` on an `ArgumentParser` (method only available on the `_SubParsersAction` object, which is returned from ArgumentParser.add_subparsers()`)

* feat: queued generation and batches

Due to a very messy branch with broad addition of `isort` on `main` alongside it, some git surgery was needed to get an agreeable git history. This commit represents all of the work on queued generation. See PR for notes.

* chore: flake8, isort, black

* fix(nodes): fix incorrect service stop() method

* fix(nodes): improve names of a few variables

* fix(tests): fix up tests after changes to batches/queue

* feat(tests): add unit tests for session queue helper functions

* feat(ui): dynamic prompts is always enabled

* feat(queue): add queue_status_changed event

* feat(ui): wip queue graphs

* feat(nodes): move cleanup til after invoker startup

* feat(nodes): add cancel_by_batch_ids

* feat(ui): wip batch graphs & UI

* fix(nodes): remove `Batch.batch_id` from required

* fix(ui): cleanup and use fixedCacheKey for all mutations

* fix(ui): remove orphaned nodes from canvas graphs

* fix(nodes): fix cancel_by_batch_ids result count

* fix(ui): only show cancel batch tooltip when batches were canceled

* chore: isort

* fix(api): return `[""]` when dynamic prompts generates no prompts

Just a simple fallback so we always have a prompt.

* feat(ui): dynamicPrompts.combinatorial is always on

There seems to be little purpose in using the combinatorial generation for dynamic prompts. I've disabled it by hiding it from the UI and defaulting combinatorial to true. If we want to enable it again in the future it's straightforward to do so.

* feat: add queue_id & support logic

* feat(ui): fix upscale button

It prepends the upscale operation to queue

* feat(nodes): return queue item when enqueuing a single graph

This facilitates one-off graph async workflows in the client.

* feat(ui): move controlnet autoprocess to queue

* fix(ui): fix non-serializable DOMRect in redux state

* feat(ui): QueueTable performance tweaks

* feat(ui): update queue list

Queue items expand to show the full queue item. Just as JSON for now.

* wip threaded session_processor

* feat(nodes,ui): fully migrate queue to session_processor

* feat(nodes,ui): add processor events

* feat(ui): ui tweaks

* feat(nodes,ui): consolidate events, reduce network requests

* feat(ui): cleanup & abstract queue hooks

* feat(nodes): optimize batch permutation

Use a generator to do only as much work as is needed.

Previously, though we only ended up creating exactly as many queue items as was needed, there was still some intermediary work that calculated *all* permutations. When that number was very high, the system had a very hard time and used a lot of memory.

The logic has been refactored to use a generator. Additionally, the batch validators are optimized to return early and use less memory.

* feat(ui): add seed behaviour parameter

This dynamic prompts parameter allows the seed to be randomized per prompt or per iteration:
- Per iteration: Use the same seed for all prompts in a single dynamic prompt expansion
- Per prompt: Use a different seed for every single prompt

"Per iteration" is appropriate for exploring a the latents space with a stable starting noise, while "Per prompt" provides more variation.

* fix(ui): remove extraneous random seed nodes from linear graphs

* fix(ui): fix controlnet autoprocess not working when queue is running

* feat(queue): add timestamps to queue status updates

Also show execution time in queue list

* feat(queue): change all execution-related events to use the `queue_id` as the room, also include `queue_item_id` in InvocationQueueItem

This allows for much simpler handling of queue items.

* feat(api): deprecate sessions router

* chore(backend): tidy logging in `dependencies.py`

* fix(backend): respect `use_memory_db`

* feat(backend): add `config.log_sql` (enables sql trace logging)

* feat: add invocation cache

Supersedes #4574

The invocation cache provides simple node memoization functionality. Nodes that use the cache are memoized and not re-executed if their inputs haven't changed. Instead, the stored output is returned.

## Results

This feature provides anywhere some significant to massive performance improvement.

The improvement is most marked on large batches of generations where you only change a couple things (e.g. different seed or prompt for each iteration) and low-VRAM systems, where skipping an extraneous model load is a big deal.

## Overview

A new `invocation_cache` service is added to handle the caching. There's not much to it.

All nodes now inherit a boolean `use_cache` field from `BaseInvocation`. This is a node field and not a class attribute, because specific instances of nodes may want to opt in or out of caching.

The recently-added `invoke_internal()` method on `BaseInvocation` is used as an entrypoint for the cache logic.

To create a cache key, the invocation is first serialized using pydantic's provided `json()` method, skipping the unique `id` field. Then python's very fast builtin `hash()` is used to create an integer key. All implementations of `InvocationCacheBase` must provide a class method `create_key()` which accepts an invocation and outputs a string or integer key.

## In-Memory Implementation

An in-memory implementation is provided. In this implementation, the node outputs are stored in memory as python classes. The in-memory cache does not persist application restarts.

Max node cache size is added as `node_cache_size` under the `Generation` config category.

It defaults to 512 - this number is up for discussion, but given that these are relatively lightweight pydantic models, I think it's safe to up this even higher.

Note that the cache isn't storing the big stuff - tensors and images are store on disk, and outputs include only references to them.

## Node Definition

The default for all nodes is to use the cache. The `@invocation` decorator now accepts an optional `use_cache: bool` argument to override the default of `True`.

Non-deterministic nodes, however, should set this to `False`. Currently, all random-stuff nodes, including `dynamic_prompt`, are set to `False`.

The field name `use_cache` is now effectively a reserved field name and possibly a breaking change if any community nodes use this as a field name. In hindsight, all our reserved field names should have been prefixed with underscores or something.

## One Gotcha

Leaf nodes probably want to opt out of the cache, because if they are not cached, their outputs are not saved again.

If you run the same graph multiple times, you only end up with a single image output, because the image storage side-effects are in the `invoke()` method, which is bypassed if we have a cache hit.

## Linear UI

The linear graphs _almost_ just work, but due to the gotcha, we need to be careful about the final image-outputting node. To resolve this, a `SaveImageInvocation` node is added and used in the linear graphs.

This node is similar to `ImagePrimitive`, except it saves a copy of its input image, and has `use_cache` set to `False` by default.

This is now the leaf node in all linear graphs, and is the only node in those graphs with `use_cache == False` _and_ the only node with `is_intermedate == False`.

## Workflow Editor

All nodes now have a footer with a new `Use Cache [ ]` checkbox. It defaults to the value set by the invocation in its python definition, but can be changed by the user.

The workflow/node validation logic has been updated to migrate old workflows to use the new default values for `use_cache`. Users may still want to review the settings that have been chosen. In the event of catastrophic failure when running this migration, the default value of `True` is applied, as this is correct for most nodes.

Users should consider saving their workflows after loading them in and having them updated.

## Future Enhancements - Callback

A future enhancement would be to provide a callback to the `use_cache` flag that would be run as the node is executed to determine, based on its own internal state, if the cache should be used or not.

This would be useful for `DynamicPromptInvocation`, where the deterministic behaviour is determined by the `combinatorial: bool` field.

## Future Enhancements - Persisted Cache

Similar to how the latents storage is backed by disk, the invocation cache could be persisted to the database or disk. We'd need to be very careful about deserializing outputs, but it's perhaps worth exploring in the future.

* fix(ui): fix queue list item width

* feat(nodes): do not send the whole node on every generator progress

* feat(ui): strip out old logic related to sessions

Things like `isProcessing` are no longer relevant with queue. Removed them all & updated everything be appropriate for queue. May be a few little quirks I've missed...

* feat(ui): fix up param collapse labels

* feat(ui): click queue count to go to queue tab

* tidy(queue): update comment, query format

* feat(ui): fix progress bar when canceling

* fix(ui): fix circular dependency

* feat(nodes): bail on node caching logic if `node_cache_size == 0`

* feat(nodes): handle KeyError on node cache pop

* feat(nodes): bypass cache codepath if caches is disabled

more better no do thing

* fix(ui): reset api cache on connect/disconnect

* feat(ui): prevent enqueue when no prompts generated

* feat(ui): add queue controls to workflow editor

* feat(ui): update floating buttons & other incidental UI tweaks

* fix(ui): fix missing/incorrect translation keys

* fix(tests): add config service to mock invocation services

invoking needs access to `node_cache_size` to occur

* optionally remove pause/resume buttons from queue UI

* option to disable prepending

* chore(ui): remove unused file

* feat(queue): remove `order_id` entirely, `item_id` is now an autoinc pk

---------

Co-authored-by: Mary Hipp <maryhipp@Marys-MacBook-Air.local>
2023-09-20 15:09:24 +10:00
psychedelicious
f6738d647e fix(ui): store customStarUI outside redux
JSX is not serializable, so it cannot be in redux. Non-serializable global state may be put into `nanostores`.

- Use `nanostores` for `customStarUI`
- Use `nanostores` for `headerComponent`
- Re-enable the serializable & immutable check redux middlewares
2023-09-14 12:13:03 +10:00
Mary Hipp Rogers
d989c7fa34
add option for custom star ui (#4530)
Co-authored-by: Mary Hipp <maryhipp@Marys-MacBook-Air.local>
2023-09-13 20:48:10 +00:00
mickr777
8c63173b0c
Translation update (#4503)
* Update Translations

* Fix Prettier Issue

* Fix Error in invokebutton.tsx

* More Translations

* few Fixes

* More Translations

* More Translations and lint Fixes

* Update constants.ts

Revert "Update constants.ts"

---------

Co-authored-by: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
2023-09-13 17:31:34 +10:00
blessedcoolant
95f44ff343 fix: Make the name extraction work for both ckpts and folders 2023-09-04 10:52:27 +12:00
blessedcoolant
f9c3c07d98 fix: Support UNIX paths 2023-09-04 10:16:57 +12:00
blessedcoolant
c91ba2dbe7 feat: Infer Model Name automatically if empty in Model Forms 2023-09-04 01:36:48 +12:00
blessedcoolant
8d4caaabb0 ui: Simply collapse spacing 2023-08-30 08:40:17 +12:00
blessedcoolant
4fd4aee2ab feat: Auto Change Dimensions on Model Switch by Type 2023-08-30 05:49:57 +12:00
blessedcoolant
9afc909ff0 ui: tweak parameter options spacing 2023-08-30 05:22:44 +12:00
blessedcoolant
98e905ee48 ui: Combine mask and coherence under Compositing 2023-08-30 04:51:32 +12:00
blessedcoolant
b5dac99411 feat: Add Seamless To Canvas Text To Image / Image To Image + SDXL + Refiner 2023-08-29 04:26:11 +12:00
psychedelicious
40e6dd8464 feat(ui): use seed + 1 for second inpaint/outpaint pass 2023-08-23 23:05:29 -04:00
blessedcoolant
7e4009a58e chore: Rename canvas refine elements to have more apt names 2023-08-23 23:05:29 -04:00
blessedcoolant
0af8a0e84b feat: Replace Seam Painting with Refine Pass for Outpainting 2023-08-23 23:05:29 -04:00
psychedelicious
955fef35aa chore(ui): remove cruft related to old canvas scaling method 2023-08-23 23:06:42 +10:00
psychedelicious
6efa953172 fix(ui): fix canvas scaling 2023-08-23 23:06:42 +10:00
psychedelicious
05c939d41e feat(ui): remove canvas beta layout 2023-08-23 23:06:42 +10:00
psychedelicious
cfee02b753 feat(ui): align invoke buttons 2023-08-23 23:06:42 +10:00
psychedelicious
0cb886b915 feat(ui): node buttons and shadow 2023-08-23 23:06:42 +10:00
psychedelicious
90abd0fe49 fix(ui): position floating buttons 2023-08-23 23:06:42 +10:00
psychedelicious
73318c2847 feat(ui): remove floating panels, move all to resizable panels
There is a console error we can ignore when toggling gallery panel on canvas - this will be resolved in the next release of the resizable library
2023-08-23 23:06:42 +10:00
psychedelicious
7b97754271 chore(ui): update all packages
- only breaking change was in `openapi-fetch`, easy fix
- also looks like prettier/eslint is a bit more comprehensive? caught a couple extra things
2023-08-23 23:06:42 +10:00
psychedelicious
01738deb23 feat(ui): add eslint rules
- `curly` requires conditionals to use curly braces
- `react/jsx-curly-brace-presence` requires string props to *not* have curly braces
2023-08-21 19:17:36 +10:00
psychedelicious
fbff22c94b feat(ui): memoize all components 2023-08-21 19:17:36 +10:00
psychedelicious
9332ce639c fix(ui): fix node mouse interactions
Add "nodrag", "nowheel" and "nopan" class names in interactable elements, as neeeded. This fixes the mouse interactions and also makes the node draggable from anywhere without needing shift.

Also fixes ctrl/cmd multi-select to support deselecting.
2023-08-21 19:17:36 +10:00
blessedcoolant
975586bb40 Merge branch 'main' into seam-painting 2023-08-17 01:05:42 +12:00
psychedelicious
70b8c3dfea fix(ui): fix context menu on workflow editor
There is a tricky mouse event interaction between chakra's `useOutsideClick()` hook (used by chakra `<Menu />`) and reactflow. The hook doesn't work when you click the main reactflow area.

To get around this, I've used a dirty hack, copy-pasting the simple context menu component we use, and extending it slightly to respond to a global `contextMenusClosed` redux action.
2023-08-16 23:04:36 +10:00
blessedcoolant
e98d7a52d4 feat: Add Seam Painting Options 2023-08-16 17:25:55 +12:00
psychedelicious
f49fc7fb55 feat: node editor
squashed rebase on main after backendd refactor
2023-08-16 09:54:38 +10:00
blessedcoolant
7293a6036a feat(wip): Add SDXL To Canvas 2023-08-12 08:16:05 +12:00
blessedcoolant
1affb7f647 feat: Add Paste / Mask Blur / Color Correction to Inpainting
Seam options are now removed. They are replaced by two options --Mask Blur and Mask Blur Method .. which control the softness of the mask that is being painted.
2023-08-12 03:28:19 +12:00
psychedelicious
bf94412d14 feat: add multi-select to gallery
multi-select actions include:
- drag to board to move all to that board
- right click to add all to board or delete all

backend changes:
- add routes for changing board for list of image names, deleting list of images
- change image-specific routes to `images/i/{image_name}` to not clobber other routes (like `images/upload`, `images/delete`)
- subclass pydantic `BaseModel` as `BaseModelExcludeNull`, which excludes null values when calling `dict()` on the model. this fixes inconsistent types related to JSON parsing null values into `null` instead of `undefined`
- remove `board_id` from `remove_image_from_board`

frontend changes:
- multi-selection stuff uses `ImageDTO[]` as payloads, for dnd and other mutations. this gives us access to image `board_id`s when hitting routes, and enables efficient cache updates.
- consolidate change board and delete image modals to handle single and multiples
- board totals are now re-fetched on mutation and not kept in sync manually - was way too tedious to do this
- fixed warning about nested `<p>` elements
- closes #4088 , need to handle case when `autoAddBoardId` is `"none"`
- add option to show gallery image delete button on every gallery image

frontend refactors/organisation:
- make typegen script js instead of ts
- enable `noUncheckedIndexedAccess` to help avoid bugs when indexing into arrays, many small changes needed to satisfy TS after this
- move all image-related endpoints into `endpoints/images.ts`, its a big file now, but this fixes a number of circular dependency issues that were otherwise felt impossible to resolve
2023-08-03 11:46:59 +10:00
blessedcoolant
dcc274a2b9 feat: Make ModelListWrapper instead of rendering conditionally 2023-08-01 22:50:10 +10:00
blessedcoolant
f404669831 fix: Rename loading vars for consistency 2023-08-01 22:42:05 +10:00
blessedcoolant
ce687b28ef fix: Model Manager Tab Issues 2023-08-01 22:41:32 +10:00
psychedelicious
fb8f218901 fix(ui): post-onnx fixes 2023-08-01 07:59:01 -04:00
Brandon Rising
8935ae0ea3 Fix issues caused by merge 2023-07-28 14:00:32 -04:00
Brandon Rising
da751da3dd Merge branch 'main' into feat/onnx 2023-07-28 09:59:35 -04:00
blessedcoolant
fd67b18c9a Merge branch 'main' into unify-prompt 2023-07-28 14:48:13 +12:00
Lincoln Stein
aa2c94be9e make LoRAs editable 2023-07-28 11:38:52 +10:00
Alexandre Macabies
10e1d623c3 Add LoRAs to the model manager. 2023-07-28 11:38:52 +10:00
blessedcoolant
3bb81bedbd Merge branch 'main' into unify-prompt 2023-07-28 05:36:04 +12:00
Mary Hipp Rogers
e191f6d4b2
prevent resize error (#4031)
* add upper bound for minWidth to prevent crash with cypress

* add fallback so UI doesnt crash when backend isnt running

---------

Co-authored-by: Mary Hipp <maryhipp@Marys-MacBook-Air.local>
2023-07-27 17:30:31 +00:00
blessedcoolant
b60adc31d0 feat: Unify Prompt Area Design Between SDXL and Regular Models 2023-07-28 03:07:50 +12:00
Brandon Rising
eb1ba8d74b Merge branch 'main' into feat/onnx 2023-07-27 09:54:30 -04:00
Brandon Rising
024f92f9a9 Add onnx models to the model manager UI 2023-07-27 09:37:37 -04:00