Compare commits

..

3613 Commits

Author SHA1 Message Date
987dce801c tidy(ui): organise tool module 2024-08-29 21:46:00 +10:00
f0f6813979 fix(ui): staging hotkeys enabled at wrong times 2024-08-29 21:37:38 +10:00
28b86d3917 fix(ui): incorrect batch origin preventing progress/staging 2024-08-29 21:37:11 +10:00
38e25c45bf feat(ui): restore minimal HUD 2024-08-29 21:30:52 +10:00
978a869a70 feat(ui): remove unused asPreview for StageComponent 2024-08-29 21:27:14 +10:00
2acc5c8317 chore(ui): lint 2024-08-29 19:01:42 +10:00
3fe4b770b8 chore: release v4.2.9.dev8 2024-08-29 18:52:14 +10:00
c800f84c50 feat(ui): revise generation mode logic
- Canvas generation mode is replace with a boolean `sendToCanvas` flag. When off, images generated on the canvas go to the gallery. When on, they get added to the staging area.
- When an image result is received, if its destination is the canvas, staging is automatically started.
- Updated queue list to show the destination column.
- Added `IconSwitch` component to represent binary choices, used for the new `sendToCanvas` flag and image viewer toggle.
- Remove the queue actions menu in `QueueControls`. Move the queue count badge to the cancel button.
- Redo layout of `QueueControls` to prevent duplicate queue count badges.
- Fix issue where gallery and options panels could show thru transparent regions of queue tab.
- Disable panel hotkeys when on mm/queue tabs.
2024-08-29 17:58:02 +10:00
a64dd129f1 chore(ui): typegen 2024-08-29 17:49:15 +10:00
cd4cc56add feat(app): add destination column to session_queue
The frontend needs to know where queue items came from (i.e. which tab), and where results are going to (i.e. send images to gallery or canvas). The `origin` column is not quite enough to represent this cleanly.

A `destination` column provides the frontend what it needs to handle incoming generations.
2024-08-29 17:49:06 +10:00
c19aa0389a tidy(ui): ViewerToggleMenu -> ViewerToggle 2024-08-29 10:58:14 +10:00
fdb125b294 feat(ui): alt quick switches to color picker 2024-08-29 10:52:17 +10:00
686856d111 feat(ui): tweak add entity button layout 2024-08-29 10:43:55 +10:00
fec61ce1ff feat(ui): restore context menu for entity list 2024-08-29 10:35:49 +10:00
bd5780de4d feat(ui): add delete button to each layer 2024-08-29 10:27:55 +10:00
db4782a632 feat(ui): add + buttons to entity categories 2024-08-29 10:15:35 +10:00
c4b2099c4f feat(ui): tweak brush fill UI 2024-08-29 09:07:20 +10:00
ec745f663d feat(ui): do not select layer on staging accept 2024-08-29 09:00:53 +10:00
4f47577076 fix(ui): more fiddly queue count layout stuff 2024-08-29 08:54:07 +10:00
6ee8e13632 fix(ui): floating params panel invoke button loading state 2024-08-29 08:42:22 +10:00
d469b1771e feat(ui): move canvas undo/redo to hook 2024-08-29 08:33:03 +10:00
e79f9782ab fix(ui): queue count badge positioning 2024-08-29 08:13:16 +10:00
ded72e0362 fix(ui): add node cmdk only enabled on workflows tab 2024-08-29 07:47:30 +10:00
37ed567aad chore: release v4.2.9.dev7 2024-08-28 22:05:15 +10:00
9692a5f996 fix(ui): pending node connection stuck 2024-08-28 22:05:03 +10:00
5db7b48cd8 chore(ui): lint 2024-08-28 21:38:57 +10:00
ea014c66ac chore: release v4.2.9.dev6 2024-08-28 21:33:12 +10:00
25918c28aa feat(ui): migrate add node popover to cmdk
Put this together as a way to figure out the library before moving on to the full app cmdk. Works great.
2024-08-28 21:32:10 +10:00
0c60469401 fix(ui): schema parsing now that node_pack is guaranteed to be present 2024-08-28 21:31:15 +10:00
f1aa50f447 chore(ui): typegen 2024-08-28 21:06:45 +10:00
a413b261f0 fix(app): node_pack not added to openapi schema correctly 2024-08-28 21:06:33 +10:00
4a1a6639f6 fix(ui): unnecessary z-index on invoke button 2024-08-28 16:51:44 +10:00
201c370ca1 feat(ui): split settings modal 2024-08-28 16:51:38 +10:00
d070c7c726 perf(ui): disable useInert on modals
This hook forcibly updates _all_ portals with `data-hidden=true` when the modal opens - then reverts it when the modal closes. It's intended to help screen readers. Unfortunately, this absolutely tanks performance because we have many portals. React needs to do alot of layout calculations (not re-renders).

IMO this behaviour is a bug in chakra. The modals which generated the portals are hidden by default, so this data attr should really be set by default. Dunno why it isn't.
2024-08-28 16:49:19 +10:00
e38e20a992 feat(ui): fix queue item count badge positioning
Previously this badge, floating over the queue menu button next to the invoke button, was rendered within the existing layout. When I initially positioned it, the app layout interfered - it would extend into an area reserved for a flex gap, which cut off the badge.

As a (bad) workaround, I had shifted the whole app down a few pixels to make room for it. What I should have done is what I've done in this commit - render the badge in a portal to take it out of the layout so we don't need that extra vertical padding.

Sleekified some styling a bit too.
2024-08-28 16:37:50 +10:00
39a94ec70e fix(ui): transparency effect not updating 2024-08-28 16:08:12 +10:00
c7bfae2d1e feat(ui): tidy canvas toolbar buttons 2024-08-28 16:04:37 +10:00
e7944c427d feat(ui): revised viewer toggle @joshistoast 2024-08-28 16:04:25 +10:00
48ed4e120d fix(ui): opacity reset value incorrect 2024-08-28 16:03:48 +10:00
a5b038a1b1 revert(ui): roll back flip, doesn't work with rotate yet 2024-08-28 12:03:38 +10:00
dc752c98b0 fix(ui): disable opacity slider fully when no valid entity selected 2024-08-28 09:00:55 +10:00
85a47cc6fe fix(ui): layer preview image sometimes not rendering
The canvas size was dynamic based on the container div's size. When the div was hidden (e.g. when selecting another tab), the container's effective size is 0. This resulted in the preview image canvas being drawn at a scale of 0.

Fixed by using an absolute size for the canvas container.
2024-08-28 08:59:38 +10:00
6450f42cfa feat(ui): tweak regional prompt box styles 2024-08-28 08:44:04 +10:00
3876f71ff4 feat(ui): tweak enabled/locked toggle styles 2024-08-28 08:25:37 +10:00
cf819e8eab feat(ui): tweak filter styling 2024-08-28 08:07:36 +10:00
2217fb8485 feat(ui): add flip & reset to transform 2024-08-28 07:57:15 +10:00
43652e830a tidy(ui): use helper to sync scaled bbox size on model change 2024-08-28 07:11:05 +10:00
a3417bf81d fix(ui): randomize seed toggle linked to prompt concat 2024-08-28 07:05:14 +10:00
06637161e3 chore: release v4.2.9.dev5 2024-08-27 19:57:34 +10:00
c4f4b16a36 chore(ui): lint 2024-08-27 19:57:02 +10:00
3001718f9f feat(ui): generalize mask fill, add to action bar 2024-08-27 19:56:57 +10:00
ac16fa65a3 feat(ui): implement interaction locking on layers 2024-08-27 19:27:38 +10:00
bc0b5335ff feat(ui): iterate on layer actions
- Add lock toggle
- Tweak lock and enabled styles
- Update entity list action bar w/ delete & delete all
- Move add layer menu to action bar
- Adjust opacity slider style
2024-08-27 19:08:57 +10:00
e91c7c5a30 feat(ui): collapsible entity groups 2024-08-27 17:59:21 +10:00
74791cc490 tidy(ui): rename some classes to be consistent 2024-08-27 17:27:38 +10:00
68409c6a0f feat(ui): tuned canvas undo/redo
- Throttle pushing to history for actions of the same type, starting with 1000ms throttle.
- History has a limit of 64 items, same as workflow editor
- Add clear history button
- Fix an issue where entity transformers would reset the entity state when the entity is fully transparent, resetting the redo stack. This could happen when you undo to the starting state of a layer
2024-08-27 17:10:01 +10:00
85613b220c tidy(ui): move all undoable reducers back to canvas slice 2024-08-27 16:25:42 +10:00
80085ad854 fix(ui): dnd image count 2024-08-27 16:16:11 +10:00
b6bfa65104 fix(ui): canvas entity opacity scale 2024-08-27 16:16:02 +10:00
0bfa033089 perf(ui): optimize all selectors 2
Mostly selector optimization. Still a few places to tidy up but I'll get to that later.
2024-08-27 16:04:05 +10:00
6f0974b5bc perf(ui): optimize all selectors 1
I learned that the inline selector syntax recreates the selector function on every render:

```ts
const val = useAppSelector((s) => s.slice.val)
```

Not good! Better is to create a selector outside the function and use it. Doing that for all selectors now, most of the way through now. Feels snappier.
2024-08-27 13:19:14 +10:00
c3b53fc4f6 feat(ui): rough out undo/redo on canvas 2024-08-27 12:05:45 +10:00
8f59a32d81 chore: release v4.2.9.dev4
Canvas dev build.
2024-08-27 11:12:28 +10:00
3b4f20f433 fix(ui): handle error from internal konva method
We are dipping into konva's private API for preview images and it appears to be unsafe (got an error once). Wrapped in a try/catch.
2024-08-27 11:02:18 +10:00
73da6e9628 feat(ui): split out loras state from canvas rendering state 2024-08-27 11:02:18 +10:00
2fc482141d feat(ui): split out session state from canvas rendering state 2024-08-27 11:02:18 +10:00
a41ec5f3fc feat(ui): split out settings state from canvas rendering state 2024-08-27 11:02:18 +10:00
c906225d03 feat(ui): split out tool state from canvas rendering state 2024-08-27 11:02:18 +10:00
2985ea3716 feat(ui): split out params/compositing state from canvas rendering state
First step to restoring undo/redo - the undoable state must be in its own slice. So params and settings must be isolated.
2024-08-27 11:02:18 +10:00
4f151c6c6f feat(ui): add CanvasModuleBase class to standardize canvas APIs
I did this ages ago but undid it for some reason, not sure why. Caught a few issues related to subscriptions.
2024-08-27 11:02:04 +10:00
c4f5252c1a feat(ui): move selected tool and tool buffer out of redux
This ephemeral state can live in the canvas classes.
2024-08-27 11:02:04 +10:00
77c13f2cf3 feat(ui): move ephemeral state into canvas classes
Things like `$lastCursorPos` are now created within the canvas drawing classes. Consumers in react access them via `useCanvasManager`.

For example:
```tsx
const canvasManager = useCanvasManager();
const lastCursorPos = useStore(canvasManager.stateApi.$lastCursorPos);
```
2024-08-27 11:02:04 +10:00
3270d36fca feat(ui): normalize all actions to accept an entityIdentifier
Previously, canvas actions specific to an entity type only needed the id of that entity type. This allowed you to pass in the id of an entity of the wrong type.

All actions for a specific entity now take a full entity identifier, and the entity identifier type can be narrowed.

`selectEntity` and `selectEntityOrThrow` now need a full entity identifier, and narrow their return values to a specific entity type _if_ the entity identifier is narrowed.

The types for canvas entities are updated with optional type parameters for this purpose.

All reducers, actions and components have been updated.
2024-08-27 11:02:04 +10:00
b6b30ff01f feat(ui): move events into modules who care about them 2024-08-27 11:02:04 +10:00
aa9bfdff35 fix(ui): color picker resets brush opacity 2024-08-27 11:02:04 +10:00
80308cc3b8 fix(ui): scaled bbox loses sync 2024-08-27 11:02:04 +10:00
f6db73bf1f feat(ui): add context menu to entity list 2024-08-27 11:02:04 +10:00
ef9f61a39f chore(ui): bump @invoke-ai/ui-library 2024-08-27 11:02:04 +10:00
a1a0881133 fix(ui): missing vae precision in graph builders 2024-08-27 11:02:04 +10:00
9956919ab6 chore: release v4.2.9.dev3
Instead of using dates, just going to increment.
2024-08-27 11:02:04 +10:00
abc07f57d6 feat(ui): use new Result utils for enqueueing 2024-08-27 11:02:04 +10:00
1a1cae79f1 fix(ui): graph building issue w/ controlnet 2024-08-27 11:02:04 +10:00
bcfafe7b06 feat(ui): add Result type & helpers
Wrappers to capture errors and turn into results:
- `withResult` wraps a sync function
- `withResultAsync` wraps an async function

Comments, tests.
2024-08-27 11:02:04 +10:00
34e8ced592 chore: release v4.2.9.dev20240824 2024-08-27 11:02:04 +10:00
1fdada65b6 fix(ui): lint & fix issues with adding regional ip adapters 2024-08-27 11:02:04 +10:00
433f3e1971 feat(ui): add knipignore tag
I'm not ready to delete some things but still want to build the app.
2024-08-27 11:02:04 +10:00
a60e23f825 feat(ui): duplicate entity 2024-08-27 11:02:04 +10:00
f69de3148e feat(ui): autocomplete on getPrefixeId 2024-08-27 11:02:04 +10:00
cbcd36ef54 feat(ui): paste canvas gens back on source in generate mode 2024-08-27 11:02:04 +10:00
aa76134340 chore(ui): typegen 2024-08-27 11:02:04 +10:00
55758acae8 feat(nodes): CanvasV2MaskAndCropInvocation can paste generated image back on source
This is needed for `Generate` mode.
2024-08-27 11:02:04 +10:00
196e43b5e5 fix(ui): extraneous entity preview updates 2024-08-27 11:02:04 +10:00
38b9828441 fix(ui): newly-added entities are selected 2024-08-27 11:02:04 +10:00
0048a7077e feat(ui): add crosshair to color picker 2024-08-27 11:02:04 +10:00
527a39a3ad fix(ui): color picker ignores alpha 2024-08-27 11:02:04 +10:00
30ce4c55c7 fix(ui): calculate renderable entities correctly in tool module 2024-08-27 11:02:04 +10:00
ca082d4288 feat(ui): better color picker 2024-08-27 11:02:04 +10:00
5e59a4f43a feat(ui): colored mask preview image 2024-08-27 11:02:04 +10:00
9f86605049 fix(ui): new rectangles don't trigger rerender 2024-08-27 11:02:04 +10:00
79058a7894 chore: bump version v4.2.9.dev20240823 2024-08-27 11:02:04 +10:00
bb3ad8c2f1 feat(ui): disable most interaction while filtering 2024-08-27 11:02:04 +10:00
799688514b fix(ui): filter preview offset 2024-08-27 11:02:04 +10:00
b7344b0df2 feat(ui): tweak layout of staging area toolbar 2024-08-27 11:02:04 +10:00
7e382c5f3f chore(ui): typegen 2024-08-27 11:02:04 +10:00
9cf357e184 tidy(app): clean up app changes for canvas v2 2024-08-27 11:01:53 +10:00
95b6c773d4 feat(ui): use singleton for clear q confirm dialog 2024-08-27 11:01:53 +10:00
89d8c5ba00 fix(ui): rip out broken recall logic, NO TS ERRORS 2024-08-27 11:01:53 +10:00
59580cf6ed chore(ui): lint 2024-08-27 11:01:53 +10:00
2b0c084f5b fix(ui): staging area interaction scopes 2024-08-27 11:01:53 +10:00
4d896073ff fix(ui): staging area actions 2024-08-27 11:01:53 +10:00
9f69503a80 tidy(ui): more cleanup 2024-08-27 11:01:53 +10:00
0311e852a0 fix(ui): upscale tab graph 2024-08-27 11:01:53 +10:00
7003a3d546 fix(ui): sdxl graph builder 2024-08-27 11:01:53 +10:00
dc73072e27 fix(ui): select next entity in the list when deleting 2024-08-27 11:01:53 +10:00
e549c44ad7 feat(ui): fix delete layer hotkey 2024-08-27 11:01:52 +10:00
45a4231cbe tidy(ui): "eye dropper" -> "color picker" 2024-08-27 11:01:52 +10:00
81f046ebac tidy(ui): regional guidance buttons 2024-08-27 11:01:52 +10:00
6ef6c593c4 feat(ui): update entity list menu 2024-08-27 11:01:52 +10:00
5b53eefef7 feat(ui): add log debug button 2024-08-27 11:01:52 +10:00
9a9919c0af chore(ui): lint 2024-08-27 11:01:52 +10:00
10661b33d4 chore(ui): prettier 2024-08-27 11:01:52 +10:00
52193d604d chore(ui): eslint 2024-08-27 11:01:52 +10:00
2568441e6a tidy(ui): remove unused stuff 4 2024-08-27 11:01:52 +10:00
1a14860b3b tidy(ui): remove unused stuff 3 2024-08-27 11:01:52 +10:00
9ff7647ec5 tidy(ui): remove unused pkg @chakra-ui/react-use-size 2024-08-27 11:01:52 +10:00
b49106e8fe feat(ui): revise graph building for control layers, fix issues w/ invocation complete events 2024-08-27 11:01:52 +10:00
906d0902a3 feat(ui): use unique id for metadata in Graph class 2024-08-27 11:01:52 +10:00
fbde6f5a7f tidy(ui): remove unused stuff 2 2024-08-27 11:01:52 +10:00
b388268987 tidy(ui): remove unused stuff 2024-08-27 11:01:52 +10:00
3b4164bd62 tidy(ui): reduce use of parseify util 2024-08-27 11:01:52 +10:00
b7fc6fe573 feat(ui): refine canvas entity list items & menus 2024-08-27 11:01:52 +10:00
2954a19d27 feat(ui): canvas layer preview, revised reactivity for adapters 2024-08-27 11:01:52 +10:00
aa45ce7fbd feat(ui): add SyncableMap
Can be used with useSyncExternal store to make a `Map` reactive.
2024-08-27 11:01:52 +10:00
77e5078e4a tidy(ui): removed unused transform methods from canvasmanager 2024-08-27 11:01:52 +10:00
603cc7bf2e feat(ui): transform tool ux 2024-08-27 11:01:52 +10:00
cd517a102d feat(ui): rough out canvas mode 2024-08-27 11:01:52 +10:00
9a442918b5 feat(ui): add canvas autosave checkbox 2024-08-27 11:01:52 +10:00
f9c03d85a5 fix(ui): memory leak when getting image DTO
must unsubscribe!
2024-08-27 11:01:52 +10:00
10d07c71c4 feat(ui): rework settings menu 2024-08-27 11:01:52 +10:00
cd05a78219 feat(ui): no entities fallback buttons 2024-08-27 11:01:52 +10:00
f8ee572abc perf(ui): optimize gallery image delete button rendering 2024-08-27 11:01:52 +10:00
d918654509 feat(ui): remove "solid" background option 2024-08-27 11:01:52 +10:00
582e30c542 tidy(ui): organise files and classes 2024-08-27 11:01:52 +10:00
34a6555301 tidy(ui): abstract compositing logic to module 2024-08-27 11:01:52 +10:00
fff860090b fix(ui): fix canvas cache property access 2024-08-27 11:01:52 +10:00
f4971197c1 tidy(ui): clean up CanvasFilter class 2024-08-27 11:01:52 +10:00
621d5e0462 tidy(ui): clean up a few bits and bobs 2024-08-27 11:01:52 +10:00
0b68a69a6c tidy(ui): abstract canvas rendering logic to module 2024-08-27 11:01:52 +10:00
9a599ce595 tidy(ui): abstract caching logic to module 2024-08-27 11:01:52 +10:00
1467ba276f tidy(ui): abstract worker logic to module 2024-08-27 11:01:52 +10:00
708facf707 tidy(ui): abstract stage logic into module 2024-08-27 11:01:52 +10:00
9c6c6adb1f feat(ui): add entity group hiding 2024-08-27 11:01:52 +10:00
c335b8581c feat(ui): move all caching out of redux
While we lose the benefit of the caches persisting across reloads, this is a much simpler way to handle things. If we need a persistent cache, we can explore it in the future.
2024-08-27 11:01:52 +10:00
f1348e45bd feat(ui): revised rasterization caching
- use `stable-hash` to generate stable, non-crypto hashes for cache entries, instead of using deep object comparisons
- use an object to store image name caches
2024-08-27 11:01:52 +10:00
ce6cf9b079 feat(ui): revise filter implementation 2024-08-27 11:01:52 +10:00
13ec80736a fix(ui): add button to delete inpaint mask 2024-08-27 11:01:52 +10:00
c9690a4b21 feat(ui): add contexts/hooks to access entity adapters directly 2024-08-27 11:01:52 +10:00
489e875a6e feat(ui): add CanvasManagerProviderGate
This context waits to render its children its until the canvas manager is available. Then its children have access to the manager directly via hook.
2024-08-27 11:01:52 +10:00
8651396048 feat(ui) do not set $canvasManager until ready 2024-08-27 11:01:52 +10:00
2bab5a6179 fix(ui): inpaint mask naming 2024-08-27 11:01:52 +10:00
006f06b615 feat(ui): efficient canvas compositing
Also solves issue of exporting layers at different opacities than what is visible
2024-08-27 11:01:52 +10:00
d603923d1b feat(ui): allow multiple inpaint masks
This is easier than making it a nullable singleton
2024-08-27 11:01:52 +10:00
86878e855b fix(ui): missing rasterization cache invalidations 2024-08-27 11:01:52 +10:00
35de60a8fa feat(ui): iterate on filter UI, flow 2024-08-27 11:01:52 +10:00
2c444a1941 fix(ui): rehydration data loss 2024-08-27 11:01:52 +10:00
3dfef01889 feat(ui): sort log namespaces 2024-08-27 11:01:52 +10:00
a845a2daa5 fix(ui): do not merge arrays by index during rehydration 2024-08-27 11:01:52 +10:00
df41f4fbce fix(ui): clone parsed data during state rehydration
Without this, the objects and arrays in `parsed` could be mutated, and the log statment would show the mutated data.
2024-08-27 11:01:52 +10:00
76482da6f5 fix(ui): fix logger filter
was accidetnally replacing the filter instead of appending to it.
2024-08-27 11:01:52 +10:00
8205abbbbf fix(ui): race condition queue status
Sequence of events causing the race condition:
- Enqueue batch
- Invalidate `SessionQueueStatus` tag
- Request updated queue status via HTTP - batch still processing at this point
- Batch completes
- Event emitted saying so
- Optimistically update the queue status cache, it is correct
- HTTP request makes it back and overwrites the optimistic update, indicating the batch is still in progress

FIxed by not invalidating the cache.
2024-08-27 11:01:52 +10:00
926873de26 fix(ui): handle opacity for masks 2024-08-27 11:01:52 +10:00
00cb1903ba feat(ui): default background to checkerboard 2024-08-27 11:01:52 +10:00
58ba38b9c7 feat(ui): clean up logging namespaces, allow skipping namespaces 2024-08-27 11:01:52 +10:00
2f6a5617f9 chore(ui): bump ui library 2024-08-27 11:01:52 +10:00
e0d84743be fix(ui): do not allow drawing if layer disabled 2024-08-27 11:01:52 +10:00
ee7c62acc4 fix(ui): stale state causing race conditions & extraneous renders 2024-08-27 11:01:52 +10:00
daf3e58bd9 fix(ui): do not clear buffer when rendering "real" objects 2024-08-27 11:01:52 +10:00
c5b9209057 tidy(ui): remove "filter" from CanvasImageState 2024-08-27 11:01:52 +10:00
2a4d6d98e2 feat(ui): better editable title 2024-08-27 11:01:52 +10:00
cfdf59d906 fix(ui): stroke eraserline 2024-08-27 11:01:52 +10:00
f91ce1a47c feat(ui): restore transparency effect for control layers 2024-08-27 11:01:52 +10:00
4af2888168 feat(ui): use text cursor for entity title 2024-08-27 11:01:52 +10:00
8471c6fe86 tidy(ui): remove extraneous logging in CanvasStateApi 2024-08-27 11:01:52 +10:00
fe65a5a2db feat(ui): better buffer commit logic 2024-08-27 11:01:52 +10:00
0df26e967c feat(ui): render buffer separately from "real" objects 2024-08-27 11:01:52 +10:00
d4822b305e fix(ui): pixelRect should always be integer 2024-08-27 11:01:52 +10:00
8df5447563 fix(ui): only update stage attrs when stage itself is dragged 2024-08-27 11:01:52 +10:00
7b5a43df9b feat(ui): add line simplification
This fixes some awkward issues where line segments stack up.
2024-08-27 11:01:52 +10:00
61ef630175 fix(ui): various things listening when they need not listen 2024-08-27 11:01:52 +10:00
4eda2ef555 feat(ui): layer opacity via caching 2024-08-27 11:01:52 +10:00
57f4489520 feat(ui): reset view fits all visible objects 2024-08-27 11:01:52 +10:00
fb6cf9e3da fix(ui): rerenders when changing canvas scale 2024-08-27 11:01:52 +10:00
f776326cff fix(ui): do not render rasterized layer unless renderObjects=true 2024-08-27 11:01:52 +10:00
5be32d5733 feat(ui): revise app layout strategy, add interaction scopes for hotkeys 2024-08-27 11:01:52 +10:00
1f73435241 feat(ui): tweak mask patterns 2024-08-27 11:01:52 +10:00
3251a00631 fix(ui): dynamic prompts recalcs when presets are loaded 2024-08-27 11:01:52 +10:00
49c4ad1dd7 fix(ui): use style preset prompts correctly 2024-08-27 11:01:52 +10:00
5857e95c4a fix(ui): discard selected staging image not all other images 2024-08-27 11:01:52 +10:00
85be2532c6 fix(ui): respect image size in staging preview 2024-08-27 11:01:52 +10:00
8b81a00def tidy(ui): cleanup after events change 2024-08-27 11:01:52 +10:00
8544595c27 feat(ui): move socket event handling out of redux
Download events and invocation status events (including progress images) are very frequent. There's no real need for these to pass through redux. Handling them outside redux is a significant performance win - far fewer store subscription calls, far fewer trips through middleware.

All event handling is moved outside middleware. Cleanup of unused actions and listeners to follow.
2024-08-27 11:01:52 +10:00
a6a5d1470c fix(ui): rebase conflicts 2024-08-27 11:01:39 +10:00
febcc12ec9 fix(ui): update compositing rect when fill changes 2024-08-27 11:01:39 +10:00
ab64078b76 feat(ui): add canvas background style 2024-08-27 11:01:39 +10:00
0ff3459b07 feat(ui): mask layers choose own opacity 2024-08-27 11:01:39 +10:00
2abd7c9bfe feat(ui): mask fill patterns 2024-08-27 11:01:39 +10:00
8e5330bdc9 build(ui): add vite types to tsconfig 2024-08-27 11:01:39 +10:00
1ecec4ea3a fix(ui): do not smooth pixel data when using eyeDropper 2024-08-27 11:01:39 +10:00
700dbe69f3 tidy(ui): tool components & translations 2024-08-27 11:01:39 +10:00
af7ba3b7e4 feat(ui): rough out eyedropper tool
It's a bit slow bc we are converting the stage to canvas on every mouse move. Also need to improve the visual but it works.
2024-08-27 11:01:39 +10:00
1f7144d62e fix(ui): ip adapters work 2024-08-27 11:01:39 +10:00
4e389e415b feat(ui): rename layers 2024-08-27 11:01:39 +10:00
2db29fb6ab feat(ui): revise entity menus 2024-08-27 11:01:39 +10:00
79653fcff5 feat(ui): split control layers from raster layers for UI and internal state, same rendering as raster layers 2024-08-27 11:01:39 +10:00
9e39180fbc feat(ui): implement cache for image rasterization, rip out some old controladapters code 2024-08-27 11:01:39 +10:00
dc0f832d8f feat(ui, app): use layer as control (wip) 2024-08-27 11:01:39 +10:00
0dcd6aa5d9 feat(ui): add contextmenu for canvas entities 2024-08-27 11:01:39 +10:00
9f4a8f11f8 feat(ui): more better logging & naming 2024-08-27 11:01:39 +10:00
6f9579d6ec feat(ui): better logging w/ path 2024-08-27 11:01:39 +10:00
2b2aabb234 feat(ui): always show marks on canvas scale slider 2024-08-27 11:01:39 +10:00
a79b9633ab fix(ui): do not import button from chakra 2024-08-27 11:01:39 +10:00
7b628c908b fix(ui): scaled bbox preview 2024-08-27 11:01:39 +10:00
181703a709 feat(ui): tidy up atoms 2024-08-27 11:01:39 +10:00
c439e3c204 feat(ui): convert all my pubsubs to atoms
its the same but better
2024-08-27 11:01:39 +10:00
11e81eb456 feat(ui): add trnalsation 2024-08-27 11:01:39 +10:00
3e24bf640e fix(ui): give up on thumbnail loading, causes flash during transformer 2024-08-27 11:01:39 +10:00
a17664fb75 fix(ui): depth anything v2 2024-08-27 11:01:39 +10:00
5aed23dc91 tidy(ui): remove unused code, comments 2024-08-27 11:01:39 +10:00
7f389716d0 fix(ui): staging area works 2024-08-27 11:01:39 +10:00
eca13b674a feat(nodes): temp disable canvas output crop 2024-08-27 11:01:39 +10:00
7c982a1bdf fix(ui): max scale 1 when reset view 2024-08-27 11:01:39 +10:00
bdfe6870fd feat(ui): better scale changer component, reset view functionality 2024-08-27 11:01:39 +10:00
7eebbc0dd9 fix(ui): img2img 2024-08-27 11:01:39 +10:00
6ae46d7c8b feat(ui): add manual scale controls 2024-08-27 11:01:39 +10:00
8aae30566e fix(ui): do not await clearBuffer 2024-08-27 11:01:39 +10:00
4b7c3e221c feat(ui): dnd image into layer 2024-08-27 11:01:39 +10:00
4015795b7f fix(ui): do not await commitBuffer 2024-08-27 11:01:39 +10:00
132dd61d8d fix(ui): properly destroy entities in manager cleanup 2024-08-27 11:01:39 +10:00
6f2b548dd1 tidy(ui): clearer component names for regional guidance 2024-08-27 11:01:39 +10:00
49dd316f17 tidy(ui): clearer component names for ip adapter 2024-08-27 11:01:39 +10:00
e0a8bb149d tidy(ui): clearer component names for inpaint mask 2024-08-27 11:01:39 +10:00
020b6db34b tidy(ui): clearer component names for control adapters 2024-08-27 11:01:39 +10:00
f6d2f0bf8c feat(ui): simplify canvas list item headers 2024-08-27 11:01:39 +10:00
1280cce803 fix(ui): ip adapter list item 2024-08-27 11:01:39 +10:00
82463d12e2 tidy(ui): clean up unused logic 2024-08-27 11:01:39 +10:00
ba6c1b84e4 feat(ui): clean up state, add mutex for image loading, add thumbnail loading 2024-08-27 11:01:39 +10:00
92b6d3198a chore(ui): add async-mutex dep 2024-08-27 11:01:39 +10:00
693ae1af50 feat(ui): txt2img, img2img, inpaint & outpaint working 2024-08-27 11:01:39 +10:00
3873a3096c feat(ui): no padding on transformer outlines 2024-08-27 11:01:39 +10:00
4a9f6ab5ef feat(ui): restore object count to layer titles 2024-08-27 11:01:39 +10:00
2fc29c5125 tidy(ui): "useIsEntitySelected" -> "useEntityIsSelected" 2024-08-27 11:01:39 +10:00
5fbc876cfd tidy(ui): move transformer statics into class 2024-08-27 11:01:39 +10:00
89b0673ac9 tidy(ui): massive cleanup
- create a context for entity identifiers, massively simplifying UI for each entity int he list
- consolidate common redux actions
- remove now-unused code
2024-08-27 11:01:39 +10:00
3179a16189 perf(ui): do not add duplicate points to lines 2024-08-27 11:01:39 +10:00
3ce216b391 feat(ui): up line tension to 0.3 2024-08-27 11:01:39 +10:00
8a3a94e21a perf(ui): disable stroke, perfect draw on compositing rect 2024-08-27 11:01:39 +10:00
f61af188f9 tidy(ui): remove unused code, initial image 2024-08-27 11:01:39 +10:00
73fc52bfed tidy(ui): remove unused state & actions 2024-08-27 11:01:39 +10:00
4eeff4eef8 feat(ui): region mask rendering 2024-08-27 11:01:39 +10:00
cff2c43030 feat(ui): esc cancels drawing buffer
maybe this is not wanted? we'll see
2024-08-27 11:01:39 +10:00
504b1f2425 fix(ui): render transformer over objects, fix issue w/ inpaint rect color 2024-08-27 11:01:38 +10:00
eff5b56990 fix(ui): brush preview fill for inpaint/region 2024-08-27 11:01:38 +10:00
0e673f1a18 fix(ui): no objects rendered until vis toggled 2024-08-27 11:01:38 +10:00
4fea22aea4 feat(ui): inpaint mask transform 2024-08-27 11:01:38 +10:00
c2478c9ac3 fix(ui): layer accidental early set isFirstRender=false 2024-08-27 11:01:38 +10:00
ed8243825e fix(ui): inpaint mask rendering 2024-08-27 11:01:38 +10:00
c7ac2b5278 feat(ui): wip inpaint mask uses new API 2024-08-27 11:01:38 +10:00
a783003556 feat(ui): move updatePosition to transformer 2024-08-27 11:01:38 +10:00
44ba1c6113 feat(ui): move resetScale to transformer 2024-08-27 11:01:38 +10:00
a02d67fcc6 tidy(ui): more imperative naming 2024-08-27 11:01:38 +10:00
14c8f7c4f5 tidy(ui): use imperative names for setters in stateapi 2024-08-27 11:01:38 +10:00
a487ecb50f fix(ui): commit drawing buffer on tool change, fixing bbox not calculating 2024-08-27 11:01:38 +10:00
fc55862823 fix(ui): sync transformer when requesting bbox calc 2024-08-27 11:01:38 +10:00
e5400601d6 tidy(ui): rename union CanvasEntity -> CanvasEntityState 2024-08-27 11:01:38 +10:00
735f9f1483 fix(ui): request rect calc immediately on transform, hiding rect 2024-08-27 11:01:38 +10:00
d139db0a0f feat(ui): move bbox calculation to transformer 2024-08-27 11:01:38 +10:00
a35bb450b1 feat(ui): use set for transformer subscriptions 2024-08-27 11:01:38 +10:00
26c01dfa48 tidy(ui): clean up worker tasks when complete 2024-08-27 11:01:38 +10:00
2b1839374a tidy(ui): remove unused code in CanvasTool 2024-08-27 11:01:38 +10:00
59f5f18e1d feat(ui): use pubsub for isTransforming on manager 2024-08-27 11:01:38 +10:00
e41fcb081c docs(ui): update transformer docstrings 2024-08-27 11:01:38 +10:00
3032042b35 feat(ui): revised event pubsub, transformer logic split out 2024-08-27 11:01:38 +10:00
544db61044 feat(ui): add simple pubsub 2024-08-27 11:01:38 +10:00
67a3aa6dff feat(ui): document & clean up object renderer 2024-08-27 11:01:38 +10:00
34f4468b20 feat(ui): split out object renderer 2024-08-27 11:01:38 +10:00
d99ae58001 fix(ui): unable to hold shit while transforming to retain ratio 2024-08-27 11:01:38 +10:00
d60ec53762 tidy(ui): rename canvas stuff 2024-08-27 11:01:38 +10:00
0ece9361d5 tidy(ui): consolidate getLoggingContext builders 2024-08-27 11:01:38 +10:00
69987a2f00 fix(ui): align all tools to 1px grid
- Offset brush tool by 0.5px when width is odd, ensuring each stroke edge is exactly on a pixel boundary
- Round the rect tool also
2024-08-27 11:01:38 +10:00
7346bfccb9 feat(ui): disable image smoothing on layers 2024-08-27 11:01:38 +10:00
b705083ce2 fix(ui): round position when rasterizing layer 2024-08-27 11:01:38 +10:00
4b3c82df6f feat(ui): continue modularizing transform 2024-08-27 11:01:38 +10:00
46290205d5 feat(ui): fix a few things that didn't unsubscribe correctly, add helper to manage subscriptions 2024-08-27 11:01:38 +10:00
7b15585b80 feat(ui): merge bbox outline into transformer 2024-08-27 11:01:38 +10:00
cbfeeb9079 fix(ui): update parent's pos not transformers 2024-08-27 11:01:38 +10:00
fdac20b43e feat(ui): merge interaction rect into transformer class 2024-08-27 11:01:38 +10:00
ae2312104e feat(ui): prepare staging area 2024-08-27 11:01:38 +10:00
74b6674af6 feat(ui): typing for logging context 2024-08-27 11:01:38 +10:00
81adce3238 feat(ui): remove inheritance of CanvasObject
JS is terrible
2024-08-27 11:01:38 +10:00
48b7f460a8 feat(ui): split & document transformer logic, iterate on class structures 2024-08-27 11:01:38 +10:00
38a8232341 feat(ui): rotation snap to nearest 45deg when holding shift 2024-08-27 11:01:38 +10:00
39a51c4f4c feat(ui): expose subscribe method for nanostores 2024-08-27 11:01:38 +10:00
220bfeb37d tidy(ui): remove layer scaling reducers 2024-08-27 11:01:38 +10:00
e766279950 fix(ui): pixel-perfect transforms 2024-08-27 11:01:38 +10:00
db82406525 fix(ui): layer visibility toggle 2024-08-27 11:01:38 +10:00
2d44f332d9 fix(nodes): fix canvas mask erode
it wasn't eroding enough and caused incorrect transparency in result images
2024-08-27 11:01:38 +10:00
ea1526689a fix(ui): do not reset layer on first render 2024-08-27 11:01:38 +10:00
200338ed72 feat(ui): revised logging and naming setup, fix staging area 2024-08-27 11:01:38 +10:00
88003a61bd feat(ui): add repr methods to layer and object classes 2024-08-27 11:01:38 +10:00
b82089b30b feat(ui): use nanoid(10) instead of uuidv4 for canvas
Shorter ids makes it much more readable
2024-08-27 11:01:38 +10:00
efd780d395 build(ui): add nanoid as explicit dep 2024-08-27 11:01:38 +10:00
3f90f783de fix(ui): move CanvasImage's konva image to correct object 2024-08-27 11:01:38 +10:00
4f5b755117 fix(ui): prevent flash when applying transform 2024-08-27 11:01:38 +10:00
a455f12581 build(ui): add eslint rules for async stuff 2024-08-27 11:01:38 +10:00
de516db383 feat(ui): trying to fix flicker after transform 2024-08-27 11:01:38 +10:00
6781575293 feat(ui): transform cleanup 2024-08-27 11:01:38 +10:00
65b0e40fc8 feat(ui): fix transform when rotated 2024-08-27 11:01:38 +10:00
19e78a07b7 fix(ui): use pixel bbox when image is in layer 2024-08-27 11:01:38 +10:00
e3b60dda07 fix(ui): transforming when axes flipped 2024-08-27 11:01:38 +10:00
a9696d3193 feat(ui): hallelujah (???) 2024-08-27 11:01:38 +10:00
336d72873f feat(ui): add debug button 2024-08-27 11:01:38 +10:00
111a380bce fix(ui): transformer padding 2024-08-27 11:01:38 +10:00
012a8351af feat(ui): wip transform mode 2 2024-08-27 11:01:38 +10:00
deeb80ea9b feat(ui): wip transform mode 2024-08-27 11:01:38 +10:00
1e97a917d6 feat(ui): wip transform mode 2024-08-27 11:01:38 +10:00
a15ba925db fix(ui): dnd to canvas broke 2024-08-27 11:01:38 +10:00
6e5a968aad fix(ui): conflicts after rebasing 2024-08-27 11:01:38 +10:00
915edaa02f fix(ui): imageDropped listener 2024-08-27 11:01:38 +10:00
f6b0fa7c18 wip 2024-08-27 11:01:38 +10:00
3f1fba0f35 fix(ui): transform tool seems to be working 2024-08-27 11:01:38 +10:00
d9fa85a4c6 fix(ui): move tool fixes, add transform tool 2024-08-27 11:01:38 +10:00
022bb8649c feat(ui): move tool now only moves 2024-08-27 11:01:38 +10:00
673bc33a01 feat(ui): layer bbox calc in worker 2024-08-27 11:01:38 +10:00
579a64928d feat(ui): tweaked entity & group selection styles 2024-08-27 11:01:38 +10:00
5316df7d7d feat(ui): canvas entity list headers 2024-08-27 11:01:38 +10:00
62fe61dc30 tidy(ui): CanvasRegion 2024-08-27 11:01:38 +10:00
ea819a4a2f tidy(ui): CanvasRect 2024-08-27 11:01:38 +10:00
868a25dae2 tidy(ui): CanvasLayer 2024-08-27 11:01:38 +10:00
3a25d00cb6 tidy(ui): CanvasInpaintMask 2024-08-27 11:01:38 +10:00
6301b74d87 tidy(ui): CanvasInitialImage 2024-08-27 11:01:38 +10:00
b43b90c299 tidy(ui): CanvasImage 2024-08-27 11:01:38 +10:00
0a43444ab3 tidy(ui): CanvasEraserLine 2024-08-27 11:01:38 +10:00
75ea4d2155 tidy(ui): CanvasControlAdapter 2024-08-27 11:01:38 +10:00
9d281388e0 tidy(ui): CanvasBrushLine 2024-08-27 11:01:38 +10:00
178e1cc50b tidy(ui): CanvasBbox 2024-08-27 11:01:38 +10:00
6eafe53b2d tidy(ui): CanvasBackground 2024-08-27 11:01:38 +10:00
7514b2b7d4 tidy(ui): update canvas classes, organise location of konva nodes 2024-08-27 11:01:38 +10:00
51dee2dba2 feat(ui): add names to all konva objects
Makes troubleshooting much simpler
2024-08-27 11:01:38 +10:00
a81c3d841c fix(ui): do not await creating new canvas image
If you await this, it causes a race condition where multiple images are created.
2024-08-27 11:01:38 +10:00
154487f966 feat(ui): use position and dimensions instead of separate x,y,width,height attrs 2024-08-27 11:01:38 +10:00
588daafcf5 fix(ui): remove weird rtkq hook wrapper
I do not understand why I did that initially but it doesn't work with TS.
2024-08-27 11:01:38 +10:00
ab00097aed feat(ui): rename types size and position to dimensions and coordinate 2024-08-27 11:01:38 +10:00
5aefae71a2 tidy(ui): hide layer settings by default 2024-08-27 11:01:38 +10:00
0edd598970 fix(ui): layer rendering when starting as disabled 2024-08-27 11:01:38 +10:00
0bb485031f feat(invocation): reduce canvas v2 mask & crop mask dilation 2024-08-27 11:01:38 +10:00
01ffd86367 feat(ui): de-jank staging area and progress images 2024-08-27 11:01:38 +10:00
e2e02f31b6 feat(ui): update staging handling to work w/ cropped mask 2024-08-27 11:01:38 +10:00
0008617348 chore(ui): typegen 2024-08-27 11:01:38 +10:00
f8f21c0edd feat(app): update CanvasV2MaskAndCropInvocation 2024-08-27 11:01:38 +10:00
010916158b feat(ui): use new canvas output node 2024-08-27 11:01:38 +10:00
df0ba004ca chore(ui): typegen 2024-08-27 11:01:38 +10:00
038b29e15b feat(app): add CanvasV2MaskAndCropInvocation & CanvasV2MaskAndCropOutput
This handles some masking and cropping that the canvas needs.
2024-08-27 11:01:21 +10:00
763ab73923 fix(ui): restore nodes output tracking 2024-08-27 11:01:21 +10:00
9a060b4437 feat(ui): rip out document size
barely knew ye
2024-08-27 11:01:21 +10:00
2307a30892 feat(ui): convert initial image to layer when starting canvas session 2024-08-27 11:01:21 +10:00
2006f84f6e fix(ui): fix layer transparency calculation 2024-08-27 11:01:21 +10:00
23b15fef6a fix(ui): reset initial image when resetting canvas 2024-08-27 11:01:21 +10:00
41e72f929d fix(ui): reset node executions states when loading workflow 2024-08-27 11:01:21 +10:00
29fc49bb3b fix(ui): entity display list 2024-08-27 11:01:21 +10:00
6f65b6a40f feat(ui): img2img working 2024-08-27 11:01:21 +10:00
1e9b22e3a4 feat(ui): rough out img2img on canvas 2024-08-27 11:01:21 +10:00
3dc2c723c3 UNDO ME WIP 2024-08-27 11:01:21 +10:00
6f007cbd48 feat(ui): log invocation source id on socket event 2024-08-27 11:01:21 +10:00
9a402dd10e feat(ui): restore document size overlay renderer 2024-08-27 11:01:21 +10:00
4249d0e13b feat(ui): make documnet size a rect 2024-08-27 11:01:21 +10:00
f6050bad67 refactor(ui): remove modular imagesize components
This is no longer necessary with canvas v2 and added a ton of extraneous redux actions when changing the image size. Also renamed to document size
2024-08-27 11:01:21 +10:00
d3a4b7b51b feat(ui): initialState is for generation mode 2024-08-27 11:01:21 +10:00
3f5f9ac764 feat(ui): split out canvas entity list component 2024-08-27 11:01:21 +10:00
e7c1299a7f feat(ui): hide bbox button when no canvas session active 2024-08-27 11:01:21 +10:00
56a3918a1e tidy(ui): remove unused naming objects/utils
The canvas manager means we don't need to worry about konva node names as we never directly select konva nodes.
2024-08-27 11:01:21 +10:00
dabf7718cf feat(ui): split up tool chooser buttons
Prep for distinct toolbars for generation vs canvas modes
2024-08-27 11:01:21 +10:00
ef22c29288 feat(ui): add useAssertSingleton util hook
This simple hook asserts that it is only ever called once. Particularly useful for things like hotkeys hooks.
2024-08-27 11:01:21 +10:00
74f06074f7 feat(ui): "stagingArea" -> "session" 2024-08-27 11:01:21 +10:00
b97bf52faa feat(ui): add reset button to canvas 2024-08-27 11:01:21 +10:00
0a77f5cec8 feat(ui): add snapToRect util 2024-08-27 11:01:21 +10:00
f8e92f7b73 fix(ui): fiddle with control adapter filters
some jank still
2024-08-27 11:01:21 +10:00
530c6e3a59 feat(ui): temp disable doc size overlay 2024-08-27 11:01:21 +10:00
11b95cfaf4 feat(ui): no animation on layer selection
Felt sluggish
2024-08-27 11:01:21 +10:00
707c005a26 feat(ui): use canvas as source for control images (wip) 2024-08-27 11:01:21 +10:00
19fa8e7e33 fix(ui): control adapter translate & scale 2024-08-27 11:01:21 +10:00
b252ded366 tidy(ui): removed unused state related to non-buffered drawing 2024-08-27 11:01:21 +10:00
84305d4e73 feat(ui): control adapter image rendering 2024-08-27 11:01:21 +10:00
1150b41e14 fix(ui): do not floor bbox calc, it cuts off the last pixels 2024-08-27 11:01:21 +10:00
88d8ccb34b feat(ui): fix issue where creating line needs 2 points 2024-08-27 11:01:21 +10:00
4111b3f1aa fix(ui): edge cases when holding shift and drawing lines 2024-08-27 11:01:21 +10:00
36862be2aa fix(ui): set buffered rect color to full alpha 2024-08-27 11:01:21 +10:00
425665e0d9 fix(ui): handle mouseup correctly 2024-08-27 11:01:21 +10:00
9abd604f69 feat(ui): buffered rect drawing 2024-08-27 11:01:21 +10:00
59bdc288b5 fix(ui): buffered drawing edge cases 2024-08-27 11:01:21 +10:00
eb37d2958e perf(ui): do not use stage.find 2024-08-27 11:01:21 +10:00
2a9738a341 perf(ui): object groups do not listen 2024-08-27 11:01:21 +10:00
6aac1cf33a perf(ui): buffered drawing (wip) 2024-08-27 11:01:21 +10:00
9ca4d072ab tidy(ui): organise files 2024-08-27 11:01:21 +10:00
7aaf14c26b tidy(ui): organise files 2024-08-27 11:01:21 +10:00
cf598ca175 tidy(ui): organise files 2024-08-27 11:01:21 +10:00
a722790afc fix(ui): background rendering 2024-08-27 11:01:21 +10:00
320151a040 pkg(ui): remove unused deps react-konva & use-image 2024-08-27 11:01:21 +10:00
c090f511c3 feat(ui): organize konva state and files 2024-08-27 11:01:21 +10:00
86dd1475b3 fix(ui): merge conflicts in image deletion listener 2024-08-27 11:01:21 +10:00
0b71ac258c fix(ui): region rendering 2024-08-27 11:01:21 +10:00
54e1eae509 fix(ui): inpaint mask rendering 2024-08-27 11:01:21 +10:00
bf57b2dc77 fix(ui): staging area rendering 2024-08-27 11:01:21 +10:00
de3c27b44f fix(ui): stale selected entity 2024-08-27 11:01:21 +10:00
05717fea93 fix(ui): staging area image offset 2024-08-27 11:01:21 +10:00
191584d229 feat(ui): tweak layer ui component 2024-08-27 11:01:21 +10:00
6069169e6b fix(ui): resetting layer resets position 2024-08-27 11:01:21 +10:00
07438587f3 feat(ui): updated layer list component styling 2024-08-27 11:01:21 +10:00
913e36d6fd feat(ui): transformable layers 2024-08-27 11:01:21 +10:00
139004b976 feat(ui): move tool icon is pointer like in other apps 2024-08-27 11:01:21 +10:00
ef4269d585 feat(ui): do not floor cursor position 2024-08-27 11:01:21 +10:00
954cb129a4 feat(ui): disable gallery hotkeys while staging 2024-08-27 11:01:21 +10:00
02c4b28de5 feat(ui): revised canvas progress & staging image handling 2024-08-27 11:01:21 +10:00
febea88b58 feat(ui): show queue item origin in queue list 2024-08-27 11:01:21 +10:00
40ccfac514 chore(ui): typegen 2024-08-27 11:01:21 +10:00
831fb814cc feat(app): add origin to session queue
The origin is an optional field indicating the queue item's origin. For example, "canvas" when the queue item originated from the canvas or "workflows" when the queue item originated from the workflows tab. If omitted, we assume the queue item originated from the API directly.

- Add migration to add the nullable column to the `session_queue` table.
- Update relevant event payloads with the new field.
- Add `cancel_by_origin` method to `session_queue` service and corresponding route. This is required for the canvas to bail out early when staging images.
- Add `origin` to both `SessionQueueItem` and `Batch` - it needs to be provided initially via the batch and then passed onto the queue item.
-
2024-08-27 11:01:21 +10:00
bf166fdd61 fix(ui): denoise start on outpainting 2024-08-27 11:01:21 +10:00
384bde3539 feat(ui): add redux events for queue cleared & batch enqueued socket events 2024-08-27 11:01:21 +10:00
6f1d238d0a feat(ui): canvas staging area works 2024-08-27 11:01:21 +10:00
ac524153a7 feat(ui): switch to view tool when staging 2024-08-27 11:01:21 +10:00
2cad2b15cf tidy(ui): disable preview images on every enqueue 2024-08-27 11:01:21 +10:00
fd63e202fe feat(ui): rough out save staging image 2024-08-27 11:01:21 +10:00
a0250e47e3 feat(ui): staging area image visibility toggle 2024-08-27 11:01:21 +10:00
7d8ece45bb fix(ui): batch building after removing canvas files 2024-08-27 11:01:21 +10:00
ffb8f053da feat(ui): make Graph class's getMetadataNode public 2024-08-27 11:01:21 +10:00
fb46f457f9 tidy(ui): remove old canvas graphs 2024-08-27 11:01:21 +10:00
6d4f4152a7 fix(ui): do not select already-selected entity 2024-08-27 11:01:20 +10:00
d3d0ac7327 tidy(ui): naming things 2024-08-27 11:01:20 +10:00
f57df46995 tidy(ui): file organisation 2024-08-27 11:01:20 +10:00
a747171745 fix(ui): reset cursor pos when fitting document 2024-08-27 11:01:20 +10:00
e9ae9e80d4 feat(ui): staging area works more better 2024-08-27 11:01:20 +10:00
3b9a59b98d feat(ui): staging area barely works 2024-08-27 11:01:20 +10:00
8a381e7f74 feat(ui): consolidate konva API 2024-08-27 11:01:20 +10:00
61513fc800 feat(ui): consolidate konva API 2024-08-27 11:01:20 +10:00
1d26c49e92 feat(ui): staging area (rendering wip) 2024-08-27 11:01:20 +10:00
77be9836d2 tidy(ui): type "Dimensions" -> "Size" 2024-08-27 11:01:20 +10:00
4427960acb feat(ui): add updateNode to Graph 2024-08-27 11:01:20 +10:00
84aa4fb7bc feat(ui): sdxl graphs 2024-08-27 11:01:20 +10:00
01df96cbe0 feat(ui): sd1 outpaint graph 2024-08-27 11:01:20 +10:00
1ac0634f57 tests(ui): add missing tests for Graph class 2024-08-27 11:01:20 +10:00
8e7d3634b1 feat(ui): add Graph.getid() util 2024-08-27 11:01:20 +10:00
fadafe5c77 feat(ui): outpaint graph, organize builder a bit 2024-08-27 11:01:20 +10:00
b2ea1f6690 feat(ui): inpaint sd1 graph 2024-08-27 11:01:20 +10:00
0a03c1f882 feat(ui): temp disable image caching while testing 2024-08-27 11:01:20 +10:00
ce8b490ed8 feat(ui): txt2img & img2img graphs 2024-08-27 11:01:20 +10:00
86eccba80d feat(ui): minor change to canvas bbox state type 2024-08-27 11:01:20 +10:00
97453e7c6c feat(ui): simplified konva node to blob/imagedata utils 2024-08-27 11:01:20 +10:00
9e1084b701 feat(ui): node manager getter/setter 2024-08-27 11:01:20 +10:00
41aec81f3f feat(ui): generation mode calculation, fudged graphs 2024-08-27 11:01:20 +10:00
a5741a0551 feat(ui): add utils for getting images from canvas 2024-08-27 11:01:20 +10:00
72f73c231a feat(ui): even more simplified API - lean on the konva node manager to abstract imperative state API & rendering 2024-08-27 11:01:20 +10:00
b8fcaa274e feat(ui): revised docstrings for renderers & simplified api 2024-08-27 11:01:20 +10:00
a33bbf48bb feat(ui): inpaint mask UI components 2024-08-27 11:01:20 +10:00
98d9490fb9 feat(ui): inpaint mask rendering (wip) 2024-08-27 11:01:20 +10:00
51c643c4f8 fix(ui): models loaded handler 2024-08-27 11:01:20 +10:00
2d7370ca6c feat(ui): internal state for inpaint mask 2024-08-27 11:01:20 +10:00
0d68141387 refactor(ui): divvy up canvas state a bit 2024-08-27 11:01:20 +10:00
e88a8c6639 feat(ui): get region and base layer canvas to blob logic working 2024-08-27 11:01:20 +10:00
2d04bb286e refactor(ui): node manager handles more tedious annoying stuff 2024-08-27 11:01:20 +10:00
6d9ba24c32 feat(ui): use node manager for addRegions 2024-08-27 11:01:20 +10:00
7645a1c86e feat(ui): persist bbox 2024-08-27 11:01:20 +10:00
dc284b9a48 fix(ui): fix generation graphs 2024-08-27 11:01:20 +10:00
8a38332d44 feat(ui): add toggle for clipToBbox 2024-08-27 11:01:20 +10:00
2407d7d148 feat(ui): rename konva node manager 2024-08-27 11:01:20 +10:00
23275cf607 refactor(ui): create classes to abstract mgmt of konva nodes 2024-08-27 11:01:20 +10:00
8a0e02d335 tidy(ui): organise renderers 2024-08-27 11:01:20 +10:00
913873623c refactor(ui): create entity to konva node map abstraction (wip)
Instead of chaining konva `find` and `findOne` methods, all konva nodes are added to a mapping object. Finding and manipulating them is much simpler.

Done for regions and layers, wip for control adapters.
2024-08-27 11:01:20 +10:00
5d81e7dd4d perf(ui): fix lag w/ region rendering
Needed to memoize these selectors
2024-08-27 11:01:20 +10:00
418650fdf3 feat(ui): move canvas fill color picker to right 2024-08-27 11:01:20 +10:00
7c24e56d9f refactor(ui): remove unused ellipse & polygon objects 2024-08-27 11:01:20 +10:00
f6faed46c3 fix(ui): incorrect rect/brush/eraser positions 2024-08-27 11:01:20 +10:00
1d393eecf1 refactor(ui): enable global debugging flag 2024-08-27 11:01:20 +10:00
03a72240c0 refactor(ui): disable the preview renderer for now 2024-08-27 11:01:20 +10:00
acf62450fb tweak(ui): canvas editor layout 2024-08-27 11:01:20 +10:00
d0269310cf perf(ui): memoize layeractionsmenu valid actions 2024-08-27 11:01:20 +10:00
43618a74e7 refactor(ui): decouple konva renderer from react
Subscribe to redux store directly, skipping all the react overhead.

With react in dev mode, a typical frame while using the brush tool on almost-empty canvas is reduced from ~7.5ms to ~3.5ms. All things considered, this still feels slow, but it's a massive improvement.
2024-08-27 11:01:20 +10:00
56fed637ec feat(ui): clip lines to bbox 2024-08-27 11:01:20 +10:00
944ae4a604 fix(ui): document fit positioning 2024-08-27 11:01:20 +10:00
f3da609102 feat(ui): document bounds overlay 2024-08-27 11:01:20 +10:00
11c8a8cf72 tidy(ui): background layer 2024-08-27 11:01:20 +10:00
656978676f refactor(ui): use "entity" instead of "data" for canvas 2024-08-27 11:01:20 +10:00
d216e6519f feat(ui): brush size border radius = 1 2024-08-27 11:01:20 +10:00
0a2bcae0e3 fix(ui): canvas HUD doesn't interrupt tool 2024-08-27 11:01:20 +10:00
31cf244420 refactor(ui): split up canvas entity renderers, temp disable preview 2024-08-27 11:01:20 +10:00
d761effac1 fix(ui): delete all layers button 2024-08-27 11:01:20 +10:00
5efaf2c661 fix(ui): ignore keyboard shortcuts in input/textarea elements 2024-08-27 11:01:20 +10:00
b79161fbec fix(ui): canvas entity ids getting clobbered 2024-08-27 11:01:20 +10:00
89a2f2134b fix(ui): move lora followup fixes 2024-08-27 11:01:20 +10:00
343c3b19b1 chore(ui): lint 2024-08-27 11:01:20 +10:00
e6ec646b2c refactor(ui): move loras to canvas slice 2024-08-27 11:01:20 +10:00
b557fe4e40 fix(ui): layer is selected when added 2024-08-27 11:01:20 +10:00
45908dfbd2 feat(ui): r to center & fit stage on document 2024-08-27 11:01:20 +10:00
1cf0673a22 feat(ui): better HUD 2024-08-27 11:01:20 +10:00
189847f8a5 fix(ui): always use current brush width when making straight lines 2024-08-27 11:01:20 +10:00
b27929f702 feat(ui): hold shift w/ brush to draw straight line 2024-08-27 11:01:20 +10:00
b1a6a9835d fix(ui): update bg on canvas resize 2024-08-27 11:01:20 +10:00
5564a16d4b refactor(ui): better hud 2024-08-27 11:01:20 +10:00
b2aa447d50 refactor(ui): scaled tool preview border 2024-08-27 11:01:20 +10:00
8666f9a848 refactor(ui): port remaining canvasV1 rendering logic to V2, remove old code 2024-08-27 11:01:20 +10:00
e7dc7c4917 refactor(ui): fix more types 2024-08-27 11:01:20 +10:00
513d0f1e5c refactor(ui): metadata recall (wip)
just enough let the app run
2024-08-27 11:01:20 +10:00
c6ce7618cf refactor(ui): undo/redo button temp fix 2024-08-27 11:01:20 +10:00
9b78b8dc91 refactor(ui): fix renderer stuff 2024-08-27 11:01:20 +10:00
3bae233f40 refactor(ui): fix misc types 2024-08-27 11:01:20 +10:00
0a305c4291 refactor(ui): fix gallery stuff 2024-08-27 11:01:20 +10:00
54fe4ddf3e refactor(ui): fix delete image stuff 2024-08-27 11:01:20 +10:00
aa877b981c refactor(ui): fix useIsReadyToEnqueue for new adapterType field 2024-08-27 11:01:20 +10:00
b8ec4348a5 refactor(ui): update generation tab graphs 2024-08-27 11:01:20 +10:00
0e3e27668c refactor(ui): add adapterType to ControlAdapterData 2024-08-27 11:01:20 +10:00
e8c8025119 refactor(ui): update components & logic to use new unified slice (again) 2024-08-27 11:01:20 +10:00
6a72eda5d2 refactor(ui): update components & logic to use new unified slice 2024-08-27 11:01:20 +10:00
35c8c54466 refactor(ui): merge compositing, params into canvasV2 slice 2024-08-27 10:59:24 +10:00
2eda45ca5b refactor(ui): add scaled bbox state 2024-08-27 10:59:24 +10:00
ecd6e7960c refactor(ui): update dnd/image upload 2024-08-27 10:59:24 +10:00
0d3a61cbdb refactor(ui): update size/prompts state 2024-08-27 10:59:24 +10:00
6737c275d7 refactor(ui): rip out old control adapter implementation 2024-08-27 10:59:24 +10:00
201a3e5838 refactor(ui): canvas v2 (wip)
fix entity count select
2024-08-27 10:59:24 +10:00
85cb239219 refactor(ui): canvas v2 (wip)
delete unused file
2024-08-27 10:59:24 +10:00
002f45e383 refactor(ui): canvas v2 (wip)
merge all canvas state reducers into one big slice (but with the logic split across files so it's not hell)
2024-08-27 10:59:24 +10:00
470e5ba290 refactor(ui): canvas v2 (wip)
Fix a few more components
2024-08-27 10:59:24 +10:00
b6722b3a10 refactor(ui): canvas v2 (wip)
missed a spot
2024-08-27 10:59:24 +10:00
6a624916ca refactor(ui): canvas v2 (wip)
Redo all UI components for different canvas entity types
2024-08-27 10:59:24 +10:00
65653e0932 refactor(ui): canvas v2 (wip) 2024-08-27 10:59:24 +10:00
a7e59d6697 refactor(ui): canvas v2 (wip) 2024-08-27 10:59:24 +10:00
f1356105c1 refactor(ui): canvas v2 (wip) 2024-08-27 10:59:24 +10:00
8acc6379fb refactor(ui): canvas v2 (wip) 2024-08-27 10:59:24 +10:00
d13014c5d9 feat(ui): bbox tool 2024-08-27 10:59:24 +10:00
db11d8ba90 fix(ui): rect tool preview 2024-08-27 10:59:24 +10:00
46a4ee2360 fix(ui): multiple stages 2024-08-27 10:59:24 +10:00
a19c053b88 feat(ui): decouple konva logic from nanostores 2024-08-27 10:59:24 +10:00
5b47a32d31 feat(ui): store all stage attrs in nanostores 2024-08-27 10:59:24 +10:00
32ae9efb6a feat(ui): round stage scale 2024-08-27 10:59:24 +10:00
b81bee551a chore(ui): bump konva 2024-08-27 10:59:24 +10:00
8c9dffd082 feat(ui): generation bbox transformation working
whew
2024-08-27 10:59:24 +10:00
cdfae643e4 feat(ui): wip generation bbox 2024-08-27 10:59:24 +10:00
cb93108206 feat(ui): wip generation bbox 2024-08-27 10:59:24 +10:00
c11343dc1c feat(ui): CL zoom and pan, some rendering optimizations 2024-08-27 10:59:24 +10:00
3733c6f89d Revert "feat(ui): add x,y,scaleX,scaleY,rotation to objects"
This reverts commit 53318b396c967c72326a7e4dea09667b2ab20bdd.
2024-08-27 10:59:24 +10:00
3c23a0eac0 feat(ui): layers manage their own bbox 2024-08-27 10:59:24 +10:00
7fd69ab1f1 docs(ui): konva image object docstrings 2024-08-27 10:59:24 +10:00
3f511774de feat(ui): add x,y,scaleX,scaleY,rotation to objects 2024-08-27 10:59:24 +10:00
3600100879 fix(ui): show color picker when using rect tool 2024-08-27 10:59:24 +10:00
8fae372103 feat(ui): image loading fallback for raster layers 2024-08-27 10:59:24 +10:00
2fce1fe04c feat(ui): bbox calc for raster layers 2024-08-27 10:59:24 +10:00
22f3e975c7 feat(ui): do not fill brush preview when drawing 2024-08-27 10:59:24 +10:00
c6ced5a210 fix(ui): brush spacing handling 2024-08-27 10:59:24 +10:00
5d66e85205 fix(ui): jank when starting a shape when not already focused on stage 2024-08-27 10:59:24 +10:00
649f163bf7 feat(ui): wip raster layers
I meant to split this up into smaller commits and undo some of it, but I committed afterwards and it's tedious to undo.
2024-08-27 10:59:24 +10:00
4c821bd930 feat(ui): support image objects on raster layers
Just the UI and internal state, not rendering yet.
2024-08-27 10:59:24 +10:00
6359de4e25 tidy(ui): clean up event handlers
Separate logic for each tool in preparation for ellipse and polygon tools.
2024-08-27 10:59:24 +10:00
2c610c8cd4 feat(ui): raster layer reset, object group util 2024-08-27 10:59:24 +10:00
7efe8a249b feat(ui): rect shape preview now has fill 2024-08-27 10:59:24 +10:00
bd421d184e feat(ui): cancel shape drawing on esc 2024-08-27 10:59:24 +10:00
78f5844ba0 feat(ui): temp disable history on CL 2024-08-27 10:59:23 +10:00
f6bb4d5051 feat(ui): raster layer logic
- Deduplicate shared logic
- Split up giant renderers file into separate cohesive files
- Tons of cleanup
- Progress on raster layer functionality
2024-08-27 10:59:23 +10:00
56642c3e87 feat(ui): add raster layer rendering and interaction (WIP) 2024-08-27 10:59:23 +10:00
9fd8678d3d feat(ui): scaffold out raster layers
Raster layers may have images, lines and shapes. These will replace initial image layers and provide sketching functionality like we have on canvas.
2024-08-27 10:59:23 +10:00
8b89518fd6 refactor(ui): revise types for line and rect objects
- Create separate object types for brush and eraser lines, instead of a single type that has a `tool` field.
- Create new object type for rect shapes.
- Add logic to schemas to migrate old object types to new.
- Update renderers & reducers.
2024-08-27 10:59:23 +10:00
50085b40bb Update starter model size estimates. 2024-08-26 20:17:50 -04:00
cff382715a default workflow: add steps to exposed fields, add more notes 2024-08-26 20:17:50 -04:00
54d54d1bf2 Run ruff 2024-08-26 20:17:50 -04:00
e84ea68282 remove prompt 2024-08-26 20:17:50 -04:00
160dd36782 update default workflow for flux 2024-08-26 20:17:50 -04:00
65bb46bcca Rename params for flux and flux vae, add comments explaining use of the config_path in model config 2024-08-26 20:17:50 -04:00
2d185fb766 Run ruff 2024-08-26 20:17:50 -04:00
2ba9b02932 Fix type error in tsc 2024-08-26 20:17:50 -04:00
849da67cc7 Remove no longer used code in the flux denoise function 2024-08-26 20:17:50 -04:00
3ea6c9666e Remove in progress images until we're able to make the valuable 2024-08-26 20:17:50 -04:00
cf633e4ef2 Only install starter models if not already installed 2024-08-26 20:17:50 -04:00
bbf934d980 Remove outdated TODO. 2024-08-26 20:17:50 -04:00
620f733110 ruff format 2024-08-26 20:17:50 -04:00
67928609a3 Downgrade accelerate and huggingface-hub deps to original versions. 2024-08-26 20:17:50 -04:00
5f15afb7db Remove flux repo dependency 2024-08-26 20:17:50 -04:00
635d2f480d ruff 2024-08-26 20:17:50 -04:00
70c278c810 Remove dependency on flux config files 2024-08-26 20:17:50 -04:00
56b9906e2e Setup scaffolding for in progress images and add ability to cancel the flux node 2024-08-26 20:17:50 -04:00
a808ce81fd Replace swish() with torch.nn.functional.silu(h). They are functionally equivalent, but in my test VAE deconding was ~8% faster after the change. 2024-08-26 20:17:50 -04:00
83f82c5ddf Switch the CLIP-L start model to use our hosted version - which is much smaller. 2024-08-26 20:17:50 -04:00
101de8c25d Update t5 encoder formats to accurately reflect the quantization strategy and data type 2024-08-26 20:17:50 -04:00
3339a4baf0 Downgrade revert torch version after removing optimum-qanto, and other minor version-related fixes. 2024-08-26 20:17:50 -04:00
dff4a88baa Move quantization scripts to a scripts/ subdir. 2024-08-26 20:17:50 -04:00
a21f6c4964 Update docs for T5 quantization script. 2024-08-26 20:17:50 -04:00
97562504b7 Remove all references to optimum-quanto and downgrade diffusers. 2024-08-26 20:17:50 -04:00
75d8ac378c Update the T5 8-bit quantized starter model to use the BnB LLM.int8() variant. 2024-08-26 20:17:50 -04:00
b9dd354e2b Fixes to the T5XXL quantization script. 2024-08-26 20:17:50 -04:00
33c2fbd201 Add script for quantizing a T5 model. 2024-08-26 20:17:50 -04:00
5063be92bf Switch flux to using its own conditioning field 2024-08-26 20:17:50 -04:00
1047584b3e Only import bnb quantize file if bitsandbytes is installed 2024-08-26 20:17:50 -04:00
6764dcfdaa Load and unload clip/t5 encoders and run inference separately in text encoding 2024-08-26 20:17:50 -04:00
012864ceb1 Update macos test vm to macOS-14 2024-08-26 20:17:50 -04:00
a0bf20bcee Run FLUX VAE decoding in the user's preferred dtype rather than float32. Tested, and seems to work well at float16. 2024-08-26 20:17:50 -04:00
14ab339b33 Move prepare_latent_image_patches(...) to sampling.py with all of the related FLUX inference code. 2024-08-26 20:17:50 -04:00
25c91efbb6 Rename field positive_prompt -> prompt. 2024-08-26 20:17:50 -04:00
1c1f2c6664 Add comment about incorrect T5 Tokenizer size calculation. 2024-08-26 20:17:50 -04:00
d7c22b3bf7 Tidy is_schnell detection logic. 2024-08-26 20:17:50 -04:00
185f2a395f Make FLUX get_noise(...) consistent across devices/dtypes. 2024-08-26 20:17:50 -04:00
0c5649491e Mark FLUX nodes as prototypes. 2024-08-26 20:17:50 -04:00
94aba5892a Attribute black-forest-labs/flux for much of the flux code 2024-08-26 20:17:50 -04:00
ef093dde29 Don't install bitsandbytes on macOS 2024-08-26 20:17:50 -04:00
34451e5f27 added FLUX dev to starter models 2024-08-26 20:17:50 -04:00
1f9bdd1a9a Undo changes to the v2 dir of frontend types 2024-08-26 20:17:50 -04:00
c27d59baf7 Run ruff 2024-08-26 20:17:50 -04:00
f130ddec7c Remove automatic install of models during flux model loader, remove no longer used import function on context 2024-08-26 20:17:50 -04:00
a0a259eef1 Fix max_seq_len field description. 2024-08-26 20:17:50 -04:00
b66f19d4d1 Add docs to the quantization scripts. 2024-08-26 20:17:50 -04:00
4105a78b83 Update load_flux_model_bnb_llm_int8.py to work with a single-file FLUX transformer checkpoint. 2024-08-26 20:17:50 -04:00
19a68afb3a Fix bug in InvokeInt8Params that was causing it to use double the necessary VRAM. 2024-08-26 20:17:50 -04:00
fd68a2475b add better workflow name 2024-08-26 20:17:50 -04:00
28ff7ba830 add better workflow description 2024-08-26 20:17:50 -04:00
5d0b248fdb fix(worker) fix T5 type 2024-08-26 20:17:50 -04:00
01a4e0f6ef update default workflow 2024-08-26 20:17:50 -04:00
91e0731506 fix schema 2024-08-26 20:17:50 -04:00
d1f904d41f tsc and lint fix 2024-08-26 20:17:50 -04:00
269388c9f4 feat(ui): create new field for t5 encoder models in nodes 2024-08-26 20:17:50 -04:00
b8486379ce fix(ui): pass base/type when installing models, add flux formats to MM badges 2024-08-26 20:17:50 -04:00
400eb94d3b fix(ui): only exclude flux main models from linear UI dropdown, not model manager list 2024-08-26 20:17:50 -04:00
e210c96485 add FLUX schnell starter models and submodels as dependenices or adhoc download options 2024-08-26 20:17:50 -04:00
5f567f41f4 add case for clip embed models in probe 2024-08-26 20:17:50 -04:00
5fed573a29 update flux_model_loader node to take a T5 encoder from node field instead of hardcoded list, assume all models have been downloaded 2024-08-26 20:17:50 -04:00
cfac7c8189 Move requantize.py to the quatnization/ dir. 2024-08-26 20:17:50 -04:00
1787de6836 Add docs to the requantize(...) function explaining why it was copied from optimum-quanto. 2024-08-26 20:17:50 -04:00
ac96f187bd Remove duplicate log_time(...) function. 2024-08-26 20:17:50 -04:00
72398350b4 More flux loader cleanup 2024-08-26 20:17:50 -04:00
df9445c351 Various styling and exception type updates 2024-08-26 20:17:50 -04:00
87b7a2e39b Switch inheritance class of flux model loaders 2024-08-26 20:17:50 -04:00
f7e46622a1 Update doc string for import_local_model and remove access_token since it's only usable for local file paths 2024-08-26 20:17:50 -04:00
71f18353a9 Address minor review comments. 2024-08-26 20:17:50 -04:00
4228de707b Rename t5Encoder -> t5_encoder. 2024-08-26 20:17:50 -04:00
b6a05629ef add default workflow for flux t2i 2024-08-26 20:17:50 -04:00
fbaa820643 exclude flux models from main model dropdown 2024-08-26 20:17:50 -04:00
db2a2d5e38 Some cleanup of the tags and description of flux nodes 2024-08-26 20:17:50 -04:00
8ba6e6b1f8 Add t5 encoders and clip embeds to the model manager 2024-08-26 20:17:50 -04:00
57168d719b Fix styling/lint 2024-08-26 20:17:50 -04:00
dee6d2c98e Fix support for 8b quantized t5 encoders, update exception messages in flux loaders 2024-08-26 20:17:50 -04:00
e49105ece5 Add tqdm progress bar to FLUX denoising. 2024-08-26 20:17:50 -04:00
0c5e11f521 Fix FLUX output image clamping. And a few other minor fixes to make inference work with the full bfloat16 FLUX transformer model. 2024-08-26 20:17:50 -04:00
a63f842a13 Select dev/schnell based on state dict, use correct max seq len based on dev/schnell, and shift in inference, separate vae flux params into separate config 2024-08-26 20:17:50 -04:00
4bd7fda694 Install sub directories with folders correctly, ensure consistent dtype of tensors in flux pipeline and vae 2024-08-26 20:17:50 -04:00
81f0886d6f Working inference node with quantized bnb nf4 checkpoint 2024-08-26 20:17:50 -04:00
2eb87f3306 Remove unused param on _run_vae_decoding in flux text to image 2024-08-26 20:17:50 -04:00
723f3ab0a9 Add nf4 bnb quantized format 2024-08-26 20:17:50 -04:00
1bd90e0fd4 Run ruff, setup initial text to image node 2024-08-26 20:17:50 -04:00
436f18ff55 Add backend functions and classes for Flux implementation, Update the way flux encoders/tokenizers are loaded for prompt encoding, Update way flux vae is loaded 2024-08-26 20:17:50 -04:00
cde9696214 Some UI cleanup, regenerate schema 2024-08-26 20:17:50 -04:00
2d9042fb93 Run Ruff 2024-08-26 20:17:50 -04:00
9ed53af520 Run Ruff 2024-08-26 20:17:50 -04:00
56fda669fd Manage quantization of models within the loader 2024-08-26 20:17:50 -04:00
1d8545a76c Remove changes to v1 workflow 2024-08-26 20:17:50 -04:00
5f59a828f9 Setup flux model loading in the UI 2024-08-26 20:17:50 -04:00
1fa6bddc89 WIP on moving from diffusers to FLUX 2024-08-26 20:17:50 -04:00
d3a5ca5247 More improvements for LLM.int8() - not fully tested. 2024-08-26 20:17:50 -04:00
f01f56a98e LLM.int8() quantization is working, but still some rough edges to solve. 2024-08-26 20:17:50 -04:00
99b0f79784 Clean up NF4 implementation. 2024-08-26 20:17:50 -04:00
e1eb104345 NF4 inference working 2024-08-26 20:17:50 -04:00
5c2f95ef50 NF4 loading working... I think. 2024-08-26 20:17:50 -04:00
b63df9bab9 wip 2024-08-26 20:17:50 -04:00
a52c899c6d Split a FluxTextEncoderInvocation out from the FluxTextToImageInvocation. This has the advantage that we benfit from automatic caching when the prompt isn't changed. 2024-08-26 20:17:50 -04:00
eeabb7ebe5 Make quantized loading fast for both T5XXL and FLUX transformer. 2024-08-26 20:17:50 -04:00
8b1cef978c Make quantized loading fast. 2024-08-26 20:17:50 -04:00
152da482cd WIP - experimentation 2024-08-26 20:17:50 -04:00
3cf0365a35 Make float16 inference work with FLUX on 24GB GPU. 2024-08-26 20:17:50 -04:00
5870742bb9 Add support for 8-bit quantizatino of the FLUX T5XXL text encoder. 2024-08-26 20:17:50 -04:00
01d8c62c57 Make 8-bit quantization save/reload work for the FLUX transformer. Reload is still very slow with the current optimum.quanto implementation. 2024-08-26 20:17:50 -04:00
55a242b2d6 Minor improvements to FLUX workflow. 2024-08-26 20:17:50 -04:00
45263b339f Got FLUX schnell working with 8-bit quantization. Still lots of rough edges to clean up. 2024-08-26 20:17:50 -04:00
3319491861 Use the FluxPipeline.encode_prompt() api rather than trying to run the two text encoders separately. 2024-08-26 20:17:50 -04:00
e687afac90 Add sentencepiece dependency for the T5 tokenizer. 2024-08-26 20:17:50 -04:00
b39031ea53 First draft of FluxTextToImageInvocation. 2024-08-26 20:17:50 -04:00
0b77511271 Update HF download logic to work for black-forest-labs/FLUX.1-schnell. 2024-08-26 20:17:50 -04:00
c99cd989c1 Update imports for compatibility with bumped diffusers version. 2024-08-26 20:17:50 -04:00
317fdadb21 Bump diffusers version to include FLUX support. 2024-08-26 20:17:50 -04:00
4e294f9e3e disable export button if no non-default presets 2024-08-26 09:23:15 -04:00
526e0f30a0 Added support for bounding boxes in the Invocation API
Adding built-in bounding boxes as a core type would help developers of nodes that include bounding box support.
2024-08-26 08:03:30 +10:00
231e5ec94a chore: bump version v4.2.8post1 2024-08-23 06:55:30 +10:00
e5bb6f9693 lint fix 2024-08-23 06:46:19 +10:00
da7dee44c6 fix(ui): use empty string fallback if unable to parse prompts when creating style preset from existing image 2024-08-23 06:46:19 +10:00
83144f4fe3 fix(docs): follow-up docker readme fixes 2024-08-22 11:19:07 -04:00
c451f52ea3 chore(ui): lint 2024-08-22 21:00:09 +10:00
8a2c78f2e1 fix(ui): dynamic prompts not recalculating when deleting or updating a style preset
The root cause was the active style preset not being reset when it was deleted, or no longer present in the list of style presets.

- Add extra reducer to `stylePresetSlice` to reset the active preset if it is deleted or otherwise unavailable
- Update the dynamic prompts listener to trigger on delete/update/list of style presets
2024-08-22 21:00:09 +10:00
bcc78bde9b chore: bump version to v4.2.8 2024-08-22 21:00:09 +10:00
054bb6fe0a translationBot(ui): update translation (Russian)
Currently translated at 100.0% (1367 of 1367 strings)

Co-authored-by: Васянатор <ilabulanov339@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/
Translation: InvokeAI/Web UI
2024-08-22 13:09:56 +10:00
4f4aa6d92e translationBot(ui): update translation (Italian)
Currently translated at 98.4% (1346 of 1367 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.4% (1346 of 1367 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-08-22 13:09:56 +10:00
eac51ac6f5 translationBot(ui): update translation files
Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/
Translation: InvokeAI/Web UI
2024-08-22 13:09:56 +10:00
9f349a7c0a fix(ui): do not constrain width of hide/show boards button
lets translations display fully
2024-08-22 11:36:07 +10:00
918afa5b15 fix(ui): show more of current board name 2024-08-22 11:36:07 +10:00
eb1113f95c feat(ui): add translation string for "Upscale" 2024-08-22 11:36:07 +10:00
4f4ba7b462 tidy(ui): clean up ActiveStylePreset markup 2024-08-21 09:06:41 +10:00
2298be0e6b fix(ui): error handling if unable to convert image URL to blob 2024-08-21 09:06:41 +10:00
63494dfca7 remove extra slash in exports path 2024-08-21 09:06:41 +10:00
36a1d39454 fix(ui): handle badge styling when template name is long 2024-08-21 09:06:41 +10:00
a6f6d5c400 fix(ui): add loading state to button when creating or updating a style preset 2024-08-21 09:06:41 +10:00
e85f221aca fix(ui): clear prompt template when prompts are recalled 2024-08-21 09:04:35 +10:00
d4797e37dc fix(ui): properly unwrap delete style preset API request so that error is caught 2024-08-19 16:12:39 -04:00
3e7923d072 fix(api): allow updating of type for style preset 2024-08-19 16:12:39 -04:00
a85d69ce3d tidy(ui): getViewModeChunks.tsx -> .ts 2024-08-19 08:25:39 +10:00
96db006c99 fix(ui): edge case with getViewModeChunks 2024-08-19 08:25:39 +10:00
8ca57d03d8 tests(ui): add tests for getViewModeChunks 2024-08-19 08:25:39 +10:00
6c404ce5f8 fix(ui): prompt template preset preview out of order 2024-08-19 08:25:39 +10:00
584e07182b fix(ui): use translations for style preset strings 2024-08-17 21:27:53 +10:00
f787e9acf6 chore: bump version v4.2.8rc2 2024-08-16 21:47:06 +10:00
5a24b89e54 fix(app): include style preset defaults in build 2024-08-16 21:47:06 +10:00
9b482e2a4f chore: bump version to v4.2.8rc1 2024-08-16 10:53:19 +10:00
Max
df4dbe2d57 Fix invoke.sh not detecting symlinks
When invoke.sh is executed using a symlink with a working directory outside of InvokeAI's root directory, it will fail.

invoke.sh attempts to cd into the correct directory at the start of the script, but will cd into the directory of the symlink instead. This commit fixes that.
2024-08-16 10:40:59 +10:00
713bd11177 feat(ui, api): prompt template export (#6745)
## Summary

Adds option to download all prompt templates to a CSV

## Related Issues / Discussions

<!--WHEN APPLICABLE: List any related issues or discussions on github or
discord. If this PR closes an issue, please use the "Closes #1234"
format, so that the issue will be automatically closed when the PR
merges.-->

## QA Instructions

<!--WHEN APPLICABLE: Describe how you have tested the changes in this
PR. Provide enough detail that a reviewer can reproduce your tests.-->

## Merge Plan

<!--WHEN APPLICABLE: Large PRs, or PRs that touch sensitive things like
DB schemas, may need some care when merging. For example, a careful
rebase by the change author, timing to not interfere with a pending
release, or a message to contributors on discord after merging.-->

## Checklist

- [ ] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-08-16 10:38:50 +10:00
182571df4b Merge branch 'main' into maryhipp/export-presets 2024-08-16 10:17:07 +10:00
29bfe492b6 ui: translations update from weblate (#6746)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for [InvokeAI/Web
UI](https://hosted.weblate.org/projects/invokeai/web-ui/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/invokeai/web-ui/horizontal-auto.svg)
2024-08-16 10:16:51 +10:00
3fb4e3050c feat(ui): focus in textarea after inserting placeholder 2024-08-16 10:14:25 +10:00
39c7ec3cd9 feat(ui): per type fallbacks for templates 2024-08-16 10:11:43 +10:00
26bfbdec7f feat(ui): use buttons instead of menu for preset import/export 2024-08-16 09:58:19 +10:00
7a3eaa8da9 feat(api): save file as prompt_templates.csv 2024-08-16 09:51:46 +10:00
599db7296f export only user style presets 2024-08-15 16:07:32 -04:00
042aab4295 translationBot(ui): update translation (Italian)
Currently translated at 98.6% (1340 of 1359 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-08-15 20:44:02 +02:00
24f298283f clean up, add context menu to import/download templates 2024-08-15 12:39:55 -04:00
68dac6349d Merge remote-tracking branch 'origin/main' into maryhipp/export-presets 2024-08-15 11:21:56 -04:00
b675fc19e8 feat: add base prop for selectedWorkflow to allow loading a workflow on launch (#6742)
## Summary
added a base prop for selectedWorkflow to allow loading a workflow on
launch

<!--A description of the changes in this PR. Include the kind of change
(fix, feature, docs, etc), the "why" and the "how". Screenshots or
videos are useful for frontend changes.-->

## Related Issues / Discussions

<!--WHEN APPLICABLE: List any related issues or discussions on github or
discord. If this PR closes an issue, please use the "Closes #1234"
format, so that the issue will be automatically closed when the PR
merges.-->

## QA Instructions
can test by loading InvokeAIUI with a selectedWorkflow prop of the
workflow ID
<!--WHEN APPLICABLE: Describe how you have tested the changes in this
PR. Provide enough detail that a reviewer can reproduce your tests.-->

## Merge Plan

<!--WHEN APPLICABLE: Large PRs, or PRs that touch sensitive things like
DB schemas, may need some care when merging. For example, a careful
rebase by the change author, timing to not interfere with a pending
release, or a message to contributors on discord after merging.-->

## Checklist

- [ ] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-08-15 10:52:23 -04:00
659019cfd6 Merge branch 'main' into chainchompa/preselect-workflows 2024-08-15 10:40:44 -04:00
dcd61e1f82 pin ruff version in python check gha 2024-08-15 09:47:49 -04:00
f5c99b1488 exclude jupyter notebooks from ruff 2024-08-15 09:47:49 -04:00
810be3e1d4 update import directions to include JSON 2024-08-15 09:47:49 -04:00
60d754d1df feat(api): tidy style presets import logic
- Extract parsing into utility function
- Log import errors
- Forbid extra properties on the imported data
2024-08-15 09:47:49 -04:00
bd07c86db9 feat(ui): make style preset menu trigger look like button 2024-08-15 09:47:49 -04:00
bcbf8b6bd8 feat(ui): revert to using {prompt} for prompt template placeholder 2024-08-15 09:47:49 -04:00
356661459b feat(api): support JSON for preset imports
This allows us to support Fooocus format presets.
2024-08-15 09:47:49 -04:00
deb917825e feat(api): use pydantic validation during style preset import
- Enforce name is present and not an empty string
- Provide empty string as default for positive and negative prompt
- Add `positive_prompt` as validation alias for `prompt` field
- Strip whitespace automatically
- Create `TypeAdapter` to validate the whole list in one go
2024-08-15 09:47:49 -04:00
15415c6d85 feat(ui): use dropzone for style preset upload
Easier to accept multiple file types and supper drag and drop in the future.
2024-08-15 09:47:49 -04:00
76b0380b5f feat(ui): create component to upload CSV of style presets to import 2024-08-15 09:47:49 -04:00
2d58754789 feat(api): add endpoint to take a CSV, parse it, validate it, and create many style preset entries 2024-08-15 09:47:49 -04:00
9cdf1f599c Merge branch 'main' into chainchompa/preselect-workflows 2024-08-15 09:25:19 -04:00
268be97ba0 remove ref, make options optional for useGetLoadWorkflow 2024-08-15 09:18:41 -04:00
a9014673a0 wip export 2024-08-15 09:00:11 -04:00
d36c43a10f ui: translations update from weblate (#6727)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for [InvokeAI/Web
UI](https://hosted.weblate.org/projects/invokeai/web-ui/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/invokeai/web-ui/horizontal-auto.svg)
2024-08-15 08:48:03 +10:00
54a5c4e482 translationBot(ui): update translation (Chinese (Simplified))
Currently translated at 98.1% (1296 of 1320 strings)

Co-authored-by: Phrixus2023 <920414016@qq.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/zh_Hans/
Translation: InvokeAI/Web UI
2024-08-15 00:46:01 +02:00
5e09a244e3 translationBot(ui): update translation (Italian)
Currently translated at 98.5% (1336 of 1355 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.5% (1302 of 1321 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.6% (1302 of 1320 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-08-15 00:46:01 +02:00
88648dca1a change selectedWorkflow to selectedWorkflowId 2024-08-14 11:22:37 -04:00
8840df2b00 Merge branch 'main' into chainchompa/preselect-workflows 2024-08-14 09:02:12 -04:00
af159acbdf cleanup 2024-08-14 08:58:38 -04:00
471719bbbe add base prop for selectedWorkflow to allow loading a workflow on launch 2024-08-14 08:47:02 -04:00
b126f2ffd5 feat(ui, api): prompt templates (#6729)
## Summary

Adds prompt templates to the UI. Demo video is attached.
* added default prompt templates to seed database on startup (these
cannot be edited or deleted by users via the UI)
* can create fresh prompt template, create from an image in gallery that
has prompt metadata, or copy an existing prompt template and modify
* if a template is active, can view what your prompt will be invoked as
by switching to "view mode"



https://github.com/user-attachments/assets/32d84e0c-b04c-48da-bae5-aa6eb685d209



## Related Issues / Discussions

<!--WHEN APPLICABLE: List any related issues or discussions on github or
discord. If this PR closes an issue, please use the "Closes #1234"
format, so that the issue will be automatically closed when the PR
merges.-->

## QA Instructions

<!--WHEN APPLICABLE: Describe how you have tested the changes in this
PR. Provide enough detail that a reviewer can reproduce your tests.-->

## Merge Plan

<!--WHEN APPLICABLE: Large PRs, or PRs that touch sensitive things like
DB schemas, may need some care when merging. For example, a careful
rebase by the change author, timing to not interfere with a pending
release, or a message to contributors on discord after merging.-->

## Checklist

- [ ] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-08-14 12:49:31 +10:00
9938f12ef0 Merge branch 'main' into maryhipp/style-presets 2024-08-14 12:33:30 +10:00
982c266073 tidy: remove extra characters in prompt templates 2024-08-14 12:31:57 +10:00
5c37391883 fix(ui): do not show [prompt] in preset preview 2024-08-14 12:29:05 +10:00
ddeafc6833 fix(ui): minimize layout shift when overlaying preset prompt preview 2024-08-14 12:24:57 +10:00
41b2d5d013 fix(ui): prompt preview not working preset starts with [prompt] 2024-08-14 12:21:38 +10:00
29d6f48901 fix(ui): prompt shows thru prompt label text 2024-08-14 12:01:49 +10:00
d5c9f4e47f chore(ui): revert framer-motion upgrade
`framer-motion` 11 breaks a lot of stuff in profoundly unintuitive ways, holy crap. UI lib rolled back its dep, pulling in latest version of that
2024-08-14 06:12:00 +10:00
24d73387d8 build(ui): fix chakra deps
We had multiple versions of @emotion/react, stemming from an extraneous dependency on @chakra-ui/react. Removed the extraneosu dep
2024-08-14 06:12:00 +10:00
e0d3927265 feat: add flag for allowPrivateStylePresets that shows a type field when creating a style preset 2024-08-13 14:08:54 -04:00
e5f7c2a9b7 add type safety / validation to form data payloads and allow type to be passed through api 2024-08-13 13:00:31 -04:00
b0760710d5 add the rest of default style presets, update image service to return default images correctly by name, add tooltip popover to images in UI 2024-08-13 11:33:15 -04:00
764accc921 update config docstring 2024-08-12 15:17:40 -04:00
6a01fce9c1 fix payloads for stringified data 2024-08-12 15:16:22 -04:00
9c732ac3b1 Merge remote-tracking branch 'origin/main' into maryhipp/style-presets 2024-08-12 14:53:45 -04:00
b70891c661 update descriptoin of placeholder in modal 2024-08-12 13:37:04 -04:00
4dbf851741 ui: add labels to prompt boxes 2024-08-12 13:33:39 -04:00
6c927a9fd4 move mdoal state into nanostore 2024-08-12 12:46:02 -04:00
096f001634 ui: add ability to copy template 2024-08-12 12:32:31 -04:00
4837e578b2 api: update dir path for style preset images, update payload for create/update formdata 2024-08-12 12:00:14 -04:00
1e547ef912 UI more pr feedback 2024-08-12 11:59:25 -04:00
f6b8970bd1 fix(app): create reference to events task to prevent accidental GC
This wasn't a problem, but it's advised in the official docs so I've done it.
2024-08-12 07:49:58 +10:00
29325a7214 fix(app): use asyncio queue and existing event loop for events
Around the time we (I) implemented pydantic events, I noticed a short pause between progress images every 4 or 5 steps when generating with SDXL. It didn't happen with SD1.5, but I did notice that with SD1.5, we'd get 4 or 5 progress events simultaneously. I'd expect one event every ~25ms, matching my it/s with SD1.5. Mysterious!

Digging in, I found an issue is related to our use of a synchronous queue for events. When the event queue is empty, we must call `asyncio.sleep` before checking again. We were sleeping for 100ms.

Said another way, every time we clear the event queue, we have to wait 100ms before another event can be dispatched, even if it is put on the queue immediately after we start waiting. In practice, this means our events get buffered into batches, dispatched once every 100ms.

This explains why I was getting batches of 4 or 5 SD1.5 progress events at once, but not the intermittent SDXL delay.

But this 100ms wait has another effect when the events are put on the queue in intervals that don't perfectly line up with the 100ms wait. This is most noticeable when the time between events is >100ms, and can add up to 100ms delay before the event is dispatched.

For example, say the queue is empty and we start a 100ms wait. Then, immediately after - like 0.01ms later - we push an event on to the queue. We still need to wait another 99.9ms before that event will be dispatched. That's the SDXL delay.

The easy fix is to reduce the sleep to something like 0.01 seconds, but this feels kinda dirty. Can't we just wait on the queue and dispatch every event immediately? Not with the normal synchronous queue - but we can with `asyncio.Queue`.

I switched the events queue to use `asyncio.Queue` (as seen in this commit), which lets us asynchronous wait on the queue in a loop.

Unfortunately, I ran into another issue - events now felt like their timing was inconsistent, but in a different way than with the 100ms sleep. The time between pushing events on the queue and dispatching them was not consistently ~0ms as I'd expect - it was highly variable from ~0ms up to ~100ms.

This is resolved by passing the asyncio loop directly into the events service and using its methods to create the task and interact with the queue. I don't fully understand why this resolved the issue, because either way we are interacting with the same event loop (as shown by `asyncio.get_running_loop()`). I suppose there's some scheduling magic happening.
2024-08-12 07:49:58 +10:00
8ecf72838d fix(api): image downloads with correct filename
Closes #6730
2024-08-10 09:53:56 -04:00
c3ab8a6aa8 chore(ui): bump rest of deps 2024-08-10 07:45:23 -04:00
1931aa3e70 chore(ui): typegen 2024-08-10 07:45:23 -04:00
d3d8055055 feat(ui): update typegen script 2024-08-10 07:45:23 -04:00
476b0a0403 chore(ui): bump openapi-typescript 2024-08-10 07:45:23 -04:00
f66584713c fix(api): sort OpenAPI schema properties for InvocationOutputMap
This makes the schema output deterministic!
2024-08-10 07:45:23 -04:00
33624fc2fa fix(api): duplicate operation id for get_image_full
There's a FastAPI bug that results in the OpenAPI spec outputting the same operation id for each operation when specifying multiple HTTP methods.

- Discussion: https://github.com/tiangolo/fastapi/discussions/8449
- Pending PR to fix: https://github.com/tiangolo/fastapi/pull/10694

In our case, we have a `get_image_full` endpoint that handles GET and HEAD.

This results in an invalid OpenAPI schema. A workaround is to use two route decorators for the operation handler. This works as expected - HEAD requests get the header, and GET requests get the resource. And the OpenAPI schema is valid.
2024-08-10 07:45:23 -04:00
41c3e73a3c fix tests 2024-08-09 16:31:42 -04:00
97553a7de2 API/DB updates per PR feedback 2024-08-09 16:27:37 -04:00
12ba15bfa9 UI updates per PR feedback 2024-08-09 16:00:13 -04:00
09d1e190e7 show warning for maxUpscaleDimension if model tab is disabled 2024-08-09 14:07:55 -04:00
8eb5d08499 missed translation 2024-08-08 16:01:16 -04:00
9be6acde7d require name to submit style preset 2024-08-08 15:53:21 -04:00
5f83bb0069 update config docstring 2024-08-08 15:20:43 -04:00
b138882abc fix tests? 2024-08-08 15:18:32 -04:00
0cd7cdb52e remove send2trash 2024-08-08 15:13:36 -04:00
1d8b7e2bcf ruff 2024-08-08 15:08:45 -04:00
6461f4758d lint fix 2024-08-08 15:07:58 -04:00
3189ab6863 get dynamic prompts working 2024-08-08 15:07:23 -04:00
3f9a674d4b seed default presets and handle them in UI 2024-08-08 15:02:41 -04:00
587f59b25b focus on prompt textarea when exiting view mode by clicking 2024-08-08 14:38:50 -04:00
4952eada87 ruff format 2024-08-08 14:22:40 -04:00
581029ebaa ruff 2024-08-08 14:21:37 -04:00
42d68780de lint 2024-08-08 14:19:33 -04:00
28032a2f80 more cleanup 2024-08-08 14:18:05 -04:00
e381e021e9 knip lint 2024-08-08 14:00:17 -04:00
641af64f93 regnerate schema 2024-08-08 13:58:25 -04:00
a7b83c8b5b Merge remote-tracking branch 'origin/main' into maryhipp/style-presets 2024-08-08 13:56:59 -04:00
4cc41e0188 translations and lint fix 2024-08-08 13:56:37 -04:00
442fc02429 resize images to 100x100 for style preset images 2024-08-08 12:56:55 -04:00
9a4d075074 fix path for style_preset_images, fix png type when converting blobs to files, built view mode components 2024-08-08 12:31:20 -04:00
17ff8196cb Remove tmp code 2024-08-07 22:06:05 -04:00
68f993998a Add support for norm layer 2024-08-07 22:06:05 -04:00
7da6120b39 Fix LoKR refactor bug 2024-08-07 22:06:05 -04:00
6cd40965c4 Depth Anything V2 (#6674)
- Updated the previous DepthAnything manual implementation to use the
`transformers` implementation instead. So we can get upstream features.
- Plugged in the DepthAnything models to be handled by Invoke's Model
Manager.
- `small_v2` model will use DepthAnythingV2. This has been added as a
new model option and is now also the default in the Linear UI.


![opera_TxRhmbFole](https://github.com/user-attachments/assets/2a25abe3-ba0b-4f97-b75a-2ce5fd6246e6)


# Merge

Review and merge.
2024-08-07 20:26:58 +05:30
408a1d6dbb Merge branch 'main' into depth_anything_v2 2024-08-07 10:45:56 -04:00
0b0abfbe8f clean up image implementation 2024-08-07 10:36:38 -04:00
cc96dcf0ed style preset images 2024-08-07 09:58:27 -04:00
2604fd9fde a whole bunch of stuff 2024-08-06 15:31:13 -04:00
140670d00e translationBot(ui): update translation files
Updated by "Cleanup translation files" hook in Weblate.

translationBot(ui): update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/
Translation: InvokeAI/Web UI
2024-08-06 17:54:47 +10:00
70233fae5d translationBot(ui): update translation (Chinese (Simplified))
Currently translated at 98.1% (1296 of 1321 strings)

Co-authored-by: Phrixus2023 <920414016@qq.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/zh_Hans/
Translation: InvokeAI/Web UI
2024-08-06 17:54:47 +10:00
6f457a6c4c translationBot(ui): update translation (German)
Currently translated at 65.1% (860 of 1321 strings)

Co-authored-by: Alexander Eichhorn <pfannkuchensack@einfach-doof.de>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/de/
Translation: InvokeAI/Web UI
2024-08-06 17:54:47 +10:00
B N
5c319f5356 translationBot(ui): update translation (German)
Currently translated at 64.8% (857 of 1321 strings)

Co-authored-by: B N <berndnieschalk@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/de/
Translation: InvokeAI/Web UI
2024-08-06 17:54:47 +10:00
991a04f090 translationBot(ui): update translation (Italian)
Currently translated at 98.6% (1303 of 1321 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.6% (1302 of 1320 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.6% (1294 of 1312 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-08-06 17:54:47 +10:00
c39fa75113 docs(ui): add comment in useIsTooLargeToUpscale 2024-08-06 11:49:35 +10:00
f7863e17ce docs(ui): add docstring for maxUpscaleDimension 2024-08-06 11:49:35 +10:00
7c526390ed fix(ui): compare upscaledPixels vs square of max dimension 2024-08-06 11:49:35 +10:00
2cff20f87a update translations, change config value to be dimension instead of total pixels 2024-08-06 11:49:35 +10:00
90ec757802 lint 2024-08-06 11:49:35 +10:00
4b85dfcefe (ui): restore optioanl limit on upcsale output resolution 2024-08-06 11:49:35 +10:00
21deefdc41 (ui): add image resolution badge to initial upscale image 2024-08-06 11:49:35 +10:00
857d74bbfe wip apply and calculate prompt with interpolation 2024-08-05 19:11:48 -04:00
fd7a635777 (ui) the most basic crud ui: view list of presets, create a new preset, edit/delete existing presets 2024-08-05 15:48:23 -04:00
af9110e964 fix prompt concat logic 2024-08-05 13:42:28 -04:00
a61209206b remove custom SDXL prompts component 2024-08-05 13:40:46 -04:00
e05cc62e5f add style presets API layer to UI 2024-08-05 13:37:07 -04:00
4d4f921a4e build: exclude matplotlib 3.9.1
There was a problem w/ this release on windows and the builds were pulled from pypi. When installing invoke on windows, pip attempts to build from source, but most (all?) systems won't have the prerequisites for this and installs fail.

This also affects GH actions.

The simple fix is to exclude version 3.9.1 from our deps.

For more information, see https://github.com/matplotlib/matplotlib/issues/28551
2024-08-05 08:38:44 +10:00
98db8f395b feat(app): clean up DiskImageStorage types 2024-08-04 09:43:20 +10:00
f465a956a3 feat(ui): remove "images can be restored" messages 2024-08-04 09:43:20 +10:00
9edb02d7ef build: remove send2trash dependency 2024-08-04 09:43:20 +10:00
6c4cf58a31 feat(app): delete model_images instead of using send2trash 2024-08-04 09:43:20 +10:00
08993c0d29 feat(app): delete images instead of using send2trash
Closes #6709
2024-08-04 09:43:20 +10:00
4f8a4b0f22 Merge branch 'main' into depth_anything_v2 2024-08-03 00:38:57 +05:30
a743f3c9b5 fix: implement model to func for depth anything 2024-08-03 00:37:17 +05:30
217fe40d99 feat(api): add style_presets router, make sure all CRUD is working, add is_default 2024-08-02 12:29:54 -04:00
b76bf50b93 feat(db,api): create new table for style presets, build out record storage service for style presets 2024-08-01 22:20:11 -04:00
571ba87e13 fix(ui): include upscale metadata for SDXL multidiffusion 2024-08-01 21:30:42 -04:00
f27b6e2b44 Add Grounded SAM support (text prompt image segmentation) (#6701)
## Summary

This PR enables Grounded SAM workflows
(https://arxiv.org/pdf/2401.14159) via the following:
- `GroundingDinoInvocation` for running a Grounding DINO model.
- `SegmentAnythingModelInvocation` for running a SAM model.
- `MaskTensorToImageInvocation` for convenient visualization.

Other notes:
- Uses the transformers implementation of Grounding DINO and SAM.
- The new models are treated as 'utility models' meaning that they are
not visible in the Models tab, and are downloaded automatically the
first time that they are used.

<img width="874" alt="image"
src="https://github.com/user-attachments/assets/1cbaa97d-0e27-4943-86b1-dc7327ba8675">

## Example

Input image

![be10ec0c-20a8-4ac7-840e-d1a05fffdb6a](https://github.com/user-attachments/assets/bf21572c-635d-4703-b4ab-7aba658a9671)

Prompt: "wheels", all other configs default
Result:

![2221c44e-64e6-4b18-b4cb-610514b7a554](https://github.com/user-attachments/assets/344b91f4-7f4a-4b70-8e2e-3b4a0e55176d)

## Related Issues / Discussions

Thanks to @blessedcoolant for the initial draft here:
https://github.com/invoke-ai/InvokeAI/pull/6678

## QA Instructions

Manual tests:
- [ ] Test that default settings work well.
- [ ] Test with / without apply_polygon_refinement
- [ ] Test mask_filter options
- [ ] Test detection_threshold values
- [ ] Test RGB input image
- [ ] Test RGBA input image
- [ ] Test grayscale input image
- [ ] Smoke test that an empty mask is returned when 0 objects are
detected
- [ ] Test on CPU
- [ ] Test on MPS (Works on Mac OS, but had to force both models to run
on CPU instead of MPS)

Performance:
- Peak GPU memory utilization with both Grounding DINO and SAM models
loaded is ~4.5GB. (The models do not need to be loaded at the same time,
so could be offloaded by the MM if needed.)
- On an RTX4090, with the models already cached, node execution takes
~0.6 secs.
- On my CPU, with the models cached, node execution takes ~10secs.

## Merge Plan

No special instructions.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [x] _Documentation added / updated (if applicable)_
2024-08-01 20:40:18 +02:00
981475a624 Merge branch 'main' into ryan/grounded-sam 2024-08-01 20:30:35 +02:00
27ac61a4fb Expose all model options in the GroundingDinoInvocation and the SegmentAnythingInvocation. 2024-08-01 14:23:32 -04:00
675ffc2757 Remove BoundingBoxInvocation field name overrides. 2024-08-01 14:05:44 -04:00
44b21f10f1 Add a pydantic model_validator to BoundingBoxField to check the validity of the coords. 2024-08-01 14:00:57 -04:00
c6d49e8b1f Shorten SegmentAnythingInvocation and GroundingDinoInvocatino docstrings, since they are used as the invocation descriptions in the UI. 2024-08-01 10:17:42 -04:00
e6a512aa86 (minor) Tweak order of mask operations. 2024-08-01 10:12:24 -04:00
c3a6a6fb22 Rename SegmentAnythingModelInvocation -> SegmentAnythingInvocation. 2024-08-01 10:00:36 -04:00
b9dc3460ba Rename SegmentAnythingModel -> SegmentAnythingPipeline. 2024-08-01 09:57:47 -04:00
63581ec980 (minor) Add None check to fix static type checking error. 2024-08-01 09:51:53 -04:00
08b1feeed7 add base prop for destination to direct users to different tabs on initial load (#6706)
## Summary
- we want a way to load the studio while being directed to a specific
tab, introduced a destination prop to achieve that
<!--A description of the changes in this PR. Include the kind of change
(fix, feature, docs, etc), the "why" and the "how". Screenshots or
videos are useful for frontend changes.-->

## Related Issues / Discussions

<!--WHEN APPLICABLE: List any related issues or discussions on github or
discord. If this PR closes an issue, please use the "Closes #1234"
format, so that the issue will be automatically closed when the PR
merges.-->

## QA Instructions

<!--WHEN APPLICABLE: Describe how you have tested the changes in this
PR. Provide enough detail that a reviewer can reproduce your tests.-->

## Merge Plan

<!--WHEN APPLICABLE: Large PRs, or PRs that touch sensitive things like
DB schemas, may need some care when merging. For example, a careful
rebase by the change author, timing to not interfere with a pending
release, or a message to contributors on discord after merging.-->

## Checklist

- [ ] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-07-31 19:25:36 -04:00
f5cfdcf32d feat: Add BoundingBox Primitive Node 2024-08-01 04:09:08 +05:30
e78fb428f0 simplify destination prop handling 2024-07-31 18:06:22 -04:00
31e270e32c add base prop for destination to direct users to different tabs 2024-07-31 17:20:51 -04:00
b5832768dc Return a MaskOutput from SegmentAnythingModelInvocation. And add a MaskTensorToImageInvocation. 2024-07-31 17:16:14 -04:00
4ce64b69cb Modular backend - LoRA/LyCORIS (#6667)
## Summary

Code for lora patching from #6577.
Additionally made it the way, that lora can patch not only `weight`, but
also `bias`, because saw some loras which doing it.

## Related Issues / Discussions

#6606 

https://invokeai.notion.site/Modular-Stable-Diffusion-Backend-Design-Document-e8952daab5d5472faecdc4a72d377b0d

## QA Instructions

Run with and without set `USE_MODULAR_DENOISE` environment.

## Merge Plan

Replace old lora patcher with new after review done.
If you think that there should be some kind of tests - feel free to add.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-07-31 21:31:31 +02:00
5a9173f766 Merge branch 'main' into stalker-modular_lora 2024-07-31 15:13:22 -04:00
0bb7ed44f6 Add some docs to OriginalWeightsStorage and fix type hints. 2024-07-31 15:08:24 -04:00
332bc9da5b fix: Update depth anything node default to v2 2024-07-31 23:52:29 +05:30
08def3da95 fix: Update canvas depth anything processor default to v2 2024-07-31 23:50:13 +05:30
daf899f9c4 fix: Move the manual image resizing out of the depth anything pipeline 2024-07-31 23:38:12 +05:30
13fb2d1f49 fix: Add Depth Anything V2 as a new option
It is also now the default in the UI replacing Depth Anything V1 small
2024-07-31 23:29:43 +05:30
95dde802ea fix: assert the return depth map to be a PIL image 2024-07-31 23:22:01 +05:30
fca119773b Split invokeai/backend/image_util/segment_anything/ dir into grounding_dino/ and segment_anything/ 2024-07-31 12:28:47 -04:00
0193267a53 Split GroundedSamInvocation into GroundingDinoInvocation and SegmentAnythingModelInvocation. 2024-07-31 12:20:23 -04:00
b4cf78a95d fix: make DA Pipeline a subclass of RawModel 2024-07-31 21:14:49 +05:30
73386826d6 Make GroundingDinoPipeline and SegmentAnythingModel subclasses of RawModel for type checking purposes. 2024-07-31 10:25:34 -04:00
9f448fecb7 Move invokeai/backend/grounded_sam -> invokeai/backend/image_util/grounded_sam 2024-07-31 10:00:30 -04:00
bcd1483a14 Re-order GroundedSAMInvocation._to_numpy_masks(...) to do slightly more work on the GPU. 2024-07-31 09:51:14 -04:00
e206890e25 Use staticmethods rather than inner functions for the Grounding DINO and SAM model loaders. 2024-07-31 09:28:52 -04:00
0a7048f650 (minor) Simplify GroundedSAMInvocation._merge_masks(...). 2024-07-31 08:58:51 -04:00
e8ecf5e155 (minor) Move apply_polygon_refinement condition up a layer. 2024-07-31 08:50:56 -04:00
33e8604b57 Make Grounding DINO DetectionResult a Pydantic model. 2024-07-31 08:47:00 -04:00
cec7399366 (minor) Use a new variable name to satisfy type checks. 2024-07-31 08:27:01 -04:00
bdae81e429 (minor) Simplify GroundedSAMInvocation._filter_detections() 2024-07-31 08:25:19 -04:00
67c32f3d6c Fix typo: zip(..., strict=True) 2024-07-31 08:15:28 -04:00
94d64b8a78 Fix gradient mask values range (#6688)
## Summary

Gradient mask node outputs mask tensor with values in range [-1, 1],
which unexpected range for mask.
It handled in denoise node the way it translates to [0, 2] mask, which
looks even more wrongly)
From discussion with @dunkeroni I understand him as he thought that
negative values will be treated same as 0, so clamping values not change
intended node logic.

## Related Issues / Discussions

#6643 

## QA Instructions

\-

## Merge Plan

\-

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-07-31 06:37:32 +05:30
fa3c0c81b3 Merge branch 'main' into stalker7779/fix_gradient_mask 2024-07-31 06:30:44 +05:30
66547b99c1 Add more karras schedulers (#6695)
## Summary

Add karras variants of `deis`, `unipc`, `kdpm2` and `kdpm_2_a`
schedulers.
Also added `dpmpp_3` schedulers, but `dpmpp_3s` currently bugged, so
added only 3m:
https://github.com/huggingface/diffusers/issues/9007

## Related Issues / Discussions

\-

## QA Instructions

\-

## Merge Plan

~@psychedelicious We need to decide what to do with schedulers order, as
it looks a bit broken:~

![image](https://github.com/user-attachments/assets/e41674af-d87c-4432-8014-c90bd86965a6)

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-07-31 06:09:26 +05:30
328e58be4c Merge branch 'main' into stalker7779/new_karras_schedulers 2024-07-31 05:56:13 +05:30
18f89ed5ed fix: Make DepthAnything work with Invoke's Model Management 2024-07-31 03:57:54 +05:30
5701c79fab Prevent Grounding DINO and Segment Anything from being moved to MPS - they don't work on MPS devices. 2024-07-30 23:04:15 +02:00
2da9f913f3 Add detection_result.py - was forgotten in a prior commit 2024-07-30 16:04:29 -04:00
6b10b59abe Make GroundedSAMInvocation work with any input image mode (RGB, RGBA, grayscale). 2024-07-30 15:55:57 -04:00
918f77bce0 Move some logic from GroundedSAMInvocation to the backend classes. 2024-07-30 15:34:33 -04:00
f170697ebe Merge branch 'main' into depth_anything_v2 2024-07-31 00:53:32 +05:30
556c6a1d84 fix: Update DepthAnything to use the transformers implementation 2024-07-31 00:51:55 +05:30
aca2a2fa13 Add mask_filter and detection_threshold options to the GroundedSAMInvocation. 2024-07-30 14:22:40 -04:00
ff6398f7d8 Add a GroundedSamInvocation for image segmentation from a text prompt (Grounding DINO + Segment Anything Model). 2024-07-30 11:12:26 -04:00
cf996472b9 Suggested changes
Co-Authored-By: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
2024-07-30 04:50:56 +03:00
156d14c349 Run api regen 2024-07-30 04:05:21 +03:00
86f705bf48 Optimize weights handling 2024-07-30 03:39:01 +03:00
1fd9631f2d Comments fix
Co-Authored-By: Ryan Dick <14897797+RyanJDick@users.noreply.github.com>
2024-07-30 00:39:50 +03:00
2227a2357f Suggested changes + simplify weights logic in patching
Co-Authored-By: Ryan Dick <14897797+RyanJDick@users.noreply.github.com>
2024-07-30 00:34:37 +03:00
58e7ab157d Ruff format 2024-07-29 22:59:17 +03:00
8d16fa6a49 Remove dpmpp_3s schedulers as it bugged now 2024-07-29 22:55:45 +03:00
55e810efa3 Add dpmpp_3 schedulers 2024-07-29 22:52:15 +03:00
2755316021 update delete board modal to be more descriptive (#6690)
## Summary

<!--A description of the changes in this PR. Include the kind of change
(fix, feature, docs, etc), the "why" and the "how". Screenshots or
videos are useful for frontend changes.-->

## Related Issues / Discussions

<!--WHEN APPLICABLE: List any related issues or discussions on github or
discord. If this PR closes an issue, please use the "Closes #1234"
format, so that the issue will be automatically closed when the PR
merges.-->

## QA Instructions

<!--WHEN APPLICABLE: Describe how you have tested the changes in this
PR. Provide enough detail that a reviewer can reproduce your tests.-->

## Merge Plan

<!--WHEN APPLICABLE: Large PRs, or PRs that touch sensitive things like
DB schemas, may need some care when merging. For example, a careful
rebase by the change author, timing to not interfere with a pending
release, or a message to contributors on discord after merging.-->

## Checklist

- [ ] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-07-29 13:43:17 -04:00
6525f18610 Merge branch 'main' into chainchompa/board-delete-info 2024-07-29 12:52:36 -04:00
2ad13ac7eb Modular backend - inpaint (#6643)
## Summary

Code for inpainting and inpaint models handling from
https://github.com/invoke-ai/InvokeAI/pull/6577.
Separated in 2 extensions as discussed briefly before, so wait for
discussion about such implementation.

## Related Issues / Discussions

#6606

https://invokeai.notion.site/Modular-Stable-Diffusion-Backend-Design-Document-e8952daab5d5472faecdc4a72d377b0d

## QA Instructions

Run with and without set `USE_MODULAR_DENOISE` environment.
Try and compare outputs between backends in cases:
- Normal generation on inpaint model
- Inpainting on inpaint model
- Inpainting on normal model

## Merge Plan

Nope.
If you think that there should be some kind of tests - feel free to add.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-07-29 10:27:25 -04:00
693a3eaff5 Merge branch 'main' into stalker-modular_inpaint-2 2024-07-29 10:14:45 -04:00
ffca792d5b edited copy for deleted boards message 2024-07-29 09:46:08 -04:00
86a92bb6b5 Add more karras schedulers 2024-07-29 15:14:34 +03:00
171a4e6d80 fix(ui): race condition when deleting a board and resetting selected/auto-add
We were checking the selected and auto-add board ids against the query cache to see if they still exist. If not, we reset.

This only works if the query cache is updated by the time we do the check - race condition!

We already have the board id from the query args, so there's no need to check the query cache - just compare the deleted board ID directly.

Previously this file's several listeners were all in a single one and I had adapted/split its logic up a bit wonkily, introducing these problems.
2024-07-29 11:36:03 +10:00
e3a75a8adf fix(ui): fix logic to reset selected/auto-add boards when toggling show archived boards
The logic was incorrect in two ways:
1. We only ran the logic if we _enable_ showing archived boards. It should be run we we _disable_ showing archived boards.
2. If we couldn't find the selected board in the query cache, we didn't do the reset. This is wrong - if the board isn't in the query cache, we _should_ do the reset. This inverted logic makes more sense before the fix for issue 1.
2024-07-29 11:36:03 +10:00
ee7503ce13 Modular backend - T2I Adapter (#6662)
## Summary

T2I Adapter code from #6577.

## Related Issues / Discussions

#6606 

https://invokeai.notion.site/Modular-Stable-Diffusion-Backend-Design-Document-e8952daab5d5472faecdc4a72d377b0d

## QA Instructions

Run with and without set `USE_MODULAR_DENOISE` environment.

## Merge Plan

Nope.
If you think that there should be some kind of tests - feel free to add.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-07-28 15:52:04 -04:00
8500bac3ca Use logger for warning 2024-07-28 22:51:52 +03:00
310719eb4c Merge branch 'main' into stalker-modular_t2i_adapter 2024-07-28 15:30:00 -04:00
e8e24822ec Modular backend - Seamless (#6651)
## Summary

Seamless code from #6577.

## Related Issues / Discussions

#6606 

https://invokeai.notion.site/Modular-Stable-Diffusion-Backend-Design-Document-e8952daab5d5472faecdc4a72d377b0d

## QA Instructions

Run with and without set `USE_MODULAR_DENOISE` environment.

## Merge Plan

Nope.
If you think that there should be some kind of tests - feel free to add.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-07-28 13:57:38 -04:00
c57a7afb87 Merge branch 'main' into stalker7779/modular_seamless 2024-07-28 13:49:43 -04:00
84d028898c Revert wrong comment copy 2024-07-27 13:20:58 +03:00
ed0174fbc6 Suggested changes
Co-Authored-By: Ryan Dick <14897797+RyanJDick@users.noreply.github.com>
2024-07-27 13:18:28 +03:00
9e582563eb Suggested changes
Co-Authored-By: Ryan Dick <14897797+RyanJDick@users.noreply.github.com>
2024-07-27 04:25:15 +03:00
faa88f72bf Make lora as separate extensions 2024-07-27 02:39:53 +03:00
0d69a31df0 Merge branch 'main' into chainchompa/board-delete-info 2024-07-26 14:03:18 -04:00
daa5a88eb2 Update docker image to use pnpm version 8 2024-07-26 13:57:33 -04:00
5b84e117b2 Suggested changes
Co-Authored-By: Ryan Dick <14897797+RyanJDick@users.noreply.github.com>
2024-07-26 20:51:12 +03:00
eb257d2d28 update delete board modal to be more descriptive 2024-07-26 13:34:25 -04:00
5810cee6c9 Suggested changes
Co-Authored-By: Ryan Dick <14897797+RyanJDick@users.noreply.github.com>
2024-07-26 19:47:28 +03:00
eef88d1f83 Update gradient mask node version 2024-07-26 19:33:41 +03:00
78f6850fc0 Fix gradient mask values range 2024-07-26 19:28:00 +03:00
bd8890be11 Revert "Fix create gradient mask node output"
This reverts commit 9d1fcba415.
2024-07-26 19:24:46 +03:00
adf1a977ea Suggested changes
Co-Authored-By: Ryan Dick <14897797+RyanJDick@users.noreply.github.com>
2024-07-26 19:22:26 +03:00
e1509bcb45 bump version to 4.2.7 2024-07-26 09:11:17 -07:00
edcaf8287d feat(app): remove beta from multidiffusion workflows 2024-07-26 13:47:51 +10:00
39bd30f2a0 feat(app): update default workflows
- Update `MultiDiffusion SDXL (Beta)`
- Add `MultiDiffusion SD1.5 (Beta)`
2024-07-26 13:47:51 +10:00
102b47190f feat(ui): update qr code cnet starter model
- For SD1.5, use the new V2 version
- Add the SDXL version
2024-07-26 13:34:32 +10:00
269fe2e3bb track accordions in tabs separately so open/close state isnt shared 2024-07-26 08:20:24 +10:00
b32aa1c77f fix missing quote in translation 2024-07-26 08:20:24 +10:00
6656544ed5 tooltip copy updates
Co-authored-by: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
2024-07-26 08:20:24 +10:00
4c75b93410 feat(ui): add informational popovers for upscale params 2024-07-26 08:20:24 +10:00
5be0de967d feat(ui): close generation and advanced accordions when switching to upscale tab 2024-07-26 08:20:24 +10:00
f8e27b837b fix(ui): memoize model manager components 2024-07-26 07:52:10 +10:00
47414be1e6 fix(ui): dropped model config cache breaking model edit UI
The model edit UI's composition allows for the model edit form to be instantiated before the model's config has been received. This results in the form having no values - all the fields are blank instead of populated by the model config.

Part of the fix is to pass the model config around directly instead of relying on _all_ components to fetch the model directly.

I also fixed a crapload of performance issues related to improper use of redux selectors.
2024-07-26 07:52:10 +10:00
74cef38bcf fix(backend): add refiner to single-file load_classes
Fixes single-file refiner loading.
2024-07-26 05:08:01 +10:00
bb876b8d4e fix(ui): copied edges must have new ids set
Problems this was causing:
- Deleting an edge was a copy of another edge deletes both edges
- Deleting a node that was a copy-with-edges of another node deletes its edges and it's original edges, leaving what I will call "ghost noodles" behind
2024-07-26 04:54:33 +10:00
ba747373db feat(ui): add button to disable info popovers from info popover 2024-07-25 08:06:41 -04:00
95661c8b21 feat(ui): enable info popovers by default 2024-07-25 08:06:41 -04:00
e5d9ca013e fix: use v1 models for large and base versions 2024-07-25 17:24:12 +05:30
4166c756ce wip: depth_anything_v2 init lint fixes 2024-07-25 14:41:22 +05:30
4f0dfbd34d wip: depth_anything_v2 initial implementation 2024-07-25 13:53:06 +05:30
b70ac88684 perf(ui): throttle page changes
Previously you could spam the next/prev buttons and really thrash the server. Throttled to 500ms, which feels like a happy medium between responsive and not-thrash-y.
2024-07-25 11:57:54 +10:00
24609da6ab feat(ui): tweak pagination styles 2024-07-25 11:57:54 +10:00
524647b1f1 fix(ui): jumpto interactions
- Autofocus on popover open
- Autoselect number on popover open
- Enter works to change page when input is focused
- Esc works to close popover when input is focused
2024-07-25 11:57:54 +10:00
cf1af94f53 feat(ui): make jump to page a popover 2024-07-25 11:57:54 +10:00
2a9fdc6314 feat(ui): add jump to option for gallery pagination 2024-07-25 11:57:54 +10:00
46c632e7cc Change layer detection keys according to LyCORIS repository 2024-07-25 02:10:47 +03:00
653f63ae71 Add layer keys check 2024-07-25 02:03:08 +03:00
8a9e2f57a4 Handle bias in full/diff lora layer 2024-07-25 02:02:37 +03:00
31949ed2f2 Refactor code a bit 2024-07-25 02:00:30 +03:00
3657285b1b chore: bump version v4.2.7rc1 2024-07-25 06:23:50 +10:00
e4b5975305 translationBot(ui): update translation files
Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/
Translation: InvokeAI/Web UI
2024-07-25 06:09:04 +10:00
b59825edc0 translationBot(ui): update translation (Spanish)
Currently translated at 34.4% (448 of 1300 strings)

Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/es/
Translation: InvokeAI/Web UI
2024-07-25 06:09:04 +10:00
25788f6869 translationBot(ui): update translation (Italian)
Currently translated at 98.6% (1289 of 1307 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.5% (1277 of 1296 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-07-25 06:09:04 +10:00
0ccb304b8b Ruff format 2024-07-24 16:01:29 +03:00
ca5a4ee59d fix(ui): few cases where board totals don't updated when moving 2024-07-24 22:30:44 +10:00
4fdefe58c7 feat(ui): clear gallery search on esc key 2024-07-24 14:10:16 +10:00
9870f5a96f fix(ui): race condition with gallery search
It was possible to clear the search term while a debounced setSearchTerm is still pending. This resulted in the gallery getting out of sync w/ the search term.

To fix this, we need to lift the state up a bit and  cancel any pending debounced setSearchTerm calls when closing the search or clearing the search term box.
2024-07-24 14:10:16 +10:00
c296ae8cfe feat(ui): add useAssertSingleton hook
Use this to enforce singleton components and hooks.
2024-07-24 14:10:16 +10:00
17493f4ae0 fix(ui): close boards search when toggling panel 2024-07-24 14:10:16 +10:00
2503dca813 fix(ui): show boards panel when opening board search 2024-07-24 14:10:16 +10:00
cb61ef9bb1 feat(ui): use color instead of super tiny icon change to indicate board search toggle state
You can't even see the icon, no point in changing it. Blue = active/open, Grey = closed.
2024-07-24 14:10:16 +10:00
1831ed620f fix(ui): gallery tabs layout 2024-07-24 14:10:16 +10:00
c385e76356 fix(ui): DeleteBoardModal must be a singleton 2024-07-24 14:10:16 +10:00
ff1972fbb3 fix(ui): spacing issue w/ boards search 2024-07-24 14:10:16 +10:00
c4b3405bfa fix(ui): make uncategorized and board components same height 2024-07-24 14:10:16 +10:00
ab2548c0cd feat(ui): minor padding tweaks in boardslist 2024-07-24 14:10:16 +10:00
dc2a3363b0 feat(ui): layout shift when using a collapse w/ flex gap
the gap isn't handled smoothly, there's always a jump. cannot use gap in the collapsible's container
2024-07-24 14:10:16 +10:00
d7a5fe2805 feat(ui): make arrow icon rotate on boards list 2024-07-24 14:10:16 +10:00
4e49689d46 feat(ui): make isPrivate required on BoardsList 2024-07-24 14:10:16 +10:00
ca8441a32f fix(ui): alignment & overflow on gallery header 2024-07-24 14:10:16 +10:00
44284d671c feat(ui): tweak padding for boards in list 2024-07-24 14:10:16 +10:00
e89de1d5b7 feat(ui): tweak board tooltip styles
When the totals were high enough, the image looked really off. Also fixed some inconsistent padding.
2024-07-24 14:10:16 +10:00
6db63349f8 fix(ui): missing key on list element 2024-07-24 14:10:16 +10:00
7f6f892533 fix circular dep 2024-07-24 14:10:16 +10:00
d1bbd0cf80 cleanup 2024-07-24 14:10:16 +10:00
bd73b6b2af reorganize the gallery - move board name to top of image grid, add hide/view boards button for toggle 2024-07-24 14:10:16 +10:00
0d40a7d865 exclude uncategorized from search and make sure list is always correct 2024-07-24 14:10:16 +10:00
c2f6b80246 move Uncategorized back to private board list 2024-07-24 14:10:16 +10:00
80f5f8210a increase font size of Move for boards 2024-07-24 14:10:16 +10:00
b7383cc0e5 board UI updates: always show search for boards and images if a term is entered, clear search when view is toggled off 2024-07-24 14:10:16 +10:00
2172e4d292 board UI updates: font tweaks, add cover image to tooltip, move uncategorized out of board list, allow collapsible board list if private enabled 2024-07-24 14:10:16 +10:00
ab0bfa709a Handle loras in modular denoise 2024-07-24 05:07:29 +03:00
6af659b1da Handle t2i adapter in modular denoise 2024-07-24 02:55:33 +03:00
db664afc49 fix(ui): model select overflowing when model names are too long 2024-07-24 09:35:32 +10:00
b99a53e64e tidy(ui): organise postprocessing listeners 2024-07-24 08:22:46 +10:00
5f4ce6fda3 tidy(ui): organise postprocessing files 2024-07-24 08:22:46 +10:00
93e95ce53f chore(ui): lint 2024-07-24 08:22:46 +10:00
2997f0a1f8 fix(ui): ts issue 2024-07-24 08:22:46 +10:00
40b262bcc2 tidy(ui): "simpleUpscale" -> "postProcessing" 2024-07-24 08:22:46 +10:00
a26f050cbb feat(ui): rename ad-hoc upscale stuff to post-processing 2024-07-24 08:22:46 +10:00
94b5b2a467 feat(ui): improve starter model search for spandrel models 2024-07-24 08:22:46 +10:00
b4519ea61f tidy(ui): remove unused maxUpscalePixels config 2024-07-24 08:22:46 +10:00
7f7ce291b5 feat(ui): revised simple upscale warning UI 2024-07-24 08:22:46 +10:00
aeb53563ff feat(ui): use graph util for ad-hoc upscale graph 2024-07-24 08:22:46 +10:00
e8d2e2330e fix(ui): set board in ad-hoc upscale graph 2024-07-24 08:22:46 +10:00
4c6b9ce7c9 fix(ui): use spandrel autoscale node in upscaling tab 2024-07-24 08:22:46 +10:00
87a2221d72 chore(ui): typegen 2024-07-24 08:22:46 +10:00
76aa6bdf05 feat(nodes): split spandrel node
`spandrel_image_to_image` now just runs the model with no changes.

`spandrel_image_to_image_autoscale` runs the model repeatedly until the desired scale is reached. previously, `spandrel_image_to_image` did this.
2024-07-24 08:22:46 +10:00
416d29fb83 Ruff format 2024-07-24 01:17:28 +03:00
0c1994d682 fix(ui): restore pnpm-lock.yaml
#6645 inadvertently removed the lockfile
2024-07-24 08:07:32 +10:00
19c00241c6 Use non-inverted mask generally(except inpaint model handling) 2024-07-24 00:59:13 +03:00
633bbb4e85 [MM2] Use typed ModelRecordChanges for model_install() rather than untyped dict (#6645)
* [MM2] replace untyped config dict passed to install_model with typed ModelRecordChanges

- adjusted frontend to work with new schema
- used this facility to assign "starter model" names and descriptions to the installed
  models.

* documentation fix

* [MM2] replace untyped config dict passed to install_model with typed ModelRecordChanges

- adjusted frontend to work with new schema
- used this facility to assign "starter model" names and descriptions to the installed
  models.

* documentation fix

* remove v9 pnpm lockfile

* [MM2] replace untyped config dict passed to install_model with typed ModelRecordChanges

- adjusted frontend to work with new schema
- used this facility to assign "starter model" names and descriptions to the installed
  models.

* [MM2] replace untyped config dict passed to install_model with typed ModelRecordChanges

- adjusted frontend to work with new schema
- used this facility to assign "starter model" names and descriptions to the installed
  models.

* remove v9 pnpm lockfile

* regenerate schema.ts

* prettified

---------

Co-authored-by: Lincoln Stein <lstein@gmail.com>
2024-07-23 21:41:00 +00:00
a221ab2fb6 fix(ui): upsell menuitem styling 2024-07-24 06:58:27 +10:00
0279a27f66 fix(ui): render settingsmenu in portal, no zindex 2024-07-24 06:58:27 +10:00
54aef4959c cleanup 2024-07-24 06:56:02 +10:00
4017609b91 clean up useIsAllowedToUpscale since its no longer necessary 2024-07-24 06:56:02 +10:00
cb0bffedd5 fix board handling for simple upscale 2024-07-24 06:56:02 +10:00
1fd2a91ccd only show warning for simple upscale if no simple upscale model is available 2024-07-24 06:56:02 +10:00
c323a760a5 Suggested changes
Co-Authored-By: Ryan Dick <14897797+RyanJDick@users.noreply.github.com>
2024-07-23 23:34:28 +03:00
9d1fcba415 Fix create gradient mask node output 2024-07-23 23:29:28 +03:00
075e0405f9 Update Simple Upscale Button to work with spandrel models (#6649)
## Summary
Update Simple Upscale Button to work with spandrel models, add
UpscaleWarning when models aren't available, clean up ESRGAN logic
<!--A description of the changes in this PR. Include the kind of change
(fix, feature, docs, etc), the "why" and the "how". Screenshots or
videos are useful for frontend changes.-->

## Related Issues / Discussions

<!--WHEN APPLICABLE: List any related issues or discussions on github or
discord. If this PR closes an issue, please use the "Closes #1234"
format, so that the issue will be automatically closed when the PR
merges.-->

## QA Instructions

<!--WHEN APPLICABLE: Describe how you have tested the changes in this
PR. Provide enough detail that a reviewer can reproduce your tests.-->

## Merge Plan

<!--WHEN APPLICABLE: Large PRs, or PRs that touch sensitive things like
DB schemas, may need some care when merging. For example, a careful
rebase by the change author, timing to not interfere with a pending
release, or a message to contributors on discord after merging.-->

## Checklist

- [ ] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-07-23 13:33:01 -04:00
bf6066d834 Merge branch 'main' into chainchompa/simple-upscale-updates 2024-07-23 13:27:48 -04:00
5635f65ee9 feat(ui): add upsells for pro edition to settings menu 2024-07-23 13:27:00 -04:00
6317cf8ef9 move handleSimpleUpscaleModels logic into handleSpandrelImageToImageModels listener 2024-07-23 13:13:21 -04:00
9e1daf06f7 Merge branch 'main' into chainchompa/simple-upscale-updates 2024-07-23 12:16:44 -04:00
e1a718b512 cleanup 2024-07-23 12:16:35 -04:00
cbce89162b update simple upscale metadata to match upscale metadata 2024-07-23 12:15:26 -04:00
b46b20210d handle simple upscale models on modelsLoaded 2024-07-23 11:53:43 -04:00
8e89157a83 reuse ParamSpandrelModel for simple upscale 2024-07-23 11:36:46 -04:00
ca21996a97 Remove old seamless class 2024-07-23 18:04:33 +03:00
62aa064e56 Handle seamless in modular denoise 2024-07-23 18:03:59 +03:00
7c975f0d00 Modular backend - add ControlNet (#6642)
## Summary

ControlNet code from #6577.

## Related Issues / Discussions

#6606

https://invokeai.notion.site/Modular-Stable-Diffusion-Backend-Design-Document-e8952daab5d5472faecdc4a72d377b0d

## QA Instructions

Run with and without set `USE_MODULAR_DENOISE` environment.

## Merge Plan

Merge #6641 firstly, to be able see output difference properly.
If you think that there should be some kind of tests - feel free to add.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-07-23 10:37:25 -04:00
8107884c8d Merge branch 'main' into chainchompa/simple-upscale-updates 2024-07-23 10:28:11 -04:00
a2f49ef7c1 cleanup esrgan frontend code 2024-07-23 10:22:38 -04:00
e2e47fd606 Merge branch 'main' into stalker-modular_controlnet 2024-07-23 10:19:12 -04:00
c098edc6b2 updated simple upscale to use spandrel node and list of available spandrel models 2024-07-23 10:15:31 -04:00
bc1d9748ce updated upscale warning to work for simple upscale 2024-07-23 10:04:31 -04:00
7b8e25f525 Modular backend - add FreeU (#6641)
## Summary

FreeU code from https://github.com/invoke-ai/InvokeAI/pull/6577.
Also fix issue with sometimes slightly different output.

## Related Issues / Discussions

#6606 

https://invokeai.notion.site/Modular-Stable-Diffusion-Backend-Design-Document-e8952daab5d5472faecdc4a72d377b0d

## QA Instructions

Run with and without set `USE_MODULAR_DENOISE` environment.

## Merge Plan

Nope.
If you think that there should be some kind of tests - feel free to add.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-07-23 10:02:56 -04:00
db52f5606f Merge branch 'main' into stalker-modular_freeu 2024-07-23 09:53:32 -04:00
de39c5ed21 Modular backend - add rescale cfg (#6640)
## Summary

Rescale CFG code from #6577.

## Related Issues / Discussions

#6606 

https://invokeai.notion.site/Modular-Stable-Diffusion-Backend-Design-Document-e8952daab5d5472faecdc4a72d377b0d

## QA Instructions

Run with and without set `USE_MODULAR_DENOISE` environment.
~~Note: for some reasons there slightly different output from run to
run, but I able sometimes to get same output on main and this branch.~~
Fix presented in #6641.

## Merge Plan

~~Nope.~~ Merge #6641 firstly, to be able see output difference
properly.
If you think that there should be some kind of tests - feel free to add.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-07-23 09:45:30 -04:00
d014dc94fd Merge branch 'main' into stalker7779/modular_rescale_cfg 2024-07-23 09:34:22 -04:00
39e804d0f8 Use consistent param names in patch_extension(...) functions: context -> ctx. 2024-07-23 09:18:04 -04:00
154e8f6e78 chore(ui): lint 2024-07-23 15:42:16 +10:00
2d31b82e60 feat(ui): tweak layout for warning message 2024-07-23 15:42:16 +10:00
8f934747f3 feat(ui): updated upscale tab warnings 2024-07-23 15:42:16 +10:00
4352341a00 feat(ui): starter models filter matches spandrel models to "upscale" search term 2024-07-23 15:42:16 +10:00
d7e0ec52ff feat(ui): make model install tab controlled
This lets us navigate directly to eg the Starter Models tab
2024-07-23 15:42:16 +10:00
1072b74c0e fix(ui): edge cases in starter models search 2024-07-23 15:42:16 +10:00
46dc8c6641 chore(ui): lint 2024-07-23 15:42:16 +10:00
a8bc6ab5b1 fix(ui): typos 2024-07-23 15:42:16 +10:00
bd91bd4a84 Math Updates 2024-07-23 15:42:16 +10:00
8756a6b8c3 fix(ui): remove sharpness param 2024-07-23 10:55:54 +10:00
2e0cebb571 fix(ui): bug where viewer would disappear on upscaling tab 2024-07-23 10:55:54 +10:00
c3a8184431 feat(ui): add number input to scale slider 2024-07-23 10:55:54 +10:00
ffa39d74b3 feat(ui): remove first unsharp from upscale graph 2024-07-23 10:55:54 +10:00
f9d3966ea2 feat(ui): add scale param to upscaling tab 2024-07-23 10:55:54 +10:00
7cee4e42a7 feat(ui): add addEdgeToMetadata graph helper 2024-07-23 10:55:54 +10:00
071c7c7c7e chore(ui): typegen 2024-07-23 10:55:54 +10:00
818045f678 tidy(ui): use × instead of translation string 2024-07-23 10:55:54 +10:00
7edefbefff feat(ui): add translation for upscaling tab 2024-07-23 10:55:54 +10:00
29efab70b7 feat(nodes): spandrel_image_to_image.scale defaults to 4.0 2024-07-23 10:55:54 +10:00
ac6adc392a feat(nodes): add scale and fit_to_multiple_of_8 to spandrel node 2024-07-23 10:55:54 +10:00
a2ef5d56ee feat(nodes): split out spandrel node upscale logic into utils 2024-07-23 10:55:54 +10:00
13f3560e55 more lint fixes 2024-07-23 10:55:54 +10:00
c4bd60e00f knip fix 2024-07-23 10:55:54 +10:00
54eda9163c remove tiledVAE option and make it true 2024-07-23 10:55:54 +10:00
582f384fff lint fix 2024-07-23 10:55:54 +10:00
a43211e650 math updates for controlnet tiles 2024-07-23 10:55:54 +10:00
6cb0581b0d add description to upscale model dropdown tooltip 2024-07-23 10:55:54 +10:00
845d77916e lint fix 2024-07-23 10:55:54 +10:00
f18431a999 use fn to get width/height of output image 2024-07-23 10:55:54 +10:00
5060bf2f62 lint fix 2024-07-23 10:55:54 +10:00
7854d913b2 add upscaling data to metadata 2024-07-23 10:55:54 +10:00
890a3ce32a add limited metadata 2024-07-23 10:55:54 +10:00
fb4b3f3350 fix creativity/sharpness/structure scales, move where loras are added, get scale const working 2024-07-23 10:55:54 +10:00
d166b08b6a restore scale but hardcode it to 2 regardless of upscale model 2024-07-23 10:55:54 +10:00
5266e9e682 fix(ui): remove unused scale param 2024-07-23 10:55:54 +10:00
d0265e21b0 fix(ui): use spandrel node for upscaling 2024-07-23 10:55:54 +10:00
3126e8e49a chore(ui): typegen 2024-07-23 10:55:54 +10:00
9e3412d776 translations and lint fix 2024-07-23 10:55:54 +10:00
4a09cc57be use the tile conttrolnet in graph instad of marys hardcoded key 2024-07-23 10:55:54 +10:00
5ab36e0433 add warning if no upscale model or no tile controlnet for base model 2024-07-23 10:55:54 +10:00
d2bf3629bf base scale off of upscale model selected 2024-07-23 10:55:54 +10:00
d9b217d908 hook up sharpness, structure, and creativity 2024-07-23 10:55:54 +10:00
2847f1b5ac add vae toggle, lint fix 2024-07-23 10:55:54 +10:00
bc30850f3a hardcode marys tile cnet key 2024-07-23 10:55:54 +10:00
7668dc68a0 cleanup, add loras 2024-07-23 10:55:54 +10:00
ea449f5a0a upscale graph built, no multidiffusion yet 2024-07-23 10:55:54 +10:00
5a1ed99ca1 restore adhoc upscale button 2024-07-23 10:55:54 +10:00
3a2707ac02 disable invoke button properly for upscaling tab 2024-07-23 10:55:54 +10:00
ce5b1103ed add send to upscale to context menu 2024-07-23 10:55:54 +10:00
fd91b83d86 build out the rest of the accordions 2024-07-23 10:55:54 +10:00
a0a54348e8 removed upscale button, created spandrel model dropdown, created upscale initial image that works with dnd 2024-07-23 10:55:54 +10:00
43b3e242b0 tidy(ui): refactor parameters panel components to be 1:1 with tabs 2024-07-23 10:55:54 +10:00
4e8dcb7a1a Suggested changes
Co-Authored-By: Ryan Dick <14897797+RyanJDick@users.noreply.github.com>
2024-07-23 01:46:29 +03:00
3cb13d6288 Rename as suggested in other PRs
Co-Authored-By: Ryan Dick <14897797+RyanJDick@users.noreply.github.com>
2024-07-23 01:01:18 +03:00
4f01c0f2d3 fix: update uncategorized board totals when deleting and moving images (#6646)
## Summary
- currently the total for uncategorized images is not updating when
moving and deleting images, this will update that count when making
those actions
<!--A description of the changes in this PR. Include the kind of change
(fix, feature, docs, etc), the "why" and the "how". Screenshots or
videos are useful for frontend changes.-->

## Related Issues / Discussions

<!--WHEN APPLICABLE: List any related issues or discussions on github or
discord. If this PR closes an issue, please use the "Closes #1234"
format, so that the issue will be automatically closed when the PR
merges.-->

## QA Instructions

<!--WHEN APPLICABLE: Describe how you have tested the changes in this
PR. Provide enough detail that a reviewer can reproduce your tests.-->

## Merge Plan

<!--WHEN APPLICABLE: Large PRs, or PRs that touch sensitive things like
DB schemas, may need some care when merging. For example, a careful
rebase by the change author, timing to not interfere with a pending
release, or a message to contributors on discord after merging.-->

## Checklist

- [ ] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-07-22 17:10:52 -04:00
87eb018380 Revert debug change 2024-07-22 23:49:20 +03:00
5003e5d763 Same changes as in other PRs, add check for running inpainting on inpaint model without source image
Co-Authored-By: Ryan Dick <14897797+RyanJDick@users.noreply.github.com>
2024-07-22 23:47:39 +03:00
e92af52fb8 fix moving items to uncategorized updating 2024-07-22 16:11:36 -04:00
5f0fe3c8a9 Suggested changes
Co-Authored-By: Ryan Dick <14897797+RyanJDick@users.noreply.github.com>
2024-07-22 23:09:11 +03:00
339dddd018 update uncategorized board totals when deleting and moving images 2024-07-22 16:03:01 -04:00
1b359b55cb Suggested changes
Co-Authored-By: Ryan Dick <14897797+RyanJDick@users.noreply.github.com>
2024-07-22 22:17:29 +03:00
d0435575c1 chore(deps): bump fastapi-events to the next minor version 2024-07-22 04:15:36 -07:00
58f3072b91 Handle inpainting on normal models 2024-07-21 22:17:29 +03:00
9e7b470189 Handle inpaint models 2024-07-21 20:45:55 +03:00
42356ec866 Add ControlNet support to denoise 2024-07-21 20:01:30 +03:00
1748848b7b Ruff fixes 2024-07-21 18:37:20 +03:00
5772965f09 Fix slightly different output with old backend 2024-07-21 18:31:30 +03:00
e046e60e1c Add FreeU support to denoise 2024-07-21 18:31:10 +03:00
9a1420280e Add rescale cfg support to denoise 2024-07-21 17:33:43 +03:00
f9c61f1b6c Fix function call that we forgot to update in #6606 (#6636)
## Summary

Fix function call that we forgot to update in #6606

## QA Instructions

Run a TiledMultiDiffusionDenoiseLatents invocation and make sure it
doesn't crash.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [x] _Tests added / updated (if applicable)_
- [x] _Documentation added / updated (if applicable)_
2024-07-19 17:19:32 -04:00
a8cc5caf96 Fix function call that we forgot to update in https://github.com/invoke-ai/InvokeAI/pull/6606 2024-07-19 17:07:52 -04:00
930ff559e4 add sdxl tile to starter models 2024-07-19 16:49:33 -04:00
473f4cc1c3 Base of modular backend (#6606)
## Summary

Base code of new modular backend from #6577.
Contains normal generation and regional prompts support.
Also preview extension included to test if extensions logic works.

## Related Issues / Discussions


https://invokeai.notion.site/Modular-Stable-Diffusion-Backend-Design-Document-e8952daab5d5472faecdc4a72d377b0d

## QA Instructions

Run with and without set `USE_MODULAR_DENOISE` environment.
Currently only normal and regional conditionings supported, so just
generate some images and compare with main output.

## Merge Plan

Discuss a bit more about injection point names?
As if for example in future unet will be overridable, current
`pre_unet`/`post_unet` assumes to name override as `unet` what feels a
bit odd.
Also `apply_cfg` - future implementation could ignore/not use cfg, so in
this case `combine_noise_predictions`/`combine_noise` seems more
suitable.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [x] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-07-19 16:37:57 -04:00
78d2b1b650 Merge branch 'main' into stalker-backend_base 2024-07-19 16:25:20 -04:00
39e10d894c Add invocation cancellation logic to patchers 2024-07-19 23:17:01 +03:00
e16faa6370 Add gradient blending to tile seams in MultiDiffusion. 2024-07-19 13:05:50 -07:00
83a86abce2 Add unit tests for ExtensionsManager and ExtensionBase. 2024-07-19 14:15:46 -04:00
0c56d4a581 Ryan's suggested changes to extension manager/extensions
Co-Authored-By: Ryan Dick <14897797+RyanJDick@users.noreply.github.com>
2024-07-18 23:49:44 +03:00
97a7f51721 don't use cpu state_dict for model unpatching when executing on cpu (#6631)
Co-authored-by: Lincoln Stein <lstein@gmail.com>
2024-07-18 15:34:01 -04:00
710dc6b487 Merge branch 'main' into stalker7779/backend_base 2024-07-18 01:08:04 +03:00
2ef3b49a79 Add run cancelling logic to extension manager 2024-07-17 04:39:15 +03:00
3f79467f7b Ruff format 2024-07-17 04:24:45 +03:00
2c2ec8f0bc Comments, a bit refactor 2024-07-17 04:20:31 +03:00
79e35bd0d3 Minor fixes 2024-07-17 03:48:37 +03:00
137202b77c Remove patch_unet logic for now 2024-07-17 03:40:27 +03:00
03e22c257b Convert conditioning_mode to enum 2024-07-17 03:37:11 +03:00
ae6d4fbc78 Move out _concat_conditionings_for_batch submethods 2024-07-17 03:31:26 +03:00
cd1bc1595a Rename sequential as private variable 2024-07-17 03:24:11 +03:00
0583101c1c Add Spandrel upscale starter models (#6605)
## Summary

This PR adds some spandrel upscale models to the starter model list.

In the future we may also want to add:
- Some DAT models
(https://drive.google.com/drive/folders/1iBdf_-LVZuz_PAbFtuxSKd_11RL1YKxM)

## QA Instructions

I installed the starter models via the model manager UI, and tested that
I could use them in a workflow.

## Merge Plan

- [ ] Merge the preceding Spandrel PRs first, then change the target
branch to `main`.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [x] _Tests added / updated (if applicable)_
- [x] _Documentation added / updated (if applicable)_
2024-07-16 16:04:52 -04:00
f866b49255 Add some ESRGAN and SwinIR upscale models to the starter models list. 2024-07-16 15:55:10 -04:00
b7c6c63005 Added some comments 2024-07-16 22:52:44 +03:00
95e9f5323b Add tiling to SpandrelImageToImageInvocation (#6594)
## Summary

Add tiling to the `SpandrelImageToImageInvocation` node so that it can
process large images.

Tiling enables this node to run on effectively any input image
dimension. Of course, the computation time increases quadratically with
the image dimension.

Some profiling results on an RTX4090:
- Input 1024x1024, 4x upscale, 4x UltraSharp ESRGAN: `13 secs`, `<4 GB
VRAM`
- Input 4096x4096, 4x upscale, 4x UltraSharop ESRGAN: `46 secs`, `<4 GB
VRAM`
- Input 4096x4096, 2x upscale, SwinIR: `165 secs`, `<5 GB VRAM`

A lot of the time is spent PNG encoding the final image:
- PNG encoding of a 16384x16384 image takes `83secs @
pil_compress_level=7`, `24secs @ pil_compress_level=1`

Callout: If we want to start building workflows that pass large images
between nodes, we are going to have to find a way to avoid the PNG
encode/decode roundtrip that we are currently doing. As is, we will be
incurring a huge penalty for every node that receives/produces a large
image.

## QA Instructions

- [x] Tested with tiling up to 4096x4096 -> 16384x16384.
- [x] Test on images with an alpha channel (the alpha channel is
dropped).
- [x] Test on images with odd dimension.
- [x] Test no tiling (`tile_size=0`)

## Merge Plan

- [x] Merge #6556 first, and change the target branch to `main`.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [x] _Documentation added / updated (if applicable)_
2024-07-16 15:51:15 -04:00
6b0ca88177 Merge branch 'main' into ryan/spandrel-upscale-tiling 2024-07-16 15:40:14 -04:00
7ad32dcad2 Add support for Spandrel Image-to-Image models (e.g. ESRGAN, Real-ESRGAN, Swin-IR, DAT, etc.) (#6556)
## Summary

- Add support for all
[spandrel](https://github.com/chaiNNer-org/spandrel) image-to-image
models - this is a collection of many popular super-resolution models
(e.g. ESRGAN, Real-ESRGAN, SwinIR, DAT, etc.)

Examples of supported models:

- DAT:
https://drive.google.com/drive/folders/1iBdf_-LVZuz_PAbFtuxSKd_11RL1YKxM
- SwinIR: https://github.com/JingyunLiang/SwinIR/releases
- Any ESRGAN / Real-ESRGAN model

## Related Issues

Closes #6394 

## QA Instructions

- [x] Test that unsupported models still fail the probe (i.e. no false
positive spandrel models)
- [x] Test adding a few non-spandrel model types
- [x] Test adding a handful of spandrel model types: ESRGAN,
Real-ESRGAN, SwinIR, DAT
- [x] Verify model size estimation for the model cache
- [x] Test using the spandrel models in a practical image upscaling
workflow

## Merge Plan

- [x] Get approval from @brandonrising and @maryhipp before merging -
this PR has commercial implications.
- [x] Merge #6571 and change the target branch to `main`

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [x] _Tests added / updated (if applicable)_
- [x] _Documentation added / updated (if applicable)_
2024-07-16 15:37:20 -04:00
81991e072b Merge branch 'main' into ryan/spandrel-upscale 2024-07-16 15:14:08 -04:00
cec345cb5c Change attention processor apply logic 2024-07-16 20:03:29 +03:00
608cbe3f5c Separate inputs in denoise context 2024-07-16 19:30:29 +03:00
7905a46ca4 chore: bump version to 4.2.6post1 2024-07-16 09:09:04 +10:00
38343917f8 fix(backend): revert non-blocking device transfer
In #6490 we enabled non-blocking torch device transfers throughout the model manager's memory management code. When using this torch feature, torch attempts to wait until the tensor transfer has completed before allowing any access to the tensor. Theoretically, that should make this a safe feature to use.

This provides a small performance improvement but causes race conditions in some situations. Specific platforms/systems are affected, and complicated data dependencies can make this unsafe.

- Intermittent black images on MPS devices - reported on discord and #6545, fixed with special handling in #6549.
- Intermittent OOMs and black images on a P4000 GPU on Windows - reported in #6613, fixed in this commit.

On my system, I haven't experience any issues with generation, but targeted testing of non-blocking ops did expose a race condition when moving tensors from CUDA to CPU.

One workaround is to use torch streams with manual sync points. Our application logic is complicated enough that this would be a lot of work and feels ripe for edge cases and missed spots.

Much safer is to fully revert non-locking - which is what this change does.
2024-07-16 08:59:42 +10:00
9f088d1bf5 Multiple small fixes 2024-07-16 00:51:25 +03:00
fd8d1c12d4 Remove 'del' operator overload 2024-07-16 00:43:32 +03:00
d623bd429b Fix condtionings logic 2024-07-16 00:31:56 +03:00
5a0c99816c chore: bump version to v4.2.6 2024-07-15 14:16:31 +10:00
24bf1ea65a fix(ui): boards cut off when search open 2024-07-15 14:07:20 +10:00
28e79c4c5e chore: ruff
Looks like an upstream change to ruff resulted in this file being a violation.
2024-07-15 14:05:04 +10:00
d7d59d704b chore: update default workflows
- Update all existing defaults
- Add Tiled MultiDiffusion workflow
2024-07-15 14:05:04 +10:00
8539c601e6 translationBot(ui): update translation (Italian)
Currently translated at 98.4% (1262 of 1282 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-07-15 11:54:45 +10:00
5cbe9fafb2 fix(ui): clear selection when deleting last image in board 2024-07-15 08:57:13 +10:00
3ecd14f394 chore: bump version to 4.2.6rc1 2024-07-13 14:55:21 +10:00
7c0dfd74a5 fix(api): deleting large images fails
This issue is caused by a race condition. When a large image is served to the client, it is done using a streaming `FileResponse`. This concurrently serves the image straight from disk. The file is kept open by FastAPI until the image is fully served.

When a user deletes an image before the file is done serving, the delete fails because the file is still held by FastAPI.

To reproduce the issue:
- Create a very large image (8k reliably creates the issue).
- Create a smaller image, so that the first image in the gallery is not the large image.
- Refresh the app. The small image should be selected.
- Select the large image and immediately delete it. You have to be fast, to delete it before it finishes loading.
- In the terminal, we expect to see an error saying `Failed to delete image file`, and the image does not disappear from the UI.
- After a short wait, once the image has fully loaded, try deleting it again. We expect this to work.

The workaround is to instead serve the image from memory.

Loading the image to memory is very fast, so there is only a tiny window in which we could create the race condition, but it technically could still occur, because FastAPI is asynchronous and handles requests concurrently.

Once we load the image into memory, deletions of that image will work. Then we return a normal `Response` object with the image bytes. This is essentially what `FileResponse` does - except it uses `anyio.open_file`, which is async.

The tradeoff is that the server thread is blocked while opening the file. I think this is a fair tradeoff.

A future enhancement could be to implement soft deletion of images (db is already set up for this), and then clean up deleted image files on startup/shutdown. We could move back to using the async `FileResponse` for best responsiveness in the server without any risk of race conditions.
2024-07-13 14:46:41 +10:00
2c1a91241e fix(app): windows indefinite hang while finding port
For some reason, I started getting this indefinite hang when the app checks if port 9090 is available. After some fiddling around, I found that adding a timeout resolves the issue.

I confirmed that the util still works by starting the app on 9090, then starting a second instance. The second instance correctly saw 9090 in use and moved to 9091.
2024-07-13 14:46:41 +10:00
84f136e737 translationBot(ui): update translation (Italian)
Currently translated at 98.4% (1262 of 1282 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-07-13 08:38:22 +10:00
499e4d4fde Add preview extension to check logic 2024-07-13 00:45:04 +03:00
e961dd1dec Remove remains of priority logic 2024-07-13 00:44:21 +03:00
7e00526999 Remove overrides logic for now 2024-07-13 00:28:56 +03:00
3a9dda9177 Renames 2024-07-12 22:44:00 +03:00
bd8ae5d896 Simplify guidance modes 2024-07-12 22:01:37 +03:00
87e96e1be2 Rename modifiers to callbacks, convert order to int, a bit unify injection points 2024-07-12 22:01:05 +03:00
0bc60378d3 A bit rework conditioning convert to unet kwargs 2024-07-12 20:43:32 +03:00
9cc852cf7f Base code from draft PR 2024-07-12 20:31:26 +03:00
712cf00a82 fix(app): vae tile size field description 2024-07-12 06:30:27 -07:00
fb1130c644 fix(ui): do not invalidate image dto cache when deleting image 2024-07-12 14:25:38 +10:00
0f65a12cf3 fix(ui): handle archived boards like other boards when they are visible, do not reset board selection when autoadd board is hidden 2024-07-12 14:25:38 +10:00
84abdc5780 fix(ui): prevent cutoff of last board 2024-07-12 14:25:38 +10:00
2320701929 Do not crash if there are invalid model configs in the DB (#6593)
## Summary

This PR changes the handling of invalid model configs in the DB to log a
warning rather than crashing the app.

This change is being made in preparation for some upcoming new model
additions. Previously, if a user rolled back from an app version that
added a new model type, the app would not launch until the DB was fixed.
This PR changes this behaviour to allow rollbacks of this type (with
warnings).

**Keep in mind that this change is only helpful to users _rolling back
to a version that has this fix_. I.e. it offers no help in the first
version that includes it.**

## QA Instructions

1. Run the Spandrel model branch, which adds a new model type
https://github.com/invoke-ai/InvokeAI/pull/6556.
2. Add a spandrel model via the model manager.
3. Rollback to main. The app will crash on launch due to the invalid
spandrel model config.
4. Checkout this branch. The app should now run with warnings about the
invalid model config.


## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [x] _Documentation added / updated (if applicable)_
2024-07-11 21:15:51 -04:00
69af099532 Warn on invalid model configs in the DB rather than crashing. 2024-07-11 21:05:55 -04:00
0428ce73a9 Add early cancellation to SpandrelImageToImageInvocation. 2024-07-11 15:42:33 -04:00
5795617f86 translationBot(ui): update translation (German)
Currently translated at 67.0% (859 of 1282 strings)

Co-authored-by: Alexander Eichhorn <pfannkuchensack@einfach-doof.de>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/de/
Translation: InvokeAI/Web UI
2024-07-11 19:23:28 +10:00
b533bc072e translationBot(ui): update translation (French)
Currently translated at 25.2% (322 of 1275 strings)

Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/fr/
Translation: InvokeAI/Web UI
2024-07-11 19:23:28 +10:00
d7199c7ca6 translationBot(ui): update translation (Russian)
Currently translated at 100.0% (1282 of 1282 strings)

translationBot(ui): update translation (Russian)

Currently translated at 100.0% (1280 of 1280 strings)

translationBot(ui): update translation (Russian)

Currently translated at 100.0% (1275 of 1275 strings)

translationBot(ui): update translation (Russian)

Currently translated at 100.0% (1273 of 1273 strings)

Co-authored-by: Васянатор <ilabulanov339@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/
Translation: InvokeAI/Web UI
2024-07-11 19:23:28 +10:00
a69284367b translationBot(ui): update translation (Italian)
Currently translated at 98.2% (1260 of 1282 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.4% (1260 of 1280 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.4% (1255 of 1275 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.4% (1253 of 1273 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.4% (1245 of 1265 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-07-11 19:23:28 +10:00
c4d2fe9c65 translationBot(ui): update translation (Chinese (Simplified))
Currently translated at 76.5% (968 of 1265 strings)

Co-authored-by: Phrixus2023 <920414016@qq.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/zh_Hans/
Translation: InvokeAI/Web UI
2024-07-11 19:23:28 +10:00
fe0d56de5c translationBot(ui): update translation files
Updated by "Remove blank strings" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/
Translation: InvokeAI/Web UI
2024-07-11 19:23:28 +10:00
HAL
7aec5624f7 translationBot(ui): update translation (Japanese)
Currently translated at 50.4% (636 of 1261 strings)

Co-authored-by: HAL <HALQME@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ja/
Translation: InvokeAI/Web UI
2024-07-11 19:23:28 +10:00
B N
2f3ec41f94 translationBot(ui): update translation (German)
Currently translated at 67.3% (849 of 1261 strings)

Co-authored-by: B N <berndnieschalk@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/de/
Translation: InvokeAI/Web UI
2024-07-11 19:23:28 +10:00
de1235c980 chore: bump version to 4.2.6a1 2024-07-11 10:34:53 +10:00
d0d2955992 Reduce peak VRAM utilization of SpandrelImageToImageInvocation. 2024-07-10 14:25:19 -04:00
d868d5d584 Make SpandrelImageToImage tiling much faster. 2024-07-10 14:25:19 -04:00
ab775726b7 Add tiling support to the SpoandrelImageToImage node. 2024-07-10 14:25:19 -04:00
650902dc29 Fix broken unit test caused by non-existent model path. 2024-07-10 13:59:17 -04:00
88c3a71586 fix(ui): fix bug with usePanel 2024-07-10 04:27:24 -07:00
ec1b429d45 feat(ui): add divider between board search and list 2024-07-10 04:27:24 -07:00
146e3a3377 feat(ui): tweak board tooltip behaviour 2024-07-10 04:27:24 -07:00
38622b0d91 feat(ui): board list title verbiage 2024-07-10 04:27:24 -07:00
7db767b7c3 feat(ui): sticky board list header 2024-07-10 04:27:24 -07:00
b70e87f25b feat(ui): tweak add board button style 2024-07-10 04:27:24 -07:00
fea1ec9085 feat(ui): updated boards resizable panel logic 2024-07-10 04:27:24 -07:00
2e7a95998c feat(ui): add support for default size in usePanel 2024-07-10 04:27:24 -07:00
788f90a7d5 feat(ui): tweak resizehandle styling 2024-07-10 04:27:24 -07:00
6bf29b20af fix(ui): fix edge case in panels
Not sure why I didn't figure out how to do this before - we only should reset a panel if it's too small.
2024-07-10 04:27:24 -07:00
8f0edcd4f4 fix(ui): edge cases when deleting, archiving, updating boards
Need to handle different cases where the selected or auto-add board is hidden - fall back to uncategorized in these situations.
2024-07-10 04:27:24 -07:00
a7c44b4a98 feat(ui): rename gallery boards on double click 2024-07-10 04:27:24 -07:00
48a57f0da8 feat(ui): boards styling
- Refine layout
- Update colors - more minimal, fewer shaded boxes
- Add indicator for search icons showing a search term is entered
- Handle new `projectName` and `projectUrl` ui props
2024-07-10 04:27:24 -07:00
dfd94bbd0b feat(ui): remove galleryHeader in favor of projectUrl & projectName 2024-07-10 04:27:24 -07:00
2edfb2356d remove extra boardname 2024-07-10 04:27:24 -07:00
58d2c1557d prettier 2024-07-10 04:27:24 -07:00
8fdff33cf8 update board header styling, toggle board search, resizing gallery panels 2024-07-10 04:27:24 -07:00
a96e34d2d1 remove collapsibles and update board title 2024-07-10 04:27:24 -07:00
8826adad24 filter out uncategorized when not included in search 2024-07-10 04:27:24 -07:00
cdacf2ecd0 clear out boards search when adding a new board 2024-07-10 04:27:24 -07:00
f193a576a6 move boardname back and make collapsible again 2024-07-10 04:27:24 -07:00
b7ebdca70a update image and assets tabs styling 2024-07-10 04:27:24 -07:00
7b5d4935b4 Merge branch 'main' into ryan/spandrel-upscale 2024-07-09 13:47:11 -04:00
c90b5541e8 Boards UI update and add support for private boards (#6588)
## Summary
Update Boards UI in the gallery and adds support for creating and
displaying private boards
<!--A description of the changes in this PR. Include the kind of change
(fix, feature, docs, etc), the "why" and the "how". Screenshots or
videos are useful for frontend changes.-->

## Related Issues / Discussions

<!--WHEN APPLICABLE: List any related issues or discussions on github or
discord. If this PR closes an issue, please use the "Closes #1234"
format, so that the issue will be automatically closed when the PR
merges.-->

## QA Instructions
Can view private boards by setting config.allowPrivateBoards to true
<!--WHEN APPLICABLE: Describe how you have tested the changes in this
PR. Provide enough detail that a reviewer can reproduce your tests.-->

## Merge Plan

<!--WHEN APPLICABLE: Large PRs, or PRs that touch sensitive things like
DB schemas, may need some care when merging. For example, a careful
rebase by the change author, timing to not interfere with a pending
release, or a message to contributors on discord after merging.-->

## Checklist

- [ ] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-07-09 10:52:01 -04:00
a79e9caab1 Merge branch 'main' into boards-ui-update 2024-07-09 10:00:26 -04:00
4313578d8e fix(docker): ensure 'chown' does not break on read-only fs; fixes #6264 2024-07-09 09:47:29 -04:00
42c2dea202 fix(docker): change 'nvidia' profile name to 'cuda' 2024-07-09 09:47:29 -04:00
b672cc37a7 docs: overhaul Docker documentation, add to main README 2024-07-09 09:47:29 -04:00
476ebd13ae feat(ui): add board button tooltip when private boards enabled 2024-07-09 22:51:08 +10:00
9ae808712e Demote error log to warning for models treated as having size 0 (#6589)
## Summary

Demote error log to warning for models treated as having size 0.

## Related Issues / Discussions

Closes #6587 

I looked into handling ESRGAN model sizes properly. They load a
state_dict with a bit of an unusual nested-dict structure. Rather than
figure out how to accurately calculate their size, we can just wait for
https://github.com/invoke-ai/InvokeAI/pull/6556. ESRGAN model size
handling should work properly when loaded through that pathway.

## QA Instructions

Loaded an ESRGAN model, and confirmed that the warning log is at the
warning level.

## Merge Plan

No special instructions.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [x] _Tests added / updated (if applicable)_
- [x] _Documentation added / updated (if applicable)_
2024-07-09 08:51:00 -04:00
2460689c00 feat(ui): style board name 2024-07-09 22:47:03 +10:00
781b800ef7 feat(ui): boards lists start collapsed 2024-07-09 22:40:50 +10:00
d38d513d23 fix(ui): autoadd badge doesn't flex shrink 2024-07-09 22:39:32 +10:00
80e1b87b9e fix(ui): autoadd badge hides when editing name 2024-07-09 22:39:17 +10:00
6014382c7b feat(ui): select a board when it is created 2024-07-09 22:37:41 +10:00
af63c538ed Demote error log to warning to models treated as having size 0. 2024-07-09 08:35:43 -04:00
060d698a12 feat(ui): restore image count for boards 2024-07-09 22:19:20 +10:00
637802d803 fix(ui): restore auto-add indicator 2024-07-09 22:14:21 +10:00
2faf1e2ed3 fix(ui): show uncategorized board when private boards disabled 2024-07-09 22:02:54 +10:00
81cf47dd99 feat(ui): boards list layout & style tweaking 2024-07-09 21:58:48 +10:00
907b257984 remove unused file and addressed pr feedback 2024-07-08 23:20:50 -04:00
e2667f957c prettier 2024-07-08 22:16:31 -04:00
40c3b5e727 generate types again 2024-07-08 22:13:12 -04:00
38c5804457 remove unused disclosure 2024-07-08 22:09:23 -04:00
faf65c988a Merge branch 'main' into boards-ui-update 2024-07-08 22:06:26 -04:00
1785825690 add current gallery board name 2024-07-08 22:03:42 -04:00
0e092c0fb5 update is_private name 2024-07-08 22:03:12 -04:00
79a7b11214 remove old boards list 2024-07-08 15:02:22 -04:00
3a85ab15a1 update BoardRecord 2024-07-08 14:55:04 -04:00
9ca6980c7a cleanup and bug fixes 2024-07-08 13:29:53 -04:00
bdf4fcda23 Fixed 404 error on latest release link (line 16):
This commit corrects a broken link on line 16 that was pointing to the latest release but causing a 404 error (page not found) when clicked. The issue was identified as a trailing dot at the end of the URL, which has now been removed. This ensures users can access the intended latest release page.
2024-07-07 08:35:06 -07:00
ecbff2aa44 Whoops... forgot to commit this file. 2024-07-05 14:57:05 -04:00
0ce6ec634d Do not assign the result of SpandrelImageToImageModel.load_from_file(...) during probe to ensure that the model is immediately gc'd. 2024-07-05 14:05:12 -04:00
d09999736c Rename spandrel models to 'Image-to-Image Model' throughout the UI. 2024-07-05 14:04:08 -04:00
35f8781ea2 Fix static type errors with SCHEDULER_NAME_VALUES. And, avoid bi-directional cross-directory imports, which contribute to circular import issues. 2024-07-05 07:38:35 -07:00
3a24d70279 Update the PR template QA instructions (#6580)
## Summary

This PR tweaks the wording of the PR template QA instructions with the
goals of:
1. Make it more clear that PR authors are responsible for testing their
PRs.
2. Encouraging sufficient detail in the test descriptions.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [x] _Tests added / updated (if applicable)_
- [x] _Documentation added / updated (if applicable)_
2024-07-04 21:20:08 +05:30
7c8846e309 Update the PR template QA instructions to 1) make it clear that authors are responsible for testing their PRs, and 2) encourage sufficient detail in the QA section. 2024-07-04 11:30:38 -04:00
bd42b75d1e Delete unused duplicate libc_util.py file (#6579)
## Summary
 
Delete an unused duplicate libc_util.py file. The active version is at
`invokeai/backend/model_manager/libc_util.py`

## QA Instructions

I ran a smoke test to confirm that memory snapshotting still works.

## Merge Plan

- [x] Change target branch to `main` before merging.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [x] _Tests added / updated (if applicable)_
- [x] _Documentation added / updated (if applicable)_
2024-07-04 20:15:39 +05:30
36202d6d25 Delete unused duplicate libc_util.py file. The active version is at invokeai/backend/model_manager/libc_util.py. 2024-07-04 10:30:40 -04:00
b35f5b3877 Enforce absolute imports with ruff (#6576)
## Summary

This PR migrates all relative imports to absolute imports, and adds a
ruff check to enforce this going forward.

The justification for this change is here:
https://github.com/invoke-ai/InvokeAI/issues/6575

## QA Instructions

Smoke test all common workflows. Most of the relative -> absolute
conversions could be completed automatically, so the risk is relatively
low.

## Merge Plan

As with any far-reaching change like this, it is likely to cause some
merge conflicts with some in-flight branches. Unfortunately, there's no
way around this, but let me know if you can think of in-flight work that
will be significantly disrupted by this.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [x] _Tests added / updated (if applicable)_ N/A
- [x] _Documentation added / updated (if applicable)_ N/A
2024-07-04 10:29:01 -04:00
1d449097cc Apply ruff rule to disallow all relative imports. 2024-07-04 09:35:37 -04:00
9da5925287 Add ruff rule to disallow relative parent imports. 2024-07-04 09:35:37 -04:00
7bbd793064 Fix some models treated as having size 0 in the model cache (#6571)
## Summary

This PR fixes a regression that caused the following models to be
treated as having size 0 in the model cache: `(TextualInversionModelRaw,
IPAdapter, LoRAModelRaw)`.

Changes:
- Call the correct model size calculation for all supported model types.
- Log an error message if an unexpected model type is loaded, to prevent
similar regressions in the future.

## QA Instructions

I tested the following features and verified that no models fell back to
using a size of 0 unexpectedly:
- Test-to-image
- Textual Inversion
- LoRA
- IP-Adapter
- ControlNet
(All tested with both SD1.5 and SDXL.)

I compared the model cache switching behavior before and after this
change with a large number of LoRAs (10). Since LoRAs are small compared
to the main models, the changes in behaviour are minimal. Nonetheless,
it makes sense to get this in for correctness. And it might make a
difference for some usage patterns with limited RAM.

## Merge Plan

No special instructions.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [x] _Tests added / updated (if applicable)_
- [x] _Documentation added / updated (if applicable)_
2024-07-04 09:21:30 -04:00
414750a45d Update calc_model_size_by_data(...) to handle all expected model types, and to log an error if an unexpected model type is received. 2024-07-04 09:08:25 -04:00
0fe92cd406 [MM bugfix] Put model install errors on the event bus (#6578)
* fix access token lookup

* fix bug preventing model install error events from being reported

---------

Co-authored-by: Lincoln Stein <lstein@gmail.com>
2024-07-03 22:44:34 -04:00
a405f14ea2 Fix SpandrelImageToImageModel size calculation for the model cache. 2024-07-03 16:38:16 -04:00
9d3739244f Prettier formatting. 2024-07-03 16:28:21 -04:00
534528b85a Re-generate schema.ts 2024-07-03 16:28:21 -04:00
114320ee69 (minor) typo 2024-07-03 16:28:21 -04:00
6161aa73af Move pil_to_tensor() and tensor_to_pil() utilities to the SpandrelImageToImage class. 2024-07-03 16:28:21 -04:00
1ab20f43c8 Tidy spandrel model probe logic, and document the reasons behind the current implementation. 2024-07-03 16:28:21 -04:00
9328c17ded Add Spandrel models to the list of models in the Model Manager tab. 2024-07-03 16:28:21 -04:00
c1c8e55e8e Fix static check errors. 2024-07-03 16:28:21 -04:00
504a42fe61 typo: fix UIType on Spandrel Upscaling node. 2024-07-03 16:28:21 -04:00
29c8ddfb88 WIP - A bunch of boilerplate to support Spandrel Image-to-Image models throughout the model manager and the frontend. 2024-07-03 16:28:21 -04:00
95079dc7d4 Use a ModelIdentifierField to identify the spandrel model in the UpscaleSpandrelInvocation. 2024-07-03 16:28:21 -04:00
2a1514272f Set the dtype correctly for SpandrelImageToImageModels when they are loaded. 2024-07-03 16:28:21 -04:00
59ce9cf41c WIP - Begin to integrate SpandreImageToImageModel type into the model manager. 2024-07-03 16:28:21 -04:00
e6abea7bc5 (minor) Remove redundant else clause on a for-loop with no break statement. 2024-07-03 16:28:21 -04:00
c335f92345 (minor) simplify startswith(...) syntax. 2024-07-03 16:28:21 -04:00
c1afe35704 Add prototype invocation for running upscaling models with spandrel. 2024-07-03 16:28:21 -04:00
6437ef3f82 add view that displays private boards with shared boards 2024-07-03 14:25:36 -04:00
bb6ff4cf37 chore(ci): update pnpm github action 2024-07-03 13:16:25 -04:00
e719018ba1 fix sort order 2024-07-03 09:20:08 -07:00
a11dc62c2e fix access token lookup 2024-07-03 13:31:08 +10:00
7c01b69c12 fix(ui): revise image selection after deletion
- For single image deletion, select the image in the same slot as the deleted image
- For multiple image deletion, empty selection
- On list images, if no images are currently selected, select the first image
2024-07-03 13:20:40 +10:00
5578660ccb fix(ui): reset page when search term changes 2024-07-03 13:20:40 +10:00
e4813f800a Update calc_model_size_by_data(...) to handle all expected model types, and to log an error if an unexpected model type is received. 2024-07-02 21:51:45 -04:00
e9936c27fb Make the VAE tile size configurable for tiled VAE (#6555)
## Summary

- This PR exposes a `tile_size` field on `ImageToLatentsInvocation` and
`LatentsToImageInvocation`.
  - Setting `tile_size = 0` preserves the default behaviour.
- This feature is primarily intended to support upscaling workflows that
require VAE encoding/decoding high resolution images. In the future, we
may want to expose the tile size as a global application config, but
that's a separate conversation.
- As a general rule, larger tile sizes produce better results at the
cost of higher memory usage.

### Example:

Original (5472x5472)

![orig](https://github.com/invoke-ai/InvokeAI/assets/14897797/af0a975d-11ed-4f3c-9e53-84f3da6c997e)

VAE roundtrip with 512x512 tiles (note the discoloration)

![vae_roundtrip_512x512](https://github.com/invoke-ai/InvokeAI/assets/14897797/d589ae3e-fe93-410a-904c-f61f0fc0f1f2)

VAE roundtrip with 1024x1024 tiles (some discoloration still present,
but less severe than at 512x512)

![vae_roundtrip_1024x1024](https://github.com/invoke-ai/InvokeAI/assets/14897797/d0bb9752-3bfa-444f-88c9-39a3ca89c748)


## Related Issues / Discussions

Related: #6144 

## QA Instructions

- [x] Test image generation via the Linear tab
- [x] Test VAE roundtrip with tiling disabled
- [x] Test VAE roundtrip with tiling and tile_size = 0
- [x] Test VAE roundtrip with tiling and tile_size > 0

## Merge Plan

No special instructions.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [x] _Tests added / updated (if applicable)_
- [x] _Documentation added / updated (if applicable)_
2024-07-02 09:16:07 -04:00
3752509066 Expose the VAE tile_size on the VAE encode and decode invocations. 2024-07-02 09:07:03 -04:00
a1b7dbfa54 Add unit test for patch_vae_tiling_params(). 2024-07-02 09:07:03 -04:00
79640ba14e Add context manager for overriding VAE tiling params. 2024-07-02 09:07:03 -04:00
4075a81676 feat(ui): gallery image selection ux
The selection logic is a bit complicated. We have image selection and pagination, both of which can be triggered using the mouse or hotkeys. We have viewer image selection and comparison image selection, which is determined by the alt key.

This change ties the room together with these behaviours:

- Changing the page using pagination buttons never changes the selection.
- Changing the selected image using arrows may change the page, if the arrow key pressed would select an image off the current page.
  - `right` on the last image of the current page goes to the next page
  - `down` on the last row of images goes to the next page
  - `left` on the first image of the current page goes to the previous page
  - `up` on the first row of images goes to the previous page
- If `alt` is held when using arrow keys, we change the page, but we only change the comparison image selection.
- When using arrow keys, if the page has changed since the last image was selected, the selection is reset to the first image on the page.
- The next/previous buttons on the image viewer do the same thing as `left` and `right` without `alt`.
- When clicking an image in the gallery:
  - If no modifier keys are held, the image is exclusively selected.
  - If `ctrl` or `meta` are held, the image's selection status is toggled.
  - If `shift` is held, all images from the last-selected image to the image are selected. If there are no images on the current page, the selection is unchanged.
  - If `alt` is held, the image is set as the compare image.
- `ctrl+a` and `meta+a` add the current page to the selection.

The logic for gallery navigation and selection is now pretty hairy. It's spread across 3 hooks, a listener, redux slice, components.

When we next make changes to this part of the app, we should consider consolidating some of the related logic. Probably most of it can go into a single listener and make it much simpler to grok.
2024-07-02 13:52:32 +10:00
4d39976909 feat(ui): restore loading spinner in search box
@maryhipp you were right, after trying loading bars and different placements, this feels like the best place for it.
2024-07-02 13:52:32 +10:00
d14894b3ae (ui) clarify auto-add options 2024-07-02 06:44:09 +10:00
6f5c5b0757 lint fix 2024-07-01 15:36:06 -04:00
93caa23ef8 undo 2024-07-01 15:36:06 -04:00
977a77f4e6 fix(ui): dont mess up redux if 403 gets thrown 2024-07-01 15:36:06 -04:00
57c0fcb93d (ui) clarify auto-add options 2024-07-01 15:36:06 -04:00
8b55900035 Update README.md
Updated to include more context confirming the community edition is in fact free for commercial use.
2024-07-01 09:12:31 -07:00
b1cc413bbd tidy(ui): remove search term fetching indicator
Don't like this UI (even though I suggested it). No need to prevent the user from interacting with the search term field during fetching. Let's figure out a nicer way to present this in a followup.
2024-07-01 20:06:28 +10:00
face94ce33 feat(ui): tweak search term placeholder verbiage 2024-07-01 20:06:28 +10:00
f0b1f0e5b6 feat(ui): pass search term as-is to query
The images service does not add the query filter if the search term is an empty string.
2024-07-01 20:06:28 +10:00
390dc47db5 feat(app): transform search term to lowercase 2024-07-01 20:06:28 +10:00
20d5c3a8bf (ui): improve loader/fetching state while searching, make search term a string in redux 2024-07-01 20:06:28 +10:00
134d831ebf (api) simplify query 2024-07-01 20:06:28 +10:00
b65ed8e8f2 fix commented out migration 2024-07-01 20:06:28 +10:00
93951dcf82 (api) ruff 2024-07-01 20:06:28 +10:00
da05034e20 feat(ui): debounced gallery search 2024-07-01 20:06:28 +10:00
d579aefb3e feat(api): add optional search_term query param to image list to search metadata 2024-07-01 20:06:28 +10:00
5d1f6db414 fix(app): fix SQL query w/ enum for python 3.11 (#6557)
## Summary

Python 3.11 has a wonderfully devious breaking change where _sometimes_
using enum classes that inherit from `str` or `int` do not work the same
way as they do in 3.10 when used within string formatting/interpolation.

This breaks the new gallery sort queries. The fix is to use
`order_dir.value` instead of `order_dir` in the query.

This was not an issue during development because the feature was
developed w/ python 3.10.

## Related Issues / Discussions

Thanks to @JPPhoto for reporting and troubleshooting:
https://discord.com/channels/1020123559063990373/1149513625321603162/1256211815982039173

## QA Instructions

JP's fancy python 3.11 system should work on this PR.

## Merge Plan

n/a

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-06-29 18:50:16 +05:30
f9961eceb7 fix(app): fix SQL query w/ enum for python 3.11 2024-06-29 11:07:39 +10:00
10076fb1e8 feat(ui): tweak gallery settings popover divider styling 2024-06-28 18:01:01 +10:00
d6e85e5f67 tidy(ui): rename GalleryBulkSelect -> GallerySelectionCountTag 2024-06-28 18:01:01 +10:00
1ce459198c chore(ui): knip 2024-06-28 18:01:01 +10:00
17d337169d fix(ui): do not reset limit when changing gallery view 2024-06-28 18:01:01 +10:00
1468f4d37e perf(ui): split out gallery settings popover components
This was taking over 15ms (!) to render each time a setting changed, wtf
2024-06-28 18:01:01 +10:00
2b744480d6 feat(ui): update UI for sorting 2024-06-28 18:01:01 +10:00
abb8d34b56 chore(ui): typegen 2024-06-28 18:01:01 +10:00
9e664d7c58 feat(api): remove order_by in favor of starred_first for images records 2024-06-28 18:01:01 +10:00
c96ccae70b feat(app): remove order_by in favor of starred_first for images records 2024-06-28 18:01:01 +10:00
f268fe126e feat(api): add order_by and order_dir to list images for sorting 2024-06-28 18:01:01 +10:00
6109a06f04 feat(ui): gallery sort by created at or starred, asc or desc 2024-06-28 18:01:01 +10:00
5df2a79549 Update starter models 2024-06-28 17:49:45 +10:00
10b9088312 update controlnet starter models 2024-06-28 17:49:45 +10:00
41f46b846b chore: ruff 2024-06-28 10:36:05 +10:00
6dfc406c52 tests: update test_bulk_download.py after addition of archived field 2024-06-28 10:36:05 +10:00
0d4b80780b feat(ui): handle edge cases when archiving/deleting boards
If the currently selected or auto-add board is archived or deleted, we should reset them. There are some edge cases taht weren't handled in the previous implementation.

All handling of this logic is moved to the (renamed) listener.
2024-06-28 10:36:05 +10:00
15b9ece411 chore(ui): typegen 2024-06-28 10:36:05 +10:00
89fcab34d0 feat(app): BoardRecord.archived is a required field 2024-06-28 10:36:05 +10:00
132289de55 chore: ruff E721
Looks like in the latest version of ruff, E721 was added or changed and now catches something it didn't before.
2024-06-28 10:36:05 +10:00
9f93e9d120 fix(app): when creating image, skip adding to board if board doesn't exist
Before this change, if you attempt to create an image that with a nonexistent board, we'd get an unhandled error when adding the image to a board. The record would be created, but file not, due to the structure of the code.

With this change, we now log a warning if we have a problem adding the image to the board, but the record and file are still created.

A future improvement would be to create a transaction for this part of the code, preventing some other situation that could result in only the record or only the file beings saved.
2024-06-28 10:36:05 +10:00
b5f23292d4 lint fix 2024-06-28 10:36:05 +10:00
a63dbb2c2d (api) change query param to include_archived 2024-06-28 10:36:05 +10:00
740bf80f3e (ui): update query param to include_archived, fix cache when archiving boards 2024-06-28 10:36:05 +10:00
dc90de600d (ui) allow auto-add on archived boards, reset to uncategorized if auto-add board is not currently visible due to archived view 2024-06-28 10:36:05 +10:00
5709f82e5f feat(ui): separate context menu for no board board
Much easier to not need to handle the board being optional in the component.
2024-06-28 10:36:05 +10:00
20042d99ec tidy(ui): archived icon component 2024-06-28 10:36:05 +10:00
8fce168dc5 fix tsc errors 2024-06-28 10:36:05 +10:00
a7ea096b28 ruff format 2024-06-28 10:36:05 +10:00
29eb3c8b62 lint fix 2024-06-28 10:36:05 +10:00
071e8bcee4 feat(ui): make archiving and auto-add mutually exclusive 2024-06-28 10:36:05 +10:00
68c0aa898f feat(ui): add ability to archive/unarchive boards, add toggle to gallery settings to show/hide archived boards in list 2024-06-28 10:36:05 +10:00
5120a76ce5 cleanup 2024-06-28 10:36:05 +10:00
38a948ac9f feat(api): add archived query param to board list endpoint to include them in the response 2024-06-28 10:36:05 +10:00
c33111468e feat(api): ability to archive boards 2024-06-28 10:36:05 +10:00
3e0fb45dd7 Load single-file checkpoints directly without conversion (#6510)
* use model_class.load_singlefile() instead of converting; works, but performance is poor

* adjust the convert api - not right just yet

* working, needs sql migrator update

* rename migration_11 before conflict merge with main

* Update invokeai/backend/model_manager/load/model_loaders/stable_diffusion.py

Co-authored-by: Ryan Dick <ryanjdick3@gmail.com>

* Update invokeai/backend/model_manager/load/model_loaders/stable_diffusion.py

Co-authored-by: Ryan Dick <ryanjdick3@gmail.com>

* implement lightweight version-by-version config migration

* simplified config schema migration code

* associate sdxl config with sdxl VAEs

* remove use of original_config_file in load_single_file()

---------

Co-authored-by: Lincoln Stein <lstein@gmail.com>
Co-authored-by: Ryan Dick <ryanjdick3@gmail.com>
2024-06-27 17:31:28 -04:00
aba16085a5 fix(backend): mps should not use non_blocking (#6549)
## Summary

We can get black outputs when moving tensors from CPU to MPS. It appears
MPS to CPU is fine. See:
- https://github.com/pytorch/pytorch/issues/107455
-
https://discuss.pytorch.org/t/should-we-set-non-blocking-to-true/38234/28

Changes:
- Add properties for each device on `TorchDevice` as a convenience.
- Add `get_non_blocking` static method on `TorchDevice`. This utility
takes a torch device and returns the flag to be used for non_blocking
when moving a tensor to the device provided.
- Update model patching and caching APIs to use this new utility.

## Related Issues / Discussions

Fixes: #6545

## QA Instructions

For both MPS and CUDA:
- Generate at least 5 images using LoRAs
- Generate at least 5 images using IP Adapters

## Merge Plan

We have pagination merged into `main` but aren't ready for that to be
released.

Once this fix is tested and merged, we will probably want to create a
`v4.2.5post1` branch off the `v4.2.5` tag, cherry-pick the fix and do a
release from the hotfix branch.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_ @RyanJDick @lstein This
feels testable but I'm not sure how.
- [ ] _Documentation added / updated (if applicable)_
2024-06-27 10:11:53 -04:00
14775cc9c4 ruff format 2024-06-27 09:45:13 -04:00
c7562dd6c0 fix(backend): mps should not use non_blocking
We can get black outputs when moving tensors from CPU to MPS. It appears MPS to CPU is fine. See:
- https://github.com/pytorch/pytorch/issues/107455
- https://discuss.pytorch.org/t/should-we-set-non-blocking-to-true/38234/28

Changes:
- Add properties for each device on `TorchDevice` as a convenience.
- Add `get_non_blocking` static method on `TorchDevice`. This utility takes a torch device and returns the flag to be used for non_blocking when moving a tensor to the device provided.
- Update model patching and caching APIs to use this new utility.

Fixes: #6545
2024-06-27 19:15:23 +10:00
a0a0c57789 chore(ui): knip 2024-06-27 13:48:40 +10:00
32ebf82d1a feat(ui): better pagination buttons 2024-06-27 13:48:40 +10:00
2dd172c2c6 feat(ui): gallery bulk select styling 2024-06-27 13:48:40 +10:00
280ec9d4b3 fix(ui): invalidate getImageDTO caches when images are mutated 2024-06-27 13:48:40 +10:00
fde8fc7575 perf(ui): optimistic updates for getImageDTO query cache 2024-06-27 13:48:40 +10:00
6dcdc87eb1 fix(ui): control adapter image preview 2024-06-27 13:48:40 +10:00
93ffcb642e lint fix 2024-06-27 13:48:40 +10:00
4c914ef2e8 use correct query params for boardIdSelected listener 2024-06-27 13:48:40 +10:00
c0ad5bc4a4 fix when deleting first image in list 2024-06-27 13:48:40 +10:00
8c58a180de GG another fix 2024-06-27 13:48:40 +10:00
715dd983b0 appease the knip 2024-06-27 13:48:40 +10:00
84ffd36071 lint fix 2024-06-27 13:48:40 +10:00
9f30f1bfec fix circular dep 2024-06-27 13:48:40 +10:00
bdff5c4e87 only show selected when greater than 0 2024-06-27 13:48:40 +10:00
afb0651f91 clear selection when board or gallery view changes 2024-06-27 13:48:40 +10:00
66e25628c3 fix neg pages 2024-06-27 13:48:40 +10:00
3a531a3c88 remove rest of cache, add bulk select UI 2024-06-27 13:48:40 +10:00
f01df49128 lint fix 2024-06-27 13:48:40 +10:00
7bbe236107 implmenet custom sort to replace images adapter logic 2024-06-27 13:48:40 +10:00
719c066ac4 feat(ui): more efficient board totals fetching
We only need to show the totals in the tooltip. Tooltips accpet a component for the tooltip label. The component isn't rendered until the tooltip is triggered.

Move the board total fetching into a tooltip component for the boards. Now we only fire these requests when the user mouses over the board
2024-06-27 13:48:40 +10:00
689dc30f87 feat(ui): tweak pagination buttons
- Fix off-by-one error when going to last page
- Update component to have minimal/no layout shift
2024-06-27 13:48:40 +10:00
1f22f6ae02 feat(ui): iterate on dynamic gallery limit
- Simplify the gallery layout
- Set an initial gallery limit to load _some_ images immediately.
- Refactor the resize observer to use the actual rendered image component to calculate the number of images per row/col. This prevents inaccuracies caused by image padding that could result in the wrong number of images.
- Debounce the limit update to not thrash teh API
- Use absolute positioning trick to ensure the gallery container is always exactly the right size
- Minimum of `imagesPerRow` images loaded at all times
2024-06-27 13:48:40 +10:00
9c931d9ca0 fix(ui): gallery content overflow
This is one of those unexpected CSS quirks. Flex containers need min-width or min-height for their children to not overflow. Add `minH={0}` to gallery container.
2024-06-27 13:48:40 +10:00
e0a241fa4f wip change limit based on size of gallery 2024-06-27 13:48:40 +10:00
6a4b4ee340 trying to invalidate all the tags 2024-06-27 13:48:40 +10:00
488bf21925 fix single pagers 2024-06-27 13:48:40 +10:00
c9c39c02b6 handle generations coming in, fix pagination to use total from list query so it updates as that changes 2024-06-27 13:48:40 +10:00
5101dc4bef some cleanup, add page buttons 2024-06-27 13:48:40 +10:00
98c77a3ed1 pull in spencers work 2024-06-27 13:48:40 +10:00
4fca62680d Update invokeai_version.py 2024-06-27 10:41:01 +10:00
f76282a5ff Fix handling handling of 0-step denoising process (#6544)
## Summary

https://github.com/invoke-ai/InvokeAI/pull/6522 introduced a change in
behavior in cases where start/end were set such that there are 0
timesteps. This PR reverts that change.

cc @StAlKeR7779 

## QA Instructions

Run with euler, 5 steps, start: 0.0, end: 0.05. I ran this test before
#6522, after #6522, and on this branch. This branch restores the
behavior to pre-#6522 i.e. noise is injected even if no denoising steps
are applied.


## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [x] _Tests added / updated (if applicable)_
- [x] _Documentation added / updated (if applicable)_
2024-06-26 13:01:58 -04:00
9a3b8c6fcb Fix handling of init_timestep in StableDiffusionGeneratorPipeline and improve its documentation. 2024-06-26 12:51:51 -04:00
bd74b84cc5 Revert "Remove the redundant init_timestep parameter that was being passed around. It is simply the first element of the timesteps array."
This reverts commit fa40061eca.
2024-06-26 12:51:51 -04:00
dc23bebebf Run ruff 2024-06-26 21:46:59 +10:00
38b6f90c02 Update prevention exception message 2024-06-26 21:46:59 +10:00
cd9dfefe3c Fix inpainting mask shape assertions. 2024-06-25 11:31:52 -07:00
b9946e50f9 Use image-space tile dimensions on the TiledMultiDiffusionDenoiseLatents invocation. This is more natural for many users. 2024-06-25 11:31:52 -07:00
06f49a30f6 Mark TiledMultiDiffusionDenoiseLatents as a Beta node. 2024-06-25 11:31:52 -07:00
e1af78c702 Make the tile_overlap input to MultiDiffusion *strictly* control the amount of overlap rather than being a lower bound. 2024-06-25 11:31:52 -07:00
c5588e1ff7 Add TODO comment explaining why some schedulers do not interact well with MultiDiffusion. 2024-06-25 11:31:52 -07:00
07ac292680 Consolidate _region_step() function - the separation wasn't really adding any value. 2024-06-25 11:31:52 -07:00
7c032ea604 (minor) Fix some documentation typos. 2024-06-25 11:31:52 -07:00
c5ee415607 Add progress image callbacks to TiledMultiDiffusionDenoiseLatentsInvocation. 2024-06-25 11:31:52 -07:00
fa40061eca Remove the redundant init_timestep parameter that was being passed around. It is simply the first element of the timesteps array. 2024-06-25 11:31:52 -07:00
7cafd78d6e Revert "Expose vae_decode(...) as a staticmethod on LatentsToImageInvocation."
This reverts commit 753239b48d.
2024-06-25 11:31:52 -07:00
8a43656cf9 (minor) Address a few small TODOs. 2024-06-25 11:31:52 -07:00
bd3b6ca11b Remove TiledStableDiffusionRefineInvocation. It was a proof-of-concept that has been superseded by TiledMultiDiffusionDenoiseLatents. 2024-06-25 11:31:52 -07:00
ceae5fe1db (minor) typo 2024-06-25 11:31:52 -07:00
25067e4f0d Delete rough notes. 2024-06-25 11:31:52 -07:00
fb0aaa3e6d Fix advanced scheduler behaviour in MultiDiffusionPipeline. 2024-06-25 11:31:52 -07:00
c22526b9d0 Fix handling of stateful schedulers in MultiDiffusionPipeline. 2024-06-25 11:31:52 -07:00
c881882f73 Connect TiledMultiDiffusionDenoiseLatents to the MultiDiffusionPipeline backend. 2024-06-25 11:31:52 -07:00
36473fc52a Remove regional conditioning logic from MultiDiffusionPipeline - it is not yet supported. 2024-06-25 11:31:52 -07:00
b9964ecc4a Initial (untested) implementation of MultiDiffusionPipeline. 2024-06-25 11:31:52 -07:00
051af802fe Remove inpainting support from MultiDiffusionPipeline. 2024-06-25 11:31:52 -07:00
3ff2e558d9 Remove IP-Adapter and T2I-Adapter support from MultiDiffusionPipeline. 2024-06-25 11:31:52 -07:00
fc187c9253 Document plan for the rest of the MultiDiffusion implementation. 2024-06-25 11:31:52 -07:00
605f460c7d Add detailed docstring to latents_from_embeddings(). 2024-06-25 11:31:52 -07:00
60d1e686d8 Copy StableDiffusionGeneratorPipeline as a starting point for a new MultiDiffusionPipeline. 2024-06-25 11:31:52 -07:00
22704dd542 Simplify handling of inpainting models. Improve the in-code documentation around inpainting. 2024-06-25 11:31:52 -07:00
875673c9ba Minor tidying of latents_from_embeddings(...). 2024-06-25 11:31:52 -07:00
f604575862 Consolidate latents_from_embeddings(...) and generate_latents_from_embeddings(...) into a single function. 2024-06-25 11:31:52 -07:00
80a67572f1 Fix invocation name of tiled_multi_diffusion_denoise_latents. 2024-06-25 11:31:52 -07:00
60ac937698 Improve clarity of comments regarded when 'noise' and 'latents' are expected to be set. 2024-06-25 11:31:52 -07:00
1e41949a02 Fix static check errors on imports in diffusers_pipeline.py. 2024-06-25 11:31:52 -07:00
5f0e330ed2 Remove a condition for handling inpainting models that never resolves to True. The same logic is already applied earlier by AddsMaskLatents. 2024-06-25 11:31:52 -07:00
9dd779b414 Add clarifying comment to explain why noise might be None in latents_from_embedding(). 2024-06-25 11:31:52 -07:00
fa183025ac Remove unused are_like_tensors() function. 2024-06-25 11:31:52 -07:00
d3c85aa91a Remove unused StableDiffusionGeneratorPipeline.use_ip_adapter member. 2024-06-25 11:31:52 -07:00
82619602a5 Remove unused StableDiffusionGeneratorPipeline.control_model. 2024-06-25 11:31:52 -07:00
196f3b721d Stricter typing for the is_gradient_mask: bool. 2024-06-25 11:31:52 -07:00
244c28859d Fix typing of control_data to reflect that it can be None. 2024-06-25 11:31:52 -07:00
40ae174c41 Fix typing of timesteps and init_timestep. 2024-06-25 11:31:52 -07:00
afaebdf151 Fix typing to reflect that the callback arg to latents_from_embeddings is never None. 2024-06-25 11:31:52 -07:00
d661517d94 Move seed above optional params. 2024-06-25 11:31:52 -07:00
82a69a54ac Simplify handling of AddsMaskGuidance, and fix some related type errors. 2024-06-25 11:31:52 -07:00
ffc28176fe Remove unused num_inference_steps. 2024-06-25 11:31:52 -07:00
230e205541 WIP TiledMultiDiffusionDenoiseLatents. Updated parameter list and first half of the logic. 2024-06-25 11:31:52 -07:00
7e94350351 Tidy DenoiseLatentsInvocation.prep_control_data(...) and fix some type errors. 2024-06-25 11:31:52 -07:00
c4e8549c73 Make DenoiseLatentsInvocation.prep_control_data(...) a staticmethod so that it can be called externally. 2024-06-25 11:31:52 -07:00
350a210835 Copy TiledStableDiffusionRefineInvocation as a starting point for TiledMultiDiffusionDenoiseLatents.py 2024-06-25 11:31:52 -07:00
ed781dbb0c Change tiling strategy to make TiledStableDiffusionRefineInvocation work with more tile shapes and overlaps. 2024-06-25 11:31:52 -07:00
b41ea963e7 Expose a few more params from TiledStableDiffusionRefineInvocation. 2024-06-25 11:31:52 -07:00
da5d105049 Add support for LoRA models in TiledStableDiffusionRefineInvocation. 2024-06-25 11:31:52 -07:00
5301770525 Add naive ControlNet support to TiledStableDiffusionRefineInvocation 2024-06-25 11:31:52 -07:00
d08e405017 Fix ControlNetModel type hint import source. 2024-06-25 11:31:52 -07:00
534640ccde Rough prototype of TiledStableDiffusionRefineInvocation is working. 2024-06-25 11:31:52 -07:00
d5ab8cab5c WIP - TiledStableDiffusionRefine 2024-06-25 11:31:52 -07:00
4767301ad3 Minor improvements to LatentsToImageInvocation type hints. 2024-06-25 11:31:52 -07:00
21d7ca45e6 Expose vae_decode(...) as a staticmethod on LatentsToImageInvocation. 2024-06-25 11:31:52 -07:00
020e8eb413 Fix return type of prepare_noise_and_latents(...). 2024-06-25 11:31:52 -07:00
3d49541c09 Make init_scheduler() a staticmethod on DenoiseLatentsInvocation so that it can be called externally. 2024-06-25 11:31:52 -07:00
1ef266845a Only allow a single positive/negative prompt conditioning input for tiled refine. 2024-06-25 11:31:52 -07:00
a37589ca5f WIP on TiledStableDiffusionRefine 2024-06-25 11:31:52 -07:00
171a505f5e Convert several methods in DenoiseLatentsInvocation to staticmethods so that they can be called externally. 2024-06-25 11:31:52 -07:00
8004a0d5f5 Simplify the logic in prepare_noise_and_latents(...). 2024-06-25 11:31:52 -07:00
610a1fd611 Split out the prepare_noise_and_latents(...) logic in DenoiseLatentsInvocation so that it can be called from other invocations. 2024-06-25 11:31:52 -07:00
43108eec13 (minor) Add a TODO note to get_scheduler(...). 2024-06-25 11:31:52 -07:00
b03073d888 [MM] Add support for probing and loading SDXL VAE checkpoint files (#6524)
* add support for probing and loading SDXL VAE checkpoint files

* broaden regexp probe for SDXL VAEs

---------

Co-authored-by: Lincoln Stein <lstein@gmail.com>
2024-06-20 02:57:27 +00:00
a43d602f16 fix(queue): add clear_queue_on_startup config to clear problematic queues 2024-06-19 11:39:25 +10:00
7e9a89f8c6 Tidy SilenceWarnings context manager (#6493)
## Summary

No functional changes, just cleaning some things up as I touch the code.
This PR cleans up the `SilenceWarnings` context manager:
- Fix type errors
- Enable SilenceWarnings to be used as both a context manager and a
decorator
- Remove duplicate implementation
- Check the initial verbosity on `__enter__()` rather than `__init__()`
- Save an indentation level in DenoiseLatents

## QA Instructions

I generated an image to confirm that warnings are still muted.

## Merge Plan

- [x] ⚠️ Merge https://github.com/invoke-ai/InvokeAI/pull/6492 first,
then change the target branch to `main`.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [x] _Tests added / updated (if applicable)_
- [x] _Documentation added / updated (if applicable)_
2024-06-18 15:23:32 -04:00
79ceac2f82 (minor) Use SilenceWarnings as a decorator rather than a context manager to save an indentation level. 2024-06-18 15:06:22 -04:00
8e47e005a7 Tidy SilenceWarnings context manager:
- Fix type errors
- Enable SilenceWarnings to be used as both a context manager and a decorator
- Remove duplicate implementation
- Check the initial verbosity on __enter__() rather than __init__()
2024-06-18 15:06:22 -04:00
d13aafb514 Tidy denoise_latents.py imports to all use absolute import paths. 2024-06-18 15:06:22 -04:00
63a7e19dbf Run ruff 2024-06-18 10:38:29 -04:00
fbc5a8ec65 Ignore validation on improperly formatted hashes (pytest) 2024-06-18 10:38:29 -04:00
8ce6e4540e Run ruff 2024-06-18 10:38:29 -04:00
f14f377ede Update validator list 2024-06-18 10:38:29 -04:00
1925f83f5e Update validator list 2024-06-18 10:38:29 -04:00
3a5ad6d112 Update validator list 2024-06-18 10:38:29 -04:00
41a6bb45f3 Initial functionality 2024-06-18 10:38:29 -04:00
70e40fa6c1 added route to install huggingface models from model marketplace (#6515)
## Summary
added route to install huggingface models from model marketplace
<!--A description of the changes in this PR. Include the kind of change
(fix, feature, docs, etc), the "why" and the "how". Screenshots or
videos are useful for frontend changes.-->

## Related Issues / Discussions

<!--WHEN APPLICABLE: List any related issues or discussions on github or
discord. If this PR closes an issue, please use the "Closes #1234"
format, so that the issue will be automatically closed when the PR
merges.-->

## QA Instructions
test by going to
http://localhost:5173/api/v2/models/install/huggingface?source=${hfRepo}
<!--WHEN APPLICABLE: Describe how we can test the changes in this PR.-->

## Merge Plan

<!--WHEN APPLICABLE: Large PRs, or PRs that touch sensitive things like
DB schemas, may need some care when merging. For example, a careful
rebase by the change author, timing to not interfere with a pending
release, or a message to contributors on discord after merging.-->

## Checklist

- [ ] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-06-16 21:13:58 -04:00
e26125b734 tests: fix test_model_install.py 2024-06-17 10:57:11 +10:00
cd70937b7f feat(api): improved model install confirmation page styling & messaging 2024-06-17 10:51:08 +10:00
f002bca2fa feat(ui): handle new model_install_download_started event
When a model install is initiated from outside the client, we now trigger the model manager tab's model install list to update.

- Handle new `model_install_download_started` event
- Handle `model_install_download_complete` event (this event is not new but was never handled)
- Update optimistic updates/cache invalidation logic to efficiently update the model install list
2024-06-17 10:07:10 +10:00
56771de856 feat(ui): add redux actions for model_install_download_started event 2024-06-17 09:52:46 +10:00
c11478a94a chore(ui): typegen 2024-06-17 09:51:18 +10:00
fb694b3e17 feat(app): add model_install_download_started event
Previously, we used `model_install_download_progress` for both download starting and progressing. When handling this event, we don't know which actual thing it represents.

Add `model_install_download_started` event to explicitly represent a model download started event.
2024-06-17 09:50:25 +10:00
1bc98abc76 docs(ui): explain model install events 2024-06-17 09:33:46 +10:00
7f03b04b2f Merge branch 'main' into chainchompa/model-install-deeplink 2024-06-14 17:16:25 -04:00
4029972530 formatting 2024-06-14 17:15:55 -04:00
328f160e88 refetch model installs when a new model install starts 2024-06-14 17:09:07 -04:00
aae318425d added route for installing huggingface model from model marketplace 2024-06-14 17:08:39 -04:00
785bb1d9e4 Fix all comparisons against the DEFAULT_PRECISION constant. DEFAULT_PRECISION is a torch.dtype. Previously, it was compared to a str in a number of places where it would always resolve to False. This is a bugfix that results in a change to the default behavior. In practice, this will not change the behavior for many users, because it only causes a change in behavior if a users has configured float32 as their default precision. 2024-06-14 11:26:10 -07:00
a3cb5da130 Improve RAM<->VRAM memory copy performance in LoRA patching and elsewhere (#6490)
* allow model patcher to optimize away the unpatching step when feasible

* remove lazy_offloading functionality

* allow model patcher to optimize away the unpatching step when feasible

* remove lazy_offloading functionality

* do not save original weights if there is a CPU copy of state dict

* Update invokeai/backend/model_manager/load/load_base.py

Co-authored-by: Ryan Dick <ryanjdick3@gmail.com>

* documentation fixes requested during penultimate review

* add non-blocking=True parameters to several torch.nn.Module.to() calls, for slight performance increases

* fix ruff errors

* prevent crash on non-cuda-enabled systems

---------

Co-authored-by: Lincoln Stein <lstein@gmail.com>
Co-authored-by: Kent Keirsey <31807370+hipsterusername@users.noreply.github.com>
Co-authored-by: Ryan Dick <ryanjdick3@gmail.com>
2024-06-13 17:10:03 +00:00
568a4844f7 fix: other recursive imports 2024-06-10 04:12:20 -07:00
b1e56e2485 fix: SchedulerOutput not being imported correctly 2024-06-10 04:12:20 -07:00
9432336e2b Add simplified model manager install API to InvocationContext (#6132)
## Summary

This three two model manager-related methods to the InvocationContext
uniform API. They are accessible via `context.models.*`:

1. **`load_local_model(model_path: Path, loader:
Optional[Callable[[Path], AnyModel]] = None) ->
LoadedModelWithoutConfig`**

*Load the model located at the indicated path.*

This will load a local model (.safetensors, .ckpt or diffusers
directory) into the model manager RAM cache and return its
`LoadedModelWithoutConfig`. If the optional loader argument is provided,
the loader will be invoked to load the model into memory. Otherwise the
method will call `safetensors.torch.load_file()` `torch.load()` (with a
pickle scan), or `from_pretrained()` as appropriate to the path type.

Be aware that the `LoadedModelWithoutConfig` object differs from
`LoadedModel` by having no `config` attribute.

Here is an example of usage:

```
def invoke(self, context: InvocatinContext) -> ImageOutput:
       model_path = Path('/opt/models/RealESRGAN_x4plus.pth')
       loadnet = context.models.load_local_model(model_path)
       with loadnet as loadnet_model:
             upscaler = RealESRGAN(loadnet=loadnet_model,...)
```

---

2. **`load_remote_model(source: str | AnyHttpUrl, loader:
Optional[Callable[[Path], AnyModel]] = None) ->
LoadedModelWithoutConfig`**

*Load the model located at the indicated URL or repo_id.*

This is similar to `load_local_model()` but it accepts either a
HugginFace repo_id (as a string), or a URL. The model's file(s) will be
downloaded to `models/.download_cache` and then loaded, returning a

```
def invoke(self, context: InvocatinContext) -> ImageOutput:
       model_url = 'https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth'
       loadnet = context.models.load_remote_model(model_url)
       with loadnet as loadnet_model:
             upscaler = RealESRGAN(loadnet=loadnet_model,...)
```
---

3. **`download_and_cache_model( source: str | AnyHttpUrl, access_token:
Optional[str] = None, timeout: Optional[int] = 0) -> Path`**

Download the model file located at source to the models cache and return
its Path. This will check `models/.download_cache` for the desired model
file and download it from the indicated source if not already present.
The local Path to the downloaded file is then returned.

---

## Other Changes

This PR performs a migration, in which it renames `models/.cache` to
`models/.convert_cache`, and migrates previously-downloaded ESRGAN,
openpose, DepthAnything and Lama inpaint models from the `models/core`
directory into `models/.download_cache`.

There are a number of legacy model files in `models/core`, such as
GFPGAN, which are no longer used. This PR deletes them and tidies up the
`models/core` directory.

## Related Issues / Discussions

I have systematically replaced all the calls to
`download_with_progress_bar()`. This function is no longer used
elsewhere and has been removed.

<!--WHEN APPLICABLE: List any related issues or discussions on github or
discord. If this PR closes an issue, please use the "Closes #1234"
format, so that the issue will be automatically closed when the PR
merges.-->

## QA Instructions

I have added unit tests for the three new calls. You may test that the
`load_and_cache_model()` call is working by running the upscaler within
the web app. On first try, you will see the model file being downloaded
into the models `.cache` directory. On subsequent tries, the model will
either load from RAM (if it hasn't been displaced) or will be loaded
from the filesystem.

<!--WHEN APPLICABLE: Describe how we can test the changes in this PR.-->

## Merge Plan

Squash merge when approved.

<!--WHEN APPLICABLE: Large PRs, or PRs that touch sensitive things like
DB schemas, may need some care when merging. For example, a careful
rebase by the change author, timing to not interfere with a pending
release, or a message to contributors on discord after merging.-->

## Checklist

- [X] _The PR has a short but descriptive title, suitable for a
changelog_
- [X] _Tests added / updated (if applicable)_
- [X] _Documentation added / updated (if applicable)_
2024-06-08 16:24:31 -07:00
7d19af2caa Merge branch 'main' into lstein/feat/simple-mm2-api 2024-06-08 18:55:06 -04:00
0dbec3ad8b Split up latent.py (code reorganization, no functional changes) (#6491)
## Summary

I've started working towards a better tiled upscaling implementation. It
is going to require some refactoring of `DenoiseLatentsInvocation`. As a
first step, this PR splits up all of the invocations in latent.py into
their own files. That file had become a bit of a dumping ground - it
should be a bit more manageable to work with now.

This PR just re-organizes the code. There should be no functional
changes.

## QA Instructions

I've done some light smoke testing. I'll do some more before merging.
The main risk is that I missed a broken import, or some other copy-paste
error.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [x] _Tests added / updated (if applicable)_: N/A
- [x] _Documentation added / updated (if applicable)_: N/A
2024-06-07 12:01:56 -04:00
52c0c4a32f Rename latent.py -> denoise_latents.py. 2024-06-07 09:28:42 -04:00
8f1afc032a Move SchedulerInvocation to a new file. No functional changes. 2024-06-07 09:28:42 -04:00
854bca668a Move CreateDenoiseMaskInvocation to its own file. No functional changes. 2024-06-07 09:28:42 -04:00
fea9013cad Move CreateGradientMaskInvocation to its own file. No functional changes. 2024-06-07 09:28:42 -04:00
045caddee1 Move LatentsToImageInvocation to its own file. No functional changes. 2024-06-07 09:28:42 -04:00
58697141bf Move ImageToLatentsInvocation to its own file. No functional changes. 2024-06-07 09:28:42 -04:00
5e419dbb56 Move ScaleLatentsInvocation and ResizeLatentsInvocation to their own file. No functional changes. 2024-06-07 09:28:42 -04:00
595096bdcf Move BlendLatentsInvocation to its own file. No functional changes. 2024-06-07 09:28:42 -04:00
ed03d281e6 Move CropLatentsCoreInvocation to its own file. No functional changes. 2024-06-07 09:28:42 -04:00
0b37496c57 Move IdealSizeInvocation to its own file. No functional changes. 2024-06-07 09:28:42 -04:00
fde58ce0a3 Merge remote-tracking branch 'origin/main' into lstein/feat/simple-mm2-api 2024-06-07 14:23:41 +10:00
dc134935c8 replace load_and_cache_model() with load_remote_model() and load_local_odel() 2024-06-07 14:12:16 +10:00
9f9379682e ruff fixes 2024-06-07 13:54:41 +10:00
f81b8bc9f6 add support for generic loading of diffusers directories 2024-06-07 13:54:30 +10:00
6d067e56f2 fix(ui): on page load, if CA processed image no longer exists, re-process it 2024-06-07 10:32:28 +10:00
2871676f79 LoRA patching optimization (#6439)
* allow model patcher to optimize away the unpatching step when feasible

* remove lazy_offloading functionality

* allow model patcher to optimize away the unpatching step when feasible

* remove lazy_offloading functionality

* do not save original weights if there is a CPU copy of state dict

* Update invokeai/backend/model_manager/load/load_base.py

Co-authored-by: Ryan Dick <ryanjdick3@gmail.com>

* documentation fixes added during penultimate review

---------

Co-authored-by: Lincoln Stein <lstein@gmail.com>
Co-authored-by: Kent Keirsey <31807370+hipsterusername@users.noreply.github.com>
Co-authored-by: Ryan Dick <ryanjdick3@gmail.com>
2024-06-06 13:53:35 +00:00
1c5c3cdbd6 tidy(ui): organize control layers konva logic
- More comments, docstrings
- Move things into saner, less-coupled locations
2024-06-06 07:45:13 +10:00
3db69af220 refactor(ui): generalize stage event handlers
Create intermediary nanostores for values required by the event handlers. This allows the event handlers to be purely imperative, with no reactivity: instead of recreating/setting the handlers when a dependent piece of state changes, we use nanostores' imperative API to access dependent state.

For example, some handlers depend on brush size. If we used the standard declarative `useSelector` API, we'd need to recreate the event handler callback each time the brush size changed. This can be costly.

An intermediate `$brushSize` nanostore is set in a `useLayoutEffect()`, which responds to changes to the redux store. Then, in the event handler, we use the imperative API to access the brush size: `$brushSize.get()`.

This change allows the event handler logic to be shared with the pending canvas v2, and also more easily tested. It's a noticeable perf improvement, too, especially when changing brush size.
2024-06-06 07:45:13 +10:00
1823e446ac fix(ui): conditionally render CL preview
This fixes an issue where it sometimes gets out of sync, and fixes some konva errors.
2024-06-06 07:45:13 +10:00
311e44ad19 tidy(ui): clean up control layers renderers, docstrings 2024-06-06 07:45:13 +10:00
848ca79da8 Changed translated labels to static suffixes, cleanup. 2024-06-05 14:45:43 +10:00
9cba0dfac9 Providing fileName string directly to DataViewer as suggested 2024-06-05 14:45:43 +10:00
37b1f21bcf ... and the workflow 2024-06-05 14:45:43 +10:00
b2e005f6b5 Just realized we might want the same change made for the Graph JSON 2024-06-05 14:45:43 +10:00
52aac954c0 Prefixed JSON filenames with the image UUID #6469 2024-06-05 14:45:43 +10:00
ff01ceae99 Update invokeai_version.py 2024-06-05 05:53:19 +10:00
669d92d8db translationBot(ui): update translation (Chinese (Traditional))
Currently translated at 14.1% (179 of 1261 strings)

Co-authored-by: hugoalh <hugoalh@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/zh_Hant/
Translation: InvokeAI/Web UI
2024-06-05 00:08:03 +10:00
2903060154 translationBot(ui): update translation (German)
Currently translated at 67.0% (834 of 1243 strings)

Co-authored-by: Ettore Atalan <atalanttore@googlemail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/de/
Translation: InvokeAI/Web UI
2024-06-05 00:08:03 +10:00
4af8699a00 translationBot(ui): update translation (Spanish)
Currently translated at 34.3% (427 of 1243 strings)

Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/es/
Translation: InvokeAI/Web UI
2024-06-05 00:08:03 +10:00
71fedd1a07 translationBot(ui): update translation (Spanish)
Currently translated at 34.3% (427 of 1243 strings)

Co-authored-by: Bruno Castillejo <soybrunocastillejo@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/es/
Translation: InvokeAI/Web UI
2024-06-05 00:08:03 +10:00
6bb1189c88 translationBot(ui): update translation (Italian)
Currently translated at 98.5% (1243 of 1261 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.5% (1243 of 1261 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.5% (1225 of 1243 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.5% (1225 of 1243 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-06-05 00:08:03 +10:00
c7546bc82e translationBot(ui): update translation (Russian)
Currently translated at 100.0% (1261 of 1261 strings)

translationBot(ui): update translation (Russian)

Currently translated at 100.0% (1243 of 1243 strings)

Co-authored-by: Васянатор <ilabulanov339@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/
Translation: InvokeAI/Web UI
2024-06-05 00:08:03 +10:00
14372e3818 fix(nodes): blend latents with weight=0 with DPMSolverSDEScheduler
- Pass the seed from `latents_a` to the output latents. Fixed an issue where using `BlendLatentsInvocation` could result in different outputs during denoising even when the alpha or slerp weight was 0.

## Explanation

`LatentsField` has an optional `seed` field. During denoising, if this `seed` field is not present, we **fall back to 0 for the seed**. The seed is used during denoising in a few ways:

1. Initializing the scheduler.

The seed is used in two places in `invokeai/app/invocations/latent.py`.

The `get_scheduler()` utility function has special handling for `DPMSolverSDEScheduler`, which appears to need a seed for deterministic outputs.

`DenoiseLatentsInvocation.init_scheduler()` has special handling for schedulers that accept a generator - the generator needs to be seeded in a particular way. At the time of this commit, these are the Invoke-supported schedulers that need this seed:
  - DDIMScheduler
  - DDPMScheduler
  - DPMSolverMultistepScheduler
  - EulerAncestralDiscreteScheduler
  - EulerDiscreteScheduler
  - KDPM2AncestralDiscreteScheduler
  - LCMScheduler
  - TCDScheduler

2. Adding noise during inpainting.

If a mask is used for denoising, and we are not using an inpainting model, we add noise to the unmasked area. If, for some reason, we have a mask but no noise, the seed is used to add noise.

I wonder if we should instead assert that if a mask is provided, we also have noise.

This is done in `invokeai/backend/stable_diffusion/diffusers_pipeline.py` in `StableDiffusionGeneratorPipeline.latents_from_embeddings()`.

When we create noise to be used in denoising, we are expected to set `LatentsField.seed` to the seed used to create the noise. This introduces some awkwardness when we manipulate any "latents" that will be used for denoising. We have to pass the seed along for every operation.

If the wrong seed or no seed is passed along, we can get unexpected outputs during denoising. One notable case relates to blending latents (slerping tensors).

If we slerp two noise tensors (`LatentsField`s) _without_ passing along the seed from the source latents, when we denoise with a seed-dependent scheduler*, the schedulers use the fallback seed of 0 and we get the wrong output. This is most obvious when slerping with a weight of 0, in which case we expect the exact same output after denoising.

*It looks like only the DPMSolver* schedulers are affected, but I haven't tested all of them.

Passing the seed along in the output fixes this issue.
2024-06-05 00:02:52 +10:00
64523c4b1b fix(ui): handle concat when recalling prompts
This required some minor reworking of of the logic to recall multiple items. I split this into a utility function that includes some special handling for concat.

Closes #6478
2024-06-04 06:01:01 +10:00
89a764a359 fix(ui): improve model metadata parsing fallback
When the model in metadata's key no longer exists, fall back to fetching by name, base and type. This was the intention all along but the logic was never put in place.
2024-06-04 06:01:01 +10:00
756108f6bd Update invokeai/app/invocations/latent.py
Co-authored-by: Ryan Dick <ryanjdick3@gmail.com>
2024-06-03 11:41:47 -07:00
68d628dc14 use zip to iterate over image prompts and adapters 2024-06-03 11:41:47 -07:00
93c9852142 fix ruff 2024-06-03 11:41:47 -07:00
493f81788c added a few comments to document design choices 2024-06-03 11:41:47 -07:00
f13427e3f4 refactor redundant code and fix typechecking errors 2024-06-03 11:41:47 -07:00
e28737fc8b add check for congruence between # of ip_adapters and image_prompts 2024-06-03 11:41:47 -07:00
7391c126d3 handle case of no IP adapters requested 2024-06-03 11:41:47 -07:00
1c59fce6ad reduce peak VRAM memory usage of IP adapter 2024-06-03 11:41:47 -07:00
a9962fd104 chore: ruff 2024-06-03 11:53:20 +10:00
e7513f6088 docs(mm): add comment in move_model_to_device 2024-06-03 10:56:04 +10:00
c7f22b6a3b tidy(mm): remove extraneous docstring
It's inherited from the ABC.
2024-06-03 10:46:28 +10:00
99413256ce tidy(mm): pass enum member instead of string 2024-06-03 10:43:09 +10:00
aa9695e377 tidy(download): _download_job -> _multifile_job 2024-06-03 10:15:53 +10:00
c58ac1e80d tidy(mm): minor formatting 2024-06-03 10:11:08 +10:00
6cc6a45274 feat(download): add type for callback_name
Just a bit of typo protection in lieu of full type safety for these methods, which is difficult due to the typing of `DownloadEventHandler`.
2024-06-03 10:05:52 +10:00
521f907f58 tidy(nodes): infill
- Set `self._context=context` instead of passing it as an arg
2024-06-03 09:43:25 +10:00
ccdecf21a3 tidy(nodes): cnet processors
- Set `self._context=context` instead of changing the type signature of `run_processor`
- Tidy a few typing things
2024-06-03 09:41:17 +10:00
b124440023 tidy(mm): move load_model_from_url from mm to invocation context 2024-06-03 08:51:21 +10:00
e3a70e598e docs(app): simplify docstring in invocation_context 2024-06-03 08:40:29 +10:00
132bbf330a tidy(app): remove unnecessary changes in invocation_context
- Any mypy issues are a misconfiguration of mypy
- Use simple conditionals instead of ternaries
- Consistent & standards-compliant docstring formatting
- Use `dict` instead of `typing.Dict`
2024-06-03 08:35:23 +10:00
2276f327e5 Merge branch 'main' into lstein/feat/simple-mm2-api 2024-06-02 09:45:31 -04:00
6b24424727 feat(ui): add help icon to compare toolbar 2024-06-02 15:30:00 +10:00
7153d846a9 feat(ui): add hotkey to cycle compare modes 2024-06-02 15:30:00 +10:00
9a0b77ad38 feat(ui): add hotkey to swap comparison images 2024-06-02 15:30:00 +10:00
220d45967e fix(ui): typo 2024-06-02 15:30:00 +10:00
038a482ef0 feat(ui): rework visibility conditions for image viewer 2024-06-02 15:30:00 +10:00
c325ad3432 feat(ui): add hotkey hint to exit compare button 2024-06-02 15:30:00 +10:00
449bc4dbe5 feat(ui): abstract out and share logic between comparisons 2024-06-02 15:30:00 +10:00
34d68a3663 feat(ui): hover comparison mode 2024-06-02 15:30:00 +10:00
8bb9571485 feat(ui): tweak slider divider styling 2024-06-02 15:30:00 +10:00
08bcc71e99 fix(ui): workflows fit on load 2024-06-02 15:30:00 +10:00
ff2b2fad83 feat(ui): revise drop zones
The main viewer area has two drop zones:
- Select for Viewer
- Select for Compare

These do what you'd imagine they would do.
2024-06-02 15:30:00 +10:00
0f0a6852f1 fix(ui): make compare image scale with first image when using contain fit 2024-06-02 15:30:00 +10:00
745140fa6b feat(ui): "first image"/"second image" -> "viewer image"/"compare image" 2024-06-02 15:30:00 +10:00
405fc46888 feat(ui): z/esc first exit compare before closing viewer 2024-06-02 15:30:00 +10:00
ca728ca29f fix(ui): ignore context menu in slider view
It doesn't make sense to allow context menu here, because the context menu will technically be on a div and not an image - there won't be any image options there.
2024-06-02 15:30:00 +10:00
d0fca53e67 fix(ui): only clear comparison image on alt click of gallery image
This logic can't e in the reducer else it applies to dnd events which isn't right
2024-06-02 15:30:00 +10:00
ad9740d72d feat(ui): alt-click comparison image exits compare 2024-06-02 15:30:00 +10:00
1c9c982b63 feat(ui): use appropriate cursor on slider 2024-06-02 15:30:00 +10:00
3cfd2755c2 fix(ui): when changing viewer state, always clear compare image 2024-06-02 15:30:00 +10:00
8ea4067f83 feat(ui): rework compare toolbar 2024-06-02 15:30:00 +10:00
940de6a5c5 fix(ui): allow drop of currently-selected image for compare 2024-06-02 15:30:00 +10:00
dd74e89127 fix(ui): close context menu on click select for compare 2024-06-02 15:30:00 +10:00
69da67e920 fix(ui): dnd on board
Copy-paste error broke this
2024-06-02 15:30:00 +10:00
76b1f241d7 fix(ui): useGalleryNavigation callback typing issue 2024-06-02 15:30:00 +10:00
0e5336d8fa feat(ui): rework comparison activation, add hotkeys 2024-06-02 15:30:00 +10:00
3501636018 feat(ui): add fill mode for slider comparison 2024-06-02 15:30:00 +10:00
e4ce188500 feat(ui): image selection gallery state & tweaks 2024-06-02 15:30:00 +10:00
e976571fba build(ui): remove unused dep 2024-06-02 15:30:00 +10:00
0da36c1238 feat(ui): use IAIDndImage for compare mode 2024-06-02 15:30:00 +10:00
4ef8cbd9d0 fix(ui): use isValidDrop in imageDropped listener
It was possible for a drop event to be invalid but still processed. Fixed by slightly changing the signature of isValidDrop.
2024-06-02 15:30:00 +10:00
8f8ddd620b feat(ui): add comparison modes, side-by-side view 2024-06-02 15:30:00 +10:00
1af53aed60 feat(ui): fix image comparison slider resizing/aspect ratio jank 2024-06-02 15:30:00 +10:00
7a4bbd092e feat(ui): revised image comparison slider
Should work for any components and image now.
2024-06-02 15:30:00 +10:00
72bbcb2d94 feat(ui): slider working for all aspect ratios 2024-06-02 15:30:00 +10:00
c2eef93476 feat(ui): wip slider implementations 2024-06-02 15:30:00 +10:00
cfb12615e1 fix: openapi stuff (#6454)
## Summary

Fix some issues with openapi schema generation. See commits for details.

## Related Issues / Discussions


https://discord.com/channels/1020123559063990373/1049495067846524939/1245141831394529352

## QA Instructions

App should work, workflows should work.

## Merge Plan

n/a

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [x] _Documentation added / updated (if applicable)_
2024-05-30 08:22:34 +05:30
a983f27aad fix(ui): update types 2024-05-30 12:03:38 +10:00
7cb32d3d83 chore(ui): typegen 2024-05-30 12:03:38 +10:00
ac56ab79a7 fix(app): add dynamic validator to AnyInvocation & AnyInvocationOutput
This fixes the tests and slightly changes output types.
2024-05-30 12:03:38 +10:00
50d3030471 feat(app): dynamic type adapters for invocations & outputs
Keep track of whether or not the typeadapter needs to be updated. Allows for dynamic invocation and output unions.
2024-05-30 12:03:38 +10:00
5beec8211a feat(api): sort openapi schemas
Reduces the constant changes to the frontend client types due to inconsistent ordering of pydantic models.
2024-05-30 12:03:38 +10:00
5a4d10467b feat(ui): use updated types 2024-05-30 12:03:38 +10:00
7590f3005e chore(ui): typegen 2024-05-30 12:03:03 +10:00
2f9ebdec69 fix(app): openapi schema generation
Some tech debt related to dynamic pydantic schemas for invocations became problematic. Including the invocations and results in the event schemas was breaking pydantic's handling of ref schemas. I don't really understand why - I think it's a pydantic bug in a remote edge case that we are hitting.

After many failed attempts I landed on this implementation, which is actually much tidier than what was in there before.

- Create pydantic-enabled types for `AnyInvocation` and `AnyInvocationOutput` and use these in place of the janky dynamic unions. Actually, they are kinda the same, but better encapsulated. Use these in `Graph`, `GraphExecutionState`, `InvocationEventBase` and `InvocationCompleteEvent`.
- Revise the custom openapi function to work with the new models.
- Split out the custom openapi function to a separate file. Add a `post_transform` callback so consumers can customize the output schema.
- Update makefile scripts.
2024-05-30 12:03:03 +10:00
e257a72f94 chore: bump pydantic, fastapi to latest 2024-05-30 12:03:03 +10:00
843f82c837 fix(ui): remove overly strict constraints on control adapter weight 2024-05-29 19:01:28 -07:00
66858effa2 docs: add FAQ for fixing controlnet_aux 2024-05-29 18:19:06 -07:00
21a60af881 when unlocking models, offload_unlocked_models should prune to vram limit only (#6450)
Co-authored-by: Lincoln Stein <lstein@gmail.com>
2024-05-29 03:01:21 +00:00
ead1748c54 issue a download progress event when install download starts 2024-05-28 19:30:42 -04:00
df91d1b849 Update TI handling for compatibility with transformers 4.40.0 (#6449)
## Summary

- Updated the documentation for `TextualInversionManager`
- Updated the `self.tokenizer.model_max_length` access to work with the
latest transformers version. Thanks to @skunkworxdark for looking into
this here:
https://github.com/invoke-ai/InvokeAI/issues/6445#issuecomment-2133098342

## Related Issues / Discussions

Closes #6445 

## QA Instructions

I tested with `transformers==4.41.1`, and compared the results against a
recent InvokeAI version before updating tranformers - no change, as
expected.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [x] _Documentation added / updated (if applicable)_
2024-05-28 08:32:02 -04:00
829b9ad66b Add a callout about the hackiness of dropping tokens in the TextualInversionManager. 2024-05-28 05:11:54 -07:00
3aa1c8d3a8 Update TextualInversionManager for compatibility with the latest transformers release. See https://github.com/invoke-ai/InvokeAI/issues/6445. 2024-05-28 05:11:54 -07:00
994c61b67a Add docs to TextualInversionManager and improve types. No changes to functionality. 2024-05-28 05:11:54 -07:00
21aa42627b feat(events): add dynamic invocation & result validators
This is required to get these event fields to deserialize correctly. If omitted, pydantic uses `BaseInvocation`/`BaseInvocationOutput`, which is not correct.

This is similar to the workaround in the `Graph` and `GraphExecutionState` classes where we need to fanagle pydantic with manual validation handling.
2024-05-28 05:11:37 -07:00
a4f88ff834 feat(events): add __event_name__ as ClassVar to EventBase
This improves types for event consumers that need to access the event name.
2024-05-28 05:11:37 -07:00
cd12ca6e85 add migration_11; fix typo 2024-05-27 22:40:01 -04:00
34e1eb19f9 merge with main and resolve conflicts 2024-05-27 22:20:34 -04:00
ddff9b4584 fix(events): typing for download event handler 2024-05-27 11:13:47 +10:00
b50133d5e1 feat(events): register event schemas
This allows for events to be dispatched using dicts as payloads, and have the dicts validated as pydantic schemas.
2024-05-27 11:13:47 +10:00
5388f5a817 fix(ui): edit variant for main models only
Closes #6444
2024-05-27 11:02:00 +10:00
27a3eb15f8 feat(ui): update event types 2024-05-27 10:17:02 +10:00
4b2d57a5e0 chore(ui): typegen
Note about the huge diff: I had a different version of pydantic installed at some point, which slightly altered a _ton_ of schema components. This typegen was done on the correct version of pydantic and un-does those alterations, in addition to the intentional changes to event models.
2024-05-27 10:17:02 +10:00
bbb90ff949 feat(events): restore whole invocation to event payloads
Removing this is a breaking API change - some consumers of the events need the whole invocation. Didn't realize that until now.
2024-05-27 10:17:02 +10:00
9d9801b2c2 feat(events): stronger generic typing for event registration 2024-05-27 10:17:02 +10:00
8498d4344b docs: update docstrings in sockets.py 2024-05-27 09:06:02 +10:00
dfad37a262 docs: update comments & docstrings 2024-05-27 09:06:02 +10:00
89dede7bad feat(ui): simplify client sio redux actions
- Add a simple helper to create socket actions in a less error-prone way
- Organize and tidy sio files
2024-05-27 09:06:02 +10:00
60784a4361 feat(ui): update client for removal of session events 2024-05-27 09:06:02 +10:00
3d8774d295 chore(ui): typegen 2024-05-27 09:06:02 +10:00
084cf26ed6 refactor: remove all session events
There's no longer any need for session-scoped events now that we have the session queue. Session started/completed/canceled map 1-to-1 to queue item status events, but queue item status events also have an event for failed state.

We can simplify queue and processor handling substantially by removing session events and instead using queue item events.

- Remove the session-scoped events entirely.
- Remove all event handling from session queue. The processor still needs to respond to some events from the queue: `QueueClearedEvent`, `BatchEnqueuedEvent` and `QueueItemStatusChangedEvent`.
- Pass an `is_canceled` callback to the invocation context instead of the cancel event
- Update processor logic to ensure the local instance of the current queue item is synced with the instance in the database. This prevents race conditions and ensures lifecycle callback do not get stale callbacks.
- Update docstrings and comments
- Add `complete_queue_item` method to session queue service as an explicit way to mark a queue item as successfully completed. Previously, the queue listened for session complete events to do this.

Closes #6442
2024-05-27 09:06:02 +10:00
8592f5c6e1 feat(events): move event sets outside sio class
This lets the event sets be consumed programmatically.
2024-05-27 09:06:02 +10:00
368127bd25 feat(events): register_events supports single event 2024-05-27 09:06:02 +10:00
c0aabcd8ea tidy(events): use tuple index access for event payloads 2024-05-27 09:06:02 +10:00
ed6c716ddc fix(mm): emit correct event when model load complete 2024-05-27 09:06:02 +10:00
eaf67b2150 feat(ui): add logging for session events 2024-05-27 09:06:02 +10:00
575943d0ad fix(processor): move session started event to session runner 2024-05-27 09:06:02 +10:00
25d1d2b591 tidy(processor): use separate handlers for each event type
Just a bit clearer without needing `isinstance` checks.
2024-05-27 09:06:02 +10:00
39415428de chore(ui): typegen 2024-05-27 09:06:02 +10:00
64d553f72c feat(events): restore temp handling of user/project 2024-05-27 09:06:02 +10:00
5b390bb11c tests: clean up tests after events changes 2024-05-27 09:06:02 +10:00
a9f773c03c fix(mm): port changes into new model_install_common file
Some subtle changes happened between this PR's last update and now. Bring them into the file.
2024-05-27 09:06:02 +10:00
585feccf82 fix(ui): update event handling to match new types 2024-05-27 09:06:02 +10:00
cbd3b15cae chore(ui): typegen 2024-05-27 09:06:02 +10:00
cc56918453 tidy(ui): remove old unused session subscribe actions 2024-05-27 09:06:02 +10:00
f82df2661a docs: clarify comment in api_app 2024-05-27 09:06:02 +10:00
a1d68eb319 fix(ui): denoise percentage 2024-05-27 09:06:02 +10:00
8b5caa7e57 chore(ui): typegen 2024-05-27 09:06:02 +10:00
b3a051250f feat(api): sort socket event names for openapi schema
Deterministic ordering prevents extraneous, non-functional changes to the autogenerated types
2024-05-27 09:06:02 +10:00
0f733c42fc fix(events): fix denoise progress percentage
- Restore calculation of step percentage but in the backend instead of client
- Simplify signatures for denoise progress event callbacks
- Clean up `step_callback.py` (types, do not recreate constant matrix on every step, formatting)
2024-05-27 09:06:02 +10:00
ec4f10aed3 chore(ui): typegen 2024-05-27 09:06:02 +10:00
d97186dfc8 feat(events): remove payload registry, add method to get event classes
We don't need to use the payload schema registry. All our events are dispatched as pydantic models, which are already validated on instantiation.

We do want to add all events to the OpenAPI schema, and we referred to the payload schema registry for this. To get all events, add a simple helper to EventBase. This is functionally identical to using the schema registry.
2024-05-27 09:06:02 +10:00
18b4f1b72a feat(ui): add missing socket events 2024-05-27 09:06:02 +10:00
5cdf71b72f feat(events): add missing events
These events weren't being emitted via socket.io:
- DownloadCancelledEvent
- DownloadCompleteEvent
- DownloadErrorEvent
- DownloadProgressEvent
- DownloadStartedEvent
- ModelInstallDownloadsCompleteEvent
2024-05-27 09:06:02 +10:00
88a2340b95 feat(events): use builder pattern for download events 2024-05-27 09:06:02 +10:00
1be4cab2d9 fix(events): dump events with mode="json"
Ensures all model events are serializable.
2024-05-27 09:06:02 +10:00
567b87cc50 docs(events): update event docstrings 2024-05-27 09:06:02 +10:00
4756920282 tests: move fixtures import to conftest.py 2024-05-27 09:06:02 +10:00
a876675448 tests: update tests to use new events 2024-05-27 09:06:02 +10:00
655f62008f fix(mm): check for presence of invoker before emitting model load event
The model loader emits events. During testing, it doesn't have access to a fully-mocked events service, so the test fails when attempting to call a nonexistent method. There was a check for this previously, but I accidentally removed it. Restored.
2024-05-27 09:06:02 +10:00
300725d1dd fix(ui): correct model load event format 2024-05-27 09:06:02 +10:00
bf03127c69 fix(events): add missing __event_name__ to EventBase 2024-05-27 09:06:02 +10:00
2dc752ea83 feat(events): simplify event classes
- Remove ABCs, they do not work well with pydantic
- Remove the event type classvar - unused
- Remove clever logic to require an event name - we already get validation for this during schema registration.
- Rename event bases to all end in "Base"
2024-05-27 09:06:02 +10:00
1b9bbaa5a4 fix(events): emit bulk download events in correct room 2024-05-27 09:06:02 +10:00
3abc182b44 chore(ui): tidy after rebase 2024-05-27 09:06:02 +10:00
8d79ce94aa feat(ui): update UI to use new events
- Use OpenAPI schema for event payload types
- Update all event listeners
- Add missing events / remove old nonexistent events
2024-05-27 09:06:02 +10:00
975dc14579 chore(ui): typegen 2024-05-27 09:06:02 +10:00
9bd78823a3 refactor(events): use pydantic schemas for events
Our events handling and implementation has a couple pain points:
- Adding or removing data from event payloads requires changes wherever the events are dispatched from.
- We have no type safety for events and need to rely on string matching and dict access when interacting with events.
- Frontend types for socket events must be manually typed. This has caused several bugs.

`fastapi-events` has a neat feature where you can create a pydantic model as an event payload, give it an `__event_name__` attr, and then dispatch the model directly.

This allows us to eliminate a layer of indirection and some unpleasant complexity:
- Event handler callbacks get type hints for their event payloads, and can use `isinstance` on them if needed.
- Event payload construction is now the responsibility of the event itself (a pydantic model), not the service. Every event model has a `build` class method, encapsulating this logic. The build methods are provided as few args as possible. For example, `InvocationStartedEvent.build()` gets the invocation instance and queue item, and can choose the data it wants to include in the event payload.
- Frontend event types may be autogenerated from the OpenAPI schema. We use the payload registry feature of `fastapi-events` to collect all payload models into one place, making it trivial to keep our schema and frontend types in sync.

This commit moves the backend over to this improved event handling setup.
2024-05-27 09:06:02 +10:00
461e857824 fix(ui): parameter not set translation 2024-05-26 08:21:06 -07:00
48db0b90e8 Bump transformers 2024-05-26 12:51:07 +10:00
c010ce49f7 Bump huggingface-hub 2024-05-26 12:51:07 +10:00
6df8b23c59 Bump transformers 2024-05-26 12:51:07 +10:00
dfe02b26c1 Bump accelerate 2024-05-26 12:51:07 +10:00
4142dc7141 Update deps to their lastest version 2024-05-26 12:51:07 +10:00
86bfcc53a3 docs: fix typo (#6395)
may noise steps -> many noise steps
2024-05-24 18:02:17 +00:00
532f82cb97 Optimize RAM to VRAM transfer (#6312)
* avoid copying model back from cuda to cpu

* handle models that don't have state dicts

* add assertions that models need a `device()` method

* do not rely on torch.nn.Module having the device() method

* apply all patches after model is on the execution device

* fix model patching in latents too

* log patched tokenizer

* closes #6375

---------

Co-authored-by: Lincoln Stein <lstein@gmail.com>
2024-05-24 17:06:09 +00:00
7437085cac fix typo (#6255) 2024-05-24 15:26:05 +00:00
e9b80cf28f fix(ui): isLocal erroneously hardcoded 2024-05-25 00:05:44 +10:00
f5a775ae4e feat(ui): toast on queue item errors, improved error descriptions
Show error toasts on queue item error events instead of invocation error events. This allows errors that occurred outside node execution to be surfaced to the user.

The error description component is updated to show the new error message if available. Commercial handling is retained, but local now uses the same component to display the error message itself.
2024-05-24 20:02:24 +10:00
50dd569411 fix(processor): race condition that could result in node errors not getting reported
I had set the cancel event at some point during troubleshooting an unrelated issue. It seemed logical that it should be set there, and didn't seem to break anything. However, this is not correct.

The cancel event should not be set in response to a queue status change event. Doing so can cause a race condition when nodes are executed very quickly.

It's possible that a previously-executed session's queue item status change event is handled after the next session starts executing. The cancel event is set and the session runner sees it aborting the session run early.

In hindsight, it doesn't make sense to set the cancel event here either. It should be set in response to user action, e.g. the user cancelled the session or cleared the queue (which implicitly cancels the current session). These events actually trigger the queue item status changed event, so if we set the cancel event here, we'd be setting it twice per cancellation.
2024-05-24 20:02:24 +10:00
125e1d7eb4 tidy: remove unnecessary whitespace changes 2024-05-24 20:02:24 +10:00
2fbe5ecb00 fix(ui): correctly fallback to error message when traceback is empty string 2024-05-24 20:02:24 +10:00
ba4d27860f tidy(ui): remove extraneous condition in socketInvocationError 2024-05-24 20:02:24 +10:00
6fc7614b4a fix(ui): race condition with progress
There's a race condition where a canceled session may emit a progress event or two after it's been canceled, and the progress image isn't cleared out.

To resolve this, the system slice tracks canceled session ids. When a progress event comes in, we check the cancellations and skip setting the progress if canceled.
2024-05-24 20:02:24 +10:00
9c926f249f feat(processor): add debug log stmts to session running callbacks 2024-05-24 20:02:24 +10:00
80faeac913 fix(processor): fix race condition related to clearing the queue 2024-05-24 20:02:24 +10:00
418c932595 tidy(processor): remove test callbacks 2024-05-24 20:02:24 +10:00
9117db2673 tidy(queue): delete unused delete_queue_item method 2024-05-24 20:02:24 +10:00
4a48aa98a4 chore: ruff 2024-05-24 20:02:24 +10:00
e365d35c93 docs(processor): update docstrings, comments 2024-05-24 20:02:24 +10:00
aa329ea811 feat(ui): handle enriched events 2024-05-24 20:02:24 +10:00
1e622a5706 chore(ui): typegen 2024-05-24 20:02:24 +10:00
ae66d32b28 feat(app): update test event callbacks 2024-05-24 20:02:24 +10:00
2dd3a85ade feat(processor): update enriched errors & fail_queue_item() 2024-05-24 20:02:24 +10:00
a8492bd7e4 feat(events): add enriched errors to events 2024-05-24 20:02:24 +10:00
25954ea750 feat(queue): session queue error handling
- Add handling for new error columns `error_type`, `error_message`, `error_traceback`.
- Update queue item model to include the new data. The `error_traceback` field has an alias of `error` for backwards compatibility.
- Add `fail_queue_item` method. This was previously handled by `cancel_queue_item`. Splitting this functionality makes failing a queue item a bit more explicit. We also don't need to handle multiple optional error args.
-
2024-05-24 20:02:24 +10:00
887b73aece feat(db): add error_type, error_message, rename error -> error_traceback to session_queue table 2024-05-24 20:02:24 +10:00
3c41c67d13 fix(processor): restore missing update of session 2024-05-24 20:02:24 +10:00
6c79be7dc3 chore: ruff 2024-05-24 20:02:24 +10:00
097619ef51 feat(processor): get user/project from queue item w/ fallback 2024-05-24 20:02:24 +10:00
a1f7a9cd6f fix(app): fix logging of error classes instead of class names 2024-05-24 20:02:24 +10:00
25b9c19eed feat(app): handle preparation errors as node errors
We were not handling node preparation errors as node errors before. Here's the explanation, copied from a comment that is no longer required:

---

TODO(psyche): Sessions only support errors on nodes, not on the session itself. When an error occurs outside
node execution, it bubbles up to the processor where it is treated as a queue item error.

Nodes are pydantic models. When we prepare a node in `session.next()`, we set its inputs. This can cause a
pydantic validation error. For example, consider a resize image node which has a constraint on its `width`
input field - it must be greater than zero. During preparation, if the width is set to zero, pydantic will
raise a validation error.

When this happens, it breaks the flow before `invocation` is set. We can't set an error on the invocation
because we didn't get far enough to get it - we don't know its id. Hence, we just set it as a queue item error.

---

This change wraps the node preparation step with exception handling. A new `NodeInputError` exception is raised when there is a validation error. This error has the node (in the state it was in just prior to the error) and an identifier of the input that failed.

This allows us to mark the node that failed preparation as errored, correctly making such errors _node_ errors and not _processor_ errors. It's much easier to diagnose these situations. The error messages look like this:

> Node b5ac87c6-0678-4b8c-96b9-d215aee12175 has invalid incoming input for height

Some of the exception handling logic is cleaned up.
2024-05-24 20:02:24 +10:00
cc2d877699 docs(app): explain why errors are handled poorly 2024-05-24 20:02:24 +10:00
be82404759 tidy(app): "outputs" -> "output" 2024-05-24 20:02:24 +10:00
33f9fe2c86 tidy(app): rearrange proccessor 2024-05-24 20:02:24 +10:00
1d973f92ff feat(app): support multiple processor lifecycle callbacks 2024-05-24 20:02:24 +10:00
7f70cde038 feat(app): make things in session runner private 2024-05-24 20:02:24 +10:00
47722528a3 feat(app): iterate on processor split 2
- Use protocol to define callbacks, this allows them to have kwargs
- Shuffle the profiler around a bit
- Move `thread_limit` and `polling_interval` to `__init__`; `start` is called programmatically and will never get these args in practice
2024-05-24 20:02:24 +10:00
be41c84305 feat(app): iterate on processor split
- Add `OnNodeError` and `OnNonFatalProcessorError` callbacks
- Move all session/node callbacks to `SessionRunner` - this ensures we dump perf stats before resetting them and generally makes sense to me
- Remove `complete` event from `SessionRunner`, it's essentially the same as `OnAfterRunSession`
- Remove extraneous `next_invocation` block, which would treat a processor error as a node error
- Simplify loops
- Add some callbacks for testing, to be removed before merge
2024-05-24 20:02:24 +10:00
82b4298b03 Fix next node calling logic 2024-05-24 20:02:24 +10:00
fa6c7badd6 Run ruff 2024-05-24 20:02:24 +10:00
45d2504c1e Break apart session processor and the running of each session into separate classes 2024-05-24 20:02:24 +10:00
f1bb7e86c0 feat(ui): invalidate cache for queue item on status change
This query is only subscribed-to in the `QueueItemDetail` component - when is rendered only when the user clicks on a queue item in the queue. Invalidating this tag instead of optimistically updating it won't cause any meaningful change to network traffic.
2024-05-24 08:59:49 +10:00
93e4c3dbc2 feat(app): update queue item's session on session completion
The session is never updated in the queue after it is first enqueued. As a result, the queue detail view in the frontend never never updates and the session itself doesn't show outputs, execution graph, etc.

We need a new method on the queue service to update a queue item's session, then call it before updating the queue item's status.

Queue item status may be updated via a session-type event _or_ queue-type event. Adding the updated session to all these events is a hairy - simpler to just update the session before we do anything that could trigger a queue item status change event:
- Before calling `emit_session_complete` in the processor (handles session error, completed and cancel events and the corresponding queue events)
- Before calling `cancel_queue_item` in the processor (handles another way queue items can be canceled, outside the session execution loop)

When serializing the session, both in the new service method and the `get_queue_item` endpoint, we need to use `exclude_none=True` to prevent unexpected validation errors.
2024-05-24 08:59:49 +10:00
c3f28f7a35 translationBot(ui): update translation (Spanish)
Currently translated at 30.5% (380 of 1243 strings)

Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/es/
Translation: InvokeAI/Web UI
2024-05-24 08:05:45 +10:00
c900a63842 translationBot(ui): update translation files
Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/
Translation: InvokeAI/Web UI
2024-05-24 08:05:45 +10:00
4eb5f004e6 Update invokeai_version.py 2024-05-24 08:00:03 +10:00
bcae735d7c fix(ui): initial image layers always ignored (#6434)
## Summary

Whoops!

## Related Issues / Discussions


https://discord.com/channels/1020123559063990373/1049495067846524939/1243186572115837009

## QA Instructions

- Generate w/ initial image layer

## Merge Plan

n/a

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-05-24 03:16:18 +05:30
861f06c459 Merge branch 'main' into psyche/fix/ui/initial-image-layer 2024-05-24 03:14:18 +05:30
c493628272 fix(ui): 'undefined' being used for metadata on uploaded images (#6433)
## Summary

TIL if you add `undefined` to a form data object, it gets stringified to
`'undefined'`. Whoops!

## Related Issues / Discussions

n/a

## QA Instructions

n/a

## Merge Plan

n/a

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-05-24 03:14:02 +05:30
46a90ca402 fix(ui): initial image layers always ignored
Whoops!
2024-05-24 06:40:48 +10:00
d45c33b446 fix(ui): 'undefined' being used for metadata on uploaded images 2024-05-24 06:17:07 +10:00
88025d32c2 feat(api): downgrade metadata parse warnings to debug
I set these to warn during testing and neglected to undo the change.
2024-05-23 22:48:34 +10:00
af64764082 fix: remove db maintenance script from launcher
It is broken.
2024-05-23 22:39:55 +10:00
70487f0c2e fix(ui): layers are "enabled", not "visible" 2024-05-23 10:14:34 +10:00
55d7d9cc75 fix(ui): control layers don't disable correctly
Closes #6424
2024-05-23 10:14:34 +10:00
106674175c add logo and change text for non-local; 2024-05-23 06:51:13 +10:00
dd1d5bdb25 use support URL for non-local 2024-05-23 06:51:13 +10:00
6259ac0bec translationBot(ui): update translation (Dutch)
Currently translated at 79.6% (973 of 1222 strings)

Co-authored-by: Dennis <dennis@vanzoerlandt.nl>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/nl/
Translation: InvokeAI/Web UI
2024-05-22 09:51:12 +10:00
ba31f8a9a9 translationBot(ui): update translation (Italian)
Currently translated at 98.5% (1210 of 1228 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.5% (1206 of 1224 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.5% (1204 of 1222 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-05-22 09:51:12 +10:00
0ba57d6dc5 feat(ui): close starter models toast when a model is installed 2024-05-22 09:40:46 +10:00
abc133e936 feat(ui): revised invocation error toast handling
Only display the session if local. Otherwise, just display the error message.
2024-05-22 09:40:46 +10:00
57743239d7 feat(ui): add updateDescription flag to toast API
If false, when updating a toast, the description is left alone. The count will still tick up.
2024-05-22 09:40:46 +10:00
4a394c60cf feat(ui): add isLocal flag to config 2024-05-22 09:40:46 +10:00
624d28a93d feat(ui): invocation error toasts do not autoclose 2024-05-22 09:40:46 +10:00
29e1ea59fc feat(ui): style copy button on ToastWithSessionRefDescription 2024-05-22 09:40:46 +10:00
2e5d24f272 tidy(ui): remove old comment 2024-05-22 09:40:46 +10:00
1afa340b1a fix(ui): show toast when recalling seed 2024-05-22 09:40:46 +10:00
3b381b5a8c tidy(ui): remove the ToastID enum
With the model install logic cleaned up the enum is less useful
2024-05-22 09:40:46 +10:00
f2b9684de8 tidy(ui): split install model into helper hook
This was duplicated like 7 times or so
2024-05-22 09:40:46 +10:00
a66b3497e0 feat(ui): port all toasts to use new util 2024-05-22 09:40:46 +10:00
683ec8e5f2 feat(ui): add stateful toast utility
Small wrapper around chakra's toast system simplifies creating and updating toasts. See comments in toast.ts for details.
2024-05-22 09:40:46 +10:00
f31f0cf733 feat(ui): restore spellcheck on prompt boxes 2024-05-22 08:52:25 +10:00
38265b3123 docs(ui): update validateWorkflow comments 2024-05-21 05:17:10 -07:00
caca28286c tests(ui): add test for resource usage check 2024-05-21 05:17:10 -07:00
38320a5100 feat(ui): reset missing images, boards and models when loading workflows
These fields are reset back to `undefined` if not accessible. A warning toast is showing, and in the JS console, the full warning message is logged.
2024-05-21 05:17:10 -07:00
7badaab17d docs: fix link to invoke ai models site 2024-05-20 20:48:42 -07:00
aa0c59bb51 fix(ui): crash when using notes nodes or missing node/field templates (#6412)
## Summary

Notes nodes used some overly-strict redux selectors. The selectors are
now more chill. Also fixed an issue where you couldn't edit a notes node
title.

Found another class of error related to the overly strict reducers that
caused errors when loading a workflow that had missing templates. Fixed
this with fallback wrapper component, works like an error boundary when
a template isn't found.

## Related Issues / Discussions


https://discord.com/channels/1020123559063990373/1149506274971631688/1242256425527545949

## QA Instructions

- Add a notes node to a workflow. Edit the notes title.
- Load a workflow that has nodes that aren't installed. Should get a
fallback UI for each missing node.
- Load a workflow that references a node with different inputs than are
in the template - like an old version of a node. Should get a fallback
field warning for both missing templates, or missing inputs.

## Merge Plan

n/a

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-05-21 07:59:43 +05:30
e4acaa5c8f chore: v4.2.2post1 2024-05-21 11:31:06 +10:00
9ba47cae20 fix(ui): unable to edit notes node title 2024-05-21 11:27:11 +10:00
bf4310ca71 fix(ui): errors when node template or field template doesn't exist
Some asserts were bubbling up in places where they shouldn't have, causing errors when a node has a field without a matching template, or vice-versa.

To resolve this without sacrificing the runtime safety provided by asserts, a `InvocationFieldCheck` component now wraps all field components. This component renders a fallback when a field doesn't exist, so the inner components can safely use the asserts.
2024-05-21 11:22:08 +10:00
e75f98317f fix(ui): notes node text not selectable 2024-05-21 10:06:25 +10:00
1249d4a6e3 fix(ui): crash when using a notes node 2024-05-21 10:06:09 +10:00
66c9f4708d Update invokeai_version.py 2024-05-21 07:11:09 +10:00
32277193b6 fix(ui): retain denoise strength and opacity when changing image 2024-05-20 18:27:51 +10:00
620ee2875e fix(ui): store hidden state of edges in workflows
This prevents a minor visual bug where collapsed edges between collapsed nodes didn't display correctly on first load of a workflow.
2024-05-20 11:36:47 +10:00
5553588147 fix(ui): ensure invocation edges have a type 2024-05-20 11:36:47 +10:00
1c29b3bd85 feat(ui): updated field type translations 2024-05-20 11:28:33 +10:00
e88b807a13 docs(ui): update field type docs & comments 2024-05-20 11:28:33 +10:00
9e55ef3d4b fix(ui): workflow migration field type
At some point, I made a mistake and imported the wrong types to some files for the old v1 and v2 workflow schema migration data.

The relevant zod schemas and inferred types have been restored.

This change doesn't alter runtime behaviour. Only type annotations.
2024-05-20 11:28:33 +10:00
8062a47d16 fix(ui): use new field type cardinality throughout app
Update business logic and tests.
2024-05-20 11:28:33 +10:00
dba8c43ecb feat(ui): explicit field type cardinality
Replace the `isCollection` and `isCollectionOrScalar` flags with a single enum value `cardinality`. Valid values are `SINGLE`, `COLLECTION` and `SINGLE_OR_COLLECTION`.

Why:
- The two flags were mutually exclusive, but this wasn't enforce. You could create a field type that had both `isCollection` and `isCollectionOrScalar` set to true, whuch makes no sense.
- There was no explicit declaration for scalar/single types.
- Checking if a type had only a single flag was tedious.

Thanks to a change a couple months back in which the workflows schema was revised, field types are internal implementation details. Changes to them are non-breaking.
2024-05-20 11:28:33 +10:00
8ebf2ddf15 fix(ui): fix t2i adapter dimensions error message
It now indicates the correct dimension of 64 (SD1.5) or 32 (SDXL) - before was hardcoded to 64.
2024-05-20 11:23:14 +10:00
f4625c2671 feat(ui): add canvas objects to metadat a for all canvas graphs 2024-05-20 10:32:59 +10:00
c94742bde6 feat(ui): add canvas objects to metadata when saving canvas to gallery 2024-05-20 10:32:59 +10:00
a34faf0bd8 chore(ui): typegen 2024-05-20 10:32:59 +10:00
ecfff6cb1e feat(api): add metadata to upload route
Canvas images are saved by uploading a blob generated from the HTML canvas element. This means the existing metadata handling, inside the graph execution engine, is not available.

To save metadata to canvas images, we need to provide it when uploading that blob.

The upload route now has a `metadata` body param. If this is provided, we use it over any metadata embedded in the image.
2024-05-20 10:32:59 +10:00
ba8bed6870 fix(ui): edge case resulting in no node templates when loading workflow, causing failure
Depending on the user behaviour and network conditions, it's possible that we could try to load a workflow before the invocation templates are available.

Fix is simple:
- Use the RTKQ query hook for openAPI schema in App.tsx
- Disable the load workflow buttons until w have templates parsed
2024-05-19 07:34:00 -07:00
ca186bca61 fix(ui): missed node execution state for progress images 2024-05-19 20:14:01 +10:00
e2f109807c fix(ui): delete edges when their source or target no longer exists 2024-05-19 20:14:01 +10:00
281bd31db2 feat(nodes): make ModelIdentifierInvocation a prototype 2024-05-19 20:14:01 +10:00
cea1874e00 perf(ui): memoize WorkflowName selectors 2024-05-19 20:14:01 +10:00
89b0e9e4de feat(ui): use connection validationResults directly in components 2024-05-19 20:14:01 +10:00
26d0d55d97 fix(ui): set nodeDragThreshold to prevent spurious position change events 2024-05-19 20:14:01 +10:00
059c5586a4 perf(ui): ignore all no-op node and edge changes 2024-05-19 20:14:01 +10:00
9ed5698aa8 fix(ui): do not remove exposed fields when updating workflows 2024-05-19 20:14:01 +10:00
0b5696c5d4 feat(ui): remove nodeExclusivelySelected action 2024-05-19 20:14:01 +10:00
a51142674a tidy(ui): more succinct syntax for edge and node updates 2024-05-19 20:14:01 +10:00
b8b671c0db feat(ui): remove selectionDeleted action 2024-05-19 20:14:01 +10:00
7cceafe0dd feat(ui): remove selectionPasted action 2024-05-19 20:14:01 +10:00
cbe32b647a feat(ui): remove selectedAll action 2024-05-19 20:14:01 +10:00
9a8e0842bb feat(ui): remove nodeReplaced action 2024-05-19 20:14:01 +10:00
1d7671298f fix(ui): group edge selection actions 2024-05-19 20:14:01 +10:00
e38d75c3dc feat(ui): get rid of nodeAdded 2024-05-19 20:14:01 +10:00
21fab9785a feat(ui): tweak edge styling 2024-05-19 20:14:01 +10:00
b3429553bb fix(ui): collapsed edges selected state 2024-05-19 20:14:01 +10:00
e480844042 fix(ui): edge styling 2024-05-19 20:14:01 +10:00
26029108f7 feat(ui): rework node and edge mutation logic
Remove our DIY'd reducers, consolidating all node and edge mutations to use `edgesChanged` and `nodesChanged`, which are called by reactflow. This makes the API for manipulating nodes and edges less tangly and error-prone.
2024-05-19 20:14:01 +10:00
504ac82077 fix(ui): duplicated edges when updating edge with lazy connect 2024-05-19 20:14:01 +10:00
6b11740dda chore(ui): knip 2024-05-19 20:14:01 +10:00
a80e3448f5 feat(ui): rework pendingConnection 2024-05-19 20:14:01 +10:00
4bda174eb9 tests(ui): coverage for getCollectItemType 2024-05-19 20:14:01 +10:00
b1e28c2f2c tests(ui): coverage for getFirstValidConnection 2024-05-19 20:14:01 +10:00
83000a4190 feat(ui): rework getFirstValidConnection with new helpers 2024-05-19 20:14:01 +10:00
c98205d0d7 tests(ui): candidate fields, getFirstValidConnection (wip) 2024-05-19 20:14:01 +10:00
ce2ad5903c feat(ui): extract logic for finding candidate fields to own function 2024-05-19 20:14:01 +10:00
fe3980a369 tests(ui): add buildNode convenience wrapper for buildInvocationNode 2024-05-19 20:14:01 +10:00
ea97ae5ae8 tidy(ui): extraneous vars in makeConnectionErrorSelector 2024-05-19 20:14:01 +10:00
3605b6b1a3 fix(ui): handling for in-progress edge updates during conection validation 2024-05-19 20:14:01 +10:00
fc31dddbf7 feat(ui): use new validateConnection 2024-05-19 20:14:01 +10:00
6ad01d824d feat(ui): add strict mode to validateConnection 2024-05-19 20:14:01 +10:00
78f9f3ee95 feat(ui): better types for validateConnection 2024-05-19 20:14:01 +10:00
972398d203 tests(ui): add iterate to test schema 2024-05-19 20:14:01 +10:00
857889d1fa tests(ui): coverage for getCollectItemType 2024-05-19 20:14:01 +10:00
8074a802d6 tests(ui): coverage for validateConnectionTypes 2024-05-19 20:14:01 +10:00
059d5a682c tidy(ui): validateConnection code clarity 2024-05-19 20:14:01 +10:00
00c2d8f95d tidy(ui): areTypesEqual var names 2024-05-19 20:14:01 +10:00
04a596179b tests(ui): finish test cases for validateConnection 2024-05-19 20:14:01 +10:00
3fcb2720d7 tests(ui): add tests for consolidated connection validation 2024-05-19 20:14:01 +10:00
6f7160b9fd fix(ui): call updateNodeInternals when making connections 2024-05-19 20:14:01 +10:00
6b4e464d17 fix(ui): rework edge update logic 2024-05-19 20:14:01 +10:00
9f7841a04b tidy(ui): clean up addnodepopover hotkeys 2024-05-19 20:14:01 +10:00
468644ab18 fix(ui): rebase conflict 2024-05-19 20:14:01 +10:00
9d127fee6b feat(ui): makeConnectionErrorSelector now creates a parameterized selector 2024-05-19 20:14:01 +10:00
6658897210 tidy(ui): tidy connection validation functions and logic 2024-05-19 20:14:01 +10:00
af7b194bec chore(ui): lint 2024-05-19 20:14:01 +10:00
de1ea50e6d fix(ui): rebase resolution 2024-05-19 20:14:01 +10:00
2680ef52c2 feat(nodes): add ModelIdentifierInvocation
This node allows a user to select _any_ model, outputting a `ModelIdentifierField` for that model.
2024-05-19 20:14:01 +10:00
a012bb6e07 feat(ui): add ModelIdentifierField field type
This new field type accepts _any_ model. A field renderer lets the user select any available model.
2024-05-19 20:14:01 +10:00
6a2c53f6c5 fix(ui): do not allow comparison between undefined original types 2024-05-19 20:14:01 +10:00
2cbf7d9221 fix(ui): stupid ts 2024-05-19 20:14:01 +10:00
fe7ed72c9c feat(nodes): make all ModelIdentifierField inputs accept connections 2024-05-19 20:14:01 +10:00
85a5a7c47a feat(ui): add originalType to FieldType, improved connection validation
We now keep track of the original field type, derived from the python type annotation in addition to the override type provided by `ui_type`.

This makes `ui_type` work more like it sound like it should work - change the UI input component only.

Connection validation is extend to also check the original types. If there is any match between two fields' "final" or original types, we consider the connection valid.This change is backwards-compatible; there is no workflow migration needed.
2024-05-19 20:14:01 +10:00
af3fd26d4e fix(ui): bug when clearing processor
When clearing the processor config, we shouldn't re-process the image. This logic wasn't handled correctly, but coincidentally the bug didn't cause a user-facing issue.

Without a config, we had a runtime error when trying to build the node for the processor graph and the listener failed.

So while we didn't re-process the image, it was because there was an error, not because the logic was correct.

Fix this by bailing if there is no image or config.
2024-05-19 07:25:48 +10:00
5127fd6320 fix(ui): control adapter autoprocess jank
If you change the control model and the new model has the same default processor, we would still re-process the image, even if there was no need to do so.

With this change, if the image and processor config are unchanged, we bail out.
2024-05-19 07:25:48 +10:00
124d34a8cc docs: add link for --extra-index-url 2024-05-19 00:56:31 +10:00
e8387d7523 docs: add link to tool on pytorch website 2024-05-19 00:56:31 +10:00
a5d08c981b docs: fix typo in --root arg of invokeai-web 2024-05-19 00:56:31 +10:00
811d0da0f0 docs: fix link to. install reqs 2024-05-19 00:56:31 +10:00
987ee704a1 Merge branch 'main' into lstein/feat/simple-mm2-api 2024-05-17 22:54:03 -04:00
e77c7e40b7 fix ruff error 2024-05-17 22:53:45 -04:00
8aebc29b91 fix test to run on 32bit cpu 2024-05-17 22:48:54 -04:00
d968c6f379 refactor multifile download code 2024-05-17 22:29:19 -04:00
17e1fc5254 chore(app): ruff 2024-05-18 09:21:45 +10:00
84e031edc2 add nulable project also 2024-05-18 09:21:45 +10:00
b6b7e737e0 ruff 2024-05-18 09:21:45 +10:00
5f3e7afd45 add nullable user to invocation error events 2024-05-18 09:21:45 +10:00
b0cfca9d24 fix(app): pass image metadata as stringified json 2024-05-18 09:04:37 +10:00
985ef89825 fix(app): type annotations in images service 2024-05-18 09:04:37 +10:00
5928ade5fd feat(app): simplified create image API
Graph, metadata and workflow all take stringified JSON only. This makes the API consistent and means we don't need to do a round-trip of pydantic parsing when handling this data.

It also prevents a failure mode where an uploaded image's metadata, workflow or graph are old and don't match the current schema.

As before, the frontend does strict validation and parsing when loading these values.
2024-05-18 09:04:37 +10:00
93ebc175c6 fix(app): retain graph in metadata when uploading images 2024-05-18 09:04:37 +10:00
386d552493 fix(ui): loading workflows from file 2024-05-18 09:04:37 +10:00
799cf06d20 fix(ui): loading library workflows 2024-05-18 09:04:37 +10:00
922716d2ab feat(ui): store graph in image metadata
The previous super-minimal implementation had a major issue - the saved workflow didn't take into account batched field values. When generating with multiple iterations or dynamic prompts, the same workflow with the first prompt, seed, etc was stored in each image.

As a result, when the batch results in multiple queue items, only one of the images has the correct workflow - the others are mismatched.

To work around this, we can store the _graph_ in the image metadata (alongside the workflow, if generated via workflow editor). When loading a workflow from an image, we can choose to load the workflow or the graph, preferring the workflow.

Internally, we need to update images router image-saving services. The changes are minimal.

To avoid pydantic errors deserializing the graph, when we extract it from the image, we will leave it as stringified JSON and let the frontend's more sophisticated and flexible parsing handle it. The worklow is also changed to just return stringified JSON, so the API is consistent.
2024-05-18 09:04:37 +10:00
66fc110b64 Revert "feat(ui): store workflow in generation tab images"
This reverts commit c9c4190fb45696088207b0ac3c69c2795d7f9694.
2024-05-18 09:04:37 +10:00
822f1e1f06 feat(ui): store workflow in generation tab images 2024-05-18 09:04:37 +10:00
5d60c3c8e1 fix(ui): jank when editing field title 2024-05-18 08:46:40 +10:00
4e21d01c7f feat(ui): dim field name when connected 2024-05-18 08:46:40 +10:00
6b7b0b3777 fix(ui): do not rearrange fields when connection/disconnecting 2024-05-18 08:46:40 +10:00
07feb5ba07 Revert "feat(ui): SDXL clip skip"
This reverts commit 40b4fa7238.
2024-05-17 15:08:04 -07:00
a18d7adad4 fix(ui): allow image dims multiple of 32 with SDXL and T2I adapter
See https://github.com/invoke-ai/InvokeAI/pull/6342#issuecomment-2109912452 for discussion.
2024-05-17 23:38:54 +10:00
32dff2c4e3 feat(ui): copy/paste input edges when copying node
- Copy edges to selected nodes on copy
- If pasted with `ctrl/meta-shift-v`, also paste the input edges
2024-05-17 23:12:29 +10:00
575ecb4028 feat(ui): prevent connections to direct-only inputs 2024-05-17 22:08:40 +10:00
ad8778df6c feat(ui): extract node execution state from nodesSlice
This state is ephemeral and not undoable.
2024-05-17 13:24:23 +10:00
d2f5103f9f fix(ui): ignore actions from other slices in nodesSlice history 2024-05-17 13:24:23 +10:00
dd42a56084 tests(ui): fix parseSchema test fixture
The schema fixture wasn't formatted quite right - doesn't affect the test but still.
2024-05-17 13:24:23 +10:00
23ac340a3f tests(ui): add test for parseSchema 2024-05-17 13:24:23 +10:00
6791b4eaa8 chore(ui): lint 2024-05-17 13:24:23 +10:00
a8b042177d feat(ui): connection validation for collection items types 2024-05-17 13:24:23 +10:00
76825f4261 fix(ui): allow collect node inputs to connect to multiple fields when using lazy connect 2024-05-17 13:24:23 +10:00
78cb4d75ad fix(ui): use elevateEdgesOnSelect so last-selected edge is the interactable one when updating edges 2024-05-17 13:24:23 +10:00
a18bbac262 fix(ui): jank interaction between edge update and autoconnect 2024-05-17 13:24:23 +10:00
9ff5596963 feat(ui): hide values for connected fields 2024-05-17 13:24:23 +10:00
8ea596b1e9 fix(ui): janky editable field title
- Do not allow whitespace-only field titles
- Make only preview text trigger editable
- Tooltip over the preview, not the whole "row"
2024-05-17 13:24:23 +10:00
e3a143eaed fix(ui): fix jank w/ stale connections 2024-05-17 13:24:23 +10:00
c359ab6d9b fix(ui): fix dependency tracking for copy/paste hotkeys 2024-05-17 13:24:23 +10:00
dbfaa07e03 feat(ui): add checks for undo/redo actions 2024-05-17 13:24:23 +10:00
7f78fe7a36 feat(ui): move viewport state to nanostores 2024-05-17 13:24:23 +10:00
6cf5b402c6 feat(ui): remove extraneous selectedEdges and selectedNodes state 2024-05-17 13:24:23 +10:00
b0c7c7cb47 feat(ui): remove remaining extraneous state from nodes slice 2024-05-17 13:24:23 +10:00
4d68cd8dbb feat(ui): recreate edge auto-add-node logic 2024-05-17 13:24:23 +10:00
2c1fa30639 feat(ui): recreate edge autoconnect logic 2024-05-17 13:24:23 +10:00
708c68413d tidy(ui): add type for templates 2024-05-17 13:24:23 +10:00
1d884fb794 feat(ui): move invocation templates out of redux
Templates are stored in nanostores. All hooks, selectors, etc are reworked to reference the nanostore.
2024-05-17 13:24:23 +10:00
f6a44681a8 feat(ui): move invocation templates out of redux (wip) 2024-05-17 13:24:23 +10:00
d4df312300 feat(ui): move nodes copy/paste out of slice 2024-05-17 13:24:23 +10:00
9c0d44b412 feat(ui): split workflow editor settings to separate slice
We need the undoable slice to be only undoable state - settings are not undoable.
2024-05-17 13:24:23 +10:00
27826369f0 feat(ui): make nodesSlice undoable 2024-05-17 13:24:23 +10:00
2dae5eb7ad more refactoring; HF subfolders not working 2024-05-16 22:26:18 -04:00
31d8b50276 [Refactor] Update min and max values for LoRACard weight input 2024-05-17 10:38:26 +10:00
40b4fa7238 feat(ui): SDXL clip skip
Uses the same CLIP Skip value for both CLIP1 and CLIP2.

Adjusted SDXL CLIP Skip min/max/markers to be within the valid range (0 to 11).

Closes #4583
2024-05-16 07:49:30 -04:00
911a24479b add tests for model install file size reporting 2024-05-16 07:18:33 -04:00
3b1743b7c2 docs: fix install reqs link 2024-05-16 10:37:42 +10:00
f489c818f1 docs(ui): add comments to nsfw & watermarker helpers 2024-05-15 14:09:44 +10:00
af477fa295 tidy(ui): remove unused modelLoader from refiner helper 2024-05-15 14:09:44 +10:00
0ff0290735 tidy(ui): use Invocation<> helper type in canvas graph builders, elsewhere 2024-05-15 14:09:44 +10:00
67dbe6d949 tidy(ui): use Invocation<> helper type in OG control adapters 2024-05-15 14:09:44 +10:00
4c3c2297b9 tidy(ui): organise graph builder files 2024-05-15 14:09:44 +10:00
cadea55521 tidy(ui): organise graph builder files 2024-05-15 14:09:44 +10:00
c8f30b1392 tidy(ui): move testing-only types to test file 2024-05-15 14:09:44 +10:00
3d14a98abf tidy(ui): use Invocation<> type in control layers types 2024-05-15 14:09:44 +10:00
77024bfca7 fix(ui): fix sdxl generation mode metadata 2024-05-15 14:09:44 +10:00
4a1c3786a1 tidy(ui): organise CL graph builder 2024-05-15 14:09:44 +10:00
b239891986 tidy(ui): clean up base model handling in graph builder 2024-05-15 14:09:44 +10:00
9fb03d43ff tests(ui): get coverage to 100% for graph builder 2024-05-15 14:09:44 +10:00
bdc59786bd tidy(ui): clean up graph builder helper functions 2024-05-15 14:09:44 +10:00
fb6e926500 tidy(ui): remove extraneous graph validate calls 2024-05-15 14:09:44 +10:00
48ccd63dba feat(ui): use integrated metadata helper 2024-05-15 14:09:44 +10:00
ee647a05dc feat(ui): move metadata util to graph class
No good reason to have it be separate. A bit cleaner this way.
2024-05-15 14:09:44 +10:00
154b52ca4d docs(ui): update docstrings for Graph builder 2024-05-15 14:09:44 +10:00
5dd460c3ce chore(ui): knip 2024-05-15 14:09:44 +10:00
4897ce2a13 tidy(ui): remove unused files 2024-05-15 14:09:44 +10:00
5425526d50 feat(ui): use graph builder for generation tab sdxl 2024-05-15 14:09:44 +10:00
5a4b050e66 feat(ui): use asserts in graph builder 2024-05-15 14:09:44 +10:00
8d39520232 feat(ui): port NSFW and watermark nodes to graph builder 2024-05-15 14:09:44 +10:00
04d12a1e98 feat(ui): add HRF graph builder helper 2024-05-15 14:09:44 +10:00
39aa70963b docs(ui): update docstrings for addGenerationTabSeamless 2024-05-15 14:09:44 +10:00
5743254a41 fix(ui): use arrays for edge methods 2024-05-15 14:09:44 +10:00
c538ffea26 tidy(ui): remove console.log 2024-05-15 14:09:44 +10:00
e8d3a7c870 feat(ui): support multiple fields for getEdgesTo, getEdgesFrom, deleteEdgesTo, deleteEdgesFrom 2024-05-15 14:09:44 +10:00
2be66b1546 feat(ui): add deleteNode and getEdges to graph util 2024-05-15 14:09:44 +10:00
76e181fd44 build(ui): add eslint no-console rule 2024-05-15 14:09:44 +10:00
b5d42fbc66 tidy(ui): remove unused graph helper 2024-05-15 14:09:44 +10:00
b463cd763e tidy(ui): remove extraneous is_intermediate node fields 2024-05-15 14:09:44 +10:00
eb320df41d feat(ui): use new lora loaders, simplify VAE loader, seamless 2024-05-15 14:09:44 +10:00
de1869773f chore(ui): typegen 2024-05-15 14:09:44 +10:00
ef89c7e537 feat(nodes): add LoRASelectorInvocation, LoRACollectionLoader, SDXLLoRACollectionLoader
These simplify loading multiple LoRAs. Instead of requiring chained lora loader nodes, configure each LoRA (model & weight) with a selector, collect them, then send the collection to the collection loader to apply all of the LoRAs to the UNet/CLIP models.

The collection loaders accept a single lora or collection of loras.
2024-05-15 14:09:44 +10:00
008645d386 fix(ui): work through merge conflicts (wip) 2024-05-15 14:09:44 +10:00
f8042ffb41 WIP, sd1.5 works 2024-05-15 14:09:44 +10:00
dbe22be598 feat(ui): use graph utils in builders (wip) 2024-05-15 14:09:44 +10:00
8f6078d007 feat(ui): refine graph building util
Simpler types and API surface.
2024-05-15 14:09:44 +10:00
4020bf47e2 feat(ui): add MetadataUtil class
Provides methods for manipulating a graph's metadata.
2024-05-15 14:09:44 +10:00
9d685da759 feat(ui): add stateful Graph class
This stateful class provides abstractions for building a graph. It exposes graph methods like adding and removing nodes and edges.

The methods are documented, tested, and strongly typed.
2024-05-15 14:09:44 +10:00
e3289856c0 feat(ui): add and use type helpers for invocations and invocation outputs 2024-05-15 14:09:44 +10:00
47b8153728 build(ui): enable TS strictPropertyInitialization
https://www.typescriptlang.org/tsconfig/#strictPropertyInitialization
2024-05-15 14:09:44 +10:00
7901e4c082 chore(ui): typegen 2024-05-15 14:09:44 +10:00
18b0977a31 feat(api): add InvocationOutputMap to OpenAPI schema
This dynamically generated schema object maps node types to their pydantic schemas. This makes it much simpler to infer node types in the UI.
2024-05-15 14:09:44 +10:00
fc6b214470 tests(ui): set up vitest coverage 2024-05-15 14:09:44 +10:00
e22211dac0 fix: Fix Outpaint not applying the expanded mask correctly
In unscaled situations
2024-05-15 13:59:01 +10:00
f29c406fed refactor model_install to work with refactored download queue 2024-05-13 22:49:15 -04:00
287c679f7b clean up type checking for single file and multifile download job callbacks 2024-05-13 18:31:40 -04:00
e222484663 chore: v4.2.1 (#6362)
## Summary

Bump to v4.2.1

## Related Issues / Discussions

n/a

## QA Instructions

n/a

## Merge Plan

Do the release after merging.

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-05-14 03:17:03 +05:30
2a9cea6689 Update invokeai_version.py
Bump to v4.2.1
2024-05-14 07:37:02 +10:00
93da75209c feat(nodes): use new blur_if_nsfw method 2024-05-14 07:23:38 +10:00
9c819f0fd8 fix(nodes): fix nsfw checker model download 2024-05-14 07:23:38 +10:00
eef6fcf286 translationBot(ui): update translation (Russian)
Currently translated at 100.0% (1210 of 1210 strings)

Co-authored-by: Васянатор <ilabulanov339@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/
Translation: InvokeAI/Web UI
2024-05-14 07:15:12 +10:00
e375d9f787 translationBot(ui): update translation (Italian)
Currently translated at 98.5% (1192 of 1210 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.5% (1192 of 1210 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.5% (1192 of 1210 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.5% (1192 of 1210 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-05-14 07:15:12 +10:00
ab18174774 translationBot(ui): update translation (Spanish)
Currently translated at 31.3% (379 of 1208 strings)

Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/es/
Translation: InvokeAI/Web UI
2024-05-14 07:15:12 +10:00
9265841384 translationBot(ui): update translation files
Updated by "Cleanup translation files" hook in Weblate.

translationBot(ui): update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/
Translation: InvokeAI/Web UI
2024-05-14 07:15:12 +10:00
c5fd08125d translationBot(ui): update translation (Italian)
Currently translated at 98.5% (1192 of 1210 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-05-14 07:15:12 +10:00
11d88dae7f translationBot(ui): update translation (Russian)
Currently translated at 100.0% (1210 of 1210 strings)

Co-authored-by: Васянатор <ilabulanov339@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/
Translation: InvokeAI/Web UI
2024-05-14 07:15:12 +10:00
3b495659b0 translationBot(ui): update translation files
Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/
Translation: InvokeAI/Web UI
2024-05-14 07:15:12 +10:00
15c9a3a4b6 translationBot(ui): update translation (Italian)
Currently translated at 98.3% (1189 of 1209 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.3% (1189 of 1209 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-05-14 07:15:12 +10:00
60e77e4ed6 translationBot(ui): update translation (Chinese (Simplified))
Currently translated at 77.8% (922 of 1185 strings)

Co-authored-by: flower_elf <miaoju2005@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/zh_Hans/
Translation: InvokeAI/Web UI
2024-05-14 07:15:12 +10:00
fa832a8ac6 translationBot(ui): update translation (Russian)
Currently translated at 100.0% (1209 of 1209 strings)

translationBot(ui): update translation (Russian)

Currently translated at 100.0% (1209 of 1209 strings)

translationBot(ui): update translation (Russian)

Currently translated at 100.0% (1188 of 1188 strings)

translationBot(ui): update translation (Russian)

Currently translated at 100.0% (1185 of 1185 strings)

Co-authored-by: Васянатор <ilabulanov339@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/
Translation: InvokeAI/Web UI
2024-05-14 07:15:12 +10:00
f7834d7d59 translationBot(ui): update translation files
Updated by "Cleanup translation files" hook in Weblate.

translationBot(ui): update translation files

Updated by "Cleanup translation files" hook in Weblate.

translationBot(ui): update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/
Translation: InvokeAI/Web UI
2024-05-14 07:15:12 +10:00
63d7461510 translationBot(ui): update translation (German)
Currently translated at 71.9% (839 of 1166 strings)

Co-authored-by: Alexander Eichhorn <pfannkuchensack@einfach-doof.de>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/de/
Translation: InvokeAI/Web UI
2024-05-14 07:15:12 +10:00
1de704160e translationBot(ui): update translation (Russian)
Currently translated at 97.3% (1154 of 1185 strings)

translationBot(ui): update translation (Russian)

Currently translated at 100.0% (1174 of 1174 strings)

translationBot(ui): update translation (Russian)

Currently translated at 100.0% (1173 of 1173 strings)

translationBot(ui): update translation (Russian)

Currently translated at 100.0% (1166 of 1166 strings)

translationBot(ui): update translation (Russian)

Currently translated at 100.0% (1165 of 1165 strings)

translationBot(ui): update translation (Russian)

Currently translated at 100.0% (1149 of 1149 strings)

translationBot(ui): update translation (Russian)

Currently translated at 100.0% (1147 of 1147 strings)

Co-authored-by: Васянатор <ilabulanov339@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/
Translation: InvokeAI/Web UI
2024-05-14 07:15:12 +10:00
b118a2565c translationBot(ui): update translation (Italian)
Currently translated at 96.0% (1138 of 1185 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.4% (1156 of 1174 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.3% (1155 of 1174 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.4% (1129 of 1147 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-05-14 07:15:12 +10:00
0bf14c2830 add multifile_download() method to download service 2024-05-12 20:14:00 -06:00
eb166baafe fix(ui): invoke button shows loading while queueing
Make the Invoke button show a loading spinner while queueing.

The queue mutations need to be awaited else the `isLoading` state doesn't work as expected. I feel like I should understand why, but I don't...
2024-05-13 11:53:29 +10:00
818d37f304 fix(api): retain cover image when converting model to diffusers
We need to retrieve and re-save the image, because a conversion to diffusers creates a new model record, with a new key.

See: https://old.reddit.com/r/StableDiffusion/comments/1cnx40d/invoke_42_control_layers_regional_guidance_w_text/l3bv152/
2024-05-13 08:46:07 +10:00
9cdb801c1c fix(api): add cover image to update model response
Fixes a bug where the image _appears_ to be reset when editing a model.

See: https://old.reddit.com/r/StableDiffusion/comments/1cnx40d/invoke_42_control_layers_regional_guidance_w_text/l3asdej/
2024-05-13 08:46:07 +10:00
5da8cde4fc fix(ui): disable listening on CA and II layers (#6332)
## Summary

Do not listen for mouse events on CA and II layers (which are not
interact-able).

## Related Issues / Discussions

Closes #6331

## QA Instructions

Move a CA or II layer above a regional guidance layer. The move tool
should now work.

## Merge Plan

n/a

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-05-13 04:07:27 +05:30
6ec3dc0c0d Merge branch 'main' into psyche/fix/ui/cl-listening-layers 2024-05-13 04:05:35 +05:30
6050dffb25 fix(ui): use translations for canvas layer select (#6357)
## Summary

Use translations instead of plain strings.

## Related Issues / Discussions


https://discord.com/channels/1020123559063990373/1054129386447716433/1239181243078279208

## QA Instructions

The layer select should still work.

## Merge Plan

n/a

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-05-13 04:04:13 +05:30
93efeafe30 Merge branch 'main' into psyche/fix/ui/canvas-layer-translations 2024-05-13 04:02:23 +05:30
f167e8a8d3 fix(ui): jank in depthanything model size select (#6335)
## Summary

The select had a default search value, which meant it only showed
"small" as an option on first load.

## Related Issues / Discussions

n/a

## QA Instructions

- Add a CA layer
- Expand advanced
- Set processor to depth anything
- Click the model size dropdown, it should show all 3 sizes

## Merge Plan

n/a

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-05-13 04:01:58 +05:30
124d49f35e fix(ui): use translations for canvas layer select 2024-05-13 08:30:18 +10:00
52d8efa892 Merge branch 'main' into psyche/fix/ui/depth-anything-select 2024-05-13 04:00:07 +05:30
4ea8416c68 fix(ui): use pluralization for invoke button tooltip 2024-05-13 08:29:31 +10:00
8dd0bfb068 feat(ui): use new model type grouping for control adapters in control layers 2024-05-13 08:29:31 +10:00
6ff1c7d541 feat(ui): add group by base & type to useGroupedModelCombobox hook
This allows comboboxes for models to have more granular groupings. For example, Control Adapter models can be grouped by base model & model type.

Before:
- `SD-1`
- `SDXL`

After:
- `SD-1 / ControlNet`
- `SD-1 / T2I Adapter`
- `SDXL / ControlNet`
- `SDXL / T2I Adapter`
2024-05-13 08:29:31 +10:00
19f5a9c3a9 feat(ui): better invoke button checks
- Improved/more thorough checking before invoking for control layers
- Improved styling for the tooltip
2024-05-13 08:29:31 +10:00
d9ce9c62ac feat(ui): disable invoke button when t2i adapter used w/ image dims that are not multiples of 64 2024-05-13 08:29:31 +10:00
cdc468a38c Merge branch 'main' into psyche/fix/ui/depth-anything-select 2024-05-13 03:57:47 +05:30
2656f13a4a fix(ui): CA processor cancellation
When a control adapter processor config is changed, if we were already processing an image, that batch is immediately canceled. This prevents the processed image from getting stuck in a weird state if you change or reset the processor at the right (err, wrong?) moment.

- Update internal state for control adapters to track processor batches, instead of just having a flag indicating if the image is processing. Add a slice migration to not break the user's existing app state.
- Update preprocessor listener with more sophisticated logic to handle canceling the batch and resetting the processed image when the config changes or is reset.
- Fixed error handling that erroneously showed "failed to queue graph" errors when an active listener instance is canceled, need to check the abort signal.
2024-05-13 08:23:02 +10:00
da61396b1c cleanup: seamless unused older code cleanup 2024-05-13 08:11:08 +10:00
6c9fb617dc fix: fix seamless 2024-05-13 08:11:08 +10:00
5dd73fe53e fix(ui): jank in depthanything model size select 2024-05-10 09:52:30 +10:00
e6793be465 fix(ui): disable listening on CA and II layers
Closes #6331
2024-05-10 06:42:53 +10:00
63e62c5720 Update INSTALL_REQUIREMENTS.md - 'linux only' under AMD for SDXL.
Moved 'Linux only.' back from under NVIDIA to under AMD for the SDXL hardware requirements.
2024-05-09 10:56:23 -04:00
0848cb8ebd Update invokeai_version.py 2024-05-09 08:01:40 -04:00
1b777bb972 Revert "feat(ui): negative prompt boxes are italicized"
This reverts commit 49c4704379.
2024-05-09 07:52:52 -04:00
029ee90351 docs(ui): add comment & TODO for konva bug 2024-05-09 07:52:52 -04:00
2f9a064d48 feat(ui): ip adapter layers are selectable
This is largely an internal change, and it should have been this way from the start - less tip-toeing around layer types. The user-facing change is when you click an IP Adapter layer, it is highlighted. That's it.
2024-05-09 07:52:52 -04:00
b180666497 feat(ui): disable spellcheck on prompt boxes
These are almost guaranteed to have non-english words - disable the spellcheck to prevent red squigglies.
2024-05-09 07:52:52 -04:00
4740cd4f64 feat(ui): add "global" to global prompt placeholders 2024-05-09 07:52:52 -04:00
8b51298ba1 feat(ui): negative prompt boxes are italicized 2024-05-09 07:52:52 -04:00
1533429e54 feat(ui): optimized empty mask logic
Turns out, it's more efficient to just use the bbox logic for empty mask calculations. We already track if if the bbox needs updating, so this calculation does minimal work.

The dedicated calculation wasn't able to use the bbox tracking so it ran far more often than the bbox calculation.

Removed the "fast" bbox calculation logic, bc the new logic means we are continually updating the bbox in the background - not only when the user switches to the move tool and/or selects a layer.

The bbox calculation logic is split out from the bbox rendering logic to support this.

Result - better perf overall, with the empty mask handling retained.
2024-05-09 07:52:52 -04:00
fc000214a5 feat(ui): check for transparency and clear masks if no pixel data
Mask vector data includes additive (brush, rect) shapes and subtractive (eraser) shapes. A different composite operation is used to draw a shape, depending on whether it is additive or subtractive.

This means that a mask may have vector objects, but once rendered, is _visually_ empty (fully transparent). The only way determine if a mask is visually empty is to render it and check every pixel.

When we generate and save layer metadata, these fully erased masks are still used. Generating with an empty mask is a no-op in the backend, so we want to avoid this and not pollute graphs/metadata.

Previously, we did that pixel-based when calculating the bbox, which we only did when using the move tool, and only for the selected layer.

This change introduces a simpler function to check if a mask is transparent, and if so, deletes all its objects to reset it. This allows us skip these no-op layers entirely.

This check is debounced to 300 ms, trailing edge only.
2024-05-09 07:52:52 -04:00
f631aea4ee fix(ui): skip RG layers with no mask
These do not need to be added to the graph or metadata, as they are no-ops on the backend.
2024-05-09 07:52:52 -04:00
32f4c1f966 fix(ui): memoize mouse event handlers
This prevents resetting the stage event handlers on every frame. Whoops!
2024-05-09 07:52:52 -04:00
adebe639e3 tidy(ui): remove errant console.logs 2024-05-09 07:52:52 -04:00
44280ed472 fix(ui): layer recall uses fresh ids
When layer metadata is stored, the layer IDs are included. When recalling the metadata, we need to assign fresh IDs, else we can end up with multiple layers with the same ID, which of course causes all sorts of issues.
2024-05-09 07:52:52 -04:00
cec8840038 fix(ui): handle disabled RG layers
Was missing a check for `layer.isEnabled`.
2024-05-09 07:52:52 -04:00
b48d4a049d bad implementation of diffusers folder download 2024-05-08 21:21:01 -07:00
fc7f484935 feat(ui): add data-testids to control layers components:
- Add Layer Menu Button: `control-layers-add-layer-menu-button`
- Delete All Layers Button: `control-layers-delete-all-layers-button`
- CL Layer List: `control-layers-layer-list`
- CL Canvas: `control-layers-canvas`
- Toggle Metadata Button: `toggle-show-metadata-button`
- Toggle Progress Button: `toggle-show-progress-button`
- Toggle Viewer Menu Button: `toggle-viewer-menu-button`
- Settings Tab Button: `generation-tab-settings-tab-button`
- Control Layers Tab Button: `generation-tab-control-layers-tab-button`
2024-05-09 07:03:13 +10:00
1aa7cd57c2 feat(ui): add invert brush scroll checkbox to control layers settings 2024-05-09 07:03:13 +10:00
722a91aedb fix(ui): canvas toolbar centering 2024-05-09 07:03:13 +10:00
03c24ca9cb lint fix 2024-05-08 15:49:37 -04:00
5820579237 switch to generation tab when someone sends to img2img 2024-05-08 15:49:37 -04:00
6c768bfe7e fix(ui): viewer toggle prevents progress toggle interaction 2024-05-08 08:39:18 -04:00
5ca794b94f feat(ui): show progress toggle on control layers toolbar 2024-05-08 08:39:18 -04:00
d20695260d feat(ui): open viewer on enqueue from generation tab 2024-05-08 08:39:18 -04:00
d8557d573b Revert "feat(ui): extend zod with a is typeguard` method"
This reverts commit 0f45933791.
2024-05-08 08:39:18 -04:00
6c1fd584d2 feat(ui): pre-CL control adapter metadata recall 2024-05-08 08:39:18 -04:00
e8e764be20 feat(ui): revise image viewer
- Viewer only exists on Generation tab
- Viewer defaults to open
- When clicking the Control Layers tab on the left panel, close the viewer (i.e. open the CL editor)
- Do not switch to editor when adding layers (this is handled by clicking the Control Layers tab)
- Do not open viewer when single-clicking images in gallery
- _Do_ open viewer when _double_-clicking images in gallery
- Do not change viewer state when switching between app tabs (this no longer makes sense; the viewer only exists on generation tab)
- Change the button to a drop down menu that states what you are currently doing, e.g. Viewing vs Editing
2024-05-08 08:39:18 -04:00
e8023c44b0 chore(ui): lint 2024-05-08 08:39:18 -04:00
a3a6449786 feat(ui): versioned control layers metadata 2024-05-08 08:39:18 -04:00
e9d2ffe3d7 fix(ui): process control image on recall if no processed image 2024-05-08 08:39:18 -04:00
23ad6fb730 feat(ui): handle missing images/models when recalling control layers 2024-05-08 08:39:18 -04:00
00f36cb491 tidy(ui): clean up control layers graph builder 2024-05-08 08:39:18 -04:00
3f489c92c8 feat(ui): handle initial image layers in control layers helper 2024-05-08 08:39:18 -04:00
f147f99bef feat(ui): better metadata labels for layers 2024-05-08 08:39:18 -04:00
6107e3d281 fix(ui): fix zControlAdapterBase schema weight 2024-05-08 08:39:18 -04:00
de33d6e647 fix(ui): metadata "Layers" -> "Layer" 2024-05-08 08:39:18 -04:00
e36e5871a1 chore(ui): lint 2024-05-08 08:39:18 -04:00
8b25c1a62e tidy(ui): remove extraneous metadata handlers 2024-05-08 08:39:18 -04:00
dfbd7eb1cf feat(ui): individual layer recall 2024-05-08 08:39:18 -04:00
b43b2714cc feat(ui): add fracturedjsonjs to pretty-serialize objects
In use on the metadata viewer - makes it sooo much easier on the eyes.
2024-05-08 08:39:18 -04:00
e537de2f6d feat(ui): layers recall
This still needs some finessing - needs logic depending on the tab...
2024-05-08 08:39:18 -04:00
ccd399e277 feat(ui): add getIsVisible to metadata handlers 2024-05-08 08:39:18 -04:00
bfad814862 fix(ui): fix IPAdapterConfigV2 schema weight 2024-05-08 08:39:18 -04:00
6e8b7f9421 feat(ui): write layers to metadata 2024-05-08 08:39:18 -04:00
e47629cbe7 feat(ui): add zod schema for layers array 2024-05-08 08:39:18 -04:00
e840de27ed feat(ui): extend zod with a is typeguard` method
Feels dangerous, but it's very handy.
2024-05-08 08:39:18 -04:00
8342f32f2e refactor(ui): rewrite all types as zod schemas
This change prepares for safe metadata recall.
2024-05-08 08:39:18 -04:00
a7aa529b99 tidy(ui): "imageName" -> "name" 2024-05-08 08:39:18 -04:00
4adc592657 feat(ui): move strength to init image layer
This further splits the control layers state into its own thing.
2024-05-07 11:02:16 +10:00
e8d60e8d83 fix(ui): image metadata viewer stuck when spamming hotkey 2024-05-07 11:02:16 +10:00
886f5c90a3 feat(ui): move img2img strength out of advanced on canvas 2024-05-07 11:02:16 +10:00
5e684c11f1 Update invokeai_version.py 2024-05-07 09:09:10 +10:00
72ce239592 revert(ui): remove floating viewer
There are unresolved platform-specific issues with this component, and its utility is debatable.

Should be easy to just revert this commit to add it back in the future if desired.
2024-05-06 19:00:07 -04:00
a826f8f8c5 fix(ui): show total layer count in control layers tab 2024-05-06 19:00:07 -04:00
b6c19a8e47 feat(ui): close viewer when adding a RG layer 2024-05-06 19:00:07 -04:00
67d6cf19c6 fix(ui): switch to viewer if auto-switch is enabled 2024-05-06 19:00:07 -04:00
a9bf651c69 chore(ui): bump all deps 2024-05-06 19:00:07 -04:00
3bd5d9a8e4 fix(ui): memoize FloatingImageViewer
Maybe this will fix @JPPhoto's issue?
2024-05-06 19:00:07 -04:00
6249982d82 fix(ui): stuck viewer when spamming toggle
There are a number of bugs with `framer-motion` that can result in sync issues with AnimatePresence and the conditionally rendered component.

You can see this if you rapidly click an accordion, occasionally it gets out of sync and is closed when it should be open.

This is a bigger problem with the viewer where the user may hold down the `z` key. It's trivial to get it to lock up.

For now, just remove the animation entirely.

Upstream issues for reference:
https://github.com/framer/motion/issues/2023
https://github.com/framer/motion/issues/2618
https://github.com/framer/motion/issues/2554
2024-05-06 19:00:07 -04:00
6b98dba71d chore(ui): lint 2024-05-06 08:55:32 -04:00
c0065a65a0 feat(ui): floating viewer always shows progress, never shows metadata 2024-05-06 08:55:32 -04:00
cce3144c74 feat(ui): add floating image viewer 2024-05-06 08:55:32 -04:00
aab152a7e9 fix(ui): track mouse out flags correctly 2024-05-06 08:55:32 -04:00
c5b948bc3f feat(ui): fade layer selection color 2024-05-06 08:55:32 -04:00
44ecddae2e feat(ui): style Settings/Control Layers tabs like tabs 2024-05-06 08:55:32 -04:00
26847895b9 fix(ui): update hotkeys for viewer 2024-05-06 08:55:32 -04:00
f211c95dbc move access token regex matching into download queue 2024-05-05 21:00:31 -04:00
8e5e9b53d6 Merge branch 'main' into lstein/feat/simple-mm2-api 2024-05-04 17:01:15 -04:00
e4a640f0a7 feat(ui): optimized rendering of selected layer
Instead of caching on every stroke, we can use a compositing rect when the layer is being drawn to improve performance.
2024-05-04 12:03:28 -04:00
b5b6a96d94 feat(ui): dynamic brush spacing
Scaled to 10% of brush size, clamped between 5px and 15px. This makes drawing feel a bit smoother, but maintains reasonable performance.
2024-05-04 12:03:28 -04:00
806a8f69c5 perf(ui): rerender of opacity sliders 2024-05-04 12:03:28 -04:00
ac0b9ba290 tidy(ui): $cursorPosition -> $lastCursorPos 2024-05-04 12:03:28 -04:00
7ca613d41c feat(ui): snap cursor pos when drawing rects
- Rects snap to stage edge when within a threshold (10 screen pixels)
- When mouse leaves stage, set last mousedown pos to null, preventing nonfunctional rect outlines

Partially addresses #6306.

There's a technical challenge to fully address the issue - mouse event are not fired when the mouse is outside the stage. While we could draw the rect even if the mouse leaves, we cannot update the rect's dimensions on mouse move, or complete the drawing on mouse up.

To fully address the issue, we'd need to a way to forward window events back to the stage, or at least handle window events. We can explore this later.
2024-05-04 12:03:28 -04:00
5cb1ff8679 fix(ui): open viewer on image click, not select 2024-05-04 12:03:28 -04:00
8794b99d51 fix(ui): save upscaled images to gallery on canvas tab 2024-05-03 23:15:10 -04:00
6bdded85da fix(ui): do not auto-hide next/prev image buttons 2024-05-03 23:15:10 -04:00
26613f10c7 feat(ui): close viewer when user switches tabs 2024-05-03 23:15:10 -04:00
6d2fe3b691 tidy(ui): clean up layer reset logic 2024-05-03 23:15:10 -04:00
2888845f7c fix(ui): invalidate mask cache when moving layer 2024-05-03 23:15:10 -04:00
4beccea6e7 fix(ui): do not run HRO if using an initial image 2024-05-03 23:15:10 -04:00
68d1458c83 fix(ui): address feedback 2024-05-04 08:40:12 +10:00
f4dde883ca feat: improve the switch states of the control layers / viewer area 2024-05-04 08:40:12 +10:00
e9a20051bd refactor DWOpenPose and add type hints 2024-05-03 18:08:53 -04:00
be7eeb576b fix(ui): fix viewer getting stuck when spamming toggle 2024-05-03 20:57:18 +10:00
af9f0e0963 feat(ui): cache control layer mask images
When invoking with control layers, we were creating and uploading the mask images on every enqueue, even when the mask didn't change. The mask image can be cached to greatly reduce the number of uploads.

With this change, we are a bit smarter about the mask images:
- Check if there is an uploaded mask image name
- If so, attempt to retrieve its DTO. Typically it will be in the RTKQ cache, so there is no network request, but it will make a network request if not cached to confirm the image actually exists on the server.
- If we don't have an uploaded mask image name, or the request fails, we go ahead and upload the generated blob
- Update the layer's state with a reference to this uploaded image for next time
- Continue as before

Any time we modify the mask (drawing/erasing, resetting the layer), we invalidate that cached image name (set it to null).

We now only upload images when we need to and generation starts faster.
2024-05-03 20:57:18 +10:00
3cba53533d Update README.md 2024-05-03 17:31:50 +10:00
ab87511a03 Update INSTALLATION.md 2024-05-03 17:31:50 +10:00
af868b0ea6 Update 010_INSTALL_AUTOMATED.md 2024-05-03 17:31:50 +10:00
960eae8255 Update TRAINING.md 2024-05-03 17:30:42 +10:00
0787c6c746 Update invokeai_version.py 2024-05-03 13:23:19 +10:00
579d436934 fix(ui): floating param/gallery buttons 2024-05-02 23:09:26 -04:00
36f01988e8 chore(ui): lint 2024-05-02 23:09:26 -04:00
d9b92d19f9 feat(ui): clearer viewer/editor context switching 2024-05-02 23:09:26 -04:00
fdfc379a84 fix(ui): layer counts 2024-05-02 23:09:26 -04:00
2062cfe84a fix(ui): cursor when no renderable layers added 2024-05-02 23:09:26 -04:00
eb36e834b2 feat(ui): add fallback when no layers exist 2024-05-02 23:09:26 -04:00
2baa33730a fix(ui): fix control layer list layout 2024-05-02 23:09:26 -04:00
c30df7ce79 feat(ui): style settings/control layers tabs 2024-05-02 23:09:26 -04:00
f05ac5a7a5 chore(ui): bump @invoke-ai/ui-library 2024-05-02 23:09:26 -04:00
85dd78b8df fix(ui): handle deleting images in use in generation tab 2024-05-02 23:09:26 -04:00
4c7be03702 tidy(ui): rename generation tab graph builders 2024-05-02 23:09:26 -04:00
e354fee4f4 fix(ui): add img2img metadata to graphs 2024-05-02 23:09:26 -04:00
20e628297c fix(ui): smoother animations in current image preview 2024-05-02 23:09:26 -04:00
98664fc46f fix(ui): gallery prev/next buttons animations 2024-05-02 23:09:26 -04:00
33617fc06a feat(ui): rework image viewer
- Rework styling
- Replace "CurrentImageDisplay" entirely
- Add a super short fade to reduce jarring transition
- Make the viewer a singleton component, overlaid on everything else - reduces change when switching tabs
2024-05-02 23:09:26 -04:00
c05e52ebae fix(ui): do not delete all layers when using image as initial image 2024-05-02 23:09:26 -04:00
5734a97c55 fix(ui): do not attempt drawing when invalid layer type selected 2024-05-02 23:09:26 -04:00
94a73d5377 feat(ui): update mm-related translations 2024-05-02 23:09:26 -04:00
0f7fdabe9b feat(ui): rename tab identifiers
- "txt2img" -> "generation"
- "unifiedCanvas" -> "canvas"
- "modelManager" -> "models"
- "nodes" -> "workflows"
- Add UI slice migration setting the active tab to "generation"
2024-05-02 23:09:26 -04:00
7c1f1076b4 feat(ui): rename tabs
- "Text to Image" -> "Generation"
- "Unified Canvas" -> "Canvas"
- "Model Manager" -> "Models"
2024-05-02 23:09:26 -04:00
a6ac184211 tidy(ui): excise img2img tab 2024-05-02 23:09:26 -04:00
7d58908e32 fix(ui): fix img2img graphs w/ control layers 2024-05-02 23:09:26 -04:00
26d3ec3fce fix(ui): destroy initial image layer after deleting 2024-05-02 23:09:26 -04:00
dc81357152 feat(ui): add img2img via control layers to graph builders 2024-05-02 23:09:26 -04:00
c9886796f6 feat(ui): add image viewer overlay
- Works on txt2img, canvas and workflows tabs, img2img has its own side-by-side view
- In workflow editor, the is closeable only if you are in edit mode, else it's always there
- Press `i` to open
- Press `esc` to close
- Selecting an image or changing image selection opens the viewer
- When generating, if auto-switch to new image is enabled, the viewer opens when an image comes in

To support this change, I organized and restructured some tab stuff.
2024-05-02 23:09:26 -04:00
209ddc2037 fix(ui): do not toggle layers on double click of opacity popover 2024-05-02 23:09:26 -04:00
8b6a283eab feat(ui): add opacity to initial image layer 2024-05-02 23:09:26 -04:00
75be6814bb feat(ui): add renderer for initial image 2024-05-02 23:09:26 -04:00
1d213067e8 feat(ui): add initial image layer to CL 2024-05-02 23:09:26 -04:00
d67480d92c feat(ui): add layerwrapper component 2024-05-02 23:09:26 -04:00
d55ea318ec tidy(ui): remove unused gallery hotkeys 2024-05-02 23:09:26 -04:00
474eab6f8a fix(ui): clamp incoming w/h to ensure always a multiple of 8
When recalling metadata and/or using control image dimensions, it was possible to set a width or height that was not a multiple of 8, resulting in generation failures.

Added a `clamp` option to the w/h actions to fix this. The option is used for all untrusted sources - everything except for the w/h number inputs, which clamp the values themselves.
2024-05-02 23:09:26 -04:00
1b13fee256 fix(ui): firefox drawing lag
Firefox v125.0.3 and below has a bug where `mouseenter` events are fired continually during mouse moves. The issue isn't present on FF v126.0b6 Developer Edition. It's not clear if the issue is present on FF nightly, and we're not sure if it will actually be fixed in the stable v126 release.

The control layers drawing logic relied on on `mouseenter` events to create new lines, and `mousemove` to extend existing lines. On the affected version of FF, all line extensions are turned into new lines, resulting in very poor performance, noncontiguous lines, and way-too-big internal state.

To resolve this, the drawing handling was updated to not use `mouseenter` at all. As a bonus, resolving this issue has resulted in simpler logic for drawing on the canvas.
2024-05-02 23:09:26 -04:00
6363095b29 feat(ui): control adapter recall for control layers
- Add set of metadata handlers for the control layers CAs
- Use these conditionally depending on the active tab - when recalling on txt2img, the CAs go to control layers, else they go to the old CA area.
2024-05-02 23:09:26 -04:00
4cd78b9478 feat(ui): add getImageDTO imperative RTKQ helper 2024-05-02 23:09:26 -04:00
2cde8a643e tidy(ui): suffix a control adapter types/objects with V2
Prevent mixing the old and new implementations up
2024-05-02 23:09:26 -04:00
f9555f03f5 tidy(ui): "CONTROLNET_PROCESSORS" -> "CA_PROCESSOR_DATA" 2024-05-02 23:09:26 -04:00
b1d8f3a3f9 tidy(ui): revert changes to old CA implementation
These changes were left over from the previous attempt to handle control adapters in control layers with the same logic. Control Layers are now handled totally separately, so these changes may be reverted.
2024-05-02 23:09:26 -04:00
38df6f3702 fix ruff error 2024-05-02 21:22:33 -04:00
3b64e7a1fd Merge branch 'main' into lstein/feat/simple-mm2-api 2024-05-02 21:20:35 -04:00
33a9f9a4dc fix(nodes): fix constraints in cnet processors
There were some invalid constraints with the processors - minimum of 0 for resolution or multiple of 64 for resolution.

Made minimum 1px and no multiple ofs.
2024-05-02 12:24:04 +10:00
c35625eb44 feat(ui): processor layout changes 2024-05-01 21:48:47 -04:00
6f572e1cce fix(ui): convert t2i to cnet and vice-versa when model changes 2024-05-01 21:48:47 -04:00
54acd3f2b1 ci(ui): restore error status for circular deps 2024-05-01 21:48:47 -04:00
6e966909ab chore(ui): lint 2024-05-01 21:48:47 -04:00
311ba8c04b fix(ui): ensure canvas size is correctly updated when model changed
Closes #6293
2024-05-01 21:48:47 -04:00
1b617768cf fix(ui): canvas infinite loop when setting bbox dims
When typing in a number into the w/h number inputs, if the number is less than the step, it appears the value of 0 is used. This is unexpected; it means Chakra isn't clamping the value correctly (or maybe our wrapper isn't clamping it).

Add checks to never bail if the width or height value from the number input component is 0.
2024-05-01 21:48:47 -04:00
8ceb94497e fix(ui): fix canvas rendering of control images 2024-05-01 21:48:47 -04:00
efb571401c feat(ui): tweak control adapter layout 2024-05-01 21:48:47 -04:00
ffba4871d0 tidy(ui): "scribble" -> "Scribble" 2024-05-01 21:48:47 -04:00
9437d701b2 fix(ui): disable clear processor when no processor selected 2024-05-01 21:48:47 -04:00
6effa19626 fix(ui): edge cases in auto-process 2024-05-01 21:48:47 -04:00
45c2ac41d5 feat(ui): processor layout/styling 2024-05-01 21:48:47 -04:00
ca1c3c0873 fix(ui): do not re-process if processor config hasn't changed 2024-05-01 21:48:47 -04:00
47ee08db91 fix(ui): processor select styling 2024-05-01 21:48:47 -04:00
c96b98fc9e feat(ui): auto-process for control layer CAs 2024-05-01 21:48:47 -04:00
905baf2787 refactor(ui): continue wiring up CA logic across (wip)
It works!
2024-05-01 21:48:47 -04:00
0e55488ff6 refactor(ui): wire up CA logic across (wip) 2024-05-01 21:48:47 -04:00
424a27eeda refactor(ui): add CA processor config components (wip) 2024-05-01 21:48:47 -04:00
6007218a51 refactor(ui): add CA config components (wip) 2024-05-01 21:48:47 -04:00
811e8a5a8b refactor(ui): rename & export actions from CL slice 2024-05-01 21:48:47 -04:00
121918352a refactor(ui): add control layers separate control adapter implementation (wip)
- Revise control adapter config types
- Recreate all control adapter mutations in control layers slice
- Bit of renaming along the way - typing 'RegionalGuidanceLayer' over and over again was getting tedious
2024-05-01 21:48:47 -04:00
3717321480 tidy(ui): organize layer components 2024-05-01 21:48:47 -04:00
4a250bdf9c Add TCD scheduler (#6086)
Adds the TCD scheduler to better support.
https://huggingface.co/h1t/TCD-SDXL-LoRA or checkpoints that have been
made with TCD

Example:
TCD Lora with Euler A

![b0ad6174-cd2b-49fe-ae42-3a83bc6ae571](https://github.com/invoke-ai/InvokeAI/assets/82827604/d823cb2f-4d9c-4f93-9fc2-e63773a378b6)

TCD Lora with TCD scheduler

![74495a51-eeac-45e6-9983-fb6551a5bdef](https://github.com/invoke-ai/InvokeAI/assets/82827604/c87604d8-a44e-4fb9-a7be-ef2600784727)
2024-05-01 12:57:01 +05:30
dce8b88aaf fix: change eta only for TCD Scheduler 2024-05-01 12:47:46 +05:30
1bdcbe3284 cleanup: use dict update to actually update the scheduler keyword args 2024-05-01 12:22:39 +05:30
49c84cd423 Merge branch 'main' into lstein/feat/simple-mm2-api 2024-04-30 18:13:42 -04:00
88ac3bc7f0 Merge branch 'main' into main 2024-04-30 16:51:44 -04:00
abb3bb9f7e Update invokeai_version.py 2024-05-01 06:30:28 +10:00
2ddb82200c fix: Manually update eta(gamma) to 1.0 for TCDScheduler
seems to work best with invoke at 4 steps
2024-05-01 01:20:53 +05:30
38880cde5c chore: update schema 2024-05-01 01:20:22 +05:30
39ab4dd83e Merge branch 'main' into pr/6086 2024-05-01 00:37:06 +05:30
631878b212 feat(ui): border radius on canvas 2024-04-30 08:10:59 -04:00
7a5399e83c feat(ui): display message when no layers are added 2024-04-30 08:10:59 -04:00
e90775731d fix(ui): layer layout orientation 2024-04-30 08:10:59 -04:00
3f26880493 fix(ui): "Global Settings" -> "Settings" 2024-04-30 08:10:59 -04:00
21cf1004db fix(ui): layers default to expanded 2024-04-30 08:10:59 -04:00
d74cd12aa6 feat(ui): collapsible layers 2024-04-30 08:10:59 -04:00
cf1883585d chore(ui): lint 2024-04-30 08:10:59 -04:00
8a791d4f16 feat(ui): make control image opacity filter toggleable 2024-04-30 08:10:59 -04:00
1212698059 tidy(ui): more renaming of components 2024-04-30 08:10:59 -04:00
ba6db33b39 tidy(ui): more renaming of components 2024-04-30 08:10:59 -04:00
b3dbfdaa02 tidy(ui): more renaming of components 2024-04-30 08:10:59 -04:00
3441187c23 tidy(ui): "regional prompts" -> "control layers" 2024-04-30 08:10:59 -04:00
8de56fd77c tidy(ui): move regionalPrompts files to controlLayers 2024-04-30 08:10:59 -04:00
22bd33b7c6 chore(ui): lint 2024-04-30 08:10:59 -04:00
2af5c4be9f fix(ui): ip adapter layers are not selectable 2024-04-30 08:10:59 -04:00
415a41e21a perf(ui): reset maskobjects when layer has no bbox (all objects erased) 2024-04-30 08:10:59 -04:00
aa2ca03056 fix(ui): filter layers based on tab when disabling invoke button 2024-04-30 08:10:59 -04:00
a20faca20f feat(ui): layer layout tweaks 2024-04-30 08:10:59 -04:00
9d042baf48 fix(ui): ip adapter layers always at bottom of list 2024-04-30 08:10:59 -04:00
6195741814 feat(ui): move global mask opacity to settings popover 2024-04-30 08:10:59 -04:00
c2f8adf93e fix(ui): deselect other layers when new layer added 2024-04-30 08:10:59 -04:00
ace3955760 fix(ui): tool preview/cursor when non-interactable layer selected 2024-04-30 08:10:59 -04:00
720e16cea6 feat(ui): tweak layer list styling to better indicate selectablility 2024-04-30 08:10:59 -04:00
a357a1ac9d feat(ui): remove select layer on click in canvas
It's very easy to end up in a spot where you cannot select a layer at all to move it around. Too tricky to handle otherwise.
2024-04-30 08:10:59 -04:00
22f160bfcc fix(ui): unlink control adapter opaicty from global mask opacity 2024-04-30 08:10:59 -04:00
fa637b5c59 fix(ui): add missed ca layer opacity logic
didn't stage the right changes a few commits back
2024-04-30 08:10:59 -04:00
1f68a60752 feat(ui): hold shift to use control image size w/o model constraints 2024-04-30 08:10:59 -04:00
048bd18e10 feat(ui): separate ca layer opacity 2024-04-30 08:10:59 -04:00
e5ec529f0f feat(ui): fix layer arranging 2024-04-30 08:10:59 -04:00
d884c15d0c feat(ui): update layer menus 2024-04-30 08:10:59 -04:00
9ee7cad613 feat(ui): make control layer ui exclusive to txt2img tab 2024-04-30 08:10:59 -04:00
629110784d fix(ui): delete control layers correctly 2024-04-30 08:10:59 -04:00
c1666a8b5a fix(ui): select default control/ip adapter models in control layers 2024-04-30 08:10:59 -04:00
d14b315bc6 fix(ui): use optimal size when using control image dims 2024-04-30 08:10:59 -04:00
fe459295ea fix(ui): exclude disabled control adapters on control layers 2024-04-30 08:10:59 -04:00
9d67ec9efe fix(ui): toggle control adapter layer vis 2024-04-30 08:10:59 -04:00
5bf4d37949 perf(ui): reduce control image processing to when it is needed
Only should reprocess if the processor settings or the image has changed.
2024-04-30 08:10:59 -04:00
387ab9cee7 feat(ui): reset controlnet model to null instead of disabling when base model changes 2024-04-30 08:10:59 -04:00
56050f7887 fix(ui): fix canvas scaling when window is zoomed
Konva doesn't react to changes to window zoom/scale. If you open the tab at, say, 90%, then bump to 100%, the pixel ratio of the canvas doesn't change. This results in lower-quality renders on the canvas (generation is unaffected).
2024-04-30 08:10:59 -04:00
c354470cd1 perf(ui): do not cache controlnet images unless required 2024-04-30 08:10:59 -04:00
ded8267505 WIP control adapters in regional 2024-04-30 08:10:59 -04:00
e822897b1c feat(nodes): add prototype heuristic image resize node
Uses the fancy cnet resize that retains edges.
2024-04-30 08:10:59 -04:00
2d7b8c2a1b fix(backend): do not round image dims to 64 in controlnet processor resize
Rounding the dims results in control images that are subtly different than the input. We round to the nearest 8px later, there's no need to round now.
2024-04-30 08:10:59 -04:00
ebeae41cb2 tidy(ui): minor ca component tidy 2024-04-30 08:10:59 -04:00
6f5f3381f9 feat(ui): revise internal state for RCC 2024-04-30 08:10:59 -04:00
2f6fec8c6c chore(ui): lint 2024-04-30 08:10:59 -04:00
cc4bef4859 refactor(ui): move size state to regional 2024-04-30 08:10:59 -04:00
b6a45e53f1 refactor(ui): move positive2 and negative2 prompt to regional 2024-04-30 08:10:59 -04:00
1cf1e53a6c refactor(ui): move positive and negative prompt to regional 2024-04-30 08:10:59 -04:00
c686625076 feat(ui): add 'control_layer' type 2024-04-30 08:10:59 -04:00
d861bc690e feat(mm): handle PC_PATH_MAX on external drives on macOS
`PC_PATH_MAX` doesn't exist for (some?) external drives on macOS. We need error handling when retrieving this value.

Also added error handling for `PC_NAME_MAX` just in case. This does work for me for external drives on macOS, though.

Closes #6277
2024-04-30 07:57:03 -04:00
1fe90c357c feat(backend): lift managed model loading out of depthanything class 2024-04-29 08:56:00 +10:00
fcb071f30c feat(backend): lift managed model loading out of lama class 2024-04-29 08:12:51 +10:00
57c831442e fix safe_filename() on windows 2024-04-28 14:42:40 -04:00
f65c7e2bfd Merge branch 'main' into lstein/feat/simple-mm2-api 2024-04-28 13:42:54 -04:00
7c39929758 support VRAM caching of dict models that lack to() 2024-04-28 13:41:06 -04:00
f262b9032d fix: changed validation to not error on connection 2024-04-28 12:48:56 -04:00
71c3197eab fix: denoise latents accepts CFG lists as input 2024-04-28 12:48:56 -04:00
a26667d3ca make download and convert cache keys safe for filename length 2024-04-28 12:24:36 -04:00
bb04f496e0 Merge branch 'main' into lstein/feat/simple-mm2-api 2024-04-28 11:33:26 -04:00
70903ef057 refactor load_ckpt_from_url() 2024-04-28 11:33:23 -04:00
241a1fdb57 feat(mm): support sdxl ckpt inpainting models
There are only a couple SDXL inpainting models, and my tests indicate they are not as good as SD1.5 inpainting, but at least we support them now.

- Add the config file. This matches what is used in A1111. The only difference from the non-inpainting SDXL config is the number of in-channels.
- Update the legacy config maps to use this config file.
2024-04-28 12:57:27 +10:00
3595beac1e docs: remove references to config script in CONFIGURATION.md 2024-04-25 17:49:32 -04:00
caa7c0f2bd docs: more pruning and tidying readme 2024-04-26 00:00:18 +10:00
d546823c4d docs: pruning and tidying readme 2024-04-26 00:00:18 +10:00
dac2d78da6 Update README.md 2024-04-26 00:00:18 +10:00
d72f272f16 Address change requests in first round of PR reviews.
Pending:

- Move model install calls into model manager and create passthrus in invocation_context.
- Consider splitting load_model_from_url() into a call to get the path and a call to load the path.
2024-04-24 23:53:30 -04:00
398f37c0ed tidy(backend): clean up controlnet_utils
- Use the our adaptation of the HWC3 function with better types
- Extraction some of the util functions, name them better, add comments
- Improve type annotations
- Remove unreachable codepaths
2024-04-25 13:20:09 +10:00
6b0bf59682 feat(backend): update nms util to make blur/thresholding optional 2024-04-25 13:20:09 +10:00
5b8f77f990 tidy(nodes): move cnet mode literals to utils
Now they can be used in type signatures without circular imports.
2024-04-25 13:20:09 +10:00
3207822738 Update invokeai_version.py 2024-04-25 12:31:59 +10:00
8d86fabf4b chore(ui): lint 2024-04-24 20:09:52 +10:00
af3e910ad3 fix(ui): fix layer arrangement 2024-04-24 20:09:52 +10:00
af25d00964 tidy(ui): use const for brush spacing 2024-04-24 20:09:52 +10:00
d4a30d08ef feat(ui): create new line when mouse held down, leaves canvas and comes back over 2024-04-24 20:09:52 +10:00
bd8a33e824 tidy(ui): clean up renderer functions
- Split logic to create layers/objects from the updating logic
- Organize and comment functions
2024-04-24 20:09:52 +10:00
b425646b7b chore(ui): lint 2024-04-24 20:09:52 +10:00
293e11cfa6 feat(ui): hide add prompt buttons when user has a prompt 2024-04-24 20:09:52 +10:00
c73aabdfbf feat(ui): regional control defaults to having a positive prompt 2024-04-24 20:09:52 +10:00
ca989c54b0 fix(ui): restore OG aspect ratio preview for non-t2i tabs 2024-04-24 20:09:52 +10:00
260e24733f fix: update SDXL IP Adpater starter model to be ViT-H 2024-04-24 00:08:21 -04:00
bb6e3e726d fix: update ip adapter starter models path (#6262)
## Summary

<!--A description of the changes in this PR. Include the kind of change
(fix, feature, docs, etc), the "why" and the "how". Screenshots or
videos are useful for frontend changes.-->

## Related Issues / Discussions

<!--WHEN APPLICABLE: List any related issues or discussions on github or
discord. If this PR closes an issue, please use the "Closes #1234"
format, so that the issue will be automatically closed when the PR
merges.-->

## QA Instructions

<!--WHEN APPLICABLE: Describe how we can test the changes in this PR.-->

## Merge Plan

<!--WHEN APPLICABLE: Large PRs, or PRs that touch sensitive things like
DB schemas, may need some care when merging. For example, a careful
rebase by the change author, timing to not interfere with a pending
release, or a message to contributors on discord after merging.-->

## Checklist

- [ ] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-04-24 08:58:15 +05:30
6b394554e2 fix: update ip adapter starter models path 2024-04-24 08:48:25 +05:30
ae1955a1a8 feat(ui): update canvas graphs to provide unet 2024-04-23 07:32:53 -04:00
1bef13db37 feat(nodes): restore unet check on CreateGradientMaskInvocation
Special handling for inpainting models
2024-04-23 07:32:53 -04:00
a461537087 chore: ruff 2024-04-23 07:32:53 -04:00
99e28da19b feat(ui): add variant to model edit
Also simplify the layouting for all model view/edit components.
2024-04-23 07:32:53 -04:00
42a159beaa chore(ui): typegen 2024-04-23 07:32:53 -04:00
0aa5aadfe8 fix(mm): move variant to MainConfigBase
shoulda been here all along
2024-04-23 07:32:53 -04:00
2537d260e3 tests: add test for probing diffusers model variant type 2024-04-23 07:32:53 -04:00
bbf919a933 chore: frontend check error 2024-04-23 07:32:53 -04:00
01897ec576 remove extra inputs 2024-04-23 07:32:53 -04:00
bc12d6654e chore: comments and ruff 2024-04-23 07:32:53 -04:00
6d7c8d5f57 remove unet test 2024-04-23 07:32:53 -04:00
38604aa408 update canvas graphs 2024-04-23 07:32:53 -04:00
781de914f4 fix threshhold 2024-04-23 07:32:53 -04:00
c094bad233 add unet check in gradient mask node 2024-04-23 07:32:53 -04:00
0063014f2b gradient mask node test for inpaint 2024-04-23 07:32:53 -04:00
d7b5ad02e8 tests: add object serializer test for dangling folders
- Ensure they are deleted on init if ephemeral
- Ensure they are _not_ deleted on init if _not_ ephemeral
2024-04-23 17:12:14 +10:00
2cee436ecf tidy(app): remove unused class 2024-04-23 17:12:14 +10:00
e6386d969f fix(app): only clear tempdirs if ephemeral and before creating tempdir
Also, this needs to happen in init, else it deletes the temp dir created in init
2024-04-23 17:12:14 +10:00
4b2b983646 tidy(api): reverted unnecessary changes in dependencies.py 2024-04-23 17:12:14 +10:00
53808149fb moved cleanup routine into object_serializer_disk.py 2024-04-23 17:12:14 +10:00
21ba55d0a6 add an initialization function that removes dangling tmpdirs from outputs/tensors 2024-04-23 17:12:14 +10:00
28c28b2fc0 fix: 🐛 handle trigger phrase form submits 2024-04-23 16:42:40 +10:00
8b9c4c62a6 chore: v4.2.0a2 2024-04-23 13:08:26 +10:00
cf637ecaa6 fix(ui): disabled ip adapters applied to regional control 2024-04-23 13:08:26 +10:00
fca718bdd3 tidy(ui): remove extraneous cursor sync 2024-04-23 12:11:47 +10:00
5196a2efec fix(ui): minor canvas overflow 2024-04-23 12:11:47 +10:00
385e93443a feat(ui): rp hotkeys
- Shift+C: Reset selected layer mask (same as canvas)
- Shift+D: Delete selected layer (cannot be Del, that deletes an image in gallery)
- Shift+A: Add layer (cannot be Ctrl+Shift+N, that opens a new window)
- Ctrl/Cmd+Wheel: Brush size (same as canvas)
2024-04-23 12:11:47 +10:00
604217313a chore(ui): lint 2024-04-23 12:11:47 +10:00
229423b370 tidy(ui): memo aspectratiopreview 2024-04-23 12:11:47 +10:00
75a548e3eb perf(ui): debounce render wait = 300ms 2024-04-23 12:11:47 +10:00
24dbb65ebb perf(ui): add brush spacing
Only add point to line if the next point is 10 or more px from the last point
2024-04-23 12:11:47 +10:00
c915220965 feat(ui): aspect ratio preview is regional prompts canvas 2024-04-23 12:11:47 +10:00
bb37e25ed0 feat(ui): rp ui layout 2024-04-23 12:11:47 +10:00
dda1111f20 Make it alpha 2024-04-22 10:54:21 -04:00
9d71b91b7f chore: v4.2.0b1 2024-04-22 10:54:21 -04:00
714126b832 build(ui): temp disable circular dependency check
I'll need to think about how to fix this properly. For now, disable the check as the UI can still build fine.
2024-04-22 23:09:39 +10:00
a10c66797d chore(ui): lint 2024-04-22 23:09:39 +10:00
6dcaf75b5f feat(ui): regional prompts spray n pray
Trying a lot of different things as I iterated, so this is smooshed into one big commit... too hard to split it now.

- Iterated on IP adapter handling and UI. Unfortunately there is an bug related to undo/redo. The IP adapter state is split across the `controlAdapters` slice and the `regionalPrompts` slice, but only the `regionalPrompts` slice supports undo/redo. If you delete the IP adapter and then undo/redo to a history state where it existed, you'll get an error. The fix is likely to merge the slices... Maybe there's a workaround.
- Iterated on UI. I think the layers are OK now.
- Removed ability to disable RP globally for now. It's enabled if you have enabled RP layers.
- Many minor tweaks and fixes.
2024-04-22 23:09:39 +10:00
018845cda0 tidy(ui): regional prompts kind -> type 2024-04-22 23:09:39 +10:00
8c0a061fa0 fix(ui): hotkeys dependency array 2024-04-20 11:32:08 -04:00
4895875ded feat(ui): rects on regional prompt UI 2024-04-20 11:32:08 -04:00
cfddbda578 tidy(ui): clean up action names 2024-04-20 11:32:08 -04:00
58d3a9e7d4 refactor(ui): revise regional prompts state to support prompt-less mask layers
This structure is more adaptable to future features like IP-Adapter-only regions, controlnet layers, image masks, etc.
2024-04-20 11:32:08 -04:00
a00e703144 feat(nodes): image mask to tensor invocation
Thanks @JPPhoto!
2024-04-20 11:32:08 -04:00
e4024bdeb9 fix(ui): floor all pixel coords
This prevents rendering objects with sub-pixel positioning, which looks soft
2024-04-20 11:32:08 -04:00
944690ac8e feat(ui): remove drag distance on layers 2024-04-20 11:32:08 -04:00
a7d69aa0a9 fix(ui): brush preview cursor jank 2024-04-20 11:32:08 -04:00
15018fdbc0 fix(ui): brush preview not visible after hotkey 2024-04-20 11:32:08 -04:00
31ace9aff8 feat(ui): tool hotkeys for rp 2024-04-20 11:32:08 -04:00
3f4ea30113 fix(ui): fix missing bbox when a layer is empty 2024-04-20 11:32:08 -04:00
7edcadb371 fix(ui): bbox rendered slightly too small 2024-04-20 11:32:08 -04:00
d582203c62 chore(ui): lint 2024-04-20 14:54:49 +10:00
148a6c08ca fix(ui): fix bbox caching 2024-04-20 14:54:49 +10:00
1e904d281a feat(ui): hook up sd1.5 t2i graph to regional prompts 2024-04-20 14:54:49 +10:00
03d9a75720 feat(ui): better rp colors 2024-04-20 14:54:49 +10:00
5edce0a4de perf(ui): caching efficiency 2024-04-20 14:54:49 +10:00
604bf4e9ec perf(ui): use efficient group caching instead of a compositing rect
Seems to be the same speed and it's less complex.
2024-04-20 14:54:49 +10:00
39d036bb37 feat(ui): update move tool to show all bboxes, mouseover bbox strokes 2024-04-20 14:54:49 +10:00
8a69fbd336 perf(ui): more bbox optimizations
- Keep track of whether the bbox needs to be recalculated (e.g. had lines/points added)
- Keep track of whether the bbox has eraser strokes - if yes, we need to do the full pixel-perfect bbox calculation, otherwise we can use the faster getClientRect
- Use comparison rather than Math.min/max in bbox calculation (slightly faster)
- Return `null` if no pixel data at all in bbox
2024-04-20 14:54:49 +10:00
a71ed10b71 perf(ui): more efficient bbox method with smaller minimum offscreen canvas size 2024-04-20 14:54:49 +10:00
9d3978edcf fix(ui): give min dimensions to rp storybook 2024-04-20 14:54:49 +10:00
18e1d74917 fix(ui): group layer color change history 2024-04-20 14:54:49 +10:00
9276ecfd02 feat(ui): rp ui styling/layout 2024-04-19 09:32:56 -04:00
ea527f5fe1 feat(nodes): add beta classification to mask tensor nodes 2024-04-19 09:32:56 -04:00
d43f9732ab feat(ui): rp ui styling 2024-04-19 09:32:56 -04:00
c613839740 feat(ui): use translations for rp features 2024-04-19 09:32:56 -04:00
bb371cfeca feat(ui): minor styling rp 2024-04-19 09:32:56 -04:00
6a5510146c feat(ui): add default rp brush size 2024-04-19 09:32:56 -04:00
9667f77c41 feat(ui): rp editor styling 2024-04-19 09:32:56 -04:00
e93e0612af tidy(ui): selectedLayer -> selectedLayerId 2024-04-19 09:32:56 -04:00
9528287d56 feat(ui): move ephemeral tool state out of redux 2024-04-19 09:32:56 -04:00
14c722c265 tidy(ui): remove unused conditional 2024-04-19 09:32:56 -04:00
4b2cd2da9f feat(ui): remove special handling of main prompt
Until we have a good handle on what works best, leaving this to the user
2024-04-19 09:32:56 -04:00
3c5b728bee feat(ui): add enabled state for RP 2024-04-19 09:32:56 -04:00
9b5c47748d tidy(ui): isRegionalPromptLayer -> isRPLayer 2024-04-19 09:32:56 -04:00
eb781272f7 tidy(ui): organize rp layer components 2024-04-19 09:32:56 -04:00
642a0de3dd feat(ui): organize layer naming
prep for non-rp layer types
2024-04-19 09:32:56 -04:00
f3b4cecf2e feat(ui): invert tensor mask instead of loading mask image and converting to tensor second time
minor efficiency improvement
2024-04-19 09:32:56 -04:00
499e7a7b74 chore(ui): typegen 2024-04-19 09:32:56 -04:00
aace364677 feat(nodes): add InvertTensorMaskInvocation 2024-04-19 09:32:56 -04:00
c195094e91 fix(ui): do not open panels when collapsed and window resize 2024-04-19 09:32:56 -04:00
e6c57edf87 tidy(ui): shuffle graph builder logic 2024-04-19 09:32:56 -04:00
c217e052a8 tidy(ui): remove unused action 2024-04-19 09:32:56 -04:00
964e2236b9 feat(ui): do not add promptless conditioning nodes 2024-04-19 09:32:56 -04:00
a6e64423d9 feat(ui): per-layer autonegative 2024-04-19 09:32:56 -04:00
d3aa97ab99 feat(ui): add copy graph button to queue item detail view 2024-04-19 09:32:56 -04:00
0d8edd67ab fix(ui): group lines together in undo history 2024-04-19 09:32:56 -04:00
d9dd00ea20 feat(ui): undo/redo in regional prompts
using the `redux-undo` library
2024-04-19 09:32:56 -04:00
170763899a tidy(ui): tidy regional prompts graph helper, add comments 2024-04-19 09:32:56 -04:00
9e1a4a4a07 feat(ui): regional prompts default layer opacity 2024-04-19 09:32:56 -04:00
dcb4a40741 fix(ui): regional prompts brush preview wonkiness 2024-04-19 09:32:56 -04:00
f8bf985256 perf(ui): do not recreate map callback on every render 2024-04-19 09:32:56 -04:00
81f29b9624 tidy(ui): remove errant console.log 2024-04-19 09:32:56 -04:00
f2dde9a035 feat(ui): cleared selected layer styling 2024-04-19 09:32:56 -04:00
85f4a066fb feat(ui): use logger for stage renderer 2024-04-19 09:32:56 -04:00
b9e6b7ba48 feat(ui): restore layer arrange functionality 2024-04-19 09:32:56 -04:00
085f7bdbee feat(ui): add invert negative mode
Adds an additional negative conditioning using the inverted mask of the positive conditioning and the positive prompt. May be useful for mutually exclusive regions.
2024-04-19 09:32:56 -04:00
e4fcb6627a feat(ui): style regional prompt boxes 2024-04-19 09:32:56 -04:00
47aa6357d1 tidy(ui): organize regional prompts files 2024-04-19 09:32:56 -04:00
b81030fe27 tidy(ui): remove unused exports 2024-04-19 09:32:56 -04:00
a1a9f0da73 tidy(ui): remove more unused files 2024-04-19 09:32:56 -04:00
8f4f3b773c tidy(ui): remove unused files, code 2024-04-19 09:32:56 -04:00
00737efc31 tidy(ui): tidy naming of regional prompt utils 2024-04-19 09:32:56 -04:00
5924dc6ff6 feat(ui): transparency on regional prompts canvas 2024-04-19 09:32:56 -04:00
246fabf2a0 feat(ui): scaling regional prompt canvas 2024-04-19 09:32:56 -04:00
30e3e12513 feat(ui): layouting regional prompts 2024-04-19 09:32:56 -04:00
a5bfe2dccb feat(ui): support negative regional prompt 2024-04-19 09:32:56 -04:00
aa6bfc8645 fix(ui): wip misc regional prompting ui 2024-04-19 09:32:56 -04:00
20ccdb6c8f fix(ui): remove extra type in nodestate 2024-04-19 09:32:56 -04:00
8caa7bc2b1 feat(ui): abstract out bbox renderer 2024-04-19 09:32:56 -04:00
ede8826757 feat(ui): remove dep on stage in mouse handlers 2024-04-19 09:32:56 -04:00
ff7aa2558a feat(ui): display prompt when debugging regions 2024-04-19 09:32:56 -04:00
c9bf00b80b feat(ui): restore invoke button (wip) 2024-04-19 09:32:56 -04:00
1f8f429d55 feat(ui): abstract layer renderer 2024-04-19 09:32:56 -04:00
d34e431002 feat(ui): abstract brush preview logic 2024-04-19 09:32:56 -04:00
cdb481e836 feat(ui): use konva generics for types in selector functions 2024-04-19 09:32:56 -04:00
525e6d697c feat(ui): re-implement with imperative konva api (wip) 2024-04-19 09:32:56 -04:00
bbbb5479e8 feat(ui): re-implement with imperative konva api (wip) 2024-04-19 09:32:56 -04:00
ae7797f662 feat(ui): re-implement with imperative konva api (wip) 2024-04-19 09:32:56 -04:00
05deeb68fa feat(ui): draft of graph helper for regional prompts 2024-04-19 09:32:56 -04:00
602a59066e fix(nodes): handle invert in alpha_mask_to_tensor 2024-04-19 09:32:56 -04:00
d1db6198b5 perf(ui): memoize & otherwise optimize regional prompts ui 2024-04-19 09:32:56 -04:00
944fa1a847 chore(ui): lint 2024-04-19 09:32:56 -04:00
52e7daffe7 feat(ui): selected layer styling 2024-04-19 09:32:56 -04:00
cf4c1750cb fix(ui): caching broke layer rendering 2024-04-19 09:32:56 -04:00
de7ecc8e3e feat(ui): tweak bbox styling 2024-04-19 09:32:56 -04:00
6c0481ef51 fix(ui): do not reset layer position when toggling visibility 2024-04-19 09:32:56 -04:00
b9d0da44eb feat(ui): wip layer transparency 2024-04-19 09:32:56 -04:00
0a42d7d510 docs(ui): update docstrings for helper function 2024-04-19 09:32:56 -04:00
c1aae0815d feat(ui): regional prompting layout, styling 2024-04-19 09:32:56 -04:00
e7523bd1d9 fix(ui): fix layer debug 2024-04-19 09:32:56 -04:00
8911017bd1 feat(ui): selectable & draggable layers 2024-04-19 09:32:56 -04:00
fc26f3e430 feat(nodes): add alpha mask to tensor invocation 2024-04-19 09:32:56 -04:00
c89a24d1ea feat(ui): add util to get blobs from layers 2024-04-19 09:32:56 -04:00
52ba4966c9 feat(ui): wip regional prompting UI
- Add eraser tool, applies per layer
2024-04-19 09:32:56 -04:00
822dfa77fc feat(ui): wip regional prompting UI
- Arrange layers
- Layer visibility
- Layered brush preview
- Cleanup
2024-04-19 09:32:56 -04:00
83d359b681 feat(ui): wip regional prompting UI 2024-04-19 09:32:56 -04:00
f87eee810b feat(ui): rough out regional prompts components 2024-04-19 09:32:56 -04:00
1d1e4d02dc feat(ui): rough out regional prompts store 2024-04-19 09:32:56 -04:00
2b9f06dc4c Re-enable app shutdown actions (#6244)
* closes #6242

* only override sigINT during slow model scanning

* fix ruff formatting

---------

Co-authored-by: Lincoln Stein <lstein@gmail.com>
2024-04-19 06:45:42 -04:00
a35386f24c fix: IP Adapter Method having incorrect informational popover 2024-04-18 13:37:55 -04:00
ac1071a5e5 chore: v4.1.0 2024-04-18 07:19:22 +10:00
34cdfc61ab Merge branch 'main' into lstein/feat/simple-mm2-api 2024-04-17 17:18:13 -04:00
5295a398f3 translationBot(ui): update translation (Italian)
Currently translated at 98.4% (1122 of 1140 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-04-17 08:41:57 +10:00
0c7283c82d translationBot(ui): update translation (Turkish)
Currently translated at 50.8% (580 of 1140 strings)

translationBot(ui): update translation (Korean)

Currently translated at 43.3% (494 of 1140 strings)

translationBot(ui): update translation (Chinese (Simplified))

Currently translated at 80.9% (923 of 1140 strings)

translationBot(ui): update translation (Russian)

Currently translated at 98.8% (1127 of 1140 strings)

translationBot(ui): update translation (Dutch)

Currently translated at 63.7% (727 of 1140 strings)

translationBot(ui): update translation (Japanese)

Currently translated at 50.4% (575 of 1140 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.3% (1121 of 1140 strings)

translationBot(ui): update translation (Spanish)

Currently translated at 27.8% (317 of 1140 strings)

translationBot(ui): update translation (German)

Currently translated at 72.2% (824 of 1140 strings)

Co-authored-by: Anonymous <noreply@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/de/
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/es/
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ja/
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ko/
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/nl/
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/tr/
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/zh_Hans/
Translation: InvokeAI/Web UI
2024-04-17 08:41:57 +10:00
73ad173c74 update labels for Style Only and CompositionOnly to be designated as beta 2024-04-17 08:29:10 +10:00
c828a4e59f Add IP Adapter Style & Composition Modes (#6213)
## Summary

Until now IP Adapter had complete control on the contents of the output.
With this PR, users are now able to select "Style Only" or "Composition
Only" to draw just the style or layout of the reference image.

Based off: https://arxiv.org/abs/2404.02733

### New IP Method Option

- `Full` - Both style and layout of the refence image are used.
- `Style Only` - Only the style of the image is used
- `Composition Only` - Only the composition of the image is used.


![opera_0BkqZTwObO](https://github.com/invoke-ai/InvokeAI/assets/54517381/1b2fbbba-44c9-4c25-87cb-3711a17d13e3)

### Example Result


![demo](https://github.com/invoke-ai/InvokeAI/assets/54517381/703f3de5-e685-4691-acda-9338a4c10796)

### Notes

- Supports both SDXL and SD1.5

### Testing

- Just check and test if it works as expected with all IP Adapter models
- both SDXL and SD1.5

## Merge Plan

Good to merge once tested for all edge cases.
2024-04-16 14:23:36 -04:00
6bab040d24 Merge branch 'main' into ip-adapter-style-comp 2024-04-16 21:14:06 +05:30
f46bbaf8c4 fix: make ip-adapter weights not be optional 2024-04-16 21:12:45 +05:30
fce6b3e44c maybe solve race issue 2024-04-16 13:09:26 +10:00
d27907cc6d fix: entire reshaping block needs to be skipped 2024-04-16 04:29:53 +05:30
7ee3fef2db cleanup: better var names for the ip adapter weight collection block 2024-04-16 04:23:50 +05:30
b39ce642b6 cleanup: raise ValueErrors when target_blocks dont match base model 2024-04-16 04:12:30 +05:30
a148c4322c fix: IP Adapter weights being incorrectly applied
They were being overwritten rather than being appended
2024-04-16 04:10:41 +05:30
f6b7bc5d98 fix: Dynamically adapt height of control adapter opts 2024-04-16 01:18:43 +05:30
5f6c6abf9c chore: change IPAdapterAttentionWeights to a dataclass 2024-04-15 23:38:55 +05:30
cd76a31a8f fix: IP Adapter method not being recalled 2024-04-15 22:29:32 +05:30
470a39935c fix merge conflicts with main 2024-04-15 09:24:57 -04:00
f1e79d5a8f Merge branch 'main' into lstein/feat/simple-mm2-api 2024-04-15 09:14:55 -04:00
f055e1edb6 Merge branch 'lstein/feat/simple-mm2-api' of github.com:invoke-ai/InvokeAI into lstein/feat/simple-mm2-api 2024-04-15 09:14:37 -04:00
e93f4d632d [util] Add generic torch device class (#6174)
* introduce new abstraction layer for GPU devices

* add unit test for device abstraction

* fix ruff

* convert TorchDeviceSelect into a stateless class

* move logic to select context-specific execution device into context API

* add mock hardware environments to pytest

* remove dangling mocker fixture

* fix unit test for running on non-CUDA systems

* remove unimplemented get_execution_device() call

* remove autocast precision

* Multiple changes:

1. Remove TorchDeviceSelect.get_execution_device(), as well as calls to
   context.models.get_execution_device().
2. Rename TorchDeviceSelect to TorchDevice
3. Added back the legacy public API defined in `invocation_api`, including
   choose_precision().
4. Added a config file migration script to accommodate removal of precision=autocast.

* add deprecation warnings to choose_torch_device() and choose_precision()

* fix test crash

* remove app_config argument from choose_torch_device() and choose_torch_dtype()

---------

Co-authored-by: Lincoln Stein <lstein@gmail.com>
2024-04-15 13:12:49 +00:00
5a8489bbfc perf(ui): memoize infill components 2024-04-15 22:50:54 +10:00
a24c9d0f7a perf(ui): optimize useFeatureStatus 2024-04-15 22:50:54 +10:00
7a92afc117 perf(ui): fix rerenders in nodes
Unmemoized selector tanking perf
2024-04-15 22:50:54 +10:00
b508945b11 feat(ui): edge labels
Add setting to render labels with format `Source Node label -> Target Node label` on edges.
2024-04-15 22:48:46 +10:00
7cf788e658 Update deps to their lastest versions (#6178)
* Update deps to their lastest versions

* missed huggingface_hub

* bump accelerate

---------

Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com>
2024-04-15 00:48:39 +00:00
06bc38d3f4 Remove tag excluder 2024-04-15 09:14:49 +10:00
d3b0212da5 Scope project files to src dir (enables --production) 2024-04-15 09:14:49 +10:00
c2b79ce14c Replace @knipignore with paths config 2024-04-15 09:14:49 +10:00
70185b0173 translationBot(ui): update translation (Russian)
Currently translated at 99.5% (1128 of 1133 strings)

Co-authored-by: Васянатор <ilabulanov339@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/
Translation: InvokeAI/Web UI
2024-04-15 09:12:38 +10:00
a83a0c6146 translationBot(ui): update translation (Chinese (Simplified))
Currently translated at 81.5% (924 of 1133 strings)

Co-authored-by: 怀瑾 <symant233@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/zh_Hans/
Translation: InvokeAI/Web UI
2024-04-15 09:12:38 +10:00
12f41039cc translationBot(ui): update translation (Italian)
Currently translated at 98.4% (1122 of 1140 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.4% (1120 of 1138 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.4% (1115 of 1133 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-04-15 09:12:38 +10:00
b3b5b7e261 Include hardcoded count of one to avoid translation issues on missing keys 2024-04-15 09:10:15 +10:00
f706a13230 Adjust gallery image length handling 2024-04-15 09:10:15 +10:00
22c6400bb8 Refactor i18n pluralization 2024-04-15 09:10:15 +10:00
1ca152f6c8 Apply eslint/prettier fixes 2024-04-15 09:10:15 +10:00
982e255878 Add dynamic label to delete button located at the top toolbar 2024-04-15 09:10:15 +10:00
7899149144 Remove unnecessary word 2024-04-15 09:10:15 +10:00
bef97b46bf Apply eslint/prettier fixes 2024-04-15 09:10:15 +10:00
cc256fee0e Modify the modal title to include selected image array length 2024-04-15 09:10:15 +10:00
ec69a58c8d Include plural variation for delete image modal title 2024-04-15 09:10:15 +10:00
ec67ba61db Pass an array of selected images instead of imageDTO 2024-04-15 09:10:15 +10:00
66126996e7 Import image selection 2024-04-15 09:10:15 +10:00
4eb66a9198 remove hires fix badge from settings when using sdxl 2024-04-15 07:57:58 +10:00
14e41a1fd9 Remove unnecessary whitespace 2024-04-15 07:54:36 +10:00
fc55522003 Import hook in the main App script 2024-04-15 07:54:36 +10:00
cd6d8ae9cc Add a hook as a singleton to update favicon and title upon queueSize change 2024-04-15 07:54:36 +10:00
2933eb594d Remove unnecessary code 2024-04-15 07:54:36 +10:00
4e08fab3f5 Apply brand red color and a black border 2024-04-15 07:54:36 +10:00
8bca7e2aa2 Apply eslint/prettier fixes 2024-04-15 07:54:36 +10:00
3706cf0ad4 Add JSDoc strings 2024-04-15 07:54:36 +10:00
a459361376 Modify the processing to consider the active queue length instead of in_progress only 2024-04-15 07:54:36 +10:00
bb330d50a6 Increase favicon alert detail size 2024-04-15 07:54:36 +10:00
102cb62960 Apply eslint/prettier fixes 2024-04-15 07:54:36 +10:00
8eeab22ecd Replace let with const 2024-04-15 07:54:36 +10:00
4343852b83 Update HTML page title and favicon upon queue item event 2024-04-15 07:54:36 +10:00
0a9bf25bff Implement updatePageTitle and updatePageFavicon methods 2024-04-15 07:54:36 +10:00
4cd09850b8 Add ID to the HTML link element 2024-04-15 07:54:36 +10:00
dbc586e0b2 Add alert variation for Invoke favicon 2024-04-15 07:54:36 +10:00
fa6efac436 change names of convert and download caches and add migration script 2024-04-14 16:10:24 -04:00
3ead827d61 port dw_openpose, depth_anything, and lama processors to new model download scheme 2024-04-14 16:10:24 -04:00
c140d3b1df add invocation_context.load_ckpt_from_url() method 2024-04-14 16:10:24 -04:00
34438ce1af add simplified model manager install API to InvocationContext 2024-04-14 16:10:24 -04:00
3ddd7ced49 change names of convert and download caches and add migration script 2024-04-14 15:57:33 -04:00
41b909cbe3 port dw_openpose, depth_anything, and lama processors to new model download scheme 2024-04-14 15:57:03 -04:00
8426f1e7b2 fix(experimental): Possible fix for conflict with regional embed length mismatch
Pushing this so people can test it out and see if this needs to be handled in a different way.
2024-04-14 12:19:19 +05:30
c2e3c61f28 fix recall all when loras, controls, or hrf arent present 2024-04-14 16:49:14 +10:00
fbfa29c2ef Update GALLERY.md 2024-04-14 16:46:31 +10:00
9ee7b951eb Update GALLERY.md 2024-04-14 16:46:31 +10:00
29dd1bb35b Update GALLERY.md 2024-04-14 16:46:31 +10:00
68d8a2497e Update GALLERY.md 2024-04-14 16:46:31 +10:00
4b171fa696 Creation of GALLERY.md and related images
First draft of the walkthrough of the Gallery right-hand panel
2024-04-14 16:46:31 +10:00
d0beb45431 Create GALLERY.md 2024-04-14 16:46:31 +10:00
e724781a80 Update WEB.md
Correct stated location of Gallery panel.
2024-04-14 16:46:31 +10:00
636ece323f Update INSTALL_DEVELOPMENT.md 2024-04-14 15:24:00 +10:00
77b3281f08 prettier 2024-04-14 15:22:33 +10:00
bd7c8cd517 added info popover back to model, updated description hover to combobox only 2024-04-14 15:22:33 +10:00
489d485907 added missing description to control adapters hover 2024-04-14 15:22:33 +10:00
6eed5ad531 added button for hiding bounding box 2024-04-14 15:22:33 +10:00
9cb0f63c44 refactor: fix a bunch of type issues in custom_attention 2024-04-13 14:17:25 +05:30
2d5786d3bb fix: Incorrect composition blocks for SD1.5 2024-04-13 13:52:10 +05:30
27466ffa1a chore: update the ip adapter node version 2024-04-13 13:39:08 +05:30
f50b156511 chore: do not include custom nodes in schema 2024-04-13 12:43:49 +05:30
9fc73743b2 feat: support SD1.5 2024-04-13 12:30:39 +05:30
d4393e4170 chore: linter fixes 2024-04-13 12:14:45 +05:30
145a0b029e Merge branch 'ip-adapter-style-comp' of https://github.com/blessedcoolant/InvokeAI into ip-adapter-style-comp 2024-04-13 12:13:06 +05:30
f2506cc769 chore: ruff fixes
Revert "chore: ruff fixes"

This reverts commit af36fe8c1e.

Revert "chore: ruff fixes"

This reverts commit af36fe8c1e.
2024-04-13 12:12:33 +05:30
7a67fd6a06 Revert "chore: ruff fixes"
This reverts commit af36fe8c1e.
2024-04-13 12:10:20 +05:30
af36fe8c1e chore: ruff fixes 2024-04-13 12:08:52 +05:30
e9f16ac8c7 feat: add UI for IP Adapter Method 2024-04-13 12:06:59 +05:30
6ea183f0d4 wip: Initial Implementation IP Adapter Style & Comp Modes 2024-04-13 11:09:45 +05:30
3a26c7bb9e fix merge conflicts 2024-04-12 00:58:11 -04:00
df5ebdbc4f add invocation_context.load_ckpt_from_url() method 2024-04-12 00:55:21 -04:00
af1b57a01f add simplified model manager install API to InvocationContext 2024-04-11 21:46:00 -04:00
24f2cde862 Remove type="submit" from all tsx files.
Fixes a problem on firefox, at least for me.
2024-04-12 09:09:32 +10:00
b18442ded4 fix(queue): poll queue on finished queue item
When a queue item is finished (completed, canceled, failed), immediately poll the queue for the next queue item.

Closes #6189
2024-04-12 07:31:47 +10:00
651c0b39b1 clear cache on all exceptions 2024-04-12 07:19:16 +10:00
46d23cd868 catch RunTimeError during model to() call rather than OutOfMemoryError 2024-04-12 07:19:16 +10:00
dedf0c6ffa fix ruff issues 2024-04-12 07:19:16 +10:00
579082ac10 [mm] clear the cache entry for a model that got an OOM during loading 2024-04-12 07:19:16 +10:00
7bc77ddb40 fix(nodes): doubly-noised latents
When using refiner with a mask (i.e. inpainting), we don't have noise provided as an input to the node.

This situation uniquely hits a code path that wasn't reviewed when gradient denoising was implemented.

That code path does two things wrong:
- It lerp'd the input latents. This was fixed in 5a1f4cb1ce.
- It added noise to the latents an extra time. This is fixed in this change.

We don't need to add noise in `latents_from_embeddings` because we do it just a lines later in `AddsMaskGuidance`.

- Remove the extraneous call to `add_noise`
- Make `seed` a required arg. We never call the function without seed anyways. If we refactor this in the future, it will be clearer that we need to look at how seed is handled.
- Move the call to create the noise to a deeper conditional, just before we call `AddsMaskGuidance`. The created noise tensor is now only used in that function, no need to create it every time.

Note: Whether or not having both noise and latents as inputs on the node is correct is a separate conversation. This change just fixes the issue with the current setup.
2024-04-11 07:21:50 -04:00
026d095afe fix(nodes): do not set seed on output latents from denoise latents
`LatentsField` objects have an optional `seed` field. This should only be populated when the latents are noise, generated from a seed.

`DenoiseLatentsInvocation` needs a seed value for scheduler initialization. It's used in a few places, and there is some logic for determining the seed to use with a series of fallbacks:
- Use the seed from the noise (a `LatentsField` object)
- Use the seed from the latents (a `LatentsField` object - normally it won't have a seed)
- Use `0` as a final fallback

In `DenoisLatentsInvocation`, we set the seed in the `LatentsOutput`, even though the output latents are not noise.

This is normally fine, but when we use refiner, we re-use the those same latents for the refiner denoise. This causes that characteristic same-seed-fried look on the refiner pass.

Simple fix - do not set the field in the output latents.
2024-04-11 07:21:50 -04:00
7e2ade50e1 fix(ui): canvas staging area & batch handling fixes
Handful of intertwined fixes.

- Create and use helper function to reset staging area.
- Clear staging area when queue items are canceled, failed, cleared, etc. Fixes a bug where the bbox ends up offset and images are put into the wrong spot.
- Fix a number of similar bugs where canvas would "forget" it had pending generations, but they continued to generate. Canvas needs to track batches that should be displayed in it using `state.canvas.batchIds`, and this was getting cleared without actually canceling those batches.
- Disable the `discard current image` button on canvas if there is only one image. Prevents accidentally canceling all canvas batches if you spam the button.
2024-04-10 21:48:34 +10:00
c0d54d5414 Revert "always enqueue with fresh bounding box"
This reverts commit fae51da278b39c61cbbea5de88661b4bc546f1ce.
2024-04-10 21:48:34 +10:00
98bfbb73ac always enqueue with fresh bounding box 2024-04-10 21:48:34 +10:00
f9af32a6d1 Fix the padding behavior when max-pooling regional IP-Adapter masks to mirror the downscaling behavior of SD and SDXL. Prior to this change, denoising with input latent dimensions that were not evenly divisible by 8 would raise an exception. 2024-04-09 16:50:43 -04:00
fba40eb1bd Fix the padding behavior when max-pooling regional prompt masks to mirror the downscaling behavior of SD and SDXL. Prior to this change, denoising with input latent dimensions that were not evenly divisible by 8 would raise an exception. 2024-04-09 16:50:43 -04:00
69f6c24f52 Fix field ordering (#6186)
Changed fields to go in w/h x/y order.

## Summary

The prior ordering of height, then width, and y, then x, doesn't match
up with the expected UX. This has been changed.

## Checklist

- [X] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_
2024-04-10 01:00:22 +05:30
80d631118d Fix field ordering
Changed fields to go in w/h x/y order.
2024-04-09 14:17:55 -05:00
0c6dd32ece (minor) Fix IP-Adapter conditional logic in CustomAttnProcessor2_0. 2024-04-09 15:06:51 -04:00
0bdbfd4d1d Add support for IP-Adapter masks. 2024-04-09 15:06:51 -04:00
2e27ed5f3d Pass IP-Adapter scales through the cross_attn_kwargs pathway, since they are the same for all attention layers. This change also helps to prepare for adding IP-Adapter region masks. 2024-04-09 15:06:51 -04:00
babdc64b17 (minor) Fix typo in IP-Adapter field description. 2024-04-09 15:06:51 -04:00
54327ec4a7 Remove documentation references to prompt-to-prompt cross-attention control. 2024-04-09 10:57:02 -04:00
4a828818da Remove support for Prompt-to-Prompt cross-attention control (aka .swap()). This feature is not widely used. It does not work with SDXL and is incompatible with IP-Adapter and regional prompting. The implementation is also intertwined with both text embedding and the UNet attention layers, resulting in a high maintenance burden. For all of these reasons, we have decided to drop support. 2024-04-09 10:57:02 -04:00
fe386252f3 Revert "feat(nodes): add prompt region from image nodes"
This reverts commit 3a531c5097.
2024-04-09 08:12:12 -04:00
182810337c Add utility to_standard_float_mask(...) to convert various mask formats to a standardized format. 2024-04-09 08:12:12 -04:00
338bf808d6 Rename MaskField to be a generice TensorField. 2024-04-09 08:12:12 -04:00
5b5a4204a1 Fix dimensions of mask produced by ExtractMasksAndPromptsInvocation. Also, added a clearer error message in case the same error is introduced in the future. 2024-04-09 08:12:12 -04:00
75ef473748 Pull the upstream changes from diffusers' AttnProcessor2_0 into CustomAttnProcessor2_0. This fixes a bug in CustomAttnProcessor2_0 that was being triggered when peft was not installed. The bug was present in a block of code that was previously copied from diffusers. The bug seems to have been introduced during diffusers' migration to PEFT for their LoRA handling. The upstream bug was fixed in 531e719163. 2024-04-09 08:12:12 -04:00
926b8d0efe feat(nodes): add prompt region from image nodes 2024-04-09 08:12:12 -04:00
9d9d1761f3 (minor) The latest ruff version has _slightly_ different formatting preferences. 2024-04-09 08:12:12 -04:00
a78df8123f Update the diffusion logic to use the new regional prompting feature. 2024-04-09 08:12:12 -04:00
7ca677578e Create a UNetAttentionPatcher for patching UNet models with CustomAttnProcessor2_0 modules. 2024-04-09 08:12:12 -04:00
31c456c1e6 Update CustomAttention to support both IP-Adapters and regional prompting. 2024-04-09 08:12:12 -04:00
2ce79b61f5 Initialize a RegionalPromptAttnProcessor2_0 class by copying AttnProcessor2_0 from diffusers. 2024-04-09 08:12:12 -04:00
109e3f0e7f Add RegionalPromptData class for managing prompt region masks. 2024-04-09 08:12:12 -04:00
dc64fec771 Add support for lists of prompt embeddings to be passed to the DenoiseLatents invocation, and add handling of the conditioning region masks in DenoiseLatents. 2024-04-09 08:12:12 -04:00
d1e45585d0 Add TextConditioningRegions to the TextConditioningData data structure. 2024-04-09 08:12:12 -04:00
aba023e0c5 Improve documentation of conditioning_data.py. 2024-04-09 08:12:12 -04:00
e354c29b52 Rename ConditioningData -> TextConditioningData. 2024-04-09 08:12:12 -04:00
a7f363e654 Split ip_adapter_conditioning out from ConditioningData. 2024-04-09 08:12:12 -04:00
9b2162e564 Remove scheduler_args from ConditioningData structure. 2024-04-09 08:12:12 -04:00
4e64b26702 Update compel nodes to accept an optional prompt mask. 2024-04-09 08:12:12 -04:00
c22d772062 Add RectangleMaskInvocation. 2024-04-09 08:12:12 -04:00
d6be7662c9 Add a MaskField primitive, and add a mask to the ConditioningField primitive type. 2024-04-09 08:12:12 -04:00
95050088d1 chore: lint fixes 2024-04-09 14:13:10 +10:00
94b5084cd5 fix: one man's max is another man's min 2024-04-09 14:13:10 +10:00
ca0d60bee6 fix: set coherence denoise to 0.2 min for refiner models 2024-04-09 14:13:10 +10:00
fd1f240853 fix: SDXL Refiner not working properly with Inpainting 2024-04-09 14:13:10 +10:00
381b41a56e fix: Update SDXL Refiner graphs to use Gradient Mask 2024-04-09 14:13:10 +10:00
b58494c420 feat(ui): add graph-to-workflow debug helper
This is intended for debug usage, so it's hidden away in the workflow library `...` menu. Hold shift to see the button for it.

- Paste a graph (from a network request, for example) and then click the convert button to convert it to a workflow.
- Disable auto layout to stack the nodes with an offset (try it out). If you change this, you must re-convert to get the changes.
- Edit the workflow JSON if you need to tweak something before loading it.
2024-04-08 20:38:04 -04:00
dca30d5462 (feat) add a method to get the path of an image from the invocation context
Fixes #6175
2024-04-08 18:42:55 +10:00
9ab6655491 feat(backend): clean up choose_precision
- Allow user-defined precision on MPS.
- Use more explicit logic to handle all possible cases.
- Add comments.
- Remove the app_config args (they were effectively unused, just get the config using the singleton getter util)
2024-04-07 09:41:05 -04:00
29cfe5a274 fix(ui): handle multipleOf on number fields
This data is already in the template but it wasn't ever used.

One big place where this improves UX is the noise node. Previously, the UI let you change width and height in increments of 1, despite the template requiring a multiple of 8. It now works in multiples of 8.
2024-04-06 13:15:20 -04:00
2c45697f3d translationBot(ui): update translation files
Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/
Translation: InvokeAI/Web UI
2024-04-06 15:19:20 +11:00
9a0a90e2a2 chore: v4.0.4 2024-04-06 15:15:16 +11:00
69f17da1a2 fix(nodes): add WithBoard to public API 2024-04-06 15:02:28 +11:00
4d0a49298c tidy(ui): remove extraneous zod schema 2024-04-06 14:54:12 +11:00
55f7a7737a feat(ui): shift around init image recall logic
Retrieving the DTO happens as part of the metadata parsing, not recall. This way, we don't show the option to recall a nonexistent image.

This matches the flow for other metadata entities like models - we don't show the model recall button if the model isn't available.
2024-04-06 14:54:12 +11:00
adc30045a6 addressed pr feedback 2024-04-06 14:54:12 +11:00
fdd0e57976 actually use the schema 2024-04-06 14:54:12 +11:00
9ba5ec4b67 fix typo Params set set 2024-04-06 14:54:12 +11:00
8a17616bf4 recall initial image from metadata and set to image2image 2024-04-06 14:54:12 +11:00
f56b9537cd added initial image to metadata viewer 2024-04-06 14:54:12 +11:00
a95756f3ed docs: update FAQ.md (shared GPU memory) 2024-04-06 14:35:36 +11:00
4068e817d6 fix(mm): typing issues in model cache 2024-04-06 14:35:36 +11:00
a09d705e4c fix(mm): remove vram check
This check prematurely reports insufficient VRAM on Windows. See #6106 for details.
2024-04-06 14:35:36 +11:00
540d506ec9 fix: Incorrect default clip vision opt in the node 2024-04-05 15:06:33 -04:00
e330966020 chore: v4.0.3 2024-04-05 15:32:30 +11:00
b783679b9f fix: typo, change shouldFitImageSize default value 2024-04-05 15:23:58 +11:00
d32e557e50 fix: add roundDownToMultiple 2024-04-05 15:23:58 +11:00
90686c7f9c feat: Unified Canvas Fit Image Size on Drop 2024-04-05 15:23:58 +11:00
4571986c63 fix misplaced lock call 2024-04-05 14:32:18 +11:00
fec989f015 navigate to workflow tab when clicking load workflow 2024-04-05 14:16:33 +11:00
b5c048d8bf translationBot(ui): update translation (Italian)
Currently translated at 98.4% (1108 of 1126 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-04-05 13:53:42 +11:00
577469be55 translationBot(ui): update translation (German)
Currently translated at 73.3% (826 of 1126 strings)

Co-authored-by: Alexander Eichhorn <pfannkuchensack@einfach-doof.de>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/de/
Translation: InvokeAI/Web UI
2024-04-05 13:53:42 +11:00
812f10730f adjust free vram calculation for models that will be removed by lazy offloading (#6150)
Co-authored-by: Lincoln Stein <lstein@gmail.com>
2024-04-04 22:51:12 -04:00
3006285d13 fix(ui): display refiner models in mm 2024-04-05 09:46:03 +11:00
5d4a571778 feat(ui): disable mosaic infill in graph builders 2024-04-05 08:49:13 +11:00
90bdd74f30 chore(ui): typegen 2024-04-05 08:49:13 +11:00
d6ccd5bc81 feat(nodes): disable mosaic fill
Needs a bit of tweaking, leaving the code in just disabled/commented it out.
2024-04-05 08:49:13 +11:00
f0b1bb0327 feat(nodes): redo tile infill
The previous algorithm errored if the image wasn't divisible by the tile size. I've reimplemented it from scratch to mitigate this issue.

The new algorithm is simpler. We create a pool of tiles, then use them to create an image composed completely of tiles. If there is any awkwardly sized space on the edge of the image, the tiles are cropped to fit.

Finally, paste the original image over the tile image.

I've added a jupyter notebook to do a smoke test of infilling methods, and 10 test images.

The other infill algorithms can be easily tested with the notebook on the same images, though I didn't set that up yet.

Tested and confirmed this gives results just as good as the earlier infill, though of course they aren't the same due to the change in the algorithm.
2024-04-05 08:49:13 +11:00
b061db414f tidy(nodes): abstractmethod is noop 2024-04-05 08:49:13 +11:00
e55ab5b3a1 ui: Color Infill UI 2024-04-05 08:49:13 +11:00
adb7966bb3 ui: intial mosaic infill ui
Need to change color picking.
2024-04-05 08:49:13 +11:00
3c195d74a5 fix: bypass edge pixels which cannot transform to tile size
Still need to fix this somehow
2024-04-05 08:49:13 +11:00
32a6b758cd wip: Initial Infill Methods Refactor 2024-04-05 08:49:13 +11:00
3659219f46 Fix IdealSizeInvocation (#6145) 2024-04-05 08:38:40 +11:00
d284e0567a fix: ip adapter clip selection being broken 2024-04-05 07:49:04 +11:00
13027891d9 fix(ui): discarding last single canvas image breaks canvas
We need to reset the staging area if we are discarding the last image.
2024-04-04 08:00:08 -04:00
8a32baf2dc chore: v4.0.2 2024-04-04 15:46:51 +11:00
8c15d14099 fix: use locale encoding
We have had a few bugs with v4 related to file encodings, especially on Windows.

Windows uses its own character encodings instead of `utf-8`, often `cp1252`. Some characters cannot be decoded using `utf-8`, causing `UnicodeDecodeError`.

There are a couple places where this can cause problems:
- In the installer bootstrap, we install or upgrade `pip` and decode the result, using `subprocess`.

  The input to this includes the user's home dir. In #6105, the user had one of the problematic characters in their username. `subprocess` attempts and fails to decode the username, which crashes the installer.

  To fix this, we need to use `locale.getpreferredencoding()` when executing the command.
- Similarly, in the model install service and config class, we attempt to load a yaml config file. If a problematic character is in the path to the file (which often includes the user's home dir), we can get the same error.

  One example is  #6129 in which the models.yaml migration fails.

  To fix this, we need to open the file with `locale.getpreferredencoding()`.
2024-04-04 15:30:47 +11:00
9cc1f20ad5 add simplified model manager install API to InvocationContext 2024-04-03 23:26:48 -04:00
38718d8c65 docs: update 020_INSTALL_MANUAL.md, remove conda section 2024-04-04 11:28:09 +11:00
98ab387e2b docs: update 020_INSTALL_MANUAL.md
Redo the install the package section. It was inaccurate with respect to extra index URLs.
2024-04-04 10:54:23 +11:00
a0ae2f37d7 docs: update 020_INSTALL_MANUAL.md
Tidy verbiage around the invokeai root and how it is determined
2024-04-04 10:54:23 +11:00
9c51abb46e fix(config): get root from venv
This logic was a bit wonky. It only selected the `venv` parent if there was already an `invokeai.yaml` file in it. Removed this constraint.
2024-04-04 10:54:23 +11:00
f887e030bb docs: update 010_INSTALL_AUTOMATED.md
Remove reference to the autodetect GPU device option.
2024-04-04 08:43:17 +11:00
52b58b4a80 feat(installer): remove extra GPU options
- Remove `CUDA_AND_DML`. This was for onnx, which we have since removed.
- Remove `AUTODETECT`. This option causes problems for windows users, as it falls back on default pypi index resulting in a non-CUDA torch being installed.
- Add more explicit settings for extra index URL, based on the torch website
- Fix bug where `xformers` wasn't installed on linux and/or windows when autodetect was selected
2024-04-04 08:43:17 +11:00
9fdfd4267c fix(ui): fix model name overflow
Closes #3897
2024-04-04 08:03:30 +11:00
c4a6d3ddc0 docs: update FAQ for missing models solution
This will be fairly common in v4 updates. The root cause is models not being added to the `models.yaml` file in v3, so we don't correctly migrate the models to the db.

The docs describe how to use `Scan Folder` to restore missing models.
2024-04-04 07:58:11 +11:00
25bbaa73b9 feat(ui): add inplace option to scan folder install ui 2024-04-04 07:58:11 +11:00
2383fb93c7 fix(ui): show model install progress as 100 if finished 2024-04-04 07:58:11 +11:00
63c60e6d63 feat(ui): refresh model scan results on completed model install 2024-04-04 07:58:11 +11:00
3a10062b53 feat(mm): more reliable mm scan folder
Compare the installed paths to determine if the model is already installed. Fixes an issue where installed models showed up as uninstalled or vice-versa. Related to relative vs absolute path handling.
2024-04-04 07:58:11 +11:00
51ca59c088 Update probe to always use cpu for loading models 2024-04-04 07:34:43 +11:00
216b34ac44 tests: update model rename test 2024-04-04 07:17:38 +11:00
7ff2371c07 fix(mm): do not rename model file if model record is renamed
Renaming the model file to the model name introduces unnecessary contraints on model names.

For example, a model name can technically be any length, but a model _filename_ cannot be too long.

There are also constraints on valid characters for filenames which shouldn't be applied to model record names.

I believe the old behaviour is a holdover from the old system.
2024-04-04 07:17:38 +11:00
4927d1b7c9 add some test IDs for accordion targeting 2024-04-04 06:35:11 +11:00
85f53f94f8 feat(mm): include needed vs free in OOM
Gives us a bit more visibility into these errors, which seem to be popping up more frequently with the new MM.
2024-04-04 06:26:15 +11:00
7da04b8333 IP-Adapter Safetensor Support (#6041)
## Summary

This PR adds support for IP Adapter safetensor files for direct usage
inside InvokeAI.

# TEST

You can download the [Composition
Adapters](https://huggingface.co/ostris/ip-composition-adapter) which
weren't previously supported in Invoke and try them out. Every other IP
Adapter model should work too.

If you pick a Safetensor IP Adapter model, you will also need to set
ViT-H or ViT-G next to it. This is a raw implementation. Can refine it
further based on feedback.

Prompt: `Spiderman holding a bunny` -- Exact same composition as the
adapter image.

![opera_UHlo1IyXPT](https://github.com/invoke-ai/InvokeAI/assets/54517381/00bf9f0b-149f-478d-87ca-3252b68d1054)
2024-04-03 22:46:45 +05:30
be574cb764 fix: incorrect suffix check in ip adapter checkpoint file 2024-04-03 22:38:28 +05:30
5f01de1993 chore: ruff and lint fixes 2024-04-03 20:41:51 +05:30
cf88bd3294 Merge branch 'main' into checkpoint-ip-adapter 2024-04-03 20:30:02 +05:30
e574815413 chore: clean up merge conflicts 2024-04-03 20:28:00 +05:30
fb293dcd84 Merge branch 'checkpoint-ip-adapter' of https://github.com/blessedcoolant/InvokeAI into checkpoint-ip-adapter 2024-04-03 20:23:07 +05:30
414851f2f0 fix: raise and present the runtime error from the exception 2024-04-03 20:21:50 +05:30
2dcbb7223b fix: use Path for ip_adapter_ckpt_path instead of str 2024-04-03 20:21:03 +05:30
132aadca15 fix(ui): cancel batch status button greyed out
Closes #6110
2024-04-03 08:23:31 -04:00
14a9f74b17 cleanup: use load_file of safetensors directly for loading ip adapters 2024-04-03 12:40:13 +05:30
1372ef15b3 fix: Fail when unexpected keys are found in IP Adapter models 2024-04-03 12:40:11 +05:30
dc1681a0de fix: clip vision model auto param
Setting to 'auto' works only for InvokeAI config and auto detects the SD model but will override if user explicitly sets it. If auto used with checkpoint models, we raise an error. Checkpoints will always need to set to non-auto.
2024-04-03 12:40:11 +05:30
be1212de9a fix: Raise a better error when incorrect CLIP Vision model is used 2024-04-03 12:40:10 +05:30
a14ce0edab chore: rename IPAdapterDiffusersConfig to IPAdapterInvokeAIConfig 2024-04-03 12:40:10 +05:30
4a0dfc3b2d ui: improve the clip vision model picker layout 2024-04-03 12:40:08 +05:30
91a70c8d07 feat: Let users pick CLIP Vision model for Checkpoint IP Adapters 2024-04-03 12:40:05 +05:30
936b99bd3c chore: improve types in ip_adapter backend file 2024-04-03 12:40:02 +05:30
9ff729a7e6 fix: Update ModelView to accommodate for the new config changes to IP Adapter 2024-04-03 12:40:01 +05:30
5829b87b8d ui: update the new ip adapter configs on the frontend 2024-04-03 12:40:01 +05:30
79f7b61dfe fix: cleanup across various ip adapter files 2024-04-03 12:39:52 +05:30
b1c8266e22 feat: add base model recognition for ip adapter safetensor files 2024-04-03 12:39:52 +05:30
67afb1763e wip: Initial implementation of safetensor support for IP Adapter 2024-04-03 12:39:52 +05:30
8584171a49 docs: fix broken link (#6116)
## Summary

Fix a broken link

## Related Issues / Discussions


https://discord.com/channels/1020123559063990373/1049495067846524939/1224970148058763376

## QA Instructions

n/a

## Merge Plan

n/a

## Checklist

- [x] _The PR has a short but descriptive title, suitable for a
changelog_
- [ ] _Tests added / updated (if applicable)_ n/a
- [x] _Documentation added / updated (if applicable)_
2024-04-03 12:35:17 +05:30
50951439bd docs: fix broken link 2024-04-03 17:36:15 +11:00
07cb6c944e chore(ui): typegen 2024-04-03 17:18:12 +11:00
1d45ef529b fix(ui): move tcd scheduler to current zod schemas
It was in the v2 schemas which should be immutable and only used for migrations
2024-04-03 17:08:02 +11:00
0259114d9c Merge branch 'main' into main 2024-04-03 17:03:19 +11:00
51e515b925 tidy: use lowercase for tcd scheduler identifier 2024-04-03 17:03:02 +11:00
8c509295f9 chore: ruff 2024-04-03 17:02:45 +11:00
7b93b554d7 fix(ui): add default coherence mode to generation slice migration
The valid values for this parameter changed when inpainting changed to gradient denoise. The generation slice's redux migration wasn't updated, resulting in a generation error until you change the setting or reset web UI.
2024-04-03 08:46:31 +11:00
21b9e96a45 Run typegen, bump version 2024-04-02 10:14:39 -04:00
b6ad33ac1a perf(ui): reduce canvas max history to 100
This should further insulate canvas from excessive GCs.
2024-04-02 08:48:18 -04:00
69ec14c7bb perf(ui): use rfdc for deep copying of objects
- Add and use more performant `deepClone` method for deep copying throughout the UI.

Benchmarks indicate the Really Fast Deep Clone library (`rfdc`) is the best all-around way to deep-clone large objects.

This is particularly relevant in canvas. When drawing or otherwise manipulating canvas objects, we need to do a lot of deep cloning of the canvas layer state objects.

Previously, we were using lodash's `cloneDeep`.

I did some fairly realistic benchmarks with a handful of deep-cloning algorithms/libraries (including the native `structuredClone`). I used a snapshot of the canvas state as the data to be copied:

On Chromium, `rfdc` is by far the fastest, over an order of magnitude faster than `cloneDeep`.

On FF, `fastest-json-copy` and `recursiveDeepCopy` are even faster, but are rather limited in data types. `rfdc`, while only half as fast as the former 2, is still nearly an order of magnitude faster than `cloneDeep`.

On Safari, `structuredClone` is the fastest, about 2x as fast as `cloneDeep`. `rfdc` is only 30% faster than `cloneDeep`.

`rfdc`'s peak memory usage is about 10% more than `cloneDeep` on Chrome. I couldn't get memory measurements from FF and Safari, but let's just assume the memory usage is similar relative to the other algos.

Overall, `rfdc` is the best choice for a single algo for all browsers. It's definitely the best for Chromium, by far the most popular desktop browser and thus our primary target.

A future enhancement might be to detect the browser and use that to determine which algorithm to use.
2024-04-02 08:48:18 -04:00
a6c91979af fix(ui): prevent canvas history leak
There were two ways the canvas history could grow too large (past the `MAX_HISTORY` setting):
- Sometimes, when pushing to history, we didn't `shift` an item out when we exceeded the max history size.
- If the max history size was exceeded by more than one item, we still only `shift`, which removes one item.

These issue could appear after an extended canvas session, resulting in a memory leak and recurring major GCs/browser performance issues.

To fix these issues, a helper function is added for both past and future layer states, which uses slicing to ensure history never grows too large.
2024-04-02 08:48:18 -04:00
e655399324 fix(config): handle windows paths in invokeai.yaml migration for legacy_conf_dir
The logic incorrectly set the `legacy_conf_dir` on windows, where the slashes go the other direction. Handle this case and update tests to catch it.
2024-04-02 08:06:59 -04:00
f75de8a35c feat(db): add migration 9 - empty session queue
Empties the session queue. This is done to prevent any lingering session queue items from causing pydantic errors due to changed schemas.
2024-04-02 13:25:14 +11:00
d4be945dde fix(nodes): gracefully handle custom nodes init error
Previously, exceptions raised as custom nodes are initialized were fatal errors, causing the app to exit.

With this change, any error on import is caught and the error message printed. App continues to start up without the node.

For example, a custom node that isn't updated for v4.0.0 may raise an error on import if it is attempting to import things that no longer exist.
2024-04-02 13:25:14 +11:00
ab33acad5c translationBot(ui): update translation (Russian)
Currently translated at 99.5% (1119 of 1124 strings)

Co-authored-by: Васянатор <ilabulanov339@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/
Translation: InvokeAI/Web UI
2024-04-02 13:15:11 +11:00
8f3d7b2946 translationBot(ui): update translation (Italian)
Currently translated at 98.3% (1106 of 1124 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.3% (1104 of 1122 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-04-02 13:15:11 +11:00
54a30f66cb translationBot(ui): update translation (German)
Currently translated at 72.4% (813 of 1122 strings)

Co-authored-by: Alexander Eichhorn <pfannkuchensack@einfach-doof.de>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/de/
Translation: InvokeAI/Web UI
2024-04-02 13:15:11 +11:00
a105da6304 chore: v4.0.0 2024-04-02 09:10:53 +11:00
4049217728 feat(db): back up database before running migrations
Just in case.
2024-04-02 09:10:53 +11:00
59b4a23479 feat(mm): use same pattern for vae converter as others
Add `dump_path` arg to the converter function & save the model to disk inside the conversion function. This is the same pattern as in the other conversion functions.
2024-04-01 12:34:49 +11:00
13f410478a fix(mm): typing issues in vae loader 2024-04-01 12:34:49 +11:00
25ff0bf80f fix(mm): return converted vae model instead of path
This was missed in #6072.
2024-04-01 12:34:49 +11:00
23390f1516 cleanup: use load_file of safetensors directly for loading ip adapters 2024-04-01 06:37:38 +05:30
f83edcf990 feat(nodes): simplify processor loop with an early continue
Prefer an early return/continue to reduce the indentation of the processor loop. Easier to read.

There are other ways to improve its structure but at first glance, they seem to involve changing the logic in scarier ways.
2024-04-01 08:39:25 +11:00
a6dd50aeaf fix(nodes): 100% cpu usage when processor paused
Should be waiting on the resume event instead of checking it in a loop
2024-04-01 08:39:25 +11:00
1badf0f32f refactor if/else logic slightly 2024-03-31 12:42:39 -04:00
3c9c58e0fa fix 100% CPU load in session_processor_default._process() 2024-03-31 12:42:39 -04:00
9a1b35fa37 fix(queue): pause & resume
This must not have been tested after the processors were unified. Needed to shift the logic around so the resume event is handled correctly. Clear and easy fix.
2024-03-30 08:25:33 -04:00
5be69f191d remove debug statement 2024-03-29 17:37:04 -04:00
3d6d89feb4 [mm] Do not write diffuser model to disk when convert_cache set to zero (#6072)
* pass model config to _load_model

* make conversion work again

* do not write diffusers to disk when convert_cache set to 0

* adding same model to cache twice is a no-op, not an assertion error

* fix issues identified by psychedelicious during pr review

* following conversion, avoid redundant read of cached submodels

* fix error introduced while merging

---------

Co-authored-by: Lincoln Stein <lstein@gmail.com>
2024-03-29 16:11:08 -04:00
0ac1c0f339 use is_relative_to() rather than relying on string matching to determine relative directory positioning 2024-03-29 10:56:06 -04:00
c308654442 migrate legacy conf files that were incorrectly relative to root 2024-03-29 10:56:06 -04:00
b0ffe36d21 feat(mm): update v3 models.yaml migration logic to handle relative paths for legacy config files 2024-03-29 10:56:06 -04:00
6b3fdb8a93 fix(mm): handle relative model paths in _register_orphaned_models 2024-03-29 10:56:06 -04:00
7639e05dd2 feat(mm): add migration for RC users to migrate their dbs 2024-03-29 10:56:06 -04:00
6d261a5a13 fix(mm): handle relative conversion config paths
I have tested main, controlnet and vae checkpoint conversions.
2024-03-29 10:56:06 -04:00
31e9cf1f06 tests: update model install tests for change to paths 2024-03-29 10:56:06 -04:00
c5d1bd1360 feat(mm): use relative paths for invoke-managed models
We switched all model paths to be absolute in #5900. In hindsight, this is a mistake, because it makes the `models_dir` non-portable.

This change reverts to the previous model pathing:
- Invoke-managed models (in the `models_dir`) are stored with relative paths
- Non-invoke-managed models (outside the `models_dir`, i.e. in-place installed models) still have absolute paths.

## Why absolute paths make things non-portable

Let's say my `models_dir` is `/media/rhino/invokeai/models/`. In the DB, all model paths will be absolute children of this path, like this:

- `/media/rhino/invokeai/models/sd-1/main/model1.ckpt`

I want to change my `models_dir` to `/home/bat/invokeai/models/`. I update my `invokeai.yaml` file and physically move the files to that directory.

On startup, the app checks for missing models. Because all of my model paths were absolute, they now point to a nonexistent path. All models are broken.

There are a couple options to recover from this situation, neither of which are reasonable:

1. The user must manually update every model's path. Unacceptable UX.
2. On startup, we check for missing models. For each missing model, we compare its path with the last-known models dir. If there is a match, we replace that portion of the path with the new models dir. Then we re-check to see if the path exists. If it does, we update the models DB entry. Brittle and requires a new DB entry for last-known models dir.

It's better to use relative paths for Invoke-managed models.
2024-03-29 10:56:06 -04:00
23da3de915 Update constants.ts 2024-03-29 12:39:08 +01:00
97579770e1 Update common.ts 2024-03-29 12:35:42 +01:00
1a83936cdd Merge branch 'invoke-ai:main' into main 2024-03-29 11:14:28 +01:00
298cae5bb9 Update schema.ts 2024-03-29 12:41:10 +05:30
cd52e99bb9 Merge branch 'main' into checkpoint-ip-adapter 2024-03-29 12:39:53 +05:30
6e4c2d3685 fix: Fail when unexpected keys are found in IP Adapter models 2024-03-29 12:34:56 +05:30
56ed697c23 fix: clip vision model auto param
Setting to 'auto' works only for InvokeAI config and auto detects the SD model but will override if user explicitly sets it. If auto used with checkpoint models, we raise an error. Checkpoints will always need to set to non-auto.
2024-03-29 12:12:16 +05:30
cd078b1865 fix: Raise a better error when incorrect CLIP Vision model is used 2024-03-29 11:58:10 +05:30
0d8b535131 chore: rename IPAdapterDiffusersConfig to IPAdapterInvokeAIConfig 2024-03-29 11:50:18 +05:30
3409711ed3 close #6080 2024-03-28 22:51:45 -04:00
3681e34d5a Use defaults for db_dir and outdir since config no longer writes defaults to invokeai.yaml 2024-03-28 22:39:48 -04:00
2526ef52c5 fix(nodes): workaround seamless multi gpu error #6010
The seamless logic errors when a second GPU is selected. I don't understand why, but a workaround is to skip the model patching when there there are no seamless axes specified.

This is also just a good practice regardless - don't patch the model unless we need to. Probably a negligible perf impact.

Closes #6010
2024-03-29 08:56:38 +11:00
80e311a069 Update schedulers.py 2024-03-28 22:52:15 +01:00
b6e6bdc195 Update schedulers.py 2024-03-28 22:51:59 +01:00
43bcedee10 Run ruff 2024-03-29 08:45:34 +11:00
98cc9b963c Only cancel session processor if current generating queue item is cancelled 2024-03-29 08:45:34 +11:00
e8eb9fd533 fix(scripts): handle multiple pages in get_external_contributions.py 2024-03-28 07:58:01 -04:00
250def76de docs: update RELEASE.md troubleshooting info
Add some notes for troubleshooting the release workflow
2024-03-28 07:58:01 -04:00
b2fb108414 docs: update RELEASE.md publish GH release section
Clarify steps & mention the `get_external_contributions.py` script
2024-03-28 07:58:01 -04:00
383f8908be docs: update RELEASE.md sanity check section
Add instructions for testing the installer w/ wheel
2024-03-28 07:58:01 -04:00
ec233e30fb ci: fix name of installer build artifact
The build workflow was naming the file `InvokeAI-installer-v4.0.0rc6.zip.zip` (note the double ".zip"). This caused some confusion when creating releases on GitHub.

Name the build artifact `installer`. This results in `installer.zip`, which it's clear needs to be extracted first before uploading to the GH release.
2024-03-28 07:58:01 -04:00
018121330a feat(scripts): helper to get all external contributions
`scripts/get_external_contributions.py` gets all commits between two refs and outputs a summary.

Useful for getting all external contributions for release notes.
2024-03-28 07:58:01 -04:00
53c19ae937 chore: ruff 2024-03-28 14:24:03 +11:00
b41422fa1a fix(installer): restore install successful message 2024-03-28 14:18:09 +11:00
a6188a1eda chore: v4.0.0rc6 2024-03-28 13:48:00 +11:00
58fd8bb8a5 docs: update 050_INSTALLING_MODELS.md
Fix a couple missing links, add blurb about how to use scan folder to replicate autoimport.
2024-03-28 12:35:41 +11:00
ec1bafdef5 docs: update INSTALL_DEVELOPMENT.md
- Add blurb about `scan_models_on_startup`
- Add blurb about editable install
2024-03-28 12:35:41 +11:00
c545262e3b revert: unrelated docstring change 2024-03-28 12:35:41 +11:00
48e1a0c217 fix(ui): remove sync models functionality
The backend functionality was removed in the previous couple commits. Removing the frontend endpoints and components.
2024-03-28 12:35:41 +11:00
ce2923533a chore(ui): typegen 2024-03-28 12:35:41 +11:00
49a647ad00 docs: remove most references to autoimport
There's still a few references in `WEB.md` but this doc is very outdated and needs to be totally redone. It's hard to just remove the references without redoing a lot more.

Will need to follow up revising this doc.
2024-03-28 12:35:41 +11:00
73c326680a feat(mm): remove autoimport; revise startup model scanning
These two changes are interrelated.

## Autoimport

The autoimport feature can be easily replicated using the scan folder tab in the model manager. Removing the implicit autoimport reduces surface area and unifies all model installation into the UI.

This functionality is removed, and the `autoimport_dir` config setting is removed.

## Startup model dir scanning

We scanned the invoke-managed models dir on startup and took certain actions:

- Register orphaned model files
- Remove model records from the db when the model path doesn't exist

### Orphaned model files

We should never have orphaned model files during normal use - we manage the models directory, and we only delete files when the user requests it.

During testing or development, when a fresh DB or memory DB is used, we could end up with orphaned models that should be registered.

Instead of always scanning for orphaned models and registering them, we now only do the scan if the new `scan_models_on_startup` config flag is set.

The description for this setting indicates it is intended for use for testing only.

### Remove records for missing model files

This functionality could unexpectedly wipe models from the db.

For example, if your models dir was on external media, and that media was inaccessible during startup, the scan would see all your models as missing and delete them from the db.

The "proactive" scan is removed. Instead, we will scan for missing models and log a warning if we find a model whose path doesn't exist. No possibility for data loss.
2024-03-28 12:35:41 +11:00
2f6cce48af docs(mm): update ModelSearch 2024-03-28 12:35:41 +11:00
3cf196dbb0 tidy(api): remove commented routes 2024-03-28 12:35:41 +11:00
c113a822d0 chore(ui): knip 2024-03-28 12:24:32 +11:00
77038a8ef6 build(ui): harden knip config, support @knipignore jsdoc tag 2024-03-28 12:24:32 +11:00
6e5b4b595a tidy(ui): remove unused files, exports 2024-03-28 12:24:32 +11:00
33900d2419 fix(ui): ts issue from react-virtuoso 2024-03-28 12:24:32 +11:00
9179a2f96b chore(ui): bump deps 2024-03-28 12:24:32 +11:00
f6fec34311 chore(ui): upgrade storybook to v8 2024-03-28 12:24:32 +11:00
627a98770f feat(ui): optimize size when using CA image size
When using a Control Adapter image's dimensions as the main output dimensions, fit the dimensions to the model's optimal dimensions.
2024-03-28 08:47:07 +11:00
0bb0e226dc Flip default ordering of workflow library; #5477 2024-03-28 07:36:03 +11:00
86d536755d Check for cuDNN version compatibility issues on startup. Prior to this check, the app would silently run with ~50% performance degradation caused by a cuDNN version mismatch. 2024-03-28 07:32:06 +11:00
1a93f56d06 ui: improve the clip vision model picker layout 2024-03-27 22:11:07 +05:30
16c366a060 feat: Let users pick CLIP Vision model for Checkpoint IP Adapters 2024-03-27 22:08:23 +05:30
688a0f30bb chore: improve types in ip_adapter backend file 2024-03-27 22:08:23 +05:30
318bc938fe fix: Update ModelView to accommodate for the new config changes to IP Adapter 2024-03-27 22:08:23 +05:30
c4a856de4a ui: update the new ip adapter configs on the frontend 2024-03-27 22:08:23 +05:30
4ed2bf53ca fix: cleanup across various ip adapter files 2024-03-27 22:08:14 +05:30
60bf0caca3 feat: add base model recognition for ip adapter safetensor files 2024-03-27 22:08:14 +05:30
b013d0e064 wip: Initial implementation of safetensor support for IP Adapter 2024-03-27 22:08:14 +05:30
e46c22e41a docs: add HF token blurb to FAQ 2024-03-27 18:59:55 +05:30
237ac58dae docs: merge INSTALL_TROUBLESHOOTING into FAQ
These two docs had overlap and were kinda the same thing.
2024-03-27 18:59:55 +05:30
3655a47200 feat(ui): remove references to HF token handling 2024-03-27 18:59:55 +05:30
7167699015 chore(ui): typegen 2024-03-27 18:59:55 +05:30
b8ac524712 feat(mm): remove hf token handling
I had added this because I mistakenly believed the HF token was required to download HF models.

Turns out this is not the case, and the vast majority of HF models do not need the API token to download.
2024-03-27 18:59:55 +05:30
a397fdbd25 chore: ruff 2024-03-27 08:16:27 -04:00
a291a42abc feat: display torch device on startup
This functionality disappeared at some point.
2024-03-27 08:16:27 -04:00
4f2892d231 docs: remove handful of deprecated docs 2024-03-27 08:06:34 -04:00
5c8bbb926a fix(mm): add missing v2-midas-inference.yaml
This is needed for SD2 depth models.

Note: These models don't seem to work.
2024-03-27 07:48:54 -04:00
21758e7b49 fix(mm): move depth variant config to sd2
Looks like a copy/paste got mixed up.
2024-03-27 07:48:54 -04:00
eb33303e79 fix(mm): handle depth and inpainting models when converting to diffusers
"Normal" models have 4 in-channels, while "Depth" models have 5 and "Inpaint" models have 9.

We need to explicitly tell diffusers the channel count when converting models.

Closes  #6058
2024-03-27 07:48:54 -04:00
536bb4f053 chore(ui): lint 2024-03-27 10:52:32 +11:00
3beb9b764a feat(ui): <GalleryImage /> styling 2024-03-27 10:52:32 +11:00
171f2aa20d fix(ui): image not getting selected 2024-03-27 10:52:32 +11:00
778922e603 tests: add test_probe_handles_state_dict_with_integer_keys 2024-03-27 09:30:25 +11:00
243de683d7 fix(mm): handle integer state dict keys in probe
It's possible for a model's state dict to have integer keys, though we do not actually support such models.

As part of probing, we call `key.startswith(...)` on the state dict keys. This raises an `AttributeError` for integer keys.

This logic is in `invokeai/backend/model_manager/probe.py:get_model_type_from_checkpoint`

To fix this, we can cast the keys to strings first. The models w/ integer keys will still fail to be probed, but we'll get a `InvalidModelConfigException` instead of `AttributeError`.

Closes #6044
2024-03-27 09:30:25 +11:00
9b9b7a7071 docs: add warning about speed to malloc docs 2024-03-27 08:45:54 +11:00
6ce82a41d5 docs: update docs for malloc change 2024-03-27 08:45:54 +11:00
f535835612 feat(mm): remove MALLOC_MMAP_THRESHOLD_ from launcher
Closes #6007
2024-03-27 08:45:54 +11:00
e89a739bc3 docs: fix incorrect links to troubleshooting docs 2024-03-27 08:45:54 +11:00
dd941f7a62 docs: fix indentation issue in INSTALL_TROUBLESHOOTING.md 2024-03-27 08:45:54 +11:00
eb15a7516f chore: ruff 2024-03-27 08:34:00 +11:00
06e51b582f test(mm): test arbitrary error handling during model install 2024-03-27 08:34:00 +11:00
16dad07294 feat(mm): improved install error log message in terminal 2024-03-27 08:34:00 +11:00
b2ea749c72 fix(mm): handle any error during installation
Previously we only handled expected error types. If a different error was raised, the install job would end up in an unexpected state where it has failed and isn't doing anything, but its status is still running.

This indirectly prevents the installer threads from exiting - they are waiting for all jobs to be completed, including the failed-but-still-running job.

We need to handle any error here to prevent this.
2024-03-27 08:34:00 +11:00
3aad6f975b docs: restore mention of WinLongPathsEnabled.reg 2024-03-26 09:18:01 -04:00
4e93b05736 docs: update all installation docs 2024-03-26 09:18:01 -04:00
3493b26c55 docs: remove deprecated installatino docs 2024-03-26 09:18:01 -04:00
fb317d0967 feat(installer): update invoke.bat.in
Forgot to update this when removing references to updating the app in invoke.sh.in
2024-03-26 14:48:29 +11:00
56af97866e docs(installer): update docstrings for install methods 2024-03-26 14:48:29 +11:00
44626c9452 tidy(installer): remove no-op --version CLI arg of installer
This wasn't used at all.
2024-03-26 14:48:29 +11:00
dfc08bd964 feat(installer): add support for installing from wheel
This allows us to easily test the installer without needing the desired version to be published on PyPI:
```sh
python3 installer/lib/main.py --wheel installer/dist/InvokeAI-4.0.0rc6-py3-none-any.whl
```

A warning message and confirmation are displayed when the arg is used.

The rest of the installer is unchanged.
2024-03-26 14:48:29 +11:00
eb2a1993f1 fix(installer): resolve all typing issues 2024-03-26 14:48:29 +11:00
743234e3d0 feat(installer): remove updater
Updating should always be done via the installer. We initially planned to only deprecate the updater, but given the scale of changes for v4, there's no point in waiting to remove it entirely.
2024-03-26 14:48:29 +11:00
a3f734af9a Update transformers 4.38.2 -> 4.39.1 and diffusers 0.27.0 -> 0.27.2 2024-03-26 11:51:08 +11:00
b4b1dbdd34 tests: add test for iterate execution order 2024-03-26 09:18:46 +11:00
83b3828b55 prioritize iterate in _get_next_node 2024-03-26 09:18:46 +11:00
3cdfc6ab16 fix tests 2024-03-26 09:06:37 +11:00
42f72b19a6 fix localization and change in settings 2024-03-26 09:06:37 +11:00
148e6d9b97 docs(installer): better comments for PYTORCH_ENABLE_MPS_FALLBACK 2024-03-26 09:04:13 +11:00
354d59df62 fix(installer): typo "10" -> "5" 2024-03-26 09:04:13 +11:00
8205c56c8a feat(installer): remove dialog references in the launcher
The launcher isn't well served by the additional complexity of two different UIs.
2024-03-26 09:04:13 +11:00
c856fab7d1 fix(ui): load default workflows mutation error
Loading default workflows sometimes requires we mutate the workflow object in order to change the category or ID of the workflow.

This happens in `invokeai/frontend/web/src/features/nodes/util/workflow/validateWorkflow.ts`

The data we get back from the query hooks is frozen and sealed by redux, because they are part of redux state. We need to clone the workflow before operating on it.

It's not clear how this ever worked in the past, because redux state has always been frozen and sealed.
2024-03-26 08:30:25 +11:00
d63d26924b tests: default settings union evaluation 2024-03-25 07:40:52 -04:00
2ec03ae95c fix(mm): default settings pydantic error
Add `extra="forbid"` to the default settings models.

Closes #6035.

Pydantic has some quirks related to unions. This affected how the union of default settings was evaluated. See https://github.com/pydantic/pydantic/issues/9095 for a detailed description of the behaviour that this change addresses.
2024-03-25 07:40:52 -04:00
0f02a72cb9 allow deletion of symlinked models in models dir 2024-03-22 18:29:24 -07:00
37fd57d4d9 Update probe.py
Minor case-sensitive typo. `ModelType.Lora` should be `ModelType.LoRA`
2024-03-22 09:09:56 -07:00
cf0c7d66ed chore: v4.0.0rc5 2024-03-22 02:35:16 -07:00
5b016bf376 fix(nodes): esrgan model name typo 2024-03-22 02:22:19 -07:00
e7a096dec1 fix(mm): remove proteus model
This model is SDXL and relies on CLIP Skip. We don't support that yet.
2024-03-22 02:22:03 -07:00
281ecd5a9a chore(nodes): update default workflows for v4
All workflows updated and tested
2024-03-22 02:21:33 -07:00
9cbf78542c remove dangling comment 2024-03-22 16:35:42 +11:00
34f5259980 catch ^C at startup time while models are being scanned 2024-03-22 16:35:42 +11:00
2ecbb9f720 fix(ui): model dependency parsing 2024-03-22 14:59:33 +11:00
ab36d7c0f2 chore(ui): typegen 2024-03-22 14:59:33 +11:00
05d6661877 feat(mm): revised list of starter models
- Enriched dependencies to not just be a string - allows reuse of a dependency as a starter model _and_ dependency of another model. For example, all the SDXL models have the fp16 VAE as a dependency, but you can also download it on its own.
- Looked at popular models on the major model sites to select the list. No SD2 models. All hosted on HF.
2024-03-22 14:59:33 +11:00
eb558d72d8 Fix minor bugs involving model manager handling of model paths (#6024)
* Fix minor bugs involving model manager handling of model paths

- Leave models found in the `autoimport` directory there. Do not move them
  into the `models` hierarchy.
- If model name, type or base is updated and model is in the `models` directory,
  update its path as appropriate.
- On startup during model scanning, if a model's path is a symbolic link, then resolve
  to an absolute path before deciding it is a new model that must be hashed and
  registered. (This prevents needless hashing at startup time).

* fix issue with dropped suffix

---------

Co-authored-by: Lincoln Stein <lstein@gmail.com>
2024-03-22 01:14:45 +00:00
4687739319 ui: Update rgbaToHex to optionally return alpha value or not 2024-03-22 06:23:51 +05:30
168b35f86d fix: make the styling of the hex code component consistent with others 2024-03-22 06:23:51 +05:30
07fe0e8dc8 chore: Move color transformers to new file 2024-03-22 06:23:51 +05:30
45fc7d8054 feat: add Hex Code to ColorField Component 2024-03-22 06:23:51 +05:30
eafc85cfe3 feat: Add Mask from ID Node 2024-03-22 06:23:51 +05:30
ddf917f68c translationBot(ui): update translation (Russian)
Currently translated at 99.5% (1117 of 1122 strings)

Co-authored-by: Васянатор <ilabulanov339@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/
Translation: InvokeAI/Web UI
2024-03-22 10:57:47 +11:00
c90807ba33 translationBot(ui): update translation (Italian)
Currently translated at 98.2% (1102 of 1122 strings)

translationBot(ui): update translation (Italian)

Currently translated at 97.9% (1099 of 1122 strings)

translationBot(ui): update translation (Italian)

Currently translated at 97.9% (1099 of 1122 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-03-22 10:57:47 +11:00
842b57e57c tests: update config tests
- Add patched rootdir fixture to all config tests. I think this isn't strictly necessary but it does ensure that any config tests that need to write files don't accidentally write to user data locations.
- Be more careful when calling `get_config()` in the tests, by clearing the LRU cache before and after. This ensures a test doesn't reference the singleton config created by a previously run test.
- Add test for env var parsing.
- Add test for config writing in the context of `get_config()`. This is effectively a mini e2e test for the config lifecycle.
2024-03-22 09:53:02 +11:00
f538ed54fb fix(config): do not write env vars to config files
Add class `DefaultInvokeAIAppConfig`, which inherits from `InvokeAIAppConfig`. When instantiated, this class does not parse environment variables, so it outputs a "clean" default config. That's the only difference.

Then, we can use this new class in the 3 places:
- When creating the example config file (no env vars should be here)
- When migrating a v3 config (we want to instantiate the migrated config without env vars, so that when we write it out, they are not written to disk)
- When creating a fresh config file (i.e. on first run with an uninitialized root or new config file path - no env vars here!)
2024-03-22 09:53:02 +11:00
d0a936ebd4 fix(mm): do not write config file when migrating models.yaml 2024-03-22 09:53:02 +11:00
27622dfd5e allow checkpoint config files to use root-relative paths 2024-03-22 08:57:45 +11:00
72b44f7ebc feat(mm): rename "blake3" to "blake3_multi"
Just make it clearer which is which.
2024-03-22 08:26:36 +11:00
7726d312e1 feat(mm): default hashing algo to blake3_single
For SSDs, `blake3` is about 10x faster than `blake3_single` - 3 files/second vs 30 files/second.

For spinning HDDs, `blake3` is about 100x slower than `blake3_single` - 300 seconds/file vs 3 seconds/file.

For external drives, `blake3` is always worse, but the difference is highly variable. For external spinning drives, it's probably way worse than internal.

The least offensive algorithm is `blake3_single`, and it's still _much_ faster than any other algorithm.
2024-03-22 08:26:36 +11:00
61520dfb86 gh: update pr template
Minor tweaks
2024-03-22 07:56:37 +11:00
6e869e6038 fix(ui): migrate redux state that has models
With the change to model identifiers from v3 to v4, if a user had persisted redux state with the old format, we could get unexpected runtime errors when rehydrating state if we try to access model attributes that no longer exist.

For example, the CLIP Skip component does this:

```ts
CLIP_SKIP_MAP[model.base].maxClip
```

In v3, models had a `base_type` attribute, but it is renamed to `base` in v4. This code therefore causes a runtime error:
- `model.base` is `undefined`
- `CLIP_SKIP_MAP[undefined]` is also undefined
- `undefined.maxClip` is a runtime error!

Resolved by adding a migration for the redux slices that have model identifiers. The migration simply resets the slice or the part of the slice that is affected, when it's simple to do a partial reset.

Closes #6000
2024-03-22 07:55:13 +11:00
9eacc0c189 fix(ui): use the old combobox component for dropdowns
Closes #6011
2024-03-22 07:33:52 +11:00
23606d9e83 pkg: pin version of ruff
If you switch between different branches, by the time you get back to `main`, a different version of `ruff` might be installed that has slightly different formatting rules. This leads to incorrect formatting changes.

Pinning `ruff` avoids this issue.
2024-03-22 07:27:06 +11:00
d4d0fea078 [feature] Add probe for SDXL controlnet models (#5382)
* add probe for SDXL controlnet models

* Update invokeai/backend/model_management/model_probe.py

Co-authored-by: Ryan Dick <ryanjdick3@gmail.com>

* Update invokeai/backend/model_manager/probe.py

Co-authored-by: Ryan Dick <ryanjdick3@gmail.com>

---------

Co-authored-by: Lincoln Stein <lstein@gmail.com>
Co-authored-by: Ryan Dick <ryanjdick3@gmail.com>
2024-03-21 14:49:45 +00:00
a5771f6120 chore(docker): remove outdated comments from docker-compose 2024-03-21 10:34:52 -04:00
35f847d5b7 fix(docker): add env vars for host and port to the Dockerfile 2024-03-21 10:34:52 -04:00
3278497674 feat(docker): remove separate pre-installation of PyTorch in the image 2024-03-21 10:34:52 -04:00
c9350f71be feat(docker): improve directory handling and expand environment variable documentation 2024-03-21 10:34:52 -04:00
b00e27b022 fix(docker): ensure the container has write permission to the runtime directory 2024-03-21 10:34:52 -04:00
a6283b9fb6 tidy: "fit_image_to_resolution" -> "resize_image_to_resolution" 2024-03-21 07:02:57 -07:00
64fb15e117 chore: ruff 2024-03-21 07:02:57 -07:00
7019d93ff0 feat(ui): add missing detect_resolution to processors 2024-03-21 07:02:57 -07:00
7467768d48 chore(ui): typegen 2024-03-21 07:02:57 -07:00
e2d7b514e0 tidy: correct attributions for controlnet processors 2024-03-21 07:02:57 -07:00
c36d12a50f feat: adaptation of Lineart Anime processor
Adapted from https://github.com/huggingface/controlnet_aux
2024-03-21 07:02:57 -07:00
c7f8fe4d5e feat: adaptation of Lineart processor
Adapted from https://github.com/huggingface/controlnet_aux
2024-03-21 07:02:57 -07:00
ffb41c3616 feat: adaptation of HED processor
Adapted from controlnet repo
2024-03-21 07:02:57 -07:00
611006b692 feat: adaptation of Canny processor
Adapted from controlnet processors package

fix: do final resize in canny processor

canny
2024-03-21 07:02:57 -07:00
ca496f0380 feat: add image utils
These all support controlnet processors.

- `pil_to_cv2`
- `cv2_to_pil`
- `pil_to_np`
- `np_to_pil`
- `normalize_image_channel_count` (a readable version of `HWC3` from the controlnet repo)
- `fit_image_to_resolution` (a readable version of `resize_image` from the controlnet repo)
- `non_maximum_suppression` (a readable version of `nms` from the controlnet repo)
- `safe_step` (a readable version of `safe_step` from the controlnet repo)
2024-03-21 07:02:57 -07:00
01d8ab04a5 feat(nodes): add missing detect_resolution to processors
Some processors, like Canny, didn't use `detect_resolution`. The resultant control images were then resized by the processors from 512x512 to the desired dimensions. The result is that the control images are the right size, but very low quality.

Using detect_resolution fixes this.
2024-03-21 07:02:57 -07:00
7a4122235f feat(mm): display progress when hashing files 2024-03-21 17:24:48 +11:00
75f4e27522 tidy(mm): clean up model download/install logs 2024-03-21 16:41:20 +11:00
8ae757334e feat(mm): make installer thread logging stmts debug 2024-03-21 16:41:20 +11:00
2038064a34 add timeouts to the download tests 2024-03-21 16:41:20 +11:00
689cb9d31d after stopping install and download services, wait for thread exit 2024-03-21 16:41:20 +11:00
0cab1d1e04 added debugging statements 2024-03-21 16:41:20 +11:00
9bd7dabed3 refactor big _install_next_item() loop 2024-03-21 16:41:20 +11:00
30283a4767 fix(ui): set aspect ratio to free when using default model settings
We need to use the `widthRecalled` and `heightRecalled` actions, which handle the aspect ratio.

Closes  #5974
2024-03-21 16:30:52 +11:00
dacfe6853e Update rc version, regenerate schema 2024-03-20 08:21:23 -07:00
2b093da4b0 Remove no longer used pwinput dependency 2024-03-20 08:15:37 -07:00
368c1b709c chore: v4.0.0rc3
RC version bump
2024-03-20 05:59:08 -07:00
2269253a6c docs: update installation docs
Remove/edit references to configure script.
2024-03-20 05:48:02 -07:00
3490aee247 tidy(installer): remove unused messages 2024-03-20 05:48:02 -07:00
f592ad3649 fix(installer): remove configure flow from installer 2024-03-20 05:48:02 -07:00
42a2bad936 fix(installer): remove deleted scripts from launcher
These scripts no longer exist and need to be removed from the launcher:
- invokeai-ti
- invokeai-merge
- invokeai-model-install
- invokeai-configure
2024-03-20 05:48:02 -07:00
ba2fd875ad fix(ui): typo 2024-03-20 16:26:14 +11:00
9d30a063e7 fix: remaining strings 2024-03-20 16:26:14 +11:00
dc9a9c0160 fix: not translated strings 2024-03-20 16:26:14 +11:00
d45931a0af fix(ui): localize text 2024-03-20 16:26:14 +11:00
c1de129bbc fix(ui): use refiner's seamless node for i2l VAE
Closes  #5995
2024-03-20 16:08:27 +11:00
bf852348aa Update pytorch and xFormers 2.1.2 -> 2.2.1 2024-03-20 15:16:08 +11:00
fc63419c6e fix(ui): refresh starter models on model add/update/delete 2024-03-20 15:05:25 +11:00
c356cabe97 chore(ui): lint 2024-03-20 15:05:25 +11:00
97fe6e483d fix(mm): do not attempt to reinstall starter model dependencies 2024-03-20 15:05:25 +11:00
1069303309 fix(config): remove configure arg & logic from docker image 2024-03-20 15:05:25 +11:00
eb607498bf fix(config): create parent dir when writing config file 2024-03-20 15:05:25 +11:00
bdb52cfcf7 feat(ui): set HF token in MM tab
- Display a toast on UI launch if the HF token is invalid
- Show form in MM if token is invalid or unable to be verified, let user set the token via this form
2024-03-20 15:05:25 +11:00
3f6f8199f6 chore(ui): typegen 2024-03-20 15:05:25 +11:00
9a5575b46b feat(mm): move HF token helper to route 2024-03-20 15:05:25 +11:00
dea9142cb8 tests: fix config test after changing config schema version format 2024-03-20 15:05:25 +11:00
02329df1df feat(config): write example config file out on app startup 2024-03-20 15:05:25 +11:00
f5337c7ce2 fix(config): handle relative paths to v3 models.yamls 2024-03-20 15:05:25 +11:00
b02f2da71d fix(config): handle legacy_conf_dir setting migration 2024-03-20 15:05:25 +11:00
6c13fa13ea fix(mm): regression from change to legacy conf dir change 2024-03-20 15:05:25 +11:00
040ea8f41b tidy: do not show msg when loading NSFW checker 2024-03-20 15:05:25 +11:00
13c72206d8 docs: update CONFIGURATION.md 2024-03-20 15:05:25 +11:00
96ef7e3889 docs: add link to docs to invokeai.yaml template 2024-03-20 15:05:25 +11:00
2eacbb4d9d fix(nodes): do not load NSFW checker model on startup
Just check if the path exists to determine if it is "available". When needed, load it.
2024-03-20 15:05:25 +11:00
0e51495071 chore(ui): lint 2024-03-20 15:05:25 +11:00
b378cfcb46 cleanup: remove unused scripts, cruft
App runs & tests pass.
2024-03-20 15:05:25 +11:00
6c558279dd feat(config): add CLI arg to specify config file
This allows users to create simple "profiles" via separate `invokeai.yaml` files.

- Remove `InvokeAIAppConfig.set_root()`, it's extraneous
- Remove `InvokeAIAppConfig.merge_from_file()`, it's extraneous
- Add `--config` to the app arg parser, add `InvokeAIAppConfig._config_file`, and consume in the config singleton getter
- `InvokeAIAppConfig.init_file_path` -> `InvokeAIAppConfig.config_file_path`
2024-03-20 15:05:25 +11:00
bd3e8cbdfb feat(ui): add starter models tab to MM
Lists all starter models with an install button if the model is not yet installed.
2024-03-20 15:05:25 +11:00
aa689e5384 style(ui): tweak ModelBaseBadge style 2024-03-20 15:05:25 +11:00
484488dee4 feat(ui): add useStarterModelsToast
This displays a toast linking to the MM tab when there are no main models installed. It is a no-op when the `starterModels` feature is disabled.
2024-03-20 15:05:25 +11:00
e40b715f39 feat(ui): add starterModels feature
This can be disabled to prevent a toast from appearing, linking users to the model manager tab.
2024-03-20 15:05:25 +11:00
e8f4012b56 feat(ui): extract FetchingModelsLoader into reusable component 2024-03-20 15:05:25 +11:00
bc12ca9220 chore(ui): typegen 2024-03-20 15:05:25 +11:00
5ceaeb234d feat(mm): add starter models route
The models from INITIAL_MODELS.yaml have been recreated as a structured python object. This data is served on a new route. The model sources are compared against currently-installed models to determine if they are already installed or not.
2024-03-20 15:05:25 +11:00
429f87c60b fix(mm): HFModelSource string format
The dunder `__str__` method for `HFModelSource` was appending a colon `:` to the end of the source strings.
2024-03-20 15:05:25 +11:00
ee3096f616 feat(config): add flag to indicate if args were parsed
This flag acts as a proxy for the `get_config()` function to determine if the full application is running.

If it was, the config will set the root, do HF login, etc.

If not (e.g. it's called by an external script), all that stuff will be skipped.
2024-03-20 15:05:25 +11:00
6af6673a4f feat: move all config-related initialization to app
HF login, legacy yaml confs, and default init file are all handled during app setup.

All directories are created as they are needed by the app.

No need to check for a valid root dir - we will make it if it doesn't exist.
2024-03-20 15:05:25 +11:00
b173e4c08d tidy(config): type checker ignores + comment 2024-03-20 15:05:25 +11:00
059f869737 tidy(config): remove ignore_missing_core_models CLI arg and setting
This is now a no-op, with all models being downloaded when they are first requested.
2024-03-20 15:05:25 +11:00
813e679b77 feat: add hf_login util
This provides a simple way to provide a HF token. If HF reports no valid token, one is prompted for until a valid token is provided, or the user presses Ctrl + C to cancel.
2024-03-20 15:05:25 +11:00
857e9c9b5f feat: add SuppressOutput util
This context manager suppresses/hides stdout.
2024-03-20 15:05:25 +11:00
5c1aa02e7b fix(config): set default legacy_conf_dir to configs
It was `configs/stable-diffusion` before, which broke conversions.
2024-03-20 15:05:25 +11:00
0e3fb4e97a deps: add pwinput, pinned to specific fork
This simple package provides a cross-platform way to type a password on the CLI and have it show up as asterisks.

The fork, pending merge into the upstream package, adds support for Ctrl+C to cancel input.
2024-03-20 15:05:25 +11:00
6e882d3fd6 feat(config): dynamic ram cache size
Use the util function to calculate ram cache size on startup. This way, the `ram` setting will always be optimized for a system, even if they add or remove RAM. In other words, the default value is now dynamic.
2024-03-20 15:05:25 +11:00
fabef8b45b feat(mm): download upscaling & lama models as they are requested 2024-03-20 15:05:25 +11:00
97f16b2b7e fix(ui): fix model install progress display 2024-03-20 15:05:25 +11:00
609c2c0abf Fix: progress image preview for inpainting 2024-03-20 13:36:05 +11:00
fe5fa7f8cc chore: make ruff 2024-03-20 13:36:05 +11:00
8b30cbe81e chore: clean up old code comments 2024-03-20 13:36:05 +11:00
2af9286345 fix: denoise mask incorectly applied after step 2024-03-20 13:36:05 +11:00
29b04b7e83 chore: bump nodes versions
Bump all nodes in prep for v4.0.0.
2024-03-20 10:28:07 +11:00
04aa97f0fd gh: update pr template 2024-03-20 10:19:04 +11:00
39fa8874fc undo 2024-03-20 10:05:46 +11:00
4e245e9331 fix refiner metadata 2024-03-20 10:05:46 +11:00
74a51571a0 Fix race condition causing hangs during model install unit tests (#5994)
* fix race condition causing hangs during model install unit tests

* remove extraneous sanity checks

---------

Co-authored-by: Lincoln Stein <lstein@gmail.com>
2024-03-19 20:54:49 +00:00
c87497fd54 record model_variant in t2i and clip_vision configs (#5989)
- Move base of t2i and clip_vision config models to DiffusersBase, which contains
  a field to record the model variant (e.g. "fp16")
- This restore the ability to load fp16 t2i and clip_vision models
- Also add defensive coding to load the vanilla model when the fp16 model
  has been replaced (or more likely, user's preferences changed since installation)

Co-authored-by: Lincoln Stein <lstein@gmail.com>
2024-03-19 20:14:12 +00:00
3f61c51c3a fix(ui): model list refreshes after changes
When consolidating all the model queries I messed up the query tags. Fixed now, so that when a model is installed, removed, or changed, the list refreshes.
2024-03-20 06:25:57 +11:00
07c9c0b0ab translationBot(ui): update translation (Russian)
Currently translated at 99.5% (1091 of 1096 strings)

Co-authored-by: Васянатор <ilabulanov339@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/
Translation: InvokeAI/Web UI
2024-03-19 22:34:53 +11:00
2322d3cbbe translationBot(ui): update translation (Japanese)
Currently translated at 52.5% (576 of 1096 strings)

translationBot(ui): update translation (Japanese)

Currently translated at 52.0% (570 of 1096 strings)

Co-authored-by: Gohsuke Shimada <ghoskay@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ja/
Translation: InvokeAI/Web UI
2024-03-19 22:34:53 +11:00
419ce02aae translationBot(ui): update translation (Italian)
Currently translated at 98.2% (1077 of 1096 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.2% (1077 of 1096 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-03-19 22:34:53 +11:00
629ccd059e translationBot(ui): update translation files
Updated by "Cleanup translation files" hook in Weblate.

translationBot(ui): update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/
Translation: InvokeAI/Web UI
2024-03-19 22:34:53 +11:00
2dfa51c2e5 translationBot(ui): update translation (Russian)
Currently translated at 99.0% (1518 of 1533 strings)

translationBot(ui): update translation (Russian)

Currently translated at 99.0% (1518 of 1533 strings)

Co-authored-by: Васянатор <ilabulanov339@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/
Translation: InvokeAI/Web UI
2024-03-19 22:34:53 +11:00
edde0fe174 translationBot(ui): update translation (Bulgarian)
Currently translated at 3.9% (61 of 1533 strings)

translationBot(ui): update translation (Bulgarian)

Currently translated at 1.8% (28 of 1533 strings)

translationBot(ui): added translation (Bulgarian)

Co-authored-by: Sufi2425 <sufi24251@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/bg/
Translation: InvokeAI/Web UI
2024-03-19 22:34:53 +11:00
3e46f7a010 translationBot(ui): update translation (Italian)
Currently translated at 97.8% (1510 of 1543 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.1% (1503 of 1532 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.1% (1503 of 1532 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-03-19 22:34:53 +11:00
faa555df20 chore(ui): lint 2024-03-19 22:11:48 +11:00
7a3e19227f feat(ui): display created_by using valueOrNull 2024-03-19 22:11:48 +11:00
e706afe8a6 feat(ui): add valueOrNull to useMetadataItem
In order to allow for null and undefined metadata values, this hook returned a symbol to indicate that parsing failed or was pending.

For values where the parsed value will never be null or undefined, it is useful get the value or null (instead of a symbol).
2024-03-19 22:11:48 +11:00
acca197893 revert(ui): restore metadata parsers for created_by 2024-03-19 22:11:48 +11:00
aa2c404cab move created_by out of recall panel 2024-03-19 22:11:48 +11:00
300a4693ae prettier 2024-03-19 21:59:51 +11:00
820614e4d8 ruff 2024-03-19 21:59:51 +11:00
fe563f05fc tsc 2024-03-19 21:59:51 +11:00
d89e653588 fix(ui): remove image_resolution from colormap 2024-03-19 21:59:51 +11:00
4e9207a10b fix(worker): remove resolution from zoe as it seems to break it 2024-03-19 21:59:51 +11:00
8c6c33a315 'feat(ui): update processor constants to calculate default resolution based on current base model, add image_resolution to the processors that didn't have it in the UI as a configurable op
tion
2024-03-19 21:59:51 +11:00
ed0f9f7d66 feat(worker): add image_resolution as option for all cnet procesors 2024-03-19 21:59:51 +11:00
b25850a585 typegen 2024-03-19 21:59:51 +11:00
94257e35f5 Comment out test failing to run due to issue in model install service 2024-03-19 01:16:11 -04:00
19e16384f7 Remove redundant embedding file read 2024-03-19 01:16:11 -04:00
a3ed6e694c Use wait_for_job instead of wait_for_installs 2024-03-19 01:16:11 -04:00
20d9d10798 Wrap in try except for InvalidModelConfigException 2024-03-19 01:16:11 -04:00
77a70a8a9c Skip hashing in test_heuristic_import_with_type 2024-03-19 01:16:11 -04:00
06abea8db0 Increase timeout for test_heuristic_import_with_type, fix Url import 2024-03-19 01:16:11 -04:00
a28f0932e6 Run ruff 2024-03-19 01:16:11 -04:00
6968a068bb Fix test to run on windows vms 2024-03-19 01:16:11 -04:00
9d5b96c119 Pull format type setting out of model_type if statement 2024-03-19 01:16:11 -04:00
5daefccf77 Simplify logic for determining model type in probe 2024-03-19 01:16:11 -04:00
1f3c35ee90 Run Ruff 2024-03-19 01:16:11 -04:00
f78ed3a952 Add unit test 2024-03-19 01:16:11 -04:00
d38262a7ea Allow type field to be a string 2024-03-19 01:16:11 -04:00
5feb62d440 Allow users to specify model type and skip detection step of probe 2024-03-19 01:16:11 -04:00
f8df293d2c Revert "fix(mm): provide ckpt config as stream to diffusers"
This reverts commit 9d045964d6.
2024-03-19 14:24:54 +11:00
9d045964d6 fix(mm): provide ckpt config as stream to diffusers
Fixes converting ckpt main models
2024-03-19 09:24:28 +11:00
9fa9ebe386 fix(config): set ignore_missing_core_models when provided as CLI arg 2024-03-19 09:24:28 +11:00
1cb1b60b4c tidy: "check_root.py" -> "check_directories.py" 2024-03-19 09:24:28 +11:00
1d4517d00d tidy: "validate_root" -> "validate_directories" 2024-03-19 09:24:28 +11:00
982b513af3 tidy(config): move a few get_config calls to inside the functions where they are needed 2024-03-19 09:24:28 +11:00
f1450c2c24 update textual inversion training to use root_path rather than root_dir 2024-03-19 09:24:28 +11:00
5d16a40b95 fix invokeai-configure to use isolated argument-parsing pattern 2024-03-19 09:24:28 +11:00
d871fca643 partially address --root CLI argument handling
- fix places where `get_config()` is being called at import time rather
  than at run time.

- add regression test for import time get_config() calling.
2024-03-19 09:24:28 +11:00
8cd65755ef make invokeai-model-install use the --root argument correctly 2024-03-19 09:24:28 +11:00
e76cc71e81 fix(config): edge cases in models.yaml migration
When running the configurator, the `legacy_models_conf_path` was stripped when saving the config file. Then the migration logic didn't fire correctly, and the custom models.yaml paths weren't migrated into the db.

- Rework the logic to migrate this path by adding it to the config object as a normal field that is not excluded from serialization.
- Rearrange the models.yaml migration logic to remove the legacy path after migrating, then write the config file. This way, the legacy path doesn't stick around.
- Move the schema version into the config object.
- Back up the config file before attempting migration.
- Add tests to cover this edge case
2024-03-19 09:24:28 +11:00
1ed1c1fb24 chore: ruff 2024-03-19 09:24:28 +11:00
9063ea9173 tests: comprehensive config migration tests
Add testing for the settings that had to be explicitly migrated.
2024-03-19 09:24:28 +11:00
4633242503 tidy(config): move config docstring builder to its script 2024-03-19 09:24:28 +11:00
e8b030427d fix(config): do not discard conf_path, migrate custom models.yaml
Hold onto `conf_path` temporarily while migrating `invokeai.yaml` so that it gets migrated correctly as the model installer starts up. Stashed as `legacy_models_yaml_path` in the config, excluded from serialization.
2024-03-19 09:24:28 +11:00
415a4baf78 docs: add note about pydantic-settings' yaml support 2024-03-19 09:24:28 +11:00
09a8c0328a docs: update CONFIGURATION.md 2024-03-19 09:24:28 +11:00
e32c609fec fix(config): ignore empty environment variables (use default values instead) 2024-03-19 09:24:28 +11:00
beffca6b49 docs: update CONFIGURATION.md 2024-03-19 09:24:28 +11:00
a281671e6c docs: update InvokeAIAppConfig doc generator
It now renders the valid values.
2024-03-19 09:24:28 +11:00
5179587b5a feat(config): restore ignore_missing_core_models arg 2024-03-19 09:24:28 +11:00
cb180909f7 fix(install): resolve config-related issues with configurator
- Do not use the singleton app config, this causes a lot of weirdness
- Update logic to use new config object
- Remove unused code
2024-03-19 09:24:28 +11:00
ce9aeeece3 feat: single app entrypoint with CLI arg parsing
We have two problems with how argparse is being utilized:
- We parse CLI args as the `api_app.py` file is read. This causes a problem pytest, which has an incompatible set of CLI args. Some tests import the FastAPI app, which triggers the config to parse CLI args, which receives the pytest args and fails.
- We've repeatedly had problems when something that uses the config is imported before the CLI args are parsed. When this happens, the root dir may not be set correctly, so we attempt to operate on incorrect paths.

To resolve these issues, we need to lift CLI arg parsing outside of the application code, but still let the application access the CLI args. We can create a external app entrypoint to do this.

- `InvokeAIArgs` is a simple helper class that parses CLI args and stores the result.
- `run_app()` is the new entrypoint. It first parses CLI args, then runs `invoke_api` to start the app.

The `invokeai-web` project script and `invokeai-web.py` dev script now call `run_app()` instead of `invoke_api()`.

The first time `get_config()` is called to get the singleton config object, it retrieves the args from `InvokeAIArgs`, sets the root dir if provided, then merges settings in from `invokeai.yaml`.

CLI arg parsing is now safely insulated from application code, but still accessible. And we don't need to worry about import order having an impact on anything, because by the time the app is running, we have already parsed CLI args. Whew!
2024-03-19 09:24:28 +11:00
5ecfa86cd0 tests: fix test on macos 2024-03-19 09:24:28 +11:00
d09f03ef25 fix(config): if no invokeai.yaml is found, create a default one
This fixes an issue with `test_images.py`, which tests the bulk images routers and imports the whole FastAPI app. This triggers the config logic which fails on the test runner, because it has no `invokeai.yaml`.

Also probably just good for graceful fallback.
2024-03-19 09:24:28 +11:00
3f8e2bfd18 fix(config): migrate deprecated max_cache_size and max_vram_cache_size settings 2024-03-19 09:24:28 +11:00
60492500db chore: ruff 2024-03-19 09:24:28 +11:00
f69938c6a8 fix(config): revised config methods
- `write_file` requires an destination file path
- `read_config` -> `merge_from_file`, if no path is provided, reads from `self.init_file_path`
- update app, tests to use new methods
- fix configurator, was overwriting config file data unexpectedly
2024-03-19 09:24:28 +11:00
5e39e46954 feat(config): more resiliant update_config method
Only set values that have changed.
2024-03-19 09:24:28 +11:00
1079bf3ccf feat(config): fix bad compress_level setting
Tweak the name of it so that incoming configs with the old default value of 6 have the setting stripped out. The result is all configs will now have the new, much better default value of 1.
2024-03-19 09:24:28 +11:00
fbbf9c01b5 tests: fix remaining tests 2024-03-19 09:24:28 +11:00
15cef98a8b tests: fix docs test 2024-03-19 09:24:28 +11:00
5606f4d627 tests: redo config tests 2024-03-19 09:24:28 +11:00
53c8f36029 docs(config): clarify comment during config migration 2024-03-19 09:24:28 +11:00
b9884a6166 feat(config): split out parse_args and read_config logic from get_config
Having this all in the `get_config` function makes testing hard. Move these two functions to their own methods, and call them on app startup explicitly.
2024-03-19 09:24:28 +11:00
77b86e9ad5 fix(install): remove broken v2.3 -> v3 migration logic from configurator 2024-03-19 09:24:28 +11:00
a6181b5759 fix(install): update configurator to use new config system 2024-03-19 09:24:28 +11:00
b4b0af7c60 fix(install): do not use deprecated pydantic methods 2024-03-19 09:24:28 +11:00
3d1f3818cb fix(config): use set_root to set root 2024-03-19 09:24:28 +11:00
deffeb9655 fix(config): use get_config singleton, new paths 2024-03-19 09:24:28 +11:00
b8c46fb15b fix(config): split check_invokeai_root into separate function to validate, use this in model_install to determine if need to run configurator 2024-03-19 09:24:28 +11:00
9539ecce79 fix(config): use correct config in textual_inversion_training 2024-03-19 09:24:28 +11:00
7716a4a8c7 fix(config): use correct config in install_helper 2024-03-19 09:24:28 +11:00
dedce2d896 fix(config): remove unnecessary resolve on config path 2024-03-19 09:24:28 +11:00
e43bfa3d70 docs(mm): do not hide members in InvokeAIAppConfig autodoc 2024-03-19 09:24:28 +11:00
897fe497dc fix(config): use new get_config across the app, use correct settings 2024-03-19 09:24:28 +11:00
7b1f9409bc fix(config): drop nonexistent config.use_cpu setting 2024-03-19 09:24:28 +11:00
a72cea014c fix(config): drop usage of deprecated config.xformers, just use the existing utility function 2024-03-19 09:24:28 +11:00
b4182b190f fix(config): use new config.patchmatch 2024-03-19 09:24:28 +11:00
22ac204678 fix(config): fix invisible_watermark handling
This setting was hardcoded to True. Simplified logic around it to not have a conditional that does nothing.
2024-03-19 09:24:28 +11:00
7ca447ded1 fix(config): use new config setup in api_app.py 2024-03-19 09:24:28 +11:00
4df28f1de6 fix(config): use yaml module instead of omegaconf when migrating models.yaml
Also use new paths.
2024-03-19 09:24:28 +11:00
ebd0cb6113 fix(config): remove reference to internet_available
Nothing ever set this. Only a debug print statement referenced it.
2024-03-19 09:24:28 +11:00
fbe3afa5e1 fix(config): fix nsfw_checker handling
This setting was hardcoded to True. Rework logic around it to not conditionally check the setting.
2024-03-19 09:24:28 +11:00
3fb116155b refactor(config): simplified config
- Remove OmegaConf. It functioned as an intermediary data format, between YAML/argparse and pydantic. It's not necessary - we can parse YAML or CLI args directly with pydantic.

- Remove dynamic CLI args. Only `root` is explicitly supported. This greatly simplifies config handling. Configuration is done by editing the YAML file. Frequently-used args can be added if there is a demand.

- A separate arg parser is created to handle the slimmed-down CLI args. It's run immediately in the `invokeai-web` script to handle `--version` and `--help`. It is also used inside the singleton config getter (see below).

- Remove categories from the config. Our settings model is mostly flat. Handling categories adds complexity for both us and users - we have to handle transforming a flat config to categorized config (and vice-versa), while users have to be careful with indentation in their YAML file.

- Add a `meta` key to the config file. Currently, this holds the config schema version only. It is not a part of the config object itself.

- Remove legacy settings that are no longer referenced, or were effectively no-op settings when referenced in code.

- Implement simple migration logic to for v3 configs. If migration is successful, the v3 config file is backed up to `invokeai.yaml.bak` and the new config written to `invokeai.yaml`.

- Previously, the singleton config was accessed by calling `InvokeAIAppConfig.get_config()`. This returned an instance of `InvokeAIAppConfig`, which _also_ has the `get_config` function. This created to a confusing situation where you weren't sure if you needed to call `get_config` or just use the config object. This method is replaced by a standalone `get_config` function which returns a singleton config object.

- Wrap CLI arg parsing (for `root`) and loading/migrating `invokeai.yaml` into the new `get_config()` function.

- Move `generate_config_docstrings` into standalone utility function.

- Make `root` a private attr (`_root`). This reduces the temptation to directly modify and or use this sensitive field and ensures it is neither serialized nor read from input data. Use `root_path` to access the resolved root path, or `set_root` to set the root to something.
2024-03-19 09:24:28 +11:00
7387b0bdc9 install missing clip_vision encoders if required by an ip adapter (#5982)
Co-authored-by: Lincoln Stein <lstein@gmail.com>
2024-03-18 02:19:53 +00:00
7ea9cac9a3 Add sdxl controlnet models (#5980)
* allow removal of models with legacy relative path addressing

* added five controlnet models for sdxl to INITIAL_MODELS

---------

Co-authored-by: Lincoln Stein <lstein@gmail.com>
2024-03-18 01:15:15 +00:00
ea5bc94b9c Resolve when instantiating _cached_model_paths 2024-03-18 11:17:23 +11:00
a1743647b7 Stop registering and moving models which have symlinks in the models dir 2024-03-18 11:17:23 +11:00
a6d64f69e1 Remove core conversion models (#5981)
## What type of PR is this? (check all applicable)

- [ ] Refactor
- [ ] Feature
- [ ] Bug Fix
- [X] Optimization
- [ ] Documentation Update
- [ ] Community Node Submission


## Have you discussed this change with the InvokeAI team?
- [X] Yes
- [ ] No, because:

      
## Have you updated all relevant documentation?
- [X] Yes
- [ ] No


## Description

We've been using a forked copy of the diffusers safetensors->diffusers
model conversion code, which was hacked to read CLIP and the other
models needed for conversion from the local invokeai root models
directory. This was getting unsustainable as the code bases diverged,
and also required the installation and maintenance of the "core/convert"
directory.

This PR gets rid of the hacked conversion code and reverts to using the
native diffusers methods. Core convert models are no longer installed at
root configure time. Instead we rely on the HuggingFace hub system to
download the conversion models if and when they are needed. They are
relatively small and the initial delay seems minor.

Conversion of SD-1, SD-2 (both epsilon and v-prediction), SDXL, VAE and
ControlNet SD-1/2 models has been tested. ControlNet SDXL models are
still a WIP due to the need for some work on the prober.

The main implication of this change is that InvokeAI is no longer
internet-independent and will need an internet connection at least the
first time a safetensors file needs to be converted. However, there are
several other places where the "no internet" rule is already violated,
and I suggest that we abandon this principle.

## Related Tickets & Documents

<!--
For pull requests that relate or close an issue, please include them
below. 

For example having the text: "closes #1234" would connect the current
pull
request to issue 1234.  And when we merge the pull request, Github will
automatically close the issue.
-->

- Related Issue #
- Closes #5964 

## QA Instructions, Screenshots, Recordings

1. Remove or move `$INVOKEAI_ROOT/models/.cache`
2. Move `$INVOKEAI/models/core/convert`
3. Try generating with an unconverted .safetensors model.

<!-- 
Please provide steps on how to test changes, any hardware or 
software specifications as well as any other pertinent information. 
-->

## Merge Plan

Merge when approved.

<!--
A merge plan describes how this PR should be handled after it is
approved.

Example merge plans:
- "This PR can be merged when approved"
- "This must be squash-merged when approved"
- "DO NOT MERGE - I will rebase and tidy commits before merging"
- "#dev-chat on discord needs to be advised of this change when it is
merged"

A merge plan is particularly important for large PRs or PRs that touch
the
database in any way.
-->

## Added/updated tests?

- [ ] Yes
- [ ] No : _please replace this line with details on why tests
      have not been included_

## [optional] Are there any post deployment tasks we need to perform?
2024-03-18 11:11:15 +11:00
e74e78894f Merge branch 'main' into optimization/remove-core-conversion-models 2024-03-17 19:25:44 -04:00
71a1740740 Remove core safetensors->diffusers conversion models
- No longer install core conversion models. Use the HuggingFace cache to load
  them if and when needed.

- Call directly into the diffusers library to perform conversions with only shallow
   wrappers around them to massage arguments, etc.

- At root configuration time, do not create all the possible model subdirectories,
  but let them be created and populated at model install time.

- Remove checks for missing core conversion files, since they are no
  longer installed.
2024-03-17 19:13:18 -04:00
b79f2f337e Allow removal of models with legacy relative path addressing (#5979)
* allow removal of models with legacy relative path addressing

* fix ruff error

---------

Co-authored-by: Lincoln Stein <lstein@gmail.com>
2024-03-17 18:07:35 +00:00
a0420d1442 fix ruff error 2024-03-17 14:01:04 -04:00
a17021ba0c allow removal of models with legacy relative path addressing 2024-03-17 09:58:16 -04:00
faa1ffb06f Update diffusers 0.26.3 -> 0.27.0 and other HF packages 2024-03-16 05:44:58 -07:00
8c04eec210 fix initial main model logic 2024-03-15 10:22:16 -04:00
330e1354b4 Run typegen, update version to 4.0.0rc2 2024-03-14 17:01:36 -04:00
21621eebf0 feat(ui): handle control adapter processed images
- Add helper functions to build metadata for control adapters, including the processed images
- Update parses to parse the new metadata
2024-03-14 12:34:03 -07:00
c24f2046e7 chore(ui): typegen 2024-03-14 12:34:03 -07:00
297408d67e feat(nodes): add control adapter processed images to metadata
In the client, a controlnet or t2i adapter has two images:
- The source control image: the image the user selected (required)
- The processed control image: the user's image after we've processed it (optional)

The processed image is optional because a user may provide a pre-processed image.

We only actually use one of these images when building the graph, and until this change, we only stored one of the in image metadata. This created a situation where only a processed image was stored in metadata - say, a canny edge map - and the user-selected image wasn't provided.

By adding the processed image to metadata, we can recall both the control image and optional processed image.

This commit is followed by a UI-facing changes to support the change.
2024-03-14 12:34:03 -07:00
0131e7d928 fix(ui): recall control adapter metadata fields 2024-03-14 12:34:03 -07:00
06ff105a1f fix(ui): reset loras/control adapters when using recall all or remix 2024-03-14 12:34:03 -07:00
bb8e6bbee6 docs: update CONFIGURATION.md
Update model hashing docs
2024-03-15 00:14:48 +11:00
328dc99f3a fix(ui): log model load events
- Fix types
- Fix logging in listener
2024-03-14 18:29:55 +05:30
ef55077e84 feat(events): add submodel_type to model load events
This was lost during MM2 migration
2024-03-14 18:29:55 +05:30
ba3d8af161 fix(events): dump event payloads to serializable format 2024-03-14 18:29:55 +05:30
b07b7af710 feat(ui): single getModelConfigs query (#5962)
## What type of PR is this? (check all applicable)

- [ ] Refactor
- [z] Feature
- [ ] Bug Fix
- [ ] Optimization
- [ ] Documentation Update
- [ ] Community Node Submission

## Description

Single query, with simple wrapper hooks (type-safe). Updated everywhere
in frontend.

## QA Instructions, Screenshots, Recordings

Things that use models should work. All of this code is strictly
typechecked, so we can be confident in this change.

<!-- 
Please provide steps on how to test changes, any hardware or 
software specifications as well as any other pertinent information. 
-->

## Merge Plan

This PR can be merged when approved

<!--
A merge plan describes how this PR should be handled after it is
approved.

Example merge plans:
- "This PR can be merged when approved"
- "This must be squash-merged when approved"
- "DO NOT MERGE - I will rebase and tidy commits before merging"
- "#dev-chat on discord needs to be advised of this change when it is
merged"

A merge plan is particularly important for large PRs or PRs that touch
the
database in any way.
-->
2024-03-14 18:20:38 +05:30
19d66d5ec7 feat(ui): single getModelConfigs query
Single query, with simple wrapper hooks (type-safe). Updated everywhere in frontend.
2024-03-14 23:37:40 +11:00
ed20255abf fix(nodes): depth anything processor (#5956) (#5961)
We were passing a PIL image when we needed to pass the np image.

Closes #5956

## What type of PR is this? (check all applicable)

- [ ] Refactor
- [ ] Feature
- [x] Bug Fix
- [ ] Optimization
- [ ] Documentation Update
- [ ] Community Node Submission


## Description

We were passing a PIL image when we needed to pass the np image.

Closes #5956

## Related Tickets & Documents

<!--
For pull requests that relate or close an issue, please include them
below. 

For example having the text: "closes #1234" would connect the current
pull
request to issue 1234.  And when we merge the pull request, Github will
automatically close the issue.
-->

- Related Issue #
- Closes #5956

## QA Instructions, Screenshots, Recordings

Depth anything processor should work.

<!-- 
Please provide steps on how to test changes, any hardware or 
software specifications as well as any other pertinent information. 
-->

## Merge Plan

This PR can be merged when approved

<!--
A merge plan describes how this PR should be handled after it is
approved.

Example merge plans:
- "This PR can be merged when approved"
- "This must be squash-merged when approved"
- "DO NOT MERGE - I will rebase and tidy commits before merging"
- "#dev-chat on discord needs to be advised of this change when it is
merged"

A merge plan is particularly important for large PRs or PRs that touch
the
database in any way.
-->
2024-03-14 14:57:40 +05:30
fed1f983db fix(nodes): depth anything processor (#5956)
We were passing a PIL image when we needed to pass the np image.

Closes #5956
2024-03-14 20:14:53 +11:00
a386544a1d chore: ruff 2024-03-14 17:32:02 +11:00
0851de9090 closes #5932 2024-03-14 17:32:02 +11:00
1bd8e33f8c Work around missing core conversion model issue
- This adds additional logic to the safetensors->diffusers conversion script
  to check for and install missing core conversion models at runtime.

- Fixes #5934
2024-03-14 16:52:01 +11:00
e3f29ed320 tests: update default settings tests 2024-03-14 16:03:37 +11:00
3fd824306c feat(mm): probe for main model default settings
Currently, this is just the width and height, derived from the model base.
2024-03-14 16:03:37 +11:00
2584a950aa feat(ui): add w/h to default model settings 2024-03-14 16:03:37 +11:00
1adaf63253 chore(ui): typegen 2024-03-14 16:03:37 +11:00
b9f1a4bd65 feat(nodes): add w/h defaults for models 2024-03-14 16:03:37 +11:00
731942dbed feat(nodes): add constraints & descriptions to default settings 2024-03-14 16:03:37 +11:00
4117cea5bf tidy(mm): remove misplaced comment 2024-03-14 15:54:42 +11:00
21617f3bc1 docs: update description for hashing_algorithm in config 2024-03-14 15:54:42 +11:00
9fcd67b5c0 feat(mm): add algorithm prefix to hashes
For example:
- md5:a0cd925fc063f98dbf029eee315060c3
- sha1:9e362940e5603fdc60566ea100a288ba2fe48b8c
- blake3:ce3f0c5f3c05d119f4a5dcaf209b50d3149046a0d3a9adee9fed4c83cad6b4d0
2024-03-14 15:54:42 +11:00
a4be935458 docs: update config docs 2024-03-14 15:54:42 +11:00
eb6e6548ed feat(mm): faster hashing for spinning disk HDDs
BLAKE3 has poor performance on spinning disks when parallelized. See https://github.com/BLAKE3-team/BLAKE3/issues/31

- Replace `skip_model_hash` setting with `hashing_algorithm`. Any algorithm we support is accepted.
- Add `random` algorithm: hashes a UUID with BLAKE3 to create a random "hash". Equivalent to the previous skip functionality.
- Add `blake3_single` algorithm: hashes on a single thread using BLAKE3, fixes the aforementioned performance issue
- Update model probe to accept the algorithm to hash with as an optional arg, defaulting to `blake3`
- Update all calls of the probe to use the app's configured hashing algorithm
- Update an external script that probes models
- Update tests
- Move ModelHash into its own module to avoid circuclar import issues
2024-03-14 15:54:42 +11:00
8287fcf097 feat: ✏️ rename "Workflow Editor" tab label to "Workflows" 2024-03-14 12:22:23 +11:00
dd475e28ed chore(ui): remove unused translation keys via script 2024-03-14 11:38:29 +11:00
24e741e2d1 feat(ui): add script to clean translations
This script removes unused translations from the `en.json` source translation file:
- Parse `en.json` to build a list of all keys, e.g. `controlnet.depthAnything`
- Check every frontend file for every key
- If the key is not found, it is removed from the translation file
- Exact matches (e.g. `controlnet.depthAnything`) and stem matches (e.g. `depthAnything`) are ignored
2024-03-14 11:38:29 +11:00
e0bf9ce5c6 tidy(ui): use normal quotes in translations 2024-03-14 11:38:29 +11:00
c66e8b395e fix(ui): remove unused input on depth anything processor node 2024-03-14 10:53:57 +11:00
4c417adc82 fix(ui): use revised metadata model types
We can also totally remove the fetch logic because we store the same model data in state now.
2024-03-14 10:53:57 +11:00
437a413ca3 chore(ui): typegen 2024-03-14 10:53:57 +11:00
4492bedd19 tidy(nodes): use ModelIdentifierField for model metadata
Until recently, this had a different shape than the ModelMetadataField. They are now the same, so we can re-use the ModelIdentifierField.
2024-03-14 10:53:57 +11:00
db12ce95a8 fix(ui): invalid collect node error w/ control adapters
The graph builders used awaited functions within `Array.prototype.forEach` loops. This doesn't do what you'd think. This caused graphs to be enqueued before they were fully constructed.

 Changed to `for..of` loops to fix this.
2024-03-14 10:53:57 +11:00
ee3a1a95ef fix(ui): control adapters require control images
There wasn't enough validation of control adapters during graph building. It would be possible for a graph to be built with empty collect node, causing an error. Addressed with an extra check.

This should never happen in practice, because the invoke button should be disabled if an invalid CA is active.
2024-03-14 10:53:57 +11:00
4bb5aba70e feat(ui): only fetch TIs on first load, add comment 2024-03-14 07:38:09 +11:00
cd55c23713 initiate TI model query when socket connects so user doesnt have to wait when opening prompt trigger phrases 2024-03-14 07:38:09 +11:00
1d2743af1b remove log 2024-03-14 07:25:48 +11:00
99d2099ccd add key for controladapter CustomSelect too 2024-03-14 07:25:48 +11:00
b64a693f16 try adding a key to force rerender when items load 2024-03-14 07:25:48 +11:00
9d523a3094 chore: cleanup DepthAnything code (#5945)
## What type of PR is this? (check all applicable)

- [x] Optimization

## Description

Was merged into next but never carried over to main. So cleaning up
again.
2024-03-13 20:46:54 +05:30
af660163ca chore: cleanup DepthAnything code 2024-03-13 20:35:52 +05:30
7e4b462fca docs: OVERVIEW.md typo 2024-03-13 22:43:20 +11:00
4468dd6948 docs: update OVERVIEW.md
Update pkg scripts.
2024-03-13 22:43:20 +11:00
4f39e248dd docs: update OVERVIEW.md
Fix links
2024-03-13 22:43:20 +11:00
44b3e5d43f docs: update INVOCATION_API.md
Add blurb about `WithMetadata` and `WithBoard` mixins.
2024-03-13 22:43:20 +11:00
8894a9e48a docs: update WORKFLOWS.md 2024-03-13 22:43:20 +11:00
c73f58e486 docs: move frontend docs to mkdocs 2024-03-13 22:43:20 +11:00
614fece147 chore(ui): prettier 2024-03-13 21:02:29 +11:00
8ef8082d65 feat(ui): style add model panel 2024-03-13 21:02:29 +11:00
d93d4afbb7 feat(ui): style HF scan tab 2024-03-13 21:02:29 +11:00
01207a2fa5 fix(mm): config.json to indicates diffusers model 2024-03-13 21:02:29 +11:00
d0800c4888 ui consistency, moved is_diffusers logic to backend, extended HuggingFaceMetadata, removed logic from service 2024-03-13 21:02:29 +11:00
2a300ecada updated add model copy, added search to hugging face results 2024-03-13 21:02:29 +11:00
90340a39c7 clean up python errors 2024-03-13 21:02:29 +11:00
ee77abb4fe updated simple install button to match other tabs 2024-03-13 21:02:29 +11:00
004bca5c42 updated endpoint types 2024-03-13 21:02:29 +11:00
5ad048a161 fixed error handling 2024-03-13 21:02:29 +11:00
6369ccd05e added placeholders, updated some copy 2024-03-13 21:02:29 +11:00
3a5314f1ca install model if diffusers or single file, cleaned up backend logic to not mess with existing model install 2024-03-13 21:02:29 +11:00
4c0896e436 removed log 2024-03-13 21:02:29 +11:00
f7cd3cf1f4 added hf models import tab and route for getting available hf models 2024-03-13 21:02:29 +11:00
efea1a8a7d ci: add always_run input to checks & tests, use this on release workflow
This bypasses the `changed-files` check, and forces the checks to run. The release workflow sets this flag to ensure that the checks and tests are always run for a release.
2024-03-13 15:32:42 +11:00
d0d695c020 disable trigger phrase form if empty 2024-03-12 21:08:15 -04:00
2a648da557 updated model manager to display when import item is cancelled 2024-03-13 09:18:05 +11:00
54f1a1f952 Update l2i invoke and seamless to support AutoencoderTiny, remove att… (#5936)
…ention processors if no mid_block is detected

## What type of PR is this? (check all applicable)

- [ ] Refactor
- [ ] Feature
- [x] Bug Fix
- [ ] Optimization
- [ ] Documentation Update
- [ ] Community Node Submission


## Have you discussed this change with the InvokeAI team?
- [x] Yes
- [ ] No, because:

      
## Have you updated all relevant documentation?
- [ ] Yes
- [x] No


## Description
L2i throws an assertion error when run with `madebyollin/taesdxl` due to
it requiring a different class in diffusers to load it. This is a small
PR to update seamless and l2i to accept AutoencoderTiny models and not
throw exceptions while processing them.

## QA Instructions, Screenshots, Recordings

<img width="445" alt="Screenshot 2024-03-12 at 12 04 29 PM"
src="https://github.com/invoke-ai/InvokeAI/assets/58442074/34a17e44-d911-4fef-8fc1-71f7b688688c">
Run an sdxl pipeline using a vae that requires AutoencoderTiny and
validate that the image successfully encodes and decodes.

## Merge Plan

This PR can be merged when approved
2024-03-12 21:52:32 +05:30
8d2a4db902 Found another instance of expecting a mid_block on the decoder in a vae 2024-03-12 12:11:38 -04:00
7b393656de Update l2i invoke and seamless to support AutoencoderTiny, remove attention processors if no mid_block is detected 2024-03-12 12:00:24 -04:00
43948e0758 feat(ui): add setting for always show image size badge 2024-03-12 18:52:23 +11:00
cc03fcbcb6 style(ui): tweak image dimension badge overlay styles 2024-03-12 18:52:23 +11:00
d1e445fa49 fix(ui): changed to theme tokens 2024-03-12 18:52:23 +11:00
adba8489f2 fix(ui): made changes to avoid overlapping 2024-03-12 18:52:23 +11:00
d919022ba5 fix(ui): fixed requested changes and made the badge display on hover 2024-03-12 18:52:23 +11:00
e076898798 fix(ui): logic to remove badge for small image size 2024-03-12 18:52:23 +11:00
9f19b766a4 feat(ui): Add image size badge to gallery images 2024-03-12 18:52:23 +11:00
4688623711 ci: add missing permission to release workflow 2024-03-12 10:16:38 +11:00
be951da99d {release} 4.0.0rc1 2024-03-12 10:05:03 +11:00
9ee2e7ff25 Do not override log_memory_usage when debug logs are enabled. The speed cost of log_memory_usage=True is large. It is common to want debug log without enabling log_memory_usage. 2024-03-12 09:48:50 +11:00
149ff758b9 Run ruff 2024-03-11 15:53:00 -04:00
65d415d5aa Remove redundant with_suffix call 2024-03-11 15:53:00 -04:00
c74c1927ec Gracefully error without deleting invokeai.yaml 2024-03-11 15:53:00 -04:00
c454ccc65c Run ruff 2024-03-11 15:53:00 -04:00
46fd3465ce Skip list logic if the list only contains primitives 2024-03-11 15:53:00 -04:00
97afa6e2a6 Allow lists of basemodel objects in omegaconf 2024-03-11 15:53:00 -04:00
96730107d1 chore(py): bump mkdocs deps 2024-03-12 02:21:43 +11:00
6a9dede66f chore: bump app deps
- `fastapi-events`: 0.10.1 -> 1.11.0
- `fastapi`: 0.109.2 -> 0.110.0
- `pydantic-settings`: 2.1.0 -> 2.2.1
- `pydantic`: 2.6.1 -> 2.6.3
- `uvicorn`: 0.27.1 -> 0.28.0
2024-03-12 02:21:43 +11:00
8c2ff794d5 fix(nodes): ip adapter uses valid ModelIdentifierField for image encoder model
- Add class method to `ModelIdentifierField` to construct the field from a model config
- Use this to construct a valid IP adapter model field
2024-03-10 17:28:58 -05:00
145bb45858 Remove dead code related to an old symmetry feature. 2024-03-10 00:13:18 -06:00
9376b13435 fix(mm): models lose file extension when syncing
We were stripping the file extension from file models when  moving them in `_sync_model_path`. For example, `some_model.safetensors` would be moved to `some_model`, which of course breaks things.

Instead of using the model's name as the new path, use the model's path's last segment. This is the same behaviour for directories, but for files, it retains the file extension.
2024-03-10 13:36:09 +11:00
eec82afd89 fix(mm): fix models.yaml backup filename
Was erroneously `models.bak`, now `models.yaml.bak`
2024-03-10 13:36:09 +11:00
c47dbf7258 docs(mm): format docstrings for ModelSearch 2024-03-10 12:09:47 +11:00
92b2e8186a tidy(mm): simplify types for ModelSearch
- Use `set` instead of `Set`
- Methods accept only `Path`s
2024-03-10 12:09:47 +11:00
70a88c6b99 docs(mm): update docstrings for ModelSearch 2024-03-10 12:09:47 +11:00
56e7c04475 tidy(mm): remove extraneous dependencies in model search
- `config` is unused
- `stats` is created on instantiation
- `logger` uses the app logger
2024-03-10 12:09:47 +11:00
bd5b43c00d tidy(mm): ModelSearch cleanup
- No need for it to by a pydantic model. Just a class now.
- Remove ABC, it made it hard to understand what was going on as attributes were spread across the ABC and implementation. Also, there is no other implementation.
- Add tests
2024-03-10 12:09:47 +11:00
631e789195 fix(canvas): create masked latents when None 2024-03-10 11:58:41 +11:00
133c90e116 fix(ui): update all components and logic to use enriched ModelIdentifierField 2024-03-10 11:03:38 +11:00
4433b78e59 chore(ui): typegen 2024-03-10 11:03:38 +11:00
daeb766468 feat(api): add ModelIdentifierField to openapi schema
- Also add `ProgressImage`
2024-03-10 11:03:38 +11:00
92b0d13d0e feat(nodes): "ModelField" -> "ModelIdentifierField", add hash/name/base/type 2024-03-10 11:03:38 +11:00
67d26cd633 docs: update CONFIGURATION.md 2024-03-10 10:38:52 +11:00
9e28317a12 docs: add DATABASE.md 2024-03-10 10:38:52 +11:00
5b51ebf1c4 docs: regenerate config docstrings 2024-03-10 10:38:52 +11:00
59228643a9 docs: skip_model_hash -> model install category, use_memory_db -> development category 2024-03-10 10:38:52 +11:00
b24657df11 docs: roll back adding examples to config docstrings
This isn't a valid docstring syntax and breaks the autogeneration
2024-03-10 10:38:52 +11:00
d4686b7f64 fix(mm): yaml migration fixup
- If the metadata yaml has an invalid version, exist the app. If we don't, the app will crawl the models dir and add models to the db without having first parsed `models.yaml`. This should not happen often, as the vast majority of users are on v3.0.0 models.yaml files.
- Fix off-by-one error with models count (need to pop the `__metadata__` stanza
- After a successful migration, rename `models.yaml` to `models.yaml.bak` to prevent the migration logic from re-running on subsequent app startups.
2024-03-09 08:37:45 -06:00
67163c2224 fix(mm): only move model files if necessary
The old logic to check if a model needed to be moved relied on the model path being a relative path. Paths are now absolute, causing this check to fail. We then assumed the paths were different and moved the model from its current location to, well, its current location.

Use more resilient method to check if a model should be moved.
2024-03-09 22:58:26 +11:00
f01e81d382 Run ruff 2024-03-08 18:46:17 -05:00
a50e0a4802 use correct key name from yaml 2024-03-08 18:46:17 -05:00
df0a5aa92a pass config_path to migration path, make sure it uses absolute path 2024-03-08 18:46:17 -05:00
0bd9a0a9ea Add ability to provide config examples in docs 2024-03-08 16:31:39 -05:00
4ae2cd242e Update to include remote_api_tokens in the config docs 2024-03-08 16:31:39 -05:00
0696094d95 tests: fix tests
The tests were testing deprecated settings (not the settings themselves, just the class's functionality).
2024-03-08 16:31:39 -05:00
fb1ae55010 docs: update CONFIGURATION.md to use autogenerated docs 2024-03-08 16:31:39 -05:00
deb1d4eb14 docs: run script to update config class's docstring 2024-03-08 16:31:39 -05:00
d156fd2093 tests: validate config docstring is current 2024-03-08 16:31:39 -05:00
c41e87160a scripts: add script to update config docstring
- Add script to call config docstring helper function and write the docstring to the file directly
- Add `make` target for this script
2024-03-08 16:31:39 -05:00
eba1fc1355 docs: autogenerated app config docs
mkdocs can autogenerate python class docs from its docstrings. Our config is a pydantic model.

It's tedious and error-prone to duplicate docstrings from the pydantic field descriptions to the class docstrings.

- Add helper function to generate a mkdocs-compatible docstring from the InvokeAIAppConfig class fields
2024-03-08 16:31:39 -05:00
96702c395e feat(config): add deprecated category for config settings
It's not clear why these are still in the config class.
2024-03-08 16:31:39 -05:00
3361aec065 docs(nodes): update config field descriptions 2024-03-08 16:31:39 -05:00
8ba4b2a150 Run ruff 2024-03-08 15:36:14 -05:00
df12e12e09 Run ruff 2024-03-08 15:36:14 -05:00
ee38fbe89c Remove check for models dir in model deletion, update tests to always assume the model path is an absolute path 2024-03-08 15:36:14 -05:00
6e2cef1db5 Remove instances making models relative to the model dir 2024-03-08 15:36:14 -05:00
b1f5ac4548 fix path 2024-03-08 15:36:14 -05:00
e52274ecac Experiment with using absolute paths within model management 2024-03-08 15:36:14 -05:00
66f0ff5b13 add ordering to search_by_attr that is used for model lists 2024-03-08 13:38:38 -06:00
cab5b64f0b only render convert button if ckpt model 2024-03-08 13:19:08 -06:00
a42812d78d ui(model_manager): Remember Scan Path 2024-03-08 14:05:57 -05:00
281222df3c remove old data migration from previous schema version 2024-03-08 13:10:27 -05:00
d5674150fa ruff 2024-03-08 13:02:04 -05:00
0cb2cf6644 wrap version check in try/except 2024-03-08 13:02:04 -05:00
da87266c9c remove log 2024-03-08 13:02:04 -05:00
35731a6f51 fix null description, add logging 2024-03-08 13:02:04 -05:00
a3dfa161a8 Run ruff 2024-03-08 13:02:04 -05:00
42d606f07c use register instead of heuristic import, get rid of typing warnings 2024-03-08 13:02:04 -05:00
9063b1ae61 on model manager start, look to see if yaml needs to be migrated and do it if so 2024-03-08 13:02:04 -05:00
6aae88bd88 Rerun typegen 2024-03-08 12:44:58 -05:00
57c1954da7 feat(ui): use control adapter processor helper in metadata parser 2024-03-08 12:44:58 -05:00
2410ed689a tests(mm): add tests for control adapter probe default settings 2024-03-08 12:44:58 -05:00
a10dccdd43 fix(mm): fix bug in control adapter probe default settings
Wasn't checking for matches correctly.
2024-03-08 12:44:58 -05:00
a3570901f7 fix(ui): do not show default settings for refiner models 2024-03-08 12:44:58 -05:00
fd457955bc feat(ui): update default settings for control adapters
- Split out main model defaults
- Add controlnet/t2i defaults (which includes only the preprocessor)
2024-03-08 12:44:58 -05:00
1f69613f5d chore(ui): typegen 2024-03-08 12:44:58 -05:00
7a87ebb3b2 fix(mm): add control adapter default settings to ModelRecordChanges schema
This is needed to update Control Adapter defaults.
2024-03-08 12:44:58 -05:00
4ee4a801c6 feat(ui): update default settings for main models
Needed some massaging now that only main models get main model default settings.
2024-03-08 12:44:58 -05:00
53b7f6be37 feat(ui): use default settings for control adapters for processor 2024-03-08 12:44:58 -05:00
dbd7c94e7c chore(ui): typegen 2024-03-08 12:44:58 -05:00
50bb9a6b41 fix(mm): remove default settings from IP adapter config 2024-03-08 12:44:58 -05:00
13bb3c5e15 feat(mm): add control adapter default settings while probing 2024-03-08 12:44:58 -05:00
80c2a4b925 feat(mm): add AnyDefaultSettings union 2024-03-08 12:44:58 -05:00
8ce485b036 feat(mm): add default settings for control adapters
Only includes `preprocessor` at this time.
2024-03-08 12:44:58 -05:00
6fc3e86061 tidy(mm): only main models get the main default settings 2024-03-08 12:44:58 -05:00
33ded359e6 Run typegen 2024-03-08 11:10:44 -05:00
effbd8a1ba chore: ruff 2024-03-08 11:10:44 -05:00
ddde355b09 fix(mm): add ui_type to model fields
Recently the schema for models was changed to a generic `ModelField`, and the UI was unable to derive the type of those fields. This didn't affect functionality, but it did break the styling of handles.

Add `ui_type` to the affected fields and update the UI to use the correct capitalizations.
2024-03-08 11:10:44 -05:00
fe2c6f621a fix(ui): do not allow model add when no location is provided 2024-03-08 14:41:03 +11:00
d0fcdbe8a3 tweak(ui): simplify layout of inplace install form elements 2024-03-08 14:41:03 +11:00
a28547b3dd make inplace optional, default to true 2024-03-08 14:41:03 +11:00
c7b2bdb846 allow inplace installs 2024-03-08 14:41:03 +11:00
4a20377fef tidy(config): move version "setting" to new CLIArgs category
It's not actually a setting.
2024-03-08 13:59:59 +11:00
ed803640f7 tidy(mm): move remote_api_tokens to new ModelInstall category 2024-03-08 13:59:59 +11:00
576bb4a61d feat(mm): support generic API tokens via regex/token pairs in config
A list of regex and token pairs is accepted. As a file is downloaded by the model installer, the URL is tested against the provided regex/token pairs. The token for the first matching regex is used during download, added as a bearer token.
2024-03-08 13:59:59 +11:00
b6065d6328 Run ruff with newest version of ruff 2024-03-08 13:59:59 +11:00
04229f4a21 Run ruff 2024-03-08 13:59:59 +11:00
73a190fb6e Add remote_repo_api_key config to be added as a token query param for all remote url model downloads 2024-03-08 13:59:59 +11:00
952d97741e Remove civit ai from tests and documentation 2024-03-08 13:59:59 +11:00
afd08c5f46 Regenerate typegen 2024-03-08 13:59:59 +11:00
d1f859a446 Remove civit AI model install resources 2024-03-08 13:59:59 +11:00
5118160282 docs(mm): update comment about model images 2024-03-08 12:26:35 +11:00
8e694992bb chore(ui): lint 2024-03-08 12:26:35 +11:00
4077dfe0c3 fix(ui): clear pending trigger phrase immediately
If we don't clear it, there's an awkward flash of error state as the mutation completes.
2024-03-08 12:26:35 +11:00
fe8e391aad fix(ui): display trigger phrases for loras in mm editor 2024-03-08 12:26:35 +11:00
ac8f606d99 fix(ui): default settings linked incorrectly 2024-03-08 12:26:35 +11:00
0aa2070ce0 perf(mm): add manual query cache updates for the update model route
This greatly reduces the number of network requests when editing models.
2024-03-08 12:26:35 +11:00
ff66779aa3 tweak(ui): add colors to base/format badges 2024-03-08 12:26:35 +11:00
2ca65ab9fa tweak(ui): style trigger phrases 2024-03-08 12:26:35 +11:00
b34624a2a8 tweak(ui): style model edit 2024-03-08 12:26:35 +11:00
b8aa9752f1 tweak(ui): update default settings layouts 2024-03-08 12:26:35 +11:00
1b5d8eb9e7 tweak(ui): use check icon for model save button 2024-03-08 12:26:35 +11:00
773182f425 fix(ui): reset model edit form state with new values
Without this, the form will incorrectly compare its state to its initial default values to determine if it is dirty. Instead, it should reset its default values to the new values after successful submit.
2024-03-08 12:26:35 +11:00
6386109fc5 feat(ui): move model save/close buttons to model header 2024-03-08 12:26:35 +11:00
c008704bc8 feat(ui): model header styling 2024-03-08 12:26:35 +11:00
a3a42d25d3 fix(mm): model images reload when changed
When we change a model image, its URL remains the same. The browser will aggressively cache the image. The easiest way to fix this is to append a random query parameter to the URL whenever we build a model config in the API.
2024-03-08 12:26:35 +11:00
8959d1bf51 fix(ui): do not persist model manager state 2024-03-08 12:26:35 +11:00
8fd9342712 fix(ui): typing issues related to trigger phrase changes 2024-03-08 12:26:35 +11:00
f0b815aa9b fix(ui): missing translation 2024-03-08 12:26:35 +11:00
3a5b0b819c chore(ui): typegen 2024-03-08 12:26:35 +11:00
bbcbcd9b63 fix(mm): only loras and main models get trigger_phrases 2024-03-08 12:26:35 +11:00
fdecb886b2 feat(ui): add main model trigger phrases 2024-03-08 12:26:35 +11:00
2f0a653a7f feat(ui): improved model list styling 2024-03-08 12:26:35 +11:00
b0add805c5 feat(ui): use stickyscrollable for models list 2024-03-08 12:26:35 +11:00
ed4e8624dd feat(ui): model manager UI tweaks
- Move image display to left
- Move description into model header
- Move model edit & convert buttons to top right of model header
- Tweak styles for model display component
2024-03-08 12:26:35 +11:00
ad70cdfe87 feat: undo/redo discard canvas staged image 2024-03-07 19:24:55 +11:00
549d461107 refactor: 🚨 satisfy the linter 2024-03-07 19:24:55 +11:00
cab3748010 feat: discard current inpaint item 2024-03-07 19:24:55 +11:00
779b3e0e8e tidy(ui): remove npm lockfile 2024-03-06 21:57:41 -05:00
9b48029bc9 tidy(mm): ModelImages service 2024-03-06 21:57:41 -05:00
347f1fd0b7 fix tests 2024-03-06 21:57:41 -05:00
4af5a09a68 cleanup 2024-03-06 21:57:41 -05:00
8df02623f2 cleanup 2024-03-06 21:57:41 -05:00
aa88fadc30 use webp images 2024-03-06 21:57:41 -05:00
8411029d93 get model image url from model config, added thumbnail formatting for images 2024-03-06 21:57:41 -05:00
239b1e8cc7 moved upload image field and added delete image functionality 2024-03-06 21:57:41 -05:00
8a68355926 got model images displaying, still need to clean up types and unused code 2024-03-06 21:57:41 -05:00
86aef9f31d removed modelimage for now 2024-03-06 21:57:41 -05:00
2f6964bfa5 fetching model image, still not working 2024-03-06 21:57:41 -05:00
c1cdfd132b moved model image to edit page, added model_images service 2024-03-06 21:57:41 -05:00
f6bfe5e6f2 created ugly model image upload component 2024-03-06 21:57:41 -05:00
b5a8455b5f translationBot(ui): update translation (Russian)
Currently translated at 94.6% (1431 of 1512 strings)

translationBot(ui): update translation (Russian)

Currently translated at 94.6% (1431 of 1512 strings)

Co-authored-by: Васянатор <ilabulanov339@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/
Translation: InvokeAI/Web UI
2024-03-07 11:47:01 +11:00
645ef081ea translationBot(ui): update translation (Italian)
Currently translated at 98.0% (1487 of 1516 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.0% (1482 of 1512 strings)

translationBot(ui): update translation (Italian)

Currently translated at 98.0% (1475 of 1505 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-03-07 11:47:01 +11:00
e68d7fa6d7 fix(ui): update types 2024-03-07 10:56:59 +11:00
c5ab1c7ad6 chore(ui): typegen 2024-03-07 10:56:59 +11:00
5a561cab78 fix(ui): typo 2024-03-07 10:56:59 +11:00
132790eebe tidy(nodes): use canonical capitalizations 2024-03-07 10:56:59 +11:00
c57f6ee885 fix(ui): fix metadata for graphs to use new enriched format 2024-03-07 10:56:59 +11:00
d4a2ea68fc chore(ui): typegen 2024-03-07 10:56:59 +11:00
528ac5dd25 refactor(nodes): model identifiers
- All models are identified by a key and optionally a submodel type via new model `ModelField`. Previously, a few model types had their own class, but not all of them. This inconsistency just added complexity without any benefit.
- Update all invocation to use the new format.
- In the node API, models are loaded by key or an instance of `ModelField` as a convenience.
- Add an enriched model schema for metadata. It includes key, hash, name, base and type.
2024-03-07 10:56:59 +11:00
afd9ae7712 tidy(mm): remove convenience methods from high level model manager service
These were added as a hold-me-over for the nodes API changes, no longer needed. A followup commit will fix the nodes API to not rely on these.
2024-03-07 10:56:59 +11:00
4eefed12f0 refactor: 🚨 please the almighty linter 2024-03-07 10:44:40 +11:00
4301a3d6fd feat: invert scroll direction for brush size 2024-03-07 10:44:40 +11:00
99c0662e3f fix(nodes): load config before doing anything else
This was preventing custom nodes from loading if a custom nodes dir was specified

Closes #5862
2024-03-07 10:36:27 +11:00
cdc0d0c182 add config_path to ModelRecordChanges 2024-03-07 10:29:29 +11:00
a00369a67a add config path as field in model update form when model is a checkpoint 2024-03-07 10:29:29 +11:00
4f096ac3ba feat(scripts): add frontend-types to Makefile to generate types 2024-03-07 10:16:44 +11:00
f5e3341465 feat(scripts): add support for file path & stdin to frontend typegen script 2024-03-07 10:16:44 +11:00
474852ef7e feat(scripts): add script to generate openapi schema 2024-03-07 10:16:44 +11:00
b1d72d411e only show default settings on main models 2024-03-07 09:07:43 +11:00
46614ee28f lint fix 2024-03-06 15:06:27 -05:00
b019f9bb8b make sure all metadata in viewer is rendered at correct font size - specifically fixes control adapter metadata being too big 2024-03-06 15:06:27 -05:00
b857692073 update uploads from canvas to controlnet to be intermediates so they do not appear in gallery 2024-03-06 15:06:27 -05:00
90fb7a1a59 move linear tab to be first on workflow edit mode 2024-03-06 15:06:27 -05:00
56fcf6af78 empty state for workflow with no linear fields in view mode 2024-03-06 15:06:27 -05:00
c4fe7e697b add right-padding to prompt textareas so that text does not go behind icons 2024-03-06 15:06:27 -05:00
2fd483dfc8 use base.800 on invokeBlue.400 for all gallery selected states 2024-03-06 15:06:27 -05:00
b9a9507422 update padding in color picker 2024-03-06 15:06:27 -05:00
f2744fd7d1 fix URL for get image workflow (#5882)
Co-authored-by: Mary Hipp <maryhipp@Marys-MacBook-Air.local>
2024-03-06 12:46:16 -05:00
fe6e879d38 fix(ui): invalidate InvocationCacheStatus query cache after clearing intermediates 2024-03-06 08:14:12 -05:00
d3ab08fe10 tests: add invocation cache tests 2024-03-06 08:14:12 -05:00
b0615bdfd4 fix(nodes): correctly serialize outputs
In order for delete by match to work, we need the whole invocation output to be stringified.

For some reason, the serialization of the output was set to only include the `type` field. It should instead include the whole output.

I don't understand how this ever worked unless pydantic had different serialization behaviour in v1 (though it appears to have been the same).

Closes #5805
2024-03-06 08:14:12 -05:00
bab20467fb fix(nodes): fix invocation cache clear method args 2024-03-06 08:14:12 -05:00
e24624109e fix(nodes): fix invocation cache ABC typing 2024-03-06 08:14:12 -05:00
458e7185b8 fix: 🐛 didn't include renamed file 2024-03-06 20:06:14 +11:00
a95128f5f2 refactor: ✏️ canvas mask compositor naming
changes `...MaskCompositer` spelling to `...MaskCompositor`
2024-03-06 20:06:14 +11:00
46f32c5e3c Remove references to the no longer existing invokeai.app.services.model_metadata package 2024-03-05 19:58:25 -05:00
e30cb4b52f updates for defaultModel (#5866)
* move defaultModel logic to modelsLoaded and update to work for key instead of name/base/type string

* lint fix

---------

Co-authored-by: Mary Hipp <maryhipp@Marys-MacBook-Air.local>
2024-03-05 09:55:22 -05:00
ba1f6bf926 chore: lint 2024-03-05 23:50:19 +11:00
4a9cca6c2d fix(ui): format model API response data 2024-03-05 23:50:19 +11:00
b0275700b3 refactor(ui): compute prompt trigger options in the component
We can derive the valid trigger options in the component without needing to lift the options list into global state.
2024-03-05 23:50:19 +11:00
8319aca5f9 chore(ui): typegen 2024-03-05 23:50:19 +11:00
51a604f907 pkg(ui): do not fix knip in lint:fix script 2024-03-05 23:50:19 +11:00
7515d73628 make trigger phrases a list of options and add lora name as description to appear in dropdown 2024-03-05 23:50:19 +11:00
2c453aa531 fix type error 2024-03-05 23:50:19 +11:00
2cca6e4c76 check if lora is enabled before adding trigger phrases 2024-03-05 23:50:19 +11:00
ef171e890a use a listener to recalculate trigger phrases when model or lora list changes 2024-03-05 23:50:19 +11:00
caafbf2f0d only show trigger phrase settings on main and lora 2024-03-05 23:50:19 +11:00
2db5eaf907 lint fix 2024-03-05 23:50:19 +11:00
f234bf6256 cleanup 2024-03-05 23:50:19 +11:00
cfa78b4052 adapt embedding popover to work for trigger phrases also 2024-03-05 23:50:19 +11:00
ba1dd4b02b UI in MM to create trigger phrases 2024-03-05 23:50:19 +11:00
bcf58cac59 feat(mm): add config to skip model hash
This is useful for when you are using a memory DB and do not want to wait for all models to be hashed on startup.
2024-03-05 23:50:19 +11:00
e866d90ab2 tidy(mm): remove unused method on probe 2024-03-05 23:50:19 +11:00
e8797787cf fix(mm): fix incorrect calls to update_model 2024-03-05 23:50:19 +11:00
0082ecb22b feat(mm): add path to ModelRecordChanges 2024-03-05 23:50:19 +11:00
656839fcd1 fix(mm): fix typing on heuristic_import 2024-03-05 23:50:19 +11:00
99407c899f feat(ui): update UI to use new model config backend
- Update all queries
- Remove Advanced Add
- Removed un-editable, internal-only model attributes from model edit UI (e.g. format, repo variant, model type)
- Update model tags so the list refreshes when a model installs
- Rename some queries, components, variables, types to match backend
- Fix divide-by-zero in install queue
2024-03-05 23:50:19 +11:00
48119d9010 revert(mm): restore convert route 2024-03-05 23:50:19 +11:00
7c9128b253 tidy(mm): use canonical capitalization for all model-related enums, classes
For example, "Lora" -> "LoRA", "Vae" -> "VAE".
2024-03-05 23:50:19 +11:00
4f9bb00275 tidy(api): tidy mm routes
Rename MM routes to be consistent:
- "import" -> "install"
- "model_record" -> "model"

Comment several unused routes while I work (may end up removing them?):
- list model summary (we use the search route instead)
- add model record
- convert model
- merge models
2024-03-05 23:50:19 +11:00
78895b3e80 fix(mm): add missing inplace parameter to model install abc 2024-03-05 23:50:19 +11:00
3030a34b88 fix(mm): make type and format required in openapi schema for model config 2024-03-05 23:50:19 +11:00
58fa9c2fac fix(mm): do not allow extra fields on ModelRecordChanges 2024-03-05 23:50:19 +11:00
a8b6635050 fix(mm): make key required in openapi schema for model config 2024-03-05 23:50:19 +11:00
6829610a71 tests: rename "example_config" -> "example_it_config" 2024-03-05 23:50:19 +11:00
5551cf8ac4 feat(mm): revise update_model to use ModelRecordChanges 2024-03-05 23:50:19 +11:00
37b969d339 tidy(mm): add default_settings to model config 2024-03-05 23:50:19 +11:00
c953e61294 tidy(mm): "trigger_words" -> "trigger_phrases" 2024-03-05 23:50:19 +11:00
93dd3c848e tidy(mm): remove unused code in select_hf_files.py 2024-03-05 23:50:19 +11:00
02bde7bb75 tests: fix test_hf_model_select::test_select_multiple_weights on windows 2024-03-05 23:50:19 +11:00
3391c19926 chore: ruff 2024-03-05 23:50:19 +11:00
0f60b1ced4 fix(mm): use .value for model config discriminators
There is a breaking change in python 3.11 related to how enums with `str` as a mixin are formatted. This appears to have not caused any grief for us until now.

Re-jigger the discriminator setup to use `.value` so everything works on both python 3.10 and 3.11.
2024-03-05 23:50:19 +11:00
44c40d7d1a refactor(mm): remove unused metadata logic, fix tests
- Metadata is merged with the config. We can simplify the MM substantially and remove the handling for metadata.
- Per discussion, we don't have an ETA for frontend implementation of tags, and with the realization that the tags from CivitAI are largely useless, there's no reason to keep tags in the MM right now. When we are ready to implement tags on the frontend, we can refer back to the implementation here and use it if it supports the design.
- Fix all tests.
2024-03-05 23:50:19 +11:00
0b9a212363 tests: remove 60s timeout for tests
This makes it very difficult to troubleshoot tests. Our github actions now have timeouts, so there's no risk of a test stalling for ages.
2024-03-05 23:50:19 +11:00
c3aa985c93 refactor(mm): get metadata working 2024-03-05 23:50:19 +11:00
7cb0da1f66 refactor(mm): wip schema changes 2024-03-05 23:50:19 +11:00
3534366146 fix(mm): fix extraneous downloaded files in diffusers
Sometimes, diffusers model components (tokenizer, unet, etc.) have multiple weights files in the same directory.

In this situation, we assume the files are different versions of the same weights. For example, we may have multiple
formats (`.bin`, `.safetensors`) with different precisions. When downloading model files, we want to select only
the best of these files for the requested format and precision/variant.

The previous logic assumed that each model weights file would have the same base filename, but this assumption was
not always true. The logic is revised score each file and choose the best scoring file, resulting in only a single
file being downloaded for each submodel/subdirectory.
2024-03-05 23:50:19 +11:00
f2b5f8753f tidy(mm): remove json_schema_extra from config - not needed 2024-03-05 23:50:19 +11:00
f13f5984c0 fix(mm): update db schema & migration 2024-03-05 23:50:19 +11:00
94e1e64296 chore: ruff 2024-03-05 23:50:19 +11:00
2411bf53c0 tidy(mm): better descriptions for model configs 2024-03-05 23:50:19 +11:00
9378e47a06 feat(mm): add source_type to model configs 2024-03-05 23:50:19 +11:00
4471ea8ad1 refactor(mm): simplify model metadata schemas 2024-03-05 23:50:19 +11:00
2c835fd550 refactor(mm): WIP db schema 2024-03-05 23:50:19 +11:00
61b737bb9f tidy(mm): remove update method from ModelConfigBase
It's only used in the soon-to-be-removed model merge logic
2024-03-05 23:50:19 +11:00
a8cd3dfc99 refactor(mm): add models table (schema WIP), rename "original_hash" -> "hash" 2024-03-05 23:50:19 +11:00
0cce582f2f tidy(mm): remove current_hash 2024-03-05 23:50:19 +11:00
4347d1c7f7 tests(mm): fix some objects in tests 2024-03-05 23:50:19 +11:00
bd4fd9693d tidy(mm): rename ckpt "last_modified" -> "converted_at"
Clarify what this timestamp means
2024-03-05 23:50:19 +11:00
9b40c28144 tidy(mm): rename ckpy "config" -> "config_path" 2024-03-05 23:50:19 +11:00
16a5d718bf fix(mm): add config field to ckpt vaes 2024-03-05 23:50:19 +11:00
76cbc745e1 refactor(mm): add CheckpointConfigBase for all ckpt models 2024-03-05 23:50:19 +11:00
0a614943f6 fix(mm): fix broken get_model_discriminator_value 2024-03-05 23:50:19 +11:00
e426096d32 fix(mm): misc typing fixes for model loaders 2024-03-05 23:50:19 +11:00
c561cd751f fix(mm): use correct import path for ConfigMixin, ModelMixin 2024-03-05 23:50:19 +11:00
af9298f0ef tidy(mm): tidy class names in config.py 2024-03-05 23:50:19 +11:00
5b74117836 fix(mm): use generic for model loader registry
This preserves the typing for classes using the decorator
2024-03-05 23:50:19 +11:00
38474c9797 fix(mm): use correct import path for ModelMixin 2024-03-05 23:50:19 +11:00
b880a31039 refactor(mm): remove ztsnr_training field on _MainConfig
This is used to determine the CFG Rescale Multiplier setting. We'll handle this in the UI as a default setting.
2024-03-05 23:50:19 +11:00
dd31bc4586 refactor(mm): remove vae field on _MainConfig
We will handle default VAE selection in the UI.
2024-03-05 23:50:19 +11:00
316573df2d feat(mm): use callable discriminator for AnyModelConfig union 2024-03-05 23:50:19 +11:00
8b34f5298c Default model settings (#5850)
* UI in MM to create trigger phrases

* add scheduler and vaePrecision to config

* UI for configuring default settings for models'

* hook MM default model settings up to API

* add button to set default settings in parameters

* pull out trigger phrases

* back-end for default settings

* lint

* remove log;
gi

* ruff

* ruff format

---------

Co-authored-by: Mary Hipp <maryhipp@Marys-MacBook-Air.local>
2024-03-04 09:39:03 -05:00
893bcd16fc Next: Allow in place local installs of models 2024-03-04 23:11:41 +11:00
f6028a4c61 Log a stack trace for invocation errors. 2024-03-04 23:01:56 +11:00
264aee3ffa translationBot(ui): update translation files
Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/
Translation: InvokeAI/Web UI
2024-03-04 21:39:46 +11:00
4deb60f365 translationBot(ui): update translation (Italian)
Currently translated at 98.0% (1442 of 1470 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-03-04 21:39:46 +11:00
B N
f2d5fb176f translationBot(ui): update translation (German)
Currently translated at 80.4% (1183 of 1470 strings)

Co-authored-by: B N <berndnieschalk@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/de/
Translation: InvokeAI/Web UI
2024-03-04 21:39:46 +11:00
94005b5501 add button to navigate to model manager if tab is enabled 2024-03-03 19:50:50 -05:00
02dc1a8780 consolidate tabs for main model and concepts in generation panel 2024-03-03 19:50:50 -05:00
ef958568ac Update Transformers 4.37.2 -> 4.38.2 2024-03-03 19:41:33 -05:00
48e323d887 docs: added both create mask nodes to defaultNodes 2024-03-03 12:58:47 -05:00
735857479d fix(canvas): use corrected mask for pasteback 2024-03-03 12:58:47 -05:00
2f372d9b18 tests(mm): update tests to reflect using UUID for key 2024-03-03 14:32:14 +11:00
554d175792 feat(mm): improved model hash class
- Use memory view for hashlib algorithms (closer to python 3.11's filehash API in hashlib)
- Remove `sha1_fast` (realized it doesn't even hash the whole file, it just does the first block)
- Add support for custom file filters
- Update docstrings
- Update tests
2024-03-03 14:32:14 +11:00
ae99428883 fix(mm): use UUIDv4 for key
This changes the functionality of this PR to only use the updated hashing for model hashes with a UUID for the key.
2024-03-03 14:32:14 +11:00
863ce00712 tests(mm): add tests for ModelHash 2024-03-03 14:32:14 +11:00
86982f3059 feat(mm): make ModelHash instantiatable, taking an algorithm as arg 2024-03-03 14:32:14 +11:00
ec8ed530a7 feat(mm): modularize ModelHash to facilitate testing 2024-03-03 14:32:14 +11:00
982076d7d7 feat(mm): add hashing algos to ModelHash
- Some algos are slow, so it is now just called ModelHash
- Added all hashlib algos, plus BLAKE3 and the fast (but incorrect) SHA1 algo
2024-03-03 14:32:14 +11:00
2e4672f931 feat(mm): make hash.py a script for testing 2024-03-03 14:32:14 +11:00
908e915a71 feat(mm): use blake3 for hashing 2024-03-03 14:32:14 +11:00
a72056e0df make model key assignment deterministic
- When installing, model keys are now calculated from the model contents.
- .safetensors, .ckpt and other single file models are hashed with sha1
- The contents of diffusers directories are hashed using imohash (faster)

fixup yaml->sql db migration script to assign deterministic key

- this commit also detects and assigns the correct image encoder for
  ip adapter models.
2024-03-03 14:32:14 +11:00
d8d7ddf43a Remove attention map saving (#5845)
## What type of PR is this? (check all applicable)

- [x] Refactor
- [ ] Feature
- [ ] Bug Fix
- [ ] Optimization
- [ ] Documentation Update
- [ ] Community Node Submission


## Have you discussed this change with the InvokeAI team?
- [x] Yes
- [ ] No, because

## Description

Attention map saving was a feature that existed a long time ago in
Invoke (>1 year ago). This PR strips out a bunch of dead code that still
remains from that feature and is polluting our diffusion implementation.

This change should not have any functional effect on the app.

## QA Instructions, Screenshots, Recordings

I did a quick smoke test of SD and SDXL image generation. All of the
deleted code was unused, so the risk should be relatively low.

## Merge Plan

- [x] Change target branch to `main` before merging.

## Added/updated tests?

- [ ] Yes
- [x] No: This PR just deletes a bunch of unused code.
2024-03-02 11:15:25 -05:00
cc45007dc4 Remove unused code for attention map saving. 2024-03-02 08:25:41 -05:00
73bec56c59 Delete unused functions from shared_invokeai_diffusion.py. 2024-03-02 08:25:41 -05:00
f8b54930f0 docs: update RELEASE.md 2024-03-02 08:23:49 -05:00
51cc9f9466 ci: add comments to workflows 2024-03-02 08:23:49 -05:00
d2ad465e96 ci: rename test matrix
Now python version: platform, e.g. `py3.10: linux-cpu`

This displays better in GH actions.
2024-03-02 08:23:49 -05:00
09037b7cd4 ci: add conditionals for jobs based on dispatch/call 2024-03-02 08:23:49 -05:00
b2a850b5ea ci: rename jobs, remove extraneous needs in release 2024-03-02 08:23:49 -05:00
3ba5c2b0b4 ci: split build job 2024-03-02 08:23:49 -05:00
06fc6ccfe5 ci: workflow & job names 2024-03-02 08:23:49 -05:00
0c6b0cfdab ci: tidy pr labeler labels 2024-03-02 08:23:49 -05:00
eef3373799 ci: fix workflows
Do not split up "on change" and "do the thing". Less convoluted, no catch-22 with required checks for PRs.
2024-03-02 08:23:49 -05:00
6935830f99 Remove unused constructor declared with typo in name: __int__. 2024-03-01 15:12:03 -05:00
7651eeea8d Merge sequential conditioning and cac conditioning logic to eliminate a bunch of duplication. 2024-03-01 15:12:03 -05:00
204e7d383b Remove outdated comments related to T2I-Adapters and ControlNets. 2024-03-01 15:12:03 -05:00
9bc4e7a593 Remove use of **kwargs in do_unet_step(...), where full parameter list is known and supported. 2024-03-01 15:12:03 -05:00
ad96857e0f Fix avoid storing extra conditioning info in two places. 2024-03-01 15:12:03 -05:00
8fb297e5f6 add regression tests for <NOKEY> issue 2024-02-29 22:31:05 -05:00
0832e1818e Fix problem of all installed models being assigned "<NOKEY>"
- Also fix redundant scanning of models directory at startup.
2024-02-29 22:31:05 -05:00
26d4d93e64 ci: update mkdocs workflow
Bit of a merge of the docs at https://github.com/squidfunk/mkdocs-material/blob/master/docs/publishing-your-site.md and the previous workflow.

Not sure how to test this without access to the main repo.
2024-02-29 21:57:20 -05:00
77f39aa935 ci: bump setup-python v4 -> v5 2024-02-29 21:57:20 -05:00
6aae940834 ci: clean up unused workflow 2024-02-29 21:57:20 -05:00
be8dcad1da feat(installer): do not delete dist/ 2024-02-29 21:57:20 -05:00
5f2e493244 feat(installer): print outputs 2024-02-29 21:57:20 -05:00
c60c9825cb feat(installer): add check for CI in create_installer.sh
If in CI, print a message saying so.

If not, prompt user to confirm that they are in the correct working directory.
2024-02-29 21:57:20 -05:00
6f368395df fix(installer): conditional syntax for old bash in create_installer.sh 2024-02-29 21:57:20 -05:00
ea4d071503 ci: add reasonable timeouts for jobs
The timeouts are at least 3x the expected time to complete the jobs.

This is particularly relevant for the `pytest` job. Occasionally, it hangs while running tests that do network things, and the job only times out after 6 hours.
2024-02-29 21:57:20 -05:00
b95e5d0730 ci: bump tj-actions/changed-files -> v41 2024-02-29 21:57:20 -05:00
99ee8f9099 feat(installer): remove vX-latest from tag_release
Also update RELEASE.md accordingly, and make the release.yml workflow match on `v*` tags.
2024-02-29 21:57:20 -05:00
50e58ff323 feat(installer): just use python3 in scripts 2024-02-29 21:57:20 -05:00
b5c12985e7 docs: update RELEASE.md 2024-02-29 21:57:20 -05:00
a865277667 ci: add comments to workflows 2024-02-29 21:57:20 -05:00
b2b65a9012 feat(installer): address feedback 2024-02-29 21:57:20 -05:00
9fe579dd99 docs: update docs/RELEASE.md 2024-02-29 21:57:20 -05:00
a0313ba634 feat: automated releases via github action
- Restructure & update code check workflows
- Add release workflow to handle checks/tests, build and publish to PyPI
- Add docs/RELEASE.md explaining the workflow & process
- `create_installer.sh`: Update to work with the release workflow
- `create_installer.sh` & `tag_release.sh`: Fix the ANSI escape codes for macOS
- `tag_release.sh`: Add check for python binary name
- `tag_release.sh`: Print `git remote -v` output
- `tag_release.sh`: Fix error when deleting nonexistant tags
2024-02-29 21:57:20 -05:00
3a2afe1d15 chore: ruff 2024-03-01 10:42:33 +11:00
813a086cfe fix race condition between downloading last file and starting install 2024-03-01 10:42:33 +11:00
e18533e3b5 add debugging statements and a timeout to download test 2024-03-01 10:42:33 +11:00
dd9daf8efb chore: ruff 2024-03-01 10:42:33 +11:00
ad86b29798 chore: remove pin on ruff
This ensures it matches the github workflow.

Also there's an update that stabilizes a number of formatting rules, so there will be a format commit after this.
2024-03-01 10:42:33 +11:00
8b03af391a fix(ui): fix metadata display issue 2024-03-01 10:42:33 +11:00
bbbd18f119 fix(ui): baseUrl hardcoded api path
We now hav multiple api versions for different routers, so we cannot hardcode the `/api/v1` portion of the baseUrl
2024-03-01 10:42:33 +11:00
c074beff7c fix(ui): typo in feature tooltips 2024-03-01 10:42:33 +11:00
0b07e2aad4 docs: add v3 -> v4 migration, invocation API docs 2024-03-01 10:42:33 +11:00
753919c6d7 docs(nodes): update all docstrings for public nodes API 2024-03-01 10:42:33 +11:00
2f26768d19 fix: make invocation_context.py accessible to mkdocs
Needs an `__init__.py`.
2024-03-01 10:42:33 +11:00
ae19971f65 docs: update mkdocs config 2024-03-01 10:42:33 +11:00
e364ce1d4e docs: bump mkdocs, add mkdocstrings
Also remove ancient requirements file - the docs dependencies are in the pyproject.toml file.
2024-03-01 10:42:33 +11:00
0b0128647b feat(nodes): revise model load API args 2024-03-01 10:42:33 +11:00
39725e9560 Next: Remove deprecated app.on_event usage in api runner 2024-03-01 10:42:33 +11:00
0305e90287 chore: ruff 2024-03-01 10:42:33 +11:00
ae34bcfbc0 fix: Assertion issue with SDXL Compel 2024-03-01 10:42:33 +11:00
01898d766f Fix merge with next 2024-03-01 10:42:33 +11:00
e7afae0159 Switch absolute path to as_posix in _walk_directory 2024-03-01 10:42:33 +11:00
f16e64084b Ruff checks 2024-03-01 10:42:33 +11:00
8992d89817 Fix directory called on _walk_directory 2024-03-01 10:42:33 +11:00
0fc2f90824 Switch ModelSearch from os.walk to os.scandir 2024-03-01 10:42:33 +11:00
c670dacc29 Ruff format 2024-03-01 10:42:33 +11:00
f475b78734 Ruff check 2024-03-01 10:42:33 +11:00
ca9b815c89 Extract TI loading logic into util, disallow it from ever failing a generation 2024-03-01 10:42:33 +11:00
8efd4284e9 Fix one last reference to the uncasted model 2024-03-01 10:42:33 +11:00
5922cee541 Allow TIs to be either a key or a name in the prompt during our transition to using keys 2024-03-01 10:42:33 +11:00
94e3857110 handle change to Civitai metadata schema for commercial usage 2024-03-01 10:42:33 +11:00
4b4b940461 updated to use new import model mutation 2024-03-01 10:42:33 +11:00
574d6538b9 fix(ui): merge conflict 2024-03-01 10:42:33 +11:00
3141c6efd5 chore(ui): bump deps
The only major version is `query-string`. The breaking change for it is dropping support for old versions of node. Not a problem for us.
2024-03-01 10:42:33 +11:00
9cf2897064 ci: change frontend check to dpdm 2024-03-01 10:42:33 +11:00
bcf742ef87 feat(ui): move from madge to dpdm for circular dependencies 2024-03-01 10:42:33 +11:00
f6c068afdd tidy(ui): fix circular dependencies in listeners 2024-03-01 10:42:33 +11:00
7d2e840590 tidy: remove some traces of ONNX 2024-03-01 10:42:33 +11:00
f0b3485ce9 chore(ui): typegen, update knip config
Knip should never touch the autogenerated types
2024-03-01 10:42:33 +11:00
37608cdea2 chore(ui): update pnpm-lock.yaml
Forgot to run `pnpm i` earlier after removing packages.
2024-03-01 10:42:33 +11:00
aafa464707 ci: add knip to ui check workflow 2024-03-01 10:42:33 +11:00
1176c549c0 feat(ui): configure knip 2024-03-01 10:42:33 +11:00
d90210fea6 tidy(ui): clean up unused code 6
unused files
2024-03-01 10:42:33 +11:00
d99bec8b1a tidy(ui): clean up unused code 5
variables, types and schemas
2024-03-01 10:42:33 +11:00
b661d93bd8 tidy(ui): clean up unused code 4
variables, types and schemas
2024-03-01 10:42:33 +11:00
dc64089c9d tidy(ui): clean up unused code 3
variables, types and schemas
2024-03-01 10:42:33 +11:00
a6f6fe581e tidy(ui): clean up unused code 2
types and schemas
2024-03-01 10:42:33 +11:00
12e859835b feat(mm): add log stmt for download complete event 2024-03-01 10:42:33 +11:00
b218282149 fix(ui): model install progress sets total bytes correctly 2024-03-01 10:42:33 +11:00
80065858ed chore(ui): lint 2024-03-01 10:42:33 +11:00
aaeef03593 fix(ui): fix remaining TS issues 2024-03-01 10:42:33 +11:00
97ecd99b9c fix(ui): fix up MM queries & types (wip) 2024-03-01 10:42:33 +11:00
202e739404 tidy(api): remove non-heuristic install route 2024-03-01 10:42:33 +11:00
10d36b4045 tidy(mm): remove ONNX from AnyModelConfig 2024-03-01 10:42:33 +11:00
8f93ae8d7c tidy(ui): clean up unused code 1
- Only export when necessary
- Remove totally usused functions, variables, state, etc
- Remove unused packages
2024-03-01 10:42:33 +11:00
506fa55f18 feat(ui): add knip + minimal config
https://knip.dev/

Replaces `unimported`
2024-03-01 10:42:33 +11:00
4c19d5cee4 fix(ui): fix missing component import 2024-03-01 10:42:33 +11:00
afa7043dcd ui: split the canvas mask blur and edge size setting 2024-03-01 10:42:33 +11:00
32b8478974 added add all button to scan models 2024-03-01 10:42:33 +11:00
d23f2de9d7 feat(ui): create metadata types for control adapters
These are the same as the existing control adapter types, but the model field is non-nullable, simplifying handling of these objects.
2024-03-01 10:42:33 +11:00
9abfb02bf0 fix(ui): model metadata handlers use model identifiers, not configs
Model metadata includes the main model, VAE and refiner model.

These used full model configs, as returned by the server, as their metadata type.

LoRA and control adapter metadata only use the metadata identifier.

This created a difference in handling. After parsing a model/vae/refiner, we have its name and can display it. But for LoRAs and control adapters, we only have the model key and must query for the full model config to get the name.

This change makes main model/vae/refiner metadata only have the model key, like LoRAs and control adapters.

The render function is now async so fetching can occur within it. All metadata fields with models now only contain the identifier, and fetch the model name to render their values.
2024-03-01 10:42:33 +11:00
7b4ef5926d fix(ui): CanvasPasteBack types 2024-03-01 10:42:33 +11:00
6c5be9e89c tidy(ui): remove unused metadata schemas 2024-03-01 10:42:33 +11:00
80697a71de feat(nodes): update LoRAMetadataItem model
LoRA model now at under `model` not `lora.
2024-03-01 10:42:33 +11:00
a253047d8e tidy(ui): tidy model identifier logic
- Move some files around
- Use util to extract key and base from model config
2024-03-01 10:42:33 +11:00
7176c5d9d6 feat(ui): optimize model query caching
When we retrieve a list of models, upsert that data into the `getModelConfig` and `getModelConfigByAttrs` query caches.

With this change, calls to those two queries are almost always going to be free, because their caches will already have all models in them. The exception is queries for models that no longer exist.
2024-03-01 10:42:33 +11:00
0b54bfb7c5 fix(ui): fix lora metadata item type 2024-03-01 10:42:33 +11:00
24daacecf2 fix(ui): fix node type 2024-03-01 10:42:33 +11:00
7326c78ab5 feat(ui): add transformation to width/height parameter schemas to round to multiple of 8
This allows image dimensions that are not multiples of 8 to still be recalled with best effort.
2024-03-01 10:42:33 +11:00
04545e792c fix(ui): fix lora metadata rendering 2024-03-01 10:42:33 +11:00
e6de915c34 fix(ui): fix type issues related to change in LoRA type 2024-03-01 10:42:33 +11:00
71ceab9094 feat(ui): migrate all metadata recall logic to new system 2024-03-01 10:42:33 +11:00
ff00ed8e80 fix(ui): use id for component key in control adapter components 2024-03-01 10:42:33 +11:00
ce3f9037cd feat(ui): no JSX in metadata handlers 2024-03-01 10:42:33 +11:00
d1f4cde8c7 feat(ui): refactor metadata handling (again)
Add concepts for metadata handlers. Handlers include parsers, recallers and validators for different metadata types:
- Parsers parse a raw metadata object of any shape to a structured object.
- Recallers load the parsed metadata into state. Recallers are optional, as some metadata types don't need to be loaded into state.
- Validators provide an additional layer of validation before recalling the metadata. This is needed because a metadata object may be valid, but not able to be recalled due to some other requirement, like base model compatibility. Validators are optional.

Sometimes metadata is not a single object but a list of items - like LoRAs. Metadata handlers may implement an optional set of "item" handlers which operate on individual items in the list.

Parsers and validators are async to allow fetching additional data, like a model config. Recallers are synchronous.

The these handlers are composed into a public API, exported as a `handlers` object. Besides the handlers functions, a metadata handler set includes:
- A function to get the label of the metadata type.
- An optional function to render the value of the metadata type.
- An optional function to render the _item_ value of the metadata type.
2024-03-01 10:42:33 +11:00
90327cb521 build(ui): do not fail build on eslint error in dev mode 2024-03-01 10:42:33 +11:00
4d5458648b chore(ui): typegen 2024-03-01 10:42:33 +11:00
8d8f1abd50 feat(api): add MM get_by_attrs route
Gets the first model that matches the given name, base and type. Raises 404 if there isn't one.

This will be used for backwards compatibility with old metadata.
2024-03-01 10:42:33 +11:00
e20a506e40 undo 2024-03-01 10:42:33 +11:00
77b8eed51b fix literal strings in MM UI 2024-03-01 10:42:33 +11:00
c954cd4c8d fix TI appearing as key in prompt 2024-03-01 10:42:33 +11:00
630d3615ca fix base model grouping in combobox 2024-03-01 10:42:33 +11:00
c80c0f0fb9 fix(mm): fix ModelCacheBase method name 2024-03-01 10:42:33 +11:00
37d66488c5 chore: ruff 2024-03-01 10:42:33 +11:00
371e3cc260 recover gracefuly from GPU out of memory errors (next version) 2024-03-01 10:42:33 +11:00
d22738723d clear out VRAM when an OOM occurs 2024-03-01 10:42:33 +11:00
fbd9ffdc5a feat(ui): bulk download click to download 2024-03-01 10:42:33 +11:00
04c060a89d fix(ui): fix node types for canvas graphs 2024-03-01 10:42:33 +11:00
6f591b324b chore(ui): typegen 2024-03-01 10:42:33 +11:00
82249cc634 tidy(nodes): rename canvas paste back 2024-03-01 10:42:33 +11:00
cc82ce820a fix: outpaint result not getting pasted back correctly 2024-03-01 10:42:33 +11:00
8e1fbd6ed1 fix: lint errors 2024-03-01 10:42:33 +11:00
68d79c002d canvas: improve paste back (or try to) 2024-03-01 10:42:33 +11:00
8f6c2a8b92 wip(ui): Replace 2 Layer Coherence pass with Gradient Mask 2024-03-01 10:42:33 +11:00
ea7b7bcf40 chore: ruff 2024-03-01 10:42:33 +11:00
1456c997fb fix(ui): fix merge issue 2024-03-01 10:42:33 +11:00
7fce234646 fix(ui): use new scan_folder response instead of hook to determine if models are installed already 2024-03-01 10:42:33 +11:00
9e02384674 chore(ui): typegen 2024-03-01 10:42:33 +11:00
531d6f40f4 feat(mm): add logic to scan_folder route to check if a model is already installed
This was done in the frontend before but it's something the backend should handle.

The logic compares the found model paths to the path and source of all installed models. It excludes core models.
2024-03-01 10:42:33 +11:00
98d60e7db5 chore(ui): lint 2024-03-01 10:42:33 +11:00
1436a5f295 build(ui): restore i18n eslint rule 2024-03-01 10:42:33 +11:00
e22c4987bf chore: ruff 2024-03-01 10:42:33 +11:00
4420392241 fix(ui): fix metadata route 2024-03-01 10:42:33 +11:00
1d410e6346 chore(ui): typegen 2024-03-01 10:42:33 +11:00
c98668e7f5 feat(api): mm metadata route "meta" -> "metadata" 2024-03-01 10:42:33 +11:00
740dbc0c32 lint fix 2024-03-01 10:42:33 +11:00
97181d159f updated translations 2024-03-01 10:42:33 +11:00
65b0d3d436 fix convert endpoint logic 2024-03-01 10:42:33 +11:00
baf1194cae clean up old model manager components and endpoints 2024-03-01 10:42:33 +11:00
9b1f63379a add model convert to checkpoint main models 2024-03-01 10:42:33 +11:00
c3f4e87a6e fix logic to see if scanned models are already installed, style tweaks 2024-03-01 10:42:33 +11:00
26a209a00d add error_reason to ModelInstallJob 2024-03-01 10:42:33 +11:00
625c86ba9a add error_reason to UI if import fails 2024-03-01 10:42:33 +11:00
53f0090197 fix types for ImportQueue, add QuickAdd for scan models 2024-03-01 10:42:33 +11:00
5496699d6c refactored and fixed issues with advanced import form 2024-03-01 10:42:33 +11:00
b5ce28e60b fix(ui): misc MM cleanup 2024-03-01 10:42:33 +11:00
816fb53a14 chore(ui): temp disable eslint i18 rule 2024-03-01 10:42:33 +11:00
793c7ec832 fix(ui): fix ImportMainModelResponse type 2024-03-01 10:42:33 +11:00
62c67d7c4b fix(ui): simplify model install event listeners 2024-03-01 10:42:33 +11:00
7c41b3439a fix(ui): fix model install event types 2024-03-01 10:42:33 +11:00
cdd2f18bbd added advanced import forms, not fully working yet 2024-03-01 10:42:33 +11:00
e7d7b37896 get positioning/scrolling working for scan results list 2024-03-01 10:42:33 +11:00
57a402053e basic scan working and renders results 2024-03-01 10:42:33 +11:00
9ae09e9a7c add scan model endpoint, break add model into tabs 2024-03-01 10:42:33 +11:00
5a12886dbb update metadata endpoint 2024-03-01 10:42:33 +11:00
5b7633f3c6 allow metadata-less models to be used for GET metadata endpoint 2024-03-01 10:42:33 +11:00
68f24d9f0d added status to import queue model 2024-03-01 10:42:33 +11:00
ea364bdf82 delete model imports and prune all finished, update state with socket messages 2024-03-01 10:42:33 +11:00
18904f79ef fix sync model endpoint 2024-03-01 10:42:33 +11:00
782d15af13 form error handling 2024-03-01 10:42:33 +11:00
86e2b39f0d finish model update 2024-03-01 10:42:33 +11:00
20576deae8 added socket listeners, added more info to ui 2024-03-01 10:42:33 +11:00
0a69779df9 edit view for model, depending on type and valid values 2024-03-01 10:42:33 +11:00
6b68971f38 hook up Add Model button 2024-03-01 10:42:33 +11:00
c46eb72d45 single model view 2024-03-01 10:42:33 +11:00
87ce74e05d added import model form and importqueue 2024-03-01 10:42:33 +11:00
c7d462b222 model list, filtering, searching 2024-03-01 10:42:33 +11:00
9068400433 workspace for mary and jenn 2024-03-01 10:42:33 +11:00
55f3c6e721 get old UI working somewhat with new endpoints 2024-03-01 10:42:33 +11:00
c778ab8db4 Allow passing in key on register 2024-03-01 10:42:33 +11:00
65b91356d0 Remove passing keys in on register 2024-03-01 10:42:33 +11:00
de9287a3e4 Run ruff 2024-03-01 10:42:33 +11:00
008716040b Allow users to run model manager without cuda 2024-03-01 10:42:33 +11:00
abc569c2dd fix(ui): roll back utility-types
It's `Required` util does not distribute over unions as expected. Also we have `ts-toolbelt` already for some utils.
2024-03-01 10:42:33 +11:00
3ed2963f43 feat(ui): refactor metadata handling
Refactor of metadata recall handling. This is in preparation for a backwards compatibility layer for models.

- Create helpers to fetch a model outside react (e.g. not in a hook)
- Created helpers to parse model metadata
- Renamed a lot of types that were confusing and/or had naming collisions
2024-03-01 10:42:33 +11:00
79b16596b5 chore(ui): typegen 2024-03-01 10:42:33 +11:00
239ecfaf79 fix(nodes): make fields on ModelConfigBase required
The setup of `ModelConfigBase` means autogenerated types have critical fields flagged as nullable (like `key` and `base`). Need to manually flag them as required.
2024-03-01 10:42:33 +11:00
0d9fbe5e04 feat(ui): replace type-fest with utility-types
- The new package has more useful types
- Only used `JsonObject` from `type-fest`; added an implementation of that type
2024-03-01 10:42:33 +11:00
cc41e8912c several small model install enhancements
- Support extended HF repoid syntax in TUI. This allows
  installation of subfolders and safetensors files, as in
  `XpucT/Deliberate::Deliberate_v5.safetensors`

- Add `error` and `error_traceback` properties to the install
  job objects.

- Rename the `heuristic_import` route to `heuristic_install`.

- Fix the example `config` input in the `heuristic_install` route.
2024-03-01 10:42:33 +11:00
1cec0bb179 use official Deliberate download repo 2024-03-01 10:42:33 +11:00
65dd4f4abc fix repo-id for the Deliberate v5 model
prevent lora and embedding file suffixes from being stripped during installation

apply psychedelicious patch to get compel to load proper TI embedding
2024-03-01 10:42:33 +11:00
5bb3aeaccd remove startup dependency on legacy models.yaml file 2024-03-01 10:42:33 +11:00
30a374a70f chore: typing 2024-03-01 10:42:33 +11:00
07dde92664 chore: typing fix 2024-03-01 10:42:33 +11:00
06cc57d82a feat(nodes): added gradient mask node 2024-03-01 10:42:33 +11:00
f7fc20459a Run ruff 2024-03-01 10:42:33 +11:00
9269bdd233 rename endpoint for scanning 2024-03-01 10:42:33 +11:00
97cfcd2eef Create /search endpoint, update model object structure in scan model page 2024-03-01 10:42:33 +11:00
571a86a965 chore(ui): bump deps
Notable updates:
- Minor version of RTK includes customizable selectors for RTK Query, so we can remove the patch that was added to ensure only the LRU memoize function was used for perf reasons. Updated to use the LRU memoize function.
- Major version of react-resizable-panels. No breaking changes, works great, and you can now resize all panels when dragging at the intersection point of panels. Cool!
- Minor (?) version of nanostores. `action` API is removed, we were using it in one spot. Fixed.
- @invoke-ai/eslint-config-react has all deps bumped and now has its dependent plugins/configs listed as normal dependencies (as opposed to peer deps). This means we can remove those packages from explicit dev deps.
2024-03-01 10:42:33 +11:00
dbd929df05 tidy(ui): remove debugging stmt 2024-03-01 10:42:33 +11:00
b59d23d608 fix(ui): handle new model format for metadata 2024-03-01 10:42:33 +11:00
9d9b417432 fix(ui): use model names in badges 2024-03-01 10:42:33 +11:00
34f3a39cc9 fix(nodes): fix TI loading 2024-03-01 10:42:33 +11:00
e3c23baae9 fix(ui): fix package build 2024-03-01 10:42:33 +11:00
6a923cce70 feat(ui): do not subscribe to bulk download sio room if baseUrl is set 2024-03-01 10:42:33 +11:00
c0f0f2f39e feat(ui): revise bulk download listeners
- Use a single listener for all of the to keep them in one spot
- Use the bulk download item name as a toast id so we can update the existing toasts
- Update handling to work with other environments
- Move all bulk download handling from components to listener
2024-03-01 10:42:33 +11:00
64908eda55 chore(ui): typegen 2024-03-01 10:42:33 +11:00
a37b60db13 feat(bulk_download): update response model, messages 2024-03-01 10:42:33 +11:00
9e296f6916 implementing download for bulk_download events 2024-03-01 10:42:33 +11:00
ab94484c6c setting up event listeners for bulk download socket 2024-03-01 10:42:33 +11:00
5cba55d670 test: clean up & fix tests
- Deduplicate the mock invocation services. This is possible now that the import order issue is resolved.
- Merge `DummyEventService` into `TestEventService` and update all tests to use `TestEventService`.
2024-03-01 10:42:33 +11:00
cbb997e7d0 tidy(bulk_download): don't store events service separately
Using the invoker object directly leaves no ambiguity as to what `_events_bus` actually is.
2024-03-01 10:42:33 +11:00
98441ad08d tidy(bulk_download): do not rely on pagination API to get all images for board
We can get all images for the board as a list of image names, then pass that to `_image_handler` to get the DTOs, decoupling from the pagination API.
2024-03-01 10:42:33 +11:00
80c67dd6e0 tidy(bulk_download): nit - use or as a coalescing operator
Just a bit cleaner.
2024-03-01 10:42:33 +11:00
38af234108 tidy(bulk_download): use single underscore for private attrs
Double underscores are used in the app but it doesn't actually do or convey anything that single underscores don't already do. Considered unpythonic except for actual dunder/magic methods.
2024-03-01 10:42:33 +11:00
2291122c2b tidy(bulk_download): remove class-level attr annotations
These can be misleading as they shadow actual assigned class attributes. This pattern is in the rest of the app but it shouldn't be.
2024-03-01 10:42:33 +11:00
bf3b10cb1c tidy(bulk_download): remove extraneous abstract methods
`start`, `stop` and `__init__` are not required in implementations of an ABC or service.
2024-03-01 10:42:33 +11:00
7f8f182a00 tidy(bulk_download): clean up comments 2024-03-01 10:42:33 +11:00
e51867756a adding bulk_download_item_name to socket events 2024-03-01 10:42:33 +11:00
a8d7cf4e97 refactoring handlers to do null check 2024-03-01 10:42:33 +11:00
037cac8154 removing dependency on an output folder, embrace python temp folder for bulk download 2024-03-01 10:42:33 +11:00
0ab9fe6987 relocating event_service fixture due to import ordering 2024-03-01 10:42:33 +11:00
b5a9ed351d moving the responsibility of cleaning up board names to the service not the route 2024-03-01 10:42:33 +11:00
5f4b406cfe updating imports to satisfy ruff 2024-03-01 10:42:33 +11:00
f15aa562c2 using temp directory for downloads 2024-03-01 10:42:33 +11:00
d0f3571e59 returning the bulk_download_item_name on response for possible polling 2024-03-01 10:42:33 +11:00
b5ca1643a6 narrowing bulk_download stop service scope 2024-03-01 10:42:33 +11:00
39c01a833d adding test coverage for new bulk download routes 2024-03-01 10:42:33 +11:00
79eb871683 cleaning up bulk download zip after the response is complete 2024-03-01 10:42:33 +11:00
7544b350f3 replacing import removed during rebase 2024-03-01 10:42:33 +11:00
284ba041bd 97% test coverage on bulk_download 2024-03-01 10:42:33 +11:00
7d91426d8f refactoring bulk_download to be better managed 2024-03-01 10:42:33 +11:00
db812133e7 refactoring dummy event service, DRY principal; adding bulk_download_event to existing invoker tests 2024-03-01 10:42:33 +11:00
795fbf0e81 refactoring bulkdownload to consider image category 2024-03-01 10:42:33 +11:00
7114d64b86 fixing issue where default board did not return images 2024-03-01 10:42:33 +11:00
c43ea9f25c using the board name to download boards 2024-03-01 10:42:33 +11:00
52b0deb179 reworking some of the logic to use a default room, adding endpoint to download file on complete 2024-03-01 10:42:33 +11:00
7ecc18938b linted and styling 2024-03-01 10:42:33 +11:00
56d2d220a8 implementation of bulkdownload background task 2024-03-01 10:42:33 +11:00
f1967c3393 adding socket events for bulk download 2024-03-01 10:42:33 +11:00
812e24cbd2 groundwork for the bulk_download_service 2024-03-01 10:42:33 +11:00
8afe328af0 fix(ui): get workflow editor model selects working 2024-03-01 10:42:33 +11:00
e771c5f467 fix(ui): get refiner model select working 2024-03-01 10:42:33 +11:00
e7e3045a8a fix(ui): get vae model select working 2024-03-01 10:42:33 +11:00
f870f810d5 fix(ui): get embedding select working 2024-03-01 10:42:33 +11:00
a793103d7a fix(ui): get lora select working 2024-03-01 10:42:33 +11:00
7e5a85496e chore(ui): bump @invoke-ai/ui-library 2024-03-01 10:42:33 +11:00
ca7e928710 fix(ui): fix low-hanging fruit types 2024-03-01 10:42:33 +11:00
5b133ad198 Add a few convenience targets to Makefile
- "test" to run pytests
- "frontend-install" to reinstall pnpm's node modeuls
2024-03-01 10:42:33 +11:00
89fa36a818 chore(nodes): update TODO comment 2024-03-01 10:42:33 +11:00
e3f9da29ba tidy(nodes): clean up profiler/stats in processor, better comments 2024-03-01 10:42:33 +11:00
763debdeeb fix(nodes): fix typing on stats service context manager 2024-03-01 10:42:33 +11:00
8bf9fd34ad fix(nodes): fix model load events
was accessing incorrect properties in event data
2024-03-01 10:42:33 +11:00
0b0cb0ccc6 feat(nodes): making invocation class var in processor 2024-03-01 10:42:33 +11:00
fa39523b11 feat(nodes): improved error messages in processor 2024-03-01 10:42:33 +11:00
16676feea8 feat(nodes): make processor thread limit and polling interval configurable 2024-03-01 10:42:33 +11:00
0788a27a80 tests(nodes): fix tests following removal of services 2024-03-01 10:42:33 +11:00
d53a2a2d4e chore(nodes): better comments for invocation context 2024-03-01 10:42:33 +11:00
ccfe6b6bef chore(nodes): "context_data" -> "data"
Changed within InvocationContext, for brevity.
2024-03-01 10:42:33 +11:00
fdac0c3c9b refactor(nodes): move is_canceled to context.util 2024-03-01 10:42:33 +11:00
18adcc1dd2 feat(nodes): add whole queue_item to InvocationContextData
No reason to not have the whole thing in there.
2024-03-01 10:42:33 +11:00
86c50f2d5b tidy(nodes): remove extraneous comments 2024-03-01 10:42:33 +11:00
3cfac8b843 feat(nodes): better invocation error messages 2024-03-01 10:42:33 +11:00
0788b6ecee chore(nodes): add comments for cancel state 2024-03-01 10:42:33 +11:00
317d076a1a feat(nodes): promote is_canceled to public node API 2024-03-01 10:42:33 +11:00
725c03cf87 refactor(nodes): merge processors
Consolidate graph processing logic into session processor.

With graphs as the unit of work, and the session queue distributing graphs, we no longer need the invocation queue or processor.

Instead, the session processor dequeues the next session and processes it in a simple loop, greatly simplifying the app.

- Remove `graph_execution_manager` service.
- Remove `queue` (invocation queue) service.
- Remove `processor` (invocation processor) service.
- Remove queue-related logic from `Invoker`. It now only starts and stops the services, providing them with access to other services.
- Remove unused `invocation_retrieval_error` and `session_retrieval_error` events, these are no longer needed.
- Clean up stats service now that it is less coupled to the rest of the app.
- Refactor cancellation logic - cancellations now originate from session queue (i.e. HTTP cancel endpoint) and are emitted as events. Processor gets the events and sets the canceled event. Access to this event is provided to the invocation context for e.g. the step callback.
- Remove `sessions` router; it provided access to `graph_executions` but that no longer exists.
2024-03-01 10:42:33 +11:00
da9991e361 tidy(nodes): remove commented tests 2024-03-01 10:42:33 +11:00
67daa127e3 chore(ui): typegen 2024-03-01 10:42:33 +11:00
7e71effa17 tidy(nodes): remove no-op model_config
Because we now customize the JSON Schema creation for GraphExecutionState, the model_config did nothing.
2024-03-01 10:42:33 +11:00
e93bd15392 tidy(nodes): remove LibraryGraphs
The workflow library supersedes this unused feature.
2024-03-01 10:42:33 +11:00
0b81703c9f tidy(nodes): move node tests to parent dir
Thanks to the resolution of the import vs union issue, we can put tests anywhere.
2024-03-01 10:42:33 +11:00
641d235102 tidy(nodes): remove GraphInvocation
`GraphInvocation` is a node that can contain a whole graph. It is removed for a number of reasons:

1. This feature was unused (the UI doesn't support it) and there is no plan for it to be used.

The use-case it served is known in other node execution engines as "node groups" or "blocks" - a self-contained group of nodes, which has group inputs and outputs. This is a planned feature that will be handled client-side.

2. It adds substantial complexity to the graph processing logic. It's probably not enough to have a measurable performance impact but it does make it harder to work in the graph logic.

3. It allows for graphs to be recursive, and the improved invocations union handling does not play well with it. Actually, it works fine within `graph.py` but not in the tests for some reason. I do not understand why. There's probably a workaround, but I took this as encouragement to remove `GraphInvocation` from the app since we don't use it.
2024-03-01 10:42:33 +11:00
b79ae3a101 fix(nodes): fix OpenAPI schema generation
The change to `Graph.nodes` and `GraphExecutionState.results` validation requires some fanagling to get the OpenAPI schema generation to work. See new comments for a details.
2024-03-01 10:42:33 +11:00
731860c332 feat(nodes): JIT graph nodes validation
We use pydantic to validate a union of valid invocations when instantiating a graph.

Previously, we constructed the union while creating the `Graph` class. This introduces a dependency on the order of imports.

For example, consider a setup where we have 3 invocations in the app:

- Python executes the module where `FirstInvocation` is defined, registering `FirstInvocation`.
- Python executes the module where `SecondInvocation` is defined, registering `SecondInvocation`.
- Python executes the module where `Graph` is defined. A union of invocations is created and used to define the `Graph.nodes` field. The union contains `FirstInvocation` and `SecondInvocation`.
- Python executes the module where `ThirdInvocation` is defined, registering `ThirdInvocation`.
- A graph is created that includes `ThirdInvocation`. Pydantic validates the graph using the union, which does not know about `ThirdInvocation`, raising a `ValidationError` about an unknown invocation type.

This scenario has been particularly problematic in tests, where we may create invocations dynamically. The test files have to be structured in such a way that the imports happen in the right order. It's a major pain.

This PR refactors the validation of graph nodes to resolve this issue:

- `BaseInvocation` gets a new method `get_typeadapter`. This builds a pydantic `TypeAdapter` for the union of all registered invocations, caching it after the first call.
- `Graph.nodes`'s type is widened to `dict[str, BaseInvocation]`. This actually is a nice bonus, because we get better type hints whenever we reference `some_graph.nodes`.
- A "plain" field validator takes over the validation logic for `Graph.nodes`. "Plain" validators totally override pydantic's own validation logic. The validator grabs the `TypeAdapter` from `BaseInvocation`, then validates each node with it. The validation is identical to the previous implementation - we get the same errors.

`BaseInvocationOutput` gets the same treatment.
2024-03-01 10:42:33 +11:00
af2117dc0c remove errant def that was crashing invokeai-configure 2024-03-01 10:42:33 +11:00
1242cb4f85 one more redundant RGB convert removed 2024-03-01 10:42:33 +11:00
cd070d8be9 chore: ruff formatting 2024-03-01 10:42:33 +11:00
56ac2104e3 chore(invocations): remove redundant RGB conversions 2024-03-01 10:42:33 +11:00
965867151b chore(invocations): use IMAGE_MODES constant literal 2024-03-01 10:42:33 +11:00
2d007ce532 fix: removed custom module 2024-03-01 10:42:33 +11:00
92394ab751 fix(nodes): canny preprocessor uses RGBA again 2024-03-01 10:42:33 +11:00
43d94c8108 feat(nodes): format option for get_image method
Also default CNet preprocessors to "RGB"
2024-03-01 10:42:33 +11:00
fc20822595 fix: Alpha channel causing issue with DW Processor 2024-03-01 10:42:33 +11:00
5a3195f757 final tidying before marking PR as ready for review
- Replace AnyModelLoader with ModelLoaderRegistry
- Fix type check errors in multiple files
- Remove apparently unneeded `get_model_config_enum()` method from model manager
- Remove last vestiges of old model manager
- Updated tests and documentation

resolve conflict with seamless.py
2024-03-01 10:42:33 +11:00
5d612ec095 Tidy names and locations of modules
- Rename old "model_management" directory to "model_management_OLD" in order to catch
  dangling references to original model manager.
- Caught and fixed most dangling references (still checking)
- Rename lora, textual_inversion and model_patcher modules
- Introduce a RawModel base class to simplfy the Union returned by the
  model loaders.
- Tidy up the model manager 2-related tests. Add useful fixtures, and
  a finalizer to the queue and installer fixtures that will stop the
  services and release threads.
2024-03-01 10:42:33 +11:00
996eb96b4e Fix issues identified during PR review by RyanjDick and brandonrising
- ModelMetadataStoreService is now injected into ModelRecordStoreService
  (these two services are really joined at the hip, and should someday be merged)
- ModelRecordStoreService is now injected into ModelManagerService
- Reduced timeout value for the various installer and download wait*() methods
- Introduced a Mock modelmanager for testing
- Removed bare print() statement with _logger in the install helper backend.
- Removed unused code from model loader init file
- Made `locker` a private variable in the `LoadedModel` object.
- Fixed up model merge frontend (will be deprecated anyway!)
2024-03-01 10:42:33 +11:00
f1597bd6da chore(ui): lint 2024-03-01 10:42:33 +11:00
e50b76571a feat(ui): fix main model & control adapter model selects 2024-03-01 10:42:33 +11:00
db363b5178 refactor(ui): url builders for each router
The MM2 router is at `api/v2/models`. URL builder utils make this a bit easier to manage.
2024-03-01 10:42:33 +11:00
dab939f7d1 feat(ui): update model identifier to be key (wip)
- Update most model identifiers to be `{key: string}` instead of name/base/type. Doesn't change the model select components yet.
- Update model _parameters_, stored in redux, to be `{key: string, base: BaseModel}` - we need to store the base model to be able to check model compatibility. May want to store the whole config? Not sure...
2024-03-01 10:42:33 +11:00
6df3c450e8 fix(nodes): fix t2i adapter model loading 2024-03-01 10:42:33 +11:00
b7ba65fef4 fix(ui): update model types 2024-03-01 10:42:33 +11:00
fc107ed711 tests(ui): add type tests 2024-03-01 10:42:33 +11:00
cb804e75ed tests(ui): enable vitest type testing
This is useful for the zod schemas and types we have created to match the backend.
2024-03-01 10:42:33 +11:00
7996d43af9 chore(ui): typegen 2024-03-01 10:42:33 +11:00
fab30b5a11 feat(ui): export components type 2024-03-01 10:42:33 +11:00
651ac56b2c fix(ui): fix type issues 2024-03-01 10:42:33 +11:00
68f53460f0 chore: lint 2024-03-01 10:42:33 +11:00
c80987eb8a chore: ruff 2024-03-01 10:42:33 +11:00
539570cc7a feat(nodes): update invocation context for mm2, update nodes model usage 2024-03-01 10:42:33 +11:00
88d6de4101 Raise InvalidModelConfigException when unable to detect load class in ModelLoader 2024-03-01 10:42:33 +11:00
4c6e34b216 Update _get_hf_load_class to support clipvision models 2024-03-01 10:42:33 +11:00
262cbaacdd References to context.services.model_manager.store.get_model can only accept keys, remove invalid assertion 2024-03-01 10:42:33 +11:00
35e8a33dfd Remove references to model_records service, change submodel property on ModelInfo to submodel_type to support new params in model manager 2024-03-01 10:42:33 +11:00
b0835db47d improve swagger documentation 2024-03-01 10:42:33 +11:00
3e330d7d9d fix a number of typechecking errors 2024-03-01 10:42:33 +11:00
ff6e94f828 add route for model conversion from safetensors to diffusers
- Begin to add SwaggerUI documentation for AnyModelConfig and other
  discriminated Unions.
2024-03-01 10:42:33 +11:00
a2cc4047f9 add a JIT download_and_cache() call to the model installer 2024-03-01 10:42:33 +11:00
4027e845d4 add back the heuristic_import() method and extend repo_ids to arbitrary file paths 2024-03-01 10:42:33 +11:00
a23dedd2ee make model manager v2 ready for PR review
- Replace legacy model manager service with the v2 manager.

- Update invocations to use new load interface.

- Fixed many but not all type checking errors in the invocations. Most
  were unrelated to model manager

- Updated routes. All the new routes live under the route tag
  `model_manager_v2`. To avoid confusion with the old routes,
  they have the URL prefix `/api/v2/models`. The old routes
  have been de-registered.

- Added a pytest for the loader.

- Updated documentation in contributing/MODEL_MANAGER.md
2024-03-01 10:42:33 +11:00
7956602b19 consolidate model manager parts into a single class 2024-03-01 10:42:33 +11:00
8db01ab1b3 probe for required encoder for IPAdapters and add to config 2024-03-01 10:42:33 +11:00
db340bc253 fix invokeai_configure script to work with new mm; rename CLIs 2024-03-01 10:42:33 +11:00
78ef946e01 BREAKING CHANGES: invocations now require model key, not base/type/name
- Implement new model loader and modify invocations and embeddings

- Finish implementation loaders for all models currently supported by
  InvokeAI.

- Move lora, textual_inversion, and model patching support into
  backend/embeddings.

- Restore support for model cache statistics collection (a little ugly,
  needs work).

- Fixed up invocations that load and patch models.

- Move seamless and silencewarnings utils into better location
2024-03-01 10:42:33 +11:00
5745ce9c7d Multiple refinements on loaders:
- Cache stat collection enabled.
- Implemented ONNX loading.
- Add ability to specify the repo version variant in installer CLI.
- If caller asks for a repo version that doesn't exist, will fall back
  to empty version rather than raising an error.
2024-03-01 10:42:33 +11:00
0d3addc69b added textual inversion and lora loaders 2024-03-01 10:42:33 +11:00
67eb715093 loaders for main, controlnet, ip-adapter, clipvision and t2i 2024-03-01 10:42:33 +11:00
8ba5360269 model loading and conversion implemented for vaes 2024-03-01 10:42:33 +11:00
b8e875bb73 add ram cache module and support files 2024-03-01 10:42:33 +11:00
010c4eae65 add concept of repo variant 2024-03-01 10:42:33 +11:00
95453a22b1 tests(ui): add parseFieldType.test.ts 2024-03-01 10:42:33 +11:00
30db708c4f feat(ui): add more types of FieldParseError
Unfortunately you cannot test for both a specific type of error and match its message. Splitting the error classes makes it easier to test expected error conditions.
2024-03-01 10:42:33 +11:00
fe27af461a feat(ui): add vitest
- Add vitest.
- Consolidate vite configs into single file (easier to config everything based on env for testing)
2024-03-01 10:42:33 +11:00
f8525837b2 feat(ui): workflow schema v3 (WIP)
The changes aim to deduplicate data between workflows and node templates, decoupling workflows from internal implementation details. A good amount of data that was needlessly duplicated from the node template to the workflow is removed.

These changes substantially reduce the file size of workflows (and therefore the images with embedded workflows):

- Default T2I SD1.5 workflow JSON is reduced from 23.7kb (798 lines) to 10.9kb (407 lines).
- Default tiled upscale workflow JSON is reduced from 102.7kb (3341 lines) to 51.9kb (1774 lines).

The trade-off is that we need to reference node templates to get things like the field type and other things. In practice, this is a non-issue, because we need a node template to do anything with a node anyways.

- Field types are not included in the workflow. They are always pulled from the node templates.

The field type is now properly an internal implementation detail and we can change it as needed. Previously this would require a migration for the workflow itself. With the v3 schema, the structure of a field type is an internal implementation detail that we are free to change as we see fit.

- Workflow nodes no long have an `outputs` property and there is no longer such a thing as a `FieldOutputInstance`. These are only on the templates.

These were never referenced at a time when we didn't also have the templates available, and there'd be no reason to do so.

- Node width and height are no longer stored in the node.

These weren't used. Also, per https://reactflow.dev/api-reference/types/node, we shouldn't be programmatically changing these properties. A future enhancement can properly add node resizing.

- `nodeTemplates` slice is merged back into `nodesSlice` as `nodes.templates`. Turns out it's just a hassle having these separate in separate slices.

- Workflow migration logic updated to support the new schema. V1 workflows migrate all the way to v3 now.

- Changes throughout the nodes code to accommodate the above changes.
2024-03-01 10:42:33 +11:00
5fbfed30ac chore(ui): regen types 2024-03-01 10:42:33 +11:00
7a2159beeb feat(nodes): add more missing exports to invocation_api
Crawled through a few custom nodes to figure out what I had missed.
2024-03-01 10:42:33 +11:00
25f64d5b19 chore(nodes): "SAMPLER_NAME_VALUES" -> "SCHEDULER_NAME_VALUES"
This was named inaccurately.
2024-03-01 10:42:33 +11:00
b845e890d1 chore(nodes): remove deprecation logic for nodes API 2024-03-01 10:42:33 +11:00
6d31bc5326 chore(nodes): export model-related objects from invocation_api 2024-03-01 10:42:33 +11:00
0f8af643d1 chore(backend): rename ModelInfo -> LoadedModelInfo
We have two different classes named `ModelInfo` which might need to be used by API consumers. We need to export both but have to deal with this naming collision.

The `ModelInfo` I've renamed here is the one that is returned when a model is loaded. It's the object least likely to be used by API consumers.
2024-03-01 10:42:33 +11:00
e0694a2856 feat(nodes): use LATENT_SCALE_FACTOR in primitives.py, noise.py
- LatentsOutput.build
- NoiseOutput.build
- Noise.width, Noise.height multiple_of
2024-03-01 10:42:33 +11:00
e5d8921cf2 feat(nodes): extract LATENT_SCALE_FACTOR to constants.py 2024-03-01 10:42:33 +11:00
fece935438 feat(nodes): use TemporaryDirectory to handle ephemeral storage in ObjectSerializerDisk
Replace `delete_on_startup: bool` & associated logic with `ephemeral: bool` and `TemporaryDirectory`.

The temp dir is created inside of `output_dir`. For example, if `output_dir` is `invokeai/outputs/tensors/`, then the temp dir might be `invokeai/outputs/tensors/tmpvj35ht7b/`.

The temp dir is cleaned up when the service is stopped, or when it is GC'd if not properly stopped.

In the event of a catastrophic crash where the temp files are not cleaned up, the user can delete the tempdir themselves.

This situation may not occur in normal use, but if you kill the process, python cannot clean up the temp dir itself. This includes running the app in a debugger and killing the debugger process - something I do relatively often.

Tests updated.
2024-03-01 10:42:33 +11:00
11f64dab38 tests: test ObjectSerializerDisk class name extraction 2024-03-01 10:42:33 +11:00
670f2f75e9 chore(nodes): update ObjectSerializerForwardCache docstring 2024-03-01 10:42:33 +11:00
66d0ec3f6c chore(nodes): fix pyright ignore 2024-03-01 10:42:33 +11:00
6087ace4f1 tidy(nodes): "latents" -> "obj" 2024-03-01 10:42:33 +11:00
a9b1aad3d7 tidy(nodes): do not store unnecessarily store invoker 2024-03-01 10:42:33 +11:00
9edb995647 feat(nodes): make delete on startup configurable for obj serializer
- The default is to not delete on startup - feels safer.
- The two services using this class _do_ delete on startup.
- The class has "ephemeral" removed from its name.
- Tests & app updated for this change.
2024-03-01 10:42:33 +11:00
091f4cb583 fix(nodes): use metadata/board_id if provided by user, overriding WithMetadata/WithBoard-provided values 2024-03-01 10:42:33 +11:00
1655061c96 tidy(nodes): clarify comment 2024-03-01 10:42:33 +11:00
220baae793 Revert "feat(nodes): use LATENT_SCALE_FACTOR const in tensor output builders"
This reverts commit ef18fc546560277302f3886e456da9a47e8edce0.
2024-03-01 10:42:33 +11:00
e08f16763b feat(nodes): use LATENT_SCALE_FACTOR const in tensor output builders 2024-03-01 10:42:33 +11:00
6d25789705 tests: fix broken tests 2024-03-01 10:42:33 +11:00
aff44c0e58 tidy(nodes): minor spelling correction 2024-03-01 10:42:33 +11:00
34d23366f4 tests: add object serializer tests
These test both object serializer and its forward cache implementation.
2024-03-01 10:42:33 +11:00
23de78ec9f feat(nodes): allow _delete_all in obj serializer to be called at any time
`_delete_all` logged how many items it deleted, and had to be called _after_ service start bc it needed access to logger.

Move the logger call to the startup method and return the the deleted stats from `_delete_all`. This lets `_delete_all` be called at any time.
2024-03-01 10:42:33 +11:00
507aeac8a5 tidy(nodes): remove object serializer on_saved
It's unused.
2024-03-01 10:42:33 +11:00
9f382419dc revert(nodes): revert making tensors/conditioning use item storage
Turns out they are just different enough in purpose that the implementations would be rather unintuitive. I've made a separate ObjectSerializer service to handle tensors and conditioning.

Refined the class a bit too.
2024-03-01 10:42:33 +11:00
73d871116c feat(nodes): support custom exception in ephemeral disk storage 2024-03-01 10:42:33 +11:00
ab58d34f9b feat(nodes): support custom save and load functions in ItemStorageEphemeralDisk 2024-03-01 10:42:33 +11:00
9cda62c2a7 feat(nodes): create helper function to generate the item ID 2024-03-01 10:42:33 +11:00
a50c7c1cd7 feat(nodes): use ItemStorageABC for tensors and conditioning
Turns out `ItemStorageABC` was almost identical to `PickleStorageBase`. Instead of maintaining separate classes, we can use `ItemStorageABC` for both.

There's only one change needed - the `ItemStorageABC.set` method must return the newly stored item's ID. This allows us to let the service handle the responsibility of naming the item, but still create the requisite output objects during node execution.

The naming implementation is improved here. It extracts the name of the generic and appends a UUID to that string when saving items.
2024-03-01 10:42:33 +11:00
ca09bd63a3 tidy(nodes): do not refer to files as latents in PickleStorageTorch (again) 2024-03-01 10:42:33 +11:00
c96f50cc9a feat(nodes): ItemStorageABC typevar no longer bound to pydantic.BaseModel
This bound is totally unnecessary. There's no requirement for any implementation of `ItemStorageABC` to work only on pydantic models.
2024-03-01 10:42:33 +11:00
de63e888d6 fix(nodes): add super init to PickleStorageTorch 2024-03-01 10:42:33 +11:00
5dd158a2d4 tidy(nodes): do not refer to files as latents in PickleStorageTorch 2024-03-01 10:42:33 +11:00
0710fb3fb0 feat(nodes): replace latents service with tensors and conditioning services
- New generic class `PickleStorageBase`, implements the same API as `LatentsStorageBase`, use for storing non-serializable data via pickling
- Implementation `PickleStorageTorch` uses `torch.save` and `torch.load`, same as `LatentsStorageDisk`
- Add `tensors: PickleStorageBase[torch.Tensor]` to `InvocationServices`
- Add `conditioning: PickleStorageBase[ConditioningFieldData]` to `InvocationServices`
- Remove `latents` service and all `LatentsStorage` classes
- Update `InvocationContext` and all usage of old `latents` service to use the new services/context wrapper methods
2024-03-01 10:42:33 +11:00
31db62ba99 tidy(nodes): delete onnx.py
It doesn't work and keeping it updated to prevent the app from starting was getting tedious. Deleted.
2024-03-01 10:42:33 +11:00
322a60f48f fix(nodes): rearrange fields.py to avoid needing forward refs 2024-03-01 10:42:33 +11:00
b386b1b8af tidy(nodes): remove unnecessary, shadowing class attr declarations 2024-03-01 10:42:33 +11:00
70034d26e2 feat(ui): revise graphs to not use LinearUIOutputInvocation
See this comment for context: https://github.com/invoke-ai/InvokeAI/pull/5491#discussion_r1480760629

- Remove this now-unnecessary node from all graphs
- Update graphs' terminal image-outputting nodes' `is_intermediate` and `board` fields appropriately
- Add util function to prepare the `board` field, tidy the utils
- Update `socketInvocationComplete` listener to work correctly with this change

I've manually tested all graph permutations that were changed (I think this is all...) to ensure images go to the gallery as expected:
- ad-hoc upscaling
- t2i w/ sd1.5
- t2i w/ sd1.5 & hrf
- t2i w/ sdxl
- t2i w/ sdxl + refiner
- i2i w/ sd1.5
- i2i w/ sdxl
- i2i w/ sdxl + refiner
- canvas t2i w/ sd1.5
- canvas t2i w/ sdxl
- canvas t2i w/ sdxl + refiner
- canvas i2i w/ sd1.5
- canvas i2i w/ sdxl
- canvas i2i w/ sdxl + refiner
- canvas inpaint w/ sd1.5
- canvas inpaint w/ sdxl
- canvas inpaint w/ sdxl + refiner
- canvas outpaint w/ sd1.5
- canvas outpaint w/ sdxl
- canvas outpaint w/ sdxl + refiner
2024-03-01 10:42:33 +11:00
d60f1965d1 chore(ui): regen types 2024-03-01 10:42:33 +11:00
7fbdfbf9e5 feat(nodes): add WithBoard field helper class
This class works the same way as `WithMetadata` - it simply adds a `board` field to the node. The context wrapper function is able to pull the board id from this. This allows image-outputting nodes to get a board field "for free", and have their outputs automatically saved to it.

This is a breaking change for node authors who may have a field called `board`, because it makes `board` a reserved field name. I'll look into how to avoid this - maybe by naming this invoke-managed field `_board` to avoid collisions?

Supporting changes:
- `WithBoard` is added to all image-outputting nodes, giving them the ability to save to board.
- Unused, duplicate `WithMetadata` and `WithWorkflow` classes are deleted from `baseinvocation.py`. The "real" versions are in `fields.py`.
- Remove `LinearUIOutputInvocation`. Now that all nodes that output images also have a `board` field by default, this node is no longer necessary. See comment here for context: https://github.com/invoke-ai/InvokeAI/pull/5491#discussion_r1480760629
- Without `LinearUIOutputInvocation`, the `ImagesInferface.update` method is no longer needed, and removed.

Note: This commit does not bump all node versions. I will ensure that is done correctly before merging the PR of which this commit is a part.

Note: A followup commit will implement the frontend changes to support this change.
2024-03-01 10:42:33 +11:00
e137071543 remove unused configdict import 2024-03-01 10:42:33 +11:00
5d2f70b3ef fix(ui): remove original l2i node in HRF graph 2024-03-01 10:42:33 +11:00
47d05fdd81 fix(nodes): do not freeze or cache config in context wrapper
- The config is already cached by the config class's `get_config()` method.
- The config mutates itself in its `root_path` property getter. Freezing the class makes any attempt to grab a path from the config error. Unfortunately this means we cannot easily freeze the class without fiddling with the inner workings of `InvokeAIAppConfig`, which is outside the scope here.
2024-03-01 10:42:33 +11:00
958b80acdd feat(nodes): context.data -> context._data 2024-03-01 10:42:33 +11:00
5730ae9b96 feat(nodes): context.__services -> context._services 2024-03-01 10:42:33 +11:00
60e2eff94d feat(nodes): cache invocation interface config 2024-03-01 10:42:33 +11:00
dcafbb9988 feat(nodes): do not hide services in invocation context interfaces 2024-03-01 10:42:33 +11:00
cc8d713c57 fix(nodes): restore missing context type annotations 2024-03-01 10:42:33 +11:00
59c77832d8 tests(nodes): fix mock InvocationContext 2024-03-01 10:42:33 +11:00
cbf22d8a80 chore(nodes): add comments for ConfigInterface 2024-03-01 10:42:33 +11:00
e11af7de9b feat(nodes): export more things from `invocation_api" 2024-03-01 10:42:33 +11:00
95dd5aad16 feat(nodes): add boards interface to invocation context 2024-03-01 10:42:33 +11:00
4ce21087d3 fix(nodes): restore type annotations for InvocationContext 2024-03-01 10:42:33 +11:00
281c334531 feat(nodes): do not freeze InvocationContextData, prevents it from being subclassesd 2024-03-01 10:42:33 +11:00
282b483d14 feat: tweak pyright config 2024-03-01 10:42:33 +11:00
a466f7a94b feat(nodes): create invocation_api.py
This is the public API for invocations.

Everything a custom node might need should be re-exported from this file.
2024-03-01 10:42:33 +11:00
05fb485d33 feat(nodes): move ConditioningFieldData to conditioning_data.py 2024-03-01 10:42:33 +11:00
6452c706e1 tests: fix missing arg for InvocationContext 2024-03-01 10:42:33 +11:00
f612a96afd feat(nodes): restore previous invocation context methods with deprecation warnings 2024-03-01 10:42:33 +11:00
9af0553652 chore: ruff 2024-03-01 10:42:33 +11:00
1616974b48 feat(nodes): tidy invocation_context.py, improve comments 2024-03-01 10:42:33 +11:00
ef27283569 tests: fix tests for new invocation context 2024-03-01 10:42:33 +11:00
a79a450e9d docs: update INVOCATIONS.md 2024-03-01 10:42:33 +11:00
8637c40661 feat(nodes): update all invocations to use new invocation context
Update all invocations to use the new context. The changes are all fairly simple, but there are a lot of them.

Supporting minor changes:
- Patch bump for all nodes that use the context
- Update invocation processor to provide new context
- Minor change to `EventServiceBase` to accept a node's ID instead of the dict version of a node
- Minor change to `ModelManagerService` to support the new wrapped context
- Fanagling of imports to avoid circular dependencies
2024-03-01 10:42:33 +11:00
9bc2d09889 feat: add pyright config
I was having issues with mypy bother over- and under-reporting certain problems. I've added a pyright config.
2024-03-01 10:42:33 +11:00
3d98446d5d feat(nodes): restricts invocation context power
Creates a low-power `InvocationContext` with simplified methods and data.

See `invocation_context.py` for detailed comments.
2024-03-01 10:42:33 +11:00
992b02aa65 tidy(nodes): move all field things to fields.py
Unfortunately, this is necessary to prevent circular imports at runtime.
2024-03-01 10:42:33 +11:00
63ab5ff5a2 translationBot(ui): update translation (Russian)
Currently translated at 98.3% (1398 of 1422 strings)

Co-authored-by: Васянатор <ilabulanov339@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/
Translation: InvokeAI/Web UI
2024-02-29 23:27:36 +11:00
9a8a9c5848 translationBot(ui): update translation (Italian)
Currently translated at 98.0% (1441 of 1470 strings)

Co-authored-by: Samantha Morello <tildsart@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-02-29 23:27:36 +11:00
1a3ffb6e94 translationBot(ui): update translation (German)
Currently translated at 80.4% (1183 of 1470 strings)

Co-authored-by: Alexander Eichhorn <pfannkuchensack@einfach-doof.de>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/de/
Translation: InvokeAI/Web UI
2024-02-29 23:27:36 +11:00
3a09bceea4 Update communityNodes.md
Updated description of metadata nodes
2024-02-26 14:20:09 -05:00
2ec6b51d8b translationBot(ui): update translation (Italian)
Currently translated at 97.2% (1430 of 1470 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-02-26 17:41:00 +11:00
B N
34b0ea20dc translationBot(ui): update translation (German)
Currently translated at 80.3% (1181 of 1470 strings)

translationBot(ui): update translation (German)

Currently translated at 80.1% (1178 of 1470 strings)

Co-authored-by: B N <berndnieschalk@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/de/
Translation: InvokeAI/Web UI
2024-02-26 17:41:00 +11:00
9986fce1a6 translationBot(ui): update translation (German)
Currently translated at 80.0% (1176 of 1470 strings)

Co-authored-by: Alexander Eichhorn <pfannkuchensack@einfach-doof.de>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/de/
Translation: InvokeAI/Web UI
2024-02-23 07:57:15 +11:00
228f1d7f62 translationBot(ui): update translation (Italian)
Currently translated at 95.6% (1406 of 1470 strings)

translationBot(ui): update translation (Italian)

Currently translated at 93.9% (1381 of 1470 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-02-23 07:57:15 +11:00
B N
01a6378dc1 translationBot(ui): update translation (German)
Currently translated at 78.8% (1159 of 1470 strings)

Co-authored-by: B N <berndnieschalk@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/de/
Translation: InvokeAI/Web UI
2024-02-23 07:57:15 +11:00
e01769294f translationBot(ui): update translation files
Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/
Translation: InvokeAI/Web UI
2024-02-20 22:33:03 +11:00
16aa261e28 updated tooltip popovers (#5751)
## What type of PR is this? (check all applicable)

- [ ] Refactor
- [ ] Feature
- [ ] Bug Fix
- [X] Optimization
- [ ] Documentation Update
- [ ] Community Node Submission


## Have you discussed this change with the InvokeAI team?
- [X] Yes
- [ ] No, because:

      
## Have you updated all relevant documentation?
- [ ] Yes
- [ ] No


## Description
Added new tooltip popovers and updated copy of existing ones

## Related Tickets & Documents

<!--
For pull requests that relate or close an issue, please include them
below. 

For example having the text: "closes #1234" would connect the current
pull
request to issue 1234.  And when we merge the pull request, Github will
automatically close the issue.
-->

- Related Issue #
- Closes #

## QA Instructions, Screenshots, Recordings

<!-- 
Please provide steps on how to test changes, any hardware or 
software specifications as well as any other pertinent information. 
-->

## Merge Plan

<!--
A merge plan describes how this PR should be handled after it is
approved.

Example merge plans:
- "This PR can be merged when approved"
- "This must be squash-merged when approved"
- "DO NOT MERGE - I will rebase and tidy commits before merging"
- "#dev-chat on discord needs to be advised of this change when it is
merged"

A merge plan is particularly important for large PRs or PRs that touch
the
database in any way.
-->

## Added/updated tests?

- [ ] Yes
- [ ] No : _please replace this line with details on why tests
      have not been included_

## [optional] Are there any post deployment tasks we need to perform?
2024-02-19 13:12:47 -05:00
1dabf18d14 Merge branch 'main' into chainchompa/tooltip-popovers 2024-02-19 13:04:15 -05:00
115d92b1ae updated copy 2024-02-19 12:50:35 -05:00
f0d4c71960 updated tooltip popovers 2024-02-19 12:50:11 -05:00
3e48edda6f add latent-upscale to communityNodes.md (#5728)
Adds the 'latent upscale' community node
2024-02-19 16:53:35 +00:00
716b584f03 translationBot(ui): update translation (Italian)
Currently translated at 97.1% (1384 of 1424 strings)

Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/
Translation: InvokeAI/Web UI
2024-02-19 08:18:33 +11:00
B N
d43b843c23 translationBot(ui): update translation (German)
Currently translated at 80.2% (1143 of 1424 strings)

Co-authored-by: B N <berndnieschalk@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/de/
Translation: InvokeAI/Web UI
2024-02-18 01:47:01 +11:00
f36b5990ed fix(ui): do not provide auth headers for openapi.json 2024-02-15 10:38:26 -05:00
5706237ec7 {release} 3.7.0 (#5727)
## What type of PR is this? (check all applicable)

Release - Invoke 3.7.0

## Have you discussed this change with the InvokeAI team?
- [X] Yes
- [ ] No, because:

      
## Have you updated all relevant documentation?
- [X] Yes
- [ ] No


## Description
Invoke 3.7.0 Release

## QA Instructions, Screenshots, Recordings
Test Installer: 

[InvokeAI-installer-v3.7.0.zip](https://github.com/invoke-ai/InvokeAI/files/14298200/InvokeAI-installer-v3.7.0.zip)

<!-- 
Please provide steps on how to test changes, any hardware or 
software specifications as well as any other pertinent information. 
-->

## Merge Plan
Merge once approved
<!--
A merge plan describes how this PR should be handled after it is
approved.

Example merge plans:
- "This PR can be merged when approved"
- "This must be squash-merged when approved"
- "DO NOT MERGE - I will rebase and tidy commits before merging"
- "#dev-chat on discord needs to be advised of this change when it is
merged"

A merge plan is particularly important for large PRs or PRs that touch
the
database in any way.
-->

## Added/updated tests?

- [ ] Yes
- [X] No : _please replace this line with details on why tests
      have not been included_

## [optional] Are there any post deployment tasks we need to perform?
1. Release on PyPi
2. Release on GitHub
3. Announce on Discord
2024-02-15 07:59:20 -07:00
163b22a7b3 {release} 3.7.0 2024-02-15 07:34:31 -07:00
1581 changed files with 105086 additions and 93167 deletions

View File

@ -0,0 +1,33 @@
name: install frontend dependencies
description: Installs frontend dependencies with pnpm, with caching
runs:
using: 'composite'
steps:
- name: setup node 18
uses: actions/setup-node@v4
with:
node-version: '18'
- name: setup pnpm
uses: pnpm/action-setup@v4
with:
version: 8.15.6
run_install: false
- name: get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: setup cache
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: install frontend dependencies
run: pnpm install --prefer-frozen-lockfile
shell: bash
working-directory: invokeai/frontend/web

28
.github/pr_labels.yml vendored
View File

@ -1,59 +1,59 @@
Root:
root:
- changed-files:
- any-glob-to-any-file: '*'
PythonDeps:
python-deps:
- changed-files:
- any-glob-to-any-file: 'pyproject.toml'
Python:
python:
- changed-files:
- all-globs-to-any-file:
- 'invokeai/**'
- '!invokeai/frontend/web/**'
PythonTests:
python-tests:
- changed-files:
- any-glob-to-any-file: 'tests/**'
CICD:
ci-cd:
- changed-files:
- any-glob-to-any-file: .github/**
Docker:
docker:
- changed-files:
- any-glob-to-any-file: docker/**
Installer:
installer:
- changed-files:
- any-glob-to-any-file: installer/**
Documentation:
docs:
- changed-files:
- any-glob-to-any-file: docs/**
Invocations:
invocations:
- changed-files:
- any-glob-to-any-file: 'invokeai/app/invocations/**'
Backend:
backend:
- changed-files:
- any-glob-to-any-file: 'invokeai/backend/**'
Api:
api:
- changed-files:
- any-glob-to-any-file: 'invokeai/app/api/**'
Services:
services:
- changed-files:
- any-glob-to-any-file: 'invokeai/app/services/**'
FrontendDeps:
frontend-deps:
- changed-files:
- any-glob-to-any-file:
- '**/*/package.json'
- '**/*/pnpm-lock.yaml'
Frontend:
frontend:
- changed-files:
- any-glob-to-any-file: 'invokeai/frontend/web/**'

View File

@ -1,66 +1,21 @@
## What type of PR is this? (check all applicable)
## Summary
- [ ] Refactor
- [ ] Feature
- [ ] Bug Fix
- [ ] Optimization
- [ ] Documentation Update
- [ ] Community Node Submission
<!--A description of the changes in this PR. Include the kind of change (fix, feature, docs, etc), the "why" and the "how". Screenshots or videos are useful for frontend changes.-->
## Related Issues / Discussions
## Have you discussed this change with the InvokeAI team?
- [ ] Yes
- [ ] No, because:
<!--WHEN APPLICABLE: List any related issues or discussions on github or discord. If this PR closes an issue, please use the "Closes #1234" format, so that the issue will be automatically closed when the PR merges.-->
## Have you updated all relevant documentation?
- [ ] Yes
- [ ] No
## QA Instructions
## Description
## Related Tickets & Documents
<!--
For pull requests that relate or close an issue, please include them
below.
For example having the text: "closes #1234" would connect the current pull
request to issue 1234. And when we merge the pull request, Github will
automatically close the issue.
-->
- Related Issue #
- Closes #
## QA Instructions, Screenshots, Recordings
<!--
Please provide steps on how to test changes, any hardware or
software specifications as well as any other pertinent information.
-->
<!--WHEN APPLICABLE: Describe how you have tested the changes in this PR. Provide enough detail that a reviewer can reproduce your tests.-->
## Merge Plan
<!--
A merge plan describes how this PR should be handled after it is approved.
<!--WHEN APPLICABLE: Large PRs, or PRs that touch sensitive things like DB schemas, may need some care when merging. For example, a careful rebase by the change author, timing to not interfere with a pending release, or a message to contributors on discord after merging.-->
Example merge plans:
- "This PR can be merged when approved"
- "This must be squash-merged when approved"
- "DO NOT MERGE - I will rebase and tidy commits before merging"
- "#dev-chat on discord needs to be advised of this change when it is merged"
## Checklist
A merge plan is particularly important for large PRs or PRs that touch the
database in any way.
-->
## Added/updated tests?
- [ ] Yes
- [ ] No : _please replace this line with details on why tests
have not been included_
## [optional] Are there any post deployment tasks we need to perform?
- [ ] _The PR has a short but descriptive title, suitable for a changelog_
- [ ] _Tests added / updated (if applicable)_
- [ ] _Documentation added / updated (if applicable)_

View File

@ -11,7 +11,7 @@ on:
- 'docker/docker-entrypoint.sh'
- 'workflows/build-container.yml'
tags:
- 'v*'
- 'v*.*.*'
workflow_dispatch:
permissions:

45
.github/workflows/build-installer.yml vendored Normal file
View File

@ -0,0 +1,45 @@
# Builds and uploads the installer and python build artifacts.
name: build installer
on:
workflow_dispatch:
workflow_call:
jobs:
build-installer:
runs-on: ubuntu-latest
timeout-minutes: 5 # expected run time: <2 min
steps:
- name: checkout
uses: actions/checkout@v4
- name: setup python
uses: actions/setup-python@v5
with:
python-version: '3.10'
cache: pip
cache-dependency-path: pyproject.toml
- name: install pypa/build
run: pip install --upgrade build
- name: setup frontend
uses: ./.github/actions/install-frontend-deps
- name: create installer
id: create_installer
run: ./create_installer.sh
working-directory: installer
- name: upload python distribution artifact
uses: actions/upload-artifact@v4
with:
name: dist
path: ${{ steps.create_installer.outputs.DIST_PATH }}
- name: upload installer artifact
uses: actions/upload-artifact@v4
with:
name: installer
path: ${{ steps.create_installer.outputs.INSTALLER_PATH }}

80
.github/workflows/frontend-checks.yml vendored Normal file
View File

@ -0,0 +1,80 @@
# Runs frontend code quality checks.
#
# Checks for changes to frontend files before running the checks.
# If always_run is true, always runs the checks.
name: 'frontend checks'
on:
push:
branches:
- 'main'
pull_request:
types:
- 'ready_for_review'
- 'opened'
- 'synchronize'
merge_group:
workflow_dispatch:
inputs:
always_run:
description: 'Always run the checks'
required: true
type: boolean
default: true
workflow_call:
inputs:
always_run:
description: 'Always run the checks'
required: true
type: boolean
default: true
defaults:
run:
working-directory: invokeai/frontend/web
jobs:
frontend-checks:
runs-on: ubuntu-latest
timeout-minutes: 10 # expected run time: <2 min
steps:
- uses: actions/checkout@v4
- name: check for changed frontend files
if: ${{ inputs.always_run != true }}
id: changed-files
uses: tj-actions/changed-files@v42
with:
files_yaml: |
frontend:
- 'invokeai/frontend/web/**'
- name: install dependencies
if: ${{ steps.changed-files.outputs.frontend_any_changed == 'true' || inputs.always_run == true }}
uses: ./.github/actions/install-frontend-deps
- name: tsc
if: ${{ steps.changed-files.outputs.frontend_any_changed == 'true' || inputs.always_run == true }}
run: 'pnpm lint:tsc'
shell: bash
- name: dpdm
if: ${{ steps.changed-files.outputs.frontend_any_changed == 'true' || inputs.always_run == true }}
run: 'pnpm lint:dpdm'
shell: bash
- name: eslint
if: ${{ steps.changed-files.outputs.frontend_any_changed == 'true' || inputs.always_run == true }}
run: 'pnpm lint:eslint'
shell: bash
- name: prettier
if: ${{ steps.changed-files.outputs.frontend_any_changed == 'true' || inputs.always_run == true }}
run: 'pnpm lint:prettier'
shell: bash
- name: knip
if: ${{ steps.changed-files.outputs.frontend_any_changed == 'true' || inputs.always_run == true }}
run: 'pnpm lint:knip'
shell: bash

60
.github/workflows/frontend-tests.yml vendored Normal file
View File

@ -0,0 +1,60 @@
# Runs frontend tests.
#
# Checks for changes to frontend files before running the tests.
# If always_run is true, always runs the tests.
name: 'frontend tests'
on:
push:
branches:
- 'main'
pull_request:
types:
- 'ready_for_review'
- 'opened'
- 'synchronize'
merge_group:
workflow_dispatch:
inputs:
always_run:
description: 'Always run the tests'
required: true
type: boolean
default: true
workflow_call:
inputs:
always_run:
description: 'Always run the tests'
required: true
type: boolean
default: true
defaults:
run:
working-directory: invokeai/frontend/web
jobs:
frontend-tests:
runs-on: ubuntu-latest
timeout-minutes: 10 # expected run time: <2 min
steps:
- uses: actions/checkout@v4
- name: check for changed frontend files
if: ${{ inputs.always_run != true }}
id: changed-files
uses: tj-actions/changed-files@v42
with:
files_yaml: |
frontend:
- 'invokeai/frontend/web/**'
- name: install dependencies
if: ${{ steps.changed-files.outputs.frontend_any_changed == 'true' || inputs.always_run == true }}
uses: ./.github/actions/install-frontend-deps
- name: vitest
if: ${{ steps.changed-files.outputs.frontend_any_changed == 'true' || inputs.always_run == true }}
run: 'pnpm test:no-watch'
shell: bash

View File

@ -1,6 +1,6 @@
name: "Pull Request Labeler"
name: 'label PRs'
on:
- pull_request_target
- pull_request_target
jobs:
labeler:
@ -9,8 +9,10 @@ jobs:
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Checkout
- name: checkout
uses: actions/checkout@v4
- uses: actions/labeler@v5
- name: label PRs
uses: actions/labeler@v5
with:
configuration-path: .github/pr_labels.yml
configuration-path: .github/pr_labels.yml

View File

@ -1,45 +0,0 @@
name: Lint frontend
on:
pull_request:
types:
- 'ready_for_review'
- 'opened'
- 'synchronize'
push:
branches:
- 'main'
merge_group:
workflow_dispatch:
defaults:
run:
working-directory: invokeai/frontend/web
jobs:
lint-frontend:
if: github.event.pull_request.draft == false
runs-on: ubuntu-22.04
steps:
- name: Setup Node 18
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Checkout
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: '8.12.1'
- name: Install dependencies
run: 'pnpm install --prefer-frozen-lockfile'
- name: Typescript
run: 'pnpm run lint:tsc'
- name: Madge
run: 'pnpm run lint:dpdm'
- name: ESLint
run: 'pnpm run lint:eslint'
- name: Prettier
run: 'pnpm run lint:prettier'
- name: Knip
run: 'pnpm run lint:knip'

View File

@ -1,51 +1,49 @@
name: mkdocs-material
# This is a mostly a copy-paste from https://github.com/squidfunk/mkdocs-material/blob/master/docs/publishing-your-site.md
name: mkdocs
on:
push:
branches:
- 'refs/heads/main'
- main
workflow_dispatch:
permissions:
contents: write
contents: write
jobs:
mkdocs-material:
deploy:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
env:
REPO_URL: '${{ github.server_url }}/${{ github.repository }}'
REPO_NAME: '${{ github.repository }}'
SITE_URL: 'https://${{ github.repository_owner }}.github.io/InvokeAI'
steps:
- name: checkout sources
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: checkout
uses: actions/checkout@v4
- name: setup python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.10'
cache: pip
cache-dependency-path: pyproject.toml
- name: install requirements
env:
PIP_USE_PEP517: 1
run: |
python -m \
pip install ".[docs]"
- name: set cache id
run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
- name: confirm buildability
run: |
python -m \
mkdocs build \
--clean \
--verbose
- name: use cache
uses: actions/cache@v4
with:
key: mkdocs-material-${{ env.cache_id }}
path: .cache
restore-keys: |
mkdocs-material-
- name: deploy to gh-pages
if: ${{ github.ref == 'refs/heads/main' }}
run: |
python -m \
mkdocs gh-deploy \
--clean \
--force
- name: install dependencies
run: python -m pip install ".[docs]"
- name: build & deploy
run: mkdocs gh-deploy --force

View File

@ -1,67 +0,0 @@
name: PyPI Release
on:
workflow_dispatch:
inputs:
publish_package:
description: 'Publish build on PyPi? [true/false]'
required: true
default: 'false'
jobs:
build-and-release:
if: github.repository == 'invoke-ai/InvokeAI'
runs-on: ubuntu-22.04
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
TWINE_NON_INTERACTIVE: 1
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node 18
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: '8.12.1'
- name: Install frontend dependencies
run: pnpm install --prefer-frozen-lockfile
working-directory: invokeai/frontend/web
- name: Build frontend
run: pnpm run build
working-directory: invokeai/frontend/web
- name: Install python dependencies
run: pip install --upgrade build twine
- name: Build python package
run: python3 -m build
- name: Upload build as workflow artifact
uses: actions/upload-artifact@v4
with:
name: dist
path: dist
- name: Check distribution
run: twine check dist/*
- name: Check PyPI versions
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')
run: |
pip install --upgrade requests
python -c "\
import scripts.pypi_helper; \
EXISTS=scripts.pypi_helper.local_on_pypi(); \
print(f'PACKAGE_EXISTS={EXISTS}')" >> $GITHUB_ENV
- name: Publish build on PyPi
if: env.PACKAGE_EXISTS == 'False' && env.TWINE_PASSWORD != '' && github.event.inputs.publish_package == 'true'
run: twine upload dist/*

76
.github/workflows/python-checks.yml vendored Normal file
View File

@ -0,0 +1,76 @@
# Runs python code quality checks.
#
# Checks for changes to python files before running the checks.
# If always_run is true, always runs the checks.
#
# TODO: Add mypy or pyright to the checks.
name: 'python checks'
on:
push:
branches:
- 'main'
pull_request:
types:
- 'ready_for_review'
- 'opened'
- 'synchronize'
merge_group:
workflow_dispatch:
inputs:
always_run:
description: 'Always run the checks'
required: true
type: boolean
default: true
workflow_call:
inputs:
always_run:
description: 'Always run the checks'
required: true
type: boolean
default: true
jobs:
python-checks:
runs-on: ubuntu-latest
timeout-minutes: 5 # expected run time: <1 min
steps:
- name: checkout
uses: actions/checkout@v4
- name: check for changed python files
if: ${{ inputs.always_run != true }}
id: changed-files
uses: tj-actions/changed-files@v42
with:
files_yaml: |
python:
- 'pyproject.toml'
- 'invokeai/**'
- '!invokeai/frontend/web/**'
- 'tests/**'
- name: setup python
if: ${{ steps.changed-files.outputs.python_any_changed == 'true' || inputs.always_run == true }}
uses: actions/setup-python@v5
with:
python-version: '3.10'
cache: pip
cache-dependency-path: pyproject.toml
- name: install ruff
if: ${{ steps.changed-files.outputs.python_any_changed == 'true' || inputs.always_run == true }}
run: pip install ruff==0.6.0
shell: bash
- name: ruff check
if: ${{ steps.changed-files.outputs.python_any_changed == 'true' || inputs.always_run == true }}
run: ruff check --output-format=github .
shell: bash
- name: ruff format
if: ${{ steps.changed-files.outputs.python_any_changed == 'true' || inputs.always_run == true }}
run: ruff format --check .
shell: bash

106
.github/workflows/python-tests.yml vendored Normal file
View File

@ -0,0 +1,106 @@
# Runs python tests on a matrix of python versions and platforms.
#
# Checks for changes to python files before running the tests.
# If always_run is true, always runs the tests.
name: 'python tests'
on:
push:
branches:
- 'main'
pull_request:
types:
- 'ready_for_review'
- 'opened'
- 'synchronize'
merge_group:
workflow_dispatch:
inputs:
always_run:
description: 'Always run the tests'
required: true
type: boolean
default: true
workflow_call:
inputs:
always_run:
description: 'Always run the tests'
required: true
type: boolean
default: true
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
matrix:
strategy:
matrix:
python-version:
- '3.10'
- '3.11'
platform:
- linux-cuda-11_7
- linux-rocm-5_2
- linux-cpu
- macos-default
- windows-cpu
include:
- platform: linux-cuda-11_7
os: ubuntu-22.04
github-env: $GITHUB_ENV
- platform: linux-rocm-5_2
os: ubuntu-22.04
extra-index-url: 'https://download.pytorch.org/whl/rocm5.2'
github-env: $GITHUB_ENV
- platform: linux-cpu
os: ubuntu-22.04
extra-index-url: 'https://download.pytorch.org/whl/cpu'
github-env: $GITHUB_ENV
- platform: macos-default
os: macOS-14
github-env: $GITHUB_ENV
- platform: windows-cpu
os: windows-2022
github-env: $env:GITHUB_ENV
name: 'py${{ matrix.python-version }}: ${{ matrix.platform }}'
runs-on: ${{ matrix.os }}
timeout-minutes: 15 # expected run time: 2-6 min, depending on platform
env:
PIP_USE_PEP517: '1'
steps:
- name: checkout
uses: actions/checkout@v4
- name: check for changed python files
if: ${{ inputs.always_run != true }}
id: changed-files
uses: tj-actions/changed-files@v42
with:
files_yaml: |
python:
- 'pyproject.toml'
- 'invokeai/**'
- '!invokeai/frontend/web/**'
- 'tests/**'
- name: setup python
if: ${{ steps.changed-files.outputs.python_any_changed == 'true' || inputs.always_run == true }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: pip
cache-dependency-path: pyproject.toml
- name: install dependencies
if: ${{ steps.changed-files.outputs.python_any_changed == 'true' || inputs.always_run == true }}
env:
PIP_EXTRA_INDEX_URL: ${{ matrix.extra-index-url }}
run: >
pip3 install --editable=".[test]"
- name: run pytest
if: ${{ steps.changed-files.outputs.python_any_changed == 'true' || inputs.always_run == true }}
run: pytest

108
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,108 @@
# Main release workflow. Triggered on tag push or manual trigger.
#
# - Runs all code checks and tests
# - Verifies the app version matches the tag version.
# - Builds the installer and build, uploading them as artifacts.
# - Publishes to TestPyPI and PyPI. Both are conditional on the previous steps passing and require a manual approval.
#
# See docs/RELEASE.md for more information on the release process.
name: release
on:
push:
tags:
- 'v*'
workflow_dispatch:
jobs:
check-version:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v4
- name: check python version
uses: samuelcolvin/check-python-version@v4
id: check-python-version
with:
version_file_path: invokeai/version/invokeai_version.py
frontend-checks:
uses: ./.github/workflows/frontend-checks.yml
with:
always_run: true
frontend-tests:
uses: ./.github/workflows/frontend-tests.yml
with:
always_run: true
python-checks:
uses: ./.github/workflows/python-checks.yml
with:
always_run: true
python-tests:
uses: ./.github/workflows/python-tests.yml
with:
always_run: true
build:
uses: ./.github/workflows/build-installer.yml
publish-testpypi:
runs-on: ubuntu-latest
timeout-minutes: 5 # expected run time: <1 min
needs:
[
check-version,
frontend-checks,
frontend-tests,
python-checks,
python-tests,
build,
]
environment:
name: testpypi
url: https://test.pypi.org/p/invokeai
permissions:
id-token: write
steps:
- name: download distribution from build job
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: publish distribution to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
publish-pypi:
runs-on: ubuntu-latest
timeout-minutes: 5 # expected run time: <1 min
needs:
[
check-version,
frontend-checks,
frontend-tests,
python-checks,
python-tests,
build,
]
environment:
name: pypi
url: https://pypi.org/p/invokeai
permissions:
id-token: write
steps:
- name: download distribution from build job
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: publish distribution to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

View File

@ -1,24 +0,0 @@
name: style checks
on:
pull_request:
push:
branches: main
jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies with pip
run: |
pip install ruff
- run: ruff check --output-format=github .
- run: ruff format --check .

View File

@ -1,129 +0,0 @@
name: Test invoke.py pip
on:
push:
branches:
- 'main'
pull_request:
types:
- 'ready_for_review'
- 'opened'
- 'synchronize'
merge_group:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
matrix:
if: github.event.pull_request.draft == false
strategy:
matrix:
python-version:
# - '3.9'
- '3.10'
pytorch:
- linux-cuda-11_7
- linux-rocm-5_2
- linux-cpu
- macos-default
- windows-cpu
include:
- pytorch: linux-cuda-11_7
os: ubuntu-22.04
github-env: $GITHUB_ENV
- pytorch: linux-rocm-5_2
os: ubuntu-22.04
extra-index-url: 'https://download.pytorch.org/whl/rocm5.2'
github-env: $GITHUB_ENV
- pytorch: linux-cpu
os: ubuntu-22.04
extra-index-url: 'https://download.pytorch.org/whl/cpu'
github-env: $GITHUB_ENV
- pytorch: macos-default
os: macOS-12
github-env: $GITHUB_ENV
- pytorch: windows-cpu
os: windows-2022
github-env: $env:GITHUB_ENV
name: ${{ matrix.pytorch }} on ${{ matrix.python-version }}
runs-on: ${{ matrix.os }}
env:
PIP_USE_PEP517: '1'
steps:
- name: Checkout sources
id: checkout-sources
uses: actions/checkout@v3
- name: Check for changed python files
id: changed-files
uses: tj-actions/changed-files@v41
with:
files_yaml: |
python:
- 'pyproject.toml'
- 'invokeai/**'
- '!invokeai/frontend/web/**'
- 'tests/**'
- name: set test prompt to main branch validation
if: steps.changed-files.outputs.python_any_changed == 'true'
run: echo "TEST_PROMPTS=tests/validate_pr_prompt.txt" >> ${{ matrix.github-env }}
- name: setup python
if: steps.changed-files.outputs.python_any_changed == 'true'
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
cache: pip
cache-dependency-path: pyproject.toml
- name: install invokeai
if: steps.changed-files.outputs.python_any_changed == 'true'
env:
PIP_EXTRA_INDEX_URL: ${{ matrix.extra-index-url }}
run: >
pip3 install
--editable=".[test]"
- name: run pytest
if: steps.changed-files.outputs.python_any_changed == 'true'
id: run-pytest
run: pytest
# - name: run invokeai-configure
# env:
# HUGGING_FACE_HUB_TOKEN: ${{ secrets.HUGGINGFACE_TOKEN }}
# run: >
# invokeai-configure
# --yes
# --default_only
# --full-precision
# # can't use fp16 weights without a GPU
# - name: run invokeai
# id: run-invokeai
# env:
# # Set offline mode to make sure configure preloaded successfully.
# HF_HUB_OFFLINE: 1
# HF_DATASETS_OFFLINE: 1
# TRANSFORMERS_OFFLINE: 1
# INVOKEAI_OUTDIR: ${{ github.workspace }}/results
# run: >
# invokeai
# --no-patchmatch
# --no-nsfw_checker
# --precision=float32
# --always_use_cpu
# --use_memory_db
# --outdir ${{ env.INVOKEAI_OUTDIR }}/${{ matrix.python-version }}/${{ matrix.pytorch }}
# --from_file ${{ env.TEST_PROMPTS }}
# - name: Archive results
# env:
# INVOKEAI_OUTDIR: ${{ github.workspace }}/results
# uses: actions/upload-artifact@v3
# with:
# name: results
# path: ${{ env.INVOKEAI_OUTDIR }}

View File

@ -7,7 +7,7 @@ embeddedLanguageFormatting: auto
overrides:
- files: '*.md'
options:
proseWrap: always
proseWrap: preserve
printWidth: 80
parser: markdown
cursorOffset: -1

View File

@ -6,16 +6,19 @@ default: help
help:
@echo Developer commands:
@echo
@echo "ruff Run ruff, fixing any safely-fixable errors and formatting"
@echo "ruff-unsafe Run ruff, fixing all fixable errors and formatting"
@echo "mypy Run mypy using the config in pyproject.toml to identify type mismatches and other coding errors"
@echo "mypy-all Run mypy ignoring the config in pyproject.tom but still ignoring missing imports"
@echo "test" Run the unit tests.
@echo "frontend-install" Install the pnpm modules needed for the front end
@echo "frontend-build Build the frontend in order to run on localhost:9090"
@echo "frontend-dev Run the frontend in developer mode on localhost:5173"
@echo "installer-zip Build the installer .zip file for the current version"
@echo "tag-release Tag the GitHub repository with the current version (use at release time only!)"
@echo "ruff Run ruff, fixing any safely-fixable errors and formatting"
@echo "ruff-unsafe Run ruff, fixing all fixable errors and formatting"
@echo "mypy Run mypy using the config in pyproject.toml to identify type mismatches and other coding errors"
@echo "mypy-all Run mypy ignoring the config in pyproject.tom but still ignoring missing imports"
@echo "test Run the unit tests."
@echo "update-config-docstring Update the app's config docstring so mkdocs can autogenerate it correctly."
@echo "frontend-install Install the pnpm modules needed for the front end"
@echo "frontend-build Build the frontend in order to run on localhost:9090"
@echo "frontend-dev Run the frontend in developer mode on localhost:5173"
@echo "frontend-typegen Generate types for the frontend from the OpenAPI schema"
@echo "installer-zip Build the installer .zip file for the current version"
@echo "tag-release Tag the GitHub repository with the current version (use at release time only!)"
@echo "openapi Generate the OpenAPI schema for the app, outputting to stdout"
# Runs ruff, fixing any safely-fixable errors and formatting
ruff:
@ -40,6 +43,10 @@ mypy-all:
test:
pytest ./tests
# Update config docstring
update-config-docstring:
python scripts/update_config_docstring.py
# Install the pnpm modules needed for the front end
frontend-install:
rm -rf invokeai/frontend/web/node_modules
@ -53,6 +60,9 @@ frontend-build:
frontend-dev:
cd invokeai/frontend/web && pnpm dev
frontend-typegen:
cd invokeai/frontend/web && python ../../../scripts/generate_openapi_schema.py | pnpm typegen
# Installer zip file
installer-zip:
cd installer && ./create_installer.sh
@ -61,3 +71,6 @@ installer-zip:
tag-release:
cd installer && ./tag_release.sh
# Generate the OpenAPI Schema for the app
openapi:
python scripts/generate_openapi_schema.py

536
README.md
View File

@ -2,21 +2,141 @@
![project hero](https://github.com/invoke-ai/InvokeAI/assets/31807370/6e3728c7-e90e-4711-905c-3b55844ff5be)
# Invoke - Professional Creative AI Tools for Visual Media
## To learn more about Invoke, or implement our Business solutions, visit [invoke.com](https://www.invoke.com/about)
# Invoke - Professional Creative AI Tools for Visual Media
#### To learn more about Invoke, or implement our Business solutions, visit [invoke.com]
[![discord badge]][discord link] [![latest release badge]][latest release link] [![github stars badge]][github stars link] [![github forks badge]][github forks link] [![CI checks on main badge]][CI checks on main link] [![latest commit to main badge]][latest commit to main link] [![github open issues badge]][github open issues link] [![github open prs badge]][github open prs link] [![translation status badge]][translation status link]
</div>
Invoke is a leading creative engine built to empower professionals and enthusiasts alike. Generate and create stunning visual media using the latest AI-driven technologies. Invoke offers an industry leading web-based UI, and serves as the foundation for multiple commercial products.
Invoke is available in two editions:
| **Community Edition** | **Professional Edition** |
|----------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------|
| **For users looking for a locally installed, self-hosted and self-managed service** | **For users or teams looking for a cloud-hosted, fully managed service** |
| - Free to use under a commercially-friendly license | - Monthly subscription fee with three different plan levels |
| - Download and install on compatible hardware | - Offers additional benefits, including multi-user support, improved model training, and more |
| - Includes all core studio features: generate, refine, iterate on images, and build workflows | - Hosted in the cloud for easy, secure model access and scalability |
| Quick Start -> [Installation and Updates][installation docs] | More Information -> [www.invoke.com/pricing](https://www.invoke.com/pricing) |
[![discord badge]][discord link]
![Highlighted Features - Canvas and Workflows](https://github.com/invoke-ai/InvokeAI/assets/31807370/708f7a82-084f-4860-bfbe-e2588c53548d)
[![latest release badge]][latest release link] [![github stars badge]][github stars link] [![github forks badge]][github forks link]
# Documentation
| **Quick Links** |
|----------------------------------------------------------------------------------------------------------------------------|
| [Installation and Updates][installation docs] - [Documentation and Tutorials][docs home] - [Bug Reports][github issues] - [Contributing][contributing docs] |
[![CI checks on main badge]][CI checks on main link] [![latest commit to main badge]][latest commit to main link]
</div>
[![github open issues badge]][github open issues link] [![github open prs badge]][github open prs link] [![translation status badge]][translation status link]
## Quick Start
1. Download and unzip the installer from the bottom of the [latest release][latest release link].
2. Run the installer script.
- **Windows**: Double-click on the `install.bat` script.
- **macOS**: Open a Terminal window, drag the file `install.sh` from Finder into the Terminal, and press enter.
- **Linux**: Run `install.sh`.
3. When prompted, enter a location for the install and select your GPU type.
4. Once the install finishes, find the directory you selected during install. The default location is `C:\Users\Username\invokeai` for Windows or `~/invokeai` for Linux/macOS.
5. Run the launcher script (`invoke.bat` for Windows, `invoke.sh` for macOS and Linux) the same way you ran the installer script in step 2.
6. Select option 1 to start the application. Once it starts up, open your browser and go to <http://localhost:9090>.
7. Open the model manager tab to install a starter model and then you'll be ready to generate.
More detail, including hardware requirements and manual install instructions, are available in the [installation documentation][installation docs].
## Docker Container
We publish official container images in Github Container Registry: https://github.com/invoke-ai/InvokeAI/pkgs/container/invokeai. Both CUDA and ROCm images are available. Check the above link for relevant tags.
> [!IMPORTANT]
> Ensure that Docker is set up to use the GPU. Refer to [NVIDIA][nvidia docker docs] or [AMD][amd docker docs] documentation.
### Generate!
Run the container, modifying the command as necessary:
```bash
docker run --runtime=nvidia --gpus=all --publish 9090:9090 ghcr.io/invoke-ai/invokeai
```
Then open `http://localhost:9090` and install some models using the Model Manager tab to begin generating.
For ROCm, add `--device /dev/kfd --device /dev/dri` to the `docker run` command.
### Persist your data
You will likely want to persist your workspace outside of the container. Use the `--volume /home/myuser/invokeai:/invokeai` flag to mount some local directory (using its **absolute** path) to the `/invokeai` path inside the container. Your generated images and models will reside there. You can use this directory with other InvokeAI installations, or switch between runtime directories as needed.
### DIY
Build your own image and customize the environment to match your needs using our `docker-compose` stack. See [README.md](./docker/README.md) in the [docker](./docker) directory.
## Troubleshooting, FAQ and Support
Please review our [FAQ][faq] for solutions to common installation problems and other issues.
For more help, please join our [Discord][discord link].
## Features
Full details on features can be found in [our documentation][features docs].
### Web Server & UI
Invoke runs a locally hosted web server & React UI with an industry-leading user experience.
### Unified Canvas
The Unified Canvas is a fully integrated canvas implementation with support for all core generation capabilities, in/out-painting, brush tools, and more. This creative tool unlocks the capability for artists to create with AI as a creative collaborator, and can be used to augment AI-generated imagery, sketches, photography, renders, and more.
### Workflows & Nodes
Invoke offers a fully featured workflow management solution, enabling users to combine the power of node-based workflows with the easy of a UI. This allows for customizable generation pipelines to be developed and shared by users looking to create specific workflows to support their production use-cases.
### Board & Gallery Management
Invoke features an organized gallery system for easily storing, accessing, and remixing your content in the Invoke workspace. Images can be dragged/dropped onto any Image-base UI element in the application, and rich metadata within the Image allows for easy recall of key prompts or settings used in your workflow.
### Other features
- Support for both ckpt and diffusers models
- SD1.5, SD2.0, and SDXL support
- Upscaling Tools
- Embedding Manager & Support
- Model Manager & Support
- Workflow creation & management
- Node-Based Architecture
## Contributing
Anyone who wishes to contribute to this project - whether documentation, features, bug fixes, code cleanup, testing, or code reviews - is very much encouraged to do so.
Get started with contributing by reading our [contribution documentation][contributing docs], joining the [#dev-chat] or the GitHub discussion board.
We hope you enjoy using Invoke as much as we enjoy creating it, and we hope you will elect to become part of our community.
## Thanks
Invoke is a combined effort of [passionate and talented people from across the world][contributors]. We thank them for their time, hard work and effort.
Original portions of the software are Copyright © 2024 by respective contributors.
[features docs]: https://invoke-ai.github.io/InvokeAI/features/
[faq]: https://invoke-ai.github.io/InvokeAI/help/FAQ/
[contributors]: https://invoke-ai.github.io/InvokeAI/other/CONTRIBUTORS/
[invoke.com]: https://www.invoke.com/about
[github issues]: https://github.com/invoke-ai/InvokeAI/issues
[docs home]: https://invoke-ai.github.io/InvokeAI
[installation docs]: https://invoke-ai.github.io/InvokeAI/installation/INSTALLATION/
[#dev-chat]: https://discord.com/channels/1020123559063990373/1049495067846524939
[contributing docs]: https://invoke-ai.github.io/InvokeAI/contributing/CONTRIBUTING/
[CI checks on main badge]: https://flat.badgen.net/github/checks/invoke-ai/InvokeAI/main?label=CI%20status%20on%20main&cache=900&icon=github
[CI checks on main link]:https://github.com/invoke-ai/InvokeAI/actions?query=branch%3Amain
[CI checks on main link]: https://github.com/invoke-ai/InvokeAI/actions?query=branch%3Amain
[discord badge]: https://flat.badgen.net/discord/members/ZmtBAhwWhy?icon=discord
[discord link]: https://discord.gg/ZmtBAhwWhy
[github forks badge]: https://flat.badgen.net/github/forks/invoke-ai/InvokeAI?icon=github
@ -30,402 +150,8 @@
[latest commit to main badge]: https://flat.badgen.net/github/last-commit/invoke-ai/InvokeAI/main?icon=github&color=yellow&label=last%20dev%20commit&cache=900
[latest commit to main link]: https://github.com/invoke-ai/InvokeAI/commits/main
[latest release badge]: https://flat.badgen.net/github/release/invoke-ai/InvokeAI/development?icon=github
[latest release link]: https://github.com/invoke-ai/InvokeAI/releases
[latest release link]: https://github.com/invoke-ai/InvokeAI/releases/latest
[translation status badge]: https://hosted.weblate.org/widgets/invokeai/-/svg-badge.svg
[translation status link]: https://hosted.weblate.org/engage/invokeai/
</div>
InvokeAI is a leading creative engine built to empower professionals
and enthusiasts alike. Generate and create stunning visual media using
the latest AI-driven technologies. InvokeAI offers an industry leading
Web Interface, interactive Command Line Interface, and also serves as
the foundation for multiple commercial products.
**Quick links**: [[How to
Install](https://invoke-ai.github.io/InvokeAI/installation/INSTALLATION/)] [<a
href="https://discord.gg/ZmtBAhwWhy">Discord Server</a>] [<a
href="https://invoke-ai.github.io/InvokeAI/">Documentation and
Tutorials</a>]
[<a href="https://github.com/invoke-ai/InvokeAI/issues">Bug Reports</a>]
[<a
href="https://github.com/invoke-ai/InvokeAI/discussions">Discussion,
Ideas & Q&A</a>]
[<a
href="https://invoke-ai.github.io/InvokeAI/contributing/CONTRIBUTING/">Contributing</a>]
<div align="center">
![Highlighted Features - Canvas and Workflows](https://github.com/invoke-ai/InvokeAI/assets/31807370/708f7a82-084f-4860-bfbe-e2588c53548d)
</div>
## Table of Contents
Table of Contents 📝
**Getting Started**
1. 🏁 [Quick Start](#quick-start)
3. 🖥️ [Hardware Requirements](#hardware-requirements)
**More About Invoke**
1. 🌟 [Features](#features)
2. 📣 [Latest Changes](#latest-changes)
3. 🛠️ [Troubleshooting](#troubleshooting)
**Supporting the Project**
1. 🤝 [Contributing](#contributing)
2. 👥 [Contributors](#contributors)
3. 💕 [Support](#support)
## Quick Start
For full installation and upgrade instructions, please see:
[InvokeAI Installation Overview](https://invoke-ai.github.io/InvokeAI/installation/INSTALLATION/)
If upgrading from version 2.3, please read [Migrating a 2.3 root
directory to 3.0](#migrating-to-3) first.
### Automatic Installer (suggested for 1st time users)
1. Go to the bottom of the [Latest Release Page](https://github.com/invoke-ai/InvokeAI/releases/latest)
2. Download the .zip file for your OS (Windows/macOS/Linux).
3. Unzip the file.
4. **Windows:** double-click on the `install.bat` script. **macOS:** Open a Terminal window, drag the file `install.sh` from Finder
into the Terminal, and press return. **Linux:** run `install.sh`.
5. You'll be asked to confirm the location of the folder in which
to install InvokeAI and its image generation model files. Pick a
location with at least 15 GB of free memory. More if you plan on
installing lots of models.
6. Wait while the installer does its thing. After installing the software,
the installer will launch a script that lets you configure InvokeAI and
select a set of starting image generation models.
7. Find the folder that InvokeAI was installed into (it is not the
same as the unpacked zip file directory!) The default location of this
folder (if you didn't change it in step 5) is `~/invokeai` on
Linux/Mac systems, and `C:\Users\YourName\invokeai` on Windows. This directory will contain launcher scripts named `invoke.sh` and `invoke.bat`.
8. On Windows systems, double-click on the `invoke.bat` file. On
macOS, open a Terminal window, drag `invoke.sh` from the folder into
the Terminal, and press return. On Linux, run `invoke.sh`
9. Press 2 to open the "browser-based UI", press enter/return, wait a
minute or two for Stable Diffusion to start up, then open your browser
and go to http://localhost:9090.
10. Type `banana sushi` in the box on the top left and click `Invoke`
### Command-Line Installation (for developers and users familiar with Terminals)
You must have Python 3.10 through 3.11 installed on your machine. Earlier or
later versions are not supported.
Node.js also needs to be installed along with `pnpm` (can be installed with
the command `npm install -g pnpm` if needed)
1. Open a command-line window on your machine. The PowerShell is recommended for Windows.
2. Create a directory to install InvokeAI into. You'll need at least 15 GB of free space:
```terminal
mkdir invokeai
````
3. Create a virtual environment named `.venv` inside this directory and activate it:
```terminal
cd invokeai
python -m venv .venv --prompt InvokeAI
```
4. Activate the virtual environment (do it every time you run InvokeAI)
_For Linux/Mac users:_
```sh
source .venv/bin/activate
```
_For Windows users:_
```ps
.venv\Scripts\activate
```
5. Install the InvokeAI module and its dependencies. Choose the command suited for your platform & GPU.
_For Windows/Linux with an NVIDIA GPU:_
```terminal
pip install "InvokeAI[xformers]" --use-pep517 --extra-index-url https://download.pytorch.org/whl/cu121
```
_For Linux with an AMD GPU:_
```sh
pip install InvokeAI --use-pep517 --extra-index-url https://download.pytorch.org/whl/rocm5.6
```
_For non-GPU systems:_
```terminal
pip install InvokeAI --use-pep517 --extra-index-url https://download.pytorch.org/whl/cpu
```
_For Macintoshes, either Intel or M1/M2/M3:_
```sh
pip install InvokeAI --use-pep517
```
6. Configure InvokeAI and install a starting set of image generation models (you only need to do this once):
```terminal
invokeai-configure --root .
```
Don't miss the dot at the end!
7. Launch the web server (do it every time you run InvokeAI):
```terminal
invokeai-web
```
8. Point your browser to http://localhost:9090 to bring up the web interface.
9. Type `banana sushi` in the box on the top left and click `Invoke`.
Be sure to activate the virtual environment each time before re-launching InvokeAI,
using `source .venv/bin/activate` or `.venv\Scripts\activate`.
## Detailed Installation Instructions
This fork is supported across Linux, Windows and Macintosh. Linux
users can use either an Nvidia-based card (with CUDA support) or an
AMD card (using the ROCm driver). For full installation and upgrade
instructions, please see:
[InvokeAI Installation Overview](https://invoke-ai.github.io/InvokeAI/installation/INSTALL_SOURCE/)
<a name="migrating-to-3"></a>
### Migrating a v2.3 InvokeAI root directory
The InvokeAI root directory is where the InvokeAI startup file,
installed models, and generated images are stored. It is ordinarily
named `invokeai` and located in your home directory. The contents and
layout of this directory has changed between versions 2.3 and 3.0 and
cannot be used directly.
We currently recommend that you use the installer to create a new root
directory named differently from the 2.3 one, e.g. `invokeai-3` and
then use a migration script to copy your 2.3 models into the new
location. However, if you choose, you can upgrade this directory in
place. This section gives both recipes.
#### Creating a new root directory and migrating old models
This is the safer recipe because it leaves your old root directory in
place to fall back on.
1. Follow the instructions above to create and install InvokeAI in a
directory that has a different name from the 2.3 invokeai directory.
In this example, we will use "invokeai-3"
2. When you are prompted to select models to install, select a minimal
set of models, such as stable-diffusion-v1.5 only.
3. After installation is complete launch `invokeai.sh` (Linux/Mac) or
`invokeai.bat` and select option 8 "Open the developers console". This
will take you to the command line.
4. Issue the command `invokeai-migrate3 --from /path/to/v2.3-root --to
/path/to/invokeai-3-root`. Provide the correct `--from` and `--to`
paths for your v2.3 and v3.0 root directories respectively.
This will copy and convert your old models from 2.3 format to 3.0
format and create a new `models` directory in the 3.0 directory. The
old models directory (which contains the models selected at install
time) will be renamed `models.orig` and can be deleted once you have
confirmed that the migration was successful.
If you wish, you can pass the 2.3 root directory to both `--from` and
`--to` in order to update in place. Warning: this directory will no
longer be usable with InvokeAI 2.3.
#### Migrating in place
For the adventurous, you may do an in-place upgrade from 2.3 to 3.0
without touching the command line. ***This recipe does not work on
Windows platforms due to a bug in the Windows version of the 2.3
upgrade script.** See the next section for a Windows recipe.
##### For Mac and Linux Users:
1. Launch the InvokeAI launcher script in your current v2.3 root directory.
2. Select option [9] "Update InvokeAI" to bring up the updater dialog.
3. Select option [1] to upgrade to the latest release.
4. Once the upgrade is finished you will be returned to the launcher
menu. Select option [6] "Re-run the configure script to fix a broken
install or to complete a major upgrade".
This will run the configure script against the v2.3 directory and
update it to the 3.0 format. The following files will be replaced:
- The invokeai.init file, replaced by invokeai.yaml
- The models directory
- The configs/models.yaml model index
The original versions of these files will be saved with the suffix
".orig" appended to the end. Once you have confirmed that the upgrade
worked, you can safely remove these files. Alternatively you can
restore a working v2.3 directory by removing the new files and
restoring the ".orig" files' original names.
##### For Windows Users:
Windows Users can upgrade with the
1. Enter the 2.3 root directory you wish to upgrade
2. Launch `invoke.sh` or `invoke.bat`
3. Select the "Developer's console" option [8]
4. Type the following commands
```
pip install "invokeai @ https://github.com/invoke-ai/InvokeAI/archive/refs/tags/v3.0.0" --use-pep517 --upgrade
invokeai-configure --root .
```
(Replace `v3.0.0` with the current release number if this document is out of date).
The first command will install and upgrade new software to run
InvokeAI. The second will prepare the 2.3 directory for use with 3.0.
You may now launch the WebUI in the usual way, by selecting option [1]
from the launcher script
#### Migrating Images
The migration script will migrate your invokeai settings and models,
including textual inversion models, LoRAs and merges that you may have
installed previously. However it does **not** migrate the generated
images stored in your 2.3-format outputs directory. To do this, you
need to run an additional step:
1. From a working InvokeAI 3.0 root directory, start the launcher and
enter menu option [8] to open the "developer's console".
2. At the developer's console command line, type the command:
```bash
invokeai-import-images
```
3. This will lead you through the process of confirming the desired
source and destination for the imported images. The images will
appear in the gallery board of your choice, and contain the
original prompt, model name, and other parameters used to generate
the image.
(Many kudos to **techjedi** for contributing this script.)
## Hardware Requirements
InvokeAI is supported across Linux, Windows and macOS. Linux
users can use either an Nvidia-based card (with CUDA support) or an
AMD card (using the ROCm driver).
### System
You will need one of the following:
- An NVIDIA-based graphics card with 4 GB or more VRAM memory. 6-8 GB
of VRAM is highly recommended for rendering using the Stable
Diffusion XL models
- An Apple computer with an M1 chip.
- An AMD-based graphics card with 4GB or more VRAM memory (Linux
only), 6-8 GB for XL rendering.
We do not recommend the GTX 1650 or 1660 series video cards. They are
unable to run in half-precision mode and do not have sufficient VRAM
to render 512x512 images.
**Memory** - At least 12 GB Main Memory RAM.
**Disk** - At least 12 GB of free disk space for the machine learning model, Python, and all its dependencies.
## Features
Feature documentation can be reviewed by navigating to [the InvokeAI Documentation page](https://invoke-ai.github.io/InvokeAI/features/)
### *Web Server & UI*
InvokeAI offers a locally hosted Web Server & React Frontend, with an industry leading user experience. The Web-based UI allows for simple and intuitive workflows, and is responsive for use on mobile devices and tablets accessing the web server.
### *Unified Canvas*
The Unified Canvas is a fully integrated canvas implementation with support for all core generation capabilities, in/outpainting, brush tools, and more. This creative tool unlocks the capability for artists to create with AI as a creative collaborator, and can be used to augment AI-generated imagery, sketches, photography, renders, and more.
### *Workflows & Nodes*
InvokeAI offers a fully featured workflow management solution, enabling users to combine the power of nodes based workflows with the easy of a UI. This allows for customizable generation pipelines to be developed and shared by users looking to create specific workflows to support their production use-cases.
### *Board & Gallery Management*
Invoke AI provides an organized gallery system for easily storing, accessing, and remixing your content in the Invoke workspace. Images can be dragged/dropped onto any Image-base UI element in the application, and rich metadata within the Image allows for easy recall of key prompts or settings used in your workflow.
### Other features
- *Support for both ckpt and diffusers models*
- *SD 2.0, 2.1, XL support*
- *Upscaling Tools*
- *Embedding Manager & Support*
- *Model Manager & Support*
- *Workflow creation & management*
- *Node-Based Architecture*
### Latest Changes
For our latest changes, view our [Release
Notes](https://github.com/invoke-ai/InvokeAI/releases) and the
[CHANGELOG](docs/CHANGELOG.md).
### Troubleshooting
Please check out our **[Troubleshooting Guide](https://invoke-ai.github.io/InvokeAI/installation/010_INSTALL_AUTOMATED/#troubleshooting)** to get solutions for common installation
problems and other issues. For more help, please join our [Discord][discord link]
## Contributing
Anyone who wishes to contribute to this project, whether documentation, features, bug fixes, code
cleanup, testing, or code reviews, is very much encouraged to do so.
Get started with contributing by reading our [Contribution documentation](https://invoke-ai.github.io/InvokeAI/contributing/CONTRIBUTING/), joining the [#dev-chat](https://discord.com/channels/1020123559063990373/1049495067846524939) or the GitHub discussion board.
If you are unfamiliar with how
to contribute to GitHub projects, we have a new contributor checklist you can follow to get started contributing:
[New Contributor Checklist](https://invoke-ai.github.io/InvokeAI/contributing/contribution_guides/newContributorChecklist/).
We hope you enjoy using our software as much as we enjoy creating it,
and we hope that some of those of you who are reading this will elect
to become part of our community.
Welcome to InvokeAI!
### Contributors
This fork is a combined effort of various people from across the world.
[Check out the list of all these amazing people](https://invoke-ai.github.io/InvokeAI/other/CONTRIBUTORS/). We thank them for
their time, hard work and effort.
### Support
For support, please use this repository's GitHub Issues tracking service, or join the [Discord][discord link].
Original portions of the software are Copyright (c) 2023 by respective contributors.
[nvidia docker docs]: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
[amd docker docs]: https://rocm.docs.amd.com/projects/install-on-linux/en/latest/how-to/docker.html

View File

@ -2,17 +2,26 @@
## Any environment variables supported by InvokeAI can be specified here,
## in addition to the examples below.
# HOST_INVOKEAI_ROOT is the path on the docker host's filesystem where InvokeAI will store data.
# Outputs will also be stored here by default.
# If relative, it will be relative to the docker directory in which the docker-compose.yml file is located
#HOST_INVOKEAI_ROOT=../../invokeai-data
# INVOKEAI_ROOT is the path to the root of the InvokeAI repository within the container.
## INVOKEAI_ROOT is the path *on the host system* where Invoke will store its data.
## It is mounted into the container and allows both containerized and non-containerized usage of Invoke.
# Usually this is the only variable you need to set. It can be relative or absolute.
# INVOKEAI_ROOT=~/invokeai
# Get this value from your HuggingFace account settings page.
# HUGGING_FACE_HUB_TOKEN=
## HOST_INVOKEAI_ROOT and CONTAINER_INVOKEAI_ROOT can be used to control the on-host
## and in-container paths separately, if needed.
## HOST_INVOKEAI_ROOT is the path on the docker host's filesystem where Invoke will store data.
## If relative, it will be relative to the docker directory in which the docker-compose.yml file is located
## CONTAINER_INVOKEAI_ROOT is the path within the container where Invoke will expect to find the runtime directory.
## It MUST be absolute. There is usually no need to change this.
# HOST_INVOKEAI_ROOT=../../invokeai-data
# CONTAINER_INVOKEAI_ROOT=/invokeai
## optional variables specific to the docker setup.
# GPU_DRIVER=nvidia #| rocm
## INVOKEAI_PORT is the port on which the InvokeAI web interface will be available
# INVOKEAI_PORT=9090
## GPU_DRIVER can be set to either `cuda` or `rocm` to enable GPU support in the container accordingly.
# GPU_DRIVER=cuda #| rocm
## CONTAINER_UID can be set to the UID of the user on the host system that should own the files in the container.
## It is usually not necessary to change this. Use `id -u` on the host system to find the UID.
# CONTAINER_UID=1000

View File

@ -18,8 +18,6 @@ ENV INVOKEAI_SRC=/opt/invokeai
ENV VIRTUAL_ENV=/opt/venv/invokeai
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
ARG TORCH_VERSION=2.1.2
ARG TORCHVISION_VERSION=0.16.2
ARG GPU_DRIVER=cuda
ARG TARGETPLATFORM="linux/amd64"
# unused but available
@ -27,7 +25,12 @@ ARG BUILDPLATFORM
WORKDIR ${INVOKEAI_SRC}
# Install pytorch before all other pip packages
COPY invokeai ./invokeai
COPY pyproject.toml ./
# Editable mode helps use the same image for development:
# the local working copy can be bind-mounted into the image
# at path defined by ${INVOKEAI_SRC}
# NOTE: there are no pytorch builds for arm64 + cuda, only cpu
# x86_64/CUDA is default
RUN --mount=type=cache,target=/root/.cache/pip \
@ -39,20 +42,10 @@ RUN --mount=type=cache,target=/root/.cache/pip \
else \
extra_index_url_arg="--extra-index-url https://download.pytorch.org/whl/cu121"; \
fi &&\
pip install $extra_index_url_arg \
torch==$TORCH_VERSION \
torchvision==$TORCHVISION_VERSION
# Install the local package.
# Editable mode helps use the same image for development:
# the local working copy can be bind-mounted into the image
# at path defined by ${INVOKEAI_SRC}
COPY invokeai ./invokeai
COPY pyproject.toml ./
RUN --mount=type=cache,target=/root/.cache/pip \
# xformers + triton fails to install on arm64
if [ "$GPU_DRIVER" = "cuda" ] && [ "$TARGETPLATFORM" = "linux/amd64" ]; then \
pip install -e ".[xformers]"; \
pip install $extra_index_url_arg -e ".[xformers]"; \
else \
pip install $extra_index_url_arg -e "."; \
fi
@ -62,6 +55,7 @@ RUN --mount=type=cache,target=/root/.cache/pip \
FROM node:20-slim AS web-builder
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack use pnpm@8.x
RUN corepack enable
WORKDIR /build
@ -101,6 +95,8 @@ RUN apt update && apt install -y --no-install-recommends \
ENV INVOKEAI_SRC=/opt/invokeai
ENV VIRTUAL_ENV=/opt/venv/invokeai
ENV INVOKEAI_ROOT=/invokeai
ENV INVOKEAI_HOST=0.0.0.0
ENV INVOKEAI_PORT=9090
ENV PATH="$VIRTUAL_ENV/bin:$INVOKEAI_SRC:$PATH"
ENV CONTAINER_UID=${CONTAINER_UID:-1000}
ENV CONTAINER_GID=${CONTAINER_GID:-1000}
@ -125,4 +121,4 @@ RUN mkdir -p ${INVOKEAI_ROOT} && chown -R ${CONTAINER_UID}:${CONTAINER_GID} ${IN
COPY docker/docker-entrypoint.sh ./
ENTRYPOINT ["/opt/invokeai/docker-entrypoint.sh"]
CMD ["invokeai-web", "--host", "0.0.0.0"]
CMD ["invokeai-web"]

View File

@ -1,41 +1,88 @@
# InvokeAI Containerized
# Invoke in Docker
All commands should be run within the `docker` directory: `cd docker`
First things first:
## Quickstart :rocket:
- Ensure that Docker can use your [NVIDIA][nvidia docker docs] or [AMD][amd docker docs] GPU.
- This document assumes a Linux system, but should work similarly under Windows with WSL2.
- We don't recommend running Invoke in Docker on macOS at this time. It works, but very slowly.
On a known working Linux+Docker+CUDA (Nvidia) system, execute `./run.sh` in this directory. It will take a few minutes - depending on your internet speed - to install the core models. Once the application starts up, open `http://localhost:9090` in your browser to Invoke!
## Quickstart
For more configuration options (using an AMD GPU, custom root directory location, etc): read on.
No `docker compose`, no persistence, single command, using the official images:
## Detailed setup
**CUDA (NVIDIA GPU):**
```bash
docker run --runtime=nvidia --gpus=all --publish 9090:9090 ghcr.io/invoke-ai/invokeai
```
**ROCm (AMD GPU):**
```bash
docker run --device /dev/kfd --device /dev/dri --publish 9090:9090 ghcr.io/invoke-ai/invokeai:main-rocm
```
Open `http://localhost:9090` in your browser once the container finishes booting, install some models, and generate away!
### Data persistence
To persist your generated images and downloaded models outside of the container, add a `--volume/-v` flag to the above command, e.g.:
```bash
docker run --volume /some/local/path:/invokeai {...etc...}
```
`/some/local/path/invokeai` will contain all your data.
It can *usually* be reused between different installs of Invoke. Tread with caution and read the release notes!
## Customize the container
The included `run.sh` script is a convenience wrapper around `docker compose`. It can be helpful for passing additional build arguments to `docker compose`. Alternatively, the familiar `docker compose` commands work just as well.
```bash
cd docker
cp .env.sample .env
# edit .env to your liking if you need to; it is well commented.
./run.sh
```
It will take a few minutes to build the image the first time. Once the application starts up, open `http://localhost:9090` in your browser to invoke!
>[!TIP]
>When using the `run.sh` script, the container will continue running after Ctrl+C. To shut it down, use the `docker compose down` command.
## Docker setup in detail
#### Linux
1. Ensure builkit is enabled in the Docker daemon settings (`/etc/docker/daemon.json`)
1. Ensure buildkit is enabled in the Docker daemon settings (`/etc/docker/daemon.json`)
2. Install the `docker compose` plugin using your package manager, or follow a [tutorial](https://docs.docker.com/compose/install/linux/#install-using-the-repository).
- The deprecated `docker-compose` (hyphenated) CLI continues to work for now.
- The deprecated `docker-compose` (hyphenated) CLI probably won't work. Update to a recent version.
3. Ensure docker daemon is able to access the GPU.
- You may need to install [nvidia-container-toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html)
- [NVIDIA docs](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html)
- [AMD docs](https://rocm.docs.amd.com/projects/install-on-linux/en/latest/how-to/docker.html)
#### macOS
> [!TIP]
> You'll be better off installing Invoke directly on your system, because Docker can not use the GPU on macOS.
If you are still reading:
1. Ensure Docker has at least 16GB RAM
2. Enable VirtioFS for file sharing
3. Enable `docker compose` V2 support
This is done via Docker Desktop preferences
This is done via Docker Desktop preferences.
### Configure Invoke environment
### Configure the Invoke Environment
1. Make a copy of `.env.sample` and name it `.env` (`cp .env.sample .env` (Mac/Linux) or `copy example.env .env` (Windows)). Make changes as necessary. Set `INVOKEAI_ROOT` to an absolute path to:
a. the desired location of the InvokeAI runtime directory, or
b. an existing, v3.0.0 compatible runtime directory.
1. Make a copy of `.env.sample` and name it `.env` (`cp .env.sample .env` (Mac/Linux) or `copy example.env .env` (Windows)). Make changes as necessary. Set `INVOKEAI_ROOT` to an absolute path to the desired location of the InvokeAI runtime directory. It may be an existing directory from a previous installation (post 4.0.0).
1. Execute `run.sh`
The image will be built automatically if needed.
The runtime directory (holding models and outputs) will be created in the location specified by `INVOKEAI_ROOT`. The default location is `~/invokeai`. The runtime directory will be populated with the base configs and models necessary to start generating.
The runtime directory (holding models and outputs) will be created in the location specified by `INVOKEAI_ROOT`. The default location is `~/invokeai`. Navigate to the Model Manager tab and install some models before generating.
### Use a GPU
@ -43,9 +90,9 @@ The runtime directory (holding models and outputs) will be created in the locati
- WSL2 is *required* for Windows.
- only `x86_64` architecture is supported.
The Docker daemon on the system must be already set up to use the GPU. In case of Linux, this involves installing `nvidia-docker-runtime` and configuring the `nvidia` runtime as default. Steps will be different for AMD. Please see Docker documentation for the most up-to-date instructions for using your GPU with Docker.
The Docker daemon on the system must be already set up to use the GPU. In case of Linux, this involves installing `nvidia-docker-runtime` and configuring the `nvidia` runtime as default. Steps will be different for AMD. Please see Docker/NVIDIA/AMD documentation for the most up-to-date instructions for using your GPU with Docker.
To use an AMD GPU, set `GPU_DRIVER=rocm` in your `.env` file.
To use an AMD GPU, set `GPU_DRIVER=rocm` in your `.env` file before running `./run.sh`.
## Customize
@ -59,30 +106,12 @@ Values are optional, but setting `INVOKEAI_ROOT` is highly recommended. The defa
INVOKEAI_ROOT=/Volumes/WorkDrive/invokeai
HUGGINGFACE_TOKEN=the_actual_token
CONTAINER_UID=1000
GPU_DRIVER=nvidia
GPU_DRIVER=cuda
```
Any environment variables supported by InvokeAI can be set here - please see the [Configuration docs](https://invoke-ai.github.io/InvokeAI/features/CONFIGURATION/) for further detail.
Any environment variables supported by InvokeAI can be set here. See the [Configuration docs](https://invoke-ai.github.io/InvokeAI/features/CONFIGURATION/) for further detail.
## Even Moar Customizing!
---
See the `docker-compose.yml` file. The `command` instruction can be uncommented and used to run arbitrary startup commands. Some examples below.
### Reconfigure the runtime directory
Can be used to download additional models from the supported model list
In conjunction with `INVOKEAI_ROOT` can be also used to initialize a runtime directory
```yaml
command:
- invokeai-configure
- --yes
```
Or install models:
```yaml
command:
- invokeai-model-install
```
[nvidia docker docs]: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
[amd docker docs]: https://rocm.docs.amd.com/projects/install-on-linux/en/latest/how-to/docker.html

View File

@ -1,45 +1,36 @@
# Copyright (c) 2023 Eugene Brodsky https://github.com/ebr
version: '3.8'
x-invokeai: &invokeai
image: "local/invokeai:latest"
build:
context: ..
dockerfile: docker/Dockerfile
# variables without a default will automatically inherit from the host environment
environment:
- INVOKEAI_ROOT
- HF_HOME
# Create a .env file in the same directory as this docker-compose.yml file
# and populate it with environment variables. See .env.sample
env_file:
- .env
# variables without a default will automatically inherit from the host environment
environment:
# if set, CONTAINER_INVOKEAI_ROOT will override the Invoke runtime directory location *inside* the container
- INVOKEAI_ROOT=${CONTAINER_INVOKEAI_ROOT:-/invokeai}
- HF_HOME
ports:
- "${INVOKEAI_PORT:-9090}:9090"
- "${INVOKEAI_PORT:-9090}:${INVOKEAI_PORT:-9090}"
volumes:
- type: bind
source: ${HOST_INVOKEAI_ROOT:-${INVOKEAI_ROOT:-~/invokeai}}
target: ${INVOKEAI_ROOT:-/invokeai}
target: ${CONTAINER_INVOKEAI_ROOT:-/invokeai}
bind:
create_host_path: true
- ${HF_HOME:-~/.cache/huggingface}:${HF_HOME:-/invokeai/.cache/huggingface}
# - ${INVOKEAI_MODELS_DIR:-${INVOKEAI_ROOT:-/invokeai/models}}
# - ${INVOKEAI_MODELS_CONFIG_PATH:-${INVOKEAI_ROOT:-/invokeai/configs/models.yaml}}
tty: true
stdin_open: true
# # Example of running alternative commands/scripts in the container
# command:
# - bash
# - -c
# - |
# invokeai-model-install --yes --default-only --config_file ${INVOKEAI_ROOT}/config_custom.yaml
# invokeai-nodes-web --host 0.0.0.0
services:
invokeai-nvidia:
invokeai-cuda:
<<: *invokeai
deploy:
resources:

View File

@ -9,10 +9,6 @@ set -e -o pipefail
### Set INVOKEAI_ROOT pointing to a valid runtime directory
# Otherwise configure the runtime dir first.
### Configure the InvokeAI runtime directory (done by default)):
# docker run --rm -it <this image> --configure
# or skip with --no-configure
### Set the CONTAINER_UID envvar to match your user.
# Ensures files created in the container are owned by you:
# docker run --rm -it -v /some/path:/invokeai -e CONTAINER_UID=$(id -u) <this image>
@ -22,43 +18,23 @@ USER_ID=${CONTAINER_UID:-1000}
USER=ubuntu
usermod -u ${USER_ID} ${USER} 1>/dev/null
configure() {
# Configure the runtime directory
if [[ -f ${INVOKEAI_ROOT}/invokeai.yaml ]]; then
echo "${INVOKEAI_ROOT}/invokeai.yaml exists. InvokeAI is already configured."
echo "To reconfigure InvokeAI, delete the above file."
echo "======================================================================"
else
mkdir -p "${INVOKEAI_ROOT}"
chown --recursive ${USER} "${INVOKEAI_ROOT}"
gosu ${USER} invokeai-configure --yes --default_only
fi
}
## Skip attempting to configure.
## Must be passed first, before any other args.
if [[ $1 != "--no-configure" ]]; then
configure
else
shift
fi
### Set the $PUBLIC_KEY env var to enable SSH access.
# We do not install openssh-server in the image by default to avoid bloat.
# but it is useful to have the full SSH server e.g. on Runpod.
# (use SCP to copy files to/from the image, etc)
if [[ -v "PUBLIC_KEY" ]] && [[ ! -d "${HOME}/.ssh" ]]; then
apt-get update
apt-get install -y openssh-server
pushd "$HOME"
mkdir -p .ssh
echo "${PUBLIC_KEY}" > .ssh/authorized_keys
chmod -R 700 .ssh
popd
service ssh start
apt-get update
apt-get install -y openssh-server
pushd "$HOME"
mkdir -p .ssh
echo "${PUBLIC_KEY}" >.ssh/authorized_keys
chmod -R 700 .ssh
popd
service ssh start
fi
mkdir -p "${INVOKEAI_ROOT}"
chown --recursive ${USER} "${INVOKEAI_ROOT}" || true
cd "${INVOKEAI_ROOT}"
# Run the CMD as the Container User (not root).

View File

@ -8,11 +8,15 @@ run() {
local build_args=""
local profile=""
# create .env file if it doesn't exist, otherwise docker compose will fail
touch .env
# parse .env file for build args
build_args=$(awk '$1 ~ /=[^$]/ && $0 !~ /^#/ {print "--build-arg " $0 " "}' .env) &&
profile="$(awk -F '=' '/GPU_DRIVER/ {print $2}' .env)"
[[ -z "$profile" ]] && profile="nvidia"
# default to 'cuda' profile
[[ -z "$profile" ]] && profile="cuda"
local service_name="invokeai-$profile"

173
docs/RELEASE.md Normal file
View File

@ -0,0 +1,173 @@
# Release Process
The app is published in twice, in different build formats.
- A [PyPI] distribution. This includes both a source distribution and built distribution (a wheel). Users install with `pip install invokeai`. The updater uses this build.
- An installer on the [InvokeAI Releases Page]. This is a zip file with install scripts and a wheel. This is only used for new installs.
## General Prep
Make a developer call-out for PRs to merge. Merge and test things out.
While the release workflow does not include end-to-end tests, it does pause before publishing so you can download and test the final build.
## Release Workflow
The `release.yml` workflow runs a number of jobs to handle code checks, tests, build and publish on PyPI.
It is triggered on **tag push**, when the tag matches `v*`. It doesn't matter if you've prepped a release branch like `release/v3.5.0` or are releasing from `main` - it works the same.
> Because commits are reference-counted, it is safe to create a release branch, tag it, let the workflow run, then delete the branch. So long as the tag exists, that commit will exist.
### Triggering the Workflow
Run `make tag-release` to tag the current commit and kick off the workflow.
The release may also be dispatched [manually].
### Workflow Jobs and Process
The workflow consists of a number of concurrently-run jobs, and two final publish jobs.
The publish jobs require manual approval and are only run if the other jobs succeed.
#### `check-version` Job
This job checks that the git ref matches the app version. It matches the ref against the `__version__` variable in `invokeai/version/invokeai_version.py`.
When the workflow is triggered by tag push, the ref is the tag. If the workflow is run manually, the ref is the target selected from the **Use workflow from** dropdown.
This job uses [samuelcolvin/check-python-version].
> Any valid [version specifier] works, so long as the tag matches the version. The release workflow works exactly the same for `RC`, `post`, `dev`, etc.
#### Check and Test Jobs
- **`python-tests`**: runs `pytest` on matrix of platforms
- **`python-checks`**: runs `ruff` (format and lint)
- **`frontend-tests`**: runs `vitest`
- **`frontend-checks`**: runs `prettier` (format), `eslint` (lint), `dpdm` (circular refs), `tsc` (static type check) and `knip` (unused imports)
> **TODO** We should add `mypy` or `pyright` to the **`check-python`** job.
> **TODO** We should add an end-to-end test job that generates an image.
#### `build-installer` Job
This sets up both python and frontend dependencies and builds the python package. Internally, this runs `installer/create_installer.sh` and uploads two artifacts:
- **`dist`**: the python distribution, to be published on PyPI
- **`InvokeAI-installer-${VERSION}.zip`**: the installer to be included in the GitHub release
#### Sanity Check & Smoke Test
At this point, the release workflow pauses as the remaining publish jobs require approval. Time to test the installer.
Because the installer pulls from PyPI, and we haven't published to PyPI yet, you will need to install from the wheel:
- Download and unzip `dist.zip` and the installer from the **Summary** tab of the workflow
- Run the installer script using the `--wheel` CLI arg, pointing at the wheel:
```sh
./install.sh --wheel ../InvokeAI-4.0.0rc6-py3-none-any.whl
```
- Install to a temporary directory so you get the new user experience
- Download a model and generate
> The same wheel file is bundled in the installer and in the `dist` artifact, which is uploaded to PyPI. You should end up with the exactly the same installation as if the installer got the wheel from PyPI.
##### Something isn't right
If testing reveals any issues, no worries. Cancel the workflow, which will cancel the pending publish jobs (you didn't approve them prematurely, right?).
Now you can start from the top:
- Fix the issues and PR the fixes per usual
- Get the PR approved and merged per usual
- Switch to `main` and pull in the fixes
- Run `make tag-release` to move the tag to `HEAD` (which has the fixes) and kick off the release workflow again
- Re-do the sanity check
#### PyPI Publish Jobs
The publish jobs will run if any of the previous jobs fail.
They use [GitHub environments], which are configured as [trusted publishers] on PyPI.
Both jobs require a maintainer to approve them from the workflow's **Summary** tab.
- Click the **Review deployments** button
- Select the environment (either `testpypi` or `pypi`)
- Click **Approve and deploy**
> **If the version already exists on PyPI, the publish jobs will fail.** PyPI only allows a given version to be published once - you cannot change it. If version published on PyPI has a problem, you'll need to "fail forward" by bumping the app version and publishing a followup release.
##### Failing PyPI Publish
Check the [python infrastructure status page] for incidents.
If there are no incidents, contact @hipsterusername or @lstein, who have owner access to GH and PyPI, to see if access has expired or something like that.
#### `publish-testpypi` Job
Publishes the distribution on the [Test PyPI] index, using the `testpypi` GitHub environment.
This job is not required for the production PyPI publish, but included just in case you want to test the PyPI release.
If approved and successful, you could try out the test release like this:
```sh
# Create a new virtual environment
python -m venv ~/.test-invokeai-dist --prompt test-invokeai-dist
# Install the distribution from Test PyPI
pip install --index-url https://test.pypi.org/simple/ invokeai
# Run and test the app
invokeai-web
# Cleanup
deactivate
rm -rf ~/.test-invokeai-dist
```
#### `publish-pypi` Job
Publishes the distribution on the production PyPI index, using the `pypi` GitHub environment.
## Publish the GitHub Release with installer
Once the release is published to PyPI, it's time to publish the GitHub release.
1. [Draft a new release] on GitHub, choosing the tag that triggered the release.
1. Write the release notes, describing important changes. The **Generate release notes** button automatically inserts the changelog and new contributors, and you can copy/paste the intro from previous releases.
1. Use `scripts/get_external_contributions.py` to get a list of external contributions to shout out in the release notes.
1. Upload the zip file created in **`build`** job into the Assets section of the release notes.
1. Check **Set as a pre-release** if it's a pre-release.
1. Check **Create a discussion for this release**.
1. Publish the release.
1. Announce the release in Discord.
> **TODO** Workflows can create a GitHub release from a template and upload release assets. One popular action to handle this is [ncipollo/release-action]. A future enhancement to the release process could set this up.
## Manual Build
The `build installer` workflow can be dispatched manually. This is useful to test the installer for a given branch or tag.
No checks are run, it just builds.
## Manual Release
The `release` workflow can be dispatched manually. You must dispatch the workflow from the right tag, else it will fail the version check.
This functionality is available as a fallback in case something goes wonky. Typically, releases should be triggered via tag push as described above.
[InvokeAI Releases Page]: https://github.com/invoke-ai/InvokeAI/releases
[PyPI]: https://pypi.org/
[Draft a new release]: https://github.com/invoke-ai/InvokeAI/releases/new
[Test PyPI]: https://test.pypi.org/
[version specifier]: https://packaging.python.org/en/latest/specifications/version-specifiers/
[ncipollo/release-action]: https://github.com/ncipollo/release-action
[GitHub environments]: https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment
[trusted publishers]: https://docs.pypi.org/trusted-publishers/
[samuelcolvin/check-python-version]: https://github.com/samuelcolvin/check-python-version
[manually]: #manual-release
[python infrastructure status page]: https://status.python.org/

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 786 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -128,7 +128,8 @@ The queue operates on a series of download job objects. These objects
specify the source and destination of the download, and keep track of
the progress of the download.
The only job type currently implemented is `DownloadJob`, a pydantic object with the
Two job types are defined. `DownloadJob` and
`MultiFileDownloadJob`. The former is a pydantic object with the
following fields:
| **Field** | **Type** | **Default** | **Description** |
@ -138,7 +139,7 @@ following fields:
| `dest` | Path | | Where to download to |
| `access_token` | str | | [optional] string containing authentication token for access |
| `on_start` | Callable | | [optional] callback when the download starts |
| `on_progress` | Callable | | [optional] callback called at intervals during download progress |
| `on_progress` | Callable | | [optional] callback called at intervals during download progress |
| `on_complete` | Callable | | [optional] callback called after successful download completion |
| `on_error` | Callable | | [optional] callback called after an error occurs |
| `id` | int | auto assigned | Job ID, an integer >= 0 |
@ -190,6 +191,33 @@ A cancelled job will have status `DownloadJobStatus.ERROR` and an
`error_type` field of "DownloadJobCancelledException". In addition,
the job's `cancelled` property will be set to True.
The `MultiFileDownloadJob` is used for diffusers model downloads,
which contain multiple files and directories under a common root:
| **Field** | **Type** | **Default** | **Description** |
|----------------|-----------------|---------------|-----------------|
| _Fields passed in at job creation time_ |
| `download_parts` | Set[DownloadJob]| | Component download jobs |
| `dest` | Path | | Where to download to |
| `on_start` | Callable | | [optional] callback when the download starts |
| `on_progress` | Callable | | [optional] callback called at intervals during download progress |
| `on_complete` | Callable | | [optional] callback called after successful download completion |
| `on_error` | Callable | | [optional] callback called after an error occurs |
| `id` | int | auto assigned | Job ID, an integer >= 0 |
| _Fields updated over the course of the download task_
| `status` | DownloadJobStatus| | Status code |
| `download_path` | Path | | Path to the root of the downloaded files |
| `bytes` | int | 0 | Bytes downloaded so far |
| `total_bytes` | int | 0 | Total size of the file at the remote site |
| `error_type` | str | | String version of the exception that caused an error during download |
| `error` | str | | String version of the traceback associated with an error |
| `cancelled` | bool | False | Set to true if the job was cancelled by the caller|
Note that the MultiFileDownloadJob does not support the `priority`,
`job_started`, `job_ended` or `content_type` attributes. You can get
these from the individual download jobs in `download_parts`.
### Callbacks
Download jobs can be associated with a series of callbacks, each with
@ -251,11 +279,40 @@ jobs using `list_jobs()`, fetch a single job by its with
running jobs with `cancel_all_jobs()`, and wait for all jobs to finish
with `join()`.
#### job = queue.download(source, dest, priority, access_token)
#### job = queue.download(source, dest, priority, access_token, on_start, on_progress, on_complete, on_cancelled, on_error)
Create a new download job and put it on the queue, returning the
DownloadJob object.
#### multifile_job = queue.multifile_download(parts, dest, access_token, on_start, on_progress, on_complete, on_cancelled, on_error)
This is similar to download(), but instead of taking a single source,
it accepts a `parts` argument consisting of a list of
`RemoteModelFile` objects. Each part corresponds to a URL/Path pair,
where the URL is the location of the remote file, and the Path is the
destination.
`RemoteModelFile` can be imported from `invokeai.backend.model_manager.metadata`, and
consists of a url/path pair. Note that the path *must* be relative.
The method returns a `MultiFileDownloadJob`.
```
from invokeai.backend.model_manager.metadata import RemoteModelFile
remote_file_1 = RemoteModelFile(url='http://www.foo.bar/my/pytorch_model.safetensors'',
path='my_model/textencoder/pytorch_model.safetensors'
)
remote_file_2 = RemoteModelFile(url='http://www.bar.baz/vae.ckpt',
path='my_model/vae/diffusers_model.safetensors'
)
job = queue.multifile_download(parts=[remote_file_1, remote_file_2],
dest='/tmp/downloads',
on_progress=TqdmProgress().update)
queue.wait_for_job(job)
print(f"The files were downloaded to {job.download_path}")
```
#### jobs = queue.list_jobs()
Return a list of all active and inactive `DownloadJob`s.

View File

@ -16,11 +16,6 @@ model. These are the:
information. It is also responsible for managing the InvokeAI
`models` directory and its contents.
* _ModelMetadataStore_ and _ModelMetaDataFetch_ Backend modules that
are able to retrieve metadata from online model repositories,
transform them into Pydantic models, and cache them to the InvokeAI
SQL database.
* _DownloadQueueServiceBase_
A multithreaded downloader responsible
for downloading models from a remote source to disk. The download
@ -32,7 +27,6 @@ model. These are the:
Responsible for loading a model from disk
into RAM and VRAM and getting it ready for inference.
## Location of the Code
The four main services can be found in
@ -63,23 +57,21 @@ provides the following fields:
|----------------|-----------------|------------------|
| `key` | str | Unique identifier for the model |
| `name` | str | Name of the model (not unique) |
| `model_type` | ModelType | The type of the model |
| `model_format` | ModelFormat | The format of the model (e.g. "diffusers"); also used as a Union discriminator |
| `base_model` | BaseModelType | The base model that the model is compatible with |
| `model_type` | ModelType | The type of the model |
| `model_format` | ModelFormat | The format of the model (e.g. "diffusers"); also used as a Union discriminator |
| `base_model` | BaseModelType | The base model that the model is compatible with |
| `path` | str | Location of model on disk |
| `original_hash` | str | Hash of the model when it was first installed |
| `current_hash` | str | Most recent hash of the model's contents |
| `hash` | str | Hash of the model |
| `description` | str | Human-readable description of the model (optional) |
| `source` | str | Model's source URL or repo id (optional) |
The `key` is a unique 32-character random ID which was generated at
install time. The `original_hash` field stores a hash of the model's
install time. The `hash` field stores a hash of the model's
contents at install time obtained by sampling several parts of the
model's files using the `imohash` library. Over the course of the
model's lifetime it may be transformed in various ways, such as
changing its precision or converting it from a .safetensors to a
diffusers model. When this happens, `original_hash` is unchanged, but
`current_hash` is updated to indicate the current contents.
diffusers model.
`ModelType`, `ModelFormat` and `BaseModelType` are string enums that
are defined in `invokeai.backend.model_manager.config`. They are also
@ -94,7 +86,6 @@ The `path` field can be absolute or relative. If relative, it is taken
to be relative to the `models_dir` setting in the user's
`invokeai.yaml` file.
### CheckpointConfig
This adds support for checkpoint configurations, and adds the
@ -174,7 +165,7 @@ store = context.services.model_manager.store
or from elsewhere in the code by accessing
`ApiDependencies.invoker.services.model_manager.store`.
### Creating a `ModelRecordService`
### Creating a `ModelRecordService`
To create a new `ModelRecordService` database or open an existing one,
you can directly create either a `ModelRecordServiceSQL` or a
@ -217,27 +208,27 @@ for use in the InvokeAI web server. Its signature is:
```
def open(
cls,
config: InvokeAIAppConfig,
conn: Optional[sqlite3.Connection] = None,
lock: Optional[threading.Lock] = None
config: InvokeAIAppConfig,
conn: Optional[sqlite3.Connection] = None,
lock: Optional[threading.Lock] = None
) -> Union[ModelRecordServiceSQL, ModelRecordServiceFile]:
```
The way it works is as follows:
1. Retrieve the value of the `model_config_db` option from the user's
`invokeai.yaml` config file.
`invokeai.yaml` config file.
2. If `model_config_db` is `auto` (the default), then:
- Use the values of `conn` and `lock` to return a `ModelRecordServiceSQL` object
opened on the passed connection and lock.
- Open up a new connection to `databases/invokeai.db` if `conn`
* Use the values of `conn` and `lock` to return a `ModelRecordServiceSQL` object
opened on the passed connection and lock.
* Open up a new connection to `databases/invokeai.db` if `conn`
and/or `lock` are missing (see note below).
3. If `model_config_db` is a Path, then use `from_db_file`
to return the appropriate type of ModelRecordService.
4. If `model_config_db` is None, then retrieve the legacy
`conf_path` option from `invokeai.yaml` and use the Path
indicated there. This will default to `configs/models.yaml`.
So a typical startup pattern would be:
```
@ -255,7 +246,7 @@ store = ModelRecordServiceBase.open(config, db_conn, lock)
Configurations can be retrieved in several ways.
#### get_model(key) -> AnyModelConfig:
#### get_model(key) -> AnyModelConfig
The basic functionality is to call the record store object's
`get_model()` method with the desired model's unique key. It returns
@ -272,28 +263,28 @@ print(model_conf.path)
If the key is unrecognized, this call raises an
`UnknownModelException`.
#### exists(key) -> AnyModelConfig:
#### exists(key) -> AnyModelConfig
Returns True if a model with the given key exists in the databsae.
#### search_by_path(path) -> AnyModelConfig:
#### search_by_path(path) -> AnyModelConfig
Returns the configuration of the model whose path is `path`. The path
is matched using a simple string comparison and won't correctly match
models referred to by different paths (e.g. using symbolic links).
#### search_by_name(name, base, type) -> List[AnyModelConfig]:
#### search_by_name(name, base, type) -> List[AnyModelConfig]
This method searches for models that match some combination of `name`,
`BaseType` and `ModelType`. Calling without any arguments will return
all the models in the database.
#### all_models() -> List[AnyModelConfig]:
#### all_models() -> List[AnyModelConfig]
Return all the model configs in the database. Exactly equivalent to
calling `search_by_name()` with no arguments.
#### search_by_tag(tags) -> List[AnyModelConfig]:
#### search_by_tag(tags) -> List[AnyModelConfig]
`tags` is a list of strings. This method returns a list of model
configs that contain all of the given tags. Examples:
@ -312,11 +303,11 @@ commercializable_models = [x for x in store.all_models() \
if x.license.contains('allowCommercialUse=Sell')]
```
#### version() -> str:
#### version() -> str
Returns the version of the database, currently at `3.2`
#### model_info_by_name(name, base_model, model_type) -> ModelConfigBase:
#### model_info_by_name(name, base_model, model_type) -> ModelConfigBase
This method exists to ease the transition from the previous version of
the model manager, in which `get_model()` took the three arguments
@ -337,7 +328,7 @@ model and pass its key to `get_model()`.
Several methods allow you to create and update stored model config
records.
#### add_model(key, config) -> AnyModelConfig:
#### add_model(key, config) -> AnyModelConfig
Given a key and a configuration, this will add the model's
configuration record to the database. `config` can either be a subclass of
@ -352,7 +343,7 @@ model with the same key is already in the database, or an
`InvalidModelConfigException` if a dict was passed and Pydantic
experienced a parse or validation error.
### update_model(key, config) -> AnyModelConfig:
### update_model(key, config) -> AnyModelConfig
Given a key and a configuration, this will update the model
configuration record in the database. `config` can be either a
@ -370,33 +361,30 @@ The `ModelInstallService` class implements the
shop for all your model install needs. It provides the following
functionality:
- Registering a model config record for a model already located on the
* Registering a model config record for a model already located on the
local filesystem, without moving it or changing its path.
- Installing a model alreadiy located on the local filesystem, by
* Installing a model alreadiy located on the local filesystem, by
moving it into the InvokeAI root directory under the
`models` folder (or wherever config parameter `models_dir`
specifies).
- Probing of models to determine their type, base type and other key
* Probing of models to determine their type, base type and other key
information.
- Interface with the InvokeAI event bus to provide status updates on
* Interface with the InvokeAI event bus to provide status updates on
the download, installation and registration process.
- Downloading a model from an arbitrary URL and installing it in
* Downloading a model from an arbitrary URL and installing it in
`models_dir`.
- Special handling for Civitai model URLs which allow the user to
paste in a model page's URL or download link
- Special handling for HuggingFace repo_ids to recursively download
* Special handling for HuggingFace repo_ids to recursively download
the contents of the repository, paying attention to alternative
variants such as fp16.
- Saving tags and other metadata about the model into the invokeai database
* Saving tags and other metadata about the model into the invokeai database
when fetching from a repo that provides that type of information,
(currently only Civitai and HuggingFace).
(currently only HuggingFace).
### Initializing the installer
@ -409,26 +397,25 @@ In the event you wish to create a new installer, you may use the
following initialization pattern:
```
from invokeai.app.services.config import InvokeAIAppConfig
from invokeai.app.services.config import get_config
from invokeai.app.services.model_records import ModelRecordServiceSQL
from invokeai.app.services.model_install import ModelInstallService
from invokeai.app.services.download import DownloadQueueService
from invokeai.app.services.shared.sqlite import SqliteDatabase
from invokeai.app.services.shared.sqlite.sqlite_database import SqliteDatabase
from invokeai.backend.util.logging import InvokeAILogger
config = InvokeAIAppConfig.get_config()
config.parse_args()
config = get_config()
logger = InvokeAILogger.get_logger(config=config)
db = SqliteDatabase(config, logger)
record_store = ModelRecordServiceSQL(db)
db = SqliteDatabase(config.db_path, logger)
record_store = ModelRecordServiceSQL(db, logger)
queue = DownloadQueueService()
queue.start()
installer = ModelInstallService(app_config=config,
installer = ModelInstallService(app_config=config,
record_store=record_store,
download_queue=queue
)
download_queue=queue
)
installer.start()
```
@ -440,10 +427,8 @@ required parameters:
| `app_config` | InvokeAIAppConfig | InvokeAI app configuration object |
| `record_store` | ModelRecordServiceBase | Config record storage database |
| `download_queue` | DownloadQueueServiceBase | Download queue object |
| `metadata_store` | Optional[ModelMetadataStore] | Metadata storage object |
|`session` | Optional[requests.Session] | Swap in a different Session object (usually for debugging) |
Once initialized, the installer will provide the following methods:
#### install_job = installer.heuristic_import(source, [config], [access_token])
@ -457,15 +442,15 @@ The `source` is a string that can be any of these forms
1. A path on the local filesystem (`C:\\users\\fred\\model.safetensors`)
2. A Url pointing to a single downloadable model file (`https://civitai.com/models/58390/detail-tweaker-lora-lora`)
3. A HuggingFace repo_id with any of the following formats:
- `model/name` -- entire model
- `model/name:fp32` -- entire model, using the fp32 variant
- `model/name:fp16:vae` -- vae submodel, using the fp16 variant
- `model/name::vae` -- vae submodel, using default precision
- `model/name:fp16:path/to/model.safetensors` -- an individual model file, fp16 variant
- `model/name::path/to/model.safetensors` -- an individual model file, default variant
* `model/name` -- entire model
* `model/name:fp32` -- entire model, using the fp32 variant
* `model/name:fp16:vae` -- vae submodel, using the fp16 variant
* `model/name::vae` -- vae submodel, using default precision
* `model/name:fp16:path/to/model.safetensors` -- an individual model file, fp16 variant
* `model/name::path/to/model.safetensors` -- an individual model file, default variant
Note that by specifying a relative path to the top of the HuggingFace
repo, you can download and install arbitrary models files.
repo, you can download and install arbitrary models files.
The variant, if not provided, will be automatically filled in with
`fp32` if the user has requested full precision, and `fp16`
@ -491,9 +476,9 @@ following illustrates basic usage:
```
from invokeai.app.services.model_install import (
LocalModelSource,
HFModelSource,
URLModelSource,
LocalModelSource,
HFModelSource,
URLModelSource,
)
source1 = LocalModelSource(path='/opt/models/sushi.safetensors') # a local safetensors file
@ -513,13 +498,13 @@ for source in [source1, source2, source3, source4, source5, source6, source7]:
source2job = installer.wait_for_installs(timeout=120)
for source in sources:
job = source2job[source]
if job.complete:
model_config = job.config_out
model_key = model_config.key
print(f"{source} installed as {model_key}")
elif job.errored:
print(f"{source}: {job.error_type}.\nStack trace:\n{job.error}")
if job.complete:
model_config = job.config_out
model_key = model_config.key
print(f"{source} installed as {model_key}")
elif job.errored:
print(f"{source}: {job.error_type}.\nStack trace:\n{job.error}")
```
As shown here, the `import_model()` method accepts a variety of
@ -528,7 +513,7 @@ HuggingFace repo_ids with and without a subfolder designation,
Civitai model URLs and arbitrary URLs that point to checkpoint files
(but not to folders).
Each call to `import_model()` return a `ModelInstallJob` job,
Each call to `import_model()` return a `ModelInstallJob` job,
an object which tracks the progress of the install.
If a remote model is requested, the model's files are downloaded in
@ -555,7 +540,7 @@ The full list of arguments to `import_model()` is as follows:
| `config` | Dict[str, Any] | None | Override all or a portion of model's probed attributes |
The next few sections describe the various types of ModelSource that
can be passed to `import_model()`.
can be passed to `import_model()`.
`config` can be used to override all or a portion of the configuration
attributes returned by the model prober. See the section below for
@ -566,7 +551,6 @@ details.
This is used for a model that is located on a locally-accessible Posix
filesystem, such as a local disk or networked fileshare.
| **Argument** | **Type** | **Default** | **Description** |
|------------------|------------------------------|-------------|-------------------------------------------|
| `path` | str | Path | None | Path to the model file or directory |
@ -586,33 +570,7 @@ The `AnyHttpUrl` class can be imported from `pydantic.networks`.
Ordinarily, no metadata is retrieved from these sources. However,
there is special-case code in the installer that looks for HuggingFace
and Civitai URLs and fetches the corresponding model metadata from
the corresponding repo.
#### CivitaiModelSource
This is used for a model that is hosted by the Civitai web site.
| **Argument** | **Type** | **Default** | **Description** |
|------------------|------------------------------|-------------|-------------------------------------------|
| `version_id` | int | None | The ID of the particular version of the desired model. |
| `access_token` | str | None | An access token needed to gain access to a subscriber's-only model. |
Civitai has two model IDs, both of which are integers. The `model_id`
corresponds to a collection of model versions that may different in
arbitrary ways, such as derivation from different checkpoint training
steps, SFW vs NSFW generation, pruned vs non-pruned, etc. The
`version_id` points to a specific version. Please use the latter.
Some Civitai models require an access token to download. These can be
generated from the Civitai profile page of a logged-in
account. Somewhat annoyingly, if you fail to provide the access token
when downloading a model that needs it, Civitai generates a redirect
to a login page rather than a 403 Forbidden error. The installer
attempts to catch this event and issue an informative error
message. Otherwise you will get an "unrecognized model suffix" error
when the model prober tries to identify the type of the HTML login
page.
and fetches the corresponding model metadata from the corresponding repo.
#### HFModelSource
@ -625,7 +583,6 @@ HuggingFace has the most complicated `ModelSource` structure:
| `subfolder` | Path | None | Look for the model in a subfolder of the repo. |
| `access_token` | str | None | An access token needed to gain access to a subscriber's-only model. |
The `repo_id` is the repository ID, such as `stabilityai/sdxl-turbo`.
The `variant` is one of the various diffusers formats that HuggingFace
@ -661,7 +618,6 @@ in. To download these files, you must provide an
`HfFolder.get_token()` will be called to fill it in with the cached
one.
#### Monitoring the install job process
When you create an install job with `import_model()`, it launches the
@ -675,14 +631,13 @@ The `ModelInstallJob` class has the following structure:
| `id` | `int` | Integer ID for this job |
| `status` | `InstallStatus` | An enum of [`waiting`, `downloading`, `running`, `completed`, `error` and `cancelled`]|
| `config_in` | `dict` | Overriding configuration values provided by the caller |
| `config_out` | `AnyModelConfig`| After successful completion, contains the configuration record written to the database |
| `inplace` | `boolean` | True if the caller asked to install the model in place using its local path |
| `source` | `ModelSource` | The local path, remote URL or repo_id of the model to be installed |
| `config_out` | `AnyModelConfig`| After successful completion, contains the configuration record written to the database |
| `inplace` | `boolean` | True if the caller asked to install the model in place using its local path |
| `source` | `ModelSource` | The local path, remote URL or repo_id of the model to be installed |
| `local_path` | `Path` | If a remote model, holds the path of the model after it is downloaded; if a local model, same as `source` |
| `error_type` | `str` | Name of the exception that led to an error status |
| `error` | `str` | Traceback of the error |
If the `event_bus` argument was provided, events will also be
broadcast to the InvokeAI event bus. The events will appear on the bus
as an event of type `EventServiceBase.model_event`, a timestamp and
@ -702,14 +657,13 @@ following keys:
| `total_bytes` | int | Total size of all the files that make up the model |
| `parts` | List[Dict]| Information on the progress of the individual files that make up the model |
The parts is a list of dictionaries that give information on each of
the components pieces of the download. The dictionary's keys are
`source`, `local_path`, `bytes` and `total_bytes`, and correspond to
the like-named keys in the main event.
Note that downloading events will not be issued for local models, and
that downloading events occur *before* the running event.
that downloading events occur _before_ the running event.
##### `model_install_running`
@ -752,14 +706,13 @@ properties: `waiting`, `downloading`, `running`, `complete`, `errored`
and `cancelled`, as well as `in_terminal_state`. The last will return
True if the job is in the complete, errored or cancelled states.
#### Model configuration and probing
The install service uses the `invokeai.backend.model_manager.probe`
module during import to determine the model's type, base type, and
other configuration parameters. Among other things, it assigns a
default name and description for the model based on probed
fields.
fields.
When downloading remote models is implemented, additional
configuration information, such as list of trigger terms, will be
@ -774,11 +727,11 @@ attributes. Here is an example of setting the
```
install_job = installer.import_model(
source=HFModelSource(repo_id='stabilityai/stable-diffusion-2-1',variant='fp32'),
config=dict(
prediction_type=SchedulerPredictionType('v_prediction')
name='stable diffusion 2 base model',
)
)
config=dict(
prediction_type=SchedulerPredictionType('v_prediction')
name='stable diffusion 2 base model',
)
)
```
### Other installer methods
@ -862,7 +815,6 @@ This method is similar to `unregister()`, but also unconditionally
deletes the corresponding model weights file(s), regardless of whether
they are inside or outside the InvokeAI models hierarchy.
#### path = installer.download_and_cache(remote_source, [access_token], [timeout])
This utility routine will download the model file located at source,
@ -887,22 +839,6 @@ and directories at regular intervals when the size of the cache
exceeds the value specified in Invoke's `convert_cache` configuration
variable.
#### List[str]=installer.scan_directory(scan_dir: Path, install: bool)
This method will recursively scan the directory indicated in
`scan_dir` for new models and either install them in the models
directory or register them in place, depending on the setting of
`install` (default False).
The return value is the list of keys of the new installed/registered
models.
#### installer.sync_to_config()
This method synchronizes models in the models directory and autoimport
directory to those in the `ModelConfigRecordService` database. New
models are registered and orphan models are unregistered.
#### installer.start(invoker)
The `start` method is called by the API intialization routines when
@ -953,7 +889,7 @@ following fields:
When you create a job, you can assign it a `priority`. If multiple
jobs are queued, the job with the lowest priority runs first. (Don't
blame me! The Unix developers came up with this convention.)
blame me! The Unix developers came up with this convention.)
Every job has a `source` and a `destination`. `source` is a string in
the base class, but subclassses redefine it more specifically.
@ -974,7 +910,7 @@ is in its lifecycle. Values are defined in the string enum
`DownloadJobStatus`, a symbol available from
`invokeai.app.services.download_manager`. Possible values are:
| **Value** | **String Value** | ** Description ** |
| **Value** | **String Value** | **Description** |
|--------------|---------------------|-------------------|
| `IDLE` | idle | Job created, but not submitted to the queue |
| `ENQUEUED` | enqueued | Job is patiently waiting on the queue |
@ -991,7 +927,7 @@ debugging and performance testing.
In case of an error, the Exception that caused the error will be
placed in the `error` field, and the job's status will be set to
`DownloadJobStatus.ERROR`.
`DownloadJobStatus.ERROR`.
After an error occurs, any partially downloaded files will be deleted
from disk, unless `preserve_partial_downloads` was set to True at job
@ -1040,11 +976,11 @@ While a job is being downloaded, the queue will emit events at
periodic intervals. A typical series of events during a successful
download session will look like this:
- enqueued
- running
- running
- running
- completed
* enqueued
* running
* running
* running
* completed
There will be a single enqueued event, followed by one or more running
events, and finally one `completed`, `error` or `cancelled`
@ -1053,12 +989,12 @@ events.
It is possible for a caller to pause download temporarily, in which
case the events may look something like this:
- enqueued
- running
- running
- paused
- running
- completed
* enqueued
* running
* running
* paused
* running
* completed
The download queue logs when downloads start and end (unless `quiet`
is set to True at initialization time) but doesn't log any progress
@ -1120,11 +1056,11 @@ A typical initialization sequence will look like:
from invokeai.app.services.download_manager import DownloadQueueService
def log_download_event(job: DownloadJobBase):
logger.info(f'job={job.id}: status={job.status}')
logger.info(f'job={job.id}: status={job.status}')
queue = DownloadQueueService(
event_handlers=[log_download_event]
)
event_handlers=[log_download_event]
)
```
Event handlers can be provided to the queue at initialization time as
@ -1155,9 +1091,9 @@ To use the former method, follow this example:
```
job = DownloadJobRemoteSource(
source='http://www.civitai.com/models/13456',
destination='/tmp/models/',
event_handlers=[my_handler1, my_handler2], # if desired
)
destination='/tmp/models/',
event_handlers=[my_handler1, my_handler2], # if desired
)
queue.submit_download_job(job, start=True)
```
@ -1172,13 +1108,13 @@ To have the queue create the job for you, follow this example instead:
```
job = queue.create_download_job(
source='http://www.civitai.com/models/13456',
destdir='/tmp/models/',
filename='my_model.safetensors',
event_handlers=[my_handler1, my_handler2], # if desired
start=True,
)
destdir='/tmp/models/',
filename='my_model.safetensors',
event_handlers=[my_handler1, my_handler2], # if desired
start=True,
)
```
The `filename` argument forces the downloader to use the specified
name for the file rather than the name provided by the remote source,
and is equivalent to manually specifying a destination of
@ -1187,7 +1123,6 @@ and is equivalent to manually specifying a destination of
Here is the full list of arguments that can be provided to
`create_download_job()`:
| **Argument** | **Type** | **Default** | **Description** |
|------------------|------------------------------|-------------|-------------------------------------------|
| `source` | Union[str, Path, AnyHttpUrl] | | Download remote or local source |
@ -1200,7 +1135,7 @@ Here is the full list of arguments that can be provided to
Internally, `create_download_job()` has a little bit of internal logic
that looks at the type of the source and selects the right subclass of
`DownloadJobBase` to create and enqueue.
`DownloadJobBase` to create and enqueue.
**TODO**: move this logic into its own method for overriding in
subclasses.
@ -1266,51 +1201,30 @@ queue and have not yet reached a terminal state.
The modules found under `invokeai.backend.model_manager.metadata`
provide a straightforward API for fetching model metadatda from online
repositories. Currently two repositories are supported: HuggingFace
and Civitai. However, the modules are easily extended for additional
repos, provided that they have defined APIs for metadata access.
repositories. Currently only HuggingFace is supported. However, the
modules are easily extended for additional repos, provided that they
have defined APIs for metadata access.
Metadata comprises any descriptive information that is not essential
for getting the model to run. For example "author" is metadata, while
"type", "base" and "format" are not. The latter fields are part of the
model's config, as defined in `invokeai.backend.model_manager.config`.
### Example Usage:
### Example Usage
```
from invokeai.backend.model_manager.metadata import (
AnyModelRepoMetadata,
CivitaiMetadataFetch,
CivitaiMetadata
ModelMetadataStore,
)
# to access the initialized sql database
from invokeai.app.api.dependencies import ApiDependencies
civitai = CivitaiMetadataFetch()
hf = HuggingFaceMetadataFetch()
# fetch the metadata
model_metadata = civitai.from_url("https://civitai.com/models/215796")
model_metadata = hf.from_id("<repo_id>")
# get some common metadata fields
author = model_metadata.author
tags = model_metadata.tags
# get some Civitai-specific fields
assert isinstance(model_metadata, CivitaiMetadata)
trained_words = model_metadata.trained_words
base_model = model_metadata.base_model_trained_on
thumbnail = model_metadata.thumbnail_url
# cache the metadata to the database using the key corresponding to
# an existing model config record in the `model_config` table
sql_cache = ModelMetadataStore(ApiDependencies.invoker.services.db)
sql_cache.add_metadata('fb237ace520b6716adc98bcb16e8462c', model_metadata)
# now we can search the database by tag, author or model name
# matches will contain a list of model keys that match the search
matches = sql_cache.search_by_tag({"tool", "turbo"})
assert isinstance(model_metadata, HuggingFaceMetadata)
```
### Structure of the Metadata objects
@ -1328,7 +1242,6 @@ This is the common base class for metadata:
| `author` | str | Model's author |
| `tags` | Set[str] | Model tags |
Note that the model config record also has a `name` field. It is
intended that the config record version be locally customizable, while
the metadata version is read-only. However, enforcing this is expected
@ -1348,53 +1261,14 @@ This descends from `ModelMetadataBase` and adds the following fields:
| `last_modified`| datetime | Date of last commit of this model to the repo |
| `files` | List[Path] | List of the files in the model repo |
#### `CivitaiMetadata`
This descends from `ModelMetadataBase` and adds the following fields:
| **Field Name** | **Type** | **Description** |
|----------------|-----------------|------------------|
| `type` | Literal["civitai"] | Used for the discriminated union of metadata classes|
| `id` | int | Civitai model id |
| `version_name` | str | Name of this version of the model (distinct from model name) |
| `version_id` | int | Civitai model version id (distinct from model id) |
| `created` | datetime | Date this version of the model was created |
| `updated` | datetime | Date this version of the model was last updated |
| `published` | datetime | Date this version of the model was published to Civitai |
| `description` | str | Model description. Quite verbose and contains HTML tags |
| `version_description` | str | Model version description, usually describes changes to the model |
| `nsfw` | bool | Whether the model tends to generate NSFW content |
| `restrictions` | LicenseRestrictions | An object that describes what is and isn't allowed with this model |
| `trained_words`| Set[str] | Trigger words for this model, if any |
| `download_url` | AnyHttpUrl | URL for downloading this version of the model |
| `base_model_trained_on` | str | Name of the model that this version was trained on |
| `thumbnail_url` | AnyHttpUrl | URL to access a representative thumbnail image of the model's output |
| `weight_min` | int | For LoRA sliders, the minimum suggested weight to apply |
| `weight_max` | int | For LoRA sliders, the maximum suggested weight to apply |
Note that `weight_min` and `weight_max` are not currently populated
and take the default values of (-1.0, +2.0). The issue is that these
values aren't part of the structured data but appear in the text
description. Some regular expression or LLM coding may be able to
extract these values.
Also be aware that `base_model_trained_on` is free text and doesn't
correspond to our `ModelType` enum.
`CivitaiMetadata` also defines some convenience properties relating to
licensing restrictions: `credit_required`, `allow_commercial_use`,
`allow_derivatives` and `allow_different_license`.
#### `AnyModelRepoMetadata`
This is a discriminated Union of `CivitaiMetadata` and
`HuggingFaceMetadata`.
This is a discriminated Union of `HuggingFaceMetadata`.
### Fetching Metadata from Online Repos
The `HuggingFaceMetadataFetch` and `CivitaiMetadataFetch` classes will
retrieve metadata from their corresponding repositories and return
The `HuggingFaceMetadataFetch` class will
retrieve metadata from its corresponding repository and return
`AnyModelRepoMetadata` objects. Their base class
`ModelMetadataFetchBase` is an abstract class that defines two
methods: `from_url()` and `from_id()`. The former accepts the type of
@ -1412,98 +1286,17 @@ provide a `requests.Session` argument. This allows you to customize
the low-level HTTP fetch requests and is used, for instance, in the
testing suite to avoid hitting the internet.
The HuggingFace and Civitai fetcher subclasses add additional
repo-specific fetching methods:
The HuggingFace fetcher subclass add additional repo-specific fetching methods:
#### HuggingFaceMetadataFetch
This overrides its base class `from_json()` method to return a
`HuggingFaceMetadata` object directly.
#### CivitaiMetadataFetch
This adds the following methods:
`from_civitai_modelid()` This takes the ID of a model, finds the
default version of the model, and then retrieves the metadata for
that version, returning a `CivitaiMetadata` object directly.
`from_civitai_versionid()` This takes the ID of a model version and
retrieves its metadata. Functionally equivalent to `from_id()`, the
only difference is that it returna a `CivitaiMetadata` object rather
than an `AnyModelRepoMetadata`.
### Metadata Storage
The `ModelMetadataStore` provides a simple facility to store model
metadata in the `invokeai.db` database. The data is stored as a JSON
blob, with a few common fields (`name`, `author`, `tags`) broken out
to be searchable.
When a metadata object is saved to the database, it is identified
using the model key, _and this key must correspond to an existing
model key in the model_config table_. There is a foreign key integrity
constraint between the `model_config.id` field and the
`model_metadata.id` field such that if you attempt to save metadata
under an unknown key, the attempt will result in an
`UnknownModelException`. Likewise, when a model is deleted from
`model_config`, the deletion of the corresponding metadata record will
be triggered.
Tags are stored in a normalized fashion in the tables `model_tags` and
`tags`. Triggers keep the tag table in sync with the `model_metadata`
table.
To create the storage object, initialize it with the InvokeAI
`SqliteDatabase` object. This is often done this way:
```
from invokeai.app.api.dependencies import ApiDependencies
metadata_store = ModelMetadataStore(ApiDependencies.invoker.services.db)
```
You can then access the storage with the following methods:
#### `add_metadata(key, metadata)`
Add the metadata using a previously-defined model key.
There is currently no `delete_metadata()` method. The metadata will
persist until the matching config is deleted from the `model_config`
table.
#### `get_metadata(key) -> AnyModelRepoMetadata`
Retrieve the metadata corresponding to the model key.
#### `update_metadata(key, new_metadata)`
Update an existing metadata record with new metadata.
#### `search_by_tag(tags: Set[str]) -> Set[str]`
Given a set of tags, find models that are tagged with them. If
multiple tags are provided then a matching model must be tagged with
*all* the tags in the set. This method returns a set of model keys and
is intended to be used in conjunction with the `ModelRecordService`:
```
model_config_store = ApiDependencies.invoker.services.model_records
matches = metadata_store.search_by_tag({'license:other'})
models = [model_config_store.get(x) for x in matches]
```
#### `search_by_name(name: str) -> Set[str]
Find all model metadata records that have the given name and return a
set of keys to the corresponding model config objects.
#### `search_by_author(author: str) -> Set[str]
Find all model metadata records that have the given author and return
a set of keys to the corresponding model config objects.
The `ModelConfigBase` stores this response in the `source_api_response` field
as a JSON blob.
***
@ -1535,16 +1328,16 @@ from invokeai.app.services.model_load import ModelLoadService, ModelLoaderRegist
config = InvokeAIAppConfig.get_config()
ram_cache = ModelCache(
max_cache_size=config.ram_cache_size, max_vram_cache_size=config.vram_cache_size, logger=logger
max_cache_size=config.ram_cache_size, max_vram_cache_size=config.vram_cache_size, logger=logger
)
convert_cache = ModelConvertCache(
cache_path=config.models_convert_cache_path, max_size=config.convert_cache_size
cache_path=config.models_convert_cache_path, max_size=config.convert_cache_size
)
loader = ModelLoadService(
app_config=config,
ram_cache=ram_cache,
convert_cache=convert_cache,
registry=ModelLoaderRegistry
app_config=config,
ram_cache=ram_cache,
convert_cache=convert_cache,
registry=ModelLoaderRegistry
)
```
@ -1567,20 +1360,26 @@ The returned `LoadedModel` object contains a copy of the configuration
record returned by the model record `get_model()` method, as well as
the in-memory loaded model:
| **Attribute Name** | **Type** | **Description** |
|----------------|-----------------|------------------|
| `config` | AnyModelConfig | A copy of the model's configuration record for retrieving base type, etc. |
| `model` | AnyModel | The instantiated model (details below) |
| `locker` | ModelLockerBase | A context manager that mediates the movement of the model into VRAM |
Because the loader can return multiple model types, it is typed to
return `AnyModel`, a Union `ModelMixin`, `torch.nn.Module`,
`IAIOnnxRuntimeModel`, `IPAdapter`, `IPAdapterPlus`, and
`EmbeddingModelRaw`. `ModelMixin` is the base class of all diffusers
models, `EmbeddingModelRaw` is used for LoRA and TextualInversion
models. The others are obvious.
### get_model_by_key(key, [submodel]) -> LoadedModel
The `get_model_by_key()` method will retrieve the model using its
unique database key. For example:
loaded_model = loader.get_model_by_key('f13dd932c0c35c22dcb8d6cda4203764', SubModelType('vae'))
`get_model_by_key()` may raise any of the following exceptions:
* `UnknownModelException` -- key not in database
* `ModelNotFoundException` -- key in database but model not found at path
* `NotImplementedException` -- the loader doesn't know how to load this type of model
### Using the Loaded Model in Inference
`LoadedModel` acts as a context manager. The context loads the model
into the execution device (e.g. VRAM on CUDA systems), locks the model
@ -1588,17 +1387,33 @@ in the execution device for the duration of the context, and returns
the model. Use it like this:
```
model_info = loader.get_model_by_key('f13dd932c0c35c22dcb8d6cda4203764', SubModelType('vae'))
with model_info as vae:
image = vae.decode(latents)[0]
loaded_model_= loader.get_model_by_key('f13dd932c0c35c22dcb8d6cda4203764', SubModelType('vae'))
with loaded_model as vae:
image = vae.decode(latents)[0]
```
`get_model_by_key()` may raise any of the following exceptions:
The object returned by the LoadedModel context manager is an
`AnyModel`, which is a Union of `ModelMixin`, `torch.nn.Module`,
`IAIOnnxRuntimeModel`, `IPAdapter`, `IPAdapterPlus`, and
`EmbeddingModelRaw`. `ModelMixin` is the base class of all diffusers
models, `EmbeddingModelRaw` is used for LoRA and TextualInversion
models. The others are obvious.
In addition, you may call `LoadedModel.model_on_device()`, a context
manager that returns a tuple of the model's state dict in CPU and the
model itself in VRAM. It is used to optimize the LoRA patching and
unpatching process:
```
loaded_model_= loader.get_model_by_key('f13dd932c0c35c22dcb8d6cda4203764', SubModelType('vae'))
with loaded_model.model_on_device() as (state_dict, vae):
image = vae.decode(latents)[0]
```
Since not all models have state dicts, the `state_dict` return value
can be None.
- `UnknownModelException` -- key not in database
- `ModelNotFoundException` -- key in database but model not found at path
- `NotImplementedException` -- the loader doesn't know how to load this type of model
### Emitting model loading events
When the `context` argument is passed to `load_model_*()`, it will
@ -1609,15 +1424,15 @@ following payload:
```
payload=dict(
queue_id=queue_id,
queue_item_id=queue_item_id,
queue_batch_id=queue_batch_id,
graph_execution_state_id=graph_execution_state_id,
model_key=model_key,
submodel_type=submodel,
hash=model_info.hash,
location=str(model_info.location),
precision=str(model_info.precision),
queue_id=queue_id,
queue_item_id=queue_item_id,
queue_batch_id=queue_batch_id,
graph_execution_state_id=graph_execution_state_id,
model_key=model_key,
submodel_type=submodel,
hash=model_info.hash,
location=str(model_info.location),
precision=str(model_info.precision),
)
```
@ -1724,6 +1539,7 @@ object, or in `context.services.model_manager` from within an
invocation.
In the examples below, we have retrieved the manager using:
```
mm = ApiDependencies.invoker.services.model_manager
```
@ -1785,3 +1601,59 @@ This method takes a model key, looks it up using the
`ModelRecordServiceBase` object in `mm.store`, and passes the returned
model configuration to `load_model_by_config()`. It may raise a
`NotImplementedException`.
## Invocation Context Model Manager API
Within invocations, the following methods are available from the
`InvocationContext` object:
### context.download_and_cache_model(source) -> Path
This method accepts a `source` of a remote model, downloads and caches
it locally, and then returns a Path to the local model. The source can
be a direct download URL or a HuggingFace repo_id.
In the case of HuggingFace repo_id, the following variants are
recognized:
* stabilityai/stable-diffusion-v4 -- default model
* stabilityai/stable-diffusion-v4:fp16 -- fp16 variant
* stabilityai/stable-diffusion-v4:fp16:vae -- the fp16 vae subfolder
* stabilityai/stable-diffusion-v4:onnx:vae -- the onnx variant vae subfolder
You can also point at an arbitrary individual file within a repo_id
directory using this syntax:
* stabilityai/stable-diffusion-v4::/checkpoints/sd4.safetensors
### context.load_local_model(model_path, [loader]) -> LoadedModel
This method loads a local model from the indicated path, returning a
`LoadedModel`. The optional loader is a Callable that accepts a Path
to the object, and returns a `AnyModel` object. If no loader is
provided, then the method will use `torch.load()` for a .ckpt or .bin
checkpoint file, `safetensors.torch.load_file()` for a safetensors
checkpoint file, or `cls.from_pretrained()` for a directory that looks
like a diffusers directory.
### context.load_remote_model(source, [loader]) -> LoadedModel
This method accepts a `source` of a remote model, downloads and caches
it locally, loads it, and returns a `LoadedModel`. The source can be a
direct download URL or a HuggingFace repo_id.
In the case of HuggingFace repo_id, the following variants are
recognized:
* stabilityai/stable-diffusion-v4 -- default model
* stabilityai/stable-diffusion-v4:fp16 -- fp16 variant
* stabilityai/stable-diffusion-v4:fp16:vae -- the fp16 vae subfolder
* stabilityai/stable-diffusion-v4:onnx:vae -- the onnx variant vae subfolder
You can also point at an arbitrary individual file within a repo_id
directory using this syntax:
* stabilityai/stable-diffusion-v4::/checkpoints/sd4.safetensors

View File

@ -0,0 +1,133 @@
# Invoke UI
Invoke's UI is made possible by many contributors and open-source libraries. Thank you!
## Dev environment
### Setup
1. Install [node] and [pnpm].
1. Run `pnpm i` to install all packages.
#### Run in dev mode
1. From `invokeai/frontend/web/`, run `pnpm dev`.
1. From repo root, run `python scripts/invokeai-web.py`.
1. Point your browser to the dev server address, e.g. <http://localhost:5173/>
### Package scripts
- `dev`: run the frontend in dev mode, enabling hot reloading
- `build`: run all checks (madge, eslint, prettier, tsc) and then build the frontend
- `typegen`: generate types from the OpenAPI schema (see [Type generation])
- `lint:dpdm`: check circular dependencies
- `lint:eslint`: check code quality
- `lint:prettier`: check code formatting
- `lint:tsc`: check type issues
- `lint:knip`: check for unused exports or objects (failures here are just suggestions, not hard fails)
- `lint`: run all checks concurrently
- `fix`: run `eslint` and `prettier`, fixing fixable issues
### Type generation
We use [openapi-typescript] to generate types from the app's OpenAPI schema.
The generated types are committed to the repo in [schema.ts].
```sh
# from the repo root, start the server
python scripts/invokeai-web.py
# from invokeai/frontend/web/, run the script
pnpm typegen
```
### Localization
We use [i18next] for localization, but translation to languages other than English happens on our [Weblate] project.
Only the English source strings should be changed on this repo.
### VSCode
#### Example debugger config
```jsonc
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Invoke UI",
"url": "http://localhost:5173",
"webRoot": "${workspaceFolder}/invokeai/frontend/web"
}
]
}
```
#### Remote dev
We've noticed an intermittent timeout issue with the VSCode remote dev port forwarding.
We suggest disabling the editor's port forwarding feature and doing it manually via SSH:
```sh
ssh -L 9090:localhost:9090 -L 5173:localhost:5173 user@host
```
## Contributing Guidelines
Thanks for your interest in contributing to the Invoke Web UI!
Please follow these guidelines when contributing.
### Check in before investing your time
Please check in before you invest your time on anything besides a trivial fix, in case it conflicts with ongoing work or isn't aligned with the vision for the app.
If a feature request or issue doesn't already exist for the thing you want to work on, please create one.
Ping `@psychedelicious` on [discord] in the `#frontend-dev` channel or in the feature request / issue you want to work on - we're happy to chat.
### Code conventions
- This is a fairly complex app with a deep component tree. Please use memoization (`useCallback`, `useMemo`, `memo`) with enthusiasm.
- If you need to add some global, ephemeral state, please use [nanostores] if possible.
- Be careful with your redux selectors. If they need to be parameterized, consider creating them inside a `useMemo`.
- Feel free to use `lodash` (via `lodash-es`) to make the intent of your code clear.
- Please add comments describing the "why", not the "how" (unless it is really arcane).
### Commit format
Please use the [conventional commits] spec for the web UI, with a scope of "ui":
- `chore(ui): bump deps`
- `chore(ui): lint`
- `feat(ui): add some cool new feature`
- `fix(ui): fix some bug`
### Submitting a PR
- Ensure your branch is tidy. Use an interactive rebase to clean up the commit history and reword the commit messages if they are not descriptive.
- Run `pnpm lint`. Some issues are auto-fixable with `pnpm fix`.
- Fill out the PR form when creating the PR.
- It doesn't need to be super detailed, but a screenshot or video is nice if you changed something visually.
- If a section isn't relevant, delete it. There are no UI tests at this time.
## Other docs
- [Workflows - Design and Implementation]
- [State Management]
[node]: https://nodejs.org/en/download/
[pnpm]: https://github.com/pnpm/pnpm
[discord]: https://discord.gg/ZmtBAhwWhy
[i18next]: https://github.com/i18next/react-i18next
[Weblate]: https://hosted.weblate.org/engage/invokeai/
[openapi-typescript]: https://github.com/drwpow/openapi-typescript
[Type generation]: #type-generation
[schema.ts]: https://github.com/invoke-ai/InvokeAI/blob/main/invokeai/frontend/web/src/services/api/schema.ts
[conventional commits]: https://www.conventionalcommits.org/en/v1.0.0/
[Workflows - Design and Implementation]: ./WORKFLOWS.md
[State Management]: ./STATE_MGMT.md

View File

@ -0,0 +1,314 @@
# Workflows - Design and Implementation
> This document describes, at a high level, the design and implementation of workflows in the InvokeAI frontend. There are a substantial number of implementation details not included, but which are hopefully clear from the code.
InvokeAI's backend uses graphs, composed of **nodes** and **edges**, to process data and generate images.
Nodes have any number of **input fields** and **output fields**. Edges connect nodes together via their inputs and outputs. Fields have data types which dictate how they may be connected.
During execution, a nodes' outputs may be passed along to any number of other nodes' inputs.
Workflows are an enriched abstraction over a graph.
## Design
InvokeAI provide two ways to build graphs in the frontend: the [Linear UI](#linear-ui) and [Workflow Editor](#workflow-editor).
To better understand the use case and challenges related to workflows, we will review both of these modes.
### Linear UI
This includes the **Text to Image**, **Image to Image** and **Unified Canvas** tabs.
The user-managed parameters on these tabs are stored as simple objects in the application state. When the user invokes, adding a generation to the queue, we internally build a graph from these parameters.
This logic can be fairly complex due to the range of features available and their interactions. Depending on the parameters selected, the graph may be very different. Building graphs in code can be challenging - you are trying to construct a non-linear structure in a linear context.
The simplest graph building logic is for **Text to Image** with a SD1.5 model: [buildLinearTextToImageGraph.ts]
There are many other graph builders in the same directory for different tabs or base models (e.g. SDXL). Some are pretty hairy.
In the Linear UI, we go straight from **simple application state** to **graph** via these builders.
### Workflow Editor
The Workflow Editor is a visual graph editor, allowing users to draw edges from node to node to construct a graph. This _far_ more approachable way to create complex graphs.
InvokeAI uses the [reactflow] library to power the Workflow Editor. It provides both a graph editor UI and manages its own internal graph state.
#### Workflows
A workflow is a representation of a graph plus additional metadata:
- Name
- Description
- Version
- Notes
- [Exposed fields](#workflow-linear-view)
- Author, tags, category, etc.
Workflows should have other qualities:
- Portable: you should be able to load a workflow created by another person.
- Resilient: you should be able to "upgrade" a workflow as the application changes.
- Abstract: as much as is possible, workflows should not be married to the specific implementation details of the application.
To support these qualities, workflows are serializable, have a versioned schemas, and represent graphs as minimally as possible. Fortunately, the reactflow state for nodes and edges works perfectly for this.
##### Workflow -> reactflow state -> InvokeAI graph
Given a workflow, we need to be able to derive reactflow state and/or an InvokeAI graph from it.
The first step - workflow to reactflow state - is very simple. The logic is in [nodesSlice.ts], in the `workflowLoaded` reducer.
The reactflow state is, however, structurally incompatible with our backend's graph structure. When a user invokes on a Workflow, we need to convert the reactflow state into an InvokeAI graph. This is far simpler than the graph building logic from the Linear UI:
[buildNodesGraph.ts]
##### Nodes vs Invocations
We often use the terms "node" and "invocation" interchangeably, but they may refer to different things in the frontend.
reactflow [has its own definitions][reactflow-concepts] of "node", "edge" and "handle" which are closely related to InvokeAI graph concepts.
- A reactflow node is related to an InvokeAI invocation. It has a "data" property, which holds the InvokeAI-specific invocation data.
- A reactflow edge is roughly equivalent to an InvokeAI edge.
- A reactflow handle is roughly equivalent to an InvokeAI input or output field.
##### Workflow Linear View
Graphs are very capable data structures, but not everyone wants to work with them all the time.
To allow less technical users - or anyone who wants a less visually noisy workspace - to benefit from the power of nodes, InvokeAI has a workflow feature called the Linear View.
A workflow input field can be added to this Linear View, and its input component can be presented similarly to the Linear UI tabs. Internally, we add the field to the workflow's list of exposed fields.
#### OpenAPI Schema
OpenAPI is a schema specification that can represent complex data structures and relationships. The backend is capable of generating an OpenAPI schema for all invocations.
When the UI connects, it requests this schema and parses each invocation into an **invocation template**. Invocation templates have a number of properties, like title, description and type, but the most important ones are their input and output **field templates**.
Invocation and field templates are the "source of truth" for graphs, because they indicate what the backend is able to process.
When a user adds a new node to their workflow, these templates are used to instantiate a node with fields instantiated from the input and output field templates.
##### Field Instances and Templates
Field templates consist of:
- Name: the identifier of the field, its variable name in python
- Type: derived from the field's type annotation in python (e.g. IntegerField, ImageField, MainModelField)
- Constraints: derived from the field's creation args in python (e.g. minimum value for an integer)
- Default value: optionally provided in the field's creation args (e.g. 42 for an integer)
Field instances are created from the templates and have name, type and optionally a value.
The type of the field determines the UI components that are rendered for it.
A field instance's name associates it with its template.
##### Stateful vs Stateless Fields
**Stateful** fields store their value in the frontend graph. Think primitives, model identifiers, images, etc. Fields are only stateful if the frontend allows the user to directly input a value for them.
Many field types, however, are **stateless**. An example is a `UNetField`, which contains some data describing a UNet. Users cannot directly provide this data - it is created and consumed in the backend.
Stateless fields do not store their value in the node, so their field instances do not have values.
"Custom" fields will always be treated as stateless fields.
##### Single and Collection Fields
Field types have a name and cardinality property which may identify it as a **SINGLE**, **COLLECTION** or **SINGLE_OR_COLLECTION** field.
- If a field is annotated in python as a singular value or class, its field type is parsed as a **SINGLE** type (e.g. `int`, `ImageField`, `str`).
- If a field is annotated in python as a list, its field type is parsed as a **COLLECTION** type (e.g. `list[int]`).
- If it is annotated as a union of a type and list, the type will be parsed as a **SINGLE_OR_COLLECTION** type (e.g. `Union[int, list[int]]`). Fields may not be unions of different types (e.g. `Union[int, list[str]]` and `Union[int, str]` are not allowed).
## Implementation
The majority of data structures in the backend are [pydantic] models. Pydantic provides OpenAPI schemas for all models and we then generate TypeScript types from those.
The OpenAPI schema is parsed at runtime into our invocation templates.
Workflows and all related data are modeled in the frontend using [zod]. Related types are inferred from the zod schemas.
> In python, invocations are pydantic models with fields. These fields become node inputs. The invocation's `invoke()` function returns a pydantic model - its output. Like the invocation itself, the output model has any number of fields, which become node outputs.
### zod Schemas and Types
The zod schemas, inferred types, and type guards are in [types/].
Roughly order from lowest-level to highest:
- `common.ts`: stateful field data, and couple other misc types
- `field.ts`: fields - types, values, instances, templates
- `invocation.ts`: invocations and other node types
- `workflow.ts`: workflows and constituents
We customize the OpenAPI schema to include additional properties on invocation and field schemas. To facilitate parsing this schema into templates, we modify/wrap the types from [openapi-types] in `openapi.ts`.
### OpenAPI Schema Parsing
The entrypoint for OpenAPI schema parsing is [parseSchema.ts].
General logic flow:
- Iterate over all invocation schema objects
- Extract relevant invocation-level attributes (e.g. title, type, version, etc)
- Iterate over the invocation's input fields
- [Parse each field's type](#parsing-field-types)
- [Build a field input template](#building-field-input-templates) from the type - either a stateful template or "generic" stateless template
- Iterate over the invocation's output fields
- Parse the field's type (same as inputs)
- [Build a field output template](#building-field-output-templates)
- Assemble the attributes and fields into an invocation template
Most of these involve very straightforward `reduce`s, but the less intuitive steps are detailed below.
#### Parsing Field Types
Field types are represented as structured objects:
```ts
type FieldType = {
name: string;
cardinality: 'SINGLE' | 'COLLECTION' | 'SINGLE_OR_COLLECTION';
};
```
The parsing logic is in `parseFieldType.ts`.
There are 4 general cases for field type parsing.
##### Primitive Types
When a field is annotated as a primitive values (e.g. `int`, `str`, `float`), the field type parsing is fairly straightforward. The field is represented by a simple OpenAPI **schema object**, which has a `type` property.
We create a field type name from this `type` string (e.g. `string` -> `StringField`). The cardinality is `"SINGLE"`.
##### Complex Types
When a field is annotated as a pydantic model (e.g. `ImageField`, `MainModelField`, `ControlField`), it is represented as a **reference object**. Reference objects are pointers to another schema or reference object within the schema.
We need to **dereference** the schema to pull these out. Dereferencing may require recursion. We use the reference object's name directly for the field type name.
> Unfortunately, at this time, we've had limited success using external libraries to deference at runtime, so we do this ourselves.
##### Collection Types
When a field is annotated as a list of a single type, the schema object has an `items` property. They may be a schema object or reference object and must be parsed to determine the item type.
We use the item type for field type name. The cardinality is `"COLLECTION"`.
##### Single or Collection Types
When a field is annotated as a union of a type and list of that type, the schema object has an `anyOf` property, which holds a list of valid types for the union.
After verifying that the union has two members (a type and list of the same type), we use the type for field type name, with cardinality `"SINGLE_OR_COLLECTION"`.
##### Optional Fields
In OpenAPI v3.1, when an object is optional, it is put into an `anyOf` along with a primitive schema object with `type: 'null'`.
Handling this adds a fair bit of complexity, as we now must filter out the `'null'` types and work with the remaining types as described above.
If there is a single remaining schema object, we must recursively call to `parseFieldType()` to get parse it.
#### Building Field Input Templates
Now that we have a field type, we can build an input template for the field.
Stateful fields all get a function to build their template, while stateless fields are constructed directly. This is possible because stateless fields have no default value or constraints.
See [buildFieldInputTemplate.ts].
#### Building Field Output Templates
Field outputs are similar to stateless fields - they do not have any value in the frontend. When building their templates, we don't need a special function for each field type.
See [buildFieldOutputTemplate.ts].
### Managing reactflow State
As described above, the workflow editor state is the essentially the reactflow state, plus some extra metadata.
We provide reactflow with an array of nodes and edges via redux, and a number of [event handlers][reactflow-events]. These handlers dispatch redux actions, managing nodes and edges.
The pieces of redux state relevant to workflows are:
- `state.nodes.nodes`: the reactflow nodes state
- `state.nodes.edges`: the reactflow edges state
- `state.nodes.workflow`: the workflow metadata
#### Building Nodes and Edges
A reactflow node has a few important top-level properties:
- `id`: unique identifier
- `type`: a string that maps to a react component to render the node
- `position`: XY coordinates
- `data`: arbitrary data
When the user adds a node, we build **invocation node data**, storing it in `data`. Invocation properties (e.g. type, version, label, etc.) are copied from the invocation template. Inputs and outputs are built from the invocation template's field templates.
See [buildInvocationNode.ts].
Edges are managed by reactflow, but briefly, they consist of:
- `source`: id of the source node
- `sourceHandle`: id of the source node handle (output field)
- `target`: id of the target node
- `targetHandle`: id of the target node handle (input field)
> Edge creation is gated behind validation logic. This validation compares the input and output field types and overall graph state.
#### Building a Workflow
Building a workflow entity is as simple as dropping the nodes, edges and metadata into an object.
Each node and edge is parsed with a zod schema, which serves to strip out any unneeded data.
See [buildWorkflow.ts].
#### Loading a Workflow
Workflows may be loaded from external sources or the user's local instance. In all cases, the workflow needs to be handled with care, as an untrusted object.
Loading has a few stages which may throw or warn if there are problems:
- Parsing the workflow data structure itself, [migrating](#workflow-migrations) it if necessary (throws)
- Check for a template for each node (warns)
- Check each node's version against its template (warns)
- Validate the source and target of each edge (warns)
This validation occurs in [validateWorkflow.ts].
If there are no fatal errors, the workflow is then stored in redux state.
### Workflow Migrations
When the workflow schema changes, we may need to perform some data migrations. This occurs as workflows are loaded. zod schemas for each workflow schema version is retained to facilitate migrations.
Previous schemas are in folders in `invokeai/frontend/web/src/features/nodes/types/`, eg `v1/`.
Migration logic is in [migrations.ts].
<!-- links -->
[pydantic]: https://github.com/pydantic/pydantic 'pydantic'
[zod]: https://github.com/colinhacks/zod 'zod'
[openapi-types]: https://github.com/kogosoftwarellc/open-api/tree/main/packages/openapi-types 'openapi-types'
[reactflow]: https://github.com/xyflow/xyflow 'reactflow'
[reactflow-concepts]: https://reactflow.dev/learn/concepts/terms-and-definitions
[reactflow-events]: https://reactflow.dev/api-reference/react-flow#event-handlers
[buildWorkflow.ts]: https://github.com/invoke-ai/InvokeAI/blob/main/invokeai/frontend/web/src/features/nodes/util/workflow/buildWorkflow.ts
[nodesSlice.ts]: https://github.com/invoke-ai/InvokeAI/blob/main/invokeai/frontend/web/src/features/nodes/store/nodesSlice.ts
[buildLinearTextToImageGraph.ts]: https://github.com/invoke-ai/InvokeAI/blob/main/invokeai/frontend/web/src/features/nodes/util/graph/buildLinearTextToImageGraph.ts
[buildNodesGraph.ts]: https://github.com/invoke-ai/InvokeAI/blob/main/invokeai/frontend/web/src/features/nodes/util/graph/buildNodesGraph.ts
[buildInvocationNode.ts]: https://github.com/invoke-ai/InvokeAI/blob/main/invokeai/frontend/web/src/features/nodes/util/node/buildInvocationNode.ts
[validateWorkflow.ts]: https://github.com/invoke-ai/InvokeAI/blob/main/invokeai/frontend/web/src/features/nodes/util/workflow/validateWorkflow.ts
[migrations.ts]: https://github.com/invoke-ai/InvokeAI/blob/main/invokeai/frontend/web/src/features/nodes/util/workflow/migrations.ts
[parseSchema.ts]: https://github.com/invoke-ai/InvokeAI/blob/main/invokeai/frontend/web/src/features/nodes/util/schema/parseSchema.ts
[buildFieldInputTemplate.ts]: https://github.com/invoke-ai/InvokeAI/blob/main/invokeai/frontend/web/src/features/nodes/util/schema/buildFieldInputTemplate.ts
[buildFieldOutputTemplate.ts]: https://github.com/invoke-ai/InvokeAI/blob/main/invokeai/frontend/web/src/features/nodes/util/schema/buildFieldOutputTemplate.ts

View File

@ -1,53 +0,0 @@
## :octicons-log-16: Important Changes Since Version 2.3
### Nodes
Behind the scenes, InvokeAI has been completely rewritten to support
"nodes," small unitary operations that can be combined into graphs to
form arbitrary workflows. For example, there is a prompt node that
processes the prompt string and feeds it to a text2latent node that
generates a latent image. The latents are then fed to a latent2image
node that translates the latent image into a PNG.
The WebGUI has a node editor that allows you to graphically design and
execute custom node graphs. The ability to save and load graphs is
still a work in progress, but coming soon.
### Command-Line Interface Retired
All "invokeai" command-line interfaces have been retired as of version
3.4.
To launch the Web GUI from the command-line, use the command
`invokeai-web` rather than the traditional `invokeai --web`.
### ControlNet
This version of InvokeAI features ControlNet, a system that allows you
to achieve exact poses for human and animal figures by providing a
model to follow. Full details are found in [ControlNet](features/CONTROLNET.md)
### New Schedulers
The list of schedulers has been completely revamped and brought up to date:
| **Short Name** | **Scheduler** | **Notes** |
|----------------|---------------------------------|-----------------------------|
| **ddim** | DDIMScheduler | |
| **ddpm** | DDPMScheduler | |
| **deis** | DEISMultistepScheduler | |
| **lms** | LMSDiscreteScheduler | |
| **pndm** | PNDMScheduler | |
| **heun** | HeunDiscreteScheduler | original noise schedule |
| **heun_k** | HeunDiscreteScheduler | using karras noise schedule |
| **euler** | EulerDiscreteScheduler | original noise schedule |
| **euler_k** | EulerDiscreteScheduler | using karras noise schedule |
| **kdpm_2** | KDPM2DiscreteScheduler | |
| **kdpm_2_a** | KDPM2AncestralDiscreteScheduler | |
| **dpmpp_2s** | DPMSolverSinglestepScheduler | |
| **dpmpp_2m** | DPMSolverMultistepScheduler | original noise scnedule |
| **dpmpp_2m_k** | DPMSolverMultistepScheduler | using karras noise schedule |
| **unipc** | UniPCMultistepScheduler | CPU only |
| **lcm** | LCMScheduler | |
Please see [3.0.0 Release Notes](https://github.com/invoke-ai/InvokeAI/releases/tag/v3.0.0) for further details.

View File

@ -1,589 +0,0 @@
---
title: Command-Line Interface
---
# :material-bash: CLI
## **Interactive Command Line Interface**
The InvokeAI command line interface (CLI) provides scriptable access
to InvokeAI's features.Some advanced features are only available
through the CLI, though they eventually find their way into the WebUI.
The CLI is accessible from the `invoke.sh`/`invoke.bat` launcher by
selecting option (1). Alternatively, it can be launched directly from
the command line by activating the InvokeAI environment and giving the
command:
```bash
invokeai
```
After some startup messages, you will be presented with the `invoke> `
prompt. Here you can type prompts to generate images and issue other
commands to load and manipulate generative models. The CLI has a large
number of command-line options that control its behavior. To get a
concise summary of the options, call `invokeai` with the `--help` argument:
```bash
invokeai --help
```
The script uses the readline library to allow for in-line editing, command
history (++up++ and ++down++), autocompletion, and more. To help keep track of
which prompts generated which images, the script writes a log file of image
names and prompts to the selected output directory.
Here is a typical session
```bash
PS1:C:\Users\fred> invokeai
* Initializing, be patient...
* Initializing, be patient...
>> Initialization file /home/lstein/invokeai/invokeai.init found. Loading...
>> Internet connectivity is True
>> InvokeAI, version 2.3.0-rc5
>> InvokeAI runtime directory is "/home/lstein/invokeai"
>> GFPGAN Initialized
>> CodeFormer Initialized
>> ESRGAN Initialized
>> Using device_type cuda
>> xformers memory-efficient attention is available and enabled
(...more initialization messages...)
* Initialization done! Awaiting your command (-h for help, 'q' to quit)
invoke> ashley judd riding a camel -n2 -s150
Outputs:
outputs/img-samples/00009.png: "ashley judd riding a camel" -n2 -s150 -S 416354203
outputs/img-samples/00010.png: "ashley judd riding a camel" -n2 -s150 -S 1362479620
invoke> "there's a fly in my soup" -n6 -g
outputs/img-samples/00011.png: "there's a fly in my soup" -n6 -g -S 2685670268
seeds for individual rows: [2685670268, 1216708065, 2335773498, 822223658, 714542046, 3395302430]
invoke> q
```
![invoke-py-demo](../assets/dream-py-demo.png)
## Arguments
The script recognizes a series of command-line switches that will
change important global defaults, such as the directory for image
outputs and the location of the model weight files.
### List of arguments recognized at the command line
These command-line arguments can be passed to `invoke.py` when you first run it
from the Windows, Mac or Linux command line. Some set defaults that can be
overridden on a per-prompt basis (see
[List of prompt arguments](#list-of-prompt-arguments). Others
| Argument <img width="240" align="right"/> | Shortcut <img width="100" align="right"/> | Default <img width="320" align="right"/> | Description |
| ----------------------------------------- | ----------------------------------------- | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `--help` | `-h` | | Print a concise help message. |
| `--outdir <path>` | `-o<path>` | `outputs/img_samples` | Location for generated images. |
| `--prompt_as_dir` | `-p` | `False` | Name output directories using the prompt text. |
| `--from_file <path>` | | `None` | Read list of prompts from a file. Use `-` to read from standard input |
| `--model <modelname>` | | `stable-diffusion-1.5` | Loads the initial model specified in configs/models.yaml. |
| `--ckpt_convert ` | | `False` | If provided both .ckpt and .safetensors files will be auto-converted into diffusers format in memory |
| `--autoconvert <path>` | | `None` | On startup, scan the indicated directory for new .ckpt/.safetensor files and automatically convert and import them |
| `--precision` | | `fp16` | Provide `fp32` for full precision mode, `fp16` for half-precision. `fp32` needed for Macintoshes and some NVidia cards. |
| `--png_compression <0-9>` | `-z<0-9>` | `6` | Select level of compression for output files, from 0 (no compression) to 9 (max compression) |
| `--safety-checker` | | `False` | Activate safety checker for NSFW and other potentially disturbing imagery |
| `--patchmatch`, `--no-patchmatch` | | `--patchmatch` | Load/Don't load the PatchMatch inpainting extension |
| `--xformers`, `--no-xformers` | | `--xformers` | Load/Don't load the Xformers memory-efficient attention module (CUDA only) |
| `--web` | | `False` | Start in web server mode |
| `--host <ip addr>` | | `localhost` | Which network interface web server should listen on. Set to 0.0.0.0 to listen on any. |
| `--port <port>` | | `9090` | Which port web server should listen for requests on. |
| `--config <path>` | | `configs/models.yaml` | Configuration file for models and their weights. |
| `--iterations <int>` | `-n<int>` | `1` | How many images to generate per prompt. |
| `--width <int>` | `-W<int>` | `512` | Width of generated image |
| `--height <int>` | `-H<int>` | `512` | Height of generated image | `--steps <int>` | `-s<int>` | `50` | How many steps of refinement to apply |
| `--strength <float>` | `-s<float>` | `0.75` | For img2img: how hard to try to match the prompt to the initial image. Ranges from 0.0-0.99, with higher values replacing the initial image completely. |
| `--fit` | `-F` | `False` | For img2img: scale the init image to fit into the specified -H and -W dimensions |
| `--grid` | `-g` | `False` | Save all image series as a grid rather than individually. |
| `--sampler <sampler>` | `-A<sampler>` | `k_lms` | Sampler to use. Use `-h` to get list of available samplers. |
| `--seamless` | | `False` | Create interesting effects by tiling elements of the image. |
| `--embedding_path <path>` | | `None` | Path to pre-trained embedding manager checkpoints, for custom models |
| `--gfpgan_model_path` | | `experiments/pretrained_models/GFPGANv1.4.pth` | Path to GFPGAN model file. |
| `--free_gpu_mem` | | `False` | Free GPU memory after sampling, to allow image decoding and saving in low VRAM conditions |
| `--precision` | | `auto` | Set model precision, default is selected by device. Options: auto, float32, float16, autocast |
!!! warning "These arguments are deprecated but still work"
<div align="center" markdown>
| Argument | Shortcut | Default | Description |
|--------------------|------------|---------------------|--------------|
| `--full_precision` | | `False` | Same as `--precision=fp32`|
| `--weights <path>` | | `None` | Path to weights file; use `--model stable-diffusion-1.4` instead |
| `--laion400m` | `-l` | `False` | Use older LAION400m weights; use `--model=laion400m` instead |
</div>
!!! tip
On Windows systems, you may run into
problems when passing the invoke script standard backslashed path
names because the Python interpreter treats "\" as an escape.
You can either double your slashes (ick): `C:\\path\\to\\my\\file`, or
use Linux/Mac style forward slashes (better): `C:/path/to/my/file`.
## The .invokeai initialization file
To start up invoke.py with your preferred settings, place your desired
startup options in a file in your home directory named `.invokeai` The
file should contain the startup options as you would type them on the
command line (`--steps=10 --grid`), one argument per line, or a
mixture of both using any of the accepted command switch formats:
!!! example "my unmodified initialization file"
```bash title="~/.invokeai" linenums="1"
# InvokeAI initialization file
# This is the InvokeAI initialization file, which contains command-line default values.
# Feel free to edit. If anything goes wrong, you can re-initialize this file by deleting
# or renaming it and then running invokeai-configure again.
# The --root option below points to the folder in which InvokeAI stores its models, configs and outputs.
--root="/Users/mauwii/invokeai"
# the --outdir option controls the default location of image files.
--outdir="/Users/mauwii/invokeai/outputs"
# You may place other frequently-used startup commands here, one or more per line.
# Examples:
# --web --host=0.0.0.0
# --steps=20
# -Ak_euler_a -C10.0
```
!!! note
The initialization file only accepts the command line arguments.
There are additional arguments that you can provide on the `invoke>` command
line (such as `-n` or `--iterations`) that cannot be entered into this file.
Also be alert for empty blank lines at the end of the file, which will cause
an arguments error at startup time.
## List of prompt arguments
After the invoke.py script initializes, it will present you with a `invoke>`
prompt. Here you can enter information to generate images from text
([txt2img](#txt2img)), to embellish an existing image or sketch
([img2img](#img2img)), or to selectively alter chosen regions of the image
([inpainting](#inpainting)).
### txt2img
!!! example ""
```bash
invoke> waterfall and rainbow -W640 -H480
```
This will create the requested image with the dimensions 640 (width)
and 480 (height).
Here are the invoke> command that apply to txt2img:
| Argument <img width="680" align="right"/> | Shortcut <img width="420" align="right"/> | Default <img width="480" align="right"/> | Description |
| ----------------------------------------- | ----------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| "my prompt" | | | Text prompt to use. The quotation marks are optional. |
| `--width <int>` | `-W<int>` | `512` | Width of generated image |
| `--height <int>` | `-H<int>` | `512` | Height of generated image |
| `--iterations <int>` | `-n<int>` | `1` | How many images to generate from this prompt |
| `--steps <int>` | `-s<int>` | `50` | How many steps of refinement to apply |
| `--cfg_scale <float>` | `-C<float>` | `7.5` | How hard to try to match the prompt to the generated image; any number greater than 1.0 works, but the useful range is roughly 5.0 to 20.0 |
| `--seed <int>` | `-S<int>` | `None` | Set the random seed for the next series of images. This can be used to recreate an image generated previously. |
| `--sampler <sampler>` | `-A<sampler>` | `k_lms` | Sampler to use. Use -h to get list of available samplers. |
| `--karras_max <int>` | | `29` | When using k\_\* samplers, set the maximum number of steps before shifting from using the Karras noise schedule (good for low step counts) to the LatentDiffusion noise schedule (good for high step counts) This value is sticky. [29] |
| `--hires_fix` | | | Larger images often have duplication artefacts. This option suppresses duplicates by generating the image at low res, and then using img2img to increase the resolution |
| `--png_compression <0-9>` | `-z<0-9>` | `6` | Select level of compression for output files, from 0 (no compression) to 9 (max compression) |
| `--grid` | `-g` | `False` | Turn on grid mode to return a single image combining all the images generated by this prompt |
| `--individual` | `-i` | `True` | Turn off grid mode (deprecated; leave off --grid instead) |
| `--outdir <path>` | `-o<path>` | `outputs/img_samples` | Temporarily change the location of these images |
| `--seamless` | | `False` | Activate seamless tiling for interesting effects |
| `--seamless_axes` | | `x,y` | Specify which axes to use circular convolution on. |
| `--log_tokenization` | `-t` | `False` | Display a color-coded list of the parsed tokens derived from the prompt |
| `--skip_normalization` | `-x` | `False` | Weighted subprompts will not be normalized. See [Weighted Prompts](../features/OTHER.md#weighted-prompts) |
| `--upscale <int> <float>` | `-U <int> <float>` | `-U 1 0.75` | Upscale image by magnification factor (2, 4), and set strength of upscaling (0.0-1.0). If strength not set, will default to 0.75. |
| `--facetool_strength <float>` | `-G <float> ` | `-G0` | Fix faces (defaults to using the GFPGAN algorithm); argument indicates how hard the algorithm should try (0.0-1.0) |
| `--facetool <name>` | `-ft <name>` | `-ft gfpgan` | Select face restoration algorithm to use: gfpgan, codeformer |
| `--codeformer_fidelity` | `-cf <float>` | `0.75` | Used along with CodeFormer. Takes values between 0 and 1. 0 produces high quality but low accuracy. 1 produces high accuracy but low quality |
| `--save_original` | `-save_orig` | `False` | When upscaling or fixing faces, this will cause the original image to be saved rather than replaced. |
| `--variation <float>` | `-v<float>` | `0.0` | Add a bit of noise (0.0=none, 1.0=high) to the image in order to generate a series of variations. Usually used in combination with `-S<seed>` and `-n<int>` to generate a series a riffs on a starting image. See [Variations](VARIATIONS.md). |
| `--with_variations <pattern>` | | `None` | Combine two or more variations. See [Variations](VARIATIONS.md) for now to use this. |
| `--save_intermediates <n>` | | `None` | Save the image from every nth step into an "intermediates" folder inside the output directory |
| `--h_symmetry_time_pct <float>` | | `None` | Create symmetry along the X axis at the desired percent complete of the generation process. (Must be between 0.0 and 1.0; set to a very small number like 0.0001 for just after the first step of generation.) |
| `--v_symmetry_time_pct <float>` | | `None` | Create symmetry along the Y axis at the desired percent complete of the generation process. (Must be between 0.0 and 1.0; set to a very small number like 0.0001 for just after the first step of generation.) |
!!! note
the width and height of the image must be multiples of 64. You can
provide different values, but they will be rounded down to the nearest multiple
of 64.
!!! example "This is a example of img2img"
```bash
invoke> waterfall and rainbow -I./vacation-photo.png -W640 -H480 --fit
```
This will modify the indicated vacation photograph by making it more like the
prompt. Results will vary greatly depending on what is in the image. We also ask
to --fit the image into a box no bigger than 640x480. Otherwise the image size
will be identical to the provided photo and you may run out of memory if it is
large.
In addition to the command-line options recognized by txt2img, img2img accepts
additional options:
| Argument <img width="160" align="right"/> | Shortcut | Default | Description |
| ----------------------------------------- | ----------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `--init_img <path>` | `-I<path>` | `None` | Path to the initialization image |
| `--fit` | `-F` | `False` | Scale the image to fit into the specified -H and -W dimensions |
| `--strength <float>` | `-s<float>` | `0.75` | How hard to try to match the prompt to the initial image. Ranges from 0.0-0.99, with higher values replacing the initial image completely. |
### inpainting
!!! example ""
```bash
invoke> waterfall and rainbow -I./vacation-photo.png -M./vacation-mask.png -W640 -H480 --fit
```
This will do the same thing as img2img, but image alterations will
only occur within transparent areas defined by the mask file specified
by `-M`. You may also supply just a single initial image with the areas
to overpaint made transparent, but you must be careful not to destroy
the pixels underneath when you create the transparent areas. See
[Inpainting](INPAINTING.md) for details.
inpainting accepts all the arguments used for txt2img and img2img, as well as
the --mask (-M) and --text_mask (-tm) arguments:
| Argument <img width="100" align="right"/> | Shortcut | Default | Description |
| ----------------------------------------- | ------------------------ | ------- | ------------------------------------------------------------------------------------------------ |
| `--init_mask <path>` | `-M<path>` | `None` | Path to an image the same size as the initial_image, with areas for inpainting made transparent. |
| `--invert_mask ` | | False | If true, invert the mask so that transparent areas are opaque and vice versa. |
| `--text_mask <prompt> [<float>]` | `-tm <prompt> [<float>]` | <none> | Create a mask from a text prompt describing part of the image |
The mask may either be an image with transparent areas, in which case the
inpainting will occur in the transparent areas only, or a black and white image,
in which case all black areas will be painted into.
`--text_mask` (short form `-tm`) is a way to generate a mask using a text
description of the part of the image to replace. For example, if you have an
image of a breakfast plate with a bagel, toast and scrambled eggs, you can
selectively mask the bagel and replace it with a piece of cake this way:
```bash
invoke> a piece of cake -I /path/to/breakfast.png -tm bagel
```
The algorithm uses <a
href="https://github.com/timojl/clipseg">clipseg</a> to classify different
regions of the image. The classifier puts out a confidence score for each region
it identifies. Generally regions that score above 0.5 are reliable, but if you
are getting too much or too little masking you can adjust the threshold down (to
get more mask), or up (to get less). In this example, by passing `-tm` a higher
value, we are insisting on a more stringent classification.
```bash
invoke> a piece of cake -I /path/to/breakfast.png -tm bagel 0.6
```
### Custom Styles and Subjects
You can load and use hundreds of community-contributed Textual
Inversion models just by typing the appropriate trigger phrase. Please
see [Concepts Library](../features/CONCEPTS.md) for more details.
## Other Commands
The CLI offers a number of commands that begin with "!".
### Postprocessing images
To postprocess a file using face restoration or upscaling, use the `!fix`
command.
#### `!fix`
This command runs a post-processor on a previously-generated image. It takes a
PNG filename or path and applies your choice of the `-U`, `-G`, or `--embiggen`
switches in order to fix faces or upscale. If you provide a filename, the script
will look for it in the current output directory. Otherwise you can provide a
full or partial path to the desired file.
Some examples:
!!! example "Upscale to 4X its original size and fix faces using codeformer"
```bash
invoke> !fix 0000045.4829112.png -G1 -U4 -ft codeformer
```
!!! example "Use the GFPGAN algorithm to fix faces, then upscale to 3X using --embiggen"
```bash
invoke> !fix 0000045.4829112.png -G0.8 -ft gfpgan
>> fixing outputs/img-samples/0000045.4829112.png
>> retrieved seed 4829112 and prompt "boy enjoying a banana split"
>> GFPGAN - Restoring Faces for image seed:4829112
Outputs:
[1] outputs/img-samples/000017.4829112.gfpgan-00.png: !fix "outputs/img-samples/0000045.4829112.png" -s 50 -S -W 512 -H 512 -C 7.5 -A k_lms -G 0.8
```
#### `!mask`
This command takes an image, a text prompt, and uses the `clipseg` algorithm to
automatically generate a mask of the area that matches the text prompt. It is
useful for debugging the text masking process prior to inpainting with the
`--text_mask` argument. See [INPAINTING.md] for details.
### Model selection and importation
The CLI allows you to add new models on the fly, as well as to switch
among them rapidly without leaving the script. There are several
different model formats, each described in the [Model Installation
Guide](../installation/050_INSTALLING_MODELS.md).
#### `!models`
This prints out a list of the models defined in `config/models.yaml'. The active
model is bold-faced
Example:
<pre>
inpainting-1.5 not loaded Stable Diffusion inpainting model
<b>stable-diffusion-1.5 active Stable Diffusion v1.5</b>
waifu-diffusion not loaded Waifu Diffusion v1.4
</pre>
#### `!switch <model>`
This quickly switches from one model to another without leaving the CLI script.
`invoke.py` uses a memory caching system; once a model has been loaded,
switching back and forth is quick. The following example shows this in action.
Note how the second column of the `!models` table changes to `cached` after a
model is first loaded, and that the long initialization step is not needed when
loading a cached model.
#### `!import_model <hugging_face_repo_ID>`
This imports and installs a `diffusers`-style model that is stored on
the [HuggingFace Web Site](https://huggingface.co). You can look up
any [Stable Diffusion diffusers
model](https://huggingface.co/models?library=diffusers) and install it
with a command like the following:
```bash
!import_model prompthero/openjourney
```
#### `!import_model <path/to/diffusers/directory>`
If you have a copy of a `diffusers`-style model saved to disk, you can
import it by passing the path to model's top-level directory.
#### `!import_model <url>`
For a `.ckpt` or `.safetensors` file, if you have a direct download
URL for the file, you can provide it to `!import_model` and the file
will be downloaded and installed for you.
#### `!import_model <path/to/model/weights.ckpt>`
This command imports a new model weights file into InvokeAI, makes it available
for image generation within the script, and writes out the configuration for the
model into `config/models.yaml` for use in subsequent sessions.
Provide `!import_model` with the path to a weights file ending in `.ckpt`. If
you type a partial path and press tab, the CLI will autocomplete. Although it
will also autocomplete to `.vae` files, these are not currenty supported (but
will be soon).
When you hit return, the CLI will prompt you to fill in additional information
about the model, including the short name you wish to use for it with the
`!switch` command, a brief description of the model, the default image width and
height to use with this model, and the model's configuration file. The latter
three fields are automatically filled with reasonable defaults. In the example
below, the bold-faced text shows what the user typed in with the exception of
the width, height and configuration file paths, which were filled in
automatically.
#### `!import_model <path/to/directory_of_models>`
If you provide the path of a directory that contains one or more
`.ckpt` or `.safetensors` files, the CLI will scan the directory and
interactively offer to import the models it finds there. Also see the
`--autoconvert` command-line option.
#### `!edit_model <name_of_model>`
The `!edit_model` command can be used to modify a model that is already defined
in `config/models.yaml`. Call it with the short name of the model you wish to
modify, and it will allow you to modify the model's `description`, `weights` and
other fields.
Example:
<pre>
invoke> <b>!edit_model waifu-diffusion</b>
>> Editing model waifu-diffusion from configuration file ./configs/models.yaml
description: <b>Waifu diffusion v1.4beta</b>
weights: models/ldm/stable-diffusion-v1/<b>model-epoch10-float16.ckpt</b>
config: configs/stable-diffusion/v1-inference.yaml
width: 512
height: 512
>> New configuration:
waifu-diffusion:
config: configs/stable-diffusion/v1-inference.yaml
description: Waifu diffusion v1.4beta
weights: models/ldm/stable-diffusion-v1/model-epoch10-float16.ckpt
height: 512
width: 512
OK to import [n]? y
>> Caching model stable-diffusion-1.4 in system RAM
>> Loading waifu-diffusion from models/ldm/stable-diffusion-v1/model-epoch10-float16.ckpt
...
</pre>
### History processing
The CLI provides a series of convenient commands for reviewing previous actions,
retrieving them, modifying them, and re-running them.
#### `!history`
The invoke script keeps track of all the commands you issue during a session,
allowing you to re-run them. On Mac and Linux systems, it also writes the
command-line history out to disk, giving you access to the most recent 1000
commands issued.
The `!history` command will return a numbered list of all the commands issued
during the session (Windows), or the most recent 1000 commands (Mac|Linux). You
can then repeat a command by using the command `!NNN`, where "NNN" is the
history line number. For example:
!!! example ""
```bash
invoke> !history
...
[14] happy woman sitting under tree wearing broad hat and flowing garment
[15] beautiful woman sitting under tree wearing broad hat and flowing garment
[18] beautiful woman sitting under tree wearing broad hat and flowing garment -v0.2 -n6
[20] watercolor of beautiful woman sitting under tree wearing broad hat and flowing garment -v0.2 -n6 -S2878767194
[21] surrealist painting of beautiful woman sitting under tree wearing broad hat and flowing garment -v0.2 -n6 -S2878767194
...
invoke> !20
invoke> watercolor of beautiful woman sitting under tree wearing broad hat and flowing garment -v0.2 -n6 -S2878767194
```
####`!fetch`
This command retrieves the generation parameters from a previously generated
image and either loads them into the command line (Linux|Mac), or prints them
out in a comment for copy-and-paste (Windows). You may provide either the name
of a file in the current output directory, or a full file path. Specify path to
a folder with image png files, and wildcard \*.png to retrieve the dream command
used to generate the images, and save them to a file commands.txt for further
processing.
!!! example "load the generation command for a single png file"
```bash
invoke> !fetch 0000015.8929913.png
# the script returns the next line, ready for editing and running:
invoke> a fantastic alien landscape -W 576 -H 512 -s 60 -A plms -C 7.5
```
!!! example "fetch the generation commands from a batch of files and store them into `selected.txt`"
```bash
invoke> !fetch outputs\selected-imgs\*.png selected.txt
```
#### `!replay`
This command replays a text file generated by !fetch or created manually
!!! example
```bash
invoke> !replay outputs\selected-imgs\selected.txt
```
!!! note
These commands may behave unexpectedly if given a PNG file that was
not generated by InvokeAI.
#### `!search <search string>`
This is similar to !history but it only returns lines that contain
`search string`. For example:
```bash
invoke> !search surreal
[21] surrealist painting of beautiful woman sitting under tree wearing broad hat and flowing garment -v0.2 -n6 -S2878767194
```
#### `!clear`
This clears the search history from memory and disk. Be advised that this
operation is irreversible and does not issue any warnings!
## Command-line editing and completion
The command-line offers convenient history tracking, editing, and command
completion.
- To scroll through previous commands and potentially edit/reuse them, use the
++up++ and ++down++ keys.
- To edit the current command, use the ++left++ and ++right++ keys to position
the cursor, and then ++backspace++, ++delete++ or insert characters.
- To move to the very beginning of the command, type ++ctrl+a++ (or
++command+a++ on the Mac)
- To move to the end of the command, type ++ctrl+e++.
- To cut a section of the command, position the cursor where you want to start
cutting and type ++ctrl+k++
- To paste a cut section back in, position the cursor where you want to paste,
and type ++ctrl+y++
Windows users can get similar, but more limited, functionality if they launch
`invoke.py` with the `winpty` program and have the `pyreadline3` library
installed:
```batch
> winpty python scripts\invoke.py
```
On the Mac and Linux platforms, when you exit invoke.py, the last 1000 lines of
your command-line history will be saved. When you restart `invoke.py`, you can
access the saved history using the ++up++ key.
In addition, limited command-line completion is installed. In various contexts,
you can start typing your command and press ++tab++. A list of potential
completions will be presented to you. You can then type a little more, hit
++tab++ again, and eventually autocomplete what you want.
When specifying file paths using the one-letter shortcuts, the CLI will attempt
to complete pathnames for you. This is most handy for the `-I` (init image) and
`-M` (init mask) paths. To initiate completion, start the path with a slash
(`/`) or `./`. For example:
```bash
invoke> zebra with a mustache -I./test-pictures<TAB>
-I./test-pictures/Lincoln-and-Parrot.png -I./test-pictures/zebra.jpg -I./test-pictures/madonna.png
-I./test-pictures/bad-sketch.png -I./test-pictures/man_with_eagle/
```
You can then type ++z++, hit ++tab++ again, and it will autofill to `zebra.jpg`.
More text completion features (such as autocompleting seeds) are on their way.

View File

@ -1,167 +0,0 @@
---
title: Embiggen
---
# :material-loupe: Embiggen
**upscale your images on limited memory machines**
GFPGAN and Real-ESRGAN are both memory intensive. In order to avoid
crashes and memory overloads during the Stable Diffusion process,
these effects are applied after Stable Diffusion has completed its
work.
In single image generations, you will see the output right away but
when you are using multiple iterations, the images will first be
generated and then upscaled and face restored after that process is
complete. While the image generation is taking place, you will still
be able to preview the base images.
If you wish to stop during the image generation but want to upscale or
face restore a particular generated image, pass it again with the same
prompt and generated seed along with the `-U` and `-G` prompt
arguments to perform those actions.
## Embiggen
If you wanted to be able to do more (pixels) without running out of VRAM,
or you want to upscale with details that couldn't possibly appear
without the context of a prompt, this is the feature to try out.
Embiggen automates the process of taking an init image, upscaling it,
cutting it into smaller tiles that slightly overlap, running all the
tiles through img2img to refine details with respect to the prompt,
and "stitching" the tiles back together into a cohesive image.
It automatically computes how many tiles are needed, and so it can be fed
*ANY* size init image and perform Img2Img on it (though it will be run only
one tile at a time, which can cause problems, see the Note at the end).
If you're familiar with "GoBig" (ala [progrock-stable](https://github.com/lowfuel/progrock-stable))
it's similar to that, except it can work up to an arbitrarily large size
(instead of just 2x), with tile overlaps configurable as a ratio, and
has extra logic to re-run any number of the tile sub-sections of the image
if for example a small part of a huge run got messed up.
### Usage
`-embiggen <scaling_factor> <esrgan_strength> <overlap_ratio OR overlap_pixels>`
Takes a scaling factor relative to the size of the `--init_img` (`-I`), followed by
ESRGAN upscaling strength (0 - 1.0), followed by minimum amount of overlap
between tiles as a decimal ratio (0 - 1.0) *OR* a number of pixels.
The scaling factor is how much larger than the `--init_img` the output
should be, and will multiply both x and y axis, so an image that is a
scaling factor of 3.0 has 3*3= 9 times as many pixels, and will take
(at least) 9 times as long (see overlap for why it might be
longer). If the `--init_img` is already the right size `-embiggen 1`,
and it can also be less than one if the init_img is too big.
Esrgan_strength defaults to 0.75, and the overlap_ratio defaults to
0.25, both are optional.
Unlike Img2Img, the `--width` (`-W`) and `--height` (`-H`) arguments
do not control the size of the image as a whole, but the size of the
tiles used to Embiggen the image.
ESRGAN is used to upscale the `--init_img` prior to cutting it into
tiles/pieces to run through img2img and then stitch back
together. Embiggen can be run without ESRGAN; just set the strength to
zero (e.g. `-embiggen 1.75 0`). The output of Embiggen can also be
upscaled after it's finished (`-U`).
The overlap is the minimum that tiles will overlap with adjacent
tiles, specified as either a ratio or a number of pixels. How much the
tiles overlap determines the likelihood the tiling will be noticable,
really small overlaps (e.g. a couple of pixels) may produce noticeable
grid-like fuzzy distortions in the final stitched image. Though, as
the overlapping space doesn't contribute to making the image bigger,
and the larger the overlap the more tiles (and the more time) it will
take to finish.
Because the overlapping parts of tiles don't "contribute" to
increasing size, every tile after the first in a row or column
effectively only covers an extra `1 - overlap_ratio` on each axis. If
the input/`--init_img` is same size as a tile, the ideal (for time)
scaling factors with the default overlap (0.25) are 1.75, 2.5, 3.25,
4.0, etc.
`-embiggen_tiles <spaced list of tiles>`
An advanced usage useful if you only want to alter parts of the image
while running Embiggen. It takes a list of tiles by number to run and
replace onto the initial image e.g. `1 3 5`. It's useful for either
fixing problem spots from a previous Embiggen run, or selectively
altering the prompt for sections of an image - for creative or
coherency reasons.
Tiles are numbered starting with one, and left-to-right,
top-to-bottom. So, if you are generating a 3x3 tiled image, the
middle row would be `4 5 6`.
`-embiggen_strength <strength>`
Another advanced option if you want to experiment with the strength parameter
that embiggen uses when it calls Img2Img. Values range from 0.0 to 1.0
and lower values preserve more of the character of the initial image.
Values that are too high will result in a completely different end image,
while values that are too low will result in an image not dissimilar to one
you would get with ESRGAN upscaling alone. The default value is 0.4.
### Examples
!!! example ""
Running Embiggen with 512x512 tiles on an existing image, scaling up by a factor of 2.5x;
and doing the same again (default ESRGAN strength is 0.75, default overlap between tiles is 0.25):
```bash
invoke > a photo of a forest at sunset -s 100 -W 512 -H 512 -I outputs/forest.png -f 0.4 -embiggen 2.5
invoke > a photo of a forest at sunset -s 100 -W 512 -H 512 -I outputs/forest.png -f 0.4 -embiggen 2.5 0.75 0.25
```
If your starting image was also 512x512 this should have taken 9 tiles.
!!! example ""
If there weren't enough clouds in the sky of that forest you just made
(and that image is about 1280 pixels (512*2.5) wide A.K.A. three
512x512 tiles with 0.25 overlaps wide) we can replace that top row of
tiles:
```bash
invoke> a photo of puffy clouds over a forest at sunset -s 100 -W 512 -H 512 -I outputs/000002.seed.png -f 0.5 -embiggen_tiles 1 2 3
```
## Fixing Previously-Generated Images
It is easy to apply embiggen to any previously-generated file without having to
look up the original prompt and provide an initial image. Just use the
syntax `!fix path/to/file.png <embiggen>`. For example, you can rewrite the
previous command to look like this:
```bash
invoke> !fix ./outputs/000002.seed.png -embiggen_tiles 1 2 3
```
A new file named `000002.seed.fixed.png` will be created in the output directory. Note that
the `!fix` command does not replace the original file, unlike the behavior at generate time.
You do not need to provide the prompt, and `!fix` automatically selects a good strength for
embiggen-ing.
!!! note
Because the same prompt is used on all the tiled images, and the model
doesn't have the context of anything outside the tile being run - it
can end up creating repeated pattern (also called 'motifs') across all
the tiles based on that prompt. The best way to combat this is
lowering the `--strength` (`-f`) to stay more true to the init image,
and increasing the number of steps so there is more compute-time to
create the detail. Anecdotally `--strength` 0.35-0.45 works pretty
well on most things. It may also work great in some examples even with
the `--strength` set high for patterns, landscapes, or subjects that
are more abstract. Because this is (relatively) fast, you can also
preserve the best parts from each.
Author: [Travco](https://github.com/travco)

View File

@ -1,310 +0,0 @@
---
title: Inpainting
---
# :octicons-paintbrush-16: Inpainting
## **Creating Transparent Regions for Inpainting**
Inpainting is really cool. To do it, you start with an initial image and use a
photoeditor to make one or more regions transparent (i.e. they have a "hole" in
them). You then provide the path to this image at the dream> command line using
the `-I` switch. Stable Diffusion will only paint within the transparent region.
There's a catch. In the current implementation, you have to prepare the initial
image correctly so that the underlying colors are preserved under the
transparent area. Many imaging editing applications will by default erase the
color information under the transparent pixels and replace them with white or
black, which will lead to suboptimal inpainting. It often helps to apply
incomplete transparency, such as any value between 1 and 99%
You also must take care to export the PNG file in such a way that the color
information is preserved. There is often an option in the export dialog that
lets you specify this.
If your photoeditor is erasing the underlying color information, `dream.py` will
give you a big fat warning. If you can't find a way to coax your photoeditor to
retain color values under transparent areas, then you can combine the `-I` and
`-M` switches to provide both the original unedited image and the masked
(partially transparent) image:
```bash
invoke> "man with cat on shoulder" -I./images/man.png -M./images/man-transparent.png
```
## **Masking using Text**
You can also create a mask using a text prompt to select the part of the image
you want to alter, using the [clipseg](https://github.com/timojl/clipseg)
algorithm. This works on any image, not just ones generated by InvokeAI.
The `--text_mask` (short form `-tm`) option takes two arguments. The first
argument is a text description of the part of the image you wish to mask (paint
over). If the text description contains a space, you must surround it with
quotation marks. The optional second argument is the minimum threshold for the
mask classifier's confidence score, described in more detail below.
To see how this works in practice, here's an image of a still life painting that
I got off the web.
<figure markdown>
![still life scaled](../assets/still-life-scaled.jpg)
</figure>
You can selectively mask out the orange and replace it with a baseball in this
way:
```bash
invoke> a baseball -I /path/to/still_life.png -tm orange
```
<figure markdown>
![](../assets/still-life-inpainted.png)
</figure>
The clipseg classifier produces a confidence score for each region it
identifies. Generally regions that score above 0.5 are reliable, but if you are
getting too much or too little masking you can adjust the threshold down (to get
more mask), or up (to get less). In this example, by passing `-tm` a higher
value, we are insisting on a tigher mask. However, if you make it too high, the
orange may not be picked up at all!
```bash
invoke> a baseball -I /path/to/breakfast.png -tm orange 0.6
```
The `!mask` command may be useful for debugging problems with the text2mask
feature. The syntax is `!mask /path/to/image.png -tm <text> <threshold>`
It will generate three files:
- The image with the selected area highlighted.
- it will be named XXXXX.<imagename>.<prompt>.selected.png
- The image with the un-selected area highlighted.
- it will be named XXXXX.<imagename>.<prompt>.deselected.png
- The image with the selected area converted into a black and white image
according to the threshold level
- it will be named XXXXX.<imagename>.<prompt>.masked.png
The `.masked.png` file can then be directly passed to the `invoke>` prompt in
the CLI via the `-M` argument. Do not attempt this with the `selected.png` or
`deselected.png` files, as they contain some transparency throughout the image
and will not produce the desired results.
Here is an example of how `!mask` works:
```bash
invoke> !mask ./test-pictures/curly.png -tm hair 0.5
>> generating masks from ./test-pictures/curly.png
>> Initializing clipseg model for text to mask inference
Outputs:
[941.1] outputs/img-samples/000019.curly.hair.deselected.png: !mask ./test-pictures/curly.png -tm hair 0.5
[941.2] outputs/img-samples/000019.curly.hair.selected.png: !mask ./test-pictures/curly.png -tm hair 0.5
[941.3] outputs/img-samples/000019.curly.hair.masked.png: !mask ./test-pictures/curly.png -tm hair 0.5
```
<figure markdown>
![curly](../assets/outpainting/curly.png)
<figcaption>Original image "curly.png"</figcaption>
</figure>
<figure markdown>
![curly hair selected](../assets/inpainting/000019.curly.hair.selected.png)
<figcaption>000019.curly.hair.selected.png</figcaption>
</figure>
<figure markdown>
![curly hair deselected](../assets/inpainting/000019.curly.hair.deselected.png)
<figcaption>000019.curly.hair.deselected.png</figcaption>
</figure>
<figure markdown>
![curly hair masked](../assets/inpainting/000019.curly.hair.masked.png)
<figcaption>000019.curly.hair.masked.png</figcaption>
</figure>
It looks like we selected the hair pretty well at the 0.5 threshold (which is
the default, so we didn't actually have to specify it), so let's have some fun:
```bash
invoke> medusa with cobras -I ./test-pictures/curly.png -M 000019.curly.hair.masked.png -C20
>> loaded input image of size 512x512 from ./test-pictures/curly.png
...
Outputs:
[946] outputs/img-samples/000024.801380492.png: "medusa with cobras" -s 50 -S 801380492 -W 512 -H 512 -C 20.0 -I ./test-pictures/curly.png -A k_lms -f 0.75
```
<figure markdown>
![](../assets/inpainting/000024.801380492.png)
</figure>
You can also skip the `!mask` creation step and just select the masked
region directly:
```bash
invoke> medusa with cobras -I ./test-pictures/curly.png -tm hair -C20
```
## Using the RunwayML inpainting model
The
[RunwayML Inpainting Model v1.5](https://huggingface.co/runwayml/stable-diffusion-inpainting)
is a specialized version of
[Stable Diffusion v1.5](https://huggingface.co/spaces/runwayml/stable-diffusion-v1-5)
that contains extra channels specifically designed to enhance inpainting and
outpainting. While it can do regular `txt2img` and `img2img`, it really shines
when filling in missing regions. It has an almost uncanny ability to blend the
new regions with existing ones in a semantically coherent way.
To install the inpainting model, follow the
[instructions](../installation/050_INSTALLING_MODELS.md) for installing a new model.
You may use either the CLI (`invoke.py` script) or directly edit the
`configs/models.yaml` configuration file to do this. The main thing to watch out
for is that the the model `config` option must be set up to use
`v1-inpainting-inference.yaml` rather than the `v1-inference.yaml` file that is
used by Stable Diffusion 1.4 and 1.5.
After installation, your `models.yaml` should contain an entry that looks like
this one:
```yml
inpainting-1.5:
weights: models/ldm/stable-diffusion-v1/sd-v1-5-inpainting.ckpt
description: SD inpainting v1.5
config: configs/stable-diffusion/v1-inpainting-inference.yaml
vae: models/ldm/stable-diffusion-v1/vae-ft-mse-840000-ema-pruned.ckpt
width: 512
height: 512
```
As shown in the example, you may include a VAE fine-tuning weights file as well.
This is strongly recommended.
To use the custom inpainting model, launch `invoke.py` with the argument
`--model inpainting-1.5` or alternatively from within the script use the
`!switch inpainting-1.5` command to load and switch to the inpainting model.
You can now do inpainting and outpainting exactly as described above, but there
will (likely) be a noticeable improvement in coherence. Txt2img and Img2img will
work as well.
There are a few caveats to be aware of:
1. The inpainting model is larger than the standard model, and will use nearly 4
GB of GPU VRAM. This makes it unlikely to run on a 4 GB graphics card.
2. When operating in Img2img mode, the inpainting model is much less steerable
than the standard model. It is great for making small changes, such as
changing the pattern of a fabric, or slightly changing a subject's expression
or hair, but the model will resist making the dramatic alterations that the
standard model lets you do.
3. While the `--hires` option works fine with the inpainting model, some special
features, such as `--embiggen` are disabled.
4. Prompt weighting (`banana++ sushi`) and merging work well with the inpainting
model, but prompt swapping
(`a ("fluffy cat").swap("smiling dog") eating a hotdog`) will not have any
effect due to the way the model is set up. You may use text masking (with
`-tm thing-to-mask`) as an effective replacement.
5. The model tends to oversharpen image if you use high step or CFG values. If
you need to do large steps, use the standard model.
6. The `--strength` (`-f`) option has no effect on the inpainting model due to
its fundamental differences with the standard model. It will always take the
full number of steps you specify.
## Troubleshooting
Here are some troubleshooting tips for inpainting and outpainting.
## Inpainting is not changing the masked region enough!
One of the things to understand about how inpainting works is that it is
equivalent to running img2img on just the masked (transparent) area. img2img
builds on top of the existing image data, and therefore will attempt to preserve
colors, shapes and textures to the best of its ability. Unfortunately this means
that if you want to make a dramatic change in the inpainted region, for example
replacing a red wall with a blue one, the algorithm will fight you.
You have a couple of options. The first is to increase the values of the
requested steps (`-sXXX`), strength (`-f0.XX`), and/or condition-free guidance
(`-CXX.X`). If this is not working for you, a more extreme step is to provide
the `--inpaint_replace 0.X` (`-r0.X`) option. This value ranges from 0.0 to 1.0.
The higher it is the less attention the algorithm will pay to the data
underneath the masked region. At high values this will enable you to replace
colored regions entirely, but beware that the masked region mayl not blend in
with the surrounding unmasked regions as well.
---
## Recipe for GIMP
[GIMP](https://www.gimp.org/) is a popular Linux photoediting tool.
1. Open image in GIMP.
2. Layer->Transparency->Add Alpha Channel
3. Use lasso tool to select region to mask
4. Choose Select -> Float to create a floating selection
5. Open the Layers toolbar (^L) and select "Floating Selection"
6. Set opacity to a value between 0% and 99%
7. Export as PNG
8. In the export dialogue, Make sure the "Save colour values from transparent
pixels" checkbox is selected.
---
## Recipe for Adobe Photoshop
1. Open image in Photoshop
<figure markdown>
![step1](../assets/step1.png)
</figure>
2. Use any of the selection tools (Marquee, Lasso, or Wand) to select the area
you desire to inpaint.
<figure markdown>
![step2](../assets/step2.png)
</figure>
3. Because we'll be applying a mask over the area we want to preserve, you
should now select the inverse by using the ++shift+ctrl+i++ shortcut, or
right clicking and using the "Select Inverse" option.
4. You'll now create a mask by selecting the image layer, and Masking the
selection. Make sure that you don't delete any of the underlying image, or
your inpainting results will be dramatically impacted.
<figure markdown>
![step4](../assets/step4.png)
</figure>
5. Make sure to hide any background layers that are present. You should see the
mask applied to your image layer, and the image on your canvas should display
the checkered background.
<figure markdown>
![step5](../assets/step5.png)
</figure>
6. Save the image as a transparent PNG by using `File`-->`Save a Copy` from the
menu bar, or by using the keyboard shortcut ++alt+ctrl+s++
<figure markdown>
![step6](../assets/step6.png)
</figure>
7. After following the inpainting instructions above (either through the CLI or
the Web UI), marvel at your newfound ability to selectively invoke. Lookin'
good!
<figure markdown>
![step7](../assets/step7.png)
</figure>
8. In the export dialogue, Make sure the "Save colour values from transparent
pixels" checkbox is selected.

View File

@ -1,171 +0,0 @@
---
title: Outpainting
---
# :octicons-paintbrush-16: Outpainting
## Outpainting and outcropping
Outpainting is a process by which the AI generates parts of the image that are
outside its original frame. It can be used to fix up images in which the subject
is off center, or when some detail (often the top of someone's head!) is cut
off.
InvokeAI supports two versions of outpainting, one called "outpaint" and the
other "outcrop." They work slightly differently and each has its advantages and
drawbacks.
### Outpainting
Outpainting is the same as inpainting, except that the painting occurs in the
regions outside of the original image. To outpaint using the `invoke.py` command
line script, prepare an image in which the borders to be extended are pure
black. Add an alpha channel (if there isn't one already), and make the borders
completely transparent and the interior completely opaque. If you wish to modify
the interior as well, you may create transparent holes in the transparency
layer, which `img2img` will paint into as usual.
Pass the image as the argument to the `-I` switch as you would for regular
inpainting:
```bash
invoke> a stream by a river -I /path/to/transparent_img.png
```
You'll likely be delighted by the results.
### Tips
1. Do not try to expand the image too much at once. Generally it is best to
expand the margins in 64-pixel increments. 128 pixels often works, but your
mileage may vary depending on the nature of the image you are trying to
outpaint into.
2. There are a series of switches that can be used to adjust how the inpainting
algorithm operates. In particular, you can use these to minimize the seam
that sometimes appears between the original image and the extended part.
These switches are:
| switch | default | description |
| -------------------------- | ------- | ---------------------------------------------------------------------- |
| `--seam_size SEAM_SIZE ` | `0` | Size of the mask around the seam between original and outpainted image |
| `--seam_blur SEAM_BLUR` | `0` | The amount to blur the seam inwards |
| `--seam_strength STRENGTH` | `0.7` | The img2img strength to use when filling the seam |
| `--seam_steps SEAM_STEPS` | `10` | The number of steps to use to fill the seam. |
| `--tile_size TILE_SIZE` | `32` | The tile size to use for filling outpaint areas |
### Outcrop
The `outcrop` extension gives you a convenient `!fix` postprocessing command
that allows you to extend a previously-generated image in 64 pixel increments in
any direction. You can apply the module to any image previously-generated by
InvokeAI. Note that it works with arbitrary PNG photographs, but not currently
with JPG or other formats. Outcropping is particularly effective when combined
with the
[runwayML custom inpainting model](INPAINTING.md#using-the-runwayml-inpainting-model).
Consider this image:
<figure markdown>
![curly_woman](../assets/outpainting/curly.png)
</figure>
Pretty nice, but it's annoying that the top of her head is cut off. She's also a
bit off center. Let's fix that!
```bash
invoke> !fix images/curly.png --outcrop top 128 right 64 bottom 64
```
This is saying to apply the `outcrop` extension by extending the top of the
image by 128 pixels, and the right and bottom of the image by 64 pixels. You can
use any combination of top|left|right|bottom, and specify any number of pixels
to extend. You can also abbreviate `--outcrop` to `-c`.
The result looks like this:
<figure markdown>
![curly_woman_outcrop](../assets/outpainting/curly-outcrop-2.png)
</figure>
The new image is larger than the original (576x704) because 64 pixels were added
to the top and right sides. You will need enough VRAM to process an image of
this size.
#### Outcropping non-InvokeAI images
You can outcrop an arbitrary image that was not generated by InvokeAI,
but your results will vary. The `inpainting-1.5` model is highly
recommended, but if not feasible, then you may be able to improve the
output by conditioning the outcropping with a text prompt that
describes the scene using the `--new_prompt` argument:
```bash
invoke> !fix images/vacation.png --outcrop top 128 --new_prompt "family vacation"
```
You may also provide a different seed for outcropping to use by passing
`-S<seed>`. A negative seed will generate a new random seed.
A number of caveats:
1. Although you can specify any pixel values, they will be rounded up to the
nearest multiple of 64. Smaller values are better. Larger extensions are more
likely to generate artefacts. However, if you wish you can run the !fix
command repeatedly to cautiously expand the image.
2. The extension is stochastic, meaning that each time you run it you'll get a
slightly different result. You can run it repeatedly until you get an image
you like. Unfortunately `!fix` does not currently respect the `-n`
(`--iterations`) argument.
3. Your results will be _much_ better if you use the `inpaint-1.5` model
released by runwayML and installed by default by `invokeai-configure`.
This model was trained specifically to harmoniously fill in image gaps. The
standard model will work as well, but you may notice color discontinuities at
the border.
4. When using the `inpaint-1.5` model, you may notice subtle changes to the area
outside the masked region. This is because the model performs an
encoding/decoding on the image as a whole. This does not occur with the
standard model.
## Outpaint
The `outpaint` extension does the same thing, but with subtle differences.
Starting with the same image, here is how we would add an additional 64 pixels
to the top of the image:
```bash
invoke> !fix images/curly.png --out_direction top 64
```
(you can abbreviate `--out_direction` as `-D`.
The result is shown here:
<figure markdown>
![curly_woman_outpaint](../assets/outpainting/curly-outpaint.png)
</figure>
Although the effect is similar, there are significant differences from
outcropping:
- You can only specify one direction to extend at a time.
- The image is **not** resized. Instead, the image is shifted by the specified
number of pixels. If you look carefully, you'll see that less of the lady's
torso is visible in the image.
- Because the image dimensions remain the same, there's no rounding to multiples
of 64.
- Attempting to outpaint larger areas will frequently give rise to ugly ghosting
effects.
- For best results, try increasing the step number.
- If you don't specify a pixel value in `-D`, it will default to half of the
whole image, which is likely not what you want.
!!! tip
Neither `outpaint` nor `outcrop` are perfect, but we continue to tune
and improve them. If one doesn't work, try the other. You may also
wish to experiment with other `img2img` arguments, such as `-C`, `-f`
and `-s`.

View File

@ -1,19 +0,0 @@
# Translation
InvokeAI uses [Weblate](https://weblate.org) for translation. Weblate is a FOSS project providing a scalable translation service. Weblate automates the tedious parts of managing translation of a growing project, and the service is generously provided at no cost to FOSS projects like InvokeAI.
## Contributing
If you'd like to contribute by adding or updating a translation, please visit our [Weblate project](https://hosted.weblate.org/engage/invokeai/). You'll need to sign in with your GitHub account (a number of other accounts are supported, including Google).
Once signed in, select a language and then the Web UI component. From here you can Browse and Translate strings from English to your chosen language. Zen mode offers a simpler translation experience.
Your changes will be attributed to you in the automated PR process; you don't need to do anything else.
## Help & Questions
Please check Weblate's [documentation](https://docs.weblate.org/en/latest/index.html) or ping @psychedelicious or @blessedcoolant on Discord if you have any questions.
## Thanks
Thanks to the InvokeAI community for their efforts to translate the project!

View File

@ -1,131 +0,0 @@
---
title: Variations
---
# :material-tune-variant: Variations
## Intro
InvokeAI's support for variations enables you to do the following:
1. Generate a series of systematic variations of an image, given a prompt. The
amount of variation from one image to the next can be controlled.
2. Given two or more variations that you like, you can combine them in a
weighted fashion.
!!! Information ""
This cheat sheet provides a quick guide for how this works in practice, using
variations to create the desired image of Xena, Warrior Princess.
## Step 1 -- Find a base image that you like
The prompt we will use throughout is:
`#!bash "lucy lawless as xena, warrior princess, character portrait, high resolution."`
This will be indicated as `#!bash "prompt"` in the examples below.
First we let SD create a series of images in the usual way, in this case
requesting six iterations.
<figure markdown>
![var1](../assets/variation_walkthru/000001.3357757885.png)
<figcaption> Seed 3357757885 looks nice </figcaption>
</figure>
---
## Step 2 - Generating Variations
Let's try to generate some variations on this image. We select the "*"
symbol in the line of icons above the image in order to fix the prompt
and seed. Then we open up the "Variations" section of the generation
panel and use the slider to set the variation amount to 0.2. The
higher this value, the more each generated image will differ from the
previous one.
Now we run the prompt a second time, requesting six iterations. You
will see six images that are thematically related to each other. Try
increasing and decreasing the variation amount and see what happens.
### **Variation Sub Seeding**
Note that the output for each image has a `-V` option giving the "variant
subseed" for that image, consisting of a seed followed by the variation amount
used to generate it.
This gives us a series of closely-related variations, including the two shown
here.
<figure markdown>
![var2](../assets/variation_walkthru/000002.3647897225.png)
<figcaption>subseed 3647897225</figcaption>
</figure>
<figure markdown>
![var3](../assets/variation_walkthru/000002.1614299449.png)
<figcaption>subseed 1614299449</figcaption>
</figure>
I like the expression on Xena's face in the first one (subseed 3647897225), and
the armor on her shoulder in the second one (subseed 1614299449). Can we combine
them to get the best of both worlds?
We combine the two variations using `-V` (`--with_variations`). Again, we must
provide the seed for the originally-chosen image in order for this to work.
```bash
invoke> "prompt" -S3357757885 -V3647897225,0.1,1614299449,0.1
Outputs:
./outputs/Xena/000003.1614299449.png: "prompt" -s50 -W512 -H512 -C7.5 -Ak_lms -V 3647897225:0.1,1614299449:0.1 -S3357757885
```
Here we are providing equal weights (0.1 and 0.1) for both the subseeds. The
resulting image is close, but not exactly what I wanted:
<figure markdown>
![var4](../assets/variation_walkthru/000003.1614299449.png)
<figcaption> subseed 1614299449 </figcaption>
</figure>
We could either try combining the images with different weights, or we can
generate more variations around the almost-but-not-quite image. We do the
latter, using both the `-V` (combining) and `-v` (variation strength) options.
Note that we use `-n6` to generate 6 variations:
```bash
invoke> "prompt" -S3357757885 -V3647897225,0.1,1614299449,0.1 -v0.05 -n6
Outputs:
./outputs/Xena/000004.3279757577.png: "prompt" -s50 -W512 -H512 -C7.5 -Ak_lms -V 3647897225:0.1,1614299449:0.1,3279757577:0.05 -S3357757885
./outputs/Xena/000004.2853129515.png: "prompt" -s50 -W512 -H512 -C7.5 -Ak_lms -V 3647897225:0.1,1614299449:0.1,2853129515:0.05 -S3357757885
./outputs/Xena/000004.3747154981.png: "prompt" -s50 -W512 -H512 -C7.5 -Ak_lms -V 3647897225:0.1,1614299449:0.1,3747154981:0.05 -S3357757885
./outputs/Xena/000004.2664260391.png: "prompt" -s50 -W512 -H512 -C7.5 -Ak_lms -V 3647897225:0.1,1614299449:0.1,2664260391:0.05 -S3357757885
./outputs/Xena/000004.1642517170.png: "prompt" -s50 -W512 -H512 -C7.5 -Ak_lms -V 3647897225:0.1,1614299449:0.1,1642517170:0.05 -S3357757885
./outputs/Xena/000004.2183375608.png: "prompt" -s50 -W512 -H512 -C7.5 -Ak_lms -V 3647897225:0.1,1614299449:0.1,2183375608:0.05 -S3357757885
```
This produces six images, all slight variations on the combination of the chosen
two images. Here's the one I like best:
<figure markdown>
![var5](../assets/variation_walkthru/000004.3747154981.png)
<figcaption> subseed 3747154981 </figcaption>
</figure>
As you can see, this is a very powerful tool, which when combined with subprompt
weighting, gives you great control over the content and quality of your
generated images.
## Variations and Samplers
The sampler you choose has a strong effect on variation strength. Some
samplers, such as `k_euler_a` are very "creative" and produce significant
amounts of image-to-image variation even when the seed is fixed and the
`-v` argument is very low. Others are more deterministic. Feel free to
experiment until you find the combination that you like.
Also be aware of the [Perlin Noise](../features/OTHER.md#thresholding-and-perlin-noise-initialization-options)
feature, which provides another way of introducing variability into your
image generation requests.

View File

@ -6,259 +6,151 @@ title: Configuration
## Intro
InvokeAI has numerous runtime settings which can be used to adjust
many aspects of its operations, including the location of files and
directories, memory usage, and performance. These settings can be
viewed and customized in several ways:
Runtime settings, including the location of files and
directories, memory usage, and performance, are managed via the
`invokeai.yaml` config file or environment variables. A subset
of settings may be set via commandline arguments.
1. By editing settings in the `invokeai.yaml` file.
2. By setting environment variables.
3. On the command-line, when InvokeAI is launched.
Settings sources are used in this order:
In addition, the most commonly changed settings are accessible
graphically via the `invokeai-configure` script.
- CLI args
- Environment variables
- `invokeai.yaml` settings
- Fallback: defaults
### How the Configuration System Works
### InvokeAI Root Directory
When InvokeAI is launched, the very first thing it needs to do is to
find its "root" directory, which contains its configuration files,
installed models, its database of images, and the folder(s) of
generated images themselves. In this document, the root directory will
be referred to as ROOT.
On startup, InvokeAI searches for its "root" directory. This is the directory
that contains models, images, the database, and so on. It also contains
a configuration file called `invokeai.yaml`.
#### Finding the Root Directory
InvokeAI searches for the root directory in this order:
To find its root directory, InvokeAI uses the following recipe:
1. The `--root <path>` CLI arg.
2. The environment variable INVOKEAI_ROOT.
3. The directory containing the currently active virtual environment.
4. Fallback: a directory in the current user's home directory named `invokeai`.
1. It first looks for the argument `--root <path>` on the command line
it was launched from, and uses the indicated path if present.
### InvokeAI Configuration File
2. Next it looks for the environment variable INVOKEAI_ROOT, and uses
the directory path found there if present.
Inside the root directory, we read settings from the `invokeai.yaml` file.
3. If neither of these are present, then InvokeAI looks for the
folder containing the `.venv` Python virtual environment directory for
the currently active environment. This directory is checked for files
expected inside the InvokeAI root before it is used.
It has two sections - one for internal use and one for user settings:
4. Finally, InvokeAI looks for a directory in the current user's home
directory named `invokeai`.
```yaml
# Internal metadata - do not edit:
schema_version: 4
#### Reading the InvokeAI Configuration File
Once the root directory has been located, InvokeAI looks for a file
named `ROOT/invokeai.yaml`, and if present reads configuration values
from it. The top of this file looks like this:
```
InvokeAI:
Web Server:
host: localhost
port: 9090
allow_origins: []
allow_credentials: true
allow_methods:
- '*'
allow_headers:
- '*'
Features:
esrgan: true
internet_available: true
log_tokenization: false
patchmatch: true
restore: true
...
# Put user settings here - see https://invoke-ai.github.io/InvokeAI/features/CONFIGURATION/:
host: 0.0.0.0 # serve the app on your local network
models_dir: D:\invokeai\models # store models on an external drive
precision: float16 # always use fp16 precision
```
This lines in this file are used to establish default values for
Invoke's settings. In the above fragment, the Web Server's listening
port is set to 9090 by the `port` setting.
The settings in this file will override the defaults. You only need
to change this file if the default for a particular setting doesn't
work for you.
You can edit this file with a text editor such as "Notepad" (do not
use Word or any other word processor). When editing, be careful to
maintain the indentation, and do not add extraneous text, as syntax
errors will prevent InvokeAI from launching. A basic guide to the
format of YAML files can be found
[here](https://circleci.com/blog/what-is-yaml-a-beginner-s-guide/).
You'll find an example file next to `invokeai.yaml` that shows the default values.
You can fix a broken `invokeai.yaml` by deleting it and running the
configuration script again -- option [6] in the launcher, "Re-run the
configure script".
Some settings, like [Model Marketplace API Keys], require the YAML
to be formatted correctly. Here is a [basic guide to YAML files].
#### Reading Environment Variables
#### Custom Config File Location
Next InvokeAI looks for defined environment variables in the format
`INVOKEAI_<setting_name>`, for example `INVOKEAI_port`. Environment
variable values take precedence over configuration file variables. On
a Macintosh system, for example, you could change the port that the
web server listens on by setting the environment variable this way:
You can use any config file with the `--config` CLI arg. Pass in the path to the `invokeai.yaml` file you want to use.
```
export INVOKEAI_port=8000
invokeai-web
Note that environment variables will trump any settings in the config file.
### Environment Variables
All settings may be set via environment variables by prefixing `INVOKEAI_`
to the variable name. For example, `INVOKEAI_HOST` would set the `host`
setting.
For non-primitive values, pass a JSON-encoded string:
```sh
export INVOKEAI_REMOTE_API_TOKENS='[{"url_regex":"modelmarketplace", "token": "12345"}]'
```
Please check out these
[Macintosh](https://phoenixnap.com/kb/set-environment-variable-mac)
and
[Windows](https://phoenixnap.com/kb/windows-set-environment-variable)
guides for setting temporary and permanent environment variables.
We suggest using `invokeai.yaml`, as it is more user-friendly.
#### Reading the Command Line
### CLI Args
Lastly, InvokeAI takes settings from the command line, which override
everything else. The command-line settings have the same name as the
corresponding configuration file settings, preceded by a `--`, for
example `--port 8000`.
A subset of settings may be specified using CLI args:
If you are using the launcher (`invoke.sh` or `invoke.bat`) to launch
InvokeAI, then just pass the command-line arguments to the launcher:
- `--root`: specify the root directory
- `--config`: override the default `invokeai.yaml` file location
```
invoke.bat --port 8000 --host 0.0.0.0
### All Settings
Following the table are additional explanations for certain settings.
<!-- prettier-ignore-start -->
::: invokeai.app.services.config.config_default.InvokeAIAppConfig
options:
heading_level: 4
members: false
show_docstring_description: false
group_by_category: true
show_category_heading: false
<!-- prettier-ignore-end -->
#### Model Marketplace API Keys
Some model marketplaces require an API key to download models. You can provide a URL pattern and appropriate token in your `invokeai.yaml` file to provide that API key.
The pattern can be any valid regex (you may need to surround the pattern with quotes):
```yaml
remote_api_tokens:
# Any URL containing `models.com` will automatically use `your_models_com_token`
- url_regex: models.com
token: your_models_com_token
# Any URL matching this contrived regex will use `some_other_token`
- url_regex: '^[a-z]{3}whatever.*\.com$'
token: some_other_token
```
The arguments will be applied when you select the web server option
(and the other options as well).
The provided token will be added as a `Bearer` token to the network requests to download the model files. As far as we know, this works for all model marketplaces that require authorization.
If, on the other hand, you prefer to launch InvokeAI directly from the
command line, you would first activate the virtual environment (known
as the "developer's console" in the launcher), and run `invokeai-web`:
#### Model Hashing
```
> C:\Users\Fred\invokeai\.venv\scripts\activate
(.venv) > invokeai-web --port 8000 --host 0.0.0.0
Models are hashed during installation, providing a stable identifier for models across all platforms. Hashing is a one-time operation.
```yaml
hashing_algorithm: blake3_single # default value
```
You can get a listing and brief instructions for each of the
command-line options by giving the `--help` argument:
You might want to change this setting, depending on your system:
```
(.venv) > invokeai-web --help
usage: InvokeAI [-h] [--host HOST] [--port PORT] [--allow_origins [ALLOW_ORIGINS ...]] [--allow_credentials | --no-allow_credentials] [--allow_methods [ALLOW_METHODS ...]]
[--allow_headers [ALLOW_HEADERS ...]] [--esrgan | --no-esrgan] [--internet_available | --no-internet_available] [--log_tokenization | --no-log_tokenization]
[--patchmatch | --no-patchmatch] [--restore | --no-restore]
[--always_use_cpu | --no-always_use_cpu] [--free_gpu_mem | --no-free_gpu_mem] [--max_loaded_models MAX_LOADED_MODELS] [--max_cache_size MAX_CACHE_SIZE]
[--max_vram_cache_size MAX_VRAM_CACHE_SIZE] [--gpu_mem_reserved GPU_MEM_RESERVED] [--precision {auto,float16,float32,autocast}]
[--sequential_guidance | --no-sequential_guidance] [--xformers_enabled | --no-xformers_enabled] [--tiled_decode | --no-tiled_decode] [--root ROOT]
[--autoimport_dir AUTOIMPORT_DIR] [--lora_dir LORA_DIR] [--embedding_dir EMBEDDING_DIR] [--controlnet_dir CONTROLNET_DIR] [--conf_path CONF_PATH]
[--models_dir MODELS_DIR] [--legacy_conf_dir LEGACY_CONF_DIR] [--db_dir DB_DIR] [--outdir OUTDIR] [--from_file FROM_FILE]
[--use_memory_db | --no-use_memory_db] [--model MODEL] [--log_handlers [LOG_HANDLERS ...]] [--log_format {plain,color,syslog,legacy}]
[--log_level {debug,info,warning,error,critical}] [--version | --no-version]
```
- `blake3_single` (default): Single-threaded - best for spinning HDDs, still OK for SSDs
- `blake3_multi`: Parallelized, memory-mapped implementation - best for SSDs, terrible for spinning disks
- `random`: Skip hashing entirely - fastest but of course no hash
## The Configuration Settings
During the first startup after upgrading to v4, all of your models will be hashed. This can take a few minutes.
The configuration settings are divided into several distinct
groups in `invokeia.yaml`:
Most common algorithms are supported, like `md5`, `sha256`, and `sha512`. These are typically much, much slower than either of the BLAKE3 variants.
### Web Server
#### Path Settings
| Setting | Default Value | Description |
|---------------------|---------------|----------------------------------------------------------------------------------------------------------------------------|
| `host` | `localhost` | Name or IP address of the network interface that the web server will listen on |
| `port` | `9090` | Network port number that the web server will listen on |
| `allow_origins` | `[]` | A list of host names or IP addresses that are allowed to connect to the InvokeAI API in the format `['host1','host2',...]` |
| `allow_credentials` | `true` | Require credentials for a foreign host to access the InvokeAI API (don't change this) |
| `allow_methods` | `*` | List of HTTP methods ("GET", "POST") that the web server is allowed to use when accessing the API |
| `allow_headers` | `*` | List of HTTP headers that the web server will accept when accessing the API |
| `ssl_certfile` | null | Path to an SSL certificate file, used to enable HTTPS. |
| `ssl_keyfile` | null | Path to an SSL keyfile, if the key is not included in the certificate file. |
These options set the paths of various directories and files used by InvokeAI. Any user-defined paths should be absolute paths.
The documentation for InvokeAI's API can be accessed by browsing to the following URL: [http://localhost:9090/docs].
### Features
These configuration settings allow you to enable and disable various InvokeAI features:
| Setting | Default Value | Description |
|----------|----------------|--------------|
| `esrgan` | `true` | Activate the ESRGAN upscaling options|
| `internet_available` | `true` | When a resource is not available locally, try to fetch it via the internet |
| `log_tokenization` | `false` | Before each text2image generation, print a color-coded representation of the prompt to the console; this can help understand why a prompt is not working as expected |
| `patchmatch` | `true` | Activate the "patchmatch" algorithm for improved inpainting |
### Generation
These options tune InvokeAI's memory and performance characteristics.
| Setting | Default Value | Description |
|-----------------------|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `sequential_guidance` | `false` | Calculate guidance in serial rather than in parallel, lowering memory requirements at the cost of some performance loss |
| `attention_type` | `auto` | Select the type of attention to use. One of `auto`,`normal`,`xformers`,`sliced`, or `torch-sdp` |
| `attention_slice_size` | `auto` | When "sliced" attention is selected, set the slice size. One of `auto`, `balanced`, `max` or the integers 1-8|
| `force_tiled_decode` | `false` | Force the VAE step to decode in tiles, reducing memory consumption at the cost of performance |
### Device
These options configure the generation execution device.
| Setting | Default Value | Description |
|-----------------------|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `device` | `auto` | Preferred execution device. One of `auto`, `cpu`, `cuda`, `cuda:1`, `mps`. `auto` will choose the device depending on the hardware platform and the installed torch capabilities. |
| `precision` | `auto` | Floating point precision. One of `auto`, `float16` or `float32`. `float16` will consume half the memory of `float32` but produce slightly lower-quality images. The `auto` setting will guess the proper precision based on your video card and operating system |
### Paths
These options set the paths of various directories and files used by
InvokeAI. Relative paths are interpreted relative to INVOKEAI_ROOT, so
if INVOKEAI_ROOT is `/home/fred/invokeai` and the path is
`autoimport/main`, then the corresponding directory will be located at
`/home/fred/invokeai/autoimport/main`.
| Setting | Default Value | Description |
|----------|----------------|--------------|
| `autoimport_dir` | `autoimport/main` | At startup time, read and import any main model files found in this directory |
| `lora_dir` | `autoimport/lora` | At startup time, read and import any LoRA/LyCORIS models found in this directory |
| `embedding_dir` | `autoimport/embedding` | At startup time, read and import any textual inversion (embedding) models found in this directory |
| `controlnet_dir` | `autoimport/controlnet` | At startup time, read and import any ControlNet models found in this directory |
| `conf_path` | `configs/models.yaml` | Location of the `models.yaml` model configuration file |
| `models_dir` | `models` | Location of the directory containing models installed by InvokeAI's model manager |
| `legacy_conf_dir` | `configs/stable-diffusion` | Location of the directory containing the .yaml configuration files for legacy checkpoint models |
| `db_dir` | `databases` | Location of the directory containing InvokeAI's image, schema and session database |
| `outdir` | `outputs` | Location of the directory in which the gallery of generated and uploaded images will be stored |
| `use_memory_db` | `false` | Keep database information in memory rather than on disk; this will not preserve image gallery information across restarts |
Note that the autoimport directories will be searched recursively,
allowing you to organize the models into folders and subfolders in any
way you wish. In addition, while we have split up autoimport
directories by the type of model they contain, this isn't
necessary. You can combine different model types in the same folder
and InvokeAI will figure out what they are. So you can easily use just
one autoimport directory by commenting out the unneeded paths:
```
Paths:
autoimport_dir: autoimport
# lora_dir: null
# embedding_dir: null
# controlnet_dir: null
```
### Logging
These settings control the information, warning, and debugging
messages printed to the console log while InvokeAI is running:
| Setting | Default Value | Description |
|----------|----------------|--------------|
| `log_handlers` | `console` | This controls where log messages are sent, and can be a list of one or more destinations. Values include `console`, `file`, `syslog` and `http`. These are described in more detail below |
| `log_format` | `color` | This controls the formatting of the log messages. Values are `plain`, `color`, `legacy` and `syslog` |
| `log_level` | `debug` | This filters messages according to the level of severity and can be one of `debug`, `info`, `warning`, `error` and `critical`. For example, setting to `warning` will display all messages at the warning level or higher, but won't display "debug" or "info" messages |
#### Logging
Several different log handler destinations are available, and multiple destinations are supported by providing a list:
```
log_handlers:
- console
- syslog=localhost
- file=/var/log/invokeai.log
```yaml
log_handlers:
- console
- syslog=localhost
- file=/var/log/invokeai.log
```
* `console` is the default. It prints log messages to the command-line window from which InvokeAI was launched.
- `console` is the default. It prints log messages to the command-line window from which InvokeAI was launched.
* `syslog` is only available on Linux and Macintosh systems. It uses
- `syslog` is only available on Linux and Macintosh systems. It uses
the operating system's "syslog" facility to write log file entries
locally or to a remote logging machine. `syslog` offers a variety
of configuration options:
@ -271,7 +163,7 @@ Several different log handler destinations are available, and multiple destinati
- Log to LAN-connected server "fredserver" using the facility LOG_USER and datagram packets.
```
* `http` can be used to log to a remote web server. The server must be
- `http` can be used to log to a remote web server. The server must be
properly configured to receive and act on log messages. The option
accepts the URL to the web server, and a `method` argument
indicating whether the message should be submitted using the GET or
@ -283,7 +175,10 @@ Several different log handler destinations are available, and multiple destinati
The `log_format` option provides several alternative formats:
* `color` - default format providing time, date and a message, using text colors to distinguish different log severities
* `plain` - same as above, but monochrome text only
* `syslog` - the log level and error message only, allowing the syslog system to attach the time and date
* `legacy` - a format similar to the one used by the legacy 2.3 InvokeAI releases.
- `color` - default format providing time, date and a message, using text colors to distinguish different log severities
- `plain` - same as above, but monochrome text only
- `syslog` - the log level and error message only, allowing the syslog system to attach the time and date
- `legacy` - a format similar to the one used by the legacy 2.3 InvokeAI releases.
[basic guide to yaml files]: https://circleci.com/blog/what-is-yaml-a-beginner-s-guide/
[Model Marketplace API Keys]: #model-marketplace-api-keys

View File

@ -165,7 +165,7 @@ Additionally, each section can be expanded with the "Show Advanced" button in o
There are several ways to install IP-Adapter models with an existing InvokeAI installation:
1. Through the command line interface launched from the invoke.sh / invoke.bat scripts, option [4] to download models.
2. Through the Model Manager UI with models from the *Tools* section of [www.models.invoke.ai](https://www.models.invoke.ai). To do this, copy the repo ID from the desired model page, and paste it in the Add Model field of the model manager. **Note** Both the IP-Adapter and the Image Encoder must be installed for IP-Adapter to work. For example, the [SD 1.5 IP-Adapter](https://models.invoke.ai/InvokeAI/ip_adapter_plus_sd15) and [SD1.5 Image Encoder](https://models.invoke.ai/InvokeAI/ip_adapter_sd_image_encoder) must be installed to use IP-Adapter with SD1.5 based models.
2. Through the Model Manager UI with models from the *Tools* section of [models.invoke.ai](https://models.invoke.ai). To do this, copy the repo ID from the desired model page, and paste it in the Add Model field of the model manager. **Note** Both the IP-Adapter and the Image Encoder must be installed for IP-Adapter to work. For example, the [SD 1.5 IP-Adapter](https://models.invoke.ai/InvokeAI/ip_adapter_plus_sd15) and [SD1.5 Image Encoder](https://models.invoke.ai/InvokeAI/ip_adapter_sd_image_encoder) must be installed to use IP-Adapter with SD1.5 based models.
3. **Advanced -- Not recommended ** Manually downloading the IP-Adapter and Image Encoder files - Image Encoder folders shouid be placed in the `models\any\clip_vision` folders. IP Adapter Model folders should be placed in the relevant `ip-adapter` folder of relevant base model folder of Invoke root directory. For example, for the SDXL IP-Adapter, files should be added to the `model/sdxl/ip_adapter/` folder.
#### Using IP-Adapter

35
docs/features/DATABASE.md Normal file
View File

@ -0,0 +1,35 @@
---
title: Database
---
# Invoke's SQLite Database
Invoke uses a SQLite database to store image, workflow, model, and execution data.
We take great care to ensure your data is safe, by utilizing transactions and a database migration system.
Even so, when testing an prerelease version of the app, we strongly suggest either backing up your database or using an in-memory database. This ensures any prelease hiccups or databases schema changes will not cause problems for your data.
## Database Backup
Backing up your database is very simple. Invoke's data is stored in an `$INVOKEAI_ROOT` directory - where your `invoke.sh`/`invoke.bat` and `invokeai.yaml` files live.
To back up your database, copy the `invokeai.db` file from `$INVOKEAI_ROOT/databases/invokeai.db` to somewhere safe.
If anything comes up during prelease testing, you can simply copy your backup back into `$INVOKEAI_ROOT/databases/`.
## In-Memory Database
SQLite can run on an in-memory database. Your existing database is untouched when this mode is enabled, but your existing data won't be accessible.
This is very useful for testing, as there is no chance of a database change modifying your "physical" database.
To run Invoke with a memory database, edit your `invokeai.yaml` file, and add `use_memory_db: true` to the `Paths:` stanza:
```yaml
InvokeAI:
Development:
use_memory_db: true
```
Delete this line (or set it to `false`) to use your main database.

92
docs/features/GALLERY.md Normal file
View File

@ -0,0 +1,92 @@
---
title: InvokeAI Gallery Panel
---
# :material-web: InvokeAI Gallery Panel
## Quick guided walkthrough of the Gallery Panel's features
The Gallery Panel is a fast way to review, find, and make use of images you've
generated and loaded. The Gallery is divided into Boards. The Uncategorized board is always
present but you can create your own for better organization.
![image](../assets/gallery/gallery.png)
### Board Display and Settings
At the very top of the Gallery Panel are the boards disclosure and settings buttons.
![image](../assets/gallery/top_controls.png)
The disclosure button shows the name of the currently selected board and allows you to show and hide the board thumbnails (shown in the image below).
![image](../assets/gallery/board_thumbnails.png)
The settings button opens a list of options.
![image](../assets/gallery/board_settings.png)
- ***Image Size*** this slider lets you control the size of the image previews (images of three different sizes).
- ***Auto-Switch to New Images*** if you turn this on, whenever a new image is generated, it will automatically be loaded into the current image panel on the Text to Image tab and into the result panel on the [Image to Image](IMG2IMG.md) tab. This will happen invisibly if you are on any other tab when the image is generated.
- ***Auto-Assign Board on Click*** whenever an image is generated or saved, it always gets put in a board. The board it gets put into is marked with AUTO (image of board marked). Turning on Auto-Assign Board on Click will make whichever board you last selected be the destination when you click Invoke. That means you can click Invoke, select a different board, and then click Invoke again and the two images will be put in two different boards. (bold)It's the board selected when Invoke is clicked that's used, not the board that's selected when the image is finished generating.(bold) Turning this off, enables the Auto-Add Board drop down which lets you set one specific board to always put generated images into. This also enables and disables the Auto-add to this Board menu item described below.
- ***Always Show Image Size Badge*** this toggles whether to show image sizes for each image preview (show two images, one with sizes shown, one without)
Below these two buttons, you'll see the Search Boards text entry area. You use this to search for specific boards by the name of the board.
Next to it is the Add Board (+) button which lets you add new boards. Boards can be renamed by clicking on the name of the board under its thumbnail and typing in the new name.
### Board Thumbnail Menu
Each board has a context menu (ctrl+click / right-click).
![image](../assets/gallery/thumbnail_menu.png)
- ***Auto-add to this Board*** if you've disabled Auto-Assign Board on Click in the board settings, you can use this option to set this board to be where new images are put.
- ***Download Board*** this will add all the images in the board into a zip file and provide a link to it in a notification (image of notification)
- ***Delete Board*** this will delete the board
> [!CAUTION]
> This will delete all the images in the board and the board itself.
### Board Contents
Every board is organized by two tabs, Images and Assets.
![image](../assets/gallery/board_tabs.png)
Images are the Invoke-generated images that are placed into the board. Assets are images that you upload into Invoke to be used as an [Image Prompt](https://support.invoke.ai/support/solutions/articles/151000159340-using-the-image-prompt-adapter-ip-adapter-) or in the [Image to Image](IMG2IMG.md) tab.
### Image Thumbnail Menu
Every image generated by Invoke has its generation information stored as text inside the image file itself. This can be read directly by selecting the image and clicking on the Info button ![image](../assets/gallery/info_button.png) in any of the image result panels.
Each image also has a context menu (ctrl+click / right-click).
![image](../assets/gallery/image_menu.png)
The options are (items marked with an * will not work with images that lack generation information):
- ***Open in New Tab*** this will open the image alone in a new browser tab, separate from the Invoke interface.
- ***Download Image*** this will trigger your browser to download the image.
- ***Load Workflow **** this will load any workflow settings into the Workflow tab and automatically open it.
- ***Remix Image **** this will load all of the image's generation information, (bold)excluding its Seed, into the left hand control panel
- ***Use Prompt **** this will load only the image's text prompts into the left-hand control panel
- ***Use Seed **** this will load only the image's Seed into the left-hand control panel
- ***Use All **** this will load all of the image's generation information into the left-hand control panel
- ***Send to Image to Image*** this will put the image into the left-hand panel in the Image to Image tab ana automatically open it
- ***Send to Unified Canvas*** This will (bold)replace whatever is already present(bold) in the Unified Canvas tab with the image and automatically open the tab
- ***Change Board*** this will oipen a small window that will let you move the image to a different board. This is the same as dragging the image to that board's thumbnail.
- ***Star Image*** this will add the image to the board's list of starred images that are always kept at the top of the gallery. This is the same as clicking on the star on the top right-hand side of the image that appears when you hover over the image with the mouse
- ***Delete Image*** this will delete the image from the board
> [!CAUTION]
> This will delete the image entirely from Invoke.
## Summary
This walkthrough only covers the Gallery interface and Boards. Actually generating images is handled by [Prompts](PROMPTS.md), the [Image to Image](IMG2IMG.md) tab, and the [Unified Canvas](UNIFIED_CANVAS.md).
## Acknowledgements
A huge shout-out to the core team working to make the Web GUI a reality,
including [psychedelicious](https://github.com/psychedelicious),
[Kyle0654](https://github.com/Kyle0654) and
[blessedcoolant](https://github.com/blessedcoolant).
[hipsterusername](https://github.com/hipsterusername) was the team's unofficial
cheerleader and added tooltips/docs.

View File

@ -20,10 +20,7 @@ are applied to generate imagery. LoRAs may be supplied with a
simply apply their effect without being triggered.
LoRAs are typically stored in .safetensors files, which are the most
secure way to store and transmit these types of weights. You may
install any number of `.safetensors` LoRA files simply by copying them
into the `autoimport/lora` directory of the corresponding InvokeAI models
directory (usually `invokeai` in your home directory).
secure way to store and transmit these types of weights.
To use these when generating, open the LoRA menu item in the options
panel, select the LoRAs you want to apply and ensure that they have

View File

@ -108,40 +108,6 @@ Can be used with .and():
Each will give you different results - try them out and see what you prefer!
### Cross-Attention Control ('prompt2prompt')
Sometimes an image you generate is almost right, and you just want to change one
detail without affecting the rest. You could use a photo editor and inpainting
to overpaint the area, but that's a pain. Here's where `prompt2prompt` comes in
handy.
Generate an image with a given prompt, record the seed of the image, and then
use the `prompt2prompt` syntax to substitute words in the original prompt for
words in a new prompt. This works for `img2img` as well.
For example, consider the prompt `a cat.swap(dog) playing with a ball in the forest`. Normally, because the words interact with each other when doing a stable diffusion image generation, these two prompts would generate different compositions:
- `a cat playing with a ball in the forest`
- `a dog playing with a ball in the forest`
| `a cat playing with a ball in the forest` | `a dog playing with a ball in the forest` |
| --- | --- |
| img | img |
- For multiple word swaps, use parentheses: `a (fluffy cat).swap(barking dog) playing with a ball in the forest`.
- To swap a comma, use quotes: `a ("fluffy, grey cat").swap("big, barking dog") playing with a ball in the forest`.
- Supports options `t_start` and `t_end` (each 0-1) loosely corresponding to (bloc97's)[(https://github.com/bloc97/CrossAttentionControl)] `prompt_edit_tokens_start/_end` but with the math swapped to make it easier to
intuitively understand. `t_start` and `t_end` are used to control on which steps cross-attention control should run. With the default values `t_start=0` and `t_end=1`, cross-attention control is active on every step of image generation. Other values can be used to turn cross-attention control off for part of the image generation process.
- For example, if doing a diffusion with 10 steps for the prompt is `a cat.swap(dog, t_start=0.3, t_end=1.0) playing with a ball in the forest`, the first 3 steps will be run as `a cat playing with a ball in the forest`, while the last 7 steps will run as `a dog playing with a ball in the forest`, but the pixels that represent `dog` will be locked to the pixels that would have represented `cat` if the `cat` prompt had been used instead.
- Conversely, for `a cat.swap(dog, t_start=0, t_end=0.7) playing with a ball in the forest`, the first 7 steps will run as `a dog playing with a ball in the forest` with the pixels that represent `dog` locked to the same pixels that would have represented `cat` if the `cat` prompt was being used instead. The final 3 steps will just run `a cat playing with a ball in the forest`.
> For img2img, the step sequence does not start at 0 but instead at `(1.0-strength)` - so if the img2img `strength` is `0.7`, `t_start` and `t_end` must both be greater than `0.3` (`1.0-0.7`) to have any effect.
Prompt2prompt `.swap()` is not compatible with xformers, which will be temporarily disabled when doing a `.swap()` - so you should expect to use more VRAM and run slower that with xformers enabled.
The `prompt2prompt` code is based off
[bloc97's colab](https://github.com/bloc97/CrossAttentionControl).
### Escaping parentheses and speech marks
If the model you are using has parentheses () or speech marks "" as part of its

View File

@ -4,278 +4,6 @@ title: Training
# :material-file-document: Training
# Textual Inversion Training
## **Personalizing Text-to-Image Generation**
Invoke Training has moved to its own repository, with a dedicated UI for accessing common scripts like Textual Inversion and LoRA training.
You may personalize the generated images to provide your own styles or objects
by training a new LDM checkpoint and introducing a new vocabulary to the fixed
model as a (.pt) embeddings file. Alternatively, you may use or train
HuggingFace Concepts embeddings files (.bin) from
<https://huggingface.co/sd-concepts-library> and its associated
notebooks.
## **Hardware and Software Requirements**
You will need a GPU to perform training in a reasonable length of
time, and at least 12 GB of VRAM. We recommend using the [`xformers`
library](../installation/070_INSTALL_XFORMERS.md) to accelerate the
training process further. During training, about ~8 GB is temporarily
needed in order to store intermediate models, checkpoints and logs.
## **Preparing for Training**
To train, prepare a folder that contains 3-5 images that illustrate
the object or concept. It is good to provide a variety of examples or
poses to avoid overtraining the system. Format these images as PNG
(preferred) or JPG. You do not need to resize or crop the images in
advance, but for more control you may wish to do so.
Place the training images in a directory on the machine InvokeAI runs
on. We recommend placing them in a subdirectory of the
`text-inversion-training-data` folder located in the InvokeAI root
directory, ordinarily `~/invokeai` (Linux/Mac), or
`C:\Users\your_name\invokeai` (Windows). For example, to create an
embedding for the "psychedelic" style, you'd place the training images
into the directory
`~invokeai/text-inversion-training-data/psychedelic`.
## **Launching Training Using the Console Front End**
InvokeAI 2.3 and higher comes with a text console-based training front
end. From within the `invoke.sh`/`invoke.bat` Invoke launcher script,
start training tool selecting choice (3):
```sh
1 "Generate images with a browser-based interface"
2 "Explore InvokeAI nodes using a command-line interface"
3 "Textual inversion training"
4 "Merge models (diffusers type only)"
5 "Download and install models"
6 "Change InvokeAI startup options"
7 "Re-run the configure script to fix a broken install or to complete a major upgrade"
8 "Open the developer console"
9 "Update InvokeAI"
```
Alternatively, you can select option (8) or from the command line, with the InvokeAI virtual environment active,
you can then launch the front end with the command `invokeai-ti --gui`.
This will launch a text-based front end that will look like this:
<figure markdown>
![ti-frontend](../assets/textual-inversion/ti-frontend.png)
</figure>
The interface is keyboard-based. Move from field to field using
control-N (^N) to move to the next field and control-P (^P) to the
previous one. <Tab> and <shift-TAB> work as well. Once a field is
active, use the cursor keys. In a checkbox group, use the up and down
cursor keys to move from choice to choice, and <space> to select a
choice. In a scrollbar, use the left and right cursor keys to increase
and decrease the value of the scroll. In textfields, type the desired
values.
The number of parameters may look intimidating, but in most cases the
predefined defaults work fine. The red circled fields in the above
illustration are the ones you will adjust most frequently.
### Model Name
This will list all the diffusers models that are currently
installed. Select the one you wish to use as the basis for your
embedding. Be aware that if you use a SD-1.X-based model for your
training, you will only be able to use this embedding with other
SD-1.X-based models. Similarly, if you train on SD-2.X, you will only
be able to use the embeddings with models based on SD-2.X.
### Trigger Term
This is the prompt term you will use to trigger the embedding. Type a
single word or phrase you wish to use as the trigger, example
"psychedelic" (without angle brackets). Within InvokeAI, you will then
be able to activate the trigger using the syntax `<psychedelic>`.
### Initializer
This is a single character that is used internally during the training
process as a placeholder for the trigger term. It defaults to "*" and
can usually be left alone.
### Resume from last saved checkpoint
As training proceeds, textual inversion will write a series of
intermediate files that can be used to resume training from where it
was left off in the case of an interruption. This checkbox will be
automatically selected if you provide a previously used trigger term
and at least one checkpoint file is found on disk.
Note that as of 20 January 2023, resume does not seem to be working
properly due to an issue with the upstream code.
### Data Training Directory
This is the location of the images to be used for training. When you
select a trigger term like "my-trigger", the frontend will prepopulate
this field with `~/invokeai/text-inversion-training-data/my-trigger`,
but you can change the path to wherever you want.
### Output Destination Directory
This is the location of the logs, checkpoint files, and embedding
files created during training. When you select a trigger term like
"my-trigger", the frontend will prepopulate this field with
`~/invokeai/text-inversion-output/my-trigger`, but you can change the
path to wherever you want.
### Image resolution
The images in the training directory will be automatically scaled to
the value you use here. For best results, you will want to use the
same default resolution of the underlying model (512 pixels for
SD-1.5, 768 for the larger version of SD-2.1).
### Center crop images
If this is selected, your images will be center cropped to make them
square before resizing them to the desired resolution. Center cropping
can indiscriminately cut off the top of subjects' heads for portrait
aspect images, so if you have images like this, you may wish to use a
photoeditor to manually crop them to a square aspect ratio.
### Mixed precision
Select the floating point precision for the embedding. "no" will
result in a full 32-bit precision, "fp16" will provide 16-bit
precision, and "bf16" will provide mixed precision (only available
when XFormers is used).
### Max training steps
How many steps the training will take before the model converges. Most
training sets will converge with 2000-3000 steps.
### Batch size
This adjusts how many training images are processed simultaneously in
each step. Higher values will cause the training process to run more
quickly, but use more memory. The default size will run with GPUs with
as little as 12 GB.
### Learning rate
The rate at which the system adjusts its internal weights during
training. Higher values risk overtraining (getting the same image each
time), and lower values will take more steps to train a good
model. The default of 0.0005 is conservative; you may wish to increase
it to 0.005 to speed up training.
### Scale learning rate by number of GPUs, steps and batch size
If this is selected (the default) the system will adjust the provided
learning rate to improve performance.
### Use xformers acceleration
This will activate XFormers memory-efficient attention. You need to
have XFormers installed for this to have an effect.
### Learning rate scheduler
This adjusts how the learning rate changes over the course of
training. The default "constant" means to use a constant learning rate
for the entire training session. The other values scale the learning
rate according to various formulas.
Only "constant" is supported by the XFormers library.
### Gradient accumulation steps
This is a parameter that allows you to use bigger batch sizes than
your GPU's VRAM would ordinarily accommodate, at the cost of some
performance.
### Warmup steps
If "constant_with_warmup" is selected in the learning rate scheduler,
then this provides the number of warmup steps. Warmup steps have a
very low learning rate, and are one way of preventing early
overtraining.
## The training run
Start the training run by advancing to the OK button (bottom right)
and pressing <enter>. A series of progress messages will be displayed
as the training process proceeds. This may take an hour or two,
depending on settings and the speed of your system. Various log and
checkpoint files will be written into the output directory (ordinarily
`~/invokeai/text-inversion-output/my-model/`)
At the end of successful training, the system will copy the file
`learned_embeds.bin` into the InvokeAI root directory's `embeddings`
directory, using a subdirectory named after the trigger token. For
example, if the trigger token was `psychedelic`, then look for the
embeddings file in
`~/invokeai/embeddings/psychedelic/learned_embeds.bin`
You may now launch InvokeAI and try out a prompt that uses the trigger
term. For example `a plate of banana sushi in <psychedelic> style`.
## **Training with the Command-Line Script**
Training can also be done using a traditional command-line script. It
can be launched from within the "developer's console", or from the
command line after activating InvokeAI's virtual environment.
It accepts a large number of arguments, which can be summarized by
passing the `--help` argument:
```sh
invokeai-ti --help
```
Typical usage is shown here:
```sh
invokeai-ti \
--model=stable-diffusion-1.5 \
--resolution=512 \
--learnable_property=style \
--initializer_token='*' \
--placeholder_token='<psychedelic>' \
--train_data_dir=/home/lstein/invokeai/training-data/psychedelic \
--output_dir=/home/lstein/invokeai/text-inversion-training/psychedelic \
--scale_lr \
--train_batch_size=8 \
--gradient_accumulation_steps=4 \
--max_train_steps=3000 \
--learning_rate=0.0005 \
--resume_from_checkpoint=latest \
--lr_scheduler=constant \
--mixed_precision=fp16 \
--only_save_embeds
```
## Troubleshooting
### `Cannot load embedding for <trigger>. It was trained on a model with token dimension 1024, but the current model has token dimension 768`
Messages like this indicate you trained the embedding on a different base model than the currently selected one.
For example, in the error above, the training was done on SD2.1 (768x768) but it was used on SD1.5 (512x512).
## Reading
For more information on textual inversion, please see the following
resources:
* The [textual inversion repository](https://github.com/rinongal/textual_inversion) and
associated paper for details and limitations.
* [HuggingFace's textual inversion training
page](https://huggingface.co/docs/diffusers/training/text_inversion)
* [HuggingFace example script
documentation](https://github.com/huggingface/diffusers/tree/main/examples/textual_inversion)
(Note that this script is similar to, but not identical, to
`textual_inversion`, but produces embed files that are completely compatible.
---
copyright (c) 2023, Lincoln Stein and the InvokeAI Development Team
You can find more by visiting the repo at https://github.com/invoke-ai/invoke-training

View File

@ -54,7 +54,7 @@ main sections:
of buttons at the top lets you modify and manipulate the image in
various ways.
3. A **gallery** section on the left that contains a history of the images you
3. A **gallery** section on the right that contains a history of the images you
have generated. These images are read and written to the directory specified
in the `INVOKEAIROOT/invokeai.yaml` initialization file, usually a directory
named `outputs` in `INVOKEAIROOT`.

View File

@ -1,43 +1,244 @@
# FAQs
# FAQ
**Where do I get started? How can I install Invoke?**
!!! info "How to Reinstall"
- You can download the latest installers [here](https://github.com/invoke-ai/InvokeAI/releases) - Note that any releases marked as *pre-release* are in a beta state. You may experience some issues, but we appreciate your help testing those! For stable/reliable installations, please install the **[Latest Release](https://github.com/invoke-ai/InvokeAI/releases/latest)**
Many issues can be resolved by re-installing the application. You won't lose any data by re-installing. We suggest downloading the [latest release](https://github.com/invoke-ai/InvokeAI/releases/latest) and using it to re-install the application. Consult the [installer guide](../installation/010_INSTALL_AUTOMATED.md) for more information.
**How can I download models? Can I use models I already have downloaded?**
When you run the installer, you'll have an option to select the version to install. If you aren't ready to upgrade, you choose the current version to fix a broken install.
- Models can be downloaded through the model manager, or through option [4] in the invoke.bat/invoke.sh launcher script. To download a model through the Model Manager, use the HuggingFace Repo ID by pressing the “Copy” button next to the repository name. Alternatively, to download a model from CivitAi, use the download link in the Model Manager.
- Models that are already downloaded can be used by creating a symlink to the model location in the `autoimport` folder or by using the Model Mangers “Scan for Models” function.
If the troubleshooting steps on this page don't get you up and running, please either [create an issue] or hop on [discord] for help.
**My images are taking a long time to generate. How can I speed up generation?**
## How to Install
- A common solution is to reduce the size of your RAM & VRAM cache to 0.25. This ensures your system has enough memory to generate images.
- Additionally, check the [hardware requirements](https://invoke-ai.github.io/InvokeAI/#hardware-requirements) to ensure that your system is capable of generating images.
- Lastly, double check your generations are happening on your GPU (if you have one). InvokeAI will log what is being used for generation upon startup.
You can download the latest installers [here](https://github.com/invoke-ai/InvokeAI/releases).
**Ive installed Python on Windows but the installer says it cant find it?**
Note that any releases marked as _pre-release_ are in a beta state. You may experience some issues, but we appreciate your help testing those! For stable/reliable installations, please install the [latest release].
- Then ensure that you checked **'Add python.exe to PATH'** when installing Python. This can be found at the bottom of the Python Installer window. If you already have Python installed, this can be done with the modify / repair feature of the installer.
## Downloading models and using existing models
**Ive installed everything successfully but I still get an error about Triton when starting Invoke?**
The Model Manager tab in the UI provides a few ways to install models, including using your already-downloaded models. You'll see a popup directing you there on first startup. For more information, see the [model install docs].
- This can be safely ignored. InvokeAI doesn't use Triton, but if you are on Linux and wish to dismiss the error, you can install Triton.
## Missing models after updating to v4
**I updated to 3.4.0 and now xFormers cant load C++/CUDA?**
If you find some models are missing after updating to v4, it's likely they weren't correctly registered before the update and didn't get picked up in the migration.
- An issue occurred with your PyTorch update. Follow these steps to fix :
1. Launch your invoke.bat / invoke.sh and select the option to open the developer console
2. Run:`pip install ".[xformers]" --upgrade --force-reinstall --extra-index-url https://download.pytorch.org/whl/cu121`
- If you run into an error with `typing_extensions`, re-open the developer console and run: `pip install -U typing-extensions`
You can use the `Scan Folder` tab in the Model Manager UI to fix this. The models will either be in the old, now-unused `autoimport` folder, or your `models` folder.
**It says my pip is out of date - is that why my install isn't working?**
- An out of date won't cause an installation to fail. The cause of the error can likely be found above the message that says pip is out of date.
- If you saw that warning but the install went well, don't worry about it (but you can update pip afterwards if you'd like).
- Find and copy your install's old `autoimport` folder path, install the main install folder.
- Go to the Model Manager and click `Scan Folder`.
- Paste the path and scan.
- IMPORTANT: Uncheck `Inplace install`.
- Click `Install All` to install all found models, or just install the models you want.
Next, find and copy your install's `models` folder path (this could be your custom models folder path, or the `models` folder inside the main install folder).
Follow the same steps to scan and import the missing models.
## Slow generation
- Check the [system requirements] to ensure that your system is capable of generating images.
- Check the `ram` setting in `invokeai.yaml`. This setting tells Invoke how much of your system RAM can be used to cache models. Having this too high or too low can slow things down. That said, it's generally safest to not set this at all and instead let Invoke manage it.
- Check the `vram` setting in `invokeai.yaml`. This setting tells Invoke how much of your GPU VRAM can be used to cache models. Counter-intuitively, if this setting is too high, Invoke will need to do a lot of shuffling of models as it juggles the VRAM cache and the currently-loaded model. The default value of 0.25 is generally works well for GPUs without 16GB or more VRAM. Even on a 24GB card, the default works well.
- Check that your generations are happening on your GPU (if you have one). InvokeAI will log what is being used for generation upon startup. If your GPU isn't used, re-install to ensure the correct versions of torch get installed.
- If you are on Windows, you may have exceeded your GPU's VRAM capacity and are using slower [shared GPU memory](#shared-gpu-memory-windows). There's a guide to opt out of this behaviour in the linked FAQ entry.
## Shared GPU Memory (Windows)
!!! tip "Nvidia GPUs with driver 536.40"
This only applies to current Nvidia cards with driver 536.40 or later, released in June 2023.
When the GPU doesn't have enough VRAM for a task, Windows is able to allocate some of its CPU RAM to the GPU. This is much slower than VRAM, but it does allow the system to generate when it otherwise might no have enough VRAM.
When shared GPU memory is used, generation slows down dramatically - but at least it doesn't crash.
If you'd like to opt out of this behavior and instead get an error when you exceed your GPU's VRAM, follow [this guide from Nvidia](https://nvidia.custhelp.com/app/answers/detail/a_id/5490).
Here's how to get the python path required in the linked guide:
- Run `invoke.bat`.
- Select option 2 for developer console.
- At least one python path will be printed. Copy the path that includes your invoke installation directory (typically the first).
## Installer cannot find python (Windows)
Ensure that you checked **Add python.exe to PATH** when installing Python. This can be found at the bottom of the Python Installer window. If you already have Python installed, you can re-run the python installer, choose the Modify option and check the box.
## Triton error on startup
This can be safely ignored. InvokeAI doesn't use Triton, but if you are on Linux and wish to dismiss the error, you can install Triton.
## Updated to 3.4.0 and xformers cant load C++/CUDA
An issue occurred with your PyTorch update. Follow these steps to fix :
1. Launch your invoke.bat / invoke.sh and select the option to open the developer console
2. Run:`pip install ".[xformers]" --upgrade --force-reinstall --extra-index-url https://download.pytorch.org/whl/cu121`
- If you run into an error with `typing_extensions`, re-open the developer console and run: `pip install -U typing-extensions`
Note that v3.4.0 is an old, unsupported version. Please upgrade to the [latest release].
## Install failed and says `pip` is out of date
An out of date `pip` typically won't cause an installation to fail. The cause of the error can likely be found above the message that says `pip` is out of date.
If you saw that warning but the install went well, don't worry about it (but you can update `pip` afterwards if you'd like).
## Replicate image found online
**How can I generate the exact same that I found on the internet?**
Most example images with prompts that you'll find on the internet have been generated using different software, so you can't expect to get identical results. In order to reproduce an image, you need to replicate the exact settings and processing steps, including (but not limited to) the model, the positive and negative prompts, the seed, the sampler, the exact image size, any upscaling steps, etc.
## OSErrors on Windows while installing dependencies
**Where can I get more help?**
During a zip file installation or an update, installation stops with an error like this:
- Create an issue on [GitHub](https://github.com/invoke-ai/InvokeAI/issues) or post in the [#help channel](https://discord.com/channels/1020123559063990373/1149510134058471514) of the InvokeAI Discord
![broken-dependency-screenshot](../assets/troubleshooting/broken-dependency.png){:width="800px"}
To resolve this, re-install the application as described above.
## HuggingFace install failed due to invalid access token
Some HuggingFace models require you to authenticate using an [access token].
Invoke doesn't manage this token for you, but it's easy to set it up:
- Follow the instructions in the link above to create an access token. Copy it.
- Run the launcher script.
- Select option 2 (developer console).
- Paste the following command:
```sh
python -c "import huggingface_hub; huggingface_hub.login()"
```
- Paste your access token when prompted and press Enter. You won't see anything when you paste it.
- Type `n` if prompted about git credentials.
If you get an error, try the command again - maybe the token didn't paste correctly.
Once your token is set, start Invoke and try downloading the model again. The installer will automatically use the access token.
If the install still fails, you may not have access to the model.
## Stable Diffusion XL generation fails after trying to load UNet
InvokeAI is working in other respects, but when trying to generate
images with Stable Diffusion XL you get a "Server Error". The text log
in the launch window contains this log line above several more lines of
error messages:
`INFO --> Loading model:D:\LONG\PATH\TO\MODEL, type sdxl:main:unet`
This failure mode occurs when there is a network glitch during
downloading the very large SDXL model.
To address this, first go to the Model Manager and delete the
Stable-Diffusion-XL-base-1.X model. Then, click the HuggingFace tab,
paste the Repo ID stabilityai/stable-diffusion-xl-base-1.0 and install
the model.
## Package dependency conflicts during installation or update
If you have previously installed InvokeAI or another Stable Diffusion
package, the installer may occasionally pick up outdated libraries and
either the installer or `invoke` will fail with complaints about
library conflicts.
To resolve this, re-install the application as described above.
## Invalid configuration file
Everything seems to install ok, you get a `ValidationError` when starting up the app.
This is caused by an invalid setting in the `invokeai.yaml` configuration file. The error message should tell you what is wrong.
Check the [configuration docs] for more detail about the settings and how to specify them.
## `ModuleNotFoundError: No module named 'controlnet_aux'`
`controlnet_aux` is a dependency of Invoke and appears to have been packaged or distributed strangely. Sometimes, it doesn't install correctly. This is outside our control.
If you encounter this error, the solution is to remove the package from the `pip` cache and re-run the Invoke installer so a fresh, working version of `controlnet_aux` can be downloaded and installed:
- Run the Invoke launcher
- Choose the developer console option
- Run this command: `pip cache remove controlnet_aux`
- Close the terminal window
- Download and run the [installer](https://github.com/invoke-ai/InvokeAI/releases/latest), selecting your current install location
## Out of Memory Issues
The models are large, VRAM is expensive, and you may find yourself
faced with Out of Memory errors when generating images. Here are some
tips to reduce the problem:
!!! info "Optimizing for GPU VRAM"
=== "4GB VRAM GPU"
This should be adequate for 512x512 pixel images using Stable Diffusion 1.5
and derived models, provided that you do not use the NSFW checker. It won't be loaded unless you go into the UI settings and turn it on.
If you are on a CUDA-enabled GPU, we will automatically use xformers or torch-sdp to reduce VRAM requirements, though you can explicitly configure this. See the [configuration docs].
=== "6GB VRAM GPU"
This is a border case. Using the SD 1.5 series you should be able to
generate images up to 640x640 with the NSFW checker enabled, and up to
1024x1024 with it disabled.
If you run into persistent memory issues there are a series of
environment variables that you can set before launching InvokeAI that
alter how the PyTorch machine learning library manages memory. See
<https://pytorch.org/docs/stable/notes/cuda.html#memory-management> for
a list of these tweaks.
=== "12GB VRAM GPU"
This should be sufficient to generate larger images up to about 1280x1280.
## Memory Leak (Linux)
If you notice a memory leak, it could be caused to memory fragmentation as models are loaded and/or moved from CPU to GPU.
A workaround is to tune memory allocation with an environment variable:
```bash
# Force blocks >1MB to be allocated with `mmap` so that they are released to the system immediately when they are freed.
MALLOC_MMAP_THRESHOLD_=1048576
```
!!! warning "Speed vs Memory Tradeoff"
Your generations may be slower overall when setting this environment variable.
!!! info "Possibly dependent on `libc` implementation"
It's not known if this issue occurs with other `libc` implementations such as `musl`.
If you encounter this issue and your system uses a different implementation, please try this environment variable and let us know if it fixes the issue.
<h3>Detailed Discussion</h3>
Python (and PyTorch) relies on the memory allocator from the C Standard Library (`libc`). On linux, with the GNU C Standard Library implementation (`glibc`), our memory access patterns have been observed to cause severe memory fragmentation.
This fragmentation results in large amounts of memory that has been freed but can't be released back to the OS. Loading models from disk and moving them between CPU/CUDA seem to be the operations that contribute most to the fragmentation.
This memory fragmentation issue can result in OOM crashes during frequent model switching, even if `ram` (the max RAM cache size) is set to a reasonable value (e.g. a OOM crash with `ram=16` on a system with 32GB of RAM).
This problem may also exist on other OSes, and other `libc` implementations. But, at the time of writing, it has only been investigated on linux with `glibc`.
To better understand how the `glibc` memory allocator works, see these references:
- Basics: <https://www.gnu.org/software/libc/manual/html_node/The-GNU-Allocator.html>
- Details: <https://sourceware.org/glibc/wiki/MallocInternals>
Note the differences between memory allocated as chunks in an arena vs. memory allocated with `mmap`. Under `glibc`'s default configuration, most model tensors get allocated as chunks in an arena making them vulnerable to the problem of fragmentation.
[model install docs]: ../installation/050_INSTALLING_MODELS.md
[system requirements]: ../installation/INSTALL_REQUIREMENTS.md
[latest release]: https://github.com/invoke-ai/InvokeAI/releases/latest
[create an issue]: https://github.com/invoke-ai/InvokeAI/issues
[discord]: https://discord.gg/ZmtBAhwWhy
[configuration docs]: ../features/CONFIGURATION.md
[access token]: https://huggingface.co/docs/hub/security-tokens#how-to-manage-user-access-tokens

View File

@ -1,128 +0,0 @@
---
title: F.A.Q.
---
# :material-frequently-asked-questions: F.A.Q.
## **Frequently-Asked-Questions**
Here are a few common installation problems and their solutions. Often these are
caused by incomplete installations or crashes during the install process.
---
### During `conda env create`, conda hangs indefinitely
If it is because of the last PIP step (usually stuck in the Git Clone step, you
can check the detailed log by this method):
```bash
export PIP_LOG="/tmp/pip_log.txt"
touch ${PIP_LOG}
tail -f ${PIP_LOG} &
conda env create -f environment-mac.yaml --debug --verbose
killall tail
rm ${PIP_LOG}
```
**SOLUTION**
Conda sometimes gets stuck at the last PIP step, in which several git
repositories are cloned and built.
Enter the stable-diffusion directory and completely remove the `src` directory
and all its contents. The safest way to do this is to enter the stable-diffusion
directory and give the command `git clean -f`. If this still doesn't fix the
problem, try "conda clean -all" and then restart at the `conda env create` step.
To further understand the problem to checking the install lot using this method:
```bash
export PIP_LOG="/tmp/pip_log.txt"
touch ${PIP_LOG}
tail -f ${PIP_LOG} &
conda env create -f environment-mac.yaml --debug --verbose
killall tail
rm ${PIP_LOG}
```
---
### `invoke.py` crashes with the complaint that it can't find `ldm.simplet2i.py`
Or it complains that function is being passed incorrect parameters.
**SOLUTION**
Reinstall the stable diffusion modules. Enter the `stable-diffusion` directory
and give the command `pip install -e .`
---
### Missing modules
`invoke.py` dies, complaining of various missing modules, none of which starts
with `ldm`.
**SOLUTION**
From within the `InvokeAI` directory, run `conda env update` This is also
frequently the solution to complaints about an unknown function in a module.
---
### How can I try new features
There's a feature or bugfix in the Stable Diffusion GitHub that you want to try
out.
**SOLUTIONS**
#### **Main Branch**
If the fix/feature is on the `main` branch, enter the stable-diffusion directory
and do a `git pull`.
Usually this will be sufficient, but if you start to see errors about missing or
incorrect modules, use the command `pip install -e .` and/or `conda env update`
(These commands won't break anything.)
`pip install -e .` and/or `conda env update -f environment.yaml`
(These commands won't break anything.)
#### **Sub Branch**
If the feature/fix is on a branch (e.g. "_foo-bugfix_"), the recipe is similar,
but do a `git pull <name of branch>`.
#### **Not Committed**
If the feature/fix is in a pull request that has not yet been made part of the
main branch or a feature/bugfix branch, then from the page for the desired pull
request, look for the line at the top that reads "_xxxx wants to merge xx
commits into lstein:main from YYYYYY_". Copy the URL in YYYY. It should have the
format
`https://github.com/<name of contributor>/stable-diffusion/tree/<name of branch>`
Then **go to the directory above stable-diffusion** and rename the directory to
"_stable-diffusion.lstein_", "_stable-diffusion.old_", or anything else. You can
then git clone the branch that contains the pull request:
`git clone https://github.com/<name of contributor>/stable-diffusion/tree/<name of branch>`
You will need to go through the install procedure again, but it should be fast
because all the dependencies are already loaded.
---
### CUDA out of memory
Image generation crashed with CUDA out of memory error after successful
sampling.
**SOLUTION**
Try to run script with option `--free_gpu_mem` This will free memory before
image decoding step.

View File

@ -20,7 +20,7 @@ When you generate an image using text-to-image, multiple steps occur in latent s
4. The VAE decodes the final latent image from latent space into image space.
Image-to-image is a similar process, with only step 1 being different:
1. The input image is encoded from image space into latent space by the VAE. Noise is then added to the input latent image. Denoising Strength dictates how may noise steps are added, and the amount of noise added at each step. A Denoising Strength of 0 means there are 0 steps and no noise added, resulting in an unchanged image, while a Denoising Strength of 1 results in the image being completely replaced with noise and a full set of denoising steps are performance. The process is then the same as steps 2-4 in the text-to-image process.
1. The input image is encoded from image space into latent space by the VAE. Noise is then added to the input latent image. Denoising Strength dictates how many noise steps are added, and the amount of noise added at each step. A Denoising Strength of 0 means there are 0 steps and no noise added, resulting in an unchanged image, while a Denoising Strength of 1 results in the image being completely replaced with noise and a full set of denoising steps are performance. The process is then the same as steps 2-4 in the text-to-image process.
Furthermore, a model provides the CLIP prompt tokenizer, the VAE, and a U-Net (where noise prediction occurs given a prompt and initial noise tensor).

View File

@ -153,8 +153,7 @@ Mac and Linux machines, and runs on GPU cards with as little as 4 GB of RAM.
## :material-target: Troubleshooting
Please check out our **[:material-frequently-asked-questions:
Troubleshooting
Guide](installation/010_INSTALL_AUTOMATED.md#troubleshooting)** to
FAQ](help/FAQ/)** to
get solutions for common installation problems and other issues.
## :octicons-repo-push-24: Contributing

View File

@ -1,580 +1,107 @@
---
title: Installing with the Automated Installer
---
# Automatic Install & Updates
# InvokeAI Automated Installation
**The same packaged installer file can be used for both new installs and updates.**
Using the installer for updates will leave everything you've added since installation, and just update the core libraries used to run Invoke.
Simply use the same path you installed to originally.
## Introduction
Both release and pre-release versions can be installed using the installer. It also supports install through a wheel if needed.
The automated installer is a Python script that automates the steps
needed to install and run InvokeAI on a stock computer running recent
versions of Linux, MacOS or Windows. It will leave you with a version
that runs a stable version of InvokeAI with the option to upgrade to
experimental versions later.
Be sure to review the [installation requirements] and ensure your system has everything it needs to install Invoke.
## Walk through
## Getting the Latest Installer
1. <a name="hardware_requirements">**Hardware Requirements**: </a>Make sure that your system meets the [hardware
requirements](../index.md#hardware-requirements) and has the
appropriate GPU drivers installed. For a system with an NVIDIA
card installed, you will need to install the CUDA driver, while
AMD-based cards require the ROCm driver. In most cases, if you've
already used the system for gaming or other graphics-intensive
tasks, the appropriate drivers will already be installed. If
unsure, check the [GPU Driver Guide](030_INSTALL_CUDA_AND_ROCM.md)
Download the `InvokeAI-installer-vX.Y.Z.zip` file from the [latest release] page. It is at the bottom of the page, under **Assets**.
!!! info "Required Space"
After unzipping the installer, you should have a `InvokeAI-Installer` folder with some files inside, including `install.bat` and `install.sh`.
Installation requires roughly 18G of free disk space to load
the libraries and recommended model weights files.
## Running the Installer
Regardless of your destination disk, your *system drive*
(`C:\` on Windows, `/` on macOS/Linux) requires at least 6GB
of free disk space to download and cache python
dependencies.
!!! tip
NOTE for Linux users: if your temporary directory is mounted
as a `tmpfs`, ensure it has sufficient space.
Windows users should first double-click the `WinLongPathsEnabled.reg` file to prevent a failed installation due to long file paths.
2. <a name="software_requirements">**Software Requirements**: </a>Check that your system has an up-to-date Python installed. To do
this, open up a command-line window ("Terminal" on Linux and
Macintosh, "Command" or "Powershell" on Windows) and type `python
--version`. If Python is installed, it will print out the version
number. If it is version `3.10.*` or `3.11.*` you meet
requirements.
Double-click the install script:
!!! warning "What to do if you have an unsupported version"
=== "Windows"
Go to [Python Downloads](https://www.python.org/downloads/)
and download the appropriate installer package for your
platform. We recommend [Version
3.10.12](https://www.python.org/downloads/release/python-3109/),
which has been extensively tested with InvokeAI.
_Please select your platform in the section below for platform-specific
setup requirements._
=== "Windows"
During the Python configuration process, look out for a
checkbox to add Python to your PATH and select it. If the
install script complains that it can't find python, then open
the Python installer again and choose "Modify" existing
installation.
Installation requires an up to date version of the Microsoft
Visual C libraries. Please install the 2015-2022 libraries
available here:
https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170
Please double-click on the file `WinLongPathsEnabled.reg` and
accept the dialog box that asks you if you wish to modify your registry.
This activates long filename support on your system and will prevent
mysterious errors during installation.
=== "Linux"
To install an appropriate version of Python on Ubuntu 22.04
and higher, run the following:
```
sudo apt update
sudo apt install -y python3 python3-pip python3-venv
sudo update-alternatives --install /usr/local/bin/python python /usr/bin/python3.10 3
```
On Ubuntu 20.04, the process is slightly different:
```
sudo apt update
sudo apt install -y software-properties-common
sudo add-apt-repository -y ppa:deadsnakes/ppa
sudo apt install -y python3.10 python3-pip python3.10-venv
sudo update-alternatives --install /usr/local/bin/python python /usr/bin/python3.10 3
```
Both `python` and `python3` commands are now pointing at
Python3.10. You can still access older versions of Python by
calling `python2`, `python3.8`, etc.
Linux systems require a couple of additional graphics
libraries to be installed for proper functioning of
`python3-opencv`. Please run the following:
`sudo apt update && sudo apt install -y libglib2.0-0 libgl1-mesa-glx`
=== "Mac"
After installing Python, you may need to run the
following command from the Terminal in order to install the Web
certificates needed to download model data from https sites. If
you see lots of CERTIFICATE ERRORS during the last part of the
install, this is the problem, and you can fix it with this command:
`/Applications/Python\ 3.10/Install\ Certificates.command`
You may need to install the Xcode command line tools. These
are a set of tools that are needed to run certain applications in a
Terminal, including InvokeAI. This package is provided
directly by Apple. To install, open a terminal window and run `xcode-select --install`. You will get a macOS system popup guiding you through the
install. If you already have them installed, you will instead see some
output in the Terminal advising you that the tools are already installed. More information can be found at [FreeCode Camp](https://www.freecodecamp.org/news/install-xcode-command-line-tools/)
3. **Download the Installer**: The InvokeAI installer is distributed as a ZIP files. Go to the
[latest release](https://github.com/invoke-ai/InvokeAI/releases/latest),
and look for a file named:
- InvokeAI-installer-v3.X.X.zip
where "3.X.X" is the latest released version. The file is located
at the very bottom of the release page, under **Assets**.
4. **Unpack the installer**: Unpack the zip file into a convenient directory. This will create a new
directory named "InvokeAI-Installer". When unpacked, the directory
will look like this:
<figure markdown>
![zipfile-screenshot](../assets/installer-walkthrough/unpacked-zipfile.png)
</figure>
5. **Launch the installer script from the desktop**: If you are using a desktop GUI, double-click the installer file
appropriate for your platform. It will be named `install.bat` on
Windows systems and `install.sh` on Linux and Macintosh
systems. Be aware that your system's file browser may suppress the
display of the file extension.
On Windows systems if you get an "Untrusted Publisher" warning.
Click on "More Info" and then select "Run Anyway." You trust us, right?
6. **[Alternative] Launch the installer script from the command line**: Alternatively, from the command line, run the shell script or .bat file:
```cmd
C:\Documents\Linco> cd InvokeAI-Installer
C:\Documents\Linco\invokeAI> .\install.bat
```sh
install.bat
```
7. **Select the location to install InvokeAI**: The script will ask you to choose where to install InvokeAI. Select a
directory with at least 18G of free space for a full install. InvokeAI and
all its support files will be installed into a new directory named
`invokeai` located at the location you specify.
=== "Linux/macOS"
<figure markdown>
![confirm-install-directory-screenshot](../assets/installer-walkthrough/confirm-directory.png)
</figure>
- The default is to install the `invokeai` directory in your home directory,
usually `C:\Users\YourName\invokeai` on Windows systems,
`/home/YourName/invokeai` on Linux systems, and `/Users/YourName/invokeai`
on Macintoshes, where "YourName" is your login name.
-If you have previously installed InvokeAI, you will be asked to
confirm whether you want to reinstall into this directory. You
may choose to reinstall, in which case your version will be upgraded,
or choose a different directory.
- The script uses tab autocompletion to suggest directory path completions.
Type part of the path (e.g. "C:\Users") and press ++tab++ repeatedly
to suggest completions.
8. **Select your GPU**: The installer will autodetect your platform and will request you to
confirm the type of GPU your graphics card has. On Linux systems,
you will have the choice of CUDA (NVidia cards), ROCm (AMD cards),
or CPU (no graphics acceleration). On Windows, you'll have the
choice of CUDA vs CPU, and on Macs you'll be offered CPU only. When
you select CPU on M1/M2/M3 Macintoshes, you will get MPS-based
graphics acceleration without installing additional drivers. If you
are unsure what GPU you are using, you can ask the installer to
guess.
9. **Watch it go!**: Sit back and let the install script work. It will install the third-party
libraries needed by InvokeAI and the application itself.
Be aware that some of the library download and install steps take a long
time. In particular, the `pytorch` package is quite large and often appears
to get "stuck" at 99.9%. Have patience and the installation step will
eventually resume. However, there are occasions when the library install
does legitimately get stuck. If you have been waiting for more than ten
minutes and nothing is happening, you can interrupt the script with ^C. You
may restart it and it will pick up where it left off.
<figure markdown>
![initial-settings-screenshot](../assets/installer-walkthrough/settings-form.png)
</figure>
10. **Post-install Configuration**: After installation completes, the
installer will launch the configuration form, which will guide you
through the first-time process of adjusting some of InvokeAI's
startup settings. To move around this form use ctrl-N for
&lt;N&gt;ext and ctrl-P for &lt;P&gt;revious, or use &lt;tab&gt;
and shift-&lt;tab&gt; to move forward and back. Once you are in a
multi-checkbox field use the up and down cursor keys to select the
item you want, and &lt;space&gt; to toggle it on and off. Within
a directory field, pressing &lt;tab&gt; will provide autocomplete
options.
Generally the defaults are fine, and you can come back to this screen at
any time to tweak your system. Here are the options you can adjust:
- ***HuggingFace Access Token***
InvokeAI has the ability to download embedded styles and subjects
from the HuggingFace Concept Library on-demand. However, some of
the concept library files are password protected. To make download
smoother, you can set up an account at huggingface.co, obtain an
access token, and paste it into this field. Note that you paste
to this screen using ctrl-shift-V
- ***Free GPU memory after each generation***
This is useful for low-memory machines and helps minimize the
amount of GPU VRAM used by InvokeAI.
- ***Enable xformers support if available***
If the xformers library was successfully installed, this will activate
it to reduce memory consumption and increase rendering speed noticeably.
Note that xformers has the side effect of generating slightly different
images even when presented with the same seed and other settings.
- ***Force CPU to be used on GPU systems***
This will use the (slow) CPU rather than the accelerated GPU. This
can be used to generate images on systems that don't have a compatible
GPU.
- ***Precision***
This controls whether to use float32 or float16 arithmetic.
float16 uses less memory but is also slightly less accurate.
Ordinarily the right arithmetic is picked automatically ("auto"),
but you may have to use float32 to get images on certain systems
and graphics cards. The "autocast" option is deprecated and
shouldn't be used unless you are asked to by a member of the team.
- **Size of the RAM cache used for fast model switching***
This allows you to keep models in memory and switch rapidly among
them rather than having them load from disk each time. This slider
controls how many models to keep loaded at once. A typical SD-1 or SD-2 model
uses 2-3 GB of memory. A typical SDXL model uses 6-7 GB. Providing more
RAM will allow more models to be co-resident.
- ***Output directory for images***
This is the path to a directory in which InvokeAI will store all its
generated images.
- ***Autoimport Folder***
This is the directory in which you can place models you have
downloaded and wish to load into InvokeAI. You can place a variety
of models in this directory, including diffusers folders, .ckpt files,
.safetensors files, as well as LoRAs, ControlNet and Textual Inversion
files (both folder and file versions). To help organize this folder,
you can create several levels of subfolders and drop your models into
whichever ones you want.
- ***LICENSE***
At the bottom of the screen you will see a checkbox for accepting
the CreativeML Responsible AI Licenses. You need to accept the license
in order to download Stable Diffusion models from the next screen.
_You can come back to the startup options form_ as many times as you like.
From the `invoke.sh` or `invoke.bat` launcher, select option (6) to relaunch
this script. On the command line, it is named `invokeai-configure`.
11. **Downloading Models**: After you press `[NEXT]` on the screen, you will be taken
to another screen that prompts you to download a series of starter models. The ones
we recommend are preselected for you, but you are encouraged to use the checkboxes to
pick and choose.
You will probably wish to download `autoencoder-840000` for use with models that
were trained with an older version of the Stability VAE.
<figure markdown>
![select-models-screenshot](../assets/installer-walkthrough/installing-models.png)
</figure>
Below the preselected list of starter models is a large text field which you can use
to specify a series of models to import. You can specify models in a variety of formats,
each separated by a space or newline. The formats accepted are:
- The path to a .ckpt or .safetensors file. On most systems, you can drag a file from
the file browser to the textfield to automatically paste the path. Be sure to remove
extraneous quotation marks and other things that come along for the ride.
- The path to a directory containing a combination of `.ckpt` and `.safetensors` files.
The directory will be scanned from top to bottom (including subfolders) and any
file that can be imported will be.
- A URL pointing to a `.ckpt` or `.safetensors` file. You can cut
and paste directly from a web page, or simply drag the link from the web page
or navigation bar. (You can also use ctrl-shift-V to paste into this field)
The file will be downloaded and installed.
- The HuggingFace repository ID (repo_id) for a `diffusers` model. These IDs have
the format _author_name/model_name_, as in `andite/anything-v4.0`
- The path to a local directory containing a `diffusers`
model. These directories always have the file `model_index.json`
at their top level.
_Select a directory for models to import_ You may select a local
directory for autoimporting at startup time. If you select this
option, the directory you choose will be scanned for new
.ckpt/.safetensors files each time InvokeAI starts up, and any new
files will be automatically imported and made available for your
use.
_Convert imported models into diffusers_ When legacy checkpoint
files are imported, you may select to use them unmodified (the
default) or to convert them into `diffusers` models. The latter
load much faster and have slightly better rendering performance,
but not all checkpoint files can be converted. Note that Stable Diffusion
Version 2.X files are **only** supported in `diffusers` format and will
be converted regardless.
_You can come back to the model install form_ as many times as you like.
From the `invoke.sh` or `invoke.bat` launcher, select option (5) to relaunch
this script. On the command line, it is named `invokeai-model-install`.
12. **Running InvokeAI for the first time**: The script will now exit and you'll be ready to generate some images. Look
for the directory `invokeai` installed in the location you chose at the
beginning of the install session. Look for a shell script named `invoke.sh`
(Linux/Mac) or `invoke.bat` (Windows). Launch the script by double-clicking
it or typing its name at the command-line:
```cmd
C:\Documents\Linco> cd invokeai
C:\Documents\Linco\invokeAI> invoke.bat
```sh
install.sh
```
- The `invoke.bat` (`invoke.sh`) script will give you the choice
of starting (1) the command-line interface, (2) the web GUI, (3)
textual inversion training, and (4) model merging.
!!! info "Running the Installer from the commandline"
- By default, the script will launch the web interface. When you
do this, you'll see a series of startup messages ending with
instructions to point your browser at
http://localhost:9090. Click on this link to open up a browser
and start exploring InvokeAI's features.
You can also run the install script from cmd/powershell (Windows) or terminal (Linux/macOS).
12. **InvokeAI Options**: You can launch InvokeAI with several different command-line arguments that
customize its behavior. For example, you can change the location of the
image output directory or balance memory usage vs performance. See
[Configuration](../features/CONFIGURATION.md) for a full list of the options.
!!! warning "Untrusted Publisher (Windows)"
- To set defaults that will take effect every time you launch InvokeAI,
use a text editor (e.g. Notepad) to exit the file
`invokeai\invokeai.init`. It contains a variety of examples that you can
follow to add and modify launch options.
You may get a popup saying the file comes from an `Untrusted Publisher`. Click `More Info` and `Run Anyway` to get past this.
- The launcher script also offers you an option labeled "open the developer
console". If you choose this option, you will be dropped into a
command-line interface in which you can run python commands directly,
access developer tools, and launch InvokeAI with customized options.
The installation process is simple, with a few prompts:
- Select the version to install. Unless you have a specific reason to install a specific version, select the default (the latest version).
- Select location for the install. Be sure you have enough space in this folder for the base application, as described in the [installation requirements].
- Select a GPU device.
!!! warning "Do not move or remove the `invokeai` directory"
The `invokeai` directory contains the `invokeai` application, its
configuration files, the model weight files, and outputs of image generation.
Once InvokeAI is installed, do not move or remove this directory."
!!! info "Slow Installation"
The installer needs to download several GB of data and install it all. It may appear to get stuck at 99.9% when installing `pytorch` or during a step labeled "Installing collected packages".
<a name="troubleshooting"></a>
## Troubleshooting
If it is stuck for over 10 minutes, something has probably gone wrong and you should close the window and restart.
### _OSErrors on Windows while installing dependencies_
## Running the Application
During a zip file installation or an online update, installation stops
with an error like this:
Find the install location you selected earlier. Double-click the launcher script to run the app:
![broken-dependency-screenshot](../assets/troubleshooting/broken-dependency.png){:width="800px"}
=== "Windows"
This seems to happen particularly often with the `pydantic` and
`numpy` packages. The most reliable solution requires several manual
steps to complete installation.
```sh
invoke.bat
```
Open up a Powershell window and navigate to the `invokeai` directory
created by the installer. Then give the following series of commands:
=== "Linux/macOS"
```cmd
rm .\.venv -r -force
python -mvenv .venv
.\.venv\Scripts\activate
pip install invokeai
invokeai-configure --yes --root .
```sh
invoke.sh
```
Choose the first option to run the UI. After a series of startup messages, you'll see something like this:
```
Uvicorn running on http://127.0.0.1:9090 (Press CTRL+C to quit)
```
If you see anything marked as an error during this process please stop
and seek help on the Discord [installation support
channel](https://discord.com/channels/1020123559063990373/1041391462190956654). A
few warning messages are OK.
Copy the URL into your browser and you should see the UI.
If you are updating from a previous version, this should restore your
system to a working state. If you are installing from scratch, there
is one additional command to give:
## First-time Setup
```cmd
wget -O invoke.bat https://raw.githubusercontent.com/invoke-ai/InvokeAI/main/installer/templates/invoke.bat.in
```
You will need to [install some models] before you can generate.
This will create the `invoke.bat` script needed to launch InvokeAI and
its related programs.
Check the [configuration docs] for details on configuring the application.
## Updating
### _Stable Diffusion XL Generation Fails after Trying to Load unet_
Updating is exactly the same as installing - download the latest installer, choose the latest version and off you go.
InvokeAI is working in other respects, but when trying to generate
images with Stable Diffusion XL you get a "Server Error". The text log
in the launch window contains this log line above several more lines of
error messages:
!!! info "Dependency Resolution Issues"
```INFO --> Loading model:D:\LONG\PATH\TO\MODEL, type sdxl:main:unet```
We've found that pip's dependency resolution can cause issues when upgrading packages. One very common problem was pip "downgrading" torch from CUDA to CPU, but things broke in other novel ways.
This failure mode occurs when there is a network glitch during
downloading the very large SDXL model.
The installer doesn't have this kind of problem, so we use it for updating as well.
To address this, first go to the Web Model Manager and delete the
Stable-Diffusion-XL-base-1.X model. Then navigate to HuggingFace and
manually download the .safetensors version of the model. The 1.0
version is located at
https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/tree/main
and the file is named `sd_xl_base_1.0.safetensors`.
## Installation Issues
Save this file to disk and then reenter the Model Manager. Navigate to
Import Models->Add Model, then type (or drag-and-drop) the path to the
.safetensors file. Press "Add Model".
If you have installation issues, please review the [FAQ]. You can also [create an issue] or ask for help on [discord].
### _Package dependency conflicts_
If you have previously installed InvokeAI or another Stable Diffusion
package, the installer may occasionally pick up outdated libraries and
either the installer or `invoke` will fail with complaints about
library conflicts. In this case, run the `invoke.sh`/`invoke.bat`
command and enter the Developer's Console by picking option (5). This
will take you to a command-line prompt.
Then give this command:
`pip install InvokeAI --force-reinstall`
This should fix the issues.
### InvokeAI runs extremely slowly on Linux or Windows systems
The most frequent cause of this problem is when the installation
process installed the CPU-only version of the torch machine-learning
library, rather than a version that takes advantage of GPU
acceleration. To confirm this issue, look at the InvokeAI startup
messages. If you see a message saying ">> Using device CPU", then
this is what happened.
To fix this problem, first determine whether you have an NVidia or an
AMD GPU. The former uses the CUDA driver, and the latter uses ROCm
(only available on Linux). Then run the `invoke.sh`/`invoke.bat`
command and enter the Developer's Console by picking option (5). This
will take you to a command-line prompt.
Then type the following commands:
=== "NVIDIA System"
```bash
pip install torch torchvision --force-reinstall --extra-index-url https://download.pytorch.org/whl/cu121
pip install xformers
```
=== "AMD System"
```bash
pip install torch torchvision --force-reinstall --extra-index-url https://download.pytorch.org/whl/rocm5.6
```
### Corrupted configuration file
Everything seems to install ok, but `invokeai` complains of a corrupted
configuration file and goes back into the configuration process (asking you to
download models, etc), but this doesn't fix the problem.
This issue is often caused by a misconfigured configuration directive in the
`invokeai\invokeai.init` initialization file that contains startup settings. The
easiest way to fix the problem is to move the file out of the way and re-run
`invokeai-configure`. Enter the developer's console (option 3 of the launcher
script) and run this command:
```cmd
invokeai-configure --root=.
```
Note the dot (.) after `--root`. It is part of the command.
_If none of these maneuvers fixes the problem_ then please report the problem to
the [InvokeAI Issues](https://github.com/invoke-ai/InvokeAI/issues) section, or
visit our [Discord Server](https://discord.gg/ZmtBAhwWhy) for interactive
assistance.
### Out of Memory Issues
The models are large, VRAM is expensive, and you may find yourself
faced with Out of Memory errors when generating images. Here are some
tips to reduce the problem:
* **4 GB of VRAM**
This should be adequate for 512x512 pixel images using Stable Diffusion 1.5
and derived models, provided that you **disable** the NSFW checker. To
disable the filter, do one of the following:
* Select option (6) "_change InvokeAI startup options_" from the
launcher. This will bring up the console-based startup settings
dialogue and allow you to unselect the "NSFW Checker" option.
* Start the startup settings dialogue directly by running
`invokeai-configure --skip-sd-weights --skip-support-models`
from the command line.
* Find the `invokeai.init` initialization file in the InvokeAI root
directory, open it in a text editor, and change `--nsfw_checker`
to `--no-nsfw_checker`
If you are on a CUDA system, you can realize significant memory
savings by activating the `xformers` library as described above. The
downside is `xformers` introduces non-deterministic behavior, such
that images generated with exactly the same prompt and settings will
be slightly different from each other. See above for more information.
* **6 GB of VRAM**
This is a border case. Using the SD 1.5 series you should be able to
generate images up to 640x640 with the NSFW checker enabled, and up to
1024x1024 with it disabled and `xformers` activated.
If you run into persistent memory issues there are a series of
environment variables that you can set before launching InvokeAI that
alter how the PyTorch machine learning library manages memory. See
https://pytorch.org/docs/stable/notes/cuda.html#memory-management for
a list of these tweaks.
* **12 GB of VRAM**
This should be sufficient to generate larger images up to about
1280x1280. If you wish to push further, consider activating
`xformers`.
### Other Problems
If you run into problems during or after installation, the InvokeAI team is
available to help you. Either create an
[Issue](https://github.com/invoke-ai/InvokeAI/issues) at our GitHub site, or
make a request for help on the "bugs-and-support" channel of our
[Discord server](https://discord.gg/ZmtBAhwWhy). We are a 100% volunteer
organization, but typically somebody will be available to help you within 24
hours, and often much sooner.
## Updating to newer versions
This distribution is changing rapidly, and we add new features
regularly. Releases are announced at
http://github.com/invoke-ai/InvokeAI/releases, and at
https://pypi.org/project/InvokeAI/ To update to the latest released
version (recommended), follow these steps:
1. Start the `invoke.sh`/`invoke.bat` launch script from within the
`invokeai` root directory.
2. Choose menu item (10) "Update InvokeAI".
3. This will launch a menu that gives you the option of:
1. Updating to the latest official release;
2. Updating to the bleeding-edge development version; or
3. Manually entering the tag or branch name of a version of
InvokeAI you wish to try out.
[installation requirements]: INSTALL_REQUIREMENTS.md
[FAQ]: ../help/FAQ.md
[install some models]: 050_INSTALLING_MODELS.md
[configuration docs]: ../features/CONFIGURATION.md
[latest release]: https://github.com/invoke-ai/InvokeAI/releases/latest
[create an issue]: https://github.com/invoke-ai/InvokeAI/issues
[discord]: https://discord.gg/ZmtBAhwWhy

View File

@ -1,122 +1,55 @@
---
title: Installing Manually
---
<figure markdown>
# :fontawesome-brands-linux: Linux | :fontawesome-brands-apple: macOS | :fontawesome-brands-windows: Windows
</figure>
# Manual Install
!!! warning "This is for Advanced Users"
**Python experience is mandatory**
**Python experience is mandatory.**
## Introduction
!!! tip "Conda"
As of InvokeAI v2.3.0 installation using the `conda` package manager is no longer being supported. It will likely still work, but we are not testing this installation method.
InvokeAI is distributed as a python package on PyPI, installable with `pip`. There are a few things that are handled by the installer and launcher that you'll need to manage manually, described in this guide.
On Windows systems, you are encouraged to install and use the
[PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.3),
which provides compatibility with Linux and Mac shells and nice
features such as command-line completion.
### Requirements
### Prerequisites
Before you start, make sure you have the following preqrequisites
installed. These are described in more detail in [Automated
Installation](010_INSTALL_AUTOMATED.md), and in many cases will
already be installed (if, for example, you have used your system for
gaming):
* **Python**
version 3.10 through 3.11
* **CUDA Tools**
For those with _NVidia GPUs_, you will need to
install the [CUDA toolkit and optionally the XFormers library](070_INSTALL_XFORMERS.md).
* **ROCm Tools**
For _Linux users with AMD GPUs_, you will need
to install the [ROCm toolkit](./030_INSTALL_CUDA_AND_ROCM.md). Note that
InvokeAI does not support AMD GPUs on Windows systems due to
lack of a Windows ROCm library.
* **Visual C++ Libraries**
_Windows users_ must install the free
[Visual C++ libraries from Microsoft](https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170)
* **The Xcode command line tools**
for _Macintosh users_. Instructions are available at
[Free Code Camp](https://www.freecodecamp.org/news/install-xcode-command-line-tools/)
* _Macintosh users_ may also need to run the `Install Certificates` command
if model downloads give lots of certificate errors. Run:
`/Applications/Python\ 3.10/Install\ Certificates.command`
Before you start, go through the [installation requirements](./INSTALL_REQUIREMENTS.md).
### Installation Walkthrough
To install InvokeAI with virtual environments and the PIP package
manager, please follow these steps:
1. Please make sure you are using Python 3.10 through 3.11. The rest of the install
procedure depends on this and will not work with other versions:
```bash
python -V
```
2. Create a directory to contain your InvokeAI library, configuration
1. Create a directory to contain your InvokeAI library, configuration
files, and models. This is known as the "runtime" or "root"
directory, and often lives in your home directory under the name `invokeai`.
Please keep in mind the disk space requirements - you will need at
least 20GB for the models and the virtual environment. From now
on we will refer to this directory as `INVOKEAI_ROOT`. For convenience,
the steps below create a shell variable of that name which contains the
path to `HOME/invokeai`.
We will refer to this directory as `INVOKEAI_ROOT`. For convenience, create an environment variable pointing to the directory.
=== "Linux/Mac"
=== "Linux/macOS"
```bash
export INVOKEAI_ROOT=~/invokeai
mkdir $INVOKEAI_ROOT
```
=== "Windows (Powershell)"
=== "Windows (PowerShell)"
```bash
Set-Variable -Name INVOKEAI_ROOT -Value $Home/invokeai
mkdir $INVOKEAI_ROOT
```
3. Enter the root (invokeai) directory and create a virtual Python
environment within it named `.venv`. If the command `python`
doesn't work, try `python3`. Note that while you may create the
virtual environment anywhere in the file system, we recommend that
you create it within the root directory as shown here. This makes
it possible for the InvokeAI applications to find the model data
and configuration. If you do not choose to install the virtual
environment inside the root directory, then you **must** set the
`INVOKEAI_ROOT` environment variable in your shell environment, for
example, by editing `~/.bashrc` or `~/.zshrc` files, or setting the
Windows environment variable using the Advanced System Settings dialogue.
Refer to your operating system documentation for details.
1. Enter the root (invokeai) directory and create a virtual Python environment within it named `.venv`.
!!! warning "Virtual Environment Location"
While you may create the virtual environment anywhere in the file system, we recommend that you create it within the root directory as shown here. This allows the application to automatically detect its data directories.
If you choose a different location for the venv, then you _must_ set the `INVOKEAI_ROOT` environment variable or specify the root directory using the `--root` CLI arg.
```terminal
cd $INVOKEAI_ROOT
python -m venv .venv --prompt InvokeAI
python3 -m venv .venv --prompt InvokeAI
```
4. Activate the new environment:
1. Activate the new environment:
=== "Linux/Mac"
=== "Linux/macOS"
```bash
source .venv/bin/activate
@ -128,51 +61,43 @@ manager, please follow these steps:
.venv\Scripts\activate
```
!!! info "Permissions Error (Windows)"
If you get a permissions error at this point, run this command and try again
`Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser`
The command-line prompt should change to to show `(InvokeAI)` at the
beginning of the prompt. Note that all the following steps should be
run while inside the INVOKEAI_ROOT directory
The command-line prompt should change to to show `(InvokeAI)` at the beginning of the prompt.
5. Make sure that pip is installed in your virtual environment and up to date:
The following steps should be run while inside the `INVOKEAI_ROOT` directory.
1. Make sure that pip is installed in your virtual environment and up to date:
```bash
python -m pip install --upgrade pip
python3 -m pip install --upgrade pip
```
6. Install the InvokeAI Package. The `--extra-index-url` option is used to select among
CUDA, ROCm and CPU/MPS drivers as shown below:
1. Install the InvokeAI Package. The base command is `pip install InvokeAI --use-pep517`, but you may need to change this depending on your system and the desired features.
=== "CUDA (NVidia)"
- You may need to provide an [extra index URL](https://pip.pypa.io/en/stable/cli/pip_install/#cmdoption-extra-index-url). Select your platform configuration using [this tool on the PyTorch website](https://pytorch.org/get-started/locally/). Copy the `--extra-index-url` string from this and append it to your install command.
```bash
pip install "InvokeAI[xformers]" --use-pep517 --extra-index-url https://download.pytorch.org/whl/cu121
```
!!! example "Install with an extra index URL"
=== "ROCm (AMD)"
```bash
pip install InvokeAI --use-pep517 --extra-index-url https://download.pytorch.org/whl/cu121
```
```bash
pip install InvokeAI --use-pep517 --extra-index-url https://download.pytorch.org/whl/rocm5.6
```
- If you have a CUDA GPU and want to install with `xformers`, you need to add an option to the package name. Note that `xformers` is not necessary. PyTorch includes an implementation of the SDP attention algorithm with the same performance.
=== "CPU (Intel Macs & non-GPU systems)"
!!! example "Install with `xformers`"
```bash
pip install InvokeAI --use-pep517 --extra-index-url https://download.pytorch.org/whl/cpu
```
```bash
pip install "InvokeAI[xformers]" --use-pep517
```
=== "MPS (M1 and M2 Macs)"
1. Deactivate and reactivate your runtime directory so that the invokeai-specific commands become available in the environment:
```bash
pip install InvokeAI --use-pep517
```
7. Deactivate and reactivate your runtime directory so that the invokeai-specific commands
become available in the environment
=== "Linux/Macintosh"
=== "Linux/macOS"
```bash
deactivate && source .venv/bin/activate
@ -185,221 +110,10 @@ manager, please follow these steps:
.venv\Scripts\activate
```
8. Set up the runtime directory
1. Run the application:
In this step you will initialize your runtime directory with the downloaded
models, model config files, directory for textual inversion embeddings, and
your outputs.
```terminal
invokeai-configure --root .
```
Don't miss the dot at the end of the command!
The script `invokeai-configure` will interactively guide you through the
process of downloading and installing the weights files needed for InvokeAI.
Note that the main Stable Diffusion weights file is protected by a license
agreement that you have to agree to. The script will list the steps you need
to take to create an account on the site that hosts the weights files,
accept the agreement, and provide an access token that allows InvokeAI to
legally download and install the weights files.
If you get an error message about a module not being installed, check that
the `invokeai` environment is active and if not, repeat step 5.
!!! tip
If you have already downloaded the weights file(s) for another Stable
Diffusion distribution, you may skip this step (by selecting "skip" when
prompted) and configure InvokeAI to use the previously-downloaded files. The
process for this is described in [Installing Models](050_INSTALLING_MODELS.md).
9. Run the command-line- or the web- interface:
From within INVOKEAI_ROOT, activate the environment
(with `source .venv/bin/activate` or `.venv\scripts\activate`), and then run
the script `invokeai`. If the virtual environment you selected is NOT inside
INVOKEAI_ROOT, then you must specify the path to the root directory by adding
`--root_dir \path\to\invokeai` to the commands below:
!!! example ""
!!! warning "Make sure that the virtual environment is activated, which should create `(.venv)` in front of your prompt!"
=== "local Webserver"
```bash
invokeai-web
```
=== "Public Webserver"
```bash
invokeai-web --host 0.0.0.0
```
=== "CLI"
```bash
invokeai
```
If you choose the run the web interface, point your browser at
http://localhost:9090 in order to load the GUI.
!!! tip
You can permanently set the location of the runtime directory
by setting the environment variable `INVOKEAI_ROOT` to the
path of the directory. As mentioned previously, this is
*highly recommended** if your virtual environment is located outside of
your runtime directory.
!!! tip
On linux, it is recommended to run invokeai with the following env var: `MALLOC_MMAP_THRESHOLD_=1048576`. For example: `MALLOC_MMAP_THRESHOLD_=1048576 invokeai --web`. This helps to prevent memory fragmentation that can lead to memory accumulation over time. This env var is set automatically when running via `invoke.sh`.
10. Render away!
Browse the [features](../features/index.md) section to learn about all the
things you can do with InvokeAI.
11. Subsequently, to relaunch the script, activate the virtual environment, and
then launch `invokeai` command. If you forget to activate the virtual
environment you will most likeley receive a `command not found` error.
Run `invokeai-web` to start the UI. You must activate the virtual environment before running the app.
!!! warning
Do not move the runtime directory after installation. The virtual environment will get confused if the directory is moved.
12. Other scripts
The [Textual Inversion](../features/TRAINING.md) script can be launched with the command:
```bash
invokeai-ti --gui
```
Similarly, the [Model Merging](../features/MODEL_MERGING.md) script can be launched with the command:
```bash
invokeai-merge --gui
```
Leave off the `--gui` option to run the script using command-line arguments. Pass the `--help` argument
to get usage instructions.
## Developer Install
!!! warning
InvokeAI uses a SQLite database. By running on `main`, you accept responsibility for your database. This
means making regular backups (especially before pulling) and/or fixing it yourself in the event that a
PR introduces a schema change.
If you don't need persistent backend storage, you can use an ephemeral in-memory database by setting
`use_memory_db: true` under `Path:` in your `invokeai.yaml` file.
If this is untenable, you should run the application via the official installer or a manual install of the
python package from pypi. These releases will not break your database.
If you have an interest in how InvokeAI works, or you would like to
add features or bugfixes, you are encouraged to install the source
code for InvokeAI. For this to work, you will need to install the
`git` source code management program. If it is not already installed
on your system, please see the [Git Installation
Guide](https://github.com/git-guides/install-git)
You will also need to install the [frontend development toolchain](https://github.com/invoke-ai/InvokeAI/blob/main/invokeai/frontend/web/README.md).
If you have a "normal" installation, you should create a totally separate virtual environment for the git-based installation, else the two may interfere.
> **Why do I need the frontend toolchain**?
>
> The InvokeAI project uses trunk-based development. That means our `main` branch is the development branch, and releases are tags on that branch. Because development is very active, we don't keep an updated build of the UI in `main` - we only build it for production releases.
>
> That means that between releases, to have a functioning application when running directly from the repo, you will need to run the UI in dev mode or build it regularly (any time the UI code changes).
1. Create a fork of the InvokeAI repository through the GitHub UI or [this link](https://github.com/invoke-ai/InvokeAI/fork)
2. From the command line, run this command:
```bash
git clone https://github.com/<your_github_username>/InvokeAI.git
```
This will create a directory named `InvokeAI` and populate it with the
full source code from your fork of the InvokeAI repository.
3. Activate the InvokeAI virtual environment as per step (4) of the manual
installation protocol (important!)
4. Enter the InvokeAI repository directory and run one of these
commands, based on your GPU:
=== "CUDA (NVidia)"
```bash
pip install -e .[xformers] --use-pep517 --extra-index-url https://download.pytorch.org/whl/cu121
```
=== "ROCm (AMD)"
```bash
pip install -e . --use-pep517 --extra-index-url https://download.pytorch.org/whl/rocm5.6
```
=== "CPU (Intel Macs & non-GPU systems)"
```bash
pip install -e . --use-pep517 --extra-index-url https://download.pytorch.org/whl/cpu
```
=== "MPS (M1 and M2 Macs)"
```bash
pip install -e . --use-pep517
```
Be sure to pass `-e` (for an editable install) and don't forget the
dot ("."). It is part of the command.
5. Install the [frontend toolchain](https://github.com/invoke-ai/InvokeAI/blob/main/invokeai/frontend/web/README.md) and do a production build of the UI as described.
6. You can now run `invokeai` and its related commands. The code will be
read from the repository, so that you can edit the .py source files
and watch the code's behavior change.
When you pull in new changes to the repo, be sure to re-build the UI.
7. If you wish to contribute to the InvokeAI project, you are
encouraged to establish a GitHub account and "fork"
https://github.com/invoke-ai/InvokeAI into your own copy of the
repository. You can then use GitHub functions to create and submit
pull requests to contribute improvements to the project.
Please see [Contributing](../index.md#contributing) for hints
on getting started.
### Unsupported Conda Install
Congratulations, you found the "secret" Conda installation
instructions. If you really **really** want to use Conda with InvokeAI
you can do so using this unsupported recipe:
```
mkdir ~/invokeai
conda create -n invokeai python=3.10
conda activate invokeai
pip install InvokeAI[xformers] --use-pep517 --extra-index-url https://download.pytorch.org/whl/cu121
invokeai-configure --root ~/invokeai
invokeai --root ~/invokeai --web
```
The `pip install` command shown in this recipe is for Linux/Windows
systems with an NVIDIA GPU. See step (6) above for the command to use
with other platforms/GPU combinations. If you don't wish to pass the
`--root` argument to `invokeai` with each launch, you may set the
environment variable INVOKEAI_ROOT to point to the installation directory.
Note that if you run into problems with the Conda installation, the InvokeAI
staff will **not** be able to help you out. Caveat Emptor!
[dev-chat]: https://discord.com/channels/1020123559063990373/1049495067846524939
If the virtual environment is _not_ inside the root directory, then you _must_ specify the path to the root directory with `--root \path\to\invokeai` or the `INVOKEAI_ROOT` environment variable.

View File

@ -1,149 +0,0 @@
---
title: NVIDIA Cuda / AMD ROCm
---
<figure markdown>
# :simple-nvidia: CUDA | :simple-amd: ROCm
</figure>
In order for InvokeAI to run at full speed, you will need a graphics
card with a supported GPU. InvokeAI supports NVidia cards via the CUDA
driver on Windows and Linux, and AMD cards via the ROCm driver on Linux.
## :simple-nvidia: CUDA
### Linux and Windows Install
If you have used your system for other graphics-intensive tasks, such
as gaming, you may very well already have the CUDA drivers
installed. To confirm, open up a command-line window and type:
```
nvidia-smi
```
If this command produces a status report on the GPU(s) installed on
your system, CUDA is installed and you have no more work to do. If
instead you get "command not found", or similar, then the driver will
need to be installed.
We strongly recommend that you install the CUDA Toolkit package
directly from NVIDIA. **Do not try to install Ubuntu's
nvidia-cuda-toolkit package. It is out of date and will cause
conflicts among the NVIDIA driver and binaries.**
Go to [CUDA Toolkit
Downloads](https://developer.nvidia.com/cuda-downloads), and use the
target selection wizard to choose your operating system, hardware
platform, and preferred installation method (e.g. "local" versus
"network").
This will provide you with a downloadable install file or, depending
on your choices, a recipe for downloading and running a install shell
script. Be sure to read and follow the full installation instructions.
After an install that seems successful, you can confirm by again
running `nvidia-smi` from the command line.
### Linux Install with a Runtime Container
On Linux systems, an alternative to installing CUDA Toolkit directly on
your system is to run an NVIDIA software container that has the CUDA
libraries already in place. This is recommended if you are already
familiar with containerization technologies such as Docker.
For downloads and instructions, visit the [NVIDIA CUDA Container
Runtime Site](https://developer.nvidia.com/nvidia-container-runtime)
### cuDNN Installation for 40/30 Series Optimization* (Optional)
1. Find the InvokeAI folder
2. Click on .venv folder - e.g., YourInvokeFolderHere\\.venv
3. Click on Lib folder - e.g., YourInvokeFolderHere\\.venv\Lib
4. Click on site-packages folder - e.g., YourInvokeFolderHere\\.venv\Lib\site-packages
5. Click on Torch directory - e.g., YourInvokeFolderHere\InvokeAI\\.venv\Lib\site-packages\torch
6. Click on the lib folder - e.g., YourInvokeFolderHere\\.venv\Lib\site-packages\torch\lib
7. Copy everything inside the folder and save it elsewhere as a backup.
8. Go to __https://developer.nvidia.com/cudnn__
9. Login or create an Account.
10. Choose the newer version of cuDNN. **Note:**
There are two versions, 11.x or 12.x for the differents architectures(Turing,Maxwell Etc...) of GPUs.
You can find which version you should download from [this link](https://docs.nvidia.com/deeplearning/cudnn/support-matrix/index.html).
13. Download the latest version and extract it from the download location
14. Find the bin folder E\cudnn-windows-x86_64-__Whatever Version__\bin
15. Copy and paste the .dll files into YourInvokeFolderHere\\.venv\Lib\site-packages\torch\lib **Make sure to copy, and not move the files**
16. If prompted, replace any existing files
**Notes:**
* If no change is seen or any issues are encountered, follow the same steps as above and paste the torch/lib backup folder you made earlier and replace it. If you didn't make a backup, you can also uninstall and reinstall torch through the command line to repair this folder.
* This optimization is intended for the newer version of graphics card (40/30 series) but results have been seen with older graphics card.
### Torch Installation
When installing torch and torchvision manually with `pip`, remember to provide
the argument `--extra-index-url
https://download.pytorch.org/whl/cu121` as described in the [Manual
Installation Guide](020_INSTALL_MANUAL.md).
## :simple-amd: ROCm
### Linux Install
AMD GPUs are only supported on Linux platforms due to the lack of a
Windows ROCm driver at the current time. Also be aware that support
for newer AMD GPUs is spotty. Your mileage may vary.
It is possible that the ROCm driver is already installed on your
machine. To test, open up a terminal window and issue the following
command:
```
rocm-smi
```
If you get a table labeled "ROCm System Management Interface" the
driver is installed and you are done. If you get "command not found,"
then the driver needs to be installed.
Go to AMD's [ROCm Downloads
Guide](https://rocmdocs.amd.com/en/latest/Installation_Guide/Installation_new.html#installation-methods)
and scroll to the _Installation Methods_ section. Find the subsection
for the install method for your preferred Linux distribution, and
issue the commands given in the recipe.
Annoyingly, the official AMD site does not have a recipe for the most
recent version of Ubuntu, 22.04. However, this [community-contributed
recipe](https://novaspirit.github.io/amdgpu-rocm-ubu22/) is reported
to work well.
After installation, please run `rocm-smi` a second time to confirm
that the driver is present and the GPU is recognized. You may need to
do a reboot in order to load the driver.
### Linux Install with a ROCm-docker Container
If you are comfortable with the Docker containerization system, then
you can build a ROCm docker file. The source code and installation
recipes are available
[Here](https://github.com/RadeonOpenCompute/ROCm-docker/blob/master/quick-start.md)
### Torch Installation
When installing torch and torchvision manually with `pip`, remember to provide
the argument `--extra-index-url
https://download.pytorch.org/whl/rocm5.6` as described in the [Manual
Installation Guide](020_INSTALL_MANUAL.md).
This will be done automatically for you if you use the installer
script.
Be aware that the torch machine learning library does not seamlessly
interoperate with all AMD GPUs and you may experience garbled images,
black images, or long startup delays before rendering commences. Most
of these issues can be solved by Googling for workarounds. If you have
a problem and find a solution, please post an
[Issue](https://github.com/invoke-ai/InvokeAI/issues) so that other
users benefit and we can update this document.

View File

@ -4,50 +4,37 @@ title: Installing with Docker
# :fontawesome-brands-docker: Docker
!!! warning "macOS and AMD GPU Users"
!!! warning "macOS users"
We highly recommend to Install InvokeAI locally using [these instructions](INSTALLATION.md),
because Docker containers can not access the GPU on macOS.
!!! warning "AMD GPU Users"
Container support for AMD GPUs has been reported to work by the community, but has not received
extensive testing. Please make sure to set the `GPU_DRIVER=rocm` environment variable (see below), and
use the `build.sh` script to build the image for this to take effect at build time.
Docker can not access the GPU on macOS, so your generation speeds will be slow. [Install InvokeAI](INSTALLATION.md) instead.
!!! tip "Linux and Windows Users"
For optimal performance, configure your Docker daemon to access your machine's GPU.
Configure Docker to access your machine's GPU.
Docker Desktop on Windows [includes GPU support](https://www.docker.com/blog/wsl-2-gpu-support-for-docker-desktop-on-nvidia-gpus/).
Linux users should install and configure the [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html)
## Why containers?
They provide a flexible, reliable way to build and deploy InvokeAI.
See [Processes](https://12factor.net/processes) under the Twelve-Factor App
methodology for details on why running applications in such a stateless fashion is important.
The container is configured for CUDA by default, but can be built to support AMD GPUs
by setting the `GPU_DRIVER=rocm` environment variable at Docker image build time.
Developers on Apple silicon (M1/M2/M3): You
[can't access your GPU cores from Docker containers](https://github.com/pytorch/pytorch/issues/81224)
and performance is reduced compared with running it directly on macOS but for
development purposes it's fine. Once you're done with development tasks on your
laptop you can build for the target platform and architecture and deploy to
another environment with NVIDIA GPUs on-premises or in the cloud.
Linux users should follow the [NVIDIA](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) or [AMD](https://rocm.docs.amd.com/projects/install-on-linux/en/latest/how-to/docker.html) documentation.
## TL;DR
This assumes properly configured Docker on Linux or Windows/WSL2. Read on for detailed customization options.
Ensure your Docker setup is able to use your GPU. Then:
```bash
docker run --runtime=nvidia --gpus=all --publish 9090:9090 ghcr.io/invoke-ai/invokeai
```
Once the container starts up, open http://localhost:9090 in your browser, install some models, and start generating.
## Build-It-Yourself
All the docker materials are located inside the [docker](https://github.com/invoke-ai/InvokeAI/tree/main/docker) directory in the Git repo.
```bash
# docker compose commands should be run from the `docker` directory
cd docker
cp .env.sample .env
docker compose up
```
## Installation in a Linux container (desktop)
We also ship the `run.sh` convenience script. See the `docker/README.md` file for detailed instructions on how to customize the docker setup to your needs.
### Prerequisites
@ -58,18 +45,9 @@ Preferences, Resources, Advanced. Increase the CPUs and Memory to avoid this
[Issue](https://github.com/invoke-ai/InvokeAI/issues/342). You may need to
increase Swap and Disk image size too.
#### Get a Huggingface-Token
Besides the Docker Agent you will need an Account on
[huggingface.co](https://huggingface.co/join).
After you succesfully registered your account, go to
[huggingface.co/settings/tokens](https://huggingface.co/settings/tokens), create
a token and copy it, since you will need in for the next step.
### Setup
Set up your environmnent variables. In the `docker` directory, make a copy of `.env.sample` and name it `.env`. Make changes as necessary.
Set up your environment variables. In the `docker` directory, make a copy of `.env.sample` and name it `.env`. Make changes as necessary.
Any environment variables supported by InvokeAI can be set here - please see the [CONFIGURATION](../features/CONFIGURATION.md) for further detail.
@ -103,10 +81,9 @@ Once the container starts up (and configures the InvokeAI root directory if this
## Troubleshooting / FAQ
- Q: I am running on Windows under WSL2, and am seeing a "no such file or directory" error.
- A: Your `docker-entrypoint.sh` file likely has Windows (CRLF) as opposed to Unix (LF) line endings,
and you may have cloned this repository before the issue was fixed. To solve this, please change
the line endings in the `docker-entrypoint.sh` file to `LF`. You can do this in VSCode
- A: Your `docker-entrypoint.sh` might have has Windows (CRLF) line endings, depending how you cloned the repository.
To solve this, change the line endings in the `docker-entrypoint.sh` file to `LF`. You can do this in VSCode
(`Ctrl+P` and search for "line endings"), or by using the `dos2unix` utility in WSL.
Finally, you may delete `docker-entrypoint.sh` followed by `git pull; git checkout docker/docker-entrypoint.sh`
to reset the file to its most recent version.
For more information on this issue, please see the [Docker Desktop documentation](https://docs.docker.com/desktop/troubleshoot/topics/#avoid-unexpected-syntax-errors-use-unix-style-line-endings-for-files-in-containers)
For more information on this issue, see [Docker Desktop documentation](https://docs.docker.com/desktop/troubleshoot/topics/#avoid-unexpected-syntax-errors-use-unix-style-line-endings-for-files-in-containers)

View File

@ -1,186 +1,52 @@
---
title: Installing Models
---
# :octicons-paintbrush-16: Installing Models
# Installing Models
## Checkpoint and Diffusers Models
The model checkpoint files ('\*.ckpt') are the Stable Diffusion
"secret sauce". They are the product of training the AI on millions of
captioned images gathered from multiple sources.
The model checkpoint files (`*.ckpt`) are the Stable Diffusion "secret sauce". They are the product of training the AI on millions of captioned images gathered from multiple sources.
Originally there was only a single Stable Diffusion weights file,
which many people named `model.ckpt`. Now there are dozens or more
that have been fine tuned to provide particulary styles, genres, or
other features. In addition, there are several new formats that
improve on the original checkpoint format: a `.safetensors` format
which prevents malware from masquerading as a model, and `diffusers`
models, the most recent innovation.
Originally there was only a single Stable Diffusion weights file, which many people named `model.ckpt`.
InvokeAI supports all three formats but strongly prefers the
`diffusers` format. These are distributed as directories containing
multiple subfolders, each of which contains a different aspect of the
model. The advantage of this is that the models load from disk really
fast. Another advantage is that `diffusers` models are supported by a
large and active set of open source developers working at and with
HuggingFace organization, and improvements in both rendering quality
and performance are being made at a rapid pace. Among other features
is the ability to download and install a `diffusers` model just by
providing its HuggingFace repository ID.
Today, there are thousands of models, fine tuned to excel at specific styles, genres, or themes.
While InvokeAI will continue to support `.ckpt` and `.safetensors`
models for the near future, these are deprecated and support will
likely be withdrawn at some point in the not-too-distant future.
!!! tip "Model Formats"
This manual will guide you through installing and configuring model
weight files and converting legacy `.ckpt` and `.safetensors` files
into performant `diffusers` models.
We also have two more popular model formats, both created [HuggingFace](https://huggingface.co/):
## Base Models
- `safetensors`: Single file, like `.ckpt` files. Prevents malware from lurking in a model.
- `diffusers`: Splits the model components into separate files, allowing very fast loading.
InvokeAI comes with support for a good set of starter models. You'll
find them listed in the master models file
`configs/INITIAL_MODELS.yaml` in the InvokeAI root directory. The
subset that are currently installed are found in
`configs/models.yaml`.
InvokeAI supports all three formats. Our backend will convert models to `diffusers` format before running them. This is a transparent process.
Note that these files are covered by an "Ethical AI" license which
forbids certain uses. When you initially download them, you are asked
to accept the license terms. In addition, some of these models carry
additional license terms that limit their use in commercial
applications or on public servers. Be sure to familiarize yourself
with the model terms by visiting the URLs in the table above.
## Starter Models
## Community-Contributed Models
When you first start InvokeAI, you'll see a popup prompting you to install some starter models from the Model Manager. Click the `Starter Models` tab to see the list.
[HuggingFace](https://huggingface.co/models?library=diffusers)
is a great resource for diffusers models, and is also the home of a
[fast-growing repository](https://huggingface.co/sd-concepts-library)
of embedding (".bin") models that add subjects and/or styles to your
images. The latter are automatically installed on the fly when you
include the text `<concept-name>` in your prompt. See [Concepts
Library](../features/CONCEPTS.md) for more information.
You'll find a collection of popular and high-quality models available for easy download.
Another popular site for community-contributed models is
[CIVITAI](https://civitai.com). This extensive site currently supports
only `.safetensors` and `.ckpt` models, but they can be easily loaded
into InvokeAI and/or converted into optimized `diffusers` models. Be
aware that CIVITAI hosts many models that generate NSFW content.
Some models carry license terms that limit their use in commercial applications or on public servers. It's your responsibility to adhere to the license terms.
## Installation
## Other Models
There are two ways to install and manage models:
You can install other models using the Model Manager. You'll find tabs for the following install methods:
1. The `invokeai-model-install` script which will download and install
them for you. In addition to supporting main models, you can install
ControlNet, LoRA and Textual Inversion models.
- **URL or Local Path**: Provide the path to a model on your computer, or a direct link to the model. Some sites require you to use an API token to download models, which you can [set up in the config file].
- **HuggingFace**: Paste a HF Repo ID to install it. If there are multiple models in the repo, you'll get a list to choose from. Repo IDs look like this: `XpucT/Deliberate`. There is a copy button on each repo to copy the ID.
- **Scan Folder**: Scan a local folder for models. You can install all of the detected models in one click.
2. The web interface (WebUI) has a GUI for importing and managing
models.
!!! tip "Autoimport"
3. By placing models (or symbolic links to models) inside one of the
InvokeAI root directory's `autoimport` folder.
The dedicated autoimport folder is removed as of v4.0.0. You can do the same thing on the **Scan Folder** tab - paste the folder you'd like to import from and then click `Install All`.
### Installation via `invokeai-model-install`
### Diffusers models in HF repo subfolders
From the `invoke` launcher, choose option [4] "Download and install
models." This will launch the same script that prompted you to select
models at install time. You can use this to add models that you
skipped the first time around. It is all right to specify a model that
was previously downloaded; the script will just confirm that the files
are complete.
HuggingFace repos can be structured in any way. Some model authors include multiple models within the same folder.
The installer has different panels for installing main models from
HuggingFace, models from Civitai and other arbitrary web sites,
ControlNet models, LoRA/LyCORIS models, and Textual Inversion
embeddings. Each section has a text box in which you can enter a new
model to install. You can refer to a model using its:
In this situation, you may need to provide some additional information to identify the model you want, by adding `:subfolder_name` to the repo ID.
1. Local path to the .ckpt, .safetensors or diffusers folder on your local machine
2. A directory on your machine that contains multiple models
3. A URL that points to a downloadable model
4. A HuggingFace repo id
!!! example
Previously-installed models are shown with checkboxes. Uncheck a box
to unregister the model from InvokeAI. Models that are physically
installed inside the InvokeAI root directory will be deleted and
purged (after a confirmation warning). Models that are located outside
the InvokeAI root directory will be unregistered but not deleted.
Say you have a repo ID `monster-labs/control_v1p_sd15_qrcode_monster`, and the model you want is inside the `v2` subfolder.
Note: The installer script uses a console-based text interface that requires
significant amounts of horizontal and vertical space. If the display
looks messed up, just enlarge the terminal window and/or relaunch the
script.
Add `:v2` to the repo ID and use that when installing the model: `monster-labs/control_v1p_sd15_qrcode_monster:v2`
If you wish you can script model addition and deletion, as well as
listing installed models. Start the "developer's console" and give the
command `invokeai-model-install --help`. This will give you a series
of command-line parameters that will let you control model
installation. Examples:
```
# (list all controlnet models)
invokeai-model-install --list controlnet
# (install the model at the indicated URL)
invokeai-model-install --add https://civitai.com/api/download/models/128713
# (delete the named model)
invokeai-model-install --delete sd-1/main/analog-diffusion
```
### Installation via the Web GUI
To install a new model using the Web GUI, do the following:
1. Open the InvokeAI Model Manager (cube at the bottom of the
left-hand panel) and navigate to *Import Models*
2. In the field labeled *Location* type in the path to the model you
wish to install. You may use a URL, HuggingFace repo id, or a path on
your local disk.
3. Alternatively, the *Scan for Models* button allows you to paste in
the path to a folder somewhere on your machine. It will be scanned for
importable models and prompt you to add the ones of your choice.
4. Press *Add Model* and wait for confirmation that the model
was added.
To delete a model, Select *Model Manager* to list all the currently
installed models. Press the trash can icons to delete any models you
wish to get rid of. Models whose weights are located inside the
InvokeAI `models` directory will be purged from disk, while those
located outside will be unregistered from InvokeAI, but not deleted.
You can see where model weights are located by clicking on the model name.
This will bring up an editable info panel showing the model's characteristics,
including the `Model Location` of its files.
### Installation via the `autoimport` function
In the InvokeAI root directory you will find a series of folders under
`autoimport`, one each for main models, controlnets, embeddings and
Loras. Any models that you add to these directories will be scanned
at startup time and registered automatically.
You may create symbolic links from these folders to models located
elsewhere on disk and they will be autoimported. You can also create
subfolders and organize them as you wish.
The location of the autoimport directories are controlled by settings
in `invokeai.yaml`. See [Configuration](../features/CONFIGURATION.md).
### Installing models that live in HuggingFace subfolders
On rare occasions you may need to install a diffusers-style model that
lives in a subfolder of a HuggingFace repo id. In this event, simply
add ":_subfolder-name_" to the end of the repo id. For example, if the
repo id is "monster-labs/control_v1p_sd15_qrcode_monster" and the model
you wish to fetch lives in a subfolder named "v2", then the repo id to
pass to the various model installers should be
```
monster-labs/control_v1p_sd15_qrcode_monster:v2
```
[set up in the config file]: ../../features/CONFIGURATION#model-marketplace-api-keys

View File

@ -1,204 +0,0 @@
---
title: Installing xFormers
---
# :material-image-size-select-large: Installing xformers
xFormers is toolbox that integrates with the pyTorch and CUDA
libraries to provide accelerated performance and reduced memory
consumption for applications using the transformers machine learning
architecture. After installing xFormers, InvokeAI users who have
CUDA GPUs will see a noticeable decrease in GPU memory consumption and
an increase in speed.
xFormers can be installed into a working InvokeAI installation without
any code changes or other updates. This document explains how to
install xFormers.
## Pip Install
For both Windows and Linux, you can install `xformers` in just a
couple of steps from the command line.
If you are used to launching `invoke.sh` or `invoke.bat` to start
InvokeAI, then run the launcher and select the "developer's console"
to get to the command line. If you run invoke.py directly from the
command line, then just be sure to activate it's virtual environment.
Then run the following three commands:
```sh
pip install xformers~=0.0.22
pip install triton # WON'T WORK ON WINDOWS
python -m xformers.info output
```
The first command installs `xformers`, the second installs the
`triton` training accelerator, and the third prints out the `xformers`
installation status. On Windows, please omit the `triton` package,
which is not available on that platform.
If all goes well, you'll see a report like the
following:
```sh
xFormers 0.0.22
memory_efficient_attention.cutlassF: available
memory_efficient_attention.cutlassB: available
memory_efficient_attention.flshattF: available
memory_efficient_attention.flshattB: available
memory_efficient_attention.smallkF: available
memory_efficient_attention.smallkB: available
memory_efficient_attention.tritonflashattF: available
memory_efficient_attention.tritonflashattB: available
indexing.scaled_index_addF: available
indexing.scaled_index_addB: available
indexing.index_select: available
swiglu.dual_gemm_silu: available
swiglu.gemm_fused_operand_sum: available
swiglu.fused.p.cpp: available
is_triton_available: True
is_functorch_available: False
pytorch.version: 2.1.0+cu121
pytorch.cuda: available
gpu.compute_capability: 8.9
gpu.name: NVIDIA GeForce RTX 4070
build.info: available
build.cuda_version: 1108
build.python_version: 3.10.11
build.torch_version: 2.1.0+cu121
build.env.TORCH_CUDA_ARCH_LIST: 5.0+PTX 6.0 6.1 7.0 7.5 8.0 8.6
build.env.XFORMERS_BUILD_TYPE: Release
build.env.XFORMERS_ENABLE_DEBUG_ASSERTIONS: None
build.env.NVCC_FLAGS: None
build.env.XFORMERS_PACKAGE_FROM: wheel-v0.0.20
build.nvcc_version: 11.8.89
source.privacy: open source
```
## Source Builds
`xformers` is currently under active development and at some point you
may wish to build it from sourcce to get the latest features and
bugfixes.
### Source Build on Linux
Note that xFormers only works with true NVIDIA GPUs and will not work
properly with the ROCm driver for AMD acceleration.
xFormers is not currently available as a pip binary wheel and must be
installed from source. These instructions were written for a system
running Ubuntu 22.04, but other Linux distributions should be able to
adapt this recipe.
#### 1. Install CUDA Toolkit 12.1
You will need the CUDA developer's toolkit in order to compile and
install xFormers. **Do not try to install Ubuntu's nvidia-cuda-toolkit
package.** It is out of date and will cause conflicts among the NVIDIA
driver and binaries. Instead install the CUDA Toolkit package provided
by NVIDIA itself. Go to [CUDA Toolkit 12.1
Downloads](https://developer.nvidia.com/cuda-12-1-0-download-archive)
and use the target selection wizard to choose your platform and Linux
distribution. Select an installer type of "runfile (local)" at the
last step.
This will provide you with a recipe for downloading and running a
install shell script that will install the toolkit and drivers.
#### 2. Confirm/Install pyTorch 2.1.0 with CUDA 12.1 support
If you are using InvokeAI 3.0.2 or higher, these will already be
installed. If not, you can check whether you have the needed libraries
using a quick command. Activate the invokeai virtual environment,
either by entering the "developer's console", or manually with a
command similar to `source ~/invokeai/.venv/bin/activate` (depending
on where your `invokeai` directory is.
Then run the command:
```sh
python -c 'exec("import torch\nprint(torch.__version__)")'
```
If it prints __2.1.0+cu121__ you're good. If not, you can install the
most up to date libraries with this command:
```sh
pip install --upgrade --force-reinstall torch torchvision
```
#### 3. Install the triton module
This module isn't necessary for xFormers image inference optimization,
but avoids a startup warning.
```sh
pip install triton
```
#### 4. Install source code build prerequisites
To build xFormers from source, you will need the `build-essentials`
package. If you don't have it installed already, run:
```sh
sudo apt install build-essential
```
#### 5. Build xFormers
There is no pip wheel package for xFormers at this time (January
2023). Although there is a conda package, InvokeAI no longer
officially supports conda installations and you're on your own if you
wish to try this route.
Following the recipe provided at the [xFormers GitHub
page](https://github.com/facebookresearch/xformers), and with the
InvokeAI virtual environment active (see step 1) run the following
commands:
```sh
pip install ninja
export TORCH_CUDA_ARCH_LIST="6.0;6.1;6.2;7.0;7.2;7.5;8.0;8.6"
pip install -v -U git+https://github.com/facebookresearch/xformers.git@main#egg=xformers
```
The TORCH_CUDA_ARCH_LIST is a list of GPU architectures to compile
xFormer support for. You can speed up compilation by selecting
the architecture specific for your system. You'll find the list of
GPUs and their architectures at NVIDIA's [GPU Compute
Capability](https://developer.nvidia.com/cuda-gpus) table.
If the compile and install completes successfully, you can check that
xFormers is installed with this command:
```sh
python -m xformers.info
```
If suiccessful, the top of the listing should indicate "available" for
each of the `memory_efficient_attention` modules, as shown here:
```sh
memory_efficient_attention.cutlassF: available
memory_efficient_attention.cutlassB: available
memory_efficient_attention.flshattF: available
memory_efficient_attention.flshattB: available
memory_efficient_attention.smallkF: available
memory_efficient_attention.smallkB: available
memory_efficient_attention.tritonflashattF: available
memory_efficient_attention.tritonflashattB: available
[...]
```
You can now launch InvokeAI and enjoy the benefits of xFormers.
### Windows
To come
---
(c) Copyright 2023 Lincoln Stein and the InvokeAI Development Team

View File

@ -1,89 +0,0 @@
---
title: build binary installers
---
# :simple-buildkite: How to build "binary" installers (InvokeAI-mac/windows/linux_on_*.zip)
## 1. Ensure `installers/requirements.in` is correct
and up to date on the branch to be installed.
## <a name="step-2"></a> 2. Run `pip-compile` on each platform.
On each target platform, in the branch that is to be installed, and
inside the InvokeAI git root folder, run the following commands:
```commandline
conda activate invokeai # or however you activate python
pip install pip-tools
pip-compile --allow-unsafe --generate-hashes --output-file=binary_installer/<reqsfile>.txt binary_installer/requirements.in
```
where `<reqsfile>.txt` is whichever of
```commandline
py3.10-darwin-arm64-mps-reqs.txt
py3.10-darwin-x86_64-reqs.txt
py3.10-linux-x86_64-cuda-reqs.txt
py3.10-windows-x86_64-cuda-reqs.txt
```
matches the current OS and architecture.
> There is no way to cross-compile these. They must be done on a system matching the target OS and arch.
## <a name="step-3"></a> 3. Set github repository and branch
Once all reqs files have been collected and committed **to the branch
to be installed**, edit `binary_installer/install.sh.in` and `binary_installer/install.bat.in` so that `RELEASE_URL`
and `RELEASE_SOURCEBALL` point to the github repo and branch that is
to be installed.
For example, to install `main` branch of `InvokeAI`, they should be
set as follows:
`install.sh.in`:
```commandline
RELEASE_URL=https://github.com/invoke-ai/InvokeAI
RELEASE_SOURCEBALL=/archive/refs/heads/main.tar.gz
```
`install.bat.in`:
```commandline
set RELEASE_URL=https://github.com/invoke-ai/InvokeAI
set RELEASE_SOURCEBALL=/archive/refs/heads/main.tar.gz
```
Or, to install `damians-cool-feature` branch of `damian0815`, set them
as follows:
`install.sh.in`:
```commandline
RELEASE_URL=https://github.com/damian0815/InvokeAI
RELEASE_SOURCEBALL=/archive/refs/heads/damians-cool-feature.tar.gz
```
`install.bat.in`:
```commandline
set RELEASE_URL=https://github.com/damian0815/InvokeAI
set RELEASE_SOURCEBALL=/archive/refs/heads/damians-cool-feature.tar.gz
```
The branch and repo specified here **must** contain the correct reqs
files. The installer zip files **do not** contain requirements files,
they are pulled from the specified branch during the installation
process.
## 4. Create zip files.
cd into the `installers/` folder and run
`./create_installers.sh`. This will create
`InvokeAI-mac_on_<branch>.zip`,
`InvokeAI-windows_on_<branch>.zip` and
`InvokeAI-linux_on_<branch>.zip`. These files can be distributed to end users.
These zips will continue to function as installers for all future
pushes to those branches, as long as necessary changes to
`requirements.in` are propagated in a timely manner to the
`py3.10-*-reqs.txt` files using pip-compile as outlined in [step
2](#step-2).
To actually install, users should unzip the appropriate zip file into an empty
folder and run `install.sh` on macOS/Linux or `install.bat` on
Windows.

View File

@ -1,88 +1,48 @@
# Overview
# Installation and Updating Overview
We offer several ways to install InvokeAI, each one suited to your
experience and preferences. We suggest that everyone start by
reviewing the
[hardware](010_INSTALL_AUTOMATED.md#hardware_requirements) and
[software](010_INSTALL_AUTOMATED.md#software_requirements)
requirements, as they are the same across each install method. Then
pick the install method most suitable to your level of experience and
needs.
Before installing, review the [installation requirements] to ensure your system is set up properly.
See the [troubleshooting
section](010_INSTALL_AUTOMATED.md#troubleshooting) of the automated
install guide for frequently-encountered installation issues.
See the [FAQ] for frequently-encountered installation issues.
This fork is supported across Linux, Windows and Macintosh. Linux users can use
either an Nvidia-based card (with CUDA support) or an AMD card (using the ROCm
driver).
If you need more help, join our [discord] or [create an issue].
<h2>Automatic Install & Updates </h2>
## **[Automated Installer (Recommended)](010_INSTALL_AUTOMATED.md)**
✅ This is the recommended installation method for first-time users.
✅ The automatic install is the best way to run InvokeAI. Check out the [installation guide] to get started.
This is a script that will install all of InvokeAI's essential
third party libraries and InvokeAI itself.
⬆️ The same installer is also the best way to update InvokeAI - Simply rerun it for the same folder you installed to.
🖥️ **Download the latest installer .zip file here** : https://github.com/invoke-ai/InvokeAI/releases/latest
- *Look for the file labelled "InvokeAI-installer-v3.X.X.zip" at the bottom of the page*
- If you experience issues, read through the full [installation instructions](010_INSTALL_AUTOMATED.md) to make sure you have met all of the installation requirements. If you need more help, join the [Discord](discord.gg/invoke-ai) or create an issue on [Github](https://github.com/invoke-ai/InvokeAI).
The installation process simply manages installation for the core libraries & application dependencies that run Invoke.
Any models, images, or other assets in the Invoke root folder won't be affected by the installation process.
<h2>Manual Install</h2>
If you are familiar with python and want more control over the packages that are installed, you can [install InvokeAI manually via PyPI].
## **[Manual Installation](020_INSTALL_MANUAL.md)**
This method is recommended for experienced users and developers.
Updates are managed by reinstalling the latest version through PyPi.
In this method you will manually run the commands needed to install
InvokeAI and its dependencies. We offer two recipes: one suited to
those who prefer the `conda` tool, and one suited to those who prefer
`pip` and Python virtual environments. In our hands the pip install
is faster and more reliable, but your mileage may vary.
Note that the conda installation method is currently deprecated and
will not be supported at some point in the future.
<h2>Developer Install</h2>
If you want to contribute to InvokeAI, consult the [developer install guide].
<h2>Docker Install</h2>
## **[Docker Installation](040_INSTALL_DOCKER.md)**
This method is recommended for those familiar with running Docker containers.
We offer a method for creating Docker containers containing InvokeAI and its dependencies. This method is recommended for individuals with experience with Docker containers and understand the pluses and minuses of a container-based install.
## Other Installation Guides
- [PyPatchMatch](060_INSTALL_PATCHMATCH.md)
- [XFormers](070_INSTALL_XFORMERS.md)
- [CUDA and ROCm Drivers](030_INSTALL_CUDA_AND_ROCM.md)
- [Installing New Models](050_INSTALLING_MODELS.md)
See the [docker installation guide].
## :fontawesome-solid-computer: Hardware Requirements
<h2>Other Installation Guides</h2>
### :octicons-cpu-24: System
You wil need one of the following:
- :simple-nvidia: An NVIDIA-based graphics card with 4 GB or more VRAM memory.
- :simple-amd: An AMD-based graphics card with 4 GB or more VRAM memory (Linux
only)
- :fontawesome-brands-apple: An Apple computer with an M1 chip.
** SDXL 1.0 Requirements*
To use SDXL, user must have one of the following:
- :simple-nvidia: An NVIDIA-based graphics card with 8 GB or more VRAM memory.
- :simple-amd: An AMD-based graphics card with 16 GB or more VRAM memory (Linux
only)
- :fontawesome-brands-apple: An Apple computer with an M1 chip.
### :fontawesome-solid-memory: Memory and Disk
- At least 12 GB Main Memory RAM.
- At least 18 GB of free disk space for the machine learning model, Python, and
all its dependencies.
We do **not recommend** the following video cards due to issues with their
running in half-precision mode and having insufficient VRAM to render 512x512
images in full-precision mode:
- NVIDIA 10xx series cards such as the 1080ti
- GTX 1650 series cards
- GTX 1660 series cards
- [PyPatchMatch](060_INSTALL_PATCHMATCH.md)
- [Installing Models](050_INSTALLING_MODELS.md)
[install InvokeAI manually via PyPI]: 020_INSTALL_MANUAL.md
[developer install guide]: INSTALL_DEVELOPMENT.md
[docker installation guide]: 040_INSTALL_DOCKER.md
[installation guide]: 010_INSTALL_AUTOMATED.md
[FAQ]: ../help/FAQ.md
[discord]: discord.gg/invoke-ai
[create an issue]: https://github.com/invoke-ai/InvokeAI/issues
[installation requirements]: INSTALL_REQUIREMENTS.md

View File

@ -0,0 +1,37 @@
# Developer Install
!!! warning
InvokeAI uses a SQLite database. By running on `main`, you accept responsibility for your database. This
means making regular backups (especially before pulling) and/or fixing it yourself in the event that a
PR introduces a schema change.
If you don't need persistent backend storage, you can use an ephemeral in-memory database by setting
`use_memory_db: true` in your `invokeai.yaml` file. You'll also want to set `scan_models_on_startup: true`
so that your models are registered on startup.
If this is untenable, you should run the application via the official installer or a manual install of the
python package from PyPI. These releases will not break your database.
If you have an interest in how InvokeAI works, or you would like to add features or bugfixes, you are encouraged to install the source code for InvokeAI.
!!! info "Why do I need the frontend toolchain?"
The repo doesn't contain a build of the frontend. You'll be responsible for rebuilding it (or running it in dev mode) to use the app, as described in the [frontend dev toolchain] docs.
<h2> Installation </h2>
1. [Fork and clone] the [InvokeAI repo].
1. Follow the [manual installation] docs to create a new virtual environment for the development install.
- Create a new folder outside the repo root for the installation and create the venv inside that folder.
- When installing the InvokeAI package, add `-e` to the command so you get an [editable install].
1. Install the [frontend dev toolchain] and do a production build of the UI as described.
1. You can now run the app as described in the [manual installation] docs.
As described in the [frontend dev toolchain] docs, you can run the UI using a dev server. If you do this, you won't need to continually rebuild the frontend. Instead, you run the dev server and use the app with the server URL it provides.
[Fork and clone]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo
[InvokeAI repo]: https://github.com/invoke-ai/InvokeAI
[frontend dev toolchain]: ../contributing/frontend/OVERVIEW.md
[manual installation]: ./020_INSTALL_MANUAL.md
[editable install]: https://pip.pypa.io/en/latest/cli/pip_install/#cmdoption-e

View File

@ -0,0 +1,181 @@
# Requirements
## GPU
!!! warning "Problematic Nvidia GPUs"
We do not recommend these GPUs. They cannot operate with half precision, but have insufficient VRAM to generate 512x512 images at full precision.
- NVIDIA 10xx series cards such as the 1080 TI
- GTX 1650 series cards
- GTX 1660 series cards
Invoke runs best with a dedicated GPU, but will fall back to running on CPU, albeit much slower. You'll need a beefier GPU for SDXL.
!!! example "Stable Diffusion 1.5"
=== "Nvidia"
```
Any GPU with at least 4GB VRAM.
```
=== "AMD"
```
Any GPU with at least 4GB VRAM. Linux only.
```
=== "Mac"
```
Any Apple Silicon Mac with at least 8GB memory.
```
!!! example "Stable Diffusion XL"
=== "Nvidia"
```
Any GPU with at least 8GB VRAM.
```
=== "AMD"
```
Any GPU with at least 16GB VRAM. Linux only.
```
=== "Mac"
```
Any Apple Silicon Mac with at least 16GB memory.
```
## RAM
At least 12GB of RAM.
## Disk
SSDs will, of course, offer the best performance.
The base application disk usage depends on the torch backend.
!!! example "Disk"
=== "Nvidia (CUDA)"
```
~6.5GB
```
=== "AMD (ROCm)"
```
~12GB
```
=== "Mac (MPS)"
```
~3.5GB
```
You'll need to set aside some space for images, depending on how much you generate. A couple GB is enough to get started.
You'll need a good chunk of space for models. Even if you only install the most popular models and the usual support models (ControlNet, IP Adapter ,etc), you will quickly hit 50GB of models.
!!! info "`tmpfs` on Linux"
If your temporary directory is mounted as a `tmpfs`, ensure it has sufficient space.
## Python
Invoke requires python 3.10 or 3.11. If you don't already have one of these versions installed, we suggest installing 3.11, as it will be supported for longer.
Check that your system has an up-to-date Python installed by running `python --version` in the terminal (Linux, macOS) or cmd/powershell (Windows).
<h3>Installing Python (Windows)</h3>
- Install python 3.11 with [an official installer].
- The installer includes an option to add python to your PATH. Be sure to enable this. If you missed it, re-run the installer, choose to modify an existing installation, and tick that checkbox.
- You may need to install [Microsoft Visual C++ Redistributable].
<h3>Installing Python (macOS)</h3>
- Install python 3.11 with [an official installer].
- If model installs fail with a certificate error, you may need to run this command (changing the python version to match what you have installed): `/Applications/Python\ 3.10/Install\ Certificates.command`
- If you haven't already, you will need to install the XCode CLI Tools by running `xcode-select --install` in a terminal.
<h3>Installing Python (Linux)</h3>
- Follow the [linux install instructions], being sure to install python 3.11.
- You'll need to install `libglib2.0-0` and `libgl1-mesa-glx` for OpenCV to work. For example, on a Debian system: `sudo apt update && sudo apt install -y libglib2.0-0 libgl1-mesa-glx`
## Drivers
If you have an Nvidia or AMD GPU, you may need to manually install drivers or other support packages for things to work well or at all.
### Nvidia
Run `nvidia-smi` on your system's command line to verify that drivers and CUDA are installed. If this command fails, or doesn't report versions, you will need to install drivers.
Go to the [CUDA Toolkit Downloads] and carefully follow the instructions for your system to get everything installed.
Confirm that `nvidia-smi` displays driver and CUDA versions after installation.
#### Linux - via Nvidia Container Runtime
An alternative to installing CUDA locally is to use the [Nvidia Container Runtime] to run the application in a container.
#### Windows - Nvidia cuDNN DLLs
An out-of-date cuDNN library can greatly hamper performance on 30-series and 40-series cards. Check with the community on discord to compare your `it/s` if you think you may need this fix.
First, locate the destination for the DLL files and make a quick back up:
1. Find your InvokeAI installation folder, e.g. `C:\Users\Username\InvokeAI\`.
1. Open the `.venv` folder, e.g. `C:\Users\Username\InvokeAI\.venv` (you may need to show hidden files to see it).
1. Navigate deeper to the `torch` package, e.g. `C:\Users\Username\InvokeAI\.venv\Lib\site-packages\torch`.
1. Copy the `lib` folder inside `torch` and back it up somewhere.
Next, download and copy the updated cuDNN DLLs:
1. Go to <https://developer.nvidia.com/cudnn>.
1. Create an account if needed and log in.
1. Choose the newest version of cuDNN that works with your GPU architecture. Consult the [cuDNN support matrix] to determine the correct version for your GPU.
1. Download the latest version and extract it.
1. Find the `bin` folder, e.g. `cudnn-windows-x86_64-SOME_VERSION\bin`.
1. Copy and paste the `.dll` files into the `lib` folder you located earlier. Replace files when prompted.
If, after restarting the app, this doesn't improve your performance, either restore your back up or re-run the installer to reset `torch` back to its original state.
### AMD
!!! info "Linux Only"
AMD GPUs are supported on Linux only, due to ROCm (the AMD equivalent of CUDA) support being Linux only.
!!! warning "Bumps Ahead"
While the application does run on AMD GPUs, there are occasional bumps related to spotty torch support.
Run `rocm-smi` on your system's command line verify that drivers and ROCm are installed. If this command fails, or doesn't report versions, you will need to install them.
Go to the [ROCm Documentation] and carefully follow the instructions for your system to get everything installed.
Confirm that `rocm-smi` displays driver and CUDA versions after installation.
#### Linux - via Docker Container
An alternative to installing ROCm locally is to use a [ROCm docker container] to run the application in a container.
[ROCm docker container]: https://github.com/ROCm/ROCm-docker
[ROCm Documentation]: https://rocm.docs.amd.com/projects/install-on-linux/en/latest/tutorial/quick-start.html
[cuDNN support matrix]: https://docs.nvidia.com/deeplearning/cudnn/support-matrix/index.html
[Nvidia Container Runtime]: https://developer.nvidia.com/container-runtime
[linux install instructions]: https://docs.python-guide.org/starting/install3/linux/
[Microsoft Visual C++ Redistributable]: https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170
[an official installer]: https://www.python.org/downloads/release/python-3118/
[CUDA Toolkit Downloads]: https://developer.nvidia.com/cuda-downloads

View File

@ -1,64 +0,0 @@
---
title: InvokeAI Binary Installer
---
The InvokeAI binary installer is a shell script that will install InvokeAI onto a stock
computer running recent versions of Linux, MacOSX or Windows. It will leave you
with a version that runs a stable version of InvokeAI. When a new version of
InvokeAI is released, you will download and reinstall the new version.
If you wish to tinker with unreleased versions of InvokeAI that introduce
potentially unstable new features, you should consider using the
[source installer](INSTALL_SOURCE.md) or one of the
[manual install](../020_INSTALL_MANUAL.md) methods.
**Important Caveats**
- This script does not support AMD GPUs. For Linux AMD support,
please use the manual or source code installer methods.
- This script has difficulty on some Macintosh machines
that have previously been used for Python development due to
conflicting development tools versions. Mac developers may wish
to try the source code installer or one of the manual methods instead.
!!! todo
Before you begin, make sure that you meet
the[hardware requirements](/#hardware-requirements) and has the
appropriate GPU drivers installed. In particular, if you are a Linux user with
an AMD GPU installed, you may need to install the
[ROCm-driver](https://rocmdocs.amd.com/en/latest/Installation_Guide/Installation-Guide.html).
Installation requires roughly 18G of free disk space to load the libraries and
recommended model weights files.
## Steps to Install
1. Download the
[latest release](https://github.com/invoke-ai/InvokeAI/releases/latest) of
InvokeAI's installer for your platform. Look for a file named `InvokeAI-binary-<your platform>.zip`
2. Place the downloaded package someplace where you have plenty of HDD space,
and have full permissions (i.e. `~/` on Lin/Mac; your home folder on Windows)
3. Extract the 'InvokeAI' folder from the downloaded package
4. Open the extracted 'InvokeAI' folder
5. Double-click 'install.bat' (Windows), or 'install.sh' (Lin/Mac) (or run from
a terminal)
6. Follow the prompts
7. After installation, please run the 'invoke.bat' file (on Windows) or
'invoke.sh' file (on Linux/Mac) to start InvokeAI.
## Troubleshooting
If you run into problems during or after installation, the InvokeAI team is
available to help you. Either create an
[Issue](https://github.com/invoke-ai/InvokeAI/issues) at our GitHub site, or
make a request for help on the "bugs-and-support" channel of our
[Discord server](https://discord.gg/ZmtBAhwWhy). We are a 100% volunteer
organization, but typically somebody will be available to help you within 24
hours, and often much sooner.

View File

@ -1,32 +0,0 @@
---
title: Running InvokeAI on Google Colab using a Jupyter Notebook
---
## Introduction
We have a [Jupyter
notebook](https://github.com/invoke-ai/InvokeAI/blob/main/notebooks/Stable_Diffusion_AI_Notebook.ipynb)
with cell-by-cell installation steps. It will download the code in
this repo as one of the steps, so instead of cloning this repo, simply
download the notebook from the link above and load it up in VSCode
(with the appropriate extensions installed)/Jupyter/JupyterLab and
start running the cells one-by-one.
!!! Note "you will need NVIDIA drivers, Python 3.10, and Git installed beforehand"
## Running Online On Google Colabotary
[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/invoke-ai/InvokeAI/blob/main/notebooks/Stable_Diffusion_AI_Notebook.ipynb)
## Running Locally (Cloning)
1. Install the Jupyter Notebook python library (one-time):
pip install jupyter
2. Clone the InvokeAI repository:
git clone https://github.com/invoke-ai/InvokeAI.git
cd invoke-ai
3. Create a virtual environment using conda:
conda create -n invoke jupyter
4. Activate the environment and start the Jupyter notebook:
conda activate invoke
jupyter notebook

View File

@ -1,135 +0,0 @@
---
title: Manual Installation, Linux
---
# :fontawesome-brands-linux: Linux
## Installation
1. You will need to install the following prerequisites if they are not already
available. Use your operating system's preferred installer.
- Python (version 3.8.5 recommended; higher may work)
- git
2. Install the Python Anaconda environment manager.
```bash
~$ wget https://repo.anaconda.com/archive/Anaconda3-2022.05-Linux-x86_64.sh
~$ chmod +x Anaconda3-2022.05-Linux-x86_64.sh
~$ ./Anaconda3-2022.05-Linux-x86_64.sh
```
After installing anaconda, you should log out of your system and log back
in. If the installation worked, your command prompt will be prefixed by the
name of the current anaconda environment - `(base)`.
3. Copy the InvokeAI source code from GitHub:
```bash
(base) ~$ git clone https://github.com/invoke-ai/InvokeAI.git
```
This will create InvokeAI folder where you will follow the rest of the
steps.
4. Enter the newly-created InvokeAI folder. From this step forward make sure
that you are working in the InvokeAI directory!
```bash
(base) ~$ cd InvokeAI
(base) ~/InvokeAI$
```
5. Use anaconda to copy necessary python packages, create a new python
environment named `invokeai` and then activate the environment.
!!! todo "For systems with a CUDA (Nvidia) card:"
```bash
(base) rm -rf src # (this is a precaution in case there is already a src directory)
(base) ~/InvokeAI$ conda env create -f environment-cuda.yml
(base) ~/InvokeAI$ conda activate invokeai
(invokeai) ~/InvokeAI$
```
!!! todo "For systems with an AMD card (using ROCm driver):"
```bash
(base) rm -rf src # (this is a precaution in case there is already a src directory)
(base) ~/InvokeAI$ conda env create -f environment-AMD.yml
(base) ~/InvokeAI$ conda activate invokeai
(invokeai) ~/InvokeAI$
```
After these steps, your command prompt will be prefixed by `(invokeai)` as
shown above.
6. Load the big stable diffusion weights files and a couple of smaller
machine-learning models:
```bash
(invokeai) ~/InvokeAI$ python3 scripts/configure_invokeai.py
```
!!! note
This script will lead you through the process of creating an account on Hugging Face,
accepting the terms and conditions of the Stable Diffusion model license,
and obtaining an access token for downloading. It will then download and
install the weights files for you.
Please look [here](../020_INSTALL_MANUAL.md) for a manual process for doing
the same thing.
7. Start generating images!
!!! todo "Run InvokeAI!"
!!! warning "IMPORTANT"
Make sure that the conda environment is activated, which should create
`(invokeai)` in front of your prompt!
=== "CLI"
```bash
python scripts/invoke.py
```
=== "local Webserver"
```bash
python scripts/invoke.py --web
```
=== "Public Webserver"
```bash
python scripts/invoke.py --web --host 0.0.0.0
```
To use an alternative model you may invoke the `!switch` command in
the CLI, or pass `--model <model_name>` during `invoke.py` launch for
either the CLI or the Web UI. See [Command Line
Client](../../deprecated/CLI.md#model-selection-and-importation). The
model names are defined in `configs/models.yaml`.
8. Subsequently, to relaunch the script, be sure to run "conda activate
invokeai" (step 5, second command), enter the `InvokeAI` directory, and then
launch the invoke script (step 8). If you forget to activate the 'invokeai'
environment, the script will fail with multiple `ModuleNotFound` errors.
## Updating to newer versions of the script
This distribution is changing rapidly. If you used the `git clone` method
(step 5) to download the InvokeAI directory, then to update to the latest and
greatest version, launch the Anaconda window, enter `InvokeAI` and type:
```bash
(invokeai) ~/InvokeAI$ git pull
(invokeai) ~/InvokeAI$ rm -rf src # prevents conda freezing errors
(invokeai) ~/InvokeAI$ conda env update -f environment.yml
```
This will bring your local copy into sync with the remote one.

View File

@ -1,525 +0,0 @@
---
title: Manual Installation, macOS
---
# :fontawesome-brands-apple: macOS
Invoke AI runs quite well on M1 Macs and we have a number of M1 users in the
community.
While the repo does run on Intel Macs, we only have a couple reports. If you
have an Intel Mac and run into issues, please create an issue on Github and we
will do our best to help.
## Requirements
- macOS 12.3 Monterey or later
- About 10GB of storage (and 10GB of data if your internet connection has data
caps)
- Any M1 Macs or an Intel Macs with 4GB+ of VRAM (ideally more)
## Installation
!!! todo "Homebrew"
First you will install the "brew" package manager. Skip this if brew is already installed.
```bash title="install brew (and Xcode command line tools)"
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
!!! todo "Conda Installation"
Now there are two different ways to set up the Python (miniconda) environment:
1. Standalone
2. with pyenv
If you don't know what we are talking about, choose Standalone. If you are familiar with python environments, choose "with pyenv"
=== "Standalone"
```bash title="Install cmake, protobuf, and rust"
brew install cmake protobuf rust
```
```bash title="Clone the InvokeAI repository"
# Clone the Invoke AI repo
git clone https://github.com/invoke-ai/InvokeAI.git
cd InvokeAI
```
Choose the appropriate architecture for your system and install miniconda:
=== "M1 arm64"
```bash title="Install miniconda for M1 arm64"
curl https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh \
-o Miniconda3-latest-MacOSX-arm64.sh
/bin/bash Miniconda3-latest-MacOSX-arm64.sh
```
=== "Intel x86_64"
```bash title="Install miniconda for Intel"
curl https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh \
-o Miniconda3-latest-MacOSX-x86_64.sh
/bin/bash Miniconda3-latest-MacOSX-x86_64.sh
```
=== "with pyenv"
```bash
brew install pyenv-virtualenv
pyenv install anaconda3-2022.05
pyenv virtualenv anaconda3-2022.05
eval "$(pyenv init -)"
pyenv activate anaconda3-2022.05
```
!!! todo "Clone the Invoke AI repo"
```bash
git clone https://github.com/invoke-ai/InvokeAI.git
cd InvokeAI
```
!!! todo "Create the environment & install packages"
=== "M1 Mac"
```bash
PIP_EXISTS_ACTION=w CONDA_SUBDIR=osx-arm64 conda env create -f environment-mac.yml
```
=== "Intel x86_64 Mac"
```bash
PIP_EXISTS_ACTION=w CONDA_SUBDIR=osx-64 conda env create -f environment-mac.yml
```
```bash
# Activate the environment (you need to do this every time you want to run SD)
conda activate invokeai
```
!!! info
`export PIP_EXISTS_ACTION=w` is a precaution to fix `conda env
create -f environment-mac.yml` never finishing in some situations. So
it isn't required but won't hurt.
!!! todo "Download the model weight files"
The `configure_invokeai.py` script downloads and installs the model weight
files for you. It will lead you through the process of getting a Hugging Face
account, accepting the Stable Diffusion model weight license agreement, and
creating a download token:
```bash
# This will take some time, depending on the speed of your internet connection
# and will consume about 10GB of space
python scripts/configure_invokeai.py
```
!!! todo "Run InvokeAI!"
!!! warning "IMPORTANT"
Make sure that the conda environment is activated, which should create
`(invokeai)` in front of your prompt!
=== "CLI"
```bash
python scripts/invoke.py
```
=== "local Webserver"
```bash
python scripts/invoke.py --web
```
=== "Public Webserver"
```bash
python scripts/invoke.py --web --host 0.0.0.0
```
To use an alternative model you may invoke the `!switch` command in
the CLI, or pass `--model <model_name>` during `invoke.py` launch for
either the CLI or the Web UI. See [Command Line
Client](../../deprecated/CLI.md#model-selection-and-importation). The
model names are defined in `configs/models.yaml`.
---
## Common problems
After you followed all the instructions and try to run invoke.py, you might get
several errors. Here's the errors I've seen and found solutions for.
### Is it slow?
```bash title="Be sure to specify 1 sample and 1 iteration."
python ./scripts/orig_scripts/txt2img.py \
--prompt "ocean" \
--ddim_steps 5 \
--n_samples 1 \
--n_iter 1
```
---
### Doesn't work anymore?
PyTorch nightly includes support for MPS. Because of this, this setup is
inherently unstable. One morning I woke up and it no longer worked no matter
what I did until I switched to miniforge. However, I have another Mac that works
just fine with Anaconda. If you can't get it to work, please search a little
first because many of the errors will get posted and solved. If you can't find a
solution please [create an issue](https://github.com/invoke-ai/InvokeAI/issues).
One debugging step is to update to the latest version of PyTorch nightly.
```bash
conda install \
pytorch \
torchvision \
-c pytorch-nightly \
-n invokeai
```
If it takes forever to run `conda env create -f environment-mac.yml`, try this:
```bash
git clean -f
conda clean \
--yes \
--all
```
Or you could try to completley reset Anaconda:
```bash
conda update \
--force-reinstall \
-y \
-n base \
-c defaults conda
```
---
### "No module named cv2", torch, 'invokeai', 'transformers', 'taming', etc
There are several causes of these errors:
1. Did you remember to `conda activate invokeai`? If your terminal prompt begins
with "(invokeai)" then you activated it. If it begins with "(base)" or
something else you haven't.
2. You might've run `./scripts/configure_invokeai.py` or `./scripts/invoke.py`
instead of `python ./scripts/configure_invokeai.py` or
`python ./scripts/invoke.py`. The cause of this error is long so it's below.
<!-- I could not find out where the error is, otherwise would have marked it as a footnote -->
3. if it says you're missing taming you need to rebuild your virtual
environment.
```bash
conda deactivate
conda env remove -n invokeai
conda env create -f environment-mac.yml
```
4. If you have activated the invokeai virtual environment and tried rebuilding
it, maybe the problem could be that I have something installed that you don't
and you'll just need to manually install it. Make sure you activate the
virtual environment so it installs there instead of globally.
```bash
conda activate invokeai
pip install <package name>
```
You might also need to install Rust (I mention this again below).
---
### How many snakes are living in your computer?
You might have multiple Python installations on your system, in which case it's
important to be explicit and consistent about which one to use for a given
project. This is because virtual environments are coupled to the Python that
created it (and all the associated 'system-level' modules).
When you run `python` or `python3`, your shell searches the colon-delimited
locations in the `PATH` environment variable (`echo $PATH` to see that list) in
that order - first match wins. You can ask for the location of the first
`python3` found in your `PATH` with the `which` command like this:
```bash
% which python3
/usr/bin/python3
```
Anything in `/usr/bin` is
[part of the OS](https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW6).
However, `/usr/bin/python3` is not actually python3, but rather a stub that
offers to install Xcode (which includes python 3). If you have Xcode installed
already, `/usr/bin/python3` will execute
`/Library/Developer/CommandLineTools/usr/bin/python3` or
`/Applications/Xcode.app/Contents/Developer/usr/bin/python3` (depending on which
Xcode you've selected with `xcode-select`).
Note that `/usr/bin/python` is an entirely different python - specifically,
python 2. Note: starting in macOS 12.3, `/usr/bin/python` no longer exists.
```bash
% which python3
/opt/homebrew/bin/python3
```
If you installed python3 with Homebrew and you've modified your path to search
for Homebrew binaries before system ones, you'll see the above path.
```bash
% which python
/opt/anaconda3/bin/python
```
If you have Anaconda installed, you will see the above path. There is a
`/opt/anaconda3/bin/python3` also.
We expect that `/opt/anaconda3/bin/python` and `/opt/anaconda3/bin/python3`
should actually be the _same python_, which you can verify by comparing the
output of `python3 -V` and `python -V`.
```bash
(invokeai) % which python
/Users/name/miniforge3/envs/invokeai/bin/python
```
The above is what you'll see if you have miniforge and correctly activated the
invokeai environment, while usingd the standalone setup instructions above.
If you otherwise installed via pyenv, you will get this result:
```bash
(anaconda3-2022.05) % which python
/Users/name/.pyenv/shims/python
```
It's all a mess and you should know
[how to modify the path environment variable](https://support.apple.com/guide/terminal/use-environment-variables-apd382cc5fa-4f58-4449-b20a-41c53c006f8f/mac)
if you want to fix it. Here's a brief hint of the most common ways you can
modify it (don't really have the time to explain it all here).
- ~/.zshrc
- ~/.bash_profile
- ~/.bashrc
- /etc/paths.d
- /etc/path
Which one you use will depend on what you have installed, except putting a file
in /etc/paths.d - which also is the way I prefer to do.
Finally, to answer the question posed by this section's title, it may help to
list all of the `python` / `python3` things found in `$PATH` instead of just the
first hit. To do so, add the `-a` switch to `which`:
```bash
% which -a python3
...
```
This will show a list of all binaries which are actually available in your PATH.
---
### Debugging?
Tired of waiting for your renders to finish before you can see if it works?
Reduce the steps! The image quality will be horrible but at least you'll get
quick feedback.
```bash
python ./scripts/txt2img.py \
--prompt "ocean" \
--ddim_steps 5 \
--n_samples 1 \
--n_iter 1
```
---
### OSError: Can't load tokenizer for 'openai/clip-vit-large-patch14'
```bash
python scripts/configure_invokeai.py
```
---
### "The operator [name] is not current implemented for the MPS device." (sic)
!!! example "example error"
```bash
... NotImplementedError: The operator 'aten::_index_put_impl_' is not current
implemented for the MPS device. If you want this op to be added in priority
during the prototype phase of this feature, please comment on
https://github.com/pytorch/pytorch/issues/77764.
As a temporary fix, you can set the environment variable
`PYTORCH_ENABLE_MPS_FALLBACK=1` to use the CPU as a fallback for this op.
WARNING: this will be slower than running natively on MPS.
```
The InvokeAI version includes this fix in
[environment-mac.yml](https://github.com/invoke-ai/InvokeAI/blob/main/environment-mac.yml).
### "Could not build wheels for tokenizers"
I have not seen this error because I had Rust installed on my computer before I
started playing with Stable Diffusion. The fix is to install Rust.
```bash
curl \
--proto '=https' \
--tlsv1.2 \
-sSf https://sh.rustup.rs | sh
```
---
### How come `--seed` doesn't work?
!!! Information
Completely reproducible results are not guaranteed across PyTorch releases,
individual commits, or different platforms. Furthermore, results may not be
reproducible between CPU and GPU executions, even when using identical seeds.
[PyTorch docs](https://pytorch.org/docs/stable/notes/randomness.html)
Second, we might have a fix that at least gets a consistent seed sort of. We're
still working on it.
### libiomp5.dylib error?
```bash
OMP: Error #15: Initializing libiomp5.dylib, but found libomp.dylib already initialized.
```
You are likely using an Intel package by mistake. Be sure to run conda with the
environment variable `CONDA_SUBDIR=osx-arm64`, like so:
`CONDA_SUBDIR=osx-arm64 conda install ...`
This error happens with Anaconda on Macs when the Intel-only `mkl` is pulled in
by a dependency.
[nomkl](https://stackoverflow.com/questions/66224879/what-is-the-nomkl-python-package-used-for)
is a metapackage designed to prevent this, by making it impossible to install
`mkl`, but if your environment is already broken it may not work.
Do _not_ use `os.environ['KMP_DUPLICATE_LIB_OK']='True'` or equivalents as this
masks the underlying issue of using Intel packages.
---
### Not enough memory
This seems to be a common problem and is probably the underlying problem for a
lot of symptoms (listed below). The fix is to lower your image size or to add
`model.half()` right after the model is loaded. I should probably test it out.
I've read that the reason this fixes problems is because it converts the model
from 32-bit to 16-bit and that leaves more RAM for other things. I have no idea
how that would affect the quality of the images though.
See [this issue](https://github.com/CompVis/stable-diffusion/issues/71).
---
### "Error: product of dimension sizes > 2\*\*31'"
This error happens with img2img, which I haven't played with too much yet. But I
know it's because your image is too big or the resolution isn't a multiple of
32x32. Because the stable-diffusion model was trained on images that were 512 x
512, it's always best to use that output size (which is the default). However,
if you're using that size and you get the above error, try 256 x 256 or 512 x
256 or something as the source image.
BTW, 2\*\*31-1 =
[2,147,483,647](https://en.wikipedia.org/wiki/2,147,483,647#In_computing), which
is also 32-bit signed [LONG_MAX](https://en.wikipedia.org/wiki/C_data_types) in
C.
---
### I just got Rickrolled! Do I have a virus?
You don't have a virus. It's part of the project. Here's
[Rick](https://github.com/invoke-ai/InvokeAI/blob/main/assets/rick.jpeg) and
here's
[the code](https://github.com/invoke-ai/InvokeAI/blob/69ae4b35e0a0f6ee1af8bb9a5d0016ccb27e36dc/scripts/txt2img.py#L79)
that swaps him in. It's a NSFW filter, which IMO, doesn't work very good (and we
call this "computer vision", sheesh).
---
### My images come out black
We might have this fixed, we are still testing.
There's a [similar issue](https://github.com/CompVis/stable-diffusion/issues/69)
on CUDA GPU's where the images come out green. Maybe it's the same issue?
Someone in that issue says to use "--precision full", but this fork actually
disables that flag. I don't know why, someone else provided that code and I
don't know what it does. Maybe the `model.half()` suggestion above would fix
this issue too. I should probably test it.
### "view size is not compatible with input tensor's size and stride"
```bash
File "/opt/anaconda3/envs/invokeai/lib/python3.10/site-packages/torch/nn/functional.py", line 2511, in layer_norm
return torch.layer_norm(input, normalized_shape, weight, bias, eps, torch.backends.cudnn.enabled)
RuntimeError: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Use .reshape(...) instead.
```
Update to the latest version of invoke-ai/InvokeAI. We were patching pytorch but
we found a file in stable-diffusion that we could change instead. This is a
32-bit vs 16-bit problem.
### The processor must support the Intel bla bla bla
What? Intel? On an Apple Silicon?
```bash
Intel MKL FATAL ERROR: This system does not meet the minimum requirements for use of the Intel(R) Math Kernel Library. The processor must support the Intel(R) Supplemental Streaming SIMD Extensions 3 (Intel(R) SSSE3) instructions. The processor must support the Intel(R) Streaming SIMD Extensions 4.2 (Intel(R) SSE4.2) instructions. The processor must support the Intel(R) Advanced Vector Extensions (Intel(R) AVX) instructions.
```
This is due to the Intel `mkl` package getting picked up when you try to install
something that depends on it-- Rosetta can translate some Intel instructions but
not the specialized ones here. To avoid this, make sure to use the environment
variable `CONDA_SUBDIR=osx-arm64`, which restricts the Conda environment to only
use ARM packages, and use `nomkl` as described above.
---
### input types 'tensor<2x1280xf32>' and 'tensor<\*xf16>' are not broadcast compatible
May appear when just starting to generate, e.g.:
```bash
invoke> clouds
Generating: 0%| | 0/1 [00:00<?, ?it/s]/Users/[...]/dev/stable-diffusion/ldm/modules/embedding_manager.py:152: UserWarning: The operator 'aten::nonzero' is not currently supported on the MPS backend and will fall back to run on the CPU. This may have performance implications. (Triggered internally at /Users/runner/work/_temp/anaconda/conda-bld/pytorch_1662016319283/work/aten/src/ATen/mps/MPSFallback.mm:11.)
placeholder_idx = torch.where(
loc("mps_add"("(mpsFileLoc): /AppleInternal/Library/BuildRoots/20d6c351-ee94-11ec-bcaf-7247572f23b4/Library/Caches/com.apple.xbs/Sources/MetalPerformanceShadersGraph/mpsgraph/MetalPerformanceShadersGraph/Core/Files/MPSGraphUtilities.mm":219:0)): error: input types 'tensor<2x1280xf32>' and 'tensor<*xf16>' are not broadcast compatible
LLVM ERROR: Failed to infer result type(s).
Abort trap: 6
/Users/[...]/opt/anaconda3/envs/invokeai/lib/python3.9/multiprocessing/resource_tracker.py:216: UserWarning: resource_tracker: There appear to be 1 leaked semaphore objects to clean up at shutdown
warnings.warn('resource_tracker: There appear to be %d '
```

View File

@ -1,17 +0,0 @@
---
title: Installing InvokeAI with the Pre-Compiled PIP Installer
---
# THIS NEEDS TO BE FLESHED OUT
## Introduction
## Walkthrough
## Updating to newer versions
### Updating the stable version
### Updating to the development version
## Troubleshooting

View File

@ -1,225 +0,0 @@
---
title: Source Installer
---
# The InvokeAI Source Installer
## Introduction
The source installer is a shell script that attempts to automate every step
needed to install and run InvokeAI on a stock computer running recent versions
of Linux, MacOS or Windows. It will leave you with a version that runs a stable
version of InvokeAI with the option to upgrade to experimental versions later.
Before you begin, make sure that you meet the
[hardware requirements](../../index.md#hardware-requirements) and has the appropriate
GPU drivers installed. In particular, if you are a Linux user with an AMD GPU
installed, you may need to install the
[ROCm driver](https://rocmdocs.amd.com/en/latest/Installation_Guide/Installation-Guide.html).
Installation requires roughly 18G of free disk space to load the libraries and
recommended model weights files.
## Walk through
Though there are multiple steps, there really is only one click involved to kick
off the process.
1. The source installer is distributed in ZIP files. Go to the
[latest release](https://github.com/invoke-ai/InvokeAI/releases/latest), and
look for a series of files named:
- [invokeAI-src-installer-2.2.3-mac.zip](https://github.com/invoke-ai/InvokeAI/releases/latest/download/invokeAI-src-installer-2.2.3-mac.zip)
- [invokeAI-src-installer-2.2.3-windows.zip](https://github.com/invoke-ai/InvokeAI/releases/latest/download/invokeAI-src-installer-2.2.3-windows.zip)
- [invokeAI-src-installer-2.2.3-linux.zip](https://github.com/invoke-ai/InvokeAI/releases/latest/download/invokeAI-src-installer-2.2.3-linux.zip)
Download the one that is appropriate for your operating system.
2. Unpack the zip file into a directory that has at least 18G of free space. Do
_not_ unpack into a directory that has an earlier version of InvokeAI.
This will create a new directory named "InvokeAI". This example shows how
this would look using the `unzip` command-line tool, but you may use any
graphical or command-line Zip extractor:
```cmd
C:\Documents\Linco> unzip invokeAI-windows.zip
Archive: C: \Linco\Downloads\invokeAI-linux.zip
creating: invokeAI\
inflating: invokeAI\install.bat
inflating: invokeAI\readme.txt
```
3. If you are a macOS user, you may need to install the Xcode command line tools.
These are a set of tools that are needed to run certain applications in a Terminal,
including InvokeAI. This package is provided directly by Apple.
To install, open a terminal window and run `xcode-select --install`. You will get
a macOS system popup guiding you through the install. If you already have them
installed, you will instead see some output in the Terminal advising you that the
tools are already installed.
More information can be found here:
https://www.freecodecamp.org/news/install-xcode-command-line-tools/
4. If you are using a desktop GUI, double-click the installer file. It will be
named `install.bat` on Windows systems and `install.sh` on Linux and
Macintosh systems.
5. Alternatively, from the command line, run the shell script or .bat file:
```cmd
C:\Documents\Linco> cd invokeAI
C:\Documents\Linco\invokeAI> install.bat
```
6. Sit back and let the install script work. It will install various binary
requirements including Conda, Git and Python, then download the current
InvokeAI code and install it along with its dependencies.
Be aware that some of the library download and install steps take a long time.
In particular, the `pytorch` package is quite large and often appears to get
"stuck" at 99.9%. Similarly, the `pip installing requirements` step may
appear to hang. Have patience and the installation step will eventually
resume. However, there are occasions when the library install does
legitimately get stuck. If you have been waiting for more than ten minutes
and nothing is happening, you can interrupt the script with ^C. You may restart
it and it will pick up where it left off.
7. After installation completes, the installer will launch a script called
`configure_invokeai.py`, which will guide you through the first-time process of
selecting one or more Stable Diffusion model weights files, downloading and
configuring them.
Note that the main Stable Diffusion weights file is protected by a license
agreement that you must agree to in order to use. The script will list the
steps you need to take to create an account on the official site that hosts
the weights files, accept the agreement, and provide an access token that
allows InvokeAI to legally download and install the weights files.
If you have already downloaded the weights file(s) for another Stable
Diffusion distribution, you may skip this step (by selecting "skip" when
prompted) and configure InvokeAI to use the previously-downloaded files. The
process for this is described in [Installing Models](../050_INSTALLING_MODELS.md).
8. The script will now exit and you'll be ready to generate some images. The
invokeAI directory will contain numerous files. Look for a shell script
named `invoke.sh` (Linux/Mac) or `invoke.bat` (Windows). Launch the script
by double-clicking it or typing its name at the command-line:
```cmd
C:\Documents\Linco> cd invokeAI
C:\Documents\Linco\invokeAI> invoke.bat
```
The `invoke.bat` (`invoke.sh`) script will give you the choice of starting (1)
the command-line interface, or (2) the web GUI. If you start the latter, you can
load the user interface by pointing your browser at http://localhost:9090.
The `invoke` script also offers you a third option labeled "open the developer
console". If you choose this option, you will be dropped into a command-line
interface in which you can run python commands directly, access developer tools,
and launch InvokeAI with customized options. To do the latter, you would launch
the script `scripts/invoke.py` as shown in this example:
```cmd
python scripts/invoke.py --web --max_load_models=3 \
--model=waifu-1.3 --steps=30 --outdir=C:/Documents/AIPhotos
```
These options are described in detail in the
[Command-Line Interface](../../deprecated/CLI.md) documentation.
## Troubleshooting
_Package dependency conflicts_ If you have previously installed
InvokeAI or another Stable Diffusion package, the installer may
occasionally pick up outdated libraries and either the installer or
`invoke` will fail with complaints out library conflicts. There are
two steps you can take to clear this problem. Both of these are done
from within the "developer's console", which you can get to by
launching `invoke.sh` (or `invoke.bat`) and selecting launch option
#3:
1. Remove the previous `invokeai` environment completely. From within
the developer's console, give the command `conda env remove -n
invokeai`. This will delete previous files installed by `invoke`.
Then exit from the developer's console and launch the script
`update.sh` (or `update.bat`). This will download the most recent
InvokeAI (including bug fixes) and reinstall the environment.
You should then be able to run `invoke.sh`/`invoke.bat`.
2. If this doesn't work, you can try cleaning your system's conda
cache. This is slightly more extreme, but won't interfere with
any other python-based programs installed on your computer.
From the developer's console, run the command `conda clean -a`
and answer "yes" to all prompts.
After this is done, run `update.sh` and try again as before.
_"Corrupted configuration file."__ Everything seems to install ok, but
`invoke` complains of a corrupted configuration file and goes calls
`configure_invokeai.py` to fix, but this doesn't fix the problem.
This issue is often caused by a misconfigured configuration directive
in the `.invokeai` initialization file that contains startup settings.
This can be corrected by fixing the offending line.
First find `.invokeai`. It is a small text file located in your home
directory, `~/.invokeai` on Mac and Linux systems, and `C:\Users\*your
name*\.invokeai` on Windows systems. Open it with a text editor
(e.g. Notepad on Windows, TextEdit on Macs, or `nano` on Linux)
and look for the lines starting with `--root` and `--outdir`.
An example is here:
```cmd
--root="/home/lstein/invokeai"
--outdir="/home/lstein/invokeai/outputs"
```
There should not be whitespace before or after the directory paths,
and the paths should not end with slashes:
```cmd
--root="/home/lstein/invokeai " # wrong! no whitespace here
--root="/home\lstein\invokeai\" # wrong! shouldn't end in a slash
```
Fix the problem with your text editor and save as a **plain text**
file. This should clear the issue.
_If none of these maneuvers fixes the problem_ then please report the
problem to the [InvokeAI
Issues](https://github.com/invoke-ai/InvokeAI/issues) section, or
visit our [Discord Server](https://discord.gg/ZmtBAhwWhy) for interactive assistance.
## Updating to newer versions
This section describes how to update InvokeAI to new versions of the software.
### Updating the stable version
This distribution is changing rapidly, and we add new features on a daily basis.
To update to the latest released version (recommended), run the `update.sh`
(Linux/Mac) or `update.bat` (Windows) scripts. This will fetch the latest
release and re-run the `configure_invokeai` script to download any updated models
files that may be needed. You can also use this to add additional models that
you did not select at installation time.
You can now close the developer console and run `invoke` as before. If you get
complaints about missing models, then you may need to do the additional step of
running `configure_invokeai.py`. This happens relatively infrequently. To do this,
simply open up the developer's console again and type
`python scripts/configure_invokeai.py`.
## Troubleshooting
If you run into problems during or after installation, the InvokeAI team is
available to help you. Either create an
[Issue](https://github.com/invoke-ai/InvokeAI/issues) at our GitHub site, or
make a request for help on the "bugs-and-support" channel of our
[Discord server](https://discord.gg/ZmtBAhwWhy). We are a 100% volunteer
organization, but typically somebody will be available to help you within 24
hours, and often much sooner.

View File

@ -1,137 +0,0 @@
---
title: Manual Installation, Windows
---
# :fontawesome-brands-windows: Windows
## **Notebook install (semi-automated)**
We have a
[Jupyter notebook](https://github.com/invoke-ai/InvokeAI/blob/main/notebooks/Stable_Diffusion_AI_Notebook.ipynb)
with cell-by-cell installation steps. It will download the code in this repo as
one of the steps, so instead of cloning this repo, simply download the notebook
from the link above and load it up in VSCode (with the appropriate extensions
installed)/Jupyter/JupyterLab and start running the cells one-by-one.
Note that you will need NVIDIA drivers, Python 3.10, and Git installed beforehand.
## **Manual Install with Conda**
1. Install Anaconda3 (miniconda3 version) from [here](https://docs.anaconda.com/anaconda/install/windows/)
2. Install Git from [here](https://git-scm.com/download/win)
3. Launch Anaconda from the Windows Start menu. This will bring up a command
window. Type all the remaining commands in this window.
4. Run the command:
```batch
git clone https://github.com/invoke-ai/InvokeAI.git
```
This will create stable-diffusion folder where you will follow the rest of
the steps.
5. Enter the newly-created InvokeAI folder. From this step forward make sure that you are working in the InvokeAI directory!
```batch
cd InvokeAI
```
6. Run the following commands:
!!! todo "For systems with a CUDA (Nvidia) card:"
```bash
rmdir src # (this is a precaution in case there is already a src directory)
conda env create -f environment-cuda.yml
conda activate invokeai
(invokeai)>
```
!!! todo "For systems with an AMD card (using ROCm driver):"
```bash
rmdir src # (this is a precaution in case there is already a src directory)
conda env create -f environment-AMD.yml
conda activate invokeai
(invokeai)>
```
This will install all python requirements and activate the "invokeai" environment
which sets PATH and other environment variables properly.
7. Load the big stable diffusion weights files and a couple of smaller machine-learning models:
```bash
python scripts/configure_invokeai.py
```
!!! note
This script will lead you through the process of creating an account on Hugging Face,
accepting the terms and conditions of the Stable Diffusion model license, and
obtaining an access token for downloading. It will then download and install the
weights files for you.
Please look [here](../020_INSTALL_MANUAL.md) for a manual process for doing the
same thing.
8. Start generating images!
!!! example ""
!!! warning "IMPORTANT"
Make sure that the conda environment is activated, which should create
`(invokeai)` in front of your prompt!
=== "CLI"
```bash
python scripts/invoke.py
```
=== "local Webserver"
```bash
python scripts/invoke.py --web
```
=== "Public Webserver"
```bash
python scripts/invoke.py --web --host 0.0.0.0
```
To use an alternative model you may invoke the `!switch` command in
the CLI, or pass `--model <model_name>` during `invoke.py` launch for
either the CLI or the Web UI. See [Command Line
Client](../../deprecated/CLI.md#model-selection-and-importation). The
model names are defined in `configs/models.yaml`.
9. Subsequently, to relaunch the script, first activate the Anaconda
command window (step 3),enter the InvokeAI directory (step 5, `cd
\path\to\InvokeAI`), run `conda activate invokeai` (step 6b), and then
launch the invoke script (step 9).
!!! tip "Tildebyte has written an alternative"
["Easy peasy Windows install"](https://github.com/invoke-ai/InvokeAI/wiki/Easy-peasy-Windows-install)
which uses the Windows Powershell and pew. If you are having trouble with
Anaconda on Windows, give this a try (or try it first!)
---
This distribution is changing rapidly. If you used the `git clone` method
(step 5) to download the stable-diffusion directory, then to update to the
latest and greatest version, launch the Anaconda window, enter
`stable-diffusion`, and type:
```bash
git pull
conda env update
```
This will bring your local copy into sync with the remote one.

View File

@ -22,6 +22,24 @@ class MyInvocation(BaseInvocation):
...
```
The full API is documented below.
## Invocation Mixins
Two important mixins are provided to facilitate working with metadata and gallery boards.
### `WithMetadata`
Inherit from this class (in addition to `BaseInvocation`) to add a `metadata` input to your node. When you do this, you can access the metadata dict from `self.metadata` in the `invoke()` function.
The dict will be populated via the node's input, and you can add any metadata you'd like to it. When you call `context.images.save()`, if the metadata dict has any data, it be automatically embedded in the image.
### `WithBoard`
Inherit from this class (in addition to `BaseInvocation`) to add a `board` input to your node. This renders as a drop-down to select a board. The user's selection will be accessible from `self.board` in the `invoke()` function.
When you call `context.images.save()`, if a board was selected, the image will added to that board as it is saved.
<!-- prettier-ignore-start -->
::: invokeai.app.services.shared.invocation_context.InvocationContext
options:

View File

@ -32,6 +32,7 @@ To use a community workflow, download the the `.json` node graph file and load i
+ [Image to Character Art Image Nodes](#image-to-character-art-image-nodes)
+ [Image Picker](#image-picker)
+ [Image Resize Plus](#image-resize-plus)
+ [Latent Upscale](#latent-upscale)
+ [Load Video Frame](#load-video-frame)
+ [Make 3D](#make-3d)
+ [Mask Operations](#mask-operations)
@ -290,6 +291,13 @@ View:
</br><img src="https://raw.githubusercontent.com/VeyDlin/image-resize-plus-node/master/.readme/node.png" width="500" />
--------------------------------
### Latent Upscale
**Description:** This node uses a small (~2.4mb) model to upscale the latents used in a Stable Diffusion 1.5 or Stable Diffusion XL image generation, rather than the typical interpolation method, avoiding the traditional downsides of the latent upscale technique.
**Node Link:** [https://github.com/gogurtenjoyer/latent-upscale](https://github.com/gogurtenjoyer/latent-upscale)
--------------------------------
### Load Video Frame
@ -346,12 +354,21 @@ See full docs here: https://github.com/skunkworxdark/Prompt-tools-nodes/edit/mai
**Description:** A set of nodes for Metadata. Collect Metadata from within an `iterate` node & extract metadata from an image.
- `Metadata Item Linked` - Allows collecting of metadata while within an iterate node with no need for a collect node or conversion to metadata node.
- `Metadata From Image` - Provides Metadata from an image.
- `Metadata To String` - Extracts a String value of a label from metadata.
- `Metadata To Integer` - Extracts an Integer value of a label from metadata.
- `Metadata To Float` - Extracts a Float value of a label from metadata.
- `Metadata To Scheduler` - Extracts a Scheduler value of a label from metadata.
- `Metadata Item Linked` - Allows collecting of metadata while within an iterate node with no need for a collect node or conversion to metadata node
- `Metadata From Image` - Provides Metadata from an image
- `Metadata To String` - Extracts a String value of a label from metadata
- `Metadata To Integer` - Extracts an Integer value of a label from metadata
- `Metadata To Float` - Extracts a Float value of a label from metadata
- `Metadata To Scheduler` - Extracts a Scheduler value of a label from metadata
- `Metadata To Bool` - Extracts Bool types from metadata
- `Metadata To Model` - Extracts model types from metadata
- `Metadata To SDXL Model` - Extracts SDXL model types from metadata
- `Metadata To LoRAs` - Extracts Loras from metadata.
- `Metadata To SDXL LoRAs` - Extracts SDXL Loras from metadata
- `Metadata To ControlNets` - Extracts ControNets from metadata
- `Metadata To IP-Adapters` - Extracts IP-Adapters from metadata
- `Metadata To T2I-Adapters` - Extracts T2I-Adapters from metadata
- `Denoise Latents + Metadata` - This is an inherited version of the existing `Denoise Latents` node but with a metadata input and output.
**Node Link:** https://github.com/skunkworxdark/metadata-linked-nodes

View File

@ -19,6 +19,8 @@ their descriptions.
| Conditioning Primitive | A conditioning tensor primitive value |
| Content Shuffle Processor | Applies content shuffle processing to image |
| ControlNet | Collects ControlNet info to pass to other nodes |
| Create Denoise Mask | Converts a greyscale or transparency image into a mask for denoising. |
| Create Gradient Mask | Creates a mask for Gradient ("soft", "differential") inpainting that gradually expands during denoising. Improves edge coherence. |
| Denoise Latents | Denoises noisy latents to decodable images |
| Divide Integers | Divides two numbers |
| Dynamic Prompt | Parses a prompt using adieyal/dynamicprompts' random or combinatorial generator |

View File

@ -2,22 +2,18 @@
set -e
BCYAN="\e[1;36m"
BYELLOW="\e[1;33m"
BGREEN="\e[1;32m"
BRED="\e[1;31m"
RED="\e[31m"
RESET="\e[0m"
function is_bin_in_path {
builtin type -P "$1" &>/dev/null
}
BCYAN="\033[1;36m"
BYELLOW="\033[1;33m"
BGREEN="\033[1;32m"
BRED="\033[1;31m"
RED="\033[31m"
RESET="\033[0m"
function git_show {
git show -s --format=oneline --abbrev-commit "$1" | cat
}
if [[ -v "VIRTUAL_ENV" ]]; then
if [[ ! -z "${VIRTUAL_ENV}" ]]; then
# we can't just call 'deactivate' because this function is not exported
# to the environment of this script from the bash process that runs the script
echo -e "${BRED}A virtual environment is activated. Please deactivate it before proceeding.${RESET}"
@ -26,31 +22,63 @@ fi
cd "$(dirname "$0")"
echo
echo -e "${BYELLOW}This script must be run from the installer directory!${RESET}"
echo "The current working directory is $(pwd)"
read -p "If that looks right, press any key to proceed, or CTRL-C to exit..."
echo
# Some machines only have `python3` in PATH, others have `python` - make an alias.
# We can use a function to approximate an alias within a non-interactive shell.
if ! is_bin_in_path python && is_bin_in_path python3; then
function python {
python3 "$@"
}
fi
VERSION=$(
cd ..
python -c "from invokeai.version import __version__ as version; print(version)"
python3 -c "from invokeai.version import __version__ as version; print(version)"
)
PATCH=""
VERSION="v${VERSION}${PATCH}"
VERSION="v${VERSION}"
if [[ ! -z ${CI} ]]; then
echo
echo -e "${BCYAN}CI environment detected${RESET}"
echo
else
echo
echo -e "${BYELLOW}This script must be run from the installer directory!${RESET}"
echo "The current working directory is $(pwd)"
read -p "If that looks right, press any key to proceed, or CTRL-C to exit..."
echo
fi
echo -e "${BGREEN}HEAD${RESET}:"
git_show HEAD
echo
# ---------------------- FRONTEND ----------------------
pushd ../invokeai/frontend/web >/dev/null
echo "Installing frontend dependencies..."
echo
pnpm i --frozen-lockfile
echo
if [[ ! -z ${CI} ]]; then
echo "Building frontend without checks..."
# In CI, we have already done the frontend checks and can just build
pnpm vite build
else
echo "Running checks and building frontend..."
# This runs all the frontend checks and builds
pnpm build
fi
echo
popd
# ---------------------- BACKEND ----------------------
echo
echo "Building wheel..."
echo
# install the 'build' package in the user site packages, if needed
# could be improved by using a temporary venv, but it's tiny and harmless
if [[ $(python3 -c 'from importlib.util import find_spec; print(find_spec("build") is None)') == "True" ]]; then
pip install --user build
fi
rm -rf ../build
python3 -m build --outdir dist/ ../.
# ----------------------
echo
@ -78,10 +106,28 @@ chmod a+x InvokeAI-Installer/install.sh
cp install.bat.in InvokeAI-Installer/install.bat
cp WinLongPathsEnabled.reg InvokeAI-Installer/
# Zip everything up
zip -r InvokeAI-installer-$VERSION.zip InvokeAI-Installer
FILENAME=InvokeAI-installer-$VERSION.zip
# clean up
rm -rf InvokeAI-Installer tmp dist ../invokeai/frontend/web/dist/
# Zip everything up
zip -r ${FILENAME} InvokeAI-Installer
echo
echo -e "${BGREEN}Built installer: ./${FILENAME}${RESET}"
echo -e "${BGREEN}Built PyPi distribution: ./dist${RESET}"
# clean up, but only if we are not in a github action
if [[ -z ${CI} ]]; then
echo
echo "Cleaning up intermediate build files..."
rm -rf InvokeAI-Installer tmp ../invokeai/frontend/web/dist/
fi
if [[ ! -z ${CI} ]]; then
echo
echo "Setting GitHub action outputs..."
echo "INSTALLER_FILENAME=${FILENAME}" >>$GITHUB_OUTPUT
echo "INSTALLER_PATH=installer/${FILENAME}" >>$GITHUB_OUTPUT
echo "DIST_PATH=installer/dist/" >>$GITHUB_OUTPUT
fi
exit 0

View File

@ -16,7 +16,7 @@ if "%1" == "use-cache" (
@rem The version in the next line is replaced by an up to date release number
@rem when create_installer.sh is run. Change the release number there.
set INSTRUCTIONS=https://invoke-ai.github.io/InvokeAI/installation/INSTALL_AUTOMATED/
set TROUBLESHOOTING=https://invoke-ai.github.io/InvokeAI/installation/INSTALL_AUTOMATED/#troubleshooting
set TROUBLESHOOTING=https://invoke-ai.github.io/InvokeAI/help/FAQ/
set PYTHON_URL=https://www.python.org/downloads/windows/
set MINIMUM_PYTHON_VERSION=3.10.0
set PYTHON_URL=https://www.python.org/downloads/release/python-3109/

View File

@ -3,8 +3,10 @@
InvokeAI installer script
"""
import locale
import os
import platform
import re
import shutil
import subprocess
import sys
@ -16,12 +18,23 @@ from typing import Optional, Tuple
SUPPORTED_PYTHON = ">=3.10.0,<=3.11.100"
INSTALLER_REQS = ["rich", "semver", "requests", "plumbum", "prompt-toolkit"]
BOOTSTRAP_VENV_PREFIX = "invokeai-installer-tmp"
DOCS_URL = "https://invoke-ai.github.io/InvokeAI/"
DISCORD_URL = "https://discord.gg/ZmtBAhwWhy"
OS = platform.uname().system
ARCH = platform.uname().machine
VERSION = "latest"
def get_version_from_wheel_filename(wheel_filename: str) -> str:
match = re.search(r"-(\d+\.\d+\.\d+)", wheel_filename)
if match:
version = match.group(1)
return version
else:
raise ValueError(f"Could not extract version from wheel filename: {wheel_filename}")
class Installer:
"""
Deploys an InvokeAI installation into a given path
@ -36,7 +49,7 @@ class Installer:
self.bootstrap()
self.available_releases = get_github_releases()
def mktemp_venv(self) -> TemporaryDirectory:
def mktemp_venv(self) -> TemporaryDirectory[str]:
"""
Creates a temporary virtual environment for the installer itself
@ -58,7 +71,7 @@ class Installer:
return venv_dir
def bootstrap(self, verbose: bool = False) -> TemporaryDirectory | None:
def bootstrap(self, verbose: bool = False) -> TemporaryDirectory[str] | None:
"""
Bootstrap the installer venv with packages required at install time
"""
@ -87,7 +100,7 @@ class Installer:
except subprocess.CalledProcessError as e:
print(e)
def app_venv(self, venv_parent) -> Path:
def app_venv(self, venv_parent: Path) -> Path:
"""
Create a virtualenv for the InvokeAI installation
"""
@ -106,26 +119,29 @@ class Installer:
return venv_dir
def install(
self, version=None, root: str = "~/invokeai", yes_to_all=False, find_links: Optional[Path] = None
self,
root: str = "~/invokeai",
yes_to_all: bool = False,
find_links: Optional[str] = None,
wheel: Optional[Path] = None,
) -> None:
"""
Install the InvokeAI application into the given runtime path
"""Install the InvokeAI application into the given runtime path
:param root: Destination path for the installation
:type root: str
:param version: InvokeAI version to install
:type version: str
:param yes: Accept defaults to all questions
:type yes: bool
:param find_links: A local directory to search for requirement wheels before going to remote indexes
:type find_links: Path
Args:
root: Destination path for the installation
yes_to_all: Accept defaults to all questions
find_links: A local directory to search for requirement wheels before going to remote indexes
wheel: A wheel file to install
"""
import messages
messages.welcome(self.available_releases)
version = messages.choose_version(self.available_releases)
if wheel:
messages.installing_from_wheel(wheel.name)
version = get_version_from_wheel_filename(wheel.name)
else:
messages.welcome(self.available_releases)
version = messages.choose_version(self.available_releases)
auto_dest = Path(os.environ.get("INVOKEAI_ROOT", root)).expanduser().resolve()
destination = auto_dest if yes_to_all else messages.dest_path(root)
@ -140,17 +156,24 @@ class Installer:
# install dependencies and the InvokeAI application
(extra_index_url, optional_modules) = get_torch_source() if not yes_to_all else (None, None)
self.instance.install(
extra_index_url,
optional_modules,
find_links,
)
self.instance.install(extra_index_url, optional_modules, find_links, wheel)
# install the launch/update scripts into the runtime directory
self.instance.install_user_scripts()
# run through the configuration flow
self.instance.configure()
message = f"""
*** Installation Successful ***
To start the application, run:
{destination}/invoke.{"bat" if sys.platform == "win32" else "sh"}
For more information, troubleshooting and support, visit our docs at:
{DOCS_URL}
Join the community on Discord:
{DISCORD_URL}
"""
print(message)
class InvokeAiInstance:
@ -181,18 +204,20 @@ class InvokeAiInstance:
return (self.runtime, self.venv)
def install(self, extra_index_url=None, optional_modules=None, find_links=None):
"""
Install the package from PyPi.
def install(
self,
extra_index_url: Optional[str] = None,
optional_modules: Optional[str] = None,
find_links: Optional[str] = None,
wheel: Optional[Path] = None,
):
"""Install the package from PyPi or a wheel, if provided.
:param extra_index_url: the "--extra-index-url ..." line for pip to look in extra indexes.
:type extra_index_url: str
:param optional_modules: optional modules to install using "[module1,module2]" format.
:type optional_modules: str
:param find_links: path to a directory containing wheels to be searched prior to going to the internet
:type find_links: Path
Args:
extra_index_url: the "--extra-index-url ..." line for pip to look in extra indexes.
optional_modules: optional modules to install using "[module1,module2]" format.
find_links: path to a directory containing wheels to be searched prior to going to the internet
wheel: a wheel file to install
"""
import messages
@ -216,7 +241,7 @@ class InvokeAiInstance:
messages.simple_banner("Installing the InvokeAI Application :art:")
from plumbum import FG, ProcessExecutionError, local # type: ignore
from plumbum import FG, ProcessExecutionError, local
pip = local[self.pip]
@ -225,12 +250,12 @@ class InvokeAiInstance:
"--require-virtualenv",
"--force-reinstall",
"--use-pep517",
str(src),
str(src) if not wheel else str(wheel),
"--find-links" if find_links is not None else None,
find_links,
"--extra-index-url" if extra_index_url is not None else None,
extra_index_url,
pre_flag,
pre_flag if not wheel else None, # Ignore the flag if we are installing a wheel
]
try:
@ -242,53 +267,6 @@ class InvokeAiInstance:
)
sys.exit(1)
def configure(self):
"""
Configure the InvokeAI runtime directory
"""
auto_install = False
# set sys.argv to a consistent state
new_argv = [sys.argv[0]]
for i in range(1, len(sys.argv)):
el = sys.argv[i]
if el in ["-r", "--root"]:
new_argv.append(el)
new_argv.append(sys.argv[i + 1])
elif el in ["-y", "--yes", "--yes-to-all"]:
auto_install = True
sys.argv = new_argv
import messages
import requests # to catch download exceptions
auto_install = auto_install or messages.user_wants_auto_configuration()
if auto_install:
sys.argv.append("--yes")
else:
messages.introduction()
from invokeai.frontend.install.invokeai_configure import invokeai_configure
# NOTE: currently the config script does its own arg parsing! this means the command-line switches
# from the installer will also automatically propagate down to the config script.
# this may change in the future with config refactoring!
succeeded = False
try:
invokeai_configure()
succeeded = True
except requests.exceptions.ConnectionError as e:
print(f"\nA network error was encountered during configuration and download: {str(e)}")
except OSError as e:
print(f"\nAn OS error was encountered during configuration and download: {str(e)}")
except Exception as e:
print(f"\nA problem was encountered during the configuration and download steps: {str(e)}")
finally:
if not succeeded:
print('To try again, find the "invokeai" directory, run the script "invoke.sh" or "invoke.bat"')
print("and choose option 7 to fix a broken install, optionally followed by option 5 to install models.")
print("Alternatively you can relaunch the installer.")
def install_user_scripts(self):
"""
Copy the launch and update scripts to the runtime dir
@ -339,7 +317,9 @@ def upgrade_pip(venv_path: Path) -> str | None:
python = str(venv_path.expanduser().resolve() / python)
try:
result = subprocess.check_output([python, "-m", "pip", "install", "--upgrade", "pip"]).decode()
result = subprocess.check_output([python, "-m", "pip", "install", "--upgrade", "pip"]).decode(
encoding=locale.getpreferredencoding()
)
except subprocess.CalledProcessError as e:
print(e)
result = None
@ -370,7 +350,7 @@ def set_sys_path(venv_path: Path) -> None:
sys.path.append(str(Path(venv_path, lib, "site-packages").expanduser().resolve()))
def get_github_releases() -> tuple[list, list] | None:
def get_github_releases() -> tuple[list[str], list[str]] | None:
"""
Query Github for published (pre-)release versions.
Return a tuple where the first element is a list of stable releases and the second element is a list of pre-releases.
@ -381,7 +361,8 @@ def get_github_releases() -> tuple[list, list] | None:
## get latest releases using github api
url = "https://api.github.com/repos/invoke-ai/InvokeAI/releases"
releases, pre_releases = [], []
releases: list[str] = []
pre_releases: list[str] = []
try:
res = requests.get(url)
res.raise_for_status()
@ -426,22 +407,29 @@ def get_torch_source() -> Tuple[str | None, str | None]:
# device can be one of: "cuda", "rocm", "cpu", "cuda_and_dml, autodetect"
device = select_gpu()
# The correct extra index URLs for torch are inconsistent, see https://pytorch.org/get-started/locally/#start-locally
url = None
optional_modules = "[onnx]"
optional_modules: str | None = None
if OS == "Linux":
if device.value == "rocm":
url = "https://download.pytorch.org/whl/rocm5.6"
elif device.value == "cpu":
url = "https://download.pytorch.org/whl/cpu"
elif device.value == "cuda":
# CUDA uses the default PyPi index
optional_modules = "[xformers,onnx-cuda]"
elif OS == "Windows":
if device.value == "cuda":
url = "https://download.pytorch.org/whl/cu121"
optional_modules = "[xformers,onnx-cuda]"
if device.value == "cuda_and_dml":
url = "https://download.pytorch.org/whl/cu121"
optional_modules = "[xformers,onnx-directml]"
elif device.value == "cpu":
# CPU uses the default PyPi index, no optional modules
pass
elif OS == "Darwin":
# macOS uses the default PyPi index, no optional modules
pass
# in all other cases, Torch wheels should be coming from PyPi as of Torch 1.13
# Fall back to defaults
return (url, optional_modules)

View File

@ -30,16 +30,17 @@ if __name__ == "__main__":
)
parser.add_argument(
"--version",
dest="version",
help="Version of InvokeAI to install. Default to the latest stable release. A special 'pre' value will install the latest published pre-release version.",
"--find-links",
dest="find_links",
help="Specifies a directory of local wheel files to be searched prior to searching the online repositories.",
type=Path,
default=None,
)
parser.add_argument(
"--find-links",
dest="find_links",
help="Specifies a directory of local wheel files to be searched prior to searching the online repositories.",
"--wheel",
dest="wheel",
help="Specifies a wheel for the InvokeAI package. Used for troubleshooting or testing prereleases.",
type=Path,
default=None,
)

View File

@ -7,8 +7,9 @@ import os
import platform
from enum import Enum
from pathlib import Path
from typing import Optional
from prompt_toolkit import HTML, prompt
from prompt_toolkit import prompt
from prompt_toolkit.completion import FuzzyWordCompleter, PathCompleter
from prompt_toolkit.validation import Validator
from rich import box, print
@ -19,13 +20,6 @@ from rich.style import Style
from rich.syntax import Syntax
from rich.text import Text
"""
INVOKE_AI_SRC=https://github.com/invoke-ai/InvokeAI/archive/refs/tags/${INVOKEAI_VERSION}.zip
INSTRUCTIONS=https://invoke-ai.github.io/InvokeAI/installation/INSTALL_AUTOMATED/
TROUBLESHOOTING=https://invoke-ai.github.io/InvokeAI/installation/INSTALL_AUTOMATED/#troubleshooting
"""
OS = platform.uname().system
ARCH = platform.uname().machine
@ -36,7 +30,7 @@ else:
console = Console(style=Style(color="grey74", bgcolor="grey19"))
def welcome(available_releases: tuple | None = None) -> None:
def welcome(available_releases: tuple[list[str], list[str]] | None = None) -> None:
@group()
def text():
if (platform_specific := _platform_specific_help()) is not None:
@ -72,7 +66,34 @@ def welcome(available_releases: tuple | None = None) -> None:
console.line()
def choose_version(available_releases: tuple | None = None) -> str:
def installing_from_wheel(wheel_filename: str) -> None:
"""Display a message about installing from a wheel"""
@group()
def text():
yield Text.from_markup(f"You are installing from a wheel file: [bold]{wheel_filename}\n")
yield Text.from_markup(
"[bold orange3]If you are not sure why you are doing this, you should cancel and install InvokeAI normally."
)
console.print(
Panel(
title="Installing from Wheel",
renderable=text(),
box=box.DOUBLE,
expand=True,
padding=(1, 2),
)
)
should_proceed = Confirm.ask("Do you want to proceed?")
if not should_proceed:
console.print("Installation cancelled.")
exit()
def choose_version(available_releases: tuple[list[str], list[str]] | None = None) -> str:
"""
Prompt the user to choose an Invoke version to install
"""
@ -98,39 +119,6 @@ def choose_version(available_releases: tuple | None = None) -> str:
return "stable" if response == "" else response
def user_wants_auto_configuration() -> bool:
"""Prompt the user to choose between manual and auto configuration."""
console.rule("InvokeAI Configuration Section")
console.print(
Panel(
Group(
"\n".join(
[
"Libraries are installed and InvokeAI will now set up its root directory and configuration. Choose between:",
"",
" * AUTOMATIC configuration: install reasonable defaults and a minimal set of starter models.",
" * MANUAL configuration: manually inspect and adjust configuration options and pick from a larger set of starter models.",
"",
"Later you can fine tune your configuration by selecting option [6] 'Change InvokeAI startup options' from the invoke.bat/invoke.sh launcher script.",
]
),
),
box=box.MINIMAL,
padding=(1, 1),
)
)
choice = (
prompt(
HTML("Choose <b>&lt;a&gt;</b>utomatic or <b>&lt;m&gt;</b>anual configuration [a/m] (a): "),
validator=Validator.from_callable(
lambda n: n == "" or n.startswith(("a", "A", "m", "M")), error_message="Please select 'a' or 'm'"
),
)
or "a"
)
return choice.lower().startswith("a")
def confirm_install(dest: Path) -> bool:
if dest.exists():
print(f":stop_sign: Directory {dest} already exists!")
@ -147,7 +135,7 @@ def confirm_install(dest: Path) -> bool:
return dest_confirmed
def dest_path(dest=None) -> Path | None:
def dest_path(dest: Optional[str | Path] = None) -> Path | None:
"""
Prompt the user for the destination path and create the path
@ -219,10 +207,8 @@ def dest_path(dest=None) -> Path | None:
class GpuType(Enum):
CUDA = "cuda"
CUDA_AND_DML = "cuda_and_dml"
ROCM = "rocm"
CPU = "cpu"
AUTODETECT = "autodetect"
def select_gpu() -> GpuType:
@ -238,10 +224,6 @@ def select_gpu() -> GpuType:
"an [gold1 b]NVIDIA[/] GPU (using CUDA™)",
GpuType.CUDA,
)
nvidia_with_dml = (
"an [gold1 b]NVIDIA[/] GPU (using CUDA™, and DirectML™ for ONNX) -- ALPHA",
GpuType.CUDA_AND_DML,
)
amd = (
"an [gold1 b]AMD[/] GPU (using ROCm™)",
GpuType.ROCM,
@ -250,27 +232,19 @@ def select_gpu() -> GpuType:
"Do not install any GPU support, use CPU for generation (slow)",
GpuType.CPU,
)
autodetect = (
"I'm not sure what to choose",
GpuType.AUTODETECT,
)
options = []
if OS == "Windows":
options = [nvidia, nvidia_with_dml, cpu]
options = [nvidia, cpu]
if OS == "Linux":
options = [nvidia, amd, cpu]
elif OS == "Darwin":
options = [cpu]
# future CoreML?
if len(options) == 1:
print(f'Your platform [gold1]{OS}-{ARCH}[/] only supports the "{options[0][1]}" driver. Proceeding with that.')
return options[0][1]
# "I don't know" is always added the last option
options.append(autodetect) # type: ignore
options = {str(i): opt for i, opt in enumerate(options, 1)}
console.rule(":space_invader: GPU (Graphics Card) selection :space_invader:")
@ -304,11 +278,6 @@ def select_gpu() -> GpuType:
),
)
if options[choice][1] is GpuType.AUTODETECT:
console.print(
"No problem. We will install CUDA support first :crossed_fingers: If Invoke does not detect a GPU, please re-run the installer and select one of the other GPU types."
)
return options[choice][1]
@ -351,34 +320,6 @@ def windows_long_paths_registry() -> None:
)
def introduction() -> None:
"""
Display a banner when starting configuration of the InvokeAI application
"""
console.rule()
console.print(
Panel(
title=":art: Configuring InvokeAI :art:",
renderable=Group(
"",
"[b]This script will:",
"",
"1. Configure the InvokeAI application directory",
"2. Help download the Stable Diffusion weight files",
" and other large models that are needed for text to image generation",
"3. Create initial configuration files.",
"",
"[i]At any point you may interrupt this program and resume later.",
"",
"[b]For the best user experience, please enlarge or maximize this window",
),
)
)
console.line(2)
def _platform_specific_help() -> Text | None:
if OS == "Darwin":
text = Text.from_markup(

View File

@ -2,12 +2,12 @@
set -e
BCYAN="\e[1;36m"
BYELLOW="\e[1;33m"
BGREEN="\e[1;32m"
BRED="\e[1;31m"
RED="\e[31m"
RESET="\e[0m"
BCYAN="\033[1;36m"
BYELLOW="\033[1;33m"
BGREEN="\033[1;32m"
BRED="\033[1;31m"
RED="\033[31m"
RESET="\033[0m"
function does_tag_exist {
git rev-parse --quiet --verify "refs/tags/$1" >/dev/null
@ -23,49 +23,40 @@ function git_show {
VERSION=$(
cd ..
python -c "from invokeai.version import __version__ as version; print(version)"
python3 -c "from invokeai.version import __version__ as version; print(version)"
)
PATCH=""
MAJOR_VERSION=$(echo $VERSION | sed 's/\..*$//')
VERSION="v${VERSION}${PATCH}"
LATEST_TAG="v${MAJOR_VERSION}-latest"
if does_tag_exist $VERSION; then
echo -e "${BCYAN}${VERSION}${RESET} already exists:"
git_show_ref tags/$VERSION
echo
fi
if does_tag_exist $LATEST_TAG; then
echo -e "${BCYAN}${LATEST_TAG}${RESET} already exists:"
git_show_ref tags/$LATEST_TAG
echo
fi
echo -e "${BGREEN}HEAD${RESET}:"
git_show
echo
echo -e -n "Create tags ${BCYAN}${VERSION}${RESET} and ${BCYAN}${LATEST_TAG}${RESET} @ ${BGREEN}HEAD${RESET}, ${RED}deleting existing tags on remote${RESET}? "
echo -e "${BGREEN}git remote -v${RESET}:"
git remote -v
echo
echo -e -n "Create tags ${BCYAN}${VERSION}${RESET} @ ${BGREEN}HEAD${RESET}, ${RED}deleting existing tags on origin remote${RESET}? "
read -e -p 'y/n [n]: ' input
RESPONSE=${input:='n'}
if [ "$RESPONSE" == 'y' ]; then
echo
echo -e "Deleting ${BCYAN}${VERSION}${RESET} tag on remote..."
git push --delete origin $VERSION
echo -e "Deleting ${BCYAN}${VERSION}${RESET} tag on origin remote..."
git push origin :refs/tags/$VERSION
echo -e "Tagging ${BGREEN}HEAD${RESET} with ${BCYAN}${VERSION}${RESET} locally..."
echo -e "Tagging ${BGREEN}HEAD${RESET} with ${BCYAN}${VERSION}${RESET} on locally..."
if ! git tag -fa $VERSION; then
echo "Existing/invalid tag"
exit -1
fi
echo -e "Deleting ${BCYAN}${LATEST_TAG}${RESET} tag on remote..."
git push --delete origin $LATEST_TAG
echo -e "Tagging ${BGREEN}HEAD${RESET} with ${BCYAN}${LATEST_TAG}${RESET} locally..."
git tag -fa $LATEST_TAG
echo -e "Pushing updated tags to remote..."
echo -e "Pushing updated tags to origin remote..."
git push origin --tags
fi
exit 0

View File

@ -9,37 +9,18 @@ set INVOKEAI_ROOT=.
:start
echo Desired action:
echo 1. Generate images with the browser-based interface
echo 2. Run textual inversion training
echo 3. Merge models (diffusers type only)
echo 4. Download and install models
echo 5. Change InvokeAI startup options
echo 6. Re-run the configure script to fix a broken install or to complete a major upgrade
echo 7. Open the developer console
echo 8. Update InvokeAI (DEPRECATED - please use the installer)
echo 9. Run the InvokeAI image database maintenance script
echo 10. Command-line help
echo 2. Open the developer console
echo 3. Command-line help
echo Q - Quit
set /P choice="Please enter 1-10, Q: [1] "
echo.
echo To update, download and run the installer from https://github.com/invoke-ai/InvokeAI/releases/latest
echo.
set /P choice="Please enter 1-4, Q: [1] "
if not defined choice set choice=1
IF /I "%choice%" == "1" (
echo Starting the InvokeAI browser-based UI..
python .venv\Scripts\invokeai-web.exe %*
) ELSE IF /I "%choice%" == "2" (
echo Starting textual inversion training..
python .venv\Scripts\invokeai-ti.exe --gui
) ELSE IF /I "%choice%" == "3" (
echo Starting model merging script..
python .venv\Scripts\invokeai-merge.exe --gui
) ELSE IF /I "%choice%" == "4" (
echo Running invokeai-model-install...
python .venv\Scripts\invokeai-model-install.exe
) ELSE IF /I "%choice%" == "5" (
echo Running invokeai-configure...
python .venv\Scripts\invokeai-configure.exe --skip-sd-weight --skip-support-models
) ELSE IF /I "%choice%" == "6" (
echo Running invokeai-configure...
python .venv\Scripts\invokeai-configure.exe --yes --skip-sd-weight
) ELSE IF /I "%choice%" == "7" (
echo Developer Console
echo Python command is:
where python
@ -51,15 +32,7 @@ IF /I "%choice%" == "1" (
echo *************************
echo *** Type `exit` to quit this shell and deactivate the Python virtual environment ***
call cmd /k
) ELSE IF /I "%choice%" == "8" (
echo UPDATING FROM WITHIN THE APP IS BEING DEPRECATED.
echo Please download the installer from https://github.com/invoke-ai/InvokeAI/releases/latest and run it to update your installation.
timeout 4
python -m invokeai.frontend.install.invokeai_update
) ELSE IF /I "%choice%" == "9" (
echo Running the db maintenance script...
python .venv\Scripts\invokeai-db-maintenance.exe
) ELSE IF /I "%choice%" == "10" (
) ELSE IF /I "%choice%" == "3" (
echo Displaying command line help...
python .venv\Scripts\invokeai-web.exe --help %*
pause

View File

@ -17,38 +17,21 @@
set -eu
# Ensure we're in the correct folder in case user's CWD is somewhere else
scriptdir=$(dirname "$0")
scriptdir=$(dirname $(readlink -f "$0"))
cd "$scriptdir"
. .venv/bin/activate
export INVOKEAI_ROOT="$scriptdir"
# Stash the CLI args - when we prompt for user input, `$@` is overwritten
PARAMS=$@
# Check to see if dialog is installed (it seems to be fairly standard, but good to check regardless) and if the user has passed the --no-tui argument to disable the dialog TUI
tui=true
if command -v dialog &>/dev/null; then
# This must use $@ to properly loop through the arguments passed by the user
for arg in "$@"; do
if [ "$arg" == "--no-tui" ]; then
tui=false
# Remove the --no-tui argument to avoid errors later on when passing arguments to InvokeAI
PARAMS=$(echo "$PARAMS" | sed 's/--no-tui//')
break
fi
done
else
tui=false
fi
# Set required env var for torch on mac MPS
# This setting allows torch to fall back to CPU for operations that are not supported by MPS on macOS.
if [ "$(uname -s)" == "Darwin" ]; then
export PYTORCH_ENABLE_MPS_FALLBACK=1
fi
# Avoid glibc memory fragmentation. See invokeai/backend/model_management/README.md for details.
export MALLOC_MMAP_THRESHOLD_=1048576
# Primary function for the case statement to determine user input
do_choice() {
case $1 in
@ -58,49 +41,12 @@ do_choice() {
invokeai-web $PARAMS
;;
2)
clear
printf "Textual inversion training\n"
invokeai-ti --gui $PARAMS
;;
3)
clear
printf "Merge models (diffusers type only)\n"
invokeai-merge --gui $PARAMS
;;
4)
clear
printf "Download and install models\n"
invokeai-model-install --root ${INVOKEAI_ROOT}
;;
5)
clear
printf "Change InvokeAI startup options\n"
invokeai-configure --root ${INVOKEAI_ROOT} --skip-sd-weights --skip-support-models
;;
6)
clear
printf "Re-run the configure script to fix a broken install or to complete a major upgrade\n"
invokeai-configure --root ${INVOKEAI_ROOT} --yes --default_only --skip-sd-weights
;;
7)
clear
printf "Open the developer console\n"
file_name=$(basename "${BASH_SOURCE[0]}")
bash --init-file "$file_name"
;;
8)
clear
printf "UPDATING FROM WITHIN THE APP IS BEING DEPRECATED\n"
printf "Please download the installer from https://github.com/invoke-ai/InvokeAI/releases/latest and run it to update your installation.\n"
sleep 4
python -m invokeai.frontend.install.invokeai_update
;;
9)
clear
printf "Running the db maintenance script\n"
invokeai-db-maintenance --root ${INVOKEAI_ROOT}
;;
10)
3)
clear
printf "Command-line help\n"
invokeai-web --help
@ -114,69 +60,25 @@ do_choice() {
clear
}
# Dialog-based TUI for launcing Invoke functions
do_dialog() {
options=(
1 "Generate images with a browser-based interface"
2 "Textual inversion training"
3 "Merge models (diffusers type only)"
4 "Download and install models"
5 "Change InvokeAI startup options"
6 "Re-run the configure script to fix a broken install or to complete a major upgrade"
7 "Open the developer console"
8 "Update InvokeAI (DEPRECATED - please use the installer)"
9 "Run the InvokeAI image database maintenance script"
10 "Command-line help"
)
choice=$(dialog --clear \
--backtitle "\Zb\Zu\Z3InvokeAI" \
--colors \
--title "What would you like to do?" \
--ok-label "Run" \
--cancel-label "Exit" \
--help-button \
--help-label "CLI Help" \
--menu "Select an option:" \
0 0 0 \
"${options[@]}" \
2>&1 >/dev/tty) || clear
do_choice "$choice"
clear
}
# Command-line interface for launching Invoke functions
do_line_input() {
clear
printf " ** For a more attractive experience, please install the 'dialog' utility using your package manager. **\n\n"
printf "What would you like to do?\n"
printf "1: Generate images using the browser-based interface\n"
printf "2: Run textual inversion training\n"
printf "3: Merge models (diffusers type only)\n"
printf "4: Download and install models\n"
printf "5: Change InvokeAI startup options\n"
printf "6: Re-run the configure script to fix a broken install\n"
printf "7: Open the developer console\n"
printf "8: Update InvokeAI\n"
printf "9: Run the InvokeAI image database maintenance script\n"
printf "10: Command-line help\n"
printf "2: Open the developer console\n"
printf "3: Command-line help\n"
printf "Q: Quit\n\n"
read -p "Please enter 1-10, Q: [1] " yn
printf "To update, download and run the installer from https://github.com/invoke-ai/InvokeAI/releases/latest.\n\n"
read -p "Please enter 1-4, Q: [1] " yn
choice=${yn:='1'}
do_choice $choice
clear
}
# Main IF statement for launching Invoke with either the TUI or CLI, and for checking if the user is in the developer console
# Main IF statement for launching Invoke, and for checking if the user is in the developer console
if [ "$0" != "bash" ]; then
while true; do
if $tui; then
# .dialogrc must be located in the same directory as the invoke.sh script
export DIALOGRC="./.dialogrc"
do_dialog
else
do_line_input
fi
do_line_input
done
else # in developer console
python --version

View File

@ -1,11 +0,0 @@
Organization of the source tree:
app -- Home of nodes invocations and services
assets -- Images and other data files used by InvokeAI
backend -- Non-user facing libraries, including the rendering
core.
configs -- Configuration files used at install and run times
frontend -- User-facing scripts, including the CLI and the WebUI
version -- Current InvokeAI version string, stored
in version/invokeai_version.py

View File

@ -1,40 +1,45 @@
# Copyright (c) 2022 Kyle Schouviller (https://github.com/kyle0654)
import asyncio
from logging import Logger
import torch
from invokeai.app.services.board_image_records.board_image_records_sqlite import SqliteBoardImageRecordStorage
from invokeai.app.services.board_images.board_images_default import BoardImagesService
from invokeai.app.services.board_records.board_records_sqlite import SqliteBoardRecordStorage
from invokeai.app.services.boards.boards_default import BoardService
from invokeai.app.services.bulk_download.bulk_download_default import BulkDownloadService
from invokeai.app.services.config.config_default import InvokeAIAppConfig
from invokeai.app.services.download.download_default import DownloadQueueService
from invokeai.app.services.events.events_fastapievents import FastAPIEventService
from invokeai.app.services.image_files.image_files_disk import DiskImageFileStorage
from invokeai.app.services.image_records.image_records_sqlite import SqliteImageRecordStorage
from invokeai.app.services.images.images_default import ImageService
from invokeai.app.services.invocation_cache.invocation_cache_memory import MemoryInvocationCache
from invokeai.app.services.invocation_services import InvocationServices
from invokeai.app.services.invocation_stats.invocation_stats_default import InvocationStatsService
from invokeai.app.services.invoker import Invoker
from invokeai.app.services.model_images.model_images_default import ModelImageFileStorageDisk
from invokeai.app.services.model_manager.model_manager_default import ModelManagerService
from invokeai.app.services.model_records.model_records_sql import ModelRecordServiceSQL
from invokeai.app.services.names.names_default import SimpleNameService
from invokeai.app.services.object_serializer.object_serializer_disk import ObjectSerializerDisk
from invokeai.app.services.object_serializer.object_serializer_forward_cache import ObjectSerializerForwardCache
from invokeai.app.services.session_processor.session_processor_default import (
DefaultSessionProcessor,
DefaultSessionRunner,
)
from invokeai.app.services.session_queue.session_queue_sqlite import SqliteSessionQueue
from invokeai.app.services.shared.sqlite.sqlite_util import init_db
from invokeai.app.services.style_preset_images.style_preset_images_disk import StylePresetImageFileStorageDisk
from invokeai.app.services.style_preset_records.style_preset_records_sqlite import SqliteStylePresetRecordsStorage
from invokeai.app.services.urls.urls_default import LocalUrlService
from invokeai.app.services.workflow_records.workflow_records_sqlite import SqliteWorkflowRecordsStorage
from invokeai.backend.stable_diffusion.diffusion.conditioning_data import ConditioningFieldData
from invokeai.backend.util.logging import InvokeAILogger
from invokeai.version.invokeai_version import __version__
from ..services.board_image_records.board_image_records_sqlite import SqliteBoardImageRecordStorage
from ..services.board_images.board_images_default import BoardImagesService
from ..services.board_records.board_records_sqlite import SqliteBoardRecordStorage
from ..services.boards.boards_default import BoardService
from ..services.bulk_download.bulk_download_default import BulkDownloadService
from ..services.config import InvokeAIAppConfig
from ..services.download import DownloadQueueService
from ..services.image_files.image_files_disk import DiskImageFileStorage
from ..services.image_records.image_records_sqlite import SqliteImageRecordStorage
from ..services.images.images_default import ImageService
from ..services.invocation_cache.invocation_cache_memory import MemoryInvocationCache
from ..services.invocation_services import InvocationServices
from ..services.invocation_stats.invocation_stats_default import InvocationStatsService
from ..services.invoker import Invoker
from ..services.model_manager.model_manager_default import ModelManagerService
from ..services.model_metadata import ModelMetadataStoreSQL
from ..services.model_records import ModelRecordServiceSQL
from ..services.names.names_default import SimpleNameService
from ..services.session_processor.session_processor_default import DefaultSessionProcessor
from ..services.session_queue.session_queue_sqlite import SqliteSessionQueue
from ..services.urls.urls_default import LocalUrlService
from ..services.workflow_records.workflow_records_sqlite import SqliteWorkflowRecordsStorage
from .events import FastAPIEventService
# TODO: is there a better way to achieve this?
def check_internet() -> bool:
@ -61,17 +66,24 @@ class ApiDependencies:
invoker: Invoker
@staticmethod
def initialize(config: InvokeAIAppConfig, event_handler_id: int, logger: Logger = logger) -> None:
def initialize(
config: InvokeAIAppConfig,
event_handler_id: int,
loop: asyncio.AbstractEventLoop,
logger: Logger = logger,
) -> None:
logger.info(f"InvokeAI version {__version__}")
logger.info(f"Root directory = {str(config.root_path)}")
logger.debug(f"Internet connectivity is {config.internet_available}")
output_folder = config.output_path
output_folder = config.outputs_path
if output_folder is None:
raise ValueError("Output folder is not set")
image_files = DiskImageFileStorage(f"{output_folder}/images")
model_images_folder = config.models_path
style_presets_folder = config.style_presets_path
db = init_db(config=config, logger=logger, image_files=image_files)
configuration = config
@ -81,7 +93,7 @@ class ApiDependencies:
board_images = BoardImagesService()
board_records = SqliteBoardRecordStorage(db=db)
boards = BoardService()
events = FastAPIEventService(event_handler_id)
events = FastAPIEventService(event_handler_id, loop=loop)
bulk_download = BulkDownloadService()
image_records = SqliteImageRecordStorage(db=db)
images = ImageService()
@ -92,20 +104,22 @@ class ApiDependencies:
conditioning = ObjectSerializerForwardCache(
ObjectSerializerDisk[ConditioningFieldData](output_folder / "conditioning", ephemeral=True)
)
download_queue_service = DownloadQueueService(event_bus=events)
model_metadata_service = ModelMetadataStoreSQL(db=db)
download_queue_service = DownloadQueueService(app_config=configuration, event_bus=events)
model_images_service = ModelImageFileStorageDisk(model_images_folder / "model_images")
model_manager = ModelManagerService.build_model_manager(
app_config=configuration,
model_record_service=ModelRecordServiceSQL(db=db, metadata_store=model_metadata_service),
model_record_service=ModelRecordServiceSQL(db=db, logger=logger),
download_queue=download_queue_service,
events=events,
)
names = SimpleNameService()
performance_statistics = InvocationStatsService()
session_processor = DefaultSessionProcessor()
session_processor = DefaultSessionProcessor(session_runner=DefaultSessionRunner())
session_queue = SqliteSessionQueue(db=db)
urls = LocalUrlService()
workflow_records = SqliteWorkflowRecordsStorage(db=db)
style_preset_records = SqliteStylePresetRecordsStorage(db=db)
style_preset_image_files = StylePresetImageFileStorageDisk(style_presets_folder / "images")
services = InvocationServices(
board_image_records=board_image_records,
@ -120,6 +134,7 @@ class ApiDependencies:
images=images,
invocation_cache=invocation_cache,
logger=logger,
model_images=model_images_service,
model_manager=model_manager,
download_queue=download_queue_service,
names=names,
@ -130,6 +145,8 @@ class ApiDependencies:
workflow_records=workflow_records,
tensors=tensors,
conditioning=conditioning,
style_preset_records=style_preset_records,
style_preset_image_files=style_preset_image_files,
)
ApiDependencies.invoker = Invoker(services)

View File

@ -1,52 +0,0 @@
# Copyright (c) 2022 Kyle Schouviller (https://github.com/kyle0654)
import asyncio
import threading
from queue import Empty, Queue
from typing import Any
from fastapi_events.dispatcher import dispatch
from ..services.events.events_base import EventServiceBase
class FastAPIEventService(EventServiceBase):
event_handler_id: int
__queue: Queue
__stop_event: threading.Event
def __init__(self, event_handler_id: int) -> None:
self.event_handler_id = event_handler_id
self.__queue = Queue()
self.__stop_event = threading.Event()
asyncio.create_task(self.__dispatch_from_queue(stop_event=self.__stop_event))
super().__init__()
def stop(self, *args, **kwargs):
self.__stop_event.set()
self.__queue.put(None)
def dispatch(self, event_name: str, payload: Any) -> None:
self.__queue.put({"event_name": event_name, "payload": payload})
async def __dispatch_from_queue(self, stop_event: threading.Event):
"""Get events on from the queue and dispatch them, from the correct thread"""
while not stop_event.is_set():
try:
event = self.__queue.get(block=False)
if not event: # Probably stopping
continue
dispatch(
event.get("event_name"),
payload=event.get("payload"),
middleware_id=self.event_handler_id,
)
except Empty:
await asyncio.sleep(0.1)
pass
except asyncio.CancelledError as e:
raise e # Raise a proper error

View File

@ -10,16 +10,13 @@ from fastapi import Body
from fastapi.routing import APIRouter
from pydantic import BaseModel, Field
from invokeai.app.api.dependencies import ApiDependencies
from invokeai.app.invocations.upscale import ESRGAN_MODELS
from invokeai.app.services.invocation_cache.invocation_cache_common import InvocationCacheStatus
from invokeai.backend.image_util.invisible_watermark import InvisibleWatermark
from invokeai.backend.image_util.patchmatch import PatchMatch
from invokeai.backend.image_util.safety_checker import SafetyChecker
from invokeai.backend.image_util.infill_methods.patchmatch import PatchMatch
from invokeai.backend.util.logging import logging
from invokeai.version import __version__
from ..dependencies import ApiDependencies
class LogLevel(int, Enum):
NotSet = logging.NOTSET
@ -101,7 +98,7 @@ async def get_app_deps() -> AppDependencyVersions:
@app_router.get("/config", operation_id="get_config", status_code=200, response_model=AppConfig)
async def get_config() -> AppConfig:
infill_methods = ["tile", "lama", "cv2"]
infill_methods = ["tile", "lama", "cv2", "color"] # TODO: add mosaic back
if PatchMatch.patchmatch_available():
infill_methods.append("patchmatch")
@ -110,13 +107,9 @@ async def get_config() -> AppConfig:
upscaling_models.append(str(Path(model).stem))
upscaler = Upscaler(upscaling_method="esrgan", upscaling_models=upscaling_models)
nsfw_methods = []
if SafetyChecker.safety_checker_available():
nsfw_methods.append("nsfw_checker")
nsfw_methods = ["nsfw_checker"]
watermarking_methods = []
if InvisibleWatermark.invisible_watermark_available():
watermarking_methods.append("invisible_watermark")
watermarking_methods = ["invisible_watermark"]
return AppConfig(
infill_methods=infill_methods,

View File

@ -2,7 +2,7 @@ from fastapi import Body, HTTPException
from fastapi.routing import APIRouter
from pydantic import BaseModel, Field
from ..dependencies import ApiDependencies
from invokeai.app.api.dependencies import ApiDependencies
board_images_router = APIRouter(prefix="/v1/board_images", tags=["boards"])

View File

@ -4,12 +4,11 @@ from fastapi import Body, HTTPException, Path, Query
from fastapi.routing import APIRouter
from pydantic import BaseModel, Field
from invokeai.app.api.dependencies import ApiDependencies
from invokeai.app.services.board_records.board_records_common import BoardChanges
from invokeai.app.services.boards.boards_common import BoardDTO
from invokeai.app.services.shared.pagination import OffsetPaginatedResults
from ..dependencies import ApiDependencies
boards_router = APIRouter(prefix="/v1/boards", tags=["boards"])
@ -32,6 +31,7 @@ class DeleteBoardResult(BaseModel):
)
async def create_board(
board_name: str = Query(description="The name of the board to create"),
is_private: bool = Query(default=False, description="Whether the board is private"),
) -> BoardDTO:
"""Creates a board"""
try:
@ -118,15 +118,13 @@ async def list_boards(
all: Optional[bool] = Query(default=None, description="Whether to list all boards"),
offset: Optional[int] = Query(default=None, description="The page offset"),
limit: Optional[int] = Query(default=None, description="The number of boards per page"),
include_archived: bool = Query(default=False, description="Whether or not to include archived boards in list"),
) -> Union[OffsetPaginatedResults[BoardDTO], list[BoardDTO]]:
"""Gets a list of boards"""
if all:
return ApiDependencies.invoker.services.boards.get_all()
return ApiDependencies.invoker.services.boards.get_all(include_archived)
elif offset is not None and limit is not None:
return ApiDependencies.invoker.services.boards.get_many(
offset,
limit,
)
return ApiDependencies.invoker.services.boards.get_many(offset, limit, include_archived)
else:
raise HTTPException(
status_code=400,

View File

@ -8,13 +8,12 @@ from fastapi.routing import APIRouter
from pydantic.networks import AnyHttpUrl
from starlette.exceptions import HTTPException
from invokeai.app.api.dependencies import ApiDependencies
from invokeai.app.services.download import (
DownloadJob,
UnknownJobIDException,
)
from ..dependencies import ApiDependencies
download_queue_router = APIRouter(prefix="/v1/download_queue", tags=["download_queue"])

View File

@ -6,15 +6,18 @@ from fastapi import BackgroundTasks, Body, HTTPException, Path, Query, Request,
from fastapi.responses import FileResponse
from fastapi.routing import APIRouter
from PIL import Image
from pydantic import BaseModel, Field, ValidationError
from pydantic import BaseModel, Field, JsonValue
from invokeai.app.invocations.fields import MetadataField, MetadataFieldValidator
from invokeai.app.services.image_records.image_records_common import ImageCategory, ImageRecordChanges, ResourceOrigin
from invokeai.app.api.dependencies import ApiDependencies
from invokeai.app.invocations.fields import MetadataField
from invokeai.app.services.image_records.image_records_common import (
ImageCategory,
ImageRecordChanges,
ResourceOrigin,
)
from invokeai.app.services.images.images_common import ImageDTO, ImageUrlsDTO
from invokeai.app.services.shared.pagination import OffsetPaginatedResults
from invokeai.app.services.workflow_records.workflow_records_common import WorkflowWithoutID, WorkflowWithoutIDValidator
from ..dependencies import ApiDependencies
from invokeai.app.services.shared.sqlite.sqlite_common import SQLiteDirection
images_router = APIRouter(prefix="/v1/images", tags=["images"])
@ -42,13 +45,17 @@ async def upload_image(
board_id: Optional[str] = Query(default=None, description="The board to add this image to, if any"),
session_id: Optional[str] = Query(default=None, description="The session ID associated with this upload, if any"),
crop_visible: Optional[bool] = Query(default=False, description="Whether to crop the image"),
metadata: Optional[JsonValue] = Body(
default=None, description="The metadata to associate with the image", embed=True
),
) -> ImageDTO:
"""Uploads an image"""
if not file.content_type or not file.content_type.startswith("image"):
raise HTTPException(status_code=415, detail="Not an image")
metadata = None
workflow = None
_metadata = None
_workflow = None
_graph = None
contents = await file.read()
try:
@ -62,22 +69,28 @@ async def upload_image(
# TODO: retain non-invokeai metadata on upload?
# attempt to parse metadata from image
metadata_raw = pil_image.info.get("invokeai_metadata", None)
if metadata_raw:
try:
metadata = MetadataFieldValidator.validate_json(metadata_raw)
except ValidationError:
ApiDependencies.invoker.services.logger.warn("Failed to parse metadata for uploaded image")
pass
metadata_raw = metadata if isinstance(metadata, str) else pil_image.info.get("invokeai_metadata", None)
if isinstance(metadata_raw, str):
_metadata = metadata_raw
else:
ApiDependencies.invoker.services.logger.debug("Failed to parse metadata for uploaded image")
pass
# attempt to parse workflow from image
workflow_raw = pil_image.info.get("invokeai_workflow", None)
if workflow_raw is not None:
try:
workflow = WorkflowWithoutIDValidator.validate_json(workflow_raw)
except ValidationError:
ApiDependencies.invoker.services.logger.warn("Failed to parse metadata for uploaded image")
pass
if isinstance(workflow_raw, str):
_workflow = workflow_raw
else:
ApiDependencies.invoker.services.logger.debug("Failed to parse workflow for uploaded image")
pass
# attempt to extract graph from image
graph_raw = pil_image.info.get("invokeai_graph", None)
if isinstance(graph_raw, str):
_graph = graph_raw
else:
ApiDependencies.invoker.services.logger.debug("Failed to parse graph for uploaded image")
pass
try:
image_dto = ApiDependencies.invoker.services.images.create(
@ -86,8 +99,9 @@ async def upload_image(
image_category=image_category,
session_id=session_id,
board_id=board_id,
metadata=metadata,
workflow=workflow,
metadata=_metadata,
workflow=_workflow,
graph=_graph,
is_intermediate=is_intermediate,
)
@ -185,21 +199,27 @@ async def get_image_metadata(
raise HTTPException(status_code=404)
class WorkflowAndGraphResponse(BaseModel):
workflow: Optional[str] = Field(description="The workflow used to generate the image, as stringified JSON")
graph: Optional[str] = Field(description="The graph used to generate the image, as stringified JSON")
@images_router.get(
"/i/{image_name}/workflow", operation_id="get_image_workflow", response_model=Optional[WorkflowWithoutID]
"/i/{image_name}/workflow", operation_id="get_image_workflow", response_model=WorkflowAndGraphResponse
)
async def get_image_workflow(
image_name: str = Path(description="The name of image whose workflow to get"),
) -> Optional[WorkflowWithoutID]:
) -> WorkflowAndGraphResponse:
try:
return ApiDependencies.invoker.services.images.get_workflow(image_name)
workflow = ApiDependencies.invoker.services.images.get_workflow(image_name)
graph = ApiDependencies.invoker.services.images.get_graph(image_name)
return WorkflowAndGraphResponse(workflow=workflow, graph=graph)
except Exception:
raise HTTPException(status_code=404)
@images_router.api_route(
@images_router.get(
"/i/{image_name}/full",
methods=["GET", "HEAD"],
operation_id="get_image_full",
response_class=Response,
responses={
@ -210,24 +230,30 @@ async def get_image_workflow(
404: {"description": "Image not found"},
},
)
@images_router.head(
"/i/{image_name}/full",
operation_id="get_image_full_head",
response_class=Response,
responses={
200: {
"description": "Return the full-resolution image",
"content": {"image/png": {}},
},
404: {"description": "Image not found"},
},
)
async def get_image_full(
image_name: str = Path(description="The name of full-resolution image file to get"),
) -> FileResponse:
) -> Response:
"""Gets a full-resolution image file"""
try:
path = ApiDependencies.invoker.services.images.get_path(image_name)
if not ApiDependencies.invoker.services.images.validate_path(path):
raise HTTPException(status_code=404)
response = FileResponse(
path,
media_type="image/png",
filename=image_name,
content_disposition_type="inline",
)
with open(path, "rb") as f:
content = f.read()
response = Response(content, media_type="image/png")
response.headers["Cache-Control"] = f"max-age={IMAGE_MAX_AGE}"
response.headers["Content-Disposition"] = f'inline; filename="{image_name}"'
return response
except Exception:
raise HTTPException(status_code=404)
@ -247,15 +273,14 @@ async def get_image_full(
)
async def get_image_thumbnail(
image_name: str = Path(description="The name of thumbnail image file to get"),
) -> FileResponse:
) -> Response:
"""Gets a thumbnail image file"""
try:
path = ApiDependencies.invoker.services.images.get_path(image_name, thumbnail=True)
if not ApiDependencies.invoker.services.images.validate_path(path):
raise HTTPException(status_code=404)
response = FileResponse(path, media_type="image/webp", content_disposition_type="inline")
with open(path, "rb") as f:
content = f.read()
response = Response(content, media_type="image/webp")
response.headers["Cache-Control"] = f"max-age={IMAGE_MAX_AGE}"
return response
except Exception:
@ -299,16 +324,14 @@ async def list_image_dtos(
),
offset: int = Query(default=0, description="The page offset"),
limit: int = Query(default=10, description="The number of images per page"),
order_dir: SQLiteDirection = Query(default=SQLiteDirection.Descending, description="The order of sort"),
starred_first: bool = Query(default=True, description="Whether to sort by starred images first"),
search_term: Optional[str] = Query(default=None, description="The term to search for"),
) -> OffsetPaginatedResults[ImageDTO]:
"""Gets a list of image DTOs"""
image_dtos = ApiDependencies.invoker.services.images.get_many(
offset,
limit,
image_origin,
categories,
is_intermediate,
board_id,
offset, limit, starred_first, order_dir, image_origin, categories, is_intermediate, board_id, search_term
)
return image_dtos

View File

@ -1,43 +1,46 @@
# Copyright (c) 2023 Lincoln D. Stein
"""FastAPI route for model configuration records."""
import io
import pathlib
import shutil
from hashlib import sha1
from random import randbytes
from typing import Any, Dict, List, Optional, Set
import traceback
from copy import deepcopy
from tempfile import TemporaryDirectory
from typing import List, Optional, Type
from fastapi import Body, Path, Query, Response
from fastapi import Body, Path, Query, Response, UploadFile
from fastapi.responses import FileResponse, HTMLResponse
from fastapi.routing import APIRouter
from pydantic import BaseModel, ConfigDict, Field
from PIL import Image
from pydantic import AnyHttpUrl, BaseModel, ConfigDict, Field
from starlette.exceptions import HTTPException
from typing_extensions import Annotated
from invokeai.app.services.model_install import ModelInstallJob
from invokeai.app.api.dependencies import ApiDependencies
from invokeai.app.services.model_images.model_images_common import ModelImageFileNotFoundException
from invokeai.app.services.model_install.model_install_common import ModelInstallJob
from invokeai.app.services.model_records import (
DuplicateModelException,
InvalidModelException,
ModelRecordOrderBy,
ModelSummary,
ModelRecordChanges,
UnknownModelException,
)
from invokeai.app.services.shared.pagination import PaginatedResults
from invokeai.backend.model_manager.config import (
AnyModelConfig,
BaseModelType,
MainCheckpointConfig,
ModelFormat,
ModelType,
SubModelType,
)
from invokeai.backend.model_manager.merge import MergeInterpolationMethod, ModelMerger
from invokeai.backend.model_manager.metadata import AnyModelRepoMetadata
from invokeai.backend.model_manager.metadata.fetch.huggingface import HuggingFaceMetadataFetch
from invokeai.backend.model_manager.metadata.metadata_base import ModelMetadataWithFiles, UnknownMetadataException
from invokeai.backend.model_manager.search import ModelSearch
from ..dependencies import ApiDependencies
from invokeai.backend.model_manager.starter_models import STARTER_MODELS, StarterModel, StarterModelWithoutDependencies
model_manager_router = APIRouter(prefix="/v2/models", tags=["model_manager"])
# images are immutable; set a high max-age
IMAGE_MAX_AGE = 31536000
class ModelsList(BaseModel):
"""Return list of configs."""
@ -47,13 +50,11 @@ class ModelsList(BaseModel):
model_config = ConfigDict(use_enum_values=True)
class ModelTagSet(BaseModel):
"""Return tags for a set of models."""
key: str
name: str
author: str
tags: Set[str]
def add_cover_image_to_model_config(config: AnyModelConfig, dependencies: Type[ApiDependencies]) -> AnyModelConfig:
"""Add a cover image URL to a model configuration."""
cover_image = dependencies.invoker.services.model_images.get_url(config.key)
config.cover_image = cover_image
return config
##############################################################################
@ -66,19 +67,16 @@ example_model_config = {
"base": "sd-1",
"type": "main",
"format": "checkpoint",
"config": "string",
"config_path": "string",
"key": "string",
"original_hash": "string",
"current_hash": "string",
"hash": "string",
"description": "string",
"source": "string",
"last_modified": 0,
"vae": "string",
"converted_at": 0,
"variant": "normal",
"prediction_type": "epsilon",
"repo_variant": "fp16",
"upcast_attention": False,
"ztsnr_training": False,
}
example_model_input = {
@ -87,50 +85,12 @@ example_model_input = {
"base": "sd-1",
"type": "main",
"format": "checkpoint",
"config": "configs/stable-diffusion/v1-inference.yaml",
"config_path": "configs/stable-diffusion/v1-inference.yaml",
"description": "Model description",
"vae": None,
"variant": "normal",
}
example_model_metadata = {
"name": "ip_adapter_sd_image_encoder",
"author": "InvokeAI",
"tags": [
"transformers",
"safetensors",
"clip_vision_model",
"endpoints_compatible",
"region:us",
"has_space",
"license:apache-2.0",
],
"files": [
{
"url": "https://huggingface.co/InvokeAI/ip_adapter_sd_image_encoder/resolve/main/README.md",
"path": "ip_adapter_sd_image_encoder/README.md",
"size": 628,
"sha256": None,
},
{
"url": "https://huggingface.co/InvokeAI/ip_adapter_sd_image_encoder/resolve/main/config.json",
"path": "ip_adapter_sd_image_encoder/config.json",
"size": 560,
"sha256": None,
},
{
"url": "https://huggingface.co/InvokeAI/ip_adapter_sd_image_encoder/resolve/main/model.safetensors",
"path": "ip_adapter_sd_image_encoder/model.safetensors",
"size": 2528373448,
"sha256": "6ca9667da1ca9e0b0f75e46bb030f7e011f44f86cbfb8d5a36590fcd7507b030",
},
],
"type": "huggingface",
"id": "InvokeAI/ip_adapter_sd_image_encoder",
"tag_dict": {"license": "apache-2.0"},
"last_modified": "2023-09-23T17:33:25Z",
}
##############################################################################
# ROUTES
##############################################################################
@ -162,6 +122,8 @@ async def list_model_records(
found_models.extend(
record_store.search_by_attr(model_type=model_type, model_name=model_name, model_format=model_format)
)
for model in found_models:
model = add_cover_image_to_model_config(model, ApiDependencies)
return ModelsList(models=found_models)
@ -202,58 +164,13 @@ async def get_model_record(
key: str = Path(description="Key of the model record to fetch."),
) -> AnyModelConfig:
"""Get a model record"""
record_store = ApiDependencies.invoker.services.model_manager.store
try:
config: AnyModelConfig = record_store.get_model(key)
return config
config = ApiDependencies.invoker.services.model_manager.store.get_model(key)
return add_cover_image_to_model_config(config, ApiDependencies)
except UnknownModelException as e:
raise HTTPException(status_code=404, detail=str(e))
@model_manager_router.get("/summary", operation_id="list_model_summary")
async def list_model_summary(
page: int = Query(default=0, description="The page to get"),
per_page: int = Query(default=10, description="The number of models per page"),
order_by: ModelRecordOrderBy = Query(default=ModelRecordOrderBy.Default, description="The attribute to order by"),
) -> PaginatedResults[ModelSummary]:
"""Gets a page of model summary data."""
record_store = ApiDependencies.invoker.services.model_manager.store
results: PaginatedResults[ModelSummary] = record_store.list_models(page=page, per_page=per_page, order_by=order_by)
return results
@model_manager_router.get(
"/i/{key}/metadata",
operation_id="get_model_metadata",
responses={
200: {
"description": "The model metadata was retrieved successfully",
"content": {"application/json": {"example": example_model_metadata}},
},
400: {"description": "Bad request"},
},
)
async def get_model_metadata(
key: str = Path(description="Key of the model repo metadata to fetch."),
) -> Optional[AnyModelRepoMetadata]:
"""Get a model metadata object."""
record_store = ApiDependencies.invoker.services.model_manager.store
result: Optional[AnyModelRepoMetadata] = record_store.get_metadata(key)
return result
@model_manager_router.get(
"/tags",
operation_id="list_tags",
)
async def list_tags() -> Set[str]:
"""Get a unique set of all the model tags."""
record_store = ApiDependencies.invoker.services.model_manager.store
result: Set[str] = record_store.list_tags()
return result
class FoundModel(BaseModel):
path: str = Field(description="Path to the model")
is_installed: bool = Field(description="Whether or not the model is already installed")
@ -291,28 +208,13 @@ async def scan_for_models(
non_core_model_paths = [p for p in found_model_paths if not p.is_relative_to(core_models_path)]
installed_models = ApiDependencies.invoker.services.model_manager.store.search_by_attr()
resolved_installed_model_paths: list[str] = []
installed_model_sources: list[str] = []
# This call lists all installed models.
for model in installed_models:
path = pathlib.Path(model.path)
# If the model has a source, we need to add it to the list of installed sources.
if model.source:
installed_model_sources.append(model.source)
# If the path is not absolute, that means it is in the app models directory, and we need to join it with
# the models path before resolving.
if not path.is_absolute():
resolved_installed_model_paths.append(str(pathlib.Path(models_path, path).resolve()))
continue
resolved_installed_model_paths.append(str(path.resolve()))
scan_results: list[FoundModel] = []
# Check if the model is installed by comparing the resolved paths, appending to the scan result.
# Check if the model is installed by comparing paths, appending to the scan result.
for p in non_core_model_paths:
path = str(p)
is_installed = path in resolved_installed_model_paths or path in installed_model_sources
is_installed = any(str(models_path / m.path) == path for m in installed_models)
found_model = FoundModel(path=path, is_installed=is_installed)
scan_results.append(found_model)
except Exception as e:
@ -323,17 +225,38 @@ async def scan_for_models(
return scan_results
class HuggingFaceModels(BaseModel):
urls: List[AnyHttpUrl] | None = Field(description="URLs for all checkpoint format models in the metadata")
is_diffusers: bool = Field(description="Whether the metadata is for a Diffusers format model")
@model_manager_router.get(
"/tags/search",
operation_id="search_by_metadata_tags",
"/hugging_face",
operation_id="get_hugging_face_models",
responses={
200: {"description": "Hugging Face repo scanned successfully"},
400: {"description": "Invalid hugging face repo"},
},
status_code=200,
response_model=HuggingFaceModels,
)
async def search_by_metadata_tags(
tags: Set[str] = Query(default=None, description="Tags to search for"),
) -> ModelsList:
"""Get a list of models."""
record_store = ApiDependencies.invoker.services.model_manager.store
results = record_store.search_by_metadata_tag(tags)
return ModelsList(models=results)
async def get_hugging_face_models(
hugging_face_repo: str = Query(description="Hugging face repo to search for models", default=None),
) -> HuggingFaceModels:
try:
metadata = HuggingFaceMetadataFetch().from_id(hugging_face_repo)
except UnknownMetadataException:
raise HTTPException(
status_code=400,
detail="No HuggingFace repository found",
)
assert isinstance(metadata, ModelMetadataWithFiles)
return HuggingFaceModels(
urls=metadata.ckpt_urls,
is_diffusers=metadata.is_diffusers,
)
@model_manager_router.patch(
@ -352,34 +275,104 @@ async def search_by_metadata_tags(
)
async def update_model_record(
key: Annotated[str, Path(description="Unique key of model")],
info: Annotated[
AnyModelConfig, Body(description="Model config", discriminator="type", example=example_model_input)
],
changes: Annotated[ModelRecordChanges, Body(description="Model config", example=example_model_input)],
) -> AnyModelConfig:
"""Update model contents with a new config. If the model name or base fields are changed, then the model is renamed."""
"""Update a model's config."""
logger = ApiDependencies.invoker.services.logger
record_store = ApiDependencies.invoker.services.model_manager.store
installer = ApiDependencies.invoker.services.model_manager.install
try:
model_response: AnyModelConfig = record_store.update_model(key, config=info)
record_store.update_model(key, changes=changes)
config = installer.sync_model_path(key)
config = add_cover_image_to_model_config(config, ApiDependencies)
logger.info(f"Updated model: {key}")
except UnknownModelException as e:
raise HTTPException(status_code=404, detail=str(e))
except ValueError as e:
logger.error(str(e))
raise HTTPException(status_code=409, detail=str(e))
return model_response
return config
@model_manager_router.get(
"/i/{key}/image",
operation_id="get_model_image",
responses={
200: {
"description": "The model image was fetched successfully",
},
400: {"description": "Bad request"},
404: {"description": "The model image could not be found"},
},
status_code=200,
)
async def get_model_image(
key: str = Path(description="The name of model image file to get"),
) -> FileResponse:
"""Gets an image file that previews the model"""
try:
path = ApiDependencies.invoker.services.model_images.get_path(key)
response = FileResponse(
path,
media_type="image/png",
filename=key + ".png",
content_disposition_type="inline",
)
response.headers["Cache-Control"] = f"max-age={IMAGE_MAX_AGE}"
return response
except Exception:
raise HTTPException(status_code=404)
@model_manager_router.patch(
"/i/{key}/image",
operation_id="update_model_image",
responses={
200: {
"description": "The model image was updated successfully",
},
400: {"description": "Bad request"},
},
status_code=200,
)
async def update_model_image(
key: Annotated[str, Path(description="Unique key of model")],
image: UploadFile,
) -> None:
if not image.content_type or not image.content_type.startswith("image"):
raise HTTPException(status_code=415, detail="Not an image")
contents = await image.read()
try:
pil_image = Image.open(io.BytesIO(contents))
except Exception:
ApiDependencies.invoker.services.logger.error(traceback.format_exc())
raise HTTPException(status_code=415, detail="Failed to read image")
logger = ApiDependencies.invoker.services.logger
model_images = ApiDependencies.invoker.services.model_images
try:
model_images.save(pil_image, key)
logger.info(f"Updated image for model: {key}")
except ValueError as e:
logger.error(str(e))
raise HTTPException(status_code=409, detail=str(e))
return
@model_manager_router.delete(
"/i/{key}",
operation_id="del_model_record",
operation_id="delete_model",
responses={
204: {"description": "Model deleted successfully"},
404: {"description": "Model not found"},
},
status_code=204,
)
async def del_model_record(
async def delete_model(
key: str = Path(description="Unique key of model to remove from model registry."),
) -> Response:
"""
@ -400,42 +393,27 @@ async def del_model_record(
raise HTTPException(status_code=404, detail=str(e))
@model_manager_router.post(
"/i/",
operation_id="add_model_record",
@model_manager_router.delete(
"/i/{key}/image",
operation_id="delete_model_image",
responses={
201: {
"description": "The model added successfully",
"content": {"application/json": {"example": example_model_config}},
},
409: {"description": "There is already a model corresponding to this path or repo_id"},
415: {"description": "Unrecognized file/folder format"},
204: {"description": "Model image deleted successfully"},
404: {"description": "Model image not found"},
},
status_code=201,
status_code=204,
)
async def add_model_record(
config: Annotated[
AnyModelConfig, Body(description="Model config", discriminator="type", example=example_model_input)
],
) -> AnyModelConfig:
"""Add a model using the configuration information appropriate for its type."""
async def delete_model_image(
key: str = Path(description="Unique key of model image to remove from model_images directory."),
) -> None:
logger = ApiDependencies.invoker.services.logger
record_store = ApiDependencies.invoker.services.model_manager.store
if config.key == "<NOKEY>":
config.key = sha1(randbytes(100)).hexdigest()
logger.info(f"Created model {config.key} for {config.name}")
model_images = ApiDependencies.invoker.services.model_images
try:
record_store.add_model(config.key, config)
except DuplicateModelException as e:
model_images.delete(key)
logger.info(f"Deleted model image: {key}")
return
except UnknownModelException as e:
logger.error(str(e))
raise HTTPException(status_code=409, detail=str(e))
except InvalidModelException as e:
logger.error(str(e))
raise HTTPException(status_code=415)
# now fetch it out
result: AnyModelConfig = record_store.get_model(config.key)
return result
raise HTTPException(status_code=404, detail=str(e))
@model_manager_router.post(
@ -451,13 +429,12 @@ async def add_model_record(
)
async def install_model(
source: str = Query(description="Model source to install, can be a local path, repo_id, or remote URL"),
# TODO(MM2): Can we type this?
config: Optional[Dict[str, Any]] = Body(
description="Dict of fields that override auto-probed values in the model config record, such as name, description and prediction_type ",
default=None,
inplace: Optional[bool] = Query(description="Whether or not to install a local model in place", default=False),
access_token: Optional[str] = Query(description="access token for the remote resource", default=None),
config: ModelRecordChanges = Body(
description="Object containing fields that override auto-probed values in the model config record, such as name, description and prediction_type ",
example={"name": "string", "description": "string"},
),
access_token: Optional[str] = None,
) -> ModelInstallJob:
"""Install a model using a string identifier.
@ -472,8 +449,9 @@ async def install_model(
- model/name:fp16:path/to/model.safetensors
- model/name::path/to/model.safetensors
`config` is an optional dict containing model configuration values that will override
the ones that are probed automatically.
`config` is a ModelRecordChanges object. Fields in this object will override
the ones that are probed automatically. Pass an empty object to accept
all the defaults.
`access_token` is an optional access token for use with Urls that require
authentication.
@ -493,6 +471,7 @@ async def install_model(
source=source,
config=config,
access_token=access_token,
inplace=bool(inplace),
)
logger.info(f"Started installation of {source}")
except UnknownModelException as e:
@ -508,10 +487,137 @@ async def install_model(
@model_manager_router.get(
"/import",
operation_id="list_model_install_jobs",
"/install/huggingface",
operation_id="install_hugging_face_model",
responses={
201: {"description": "The model is being installed"},
400: {"description": "Bad request"},
409: {"description": "There is already a model corresponding to this path or repo_id"},
},
status_code=201,
response_class=HTMLResponse,
)
async def list_model_install_jobs() -> List[ModelInstallJob]:
async def install_hugging_face_model(
source: str = Query(description="HuggingFace repo_id to install"),
) -> HTMLResponse:
"""Install a Hugging Face model using a string identifier."""
def generate_html(title: str, heading: str, repo_id: str, is_error: bool, message: str | None = "") -> str:
if message:
message = f"<p>{message}</p>"
title_class = "error" if is_error else "success"
return f"""
<html>
<head>
<title>{title}</title>
<style>
body {{
text-align: center;
background-color: hsl(220 12% 10% / 1);
font-family: Helvetica, sans-serif;
color: hsl(220 12% 86% / 1);
}}
.repo-id {{
color: hsl(220 12% 68% / 1);
}}
.error {{
color: hsl(0 42% 68% / 1)
}}
.message-box {{
display: inline-block;
border-radius: 5px;
background-color: hsl(220 12% 20% / 1);
padding-inline-end: 30px;
padding: 20px;
padding-inline-start: 30px;
padding-inline-end: 30px;
}}
.container {{
display: flex;
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
}}
a {{
color: inherit
}}
a:visited {{
color: inherit
}}
a:active {{
color: inherit
}}
</style>
</head>
<body style="background-color: hsl(220 12% 10% / 1);">
<div class="container">
<div class="message-box">
<h2 class="{title_class}">{heading}</h2>
{message}
<p class="repo-id">Repo ID: {repo_id}</p>
</div>
</div>
</body>
</html>
"""
try:
metadata = HuggingFaceMetadataFetch().from_id(source)
assert isinstance(metadata, ModelMetadataWithFiles)
except UnknownMetadataException:
title = "Unable to Install Model"
heading = "No HuggingFace repository found with that repo ID."
message = "Ensure the repo ID is correct and try again."
return HTMLResponse(content=generate_html(title, heading, source, True, message), status_code=400)
logger = ApiDependencies.invoker.services.logger
try:
installer = ApiDependencies.invoker.services.model_manager.install
if metadata.is_diffusers:
installer.heuristic_import(
source=source,
inplace=False,
)
elif metadata.ckpt_urls is not None and len(metadata.ckpt_urls) == 1:
installer.heuristic_import(
source=str(metadata.ckpt_urls[0]),
inplace=False,
)
else:
title = "Unable to Install Model"
heading = "This HuggingFace repo has multiple models."
message = "Please use the Model Manager to install this model."
return HTMLResponse(content=generate_html(title, heading, source, True, message), status_code=200)
title = "Model Install Started"
heading = "Your HuggingFace model is installing now."
message = "You can close this tab and check the Model Manager for installation progress."
return HTMLResponse(content=generate_html(title, heading, source, False, message), status_code=201)
except Exception as e:
logger.error(str(e))
title = "Unable to Install Model"
heading = "There was an problem installing this model."
message = 'Please use the Model Manager directly to install this model. If the issue persists, ask for help on <a href="https://discord.gg/ZmtBAhwWhy">discord</a>.'
return HTMLResponse(content=generate_html(title, heading, source, True, message), status_code=500)
@model_manager_router.get(
"/install",
operation_id="list_model_installs",
)
async def list_model_installs() -> List[ModelInstallJob]:
"""Return the list of model install jobs.
Install jobs have a numeric `id`, a `status`, and other fields that provide information on
@ -525,9 +631,8 @@ async def list_model_install_jobs() -> List[ModelInstallJob]:
* "cancelled" -- Job was cancelled before completion.
Once completed, information about the model such as its size, base
model, type, and metadata can be retrieved from the `config_out`
field. For multi-file models such as diffusers, information on individual files
can be retrieved from `download_parts`.
model and type can be retrieved from the `config_out` field. For multi-file models such as diffusers,
information on individual files can be retrieved from `download_parts`.
See the example and schema below for more information.
"""
@ -536,7 +641,7 @@ async def list_model_install_jobs() -> List[ModelInstallJob]:
@model_manager_router.get(
"/import/{id}",
"/install/{id}",
operation_id="get_model_install_job",
responses={
200: {"description": "Success"},
@ -556,7 +661,7 @@ async def get_model_install_job(id: int = Path(description="Model install id"))
@model_manager_router.delete(
"/import/{id}",
"/install/{id}",
operation_id="cancel_model_install_job",
responses={
201: {"description": "The job was cancelled successfully"},
@ -574,8 +679,8 @@ async def cancel_model_install_job(id: int = Path(description="Model install job
installer.cancel_job(job)
@model_manager_router.patch(
"/import",
@model_manager_router.delete(
"/install",
operation_id="prune_model_install_jobs",
responses={
204: {"description": "All completed and errored jobs have been pruned"},
@ -588,25 +693,6 @@ async def prune_model_install_jobs() -> Response:
return Response(status_code=204)
@model_manager_router.patch(
"/sync",
operation_id="sync_models_to_config",
responses={
204: {"description": "Model config record database resynced with files on disk"},
400: {"description": "Bad request"},
},
)
async def sync_models_to_config() -> Response:
"""
Traverse the models and autoimport directories.
Model files without a corresponding
record in the database are added. Orphan records without a models file are deleted.
"""
ApiDependencies.invoker.services.model_manager.install.sync_to_config()
return Response(status_code=204)
@model_manager_router.put(
"/convert/{key}",
operation_id="convert_model",
@ -629,8 +715,8 @@ async def convert_model(
The return value is the model configuration for the converted model.
"""
model_manager = ApiDependencies.invoker.services.model_manager
loader = model_manager.load
logger = ApiDependencies.invoker.services.logger
loader = ApiDependencies.invoker.services.model_manager.load
store = ApiDependencies.invoker.services.model_manager.store
installer = ApiDependencies.invoker.services.model_manager.install
@ -644,108 +730,70 @@ async def convert_model(
logger.error(f"The model with key {key} is not a main checkpoint model.")
raise HTTPException(400, f"The model with key {key} is not a main checkpoint model.")
# loading the model will convert it into a cached diffusers file
model_manager.load_model_by_config(model_config, submodel_type=SubModelType.Scheduler)
with TemporaryDirectory(dir=ApiDependencies.invoker.services.configuration.models_path) as tmpdir:
convert_path = pathlib.Path(tmpdir) / pathlib.Path(model_config.path).stem
converted_model = loader.load_model(model_config)
# write the converted file to the convert path
raw_model = converted_model.model
assert hasattr(raw_model, "save_pretrained")
raw_model.save_pretrained(convert_path) # type: ignore
assert convert_path.exists()
# Get the path of the converted model from the loader
cache_path = loader.convert_cache.cache_path(key)
assert cache_path.exists()
# temporarily rename the original safetensors file so that there is no naming conflict
original_name = model_config.name
model_config.name = f"{original_name}.DELETE"
changes = ModelRecordChanges(name=model_config.name)
store.update_model(key, changes=changes)
# temporarily rename the original safetensors file so that there is no naming conflict
original_name = model_config.name
model_config.name = f"{original_name}.DELETE"
store.update_model(key, config=model_config)
# install the diffusers
try:
new_key = installer.install_path(
convert_path,
config=ModelRecordChanges(
name=original_name,
description=model_config.description,
hash=model_config.hash,
source=model_config.source,
),
)
except Exception as e:
logger.error(str(e))
store.update_model(key, changes=ModelRecordChanges(name=original_name))
raise HTTPException(status_code=409, detail=str(e))
# install the diffusers
# Update the model image if the model had one
try:
new_key = installer.install_path(
cache_path,
config={
"name": original_name,
"description": model_config.description,
"original_hash": model_config.original_hash,
"source": model_config.source,
},
)
except DuplicateModelException as e:
logger.error(str(e))
raise HTTPException(status_code=409, detail=str(e))
# get the original metadata
if orig_metadata := store.get_metadata(key):
store.metadata_store.add_metadata(new_key, orig_metadata)
model_image = ApiDependencies.invoker.services.model_images.get(key)
ApiDependencies.invoker.services.model_images.save(model_image, new_key)
ApiDependencies.invoker.services.model_images.delete(key)
except ModelImageFileNotFoundException:
pass
# delete the original safetensors file
installer.delete(key)
# delete the cached version
shutil.rmtree(cache_path)
# delete the temporary directory
# shutil.rmtree(cache_path)
# return the config record for the new diffusers directory
new_config: AnyModelConfig = store.get_model(new_key)
new_config = store.get_model(new_key)
new_config = add_cover_image_to_model_config(new_config, ApiDependencies)
return new_config
@model_manager_router.put(
"/merge",
operation_id="merge",
responses={
200: {
"description": "Model converted successfully",
"content": {"application/json": {"example": example_model_config}},
},
400: {"description": "Bad request"},
404: {"description": "Model not found"},
409: {"description": "There is already a model registered at this location"},
},
)
async def merge(
keys: List[str] = Body(description="Keys for two to three models to merge", min_length=2, max_length=3),
merged_model_name: Optional[str] = Body(description="Name of destination model", default=None),
alpha: float = Body(description="Alpha weighting strength to apply to 2d and 3d models", default=0.5),
force: bool = Body(
description="Force merging of models created with different versions of diffusers",
default=False,
),
interp: Optional[MergeInterpolationMethod] = Body(description="Interpolation method", default=None),
merge_dest_directory: Optional[str] = Body(
description="Save the merged model to the designated directory (with 'merged_model_name' appended)",
default=None,
),
) -> AnyModelConfig:
"""
Merge diffusers models. The process is controlled by a set parameters provided in the body of the request.
```
Argument Description [default]
-------- ----------------------
keys List of 2-3 model keys to merge together. All models must use the same base type.
merged_model_name Name for the merged model [Concat model names]
alpha Alpha value (0.0-1.0). Higher values give more weight to the second model [0.5]
force If true, force the merge even if the models were generated by different versions of the diffusers library [False]
interp Interpolation method. One of "weighted_sum", "sigmoid", "inv_sigmoid" or "add_difference" [weighted_sum]
merge_dest_directory Specify a directory to store the merged model in [models directory]
```
"""
logger = ApiDependencies.invoker.services.logger
try:
logger.info(f"Merging models: {keys} into {merge_dest_directory or '<MODELS>'}/{merged_model_name}")
dest = pathlib.Path(merge_dest_directory) if merge_dest_directory else None
installer = ApiDependencies.invoker.services.model_manager.install
merger = ModelMerger(installer)
model_names = [installer.record_store.get_model(x).name for x in keys]
response = merger.merge_diffusion_models_and_save(
model_keys=keys,
merged_model_name=merged_model_name or "+".join(model_names),
alpha=alpha,
interp=interp,
force=force,
merge_dest_directory=dest,
)
except UnknownModelException:
raise HTTPException(
status_code=404,
detail=f"One or more of the models '{keys}' not found",
)
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
return response
@model_manager_router.get("/starter_models", operation_id="get_starter_models", response_model=list[StarterModel])
async def get_starter_models() -> list[StarterModel]:
installed_models = ApiDependencies.invoker.services.model_manager.store.search_by_attr()
installed_model_sources = {m.source for m in installed_models}
starter_models = deepcopy(STARTER_MODELS)
for model in starter_models:
if model.source in installed_model_sources:
model.is_installed = True
# Remove already-installed dependencies
missing_deps: list[StarterModelWithoutDependencies] = []
for dep in model.dependencies or []:
if dep.source not in installed_model_sources:
missing_deps.append(dep)
model.dependencies = missing_deps
return starter_models

View File

@ -4,12 +4,14 @@ from fastapi import Body, Path, Query
from fastapi.routing import APIRouter
from pydantic import BaseModel
from invokeai.app.api.dependencies import ApiDependencies
from invokeai.app.services.session_processor.session_processor_common import SessionProcessorStatus
from invokeai.app.services.session_queue.session_queue_common import (
QUEUE_ITEM_STATUS,
Batch,
BatchStatus,
CancelByBatchIDsResult,
CancelByOriginResult,
ClearResult,
EnqueueBatchResult,
PruneResult,
@ -19,8 +21,6 @@ from invokeai.app.services.session_queue.session_queue_common import (
)
from invokeai.app.services.shared.pagination import CursorPaginatedResults
from ..dependencies import ApiDependencies
session_queue_router = APIRouter(prefix="/v1/queue", tags=["queue"])
@ -106,6 +106,19 @@ async def cancel_by_batch_ids(
return ApiDependencies.invoker.services.session_queue.cancel_by_batch_ids(queue_id=queue_id, batch_ids=batch_ids)
@session_queue_router.put(
"/{queue_id}/cancel_by_origin",
operation_id="cancel_by_origin",
responses={200: {"model": CancelByBatchIDsResult}},
)
async def cancel_by_origin(
queue_id: str = Path(description="The queue id to perform this operation on"),
origin: str = Query(description="The origin to cancel all queue items for"),
) -> CancelByOriginResult:
"""Immediately cancels all queue items with the given origin"""
return ApiDependencies.invoker.services.session_queue.cancel_by_origin(queue_id=queue_id, origin=origin)
@session_queue_router.put(
"/{queue_id}/clear",
operation_id="clear",
@ -203,6 +216,7 @@ async def get_batch_status(
responses={
200: {"model": SessionQueueItem},
},
response_model_exclude_none=True,
)
async def get_queue_item(
queue_id: str = Path(description="The queue id to perform this operation on"),

View File

@ -0,0 +1,274 @@
import csv
import io
import json
import traceback
from typing import Optional
import pydantic
from fastapi import APIRouter, File, Form, HTTPException, Path, Response, UploadFile
from fastapi.responses import FileResponse
from PIL import Image
from pydantic import BaseModel, Field
from invokeai.app.api.dependencies import ApiDependencies
from invokeai.app.api.routers.model_manager import IMAGE_MAX_AGE
from invokeai.app.services.style_preset_images.style_preset_images_common import StylePresetImageFileNotFoundException
from invokeai.app.services.style_preset_records.style_preset_records_common import (
InvalidPresetImportDataError,
PresetData,
PresetType,
StylePresetChanges,
StylePresetNotFoundError,
StylePresetRecordWithImage,
StylePresetWithoutId,
UnsupportedFileTypeError,
parse_presets_from_file,
)
class StylePresetFormData(BaseModel):
name: str = Field(description="Preset name")
positive_prompt: str = Field(description="Positive prompt")
negative_prompt: str = Field(description="Negative prompt")
type: PresetType = Field(description="Preset type")
style_presets_router = APIRouter(prefix="/v1/style_presets", tags=["style_presets"])
@style_presets_router.get(
"/i/{style_preset_id}",
operation_id="get_style_preset",
responses={
200: {"model": StylePresetRecordWithImage},
},
)
async def get_style_preset(
style_preset_id: str = Path(description="The style preset to get"),
) -> StylePresetRecordWithImage:
"""Gets a style preset"""
try:
image = ApiDependencies.invoker.services.style_preset_image_files.get_url(style_preset_id)
style_preset = ApiDependencies.invoker.services.style_preset_records.get(style_preset_id)
return StylePresetRecordWithImage(image=image, **style_preset.model_dump())
except StylePresetNotFoundError:
raise HTTPException(status_code=404, detail="Style preset not found")
@style_presets_router.patch(
"/i/{style_preset_id}",
operation_id="update_style_preset",
responses={
200: {"model": StylePresetRecordWithImage},
},
)
async def update_style_preset(
image: Optional[UploadFile] = File(description="The image file to upload", default=None),
style_preset_id: str = Path(description="The id of the style preset to update"),
data: str = Form(description="The data of the style preset to update"),
) -> StylePresetRecordWithImage:
"""Updates a style preset"""
if image is not None:
if not image.content_type or not image.content_type.startswith("image"):
raise HTTPException(status_code=415, detail="Not an image")
contents = await image.read()
try:
pil_image = Image.open(io.BytesIO(contents))
except Exception:
ApiDependencies.invoker.services.logger.error(traceback.format_exc())
raise HTTPException(status_code=415, detail="Failed to read image")
try:
ApiDependencies.invoker.services.style_preset_image_files.save(style_preset_id, pil_image)
except ValueError as e:
raise HTTPException(status_code=409, detail=str(e))
else:
try:
ApiDependencies.invoker.services.style_preset_image_files.delete(style_preset_id)
except StylePresetImageFileNotFoundException:
pass
try:
parsed_data = json.loads(data)
validated_data = StylePresetFormData(**parsed_data)
name = validated_data.name
type = validated_data.type
positive_prompt = validated_data.positive_prompt
negative_prompt = validated_data.negative_prompt
except pydantic.ValidationError:
raise HTTPException(status_code=400, detail="Invalid preset data")
preset_data = PresetData(positive_prompt=positive_prompt, negative_prompt=negative_prompt)
changes = StylePresetChanges(name=name, preset_data=preset_data, type=type)
style_preset_image = ApiDependencies.invoker.services.style_preset_image_files.get_url(style_preset_id)
style_preset = ApiDependencies.invoker.services.style_preset_records.update(
style_preset_id=style_preset_id, changes=changes
)
return StylePresetRecordWithImage(image=style_preset_image, **style_preset.model_dump())
@style_presets_router.delete(
"/i/{style_preset_id}",
operation_id="delete_style_preset",
)
async def delete_style_preset(
style_preset_id: str = Path(description="The style preset to delete"),
) -> None:
"""Deletes a style preset"""
try:
ApiDependencies.invoker.services.style_preset_image_files.delete(style_preset_id)
except StylePresetImageFileNotFoundException:
pass
ApiDependencies.invoker.services.style_preset_records.delete(style_preset_id)
@style_presets_router.post(
"/",
operation_id="create_style_preset",
responses={
200: {"model": StylePresetRecordWithImage},
},
)
async def create_style_preset(
image: Optional[UploadFile] = File(description="The image file to upload", default=None),
data: str = Form(description="The data of the style preset to create"),
) -> StylePresetRecordWithImage:
"""Creates a style preset"""
try:
parsed_data = json.loads(data)
validated_data = StylePresetFormData(**parsed_data)
name = validated_data.name
type = validated_data.type
positive_prompt = validated_data.positive_prompt
negative_prompt = validated_data.negative_prompt
except pydantic.ValidationError:
raise HTTPException(status_code=400, detail="Invalid preset data")
preset_data = PresetData(positive_prompt=positive_prompt, negative_prompt=negative_prompt)
style_preset = StylePresetWithoutId(name=name, preset_data=preset_data, type=type)
new_style_preset = ApiDependencies.invoker.services.style_preset_records.create(style_preset=style_preset)
if image is not None:
if not image.content_type or not image.content_type.startswith("image"):
raise HTTPException(status_code=415, detail="Not an image")
contents = await image.read()
try:
pil_image = Image.open(io.BytesIO(contents))
except Exception:
ApiDependencies.invoker.services.logger.error(traceback.format_exc())
raise HTTPException(status_code=415, detail="Failed to read image")
try:
ApiDependencies.invoker.services.style_preset_image_files.save(new_style_preset.id, pil_image)
except ValueError as e:
raise HTTPException(status_code=409, detail=str(e))
preset_image = ApiDependencies.invoker.services.style_preset_image_files.get_url(new_style_preset.id)
return StylePresetRecordWithImage(image=preset_image, **new_style_preset.model_dump())
@style_presets_router.get(
"/",
operation_id="list_style_presets",
responses={
200: {"model": list[StylePresetRecordWithImage]},
},
)
async def list_style_presets() -> list[StylePresetRecordWithImage]:
"""Gets a page of style presets"""
style_presets_with_image: list[StylePresetRecordWithImage] = []
style_presets = ApiDependencies.invoker.services.style_preset_records.get_many()
for preset in style_presets:
image = ApiDependencies.invoker.services.style_preset_image_files.get_url(preset.id)
style_preset_with_image = StylePresetRecordWithImage(image=image, **preset.model_dump())
style_presets_with_image.append(style_preset_with_image)
return style_presets_with_image
@style_presets_router.get(
"/i/{style_preset_id}/image",
operation_id="get_style_preset_image",
responses={
200: {
"description": "The style preset image was fetched successfully",
},
400: {"description": "Bad request"},
404: {"description": "The style preset image could not be found"},
},
status_code=200,
)
async def get_style_preset_image(
style_preset_id: str = Path(description="The id of the style preset image to get"),
) -> FileResponse:
"""Gets an image file that previews the model"""
try:
path = ApiDependencies.invoker.services.style_preset_image_files.get_path(style_preset_id)
response = FileResponse(
path,
media_type="image/png",
filename=style_preset_id + ".png",
content_disposition_type="inline",
)
response.headers["Cache-Control"] = f"max-age={IMAGE_MAX_AGE}"
return response
except Exception:
raise HTTPException(status_code=404)
@style_presets_router.get(
"/export",
operation_id="export_style_presets",
responses={200: {"content": {"text/csv": {}}, "description": "A CSV file with the requested data."}},
status_code=200,
)
async def export_style_presets():
# Create an in-memory stream to store the CSV data
output = io.StringIO()
writer = csv.writer(output)
# Write the header
writer.writerow(["name", "prompt", "negative_prompt"])
style_presets = ApiDependencies.invoker.services.style_preset_records.get_many(type=PresetType.User)
for preset in style_presets:
writer.writerow([preset.name, preset.preset_data.positive_prompt, preset.preset_data.negative_prompt])
csv_data = output.getvalue()
output.close()
return Response(
content=csv_data,
media_type="text/csv",
headers={"Content-Disposition": "attachment; filename=prompt_templates.csv"},
)
@style_presets_router.post(
"/import",
operation_id="import_style_presets",
)
async def import_style_presets(file: UploadFile = File(description="The file to import")):
try:
style_presets = await parse_presets_from_file(file)
ApiDependencies.invoker.services.style_preset_records.create_many(style_presets)
except InvalidPresetImportDataError as e:
ApiDependencies.invoker.services.logger.error(traceback.format_exc())
raise HTTPException(status_code=400, detail=str(e))
except UnsupportedFileTypeError as e:
ApiDependencies.invoker.services.logger.error(traceback.format_exc())
raise HTTPException(status_code=415, detail=str(e))

View File

@ -1,66 +1,125 @@
# Copyright (c) 2022 Kyle Schouviller (https://github.com/kyle0654)
from typing import Any
from fastapi import FastAPI
from fastapi_events.handlers.local import local_handler
from fastapi_events.typing import Event
from pydantic import BaseModel
from socketio import ASGIApp, AsyncServer
from ..services.events.events_base import EventServiceBase
from invokeai.app.services.events.events_common import (
BatchEnqueuedEvent,
BulkDownloadCompleteEvent,
BulkDownloadErrorEvent,
BulkDownloadEventBase,
BulkDownloadStartedEvent,
DownloadCancelledEvent,
DownloadCompleteEvent,
DownloadErrorEvent,
DownloadEventBase,
DownloadProgressEvent,
DownloadStartedEvent,
FastAPIEvent,
InvocationCompleteEvent,
InvocationDenoiseProgressEvent,
InvocationErrorEvent,
InvocationStartedEvent,
ModelEventBase,
ModelInstallCancelledEvent,
ModelInstallCompleteEvent,
ModelInstallDownloadProgressEvent,
ModelInstallDownloadsCompleteEvent,
ModelInstallErrorEvent,
ModelInstallStartedEvent,
ModelLoadCompleteEvent,
ModelLoadStartedEvent,
QueueClearedEvent,
QueueEventBase,
QueueItemStatusChangedEvent,
register_events,
)
class QueueSubscriptionEvent(BaseModel):
"""Event data for subscribing to the socket.io queue room.
This is a pydantic model to ensure the data is in the correct format."""
queue_id: str
class BulkDownloadSubscriptionEvent(BaseModel):
"""Event data for subscribing to the socket.io bulk downloads room.
This is a pydantic model to ensure the data is in the correct format."""
bulk_download_id: str
QUEUE_EVENTS = {
InvocationStartedEvent,
InvocationDenoiseProgressEvent,
InvocationCompleteEvent,
InvocationErrorEvent,
QueueItemStatusChangedEvent,
BatchEnqueuedEvent,
QueueClearedEvent,
}
MODEL_EVENTS = {
DownloadCancelledEvent,
DownloadCompleteEvent,
DownloadErrorEvent,
DownloadProgressEvent,
DownloadStartedEvent,
ModelLoadStartedEvent,
ModelLoadCompleteEvent,
ModelInstallDownloadProgressEvent,
ModelInstallDownloadsCompleteEvent,
ModelInstallStartedEvent,
ModelInstallCompleteEvent,
ModelInstallCancelledEvent,
ModelInstallErrorEvent,
}
BULK_DOWNLOAD_EVENTS = {BulkDownloadStartedEvent, BulkDownloadCompleteEvent, BulkDownloadErrorEvent}
class SocketIO:
__sio: AsyncServer
__app: ASGIApp
_sub_queue = "subscribe_queue"
_unsub_queue = "unsubscribe_queue"
__sub_queue: str = "subscribe_queue"
__unsub_queue: str = "unsubscribe_queue"
__sub_bulk_download: str = "subscribe_bulk_download"
__unsub_bulk_download: str = "unsubscribe_bulk_download"
_sub_bulk_download = "subscribe_bulk_download"
_unsub_bulk_download = "unsubscribe_bulk_download"
def __init__(self, app: FastAPI):
self.__sio = AsyncServer(async_mode="asgi", cors_allowed_origins="*")
self.__app = ASGIApp(socketio_server=self.__sio, socketio_path="/ws/socket.io")
app.mount("/ws", self.__app)
self._sio = AsyncServer(async_mode="asgi", cors_allowed_origins="*")
self._app = ASGIApp(socketio_server=self._sio, socketio_path="/ws/socket.io")
app.mount("/ws", self._app)
self.__sio.on(self.__sub_queue, handler=self._handle_sub_queue)
self.__sio.on(self.__unsub_queue, handler=self._handle_unsub_queue)
local_handler.register(event_name=EventServiceBase.queue_event, _func=self._handle_queue_event)
local_handler.register(event_name=EventServiceBase.model_event, _func=self._handle_model_event)
self._sio.on(self._sub_queue, handler=self._handle_sub_queue)
self._sio.on(self._unsub_queue, handler=self._handle_unsub_queue)
self._sio.on(self._sub_bulk_download, handler=self._handle_sub_bulk_download)
self._sio.on(self._unsub_bulk_download, handler=self._handle_unsub_bulk_download)
self.__sio.on(self.__sub_bulk_download, handler=self._handle_sub_bulk_download)
self.__sio.on(self.__unsub_bulk_download, handler=self._handle_unsub_bulk_download)
local_handler.register(event_name=EventServiceBase.bulk_download_event, _func=self._handle_bulk_download_event)
register_events(QUEUE_EVENTS, self._handle_queue_event)
register_events(MODEL_EVENTS, self._handle_model_event)
register_events(BULK_DOWNLOAD_EVENTS, self._handle_bulk_image_download_event)
async def _handle_queue_event(self, event: Event):
await self.__sio.emit(
event=event[1]["event"],
data=event[1]["data"],
room=event[1]["data"]["queue_id"],
)
async def _handle_sub_queue(self, sid: str, data: Any) -> None:
await self._sio.enter_room(sid, QueueSubscriptionEvent(**data).queue_id)
async def _handle_sub_queue(self, sid, data, *args, **kwargs) -> None:
if "queue_id" in data:
await self.__sio.enter_room(sid, data["queue_id"])
async def _handle_unsub_queue(self, sid: str, data: Any) -> None:
await self._sio.leave_room(sid, QueueSubscriptionEvent(**data).queue_id)
async def _handle_unsub_queue(self, sid, data, *args, **kwargs) -> None:
if "queue_id" in data:
await self.__sio.leave_room(sid, data["queue_id"])
async def _handle_sub_bulk_download(self, sid: str, data: Any) -> None:
await self._sio.enter_room(sid, BulkDownloadSubscriptionEvent(**data).bulk_download_id)
async def _handle_model_event(self, event: Event) -> None:
await self.__sio.emit(event=event[1]["event"], data=event[1]["data"])
async def _handle_unsub_bulk_download(self, sid: str, data: Any) -> None:
await self._sio.leave_room(sid, BulkDownloadSubscriptionEvent(**data).bulk_download_id)
async def _handle_bulk_download_event(self, event: Event):
await self.__sio.emit(
event=event[1]["event"],
data=event[1]["data"],
room=event[1]["data"]["bulk_download_id"],
)
async def _handle_queue_event(self, event: FastAPIEvent[QueueEventBase]):
await self._sio.emit(event=event[0], data=event[1].model_dump(mode="json"), room=event[1].queue_id)
async def _handle_sub_bulk_download(self, sid, data, *args, **kwargs):
if "bulk_download_id" in data:
await self.__sio.enter_room(sid, data["bulk_download_id"])
async def _handle_model_event(self, event: FastAPIEvent[ModelEventBase | DownloadEventBase]) -> None:
await self._sio.emit(event=event[0], data=event[1].model_dump(mode="json"))
async def _handle_unsub_bulk_download(self, sid, data, *args, **kwargs):
if "bulk_download_id" in data:
await self.__sio.leave_room(sid, data["bulk_download_id"])
async def _handle_bulk_image_download_event(self, event: FastAPIEvent[BulkDownloadEventBase]) -> None:
await self._sio.emit(event=event[0], data=event[1].model_dump(mode="json"), room=event[1].bulk_download_id)

View File

@ -1,82 +1,68 @@
# parse_args() must be called before any other imports. if it is not called first, consumers of the config
# which are imported/used before parse_args() is called will get the default config values instead of the
# values from the command line or config file.
import sys
import asyncio
import logging
import mimetypes
import socket
from contextlib import asynccontextmanager
from pathlib import Path
import torch
import uvicorn
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.gzip import GZipMiddleware
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
from fastapi.responses import HTMLResponse
from fastapi_events.handlers.local import local_handler
from fastapi_events.middleware import EventHandlerASGIMiddleware
from torch.backends.mps import is_available as is_mps_available
# for PyCharm:
# noinspection PyUnresolvedReferences
import invokeai.backend.util.hotfixes # noqa: F401 (monkeypatching on import)
import invokeai.frontend.web as web_dir
from invokeai.app.api.dependencies import ApiDependencies
from invokeai.app.api.no_cache_staticfiles import NoCacheStaticFiles
from invokeai.version.invokeai_version import __version__
from invokeai.app.api.routers import (
app_info,
board_images,
boards,
download_queue,
images,
model_manager,
session_queue,
style_presets,
utilities,
workflows,
)
from invokeai.app.api.sockets import SocketIO
from invokeai.app.services.config.config_default import get_config
from invokeai.app.util.custom_openapi import get_openapi_func
from invokeai.backend.util.devices import TorchDevice
from invokeai.backend.util.logging import InvokeAILogger
from .invocations.fields import InputFieldJSONSchemaExtra, OutputFieldJSONSchemaExtra
from .services.config import InvokeAIAppConfig
app_config = InvokeAIAppConfig.get_config()
app_config.parse_args()
if app_config.version:
print(f"InvokeAI version {__version__}")
sys.exit(0)
if True: # hack to make flake8 happy with imports coming after setting up the config
import asyncio
import mimetypes
import socket
from inspect import signature
from pathlib import Path
from typing import Any
import uvicorn
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.gzip import GZipMiddleware
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
from fastapi.openapi.utils import get_openapi
from fastapi.responses import HTMLResponse
from fastapi_events.handlers.local import local_handler
from fastapi_events.middleware import EventHandlerASGIMiddleware
from pydantic.json_schema import models_json_schema
from torch.backends.mps import is_available as is_mps_available
# for PyCharm:
# noinspection PyUnresolvedReferences
import invokeai.backend.util.hotfixes # noqa: F401 (monkeypatching on import)
import invokeai.frontend.web as web_dir
from ..backend.util.logging import InvokeAILogger
from .api.dependencies import ApiDependencies
from .api.routers import (
app_info,
board_images,
boards,
download_queue,
images,
model_manager,
session_queue,
utilities,
workflows,
)
from .api.sockets import SocketIO
from .invocations.baseinvocation import (
BaseInvocation,
UIConfigBase,
)
if is_mps_available():
import invokeai.backend.util.mps_fixes # noqa: F401 (monkeypatching on import)
app_config = get_config()
if is_mps_available():
import invokeai.backend.util.mps_fixes # noqa: F401 (monkeypatching on import)
app_config = InvokeAIAppConfig.get_config()
app_config.parse_args()
logger = InvokeAILogger.get_logger(config=app_config)
# fix for windows mimetypes registry entries being borked
# see https://github.com/invoke-ai/InvokeAI/discussions/3684#discussioncomment-6391352
mimetypes.add_type("application/javascript", ".js")
mimetypes.add_type("text/css", ".css")
torch_device_name = TorchDevice.get_torch_device_name()
logger.info(f"Using torch device: {torch_device_name}")
loop = asyncio.new_event_loop()
@asynccontextmanager
async def lifespan(app: FastAPI):
# Add startup event to load dependencies
ApiDependencies.initialize(config=app_config, event_handler_id=event_handler_id, logger=logger)
ApiDependencies.initialize(config=app_config, event_handler_id=event_handler_id, loop=loop, logger=logger)
yield
# Shut down threads
ApiDependencies.shutdown()
@ -123,84 +109,9 @@ app.include_router(board_images.board_images_router, prefix="/api")
app.include_router(app_info.app_router, prefix="/api")
app.include_router(session_queue.session_queue_router, prefix="/api")
app.include_router(workflows.workflows_router, prefix="/api")
app.include_router(style_presets.style_presets_router, prefix="/api")
# Build a custom OpenAPI to include all outputs
# TODO: can outputs be included on metadata of invocation schemas somehow?
def custom_openapi() -> dict[str, Any]:
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title=app.title,
description="An API for invoking AI image operations",
version="1.0.0",
routes=app.routes,
separate_input_output_schemas=False, # https://fastapi.tiangolo.com/how-to/separate-openapi-schemas/
)
# Add all outputs
all_invocations = BaseInvocation.get_invocations()
output_types = set()
output_type_titles = {}
for invoker in all_invocations:
output_type = signature(invoker.invoke).return_annotation
output_types.add(output_type)
output_schemas = models_json_schema(
models=[(o, "serialization") for o in output_types], ref_template="#/components/schemas/{model}"
)
for schema_key, output_schema in output_schemas[1]["$defs"].items():
# TODO: note that we assume the schema_key here is the TYPE.__name__
# This could break in some cases, figure out a better way to do it
output_type_titles[schema_key] = output_schema["title"]
openapi_schema["components"]["schemas"][schema_key] = output_schema
openapi_schema["components"]["schemas"][schema_key]["class"] = "output"
# Add Node Editor UI helper schemas
ui_config_schemas = models_json_schema(
[
(UIConfigBase, "serialization"),
(InputFieldJSONSchemaExtra, "serialization"),
(OutputFieldJSONSchemaExtra, "serialization"),
],
ref_template="#/components/schemas/{model}",
)
for schema_key, ui_config_schema in ui_config_schemas[1]["$defs"].items():
openapi_schema["components"]["schemas"][schema_key] = ui_config_schema
# Add a reference to the output type to additionalProperties of the invoker schema
for invoker in all_invocations:
invoker_name = invoker.__name__ # type: ignore [attr-defined] # this is a valid attribute
output_type = signature(obj=invoker.invoke).return_annotation
output_type_title = output_type_titles[output_type.__name__]
invoker_schema = openapi_schema["components"]["schemas"][f"{invoker_name}"]
outputs_ref = {"$ref": f"#/components/schemas/{output_type_title}"}
invoker_schema["output"] = outputs_ref
invoker_schema["class"] = "invocation"
# This code no longer seems to be necessary?
# Leave it here just in case
#
# from invokeai.backend.model_manager import get_model_config_formats
# formats = get_model_config_formats()
# for model_config_name, enum_set in formats.items():
# if model_config_name in openapi_schema["components"]["schemas"]:
# # print(f"Config with name {name} already defined")
# continue
# openapi_schema["components"]["schemas"][model_config_name] = {
# "title": model_config_name,
# "description": "An enumeration.",
# "type": "string",
# "enum": [v.value for v in enum_set],
# }
app.openapi_schema = openapi_schema
return app.openapi_schema
app.openapi = custom_openapi # type: ignore [method-assign] # this is a valid assignment
app.openapi = get_openapi_func(app)
@app.get("/docs", include_in_schema=False)
@ -232,21 +143,34 @@ app.mount(
) # docs favicon is in here
def check_cudnn(logger: logging.Logger) -> None:
"""Check for cuDNN issues that could be causing degraded performance."""
if torch.backends.cudnn.is_available():
try:
# Note: At the time of writing (torch 2.2.1), torch.backends.cudnn.version() only raises an error the first
# time it is called. Subsequent calls will return the version number without complaining about a mismatch.
cudnn_version = torch.backends.cudnn.version()
logger.info(f"cuDNN version: {cudnn_version}")
except RuntimeError as e:
logger.warning(
"Encountered a cuDNN version issue. This may result in degraded performance. This issue is usually "
"caused by an incompatible cuDNN version installed in your python environment, or on the host "
f"system. Full error message:\n{e}"
)
def invoke_api() -> None:
def find_port(port: int) -> int:
"""Find a port not in use starting at given port"""
# Taken from https://waylonwalker.com/python-find-available-port/, thanks Waylon!
# https://github.com/WaylonWalker
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(1)
if s.connect_ex(("localhost", port)) == 0:
return find_port(port=port + 1)
else:
return port
from invokeai.backend.install.check_root import check_invokeai_root
check_invokeai_root(app_config) # note, may exit with an exception if root not set up
if app_config.dev_reload:
try:
import jurigged
@ -262,8 +186,8 @@ def invoke_api() -> None:
if port != app_config.port:
logger.warn(f"Port {app_config.port} in use, using port {port}")
# Start our own event loop for eventing usage
loop = asyncio.new_event_loop()
check_cudnn(logger)
config = uvicorn.Config(
app=app,
host=app_config.host,

View File

@ -3,9 +3,9 @@ import sys
from importlib.util import module_from_spec, spec_from_file_location
from pathlib import Path
from invokeai.app.services.config.config_default import InvokeAIAppConfig
from invokeai.app.services.config.config_default import get_config
custom_nodes_path = Path(InvokeAIAppConfig.get_config().custom_nodes_path.resolve())
custom_nodes_path = Path(get_config().custom_nodes_path)
custom_nodes_path.mkdir(parents=True, exist_ok=True)
custom_nodes_init_path = str(custom_nodes_path / "__init__.py")

Some files were not shown because too many files have changed in this diff Show More