mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Compare commits
348 Commits
v4.2.9.dev
...
invokeai-b
Author | SHA1 | Date | |
---|---|---|---|
dbd2161601 | |||
1f83ac2eae | |||
f7bb68d01c | |||
8cddf9c5b3 | |||
9b546ccf06 | |||
73dbf73a95 | |||
18a1f3893f | |||
018d5dab53 | |||
96a5de30e3 | |||
4d62d5b802 | |||
17de5c7008 | |||
f95403dcda | |||
e54d060d17 | |||
a01f1d4940 | |||
1873817ac9 | |||
31333a736c | |||
03274b6da6 | |||
0646649c05 | |||
2af511c98a | |||
f0039cc70a | |||
8fa7d5ca64 | |||
d90aa42799 | |||
c5b34d21e5 | |||
40a4867143 | |||
4b25f80427 | |||
894e2e643d | |||
a38ff1a16b | |||
41f268b475 | |||
b3ae3f595f | |||
29962613d8 | |||
1170cee1d8 | |||
5983e65b22 | |||
bc724fcdc3 | |||
1faf9c5cdd | |||
6d1f8e6997 | |||
b141ab42d3 | |||
0590bd6626 | |||
35c4ff8ab0 | |||
0784e49d92 | |||
09fe21116b | |||
b185931f84 | |||
1a4d229650 | |||
e9d2205976 | |||
4b624dccf0 | |||
3dffa33097 | |||
ab9756b8d2 | |||
4b74b51ffe | |||
0a020e1c06 | |||
baf60948ee | |||
4e4fa1b71d | |||
7bd870febb | |||
b62cce20b8 | |||
6a8848b61f | |||
c8fa01908c | |||
261be4e2e5 | |||
e0695234e7 | |||
cb1d433f30 | |||
e3772f674d | |||
ad5142d6f7 | |||
fc4b76c8b9 | |||
1e6d804104 | |||
793488e90a | |||
11cd8d026f | |||
25faec8d70 | |||
a14fc3ace5 | |||
667dee7b22 | |||
f75a20b218 | |||
8246e4abf2 | |||
afcb278e66 | |||
0a0e44b51e | |||
d4d3441a52 | |||
3a0fed2fda | |||
fad6fc807b | |||
63ecdb19fe | |||
d7b2dbba66 | |||
16aeb8d640 | |||
e0bd30b98c | |||
90f77c047c | |||
941fc2297f | |||
110b067c52 | |||
71e4addd10 | |||
67435da996 | |||
8518f8c2ac | |||
d3b63ca0fe | |||
605ceb2e95 | |||
b632b35079 | |||
c9372f919c | |||
acd9838559 | |||
fd74f51384 | |||
1e5a44a474 | |||
78ea5d773d | |||
7547784e98 | |||
e82641d5f9 | |||
beff122d90 | |||
dabf56bee8 | |||
4faf902ec4 | |||
2c5c20c8a0 | |||
a8b9458de2 | |||
274d6238fa | |||
10400761f0 | |||
b598b844e4 | |||
8554f81e57 | |||
74ff73ffc8 | |||
993baadc22 | |||
ccfb0b94b9 | |||
8fbe019273 | |||
352805d607 | |||
879c80022e | |||
ea5f6b9826 | |||
4145e27ce6 | |||
3d4f4b677f | |||
249173faf5 | |||
794ef868af | |||
a1ed22517f | |||
3765ee9b59 | |||
91e4c60876 | |||
46e578e1ef | |||
3a8ef0a00c | |||
2a586f3179 | |||
6ce24846eb | |||
c2487e4330 | |||
cf262dd2ea | |||
5a8d66ab02 | |||
b0b0c48d8a | |||
8404e06d77 | |||
a91d01c27a | |||
5eeca47887 | |||
66b361294b | |||
0fb1e79a0b | |||
14f1efaf4f | |||
23aa17e387 | |||
f23cc54e1b | |||
e3d992d5d7 | |||
bb972b2e3d | |||
41a8fdea53 | |||
a78ff86e42 | |||
8e2fd4c96a | |||
2f424f29a0 | |||
90f00db032 | |||
77a63e5310 | |||
8f921741a5 | |||
071df30597 | |||
589a817952 | |||
dcb21c0f46 | |||
1cb88960fe | |||
610a1483b7 | |||
b4e7fc0d1d | |||
b792b7d68c | |||
abaa91195d | |||
1806bfb755 | |||
7377855c02 | |||
5f2a6f24cf | |||
5b8b92d957 | |||
352202a7bc | |||
82144de85f | |||
b70d713e89 | |||
e39dde4140 | |||
c151541703 | |||
29b348ece1 | |||
9f7c86c33e | |||
a79d40519c | |||
4515d52a42 | |||
2a8513eee0 | |||
b856fac713 | |||
4a3951681c | |||
ba89444e36 | |||
a044403ac3 | |||
16dea46b79 | |||
1f80b5335b | |||
eee7f13771 | |||
6db509a4ff | |||
b7965e1ee6 | |||
c3d292e8f9 | |||
206593ec99 | |||
1b62c781d7 | |||
c4de509983 | |||
8d80802a35 | |||
694925f427 | |||
61d5cb2536 | |||
c23fe4f6d2 | |||
e6e93bbb80 | |||
b5bd5240b6 | |||
827ac82d54 | |||
9c2f3259ca | |||
6abe2bfe42 | |||
acf955fc7b | |||
023db8ac41 | |||
65cf733a0c | |||
8323169864 | |||
bf5cd1bd3b | |||
c9db01e272 | |||
6d5e9161fb | |||
0636348585 | |||
4c44523ba0 | |||
5372800e60 | |||
2ae396640b | |||
252f222068 | |||
142ba8c8ea | |||
84dfd2003e | |||
5a633ba811 | |||
f207647f0f | |||
ad16581ab8 | |||
fd722ddf7d | |||
d669e69755 | |||
d912bab4c2 | |||
68c2722c02 | |||
426fea9681 | |||
62cfdb9f11 | |||
46b4d6497c | |||
757c0a5775 | |||
9c8f0b44ad | |||
21433a948c | |||
183344b878 | |||
fc164d5be2 | |||
45aa770cd1 | |||
6d0e782d71 | |||
117f70e1ec | |||
c840bd8c12 | |||
3c64fad379 | |||
bc813e4065 | |||
7c1d2422f0 | |||
a5b11e1071 | |||
c7e4daf431 | |||
4c61f3a514 | |||
2a179799d8 | |||
650f4bb58c | |||
7b92b27ceb | |||
8f1b301d01 | |||
e3a19d4f3e | |||
70283f7d8d | |||
ecbb385447 | |||
8dc56471ef | |||
282ba201d2 | |||
2394f6458f | |||
47c1be3322 | |||
741464b053 | |||
3aab5e7e20 | |||
1e7a6dc676 | |||
81fd2ee8c1 | |||
357601e2d6 | |||
71ff759692 | |||
b0657d5fde | |||
fa391c0b78 | |||
6082aace6d | |||
7ef63161ba | |||
b731b55de4 | |||
51956ba356 | |||
f494077003 | |||
317165c410 | |||
f5aadbc200 | |||
774230f7b9 | |||
72e25d99c7 | |||
7c7c1ba02d | |||
9c6af74556 | |||
57daa3e1c2 | |||
ce98fdc5c4 | |||
f901645c12 | |||
f514f17e92 | |||
8744dd0c46 | |||
f3d669319e | |||
ace7032067 | |||
d32819875a | |||
5b5898827c | |||
8a233174de | |||
bec81170b5 | |||
2f25363d76 | |||
2aa5688d90 | |||
ed06a70eca | |||
e80160f8dd | |||
bfe64b1510 | |||
bb1769abab | |||
e3f906e90d | |||
d77dc68119 | |||
ee3d695e2e | |||
0443befd2f | |||
b4fd02b910 | |||
4e0fe4ad6e | |||
3231499992 | |||
c134161a45 | |||
c3f533f20f | |||
519a9071a8 | |||
87b4663026 | |||
6c11e8ee06 | |||
2a739890a3 | |||
02e84c9565 | |||
39715017f9 | |||
35518542f8 | |||
0aa1106c96 | |||
9cf7e5f634 | |||
d9c46277ea | |||
33f832e6ab | |||
281c788489 | |||
3858bef185 | |||
f9a1afd09c | |||
251e9c0294 | |||
d8bf2e3c10 | |||
218f30b7d0 | |||
da983c7773 | |||
7012e16c43 | |||
b1050abf7f | |||
210998081a | |||
604acb9d91 | |||
ef822902d4 | |||
5beeb1a897 | |||
de6304b729 | |||
d0be79c33d | |||
036ca31282 | |||
7dbe027b18 | |||
523e44ccfe | |||
6a7948466e | |||
4ce8b1ba21 | |||
68a3132d81 | |||
b69f9d4af1 | |||
6a1129ab64 | |||
8e1fd92e7f | |||
c22326f9f8 | |||
f64a4db5fa | |||
3f477da46c | |||
71972c3709 | |||
d4083221a6 | |||
5b4a241f5c | |||
cd333e414b | |||
af3543a8c7 | |||
686f6ef8d6 | |||
f70b7272f3 | |||
24d92979db | |||
c669336d6b | |||
5529309e73 | |||
49c0516602 | |||
c1c62f770f | |||
e2b6dfeeb9 | |||
8f527c2b2d | |||
3732af63e8 | |||
de89041779 | |||
488326dd95 | |||
c3edede73f | |||
6e730bd654 | |||
884a5543c7 | |||
ac972ebbe3 | |||
3c6c18b34c | |||
8f6e43d4a4 | |||
404000bf93 | |||
e744774171 | |||
096e1d3a5d | |||
82e4d5aed2 | |||
5a7145c485 | |||
afc8639c25 | |||
141be95c2c |
@ -1,5 +1,8 @@
|
||||
root = true
|
||||
|
||||
# All files
|
||||
[*]
|
||||
max_line_length = 80
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
@ -10,3 +13,18 @@ trim_trailing_whitespace = true
|
||||
# Python
|
||||
[*.py]
|
||||
indent_size = 4
|
||||
max_line_length = 120
|
||||
|
||||
# css
|
||||
[*.css]
|
||||
indent_size = 4
|
||||
|
||||
# flake8
|
||||
[.flake8]
|
||||
indent_size = 4
|
||||
|
||||
# Markdown MkDocs
|
||||
[docs/**/*.md]
|
||||
max_line_length = 80
|
||||
indent_size = 4
|
||||
indent_style = unset
|
||||
|
37
.flake8
Normal file
37
.flake8
Normal file
@ -0,0 +1,37 @@
|
||||
[flake8]
|
||||
max-line-length = 120
|
||||
extend-ignore =
|
||||
# See https://github.com/PyCQA/pycodestyle/issues/373
|
||||
E203,
|
||||
# use Bugbear's B950 instead
|
||||
E501,
|
||||
# from black repo https://github.com/psf/black/blob/main/.flake8
|
||||
E266, W503, B907
|
||||
extend-select =
|
||||
# Bugbear line length
|
||||
B950
|
||||
extend-exclude =
|
||||
scripts/orig_scripts/*
|
||||
ldm/models/*
|
||||
ldm/modules/*
|
||||
ldm/data/*
|
||||
ldm/generate.py
|
||||
ldm/util.py
|
||||
ldm/simplet2i.py
|
||||
per-file-ignores =
|
||||
# B950 line too long
|
||||
# W605 invalid escape sequence
|
||||
# F841 assigned to but never used
|
||||
# F401 imported but unused
|
||||
tests/test_prompt_parser.py: B950, W605, F401
|
||||
tests/test_textual_inversion.py: F841, B950
|
||||
# B023 Function definition does not bind loop variable
|
||||
scripts/legacy_api.py: F401, B950, B023, F841
|
||||
ldm/invoke/__init__.py: F401
|
||||
# B010 Do not call setattr with a constant attribute value
|
||||
ldm/invoke/server_legacy.py: B010
|
||||
# =====================
|
||||
# flake-quote settings:
|
||||
# =====================
|
||||
# Set this to match black style:
|
||||
inline-quotes = double
|
50
.github/CODEOWNERS
vendored
50
.github/CODEOWNERS
vendored
@ -2,50 +2,60 @@
|
||||
/.github/workflows/ @mauwii @lstein @blessedcoolant
|
||||
|
||||
# documentation
|
||||
/docs/ @lstein @mauwii @tildebyte @blessedcoolant
|
||||
mkdocs.yml @lstein @mauwii @blessedcoolant
|
||||
/docs/ @lstein @mauwii @blessedcoolant
|
||||
mkdocs.yml @mauwii @lstein
|
||||
|
||||
# installation and configuration
|
||||
/pyproject.toml @mauwii @lstein @ebr @blessedcoolant
|
||||
/docker/ @mauwii @lstein @blessedcoolant
|
||||
/pyproject.toml @mauwii @lstein @ebr
|
||||
/docker/ @mauwii
|
||||
/scripts/ @ebr @lstein @blessedcoolant
|
||||
/installer/ @ebr @lstein @tildebyte @blessedcoolant
|
||||
ldm/invoke/config @lstein @ebr @blessedcoolant
|
||||
invokeai/assets @lstein @ebr @blessedcoolant
|
||||
/installer/ @ebr @lstein
|
||||
ldm/invoke/config @lstein @ebr
|
||||
invokeai/assets @lstein @blessedcoolant
|
||||
invokeai/configs @lstein @ebr @blessedcoolant
|
||||
/ldm/invoke/_version.py @lstein @blessedcoolant
|
||||
|
||||
# web ui
|
||||
/invokeai/frontend @blessedcoolant @psychedelicious @lstein
|
||||
/invokeai/backend @blessedcoolant @psychedelicious @lstein
|
||||
/invokeai/frontend @blessedcoolant @psychedelicious
|
||||
/invokeai/backend @blessedcoolant @psychedelicious
|
||||
|
||||
# generation and model management
|
||||
/ldm/*.py @lstein @blessedcoolant
|
||||
/ldm/generate.py @lstein @keturn @blessedcoolant
|
||||
/ldm/generate.py @lstein @keturn
|
||||
/ldm/invoke/args.py @lstein @blessedcoolant
|
||||
/ldm/invoke/ckpt* @lstein @blessedcoolant
|
||||
/ldm/invoke/ckpt_generator @lstein @blessedcoolant
|
||||
/ldm/invoke/CLI.py @lstein @blessedcoolant
|
||||
/ldm/invoke/config @lstein @ebr @mauwii @blessedcoolant
|
||||
/ldm/invoke/generator @keturn @damian0815 @blessedcoolant
|
||||
/ldm/invoke/generator @keturn @damian0815
|
||||
/ldm/invoke/globals.py @lstein @blessedcoolant
|
||||
/ldm/invoke/merge_diffusers.py @lstein @blessedcoolant
|
||||
/ldm/invoke/model_manager.py @lstein @blessedcoolant
|
||||
/ldm/invoke/txt2mask.py @lstein @blessedcoolant
|
||||
/ldm/invoke/patchmatch.py @Kyle0654 @blessedcoolant @lstein
|
||||
/ldm/invoke/patchmatch.py @Kyle0654 @lstein
|
||||
/ldm/invoke/restoration @lstein @blessedcoolant
|
||||
|
||||
# attention, textual inversion, model configuration
|
||||
/ldm/models @damian0815 @keturn @lstein @blessedcoolant
|
||||
/ldm/modules @damian0815 @keturn @lstein @blessedcoolant
|
||||
/ldm/models @damian0815 @keturn @blessedcoolant
|
||||
/ldm/modules/textual_inversion_manager.py @lstein @blessedcoolant
|
||||
/ldm/modules/attention.py @damian0815 @keturn
|
||||
/ldm/modules/diffusionmodules @damian0815 @keturn
|
||||
/ldm/modules/distributions @damian0815 @keturn
|
||||
/ldm/modules/ema.py @damian0815 @keturn
|
||||
/ldm/modules/embedding_manager.py @lstein
|
||||
/ldm/modules/encoders @damian0815 @keturn
|
||||
/ldm/modules/image_degradation @damian0815 @keturn
|
||||
/ldm/modules/losses @damian0815 @keturn
|
||||
/ldm/modules/x_transformer.py @damian0815 @keturn
|
||||
|
||||
# Nodes
|
||||
apps/ @Kyle0654 @lstein @blessedcoolant
|
||||
apps/ @Kyle0654 @jpphoto
|
||||
|
||||
# legacy REST API
|
||||
# is CapableWeb still engaged?
|
||||
/ldm/invoke/pngwriter.py @CapableWeb @lstein @blessedcoolant
|
||||
/ldm/invoke/server_legacy.py @CapableWeb @lstein @blessedcoolant
|
||||
/scripts/legacy_api.py @CapableWeb @lstein @blessedcoolant
|
||||
/tests/legacy_tests.sh @CapableWeb @lstein @blessedcoolant
|
||||
# these are dead code
|
||||
#/ldm/invoke/pngwriter.py @CapableWeb
|
||||
#/ldm/invoke/server_legacy.py @CapableWeb
|
||||
#/scripts/legacy_api.py @CapableWeb
|
||||
#/tests/legacy_tests.sh @CapableWeb
|
||||
|
||||
|
||||
|
10
.github/workflows/mkdocs-material.yml
vendored
10
.github/workflows/mkdocs-material.yml
vendored
@ -9,6 +9,10 @@ jobs:
|
||||
mkdocs-material:
|
||||
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
|
||||
@ -19,11 +23,15 @@ jobs:
|
||||
uses: actions/setup-python@v4
|
||||
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 -r docs/requirements-mkdocs.txt
|
||||
pip install ".[docs]"
|
||||
|
||||
- name: confirm buildability
|
||||
run: |
|
||||
|
41
.pre-commit-config.yaml
Normal file
41
.pre-commit-config.yaml
Normal file
@ -0,0 +1,41 @@
|
||||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
repos:
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 23.1.0
|
||||
hooks:
|
||||
- id: black
|
||||
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.12.0
|
||||
hooks:
|
||||
- id: isort
|
||||
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 6.0.0
|
||||
hooks:
|
||||
- id: flake8
|
||||
additional_dependencies:
|
||||
- flake8-black
|
||||
- flake8-bugbear
|
||||
- flake8-comprehensions
|
||||
- flake8-simplify
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||
rev: 'v3.0.0-alpha.4'
|
||||
hooks:
|
||||
- id: prettier
|
||||
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.4.0
|
||||
hooks:
|
||||
- id: check-added-large-files
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-shebang-scripts-are-executable
|
||||
- id: check-merge-conflict
|
||||
- id: check-symlinks
|
||||
- id: check-toml
|
||||
- id: end-of-file-fixer
|
||||
- id: no-commit-to-branch
|
||||
args: ['--branch', 'main']
|
||||
- id: trailing-whitespace
|
14
.prettierignore
Normal file
14
.prettierignore
Normal file
@ -0,0 +1,14 @@
|
||||
invokeai/frontend/.husky
|
||||
invokeai/frontend/patches
|
||||
|
||||
# Ignore artifacts:
|
||||
build
|
||||
coverage
|
||||
static
|
||||
invokeai/frontend/dist
|
||||
|
||||
# Ignore all HTML files:
|
||||
*.html
|
||||
|
||||
# Ignore deprecated docs
|
||||
docs/installation/deprecated_documentation
|
@ -1,9 +1,9 @@
|
||||
endOfLine: lf
|
||||
tabWidth: 2
|
||||
useTabs: false
|
||||
singleQuote: true
|
||||
quoteProps: as-needed
|
||||
embeddedLanguageFormatting: auto
|
||||
endOfLine: lf
|
||||
singleQuote: true
|
||||
semi: true
|
||||
trailingComma: es5
|
||||
useTabs: false
|
||||
overrides:
|
||||
- files: '*.md'
|
||||
options:
|
||||
@ -11,3 +11,9 @@ overrides:
|
||||
printWidth: 80
|
||||
parser: markdown
|
||||
cursorOffset: -1
|
||||
- files: docs/**/*.md
|
||||
options:
|
||||
tabWidth: 4
|
||||
- files: 'invokeai/frontend/public/locales/*.json'
|
||||
options:
|
||||
tabWidth: 4
|
||||
|
@ -145,7 +145,7 @@ not supported.
|
||||
_For Linux with an AMD GPU:_
|
||||
|
||||
```sh
|
||||
pip install InvokeAI --use-pep517 --extra-index-url https://download.pytorch.org/whl/rocm5.2
|
||||
pip install InvokeAI --use-pep517 --extra-index-url https://download.pytorch.org/whl/rocm5.4.2
|
||||
```
|
||||
|
||||
_For Macintoshes, either Intel or M1/M2:_
|
||||
|
Binary file not shown.
@ -1,164 +0,0 @@
|
||||
@echo off
|
||||
|
||||
@rem This script will install git (if not found on the PATH variable)
|
||||
@rem using micromamba (an 8mb static-linked single-file binary, conda replacement).
|
||||
@rem For users who already have git, this step will be skipped.
|
||||
|
||||
@rem Next, it'll download the project's source code.
|
||||
@rem Then it will download a self-contained, standalone Python and unpack it.
|
||||
@rem Finally, it'll create the Python virtual environment and preload the models.
|
||||
|
||||
@rem This enables a user to install this project without manually installing git or Python
|
||||
|
||||
@rem change to the script's directory
|
||||
PUSHD "%~dp0"
|
||||
|
||||
set "no_cache_dir=--no-cache-dir"
|
||||
if "%1" == "use-cache" (
|
||||
set "no_cache_dir="
|
||||
)
|
||||
|
||||
echo ***** Installing InvokeAI.. *****
|
||||
@rem Config
|
||||
set INSTALL_ENV_DIR=%cd%\installer_files\env
|
||||
@rem https://mamba.readthedocs.io/en/latest/installation.html
|
||||
set MICROMAMBA_DOWNLOAD_URL=https://github.com/cmdr2/stable-diffusion-ui/releases/download/v1.1/micromamba.exe
|
||||
set RELEASE_URL=https://github.com/invoke-ai/InvokeAI
|
||||
set RELEASE_SOURCEBALL=/archive/refs/heads/main.tar.gz
|
||||
set PYTHON_BUILD_STANDALONE_URL=https://github.com/indygreg/python-build-standalone/releases/download
|
||||
set PYTHON_BUILD_STANDALONE=20221002/cpython-3.10.7+20221002-x86_64-pc-windows-msvc-shared-install_only.tar.gz
|
||||
|
||||
set PACKAGES_TO_INSTALL=
|
||||
|
||||
call git --version >.tmp1 2>.tmp2
|
||||
if "%ERRORLEVEL%" NEQ "0" set PACKAGES_TO_INSTALL=%PACKAGES_TO_INSTALL% git
|
||||
|
||||
@rem Cleanup
|
||||
del /q .tmp1 .tmp2
|
||||
|
||||
@rem (if necessary) install git into a contained environment
|
||||
if "%PACKAGES_TO_INSTALL%" NEQ "" (
|
||||
@rem download micromamba
|
||||
echo ***** Downloading micromamba from %MICROMAMBA_DOWNLOAD_URL% to micromamba.exe *****
|
||||
|
||||
call curl -L "%MICROMAMBA_DOWNLOAD_URL%" > micromamba.exe
|
||||
|
||||
@rem test the mamba binary
|
||||
echo ***** Micromamba version: *****
|
||||
call micromamba.exe --version
|
||||
|
||||
@rem create the installer env
|
||||
if not exist "%INSTALL_ENV_DIR%" (
|
||||
call micromamba.exe create -y --prefix "%INSTALL_ENV_DIR%"
|
||||
)
|
||||
|
||||
echo ***** Packages to install:%PACKAGES_TO_INSTALL% *****
|
||||
|
||||
call micromamba.exe install -y --prefix "%INSTALL_ENV_DIR%" -c conda-forge %PACKAGES_TO_INSTALL%
|
||||
|
||||
if not exist "%INSTALL_ENV_DIR%" (
|
||||
echo ----- There was a problem while installing "%PACKAGES_TO_INSTALL%" using micromamba. Cannot continue. -----
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
)
|
||||
|
||||
del /q micromamba.exe
|
||||
|
||||
@rem For 'git' only
|
||||
set PATH=%INSTALL_ENV_DIR%\Library\bin;%PATH%
|
||||
|
||||
@rem Download/unpack/clean up InvokeAI release sourceball
|
||||
set err_msg=----- InvokeAI source download failed -----
|
||||
echo Trying to download "%RELEASE_URL%%RELEASE_SOURCEBALL%"
|
||||
curl -L %RELEASE_URL%%RELEASE_SOURCEBALL% --output InvokeAI.tgz
|
||||
if %errorlevel% neq 0 goto err_exit
|
||||
|
||||
set err_msg=----- InvokeAI source unpack failed -----
|
||||
tar -zxf InvokeAI.tgz
|
||||
if %errorlevel% neq 0 goto err_exit
|
||||
|
||||
del /q InvokeAI.tgz
|
||||
|
||||
set err_msg=----- InvokeAI source copy failed -----
|
||||
cd InvokeAI-*
|
||||
xcopy . .. /e /h
|
||||
if %errorlevel% neq 0 goto err_exit
|
||||
cd ..
|
||||
|
||||
@rem cleanup
|
||||
for /f %%i in ('dir /b InvokeAI-*') do rd /s /q %%i
|
||||
rd /s /q .dev_scripts .github docker-build tests
|
||||
del /q requirements.in requirements-mkdocs.txt shell.nix
|
||||
|
||||
echo ***** Unpacked InvokeAI source *****
|
||||
|
||||
@rem Download/unpack/clean up python-build-standalone
|
||||
set err_msg=----- Python download failed -----
|
||||
curl -L %PYTHON_BUILD_STANDALONE_URL%/%PYTHON_BUILD_STANDALONE% --output python.tgz
|
||||
if %errorlevel% neq 0 goto err_exit
|
||||
|
||||
set err_msg=----- Python unpack failed -----
|
||||
tar -zxf python.tgz
|
||||
if %errorlevel% neq 0 goto err_exit
|
||||
|
||||
del /q python.tgz
|
||||
|
||||
echo ***** Unpacked python-build-standalone *****
|
||||
|
||||
@rem create venv
|
||||
set err_msg=----- problem creating venv -----
|
||||
.\python\python -E -s -m venv .venv
|
||||
if %errorlevel% neq 0 goto err_exit
|
||||
call .venv\Scripts\activate.bat
|
||||
|
||||
echo ***** Created Python virtual environment *****
|
||||
|
||||
@rem Print venv's Python version
|
||||
set err_msg=----- problem calling venv's python -----
|
||||
echo We're running under
|
||||
.venv\Scripts\python --version
|
||||
if %errorlevel% neq 0 goto err_exit
|
||||
|
||||
set err_msg=----- pip update failed -----
|
||||
.venv\Scripts\python -m pip install %no_cache_dir% --no-warn-script-location --upgrade pip wheel
|
||||
if %errorlevel% neq 0 goto err_exit
|
||||
|
||||
echo ***** Updated pip and wheel *****
|
||||
|
||||
set err_msg=----- requirements file copy failed -----
|
||||
copy binary_installer\py3.10-windows-x86_64-cuda-reqs.txt requirements.txt
|
||||
if %errorlevel% neq 0 goto err_exit
|
||||
|
||||
set err_msg=----- main pip install failed -----
|
||||
.venv\Scripts\python -m pip install %no_cache_dir% --no-warn-script-location -r requirements.txt
|
||||
if %errorlevel% neq 0 goto err_exit
|
||||
|
||||
echo ***** Installed Python dependencies *****
|
||||
|
||||
set err_msg=----- InvokeAI setup failed -----
|
||||
.venv\Scripts\python -m pip install %no_cache_dir% --no-warn-script-location -e .
|
||||
if %errorlevel% neq 0 goto err_exit
|
||||
|
||||
copy binary_installer\invoke.bat.in .\invoke.bat
|
||||
echo ***** Installed invoke launcher script ******
|
||||
|
||||
@rem more cleanup
|
||||
rd /s /q binary_installer installer_files
|
||||
|
||||
@rem preload the models
|
||||
call .venv\Scripts\python ldm\invoke\config\invokeai_configure.py
|
||||
set err_msg=----- model download clone failed -----
|
||||
if %errorlevel% neq 0 goto err_exit
|
||||
deactivate
|
||||
|
||||
echo ***** Finished downloading models *****
|
||||
|
||||
echo All done! Execute the file invoke.bat in this directory to start InvokeAI
|
||||
pause
|
||||
exit
|
||||
|
||||
:err_exit
|
||||
echo %err_msg%
|
||||
pause
|
||||
exit
|
@ -1,235 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# ensure we're in the correct folder in case user's CWD is somewhere else
|
||||
scriptdir=$(dirname "$0")
|
||||
cd "$scriptdir"
|
||||
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
function _err_exit {
|
||||
if test "$1" -ne 0
|
||||
then
|
||||
echo -e "Error code $1; Error caught was '$2'"
|
||||
read -p "Press any key to exit..."
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
# This script will install git (if not found on the PATH variable)
|
||||
# using micromamba (an 8mb static-linked single-file binary, conda replacement).
|
||||
# For users who already have git, this step will be skipped.
|
||||
|
||||
# Next, it'll download the project's source code.
|
||||
# Then it will download a self-contained, standalone Python and unpack it.
|
||||
# Finally, it'll create the Python virtual environment and preload the models.
|
||||
|
||||
# This enables a user to install this project without manually installing git or Python
|
||||
|
||||
echo -e "\n***** Installing InvokeAI into $(pwd)... *****\n"
|
||||
|
||||
export no_cache_dir="--no-cache-dir"
|
||||
if [ $# -ge 1 ]; then
|
||||
if [ "$1" = "use-cache" ]; then
|
||||
export no_cache_dir=""
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
OS_NAME=$(uname -s)
|
||||
case "${OS_NAME}" in
|
||||
Linux*) OS_NAME="linux";;
|
||||
Darwin*) OS_NAME="darwin";;
|
||||
*) echo -e "\n----- Unknown OS: $OS_NAME! This script runs only on Linux or macOS -----\n" && exit
|
||||
esac
|
||||
|
||||
OS_ARCH=$(uname -m)
|
||||
case "${OS_ARCH}" in
|
||||
x86_64*) ;;
|
||||
arm64*) ;;
|
||||
*) echo -e "\n----- Unknown system architecture: $OS_ARCH! This script runs only on x86_64 or arm64 -----\n" && exit
|
||||
esac
|
||||
|
||||
# https://mamba.readthedocs.io/en/latest/installation.html
|
||||
MAMBA_OS_NAME=$OS_NAME
|
||||
MAMBA_ARCH=$OS_ARCH
|
||||
if [ "$OS_NAME" == "darwin" ]; then
|
||||
MAMBA_OS_NAME="osx"
|
||||
fi
|
||||
|
||||
if [ "$OS_ARCH" == "linux" ]; then
|
||||
MAMBA_ARCH="aarch64"
|
||||
fi
|
||||
|
||||
if [ "$OS_ARCH" == "x86_64" ]; then
|
||||
MAMBA_ARCH="64"
|
||||
fi
|
||||
|
||||
PY_ARCH=$OS_ARCH
|
||||
if [ "$OS_ARCH" == "arm64" ]; then
|
||||
PY_ARCH="aarch64"
|
||||
fi
|
||||
|
||||
# Compute device ('cd' segment of reqs files) detect goes here
|
||||
# This needs a ton of work
|
||||
# Suggestions:
|
||||
# - lspci
|
||||
# - check $PATH for nvidia-smi, gtt CUDA/GPU version from output
|
||||
# - Surely there's a similar utility for AMD?
|
||||
CD="cuda"
|
||||
if [ "$OS_NAME" == "darwin" ] && [ "$OS_ARCH" == "arm64" ]; then
|
||||
CD="mps"
|
||||
fi
|
||||
|
||||
# config
|
||||
INSTALL_ENV_DIR="$(pwd)/installer_files/env"
|
||||
MICROMAMBA_DOWNLOAD_URL="https://micro.mamba.pm/api/micromamba/${MAMBA_OS_NAME}-${MAMBA_ARCH}/latest"
|
||||
RELEASE_URL=https://github.com/invoke-ai/InvokeAI
|
||||
RELEASE_SOURCEBALL=/archive/refs/heads/main.tar.gz
|
||||
PYTHON_BUILD_STANDALONE_URL=https://github.com/indygreg/python-build-standalone/releases/download
|
||||
if [ "$OS_NAME" == "darwin" ]; then
|
||||
PYTHON_BUILD_STANDALONE=20221002/cpython-3.10.7+20221002-${PY_ARCH}-apple-darwin-install_only.tar.gz
|
||||
elif [ "$OS_NAME" == "linux" ]; then
|
||||
PYTHON_BUILD_STANDALONE=20221002/cpython-3.10.7+20221002-${PY_ARCH}-unknown-linux-gnu-install_only.tar.gz
|
||||
fi
|
||||
echo "INSTALLING $RELEASE_SOURCEBALL FROM $RELEASE_URL"
|
||||
|
||||
PACKAGES_TO_INSTALL=""
|
||||
|
||||
if ! hash "git" &>/dev/null; then PACKAGES_TO_INSTALL="$PACKAGES_TO_INSTALL git"; fi
|
||||
|
||||
# (if necessary) install git and conda into a contained environment
|
||||
if [ "$PACKAGES_TO_INSTALL" != "" ]; then
|
||||
# download micromamba
|
||||
echo -e "\n***** Downloading micromamba from $MICROMAMBA_DOWNLOAD_URL to micromamba *****\n"
|
||||
|
||||
curl -L "$MICROMAMBA_DOWNLOAD_URL" | tar -xvjO bin/micromamba > micromamba
|
||||
|
||||
chmod u+x ./micromamba
|
||||
|
||||
# test the mamba binary
|
||||
echo -e "\n***** Micromamba version: *****\n"
|
||||
./micromamba --version
|
||||
|
||||
# create the installer env
|
||||
if [ ! -e "$INSTALL_ENV_DIR" ]; then
|
||||
./micromamba create -y --prefix "$INSTALL_ENV_DIR"
|
||||
fi
|
||||
|
||||
echo -e "\n***** Packages to install:$PACKAGES_TO_INSTALL *****\n"
|
||||
|
||||
./micromamba install -y --prefix "$INSTALL_ENV_DIR" -c conda-forge "$PACKAGES_TO_INSTALL"
|
||||
|
||||
if [ ! -e "$INSTALL_ENV_DIR" ]; then
|
||||
echo -e "\n----- There was a problem while initializing micromamba. Cannot continue. -----\n"
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -f micromamba.exe
|
||||
|
||||
export PATH="$INSTALL_ENV_DIR/bin:$PATH"
|
||||
|
||||
# Download/unpack/clean up InvokeAI release sourceball
|
||||
_err_msg="\n----- InvokeAI source download failed -----\n"
|
||||
curl -L $RELEASE_URL/$RELEASE_SOURCEBALL --output InvokeAI.tgz
|
||||
_err_exit $? _err_msg
|
||||
_err_msg="\n----- InvokeAI source unpack failed -----\n"
|
||||
tar -zxf InvokeAI.tgz
|
||||
_err_exit $? _err_msg
|
||||
|
||||
rm -f InvokeAI.tgz
|
||||
|
||||
_err_msg="\n----- InvokeAI source copy failed -----\n"
|
||||
cd InvokeAI-*
|
||||
cp -r . ..
|
||||
_err_exit $? _err_msg
|
||||
cd ..
|
||||
|
||||
# cleanup
|
||||
rm -rf InvokeAI-*/
|
||||
rm -rf .dev_scripts/ .github/ docker-build/ tests/ requirements.in requirements-mkdocs.txt shell.nix
|
||||
|
||||
echo -e "\n***** Unpacked InvokeAI source *****\n"
|
||||
|
||||
# Download/unpack/clean up python-build-standalone
|
||||
_err_msg="\n----- Python download failed -----\n"
|
||||
curl -L $PYTHON_BUILD_STANDALONE_URL/$PYTHON_BUILD_STANDALONE --output python.tgz
|
||||
_err_exit $? _err_msg
|
||||
_err_msg="\n----- Python unpack failed -----\n"
|
||||
tar -zxf python.tgz
|
||||
_err_exit $? _err_msg
|
||||
|
||||
rm -f python.tgz
|
||||
|
||||
echo -e "\n***** Unpacked python-build-standalone *****\n"
|
||||
|
||||
# create venv
|
||||
_err_msg="\n----- problem creating venv -----\n"
|
||||
|
||||
if [ "$OS_NAME" == "darwin" ]; then
|
||||
# patch sysconfig so that extensions can build properly
|
||||
# adapted from https://github.com/cashapp/hermit-packages/commit/fcba384663892f4d9cfb35e8639ff7a28166ee43
|
||||
PYTHON_INSTALL_DIR="$(pwd)/python"
|
||||
SYSCONFIG="$(echo python/lib/python*/_sysconfigdata_*.py)"
|
||||
TMPFILE="$(mktemp)"
|
||||
chmod +w "${SYSCONFIG}"
|
||||
cp "${SYSCONFIG}" "${TMPFILE}"
|
||||
sed "s,'/install,'${PYTHON_INSTALL_DIR},g" "${TMPFILE}" > "${SYSCONFIG}"
|
||||
rm -f "${TMPFILE}"
|
||||
fi
|
||||
|
||||
./python/bin/python3 -E -s -m venv .venv
|
||||
_err_exit $? _err_msg
|
||||
source .venv/bin/activate
|
||||
|
||||
echo -e "\n***** Created Python virtual environment *****\n"
|
||||
|
||||
# Print venv's Python version
|
||||
_err_msg="\n----- problem calling venv's python -----\n"
|
||||
echo -e "We're running under"
|
||||
.venv/bin/python3 --version
|
||||
_err_exit $? _err_msg
|
||||
|
||||
_err_msg="\n----- pip update failed -----\n"
|
||||
.venv/bin/python3 -m pip install $no_cache_dir --no-warn-script-location --upgrade pip
|
||||
_err_exit $? _err_msg
|
||||
|
||||
echo -e "\n***** Updated pip *****\n"
|
||||
|
||||
_err_msg="\n----- requirements file copy failed -----\n"
|
||||
cp binary_installer/py3.10-${OS_NAME}-"${OS_ARCH}"-${CD}-reqs.txt requirements.txt
|
||||
_err_exit $? _err_msg
|
||||
|
||||
_err_msg="\n----- main pip install failed -----\n"
|
||||
.venv/bin/python3 -m pip install $no_cache_dir --no-warn-script-location -r requirements.txt
|
||||
_err_exit $? _err_msg
|
||||
|
||||
echo -e "\n***** Installed Python dependencies *****\n"
|
||||
|
||||
_err_msg="\n----- InvokeAI setup failed -----\n"
|
||||
.venv/bin/python3 -m pip install $no_cache_dir --no-warn-script-location -e .
|
||||
_err_exit $? _err_msg
|
||||
|
||||
echo -e "\n***** Installed InvokeAI *****\n"
|
||||
|
||||
cp binary_installer/invoke.sh.in ./invoke.sh
|
||||
chmod a+rx ./invoke.sh
|
||||
echo -e "\n***** Installed invoke launcher script ******\n"
|
||||
|
||||
# more cleanup
|
||||
rm -rf binary_installer/ installer_files/
|
||||
|
||||
# preload the models
|
||||
.venv/bin/python3 scripts/configure_invokeai.py
|
||||
_err_msg="\n----- model download clone failed -----\n"
|
||||
_err_exit $? _err_msg
|
||||
deactivate
|
||||
|
||||
echo -e "\n***** Finished downloading models *****\n"
|
||||
|
||||
echo "All done! Run the command"
|
||||
echo " $scriptdir/invoke.sh"
|
||||
echo "to start InvokeAI."
|
||||
read -p "Press any key to exit..."
|
||||
exit
|
@ -1,36 +0,0 @@
|
||||
@echo off
|
||||
|
||||
PUSHD "%~dp0"
|
||||
call .venv\Scripts\activate.bat
|
||||
|
||||
echo Do you want to generate images using the
|
||||
echo 1. command-line
|
||||
echo 2. browser-based UI
|
||||
echo OR
|
||||
echo 3. open the developer console
|
||||
set /p choice="Please enter 1, 2 or 3: "
|
||||
if /i "%choice%" == "1" (
|
||||
echo Starting the InvokeAI command-line.
|
||||
.venv\Scripts\python scripts\invoke.py %*
|
||||
) else if /i "%choice%" == "2" (
|
||||
echo Starting the InvokeAI browser-based UI.
|
||||
.venv\Scripts\python scripts\invoke.py --web %*
|
||||
) else if /i "%choice%" == "3" (
|
||||
echo Developer Console
|
||||
echo Python command is:
|
||||
where python
|
||||
echo Python version is:
|
||||
python --version
|
||||
echo *************************
|
||||
echo You are now in the system shell, with the local InvokeAI Python virtual environment activated,
|
||||
echo so that you can troubleshoot this InvokeAI installation as necessary.
|
||||
echo *************************
|
||||
echo *** Type `exit` to quit this shell and deactivate the Python virtual environment ***
|
||||
call cmd /k
|
||||
) else (
|
||||
echo Invalid selection
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
|
||||
deactivate
|
@ -1,46 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -eu
|
||||
|
||||
. .venv/bin/activate
|
||||
|
||||
# set required env var for torch on mac MPS
|
||||
if [ "$(uname -s)" == "Darwin" ]; then
|
||||
export PYTORCH_ENABLE_MPS_FALLBACK=1
|
||||
fi
|
||||
|
||||
echo "Do you want to generate images using the"
|
||||
echo "1. command-line"
|
||||
echo "2. browser-based UI"
|
||||
echo "OR"
|
||||
echo "3. open the developer console"
|
||||
echo "Please enter 1, 2, or 3:"
|
||||
read choice
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
printf "\nStarting the InvokeAI command-line..\n";
|
||||
.venv/bin/python scripts/invoke.py $*;
|
||||
;;
|
||||
2)
|
||||
printf "\nStarting the InvokeAI browser-based UI..\n";
|
||||
.venv/bin/python scripts/invoke.py --web $*;
|
||||
;;
|
||||
3)
|
||||
printf "\nDeveloper Console:\n";
|
||||
printf "Python command is:\n\t";
|
||||
which python;
|
||||
printf "Python version is:\n\t";
|
||||
python --version;
|
||||
echo "*************************"
|
||||
echo "You are now in your user shell ($SHELL) with the local InvokeAI Python virtual environment activated,";
|
||||
echo "so that you can troubleshoot this InvokeAI installation as necessary.";
|
||||
printf "*************************\n"
|
||||
echo "*** Type \`exit\` to quit this shell and deactivate the Python virtual environment *** ";
|
||||
/usr/bin/env "$SHELL";
|
||||
;;
|
||||
*)
|
||||
echo "Invalid selection";
|
||||
exit
|
||||
;;
|
||||
esac
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,17 +0,0 @@
|
||||
InvokeAI
|
||||
|
||||
Project homepage: https://github.com/invoke-ai/InvokeAI
|
||||
|
||||
Installation on Windows:
|
||||
NOTE: You might need to enable Windows Long Paths. If you're not sure,
|
||||
then you almost certainly need to. Simply double-click the 'WinLongPathsEnabled.reg'
|
||||
file. Note that you will need to have admin privileges in order to
|
||||
do this.
|
||||
|
||||
Please double-click the 'install.bat' file (while keeping it inside the invokeAI folder).
|
||||
|
||||
Installation on Linux and Mac:
|
||||
Please open the terminal, and run './install.sh' (while keeping it inside the invokeAI folder).
|
||||
|
||||
After installation, please run the 'invoke.bat' file (on Windows) or 'invoke.sh'
|
||||
file (on Linux/Mac) to start InvokeAI.
|
@ -1,33 +0,0 @@
|
||||
--prefer-binary
|
||||
--extra-index-url https://download.pytorch.org/whl/torch_stable.html
|
||||
--extra-index-url https://download.pytorch.org/whl/cu116
|
||||
--trusted-host https://download.pytorch.org
|
||||
accelerate~=0.15
|
||||
albumentations
|
||||
diffusers[torch]~=0.11
|
||||
einops
|
||||
eventlet
|
||||
flask_cors
|
||||
flask_socketio
|
||||
flaskwebgui==1.0.3
|
||||
getpass_asterisk
|
||||
imageio-ffmpeg
|
||||
pyreadline3
|
||||
realesrgan
|
||||
send2trash
|
||||
streamlit
|
||||
taming-transformers-rom1504
|
||||
test-tube
|
||||
torch-fidelity
|
||||
torch==1.12.1 ; platform_system == 'Darwin'
|
||||
torch==1.12.0+cu116 ; platform_system == 'Linux' or platform_system == 'Windows'
|
||||
torchvision==0.13.1 ; platform_system == 'Darwin'
|
||||
torchvision==0.13.0+cu116 ; platform_system == 'Linux' or platform_system == 'Windows'
|
||||
transformers
|
||||
picklescan
|
||||
https://github.com/openai/CLIP/archive/d50d76daa670286dd6cacf3bcd80b5e4823fc8e1.zip
|
||||
https://github.com/invoke-ai/clipseg/archive/1f754751c85d7d4255fa681f4491ff5711c1c288.zip
|
||||
https://github.com/invoke-ai/GFPGAN/archive/3f5d2397361199bc4a91c08bb7d80f04d7805615.zip ; platform_system=='Windows'
|
||||
https://github.com/invoke-ai/GFPGAN/archive/c796277a1cf77954e5fc0b288d7062d162894248.zip ; platform_system=='Linux' or platform_system=='Darwin'
|
||||
https://github.com/Birch-san/k-diffusion/archive/363386981fee88620709cf8f6f2eea167bd6cd74.zip
|
||||
https://github.com/invoke-ai/PyPatchMatch/archive/129863937a8ab37f6bbcec327c994c0f932abdbc.zip
|
5
docs/.markdownlint.jsonc
Normal file
5
docs/.markdownlint.jsonc
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"MD046": false,
|
||||
"MD007": false,
|
||||
"MD030": false
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
title: Concepts Library
|
||||
title: Styles and Subjects
|
||||
---
|
||||
|
||||
# :material-library-shelves: The Hugging Face Concepts Library and Importing Textual Inversion files
|
||||
@ -25,10 +25,14 @@ library which downloads and merges TI files automatically upon request. You can
|
||||
also install your own or others' TI files by placing them in a designated
|
||||
directory.
|
||||
|
||||
You may also be interested in using [LoRA Models](LORAS.md) to
|
||||
generate images with specialized styles and subjects.
|
||||
|
||||
### An Example
|
||||
|
||||
Here are a few examples to illustrate how it works. All these images were
|
||||
generated using the command-line client and the Stable Diffusion 1.5 model:
|
||||
Here are a few examples to illustrate how Textual Inversion works. All
|
||||
these images were generated using the command-line client and the
|
||||
Stable Diffusion 1.5 model:
|
||||
|
||||
| Japanese gardener | Japanese gardener <ghibli-face> | Japanese gardener <hoi4-leaders> | Japanese gardener <cartoona-animals> |
|
||||
| :--------------------------------: | :-----------------------------------: | :------------------------------------: | :----------------------------------------: |
|
||||
@ -109,21 +113,50 @@ For example, TI files generated by the Hugging Face toolkit share the named
|
||||
`learned_embedding.bin`. You can use subdirectories to keep them distinct.
|
||||
|
||||
At startup time, InvokeAI will scan the `embeddings` directory and load any TI
|
||||
files it finds there. At startup you will see a message similar to this one:
|
||||
files it finds there. At startup you will see messages similar to these:
|
||||
|
||||
```bash
|
||||
>> Current embedding manager terms: *, <HOI4-Leader>, <princess-knight>
|
||||
>> Loading embeddings from /data/lstein/invokeai-2.3/embeddings
|
||||
| Loading v1 embedding file: style-hamunaptra
|
||||
| Loading v4 embedding file: embeddings/learned_embeds-steps-500.bin
|
||||
| Loading v2 embedding file: lfa
|
||||
| Loading v3 embedding file: easynegative
|
||||
| Loading v1 embedding file: rem_rezero
|
||||
| Loading v2 embedding file: midj-strong
|
||||
| Loading v4 embedding file: anime-background-style-v2/learned_embeds.bin
|
||||
| Loading v4 embedding file: kamon-style/learned_embeds.bin
|
||||
** Notice: kamon-style/learned_embeds.bin was trained on a model with an incompatible token dimension: 768 vs 1024.
|
||||
>> Textual inversion triggers: <anime-background-style-v2>, <easynegative>, <lfa>, <midj-strong>, <milo>, Rem3-2600, Style-Hamunaptra
|
||||
```
|
||||
|
||||
Note the `*` trigger term. This is a placeholder term that many early TI
|
||||
tutorials taught people to use rather than a more descriptive term.
|
||||
Unfortunately, if you have multiple TI files that all use this term, only the
|
||||
first one loaded will be triggered by use of the term.
|
||||
Textual Inversion embeddings trained on version 1.X stable diffusion
|
||||
models are incompatible with version 2.X models and vice-versa.
|
||||
|
||||
To avoid this problem, you can use the `merge_embeddings.py` script to merge two
|
||||
or more TI files together. If it encounters a collision of terms, the script
|
||||
will prompt you to select new terms that do not collide. See
|
||||
[Textual Inversion](TEXTUAL_INVERSION.md) for details.
|
||||
After the embeddings load, InvokeAI will print out a list of all the
|
||||
recognized trigger terms. To trigger the term, include it in the
|
||||
prompt exactly as written, including angle brackets if any and
|
||||
respecting the capitalization.
|
||||
|
||||
There are at least four different embedding file formats, and each uses
|
||||
a different convention for the trigger terms. In some cases, the
|
||||
trigger term is specified in the file contents and may or may not be
|
||||
surrounded by angle brackets. In the example above, `Rem3-2600`,
|
||||
`Style-Hamunaptra`, and `<midj-strong>` were specified this way and
|
||||
there is no easy way to change the term.
|
||||
|
||||
In other cases the trigger term is not contained within the embedding
|
||||
file. In this case, InvokeAI constructs a trigger term consisting of
|
||||
the base name of the file (without the file extension) surrounded by
|
||||
angle brackets. In the example above `<easynegative`> is such a file
|
||||
(the filename was `easynegative.safetensors`). In such cases, you can
|
||||
change the trigger term simply by renaming the file.
|
||||
|
||||
## Training your own Textual Inversion models
|
||||
|
||||
InvokeAI provides a script that lets you train your own Textual
|
||||
Inversion embeddings using a small number (about a half-dozen) images
|
||||
of your desired style or subject. Please see [Textual
|
||||
Inversion](TEXTUAL_INVERSION.md) for details.
|
||||
|
||||
## Further Reading
|
||||
|
||||
|
100
docs/features/LORAS.md
Normal file
100
docs/features/LORAS.md
Normal file
@ -0,0 +1,100 @@
|
||||
---
|
||||
title: Low-Rank Adaptation (LoRA) Models
|
||||
---
|
||||
|
||||
# :material-library-shelves: Using Low-Rank Adaptation (LoRA) Models
|
||||
|
||||
## Introduction
|
||||
|
||||
LoRA is a technique for fine-tuning Stable Diffusion models using much
|
||||
less time and memory than traditional training techniques. The
|
||||
resulting model files are much smaller than full model files, and can
|
||||
be used to generate specialized styles and subjects.
|
||||
|
||||
LoRAs are built on top of Stable Diffusion v1.x or 2.x checkpoint or
|
||||
diffusers models. To load a LoRA, you include its name in the text
|
||||
prompt using a simple syntax described below. While you will generally
|
||||
get the best results when you use the same model the LoRA was trained
|
||||
on, they will work to a greater or lesser extent with other models.
|
||||
The major caveat is that a LoRA built on top of a SD v1.x model cannot
|
||||
be used with a v2.x model, and vice-versa. If you try, you will get an
|
||||
error! You may refer to multiple LoRAs in your prompt.
|
||||
|
||||
When you apply a LoRA in a prompt you can specify a weight. The higher
|
||||
the weight, the more influence it will have on the image. Useful
|
||||
ranges for weights are usually in the 0.0 to 1.0 range (with ranges
|
||||
between 0.5 and 1.0 being most typical). However you can specify a
|
||||
higher weight if you wish. Like models, each LoRA has a slightly
|
||||
different useful weight range and will interact with other generation
|
||||
parameters such as the CFG, step count and sampler. The author of the
|
||||
LoRA will often provide guidance on the best settings, but feel free
|
||||
to experiment. Be aware that it often helps to reduce the CFG value
|
||||
when using LoRAs.
|
||||
|
||||
## Installing LoRAs
|
||||
|
||||
This is very easy! Download a LoRA model file from your favorite site
|
||||
(e.g. [CIVITAI](https://civitai.com) and place it in the `loras`
|
||||
folder in the InvokeAI root directory (usually `~invokeai/loras` on
|
||||
Linux/Macintosh machines, and `C:\Users\your-name\invokeai/loras` on
|
||||
Windows systems). If the `loras` folder does not already exist, just
|
||||
create it. The vast majority of LoRA models use the Kohya file format,
|
||||
which is a type of `.safetensors` file.
|
||||
|
||||
You may change where InvokeAI looks for the `loras` folder by passing the
|
||||
`--lora_directory` option to the `invoke.sh`/`invoke.bat` launcher, or
|
||||
by placing the option in `invokeai.init`. For example:
|
||||
|
||||
```
|
||||
invoke.sh --lora_directory=C:\Users\your-name\SDModels\lora
|
||||
```
|
||||
|
||||
## Using a LoRA in your prompt
|
||||
|
||||
To activate a LoRA use the syntax `withLora(my-lora-name,weight)`
|
||||
somewhere in the text of the prompt. The position doesn't matter; use
|
||||
whatever is most comfortable for you.
|
||||
|
||||
For example, if you have a LoRA named `parchment_people.safetensors`
|
||||
in your `loras` directory, you can load it with a weight of 0.9 with a
|
||||
prompt like this one:
|
||||
|
||||
```
|
||||
family sitting at dinner table withLora(parchment_people,0.9)
|
||||
```
|
||||
|
||||
Add additional `withLora()` phrases to load more LoRAs.
|
||||
|
||||
You may omit the weight entirely to default to a weight of 1.0:
|
||||
|
||||
```
|
||||
family sitting at dinner table withLora(parchment_people)
|
||||
```
|
||||
|
||||
If you watch the console as your prompt executes, you will see
|
||||
messages relating to the loading and execution of the LoRA. If things
|
||||
don't work as expected, note down the console messages and report them
|
||||
on the InvokeAI Issues pages or Discord channel.
|
||||
|
||||
That's pretty much all you need to know!
|
||||
|
||||
## Training Kohya Models
|
||||
|
||||
InvokeAI cannot currently train LoRA models, but it can load and use
|
||||
existing LoRA ones to generate images. While there are several LoRA
|
||||
model file formats, the predominant one is ["Kohya"
|
||||
format](https://github.com/kohya-ss/sd-scripts), written by [Kohya
|
||||
S.](https://github.com/kohya-ss). InvokeAI provides support for this
|
||||
format. For creating your own Kohya models, we recommend the Windows
|
||||
GUI written by former InvokeAI-team member
|
||||
[bmaltais](https://github.com/bmaltais), which can be found at
|
||||
[kohya_ss](https://github.com/bmaltais/kohya_ss).
|
||||
|
||||
We can also recommend the [HuggingFace DreamBooth Training
|
||||
UI](https://huggingface.co/spaces/lora-library/LoRA-DreamBooth-Training-UI),
|
||||
a paid service that supports both Textual Inversion and LoRA training.
|
||||
|
||||
You may also be interested in [Textual
|
||||
Inversion](TEXTUAL_INVERSION.md) training, which is supported by
|
||||
InvokeAI as a text console and command-line tool.
|
||||
|
@ -154,8 +154,11 @@ training sets will converge with 2000-3000 steps.
|
||||
|
||||
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.
|
||||
quickly, but use more memory. The default size is selected based on
|
||||
whether you have the `xformers` memory-efficient attention library
|
||||
installed. If `xformers` is available, the batch size will be 8,
|
||||
otherwise 3. These values were chosen to allow training to run with
|
||||
GPUs with as little as 12 GB VRAM.
|
||||
|
||||
### Learning rate
|
||||
|
||||
@ -172,8 +175,10 @@ 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.
|
||||
This will activate XFormers memory-efficient attention, which will
|
||||
reduce memory requirements by half or more and allow you to select a
|
||||
higher batch size. You need to have XFormers installed for this to
|
||||
have an effect.
|
||||
|
||||
### Learning rate scheduler
|
||||
|
||||
@ -250,6 +255,49 @@ invokeai-ti \
|
||||
--only_save_embeds
|
||||
```
|
||||
|
||||
## Using Distributed Training
|
||||
|
||||
If you have multiple GPUs on one machine, or a cluster of GPU-enabled
|
||||
machines, you can activate distributed training. See the [HuggingFace
|
||||
Accelerate pages](https://huggingface.co/docs/accelerate/index) for
|
||||
full information, but the basic recipe is:
|
||||
|
||||
1. Enter the InvokeAI developer's console command line by selecting
|
||||
option [8] from the `invoke.sh`/`invoke.bat` script.
|
||||
|
||||
2. Configurate Accelerate using `accelerate config`:
|
||||
```sh
|
||||
accelerate config
|
||||
```
|
||||
This will guide you through the configuration process, including
|
||||
specifying how many machines you will run training on and the number
|
||||
of GPUs pe rmachine.
|
||||
|
||||
You only need to do this once.
|
||||
|
||||
3. Launch training from the command line using `accelerate launch`. Be sure
|
||||
that your current working directory is the InvokeAI root directory (usually
|
||||
named `invokeai` in your home directory):
|
||||
|
||||
```sh
|
||||
accelerate launch .venv/bin/invokeai-ti \
|
||||
--model=stable-diffusion-1.5 \
|
||||
--resolution=512 \
|
||||
--learnable_property=object \
|
||||
--initializer_token='*' \
|
||||
--placeholder_token='<shraddha>' \
|
||||
--train_data_dir=/home/lstein/invokeai/text-inversion-training-data/shraddha \
|
||||
--output_dir=/home/lstein/invokeai/text-inversion-training/shraddha \
|
||||
--scale_lr \
|
||||
--train_batch_size=10 \
|
||||
--gradient_accumulation_steps=4 \
|
||||
--max_train_steps=2000 \
|
||||
--learning_rate=0.0005 \
|
||||
--lr_scheduler=constant \
|
||||
--mixed_precision=fp16 \
|
||||
--only_save_embeds
|
||||
```
|
||||
|
||||
## Using Embeddings
|
||||
|
||||
After training completes, the resultant embeddings will be saved into your `$INVOKEAI_ROOT/embeddings/<trigger word>/learned_embeds.bin`.
|
||||
|
@ -2,62 +2,84 @@
|
||||
title: Overview
|
||||
---
|
||||
|
||||
Here you can find the documentation for InvokeAI's various features.
|
||||
- The Basics
|
||||
|
||||
## The Basics
|
||||
### * The [Web User Interface](WEB.md)
|
||||
Guide to the Web interface. Also see the [WebUI Hotkeys Reference Guide](WEBUIHOTKEYS.md)
|
||||
- The [Web User Interface](WEB.md)
|
||||
|
||||
### * The [Unified Canvas](UNIFIED_CANVAS.md)
|
||||
Build complex scenes by combine and modifying multiple images in a stepwise
|
||||
fashion. This feature combines img2img, inpainting and outpainting in
|
||||
a single convenient digital artist-optimized user interface.
|
||||
Guide to the Web interface. Also see the
|
||||
[WebUI Hotkeys Reference Guide](WEBUIHOTKEYS.md)
|
||||
|
||||
### * The [Command Line Interface (CLI)](CLI.md)
|
||||
Scriptable access to InvokeAI's features.
|
||||
- The [Unified Canvas](UNIFIED_CANVAS.md)
|
||||
|
||||
## Image Generation
|
||||
### * [Prompt Engineering](PROMPTS.md)
|
||||
Get the images you want with the InvokeAI prompt engineering language.
|
||||
Build complex scenes by combine and modifying multiple images in a
|
||||
stepwise fashion. This feature combines img2img, inpainting and
|
||||
outpainting in a single convenient digital artist-optimized user
|
||||
interface.
|
||||
|
||||
## * [Post-Processing](POSTPROCESS.md)
|
||||
Restore mangled faces and make images larger with upscaling. Also see the [Embiggen Upscaling Guide](EMBIGGEN.md).
|
||||
- The [Command Line Interface (CLI)](CLI.md)
|
||||
|
||||
## * The [Concepts Library](CONCEPTS.md)
|
||||
Add custom subjects and styles using HuggingFace's repository of embeddings.
|
||||
Scriptable access to InvokeAI's features.
|
||||
|
||||
### * [Image-to-Image Guide for the CLI](IMG2IMG.md)
|
||||
Use a seed image to build new creations in the CLI.
|
||||
- [Visual Manual for InvokeAI](https://docs.google.com/presentation/d/e/2PACX-1vSE90aC7bVVg0d9KXVMhy-Wve-wModgPFp7AGVTOCgf4xE03SnV24mjdwldolfCr59D_35oheHe4Cow/pub?start=false&loop=true&delayms=60000) (contributed by Statcomm)
|
||||
|
||||
### * [Inpainting Guide for the CLI](INPAINTING.md)
|
||||
Selectively erase and replace portions of an existing image in the CLI.
|
||||
- Image Generation
|
||||
|
||||
### * [Outpainting Guide for the CLI](OUTPAINTING.md)
|
||||
Extend the borders of the image with an "outcrop" function within the CLI.
|
||||
- [Prompt Engineering](PROMPTS.md)
|
||||
|
||||
### * [Generating Variations](VARIATIONS.md)
|
||||
Have an image you like and want to generate many more like it? Variations
|
||||
are the ticket.
|
||||
Get the images you want with the InvokeAI prompt engineering language.
|
||||
|
||||
## Model Management
|
||||
- [Post-Processing](POSTPROCESS.md)
|
||||
|
||||
## * [Model Installation](../installation/050_INSTALLING_MODELS.md)
|
||||
Learn how to import third-party models and switch among them. This
|
||||
guide also covers optimizing models to load quickly.
|
||||
Restore mangled faces and make images larger with upscaling. Also see
|
||||
the [Embiggen Upscaling Guide](EMBIGGEN.md).
|
||||
|
||||
## * [Merging Models](MODEL_MERGING.md)
|
||||
Teach an old model new tricks. Merge 2-3 models together to create a
|
||||
new model that combines characteristics of the originals.
|
||||
- The [Concepts Library](CONCEPTS.md)
|
||||
|
||||
## * [Textual Inversion](TEXTUAL_INVERSION.md)
|
||||
Personalize models by adding your own style or subjects.
|
||||
Add custom subjects and styles using HuggingFace's repository of
|
||||
embeddings.
|
||||
|
||||
# Other Features
|
||||
- [Image-to-Image Guide for the CLI](IMG2IMG.md)
|
||||
|
||||
## * [The NSFW Checker](NSFW.md)
|
||||
Prevent InvokeAI from displaying unwanted racy images.
|
||||
Use a seed image to build new creations in the CLI.
|
||||
|
||||
## * [Miscellaneous](OTHER.md)
|
||||
Run InvokeAI on Google Colab, generate images with repeating patterns,
|
||||
batch process a file of prompts, increase the "creativity" of image
|
||||
generation by adding initial noise, and more!
|
||||
- [Inpainting Guide for the CLI](INPAINTING.md)
|
||||
|
||||
Selectively erase and replace portions of an existing image in the CLI.
|
||||
|
||||
- [Outpainting Guide for the CLI](OUTPAINTING.md)
|
||||
|
||||
Extend the borders of the image with an "outcrop" function within the
|
||||
CLI.
|
||||
|
||||
- [Generating Variations](VARIATIONS.md)
|
||||
|
||||
Have an image you like and want to generate many more like it?
|
||||
Variations are the ticket.
|
||||
|
||||
- Model Management
|
||||
|
||||
- [Model Installation](../installation/050_INSTALLING_MODELS.md)
|
||||
|
||||
Learn how to import third-party models and switch among them. This guide
|
||||
also covers optimizing models to load quickly.
|
||||
|
||||
- [Merging Models](MODEL_MERGING.md)
|
||||
|
||||
Teach an old model new tricks. Merge 2-3 models together to create a new
|
||||
model that combines characteristics of the originals.
|
||||
|
||||
- [Textual Inversion](TEXTUAL_INVERSION.md)
|
||||
|
||||
Personalize models by adding your own style or subjects.
|
||||
|
||||
- Other Features
|
||||
|
||||
- [The NSFW Checker](NSFW.md)
|
||||
|
||||
Prevent InvokeAI from displaying unwanted racy images.
|
||||
|
||||
- [Miscellaneous](OTHER.md)
|
||||
|
||||
Run InvokeAI on Google Colab, generate images with repeating patterns,
|
||||
batch process a file of prompts, increase the "creativity" of image
|
||||
generation by adding initial noise, and more!
|
||||
|
4
docs/help/IDE-Settings/index.md
Normal file
4
docs/help/IDE-Settings/index.md
Normal file
@ -0,0 +1,4 @@
|
||||
# :octicons-file-code-16: IDE-Settings
|
||||
|
||||
Here we will share settings for IDEs used by our developers, maybe you can find
|
||||
something interestening which will help to boost your development efficency 🔥
|
250
docs/help/IDE-Settings/vs-code.md
Normal file
250
docs/help/IDE-Settings/vs-code.md
Normal file
@ -0,0 +1,250 @@
|
||||
---
|
||||
title: Visual Studio Code
|
||||
---
|
||||
|
||||
# :material-microsoft-visual-studio-code:Visual Studio Code
|
||||
|
||||
The Workspace Settings are stored in the project (repository) root and get
|
||||
higher priorized than your user settings.
|
||||
|
||||
This helps to have different settings for different projects, while the user
|
||||
settings get used as a default value if no workspace settings are provided.
|
||||
|
||||
## tasks.json
|
||||
|
||||
First we will create a task configuration which will create a virtual
|
||||
environment and update the deps (pip, setuptools and wheel).
|
||||
|
||||
Into this venv we will then install the pyproject.toml in editable mode with
|
||||
dev, docs and test dependencies.
|
||||
|
||||
```json title=".vscode/tasks.json"
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Create virtual environment",
|
||||
"detail": "Create .venv and upgrade pip, setuptools and wheel",
|
||||
"command": "python3",
|
||||
"args": [
|
||||
"-m",
|
||||
"venv",
|
||||
".venv",
|
||||
"--prompt",
|
||||
"InvokeAI",
|
||||
"--upgrade-deps"
|
||||
],
|
||||
"runOptions": {
|
||||
"instanceLimit": 1,
|
||||
"reevaluateOnRerun": true
|
||||
},
|
||||
"group": {
|
||||
"kind": "build"
|
||||
},
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "build InvokeAI",
|
||||
"detail": "Build pyproject.toml with extras dev, docs and test",
|
||||
"command": "${workspaceFolder}/.venv/bin/python3",
|
||||
"args": [
|
||||
"-m",
|
||||
"pip",
|
||||
"install",
|
||||
"--use-pep517",
|
||||
"--editable",
|
||||
".[dev,docs,test]"
|
||||
],
|
||||
"dependsOn": "Create virtual environment",
|
||||
"dependsOrder": "sequence",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The fastest way to build InvokeAI now is ++cmd+shift+b++
|
||||
|
||||
## launch.json
|
||||
|
||||
This file is used to define debugger configurations, so that you can one-click
|
||||
launch and monitor the application, set halt points to inspect specific states,
|
||||
...
|
||||
|
||||
```json title=".vscode/launch.json"
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "invokeai web",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": ".venv/bin/invokeai",
|
||||
"justMyCode": true
|
||||
},
|
||||
{
|
||||
"name": "invokeai cli",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": ".venv/bin/invokeai",
|
||||
"justMyCode": true
|
||||
},
|
||||
{
|
||||
"name": "mkdocs serve",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": ".venv/bin/mkdocs",
|
||||
"args": ["serve"],
|
||||
"justMyCode": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Then you only need to hit ++f5++ and the fun begins :nerd: (It is asumed that
|
||||
you have created a virtual environment via the [tasks](#tasksjson) from the
|
||||
previous step.)
|
||||
|
||||
## extensions.json
|
||||
|
||||
A list of recommended vscode-extensions to make your life easier:
|
||||
|
||||
```json title=".vscode/extensions.json"
|
||||
{
|
||||
"recommendations": [
|
||||
"editorconfig.editorconfig",
|
||||
"github.vscode-pull-request-github",
|
||||
"ms-python.black-formatter",
|
||||
"ms-python.flake8",
|
||||
"ms-python.isort",
|
||||
"ms-python.python",
|
||||
"ms-python.vscode-pylance",
|
||||
"redhat.vscode-yaml",
|
||||
"tamasfe.even-better-toml",
|
||||
"eamodio.gitlens",
|
||||
"foxundermoon.shell-format",
|
||||
"timonwong.shellcheck",
|
||||
"esbenp.prettier-vscode",
|
||||
"davidanson.vscode-markdownlint",
|
||||
"yzhang.markdown-all-in-one",
|
||||
"bierner.github-markdown-preview",
|
||||
"ms-azuretools.vscode-docker",
|
||||
"mads-hartmann.bash-ide-vscode"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## settings.json
|
||||
|
||||
With bellow settings your files already get formated when you save them (only
|
||||
your modifications if available), which will help you to not run into trouble
|
||||
with the pre-commit hooks. If the hooks fail, they will prevent you from
|
||||
commiting, but most hooks directly add a fixed version, so that you just need to
|
||||
stage and commit them:
|
||||
|
||||
```json title=".vscode/settings.json"
|
||||
{
|
||||
"[json]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.quickSuggestions": {
|
||||
"comments": false,
|
||||
"strings": true,
|
||||
"other": true
|
||||
},
|
||||
"editor.suggest.insertMode": "replace",
|
||||
"gitlens.codeLens.scopes": ["document"]
|
||||
},
|
||||
"[jsonc]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnSaveMode": "modificationsIfAvailable"
|
||||
},
|
||||
"[python]": {
|
||||
"editor.defaultFormatter": "ms-python.black-formatter",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnSaveMode": "file"
|
||||
},
|
||||
"[toml]": {
|
||||
"editor.defaultFormatter": "tamasfe.even-better-toml",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnSaveMode": "modificationsIfAvailable"
|
||||
},
|
||||
"[yaml]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnSaveMode": "modificationsIfAvailable"
|
||||
},
|
||||
"[markdown]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.rulers": [80],
|
||||
"editor.unicodeHighlight.ambiguousCharacters": false,
|
||||
"editor.unicodeHighlight.invisibleCharacters": false,
|
||||
"diffEditor.ignoreTrimWhitespace": false,
|
||||
"editor.wordWrap": "on",
|
||||
"editor.quickSuggestions": {
|
||||
"comments": "off",
|
||||
"strings": "off",
|
||||
"other": "off"
|
||||
},
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnSaveMode": "modificationsIfAvailable"
|
||||
},
|
||||
"[shellscript]": {
|
||||
"editor.defaultFormatter": "foxundermoon.shell-format"
|
||||
},
|
||||
"[ignore]": {
|
||||
"editor.defaultFormatter": "foxundermoon.shell-format"
|
||||
},
|
||||
"editor.rulers": [88],
|
||||
"evenBetterToml.formatter.alignEntries": false,
|
||||
"evenBetterToml.formatter.allowedBlankLines": 1,
|
||||
"evenBetterToml.formatter.arrayAutoExpand": true,
|
||||
"evenBetterToml.formatter.arrayTrailingComma": true,
|
||||
"evenBetterToml.formatter.arrayAutoCollapse": true,
|
||||
"evenBetterToml.formatter.columnWidth": 88,
|
||||
"evenBetterToml.formatter.compactArrays": true,
|
||||
"evenBetterToml.formatter.compactInlineTables": true,
|
||||
"evenBetterToml.formatter.indentEntries": false,
|
||||
"evenBetterToml.formatter.inlineTableExpand": true,
|
||||
"evenBetterToml.formatter.reorderArrays": true,
|
||||
"evenBetterToml.formatter.reorderKeys": true,
|
||||
"evenBetterToml.formatter.compactEntries": false,
|
||||
"evenBetterToml.schema.enabled": true,
|
||||
"python.analysis.typeCheckingMode": "basic",
|
||||
"python.formatting.provider": "black",
|
||||
"python.languageServer": "Pylance",
|
||||
"python.linting.enabled": true,
|
||||
"python.linting.flake8Enabled": true,
|
||||
"python.testing.unittestEnabled": false,
|
||||
"python.testing.pytestEnabled": true,
|
||||
"python.testing.pytestArgs": [
|
||||
"tests",
|
||||
"--cov=ldm",
|
||||
"--cov-branch",
|
||||
"--cov-report=term:skip-covered"
|
||||
],
|
||||
"yaml.schemas": {
|
||||
"https://json.schemastore.org/prettierrc.json": "${workspaceFolder}/.prettierrc.yaml"
|
||||
}
|
||||
}
|
||||
```
|
135
docs/help/contributing/010_PULL_REQUEST.md
Normal file
135
docs/help/contributing/010_PULL_REQUEST.md
Normal file
@ -0,0 +1,135 @@
|
||||
---
|
||||
title: Pull-Request
|
||||
---
|
||||
|
||||
# :octicons-git-pull-request-16: Pull-Request
|
||||
|
||||
## pre-requirements
|
||||
|
||||
To follow the steps in this tutorial you will need:
|
||||
|
||||
- [GitHub](https://github.com) account
|
||||
- [git](https://git-scm.com/downloads) source controll
|
||||
- Text / Code Editor (personally I preffer
|
||||
[Visual Studio Code](https://code.visualstudio.com/Download))
|
||||
- Terminal:
|
||||
- If you are on Linux/MacOS you can use bash or zsh
|
||||
- for Windows Users the commands are written for PowerShell
|
||||
|
||||
## Fork Repository
|
||||
|
||||
The first step to be done if you want to contribute to InvokeAI, is to fork the
|
||||
rpeository.
|
||||
|
||||
Since you are already reading this doc, the easiest way to do so is by clicking
|
||||
[here](https://github.com/invoke-ai/InvokeAI/fork). You could also open
|
||||
[InvokeAI](https://github.com/invoke-ai/InvoekAI) and click on the "Fork" Button
|
||||
in the top right.
|
||||
|
||||
## Clone your fork
|
||||
|
||||
After you forked the Repository, you should clone it to your dev machine:
|
||||
|
||||
=== ":fontawesome-brands-linux:Linux / :simple-apple:macOS"
|
||||
|
||||
``` sh
|
||||
git clone https://github.com/<github username>/InvokeAI \
|
||||
&& cd InvokeAI
|
||||
```
|
||||
|
||||
=== ":fontawesome-brands-windows:Windows"
|
||||
|
||||
``` powershell
|
||||
git clone https://github.com/<github username>/InvokeAI `
|
||||
&& cd InvokeAI
|
||||
```
|
||||
|
||||
## Install in Editable Mode
|
||||
|
||||
To install InvokeAI in editable mode, (as always) we recommend to create and
|
||||
activate a venv first. Afterwards you can install the InvokeAI Package,
|
||||
including dev and docs extras in editable mode, follwed by the installation of
|
||||
the pre-commit hook:
|
||||
|
||||
=== ":fontawesome-brands-linux:Linux / :simple-apple:macOS"
|
||||
|
||||
``` sh
|
||||
python -m venv .venv \
|
||||
--prompt InvokeAI \
|
||||
--upgrade-deps \
|
||||
&& source .venv/bin/activate \
|
||||
&& pip install \
|
||||
--upgrade-deps \
|
||||
--use-pep517 \
|
||||
--editable=".[dev,docs]" \
|
||||
&& pre-commit install
|
||||
```
|
||||
|
||||
=== ":fontawesome-brands-windows:Windows"
|
||||
|
||||
``` powershell
|
||||
python -m venv .venv `
|
||||
--prompt InvokeAI `
|
||||
--upgrade-deps `
|
||||
&& .venv/scripts/activate.ps1 `
|
||||
&& pip install `
|
||||
--upgrade `
|
||||
--use-pep517 `
|
||||
--editable=".[dev,docs]" `
|
||||
&& pre-commit install
|
||||
```
|
||||
|
||||
## Create a branch
|
||||
|
||||
Make sure you are on main branch, from there create your feature branch:
|
||||
|
||||
=== ":fontawesome-brands-linux:Linux / :simple-apple:macOS"
|
||||
|
||||
``` sh
|
||||
git checkout main \
|
||||
&& git pull \
|
||||
&& git checkout -B <branch name>
|
||||
```
|
||||
|
||||
=== ":fontawesome-brands-windows:Windows"
|
||||
|
||||
``` powershell
|
||||
git checkout main `
|
||||
&& git pull `
|
||||
&& git checkout -B <branch name>
|
||||
```
|
||||
|
||||
## Commit your changes
|
||||
|
||||
When you are done with adding / updating content, you need to commit those
|
||||
changes to your repository before you can actually open an PR:
|
||||
|
||||
```{ .sh .annotate }
|
||||
git add <files you have changed> # (1)!
|
||||
git commit -m "A commit message which describes your change"
|
||||
git push
|
||||
```
|
||||
|
||||
1. Replace this with a space seperated list of the files you changed, like:
|
||||
`README.md foo.sh bar.json baz`
|
||||
|
||||
## Create a Pull Request
|
||||
|
||||
After pushing your changes, you are ready to create a Pull Request. just head
|
||||
over to your fork on [GitHub](https://github.com), which should already show you
|
||||
a message that there have been recent changes on your feature branch and a green
|
||||
button which you could use to create the PR.
|
||||
|
||||
The default target for your PRs would be the main branch of
|
||||
[invoke-ai/InvokeAI](https://github.com/invoke-ai/InvokeAI)
|
||||
|
||||
Another way would be to create it in VS-Code or via the GitHub CLI (or even via
|
||||
the GitHub CLI in a VS-Code Terminal Window 🤭):
|
||||
|
||||
```sh
|
||||
gh pr create
|
||||
```
|
||||
|
||||
The CLI will inform you if there are still unpushed commits on your branch. It
|
||||
will also prompt you for things like the the Title and the Body (Description) if
|
||||
you did not already pass them as arguments.
|
26
docs/help/contributing/020_ISSUES.md
Normal file
26
docs/help/contributing/020_ISSUES.md
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
title: Issues
|
||||
---
|
||||
|
||||
# :octicons-issue-opened-16: Issues
|
||||
|
||||
## :fontawesome-solid-bug: Report a bug
|
||||
|
||||
If you stumbled over a bug while using InvokeAI, we would apreciate it a lot if
|
||||
you
|
||||
[open a issue](https://github.com/invoke-ai/InvokeAI/issues/new?assignees=&labels=bug&template=BUG_REPORT.yml&title=%5Bbug%5D%3A+)
|
||||
to inform us about the details so that our developers can look into it.
|
||||
|
||||
If you also know how to fix the bug, take a look [here](010_PULL_REQUEST.md) to
|
||||
find out how to create a Pull Request.
|
||||
|
||||
## Request a feature
|
||||
|
||||
If you have a idea for a new feature on your mind which you would like to see in
|
||||
InvokeAI, there is a
|
||||
[feature request](https://github.com/invoke-ai/InvokeAI/issues/new?assignees=&labels=bug&template=BUG_REPORT.yml&title=%5Bbug%5D%3A+)
|
||||
available in the issues section of the repository.
|
||||
|
||||
If you are just curious which features already got requested you can find the
|
||||
overview of open requests
|
||||
[here](https://github.com/invoke-ai/InvokeAI/labels/enhancement)
|
32
docs/help/contributing/030_DOCS.md
Normal file
32
docs/help/contributing/030_DOCS.md
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
title: docs
|
||||
---
|
||||
|
||||
# :simple-readthedocs: MkDocs-Material
|
||||
|
||||
If you want to contribute to the docs, there is a easy way to verify the results
|
||||
of your changes before commiting them.
|
||||
|
||||
Just follow the steps in the [Pull-Requests](010_PULL_REQUEST.md) docs, there we
|
||||
already
|
||||
[create a venv and install the docs extras](010_PULL_REQUEST.md#install-in-editable-mode).
|
||||
When installed it's as simple as:
|
||||
|
||||
```sh
|
||||
mkdocs serve
|
||||
```
|
||||
|
||||
This will build the docs locally and serve them on your local host, even
|
||||
auto-refresh is included, so you can just update a doc, save it and tab to the
|
||||
browser, without the needs of restarting the `mkdocs serve`.
|
||||
|
||||
More information about the "mkdocs flavored markdown syntax" can be found
|
||||
[here](https://squidfunk.github.io/mkdocs-material/reference/).
|
||||
|
||||
## :material-microsoft-visual-studio-code:VS-Code
|
||||
|
||||
We also provide a
|
||||
[launch configuration for VS-Code](../IDE-Settings/vs-code.md#launchjson) which
|
||||
includes a `mkdocs serve` entrypoint as well. You also don't have to worry about
|
||||
the formatting since this is automated via prettier, but this is of course not
|
||||
limited to VS-Code.
|
76
docs/help/contributing/090_NODE_TRANSFORMATION.md
Normal file
76
docs/help/contributing/090_NODE_TRANSFORMATION.md
Normal file
@ -0,0 +1,76 @@
|
||||
# Tranformation to nodes
|
||||
|
||||
## Current state
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
web[WebUI];
|
||||
cli[CLI];
|
||||
web --> |img2img| generate(generate);
|
||||
web --> |txt2img| generate(generate);
|
||||
cli --> |txt2img| generate(generate);
|
||||
cli --> |img2img| generate(generate);
|
||||
generate --> model_manager;
|
||||
generate --> generators;
|
||||
generate --> ti_manager[TI Manager];
|
||||
generate --> etc;
|
||||
```
|
||||
|
||||
## Transitional Architecture
|
||||
|
||||
### first step
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
web[WebUI];
|
||||
cli[CLI];
|
||||
web --> |img2img| img2img_node(Img2img node);
|
||||
web --> |txt2img| generate(generate);
|
||||
img2img_node --> model_manager;
|
||||
img2img_node --> generators;
|
||||
cli --> |txt2img| generate;
|
||||
cli --> |img2img| generate;
|
||||
generate --> model_manager;
|
||||
generate --> generators;
|
||||
generate --> ti_manager[TI Manager];
|
||||
generate --> etc;
|
||||
```
|
||||
|
||||
### second step
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
web[WebUI];
|
||||
cli[CLI];
|
||||
web --> |img2img| img2img_node(img2img node);
|
||||
img2img_node --> model_manager;
|
||||
img2img_node --> generators;
|
||||
web --> |txt2img| txt2img_node(txt2img node);
|
||||
cli --> |txt2img| txt2img_node;
|
||||
cli --> |img2img| generate(generate);
|
||||
generate --> model_manager;
|
||||
generate --> generators;
|
||||
generate --> ti_manager[TI Manager];
|
||||
generate --> etc;
|
||||
txt2img_node --> model_manager;
|
||||
txt2img_node --> generators;
|
||||
txt2img_node --> ti_manager[TI Manager];
|
||||
```
|
||||
|
||||
## Final Architecture
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
web[WebUI];
|
||||
cli[CLI];
|
||||
web --> |img2img|img2img_node(img2img node);
|
||||
cli --> |img2img|img2img_node;
|
||||
web --> |txt2img|txt2img_node(txt2img node);
|
||||
cli --> |txt2img|txt2img_node;
|
||||
img2img_node --> model_manager;
|
||||
txt2img_node --> model_manager;
|
||||
img2img_node --> generators;
|
||||
txt2img_node --> generators;
|
||||
img2img_node --> ti_manager[TI Manager];
|
||||
txt2img_node --> ti_manager[TI Manager];
|
||||
```
|
16
docs/help/contributing/index.md
Normal file
16
docs/help/contributing/index.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
title: Contributing
|
||||
---
|
||||
|
||||
# :fontawesome-solid-code-commit: Contributing
|
||||
|
||||
There are different ways how you can contribute to
|
||||
[InvokeAI](https://github.com/invoke-ai/InvokeAI), like Translations, opening
|
||||
Issues for Bugs or ideas how to improve.
|
||||
|
||||
This Section of the docs will explain some of the different ways of how you can
|
||||
contribute to make it easier for newcommers as well as advanced users :nerd:
|
||||
|
||||
If you want to contribute code, but you do not have an exact idea yet, take a
|
||||
look at the currently open
|
||||
[:fontawesome-solid-bug: Bug Reports](https://github.com/invoke-ai/InvokeAI/issues?q=is%3Aissue+is%3Aopen+label%3Abug)
|
12
docs/help/index.md
Normal file
12
docs/help/index.md
Normal file
@ -0,0 +1,12 @@
|
||||
# :material-help:Help
|
||||
|
||||
If you are looking for help with the installation of InvokeAI, please take a
|
||||
look into the [Installation](../installation/index.md) section of the docs.
|
||||
|
||||
Here you will find help to topics like
|
||||
|
||||
- how to contribute
|
||||
- configuration recommendation for IDEs
|
||||
|
||||
If you have an Idea about what's missing and aren't scared from contributing,
|
||||
just take a look at [DOCS](./contributing/030_DOCS.md) to find out how to do so.
|
456
docs/index.md
456
docs/index.md
@ -2,6 +2,8 @@
|
||||
title: Home
|
||||
---
|
||||
|
||||
# :octicons-home-16: Home
|
||||
|
||||
<!--
|
||||
The Docs you find here (/docs/*) are built and deployed via mkdocs. If you want to run a local version to verify your changes, it's as simple as::
|
||||
|
||||
@ -29,36 +31,36 @@ title: Home
|
||||
[![github open prs badge]][github open prs link]
|
||||
|
||||
[ci checks on dev badge]:
|
||||
https://flat.badgen.net/github/checks/invoke-ai/InvokeAI/development?label=CI%20status%20on%20dev&cache=900&icon=github
|
||||
https://flat.badgen.net/github/checks/invoke-ai/InvokeAI/development?label=CI%20status%20on%20dev&cache=900&icon=github
|
||||
[ci checks on dev link]:
|
||||
https://github.com/invoke-ai/InvokeAI/actions?query=branch%3Adevelopment
|
||||
https://github.com/invoke-ai/InvokeAI/actions?query=branch%3Adevelopment
|
||||
[ci checks on main badge]:
|
||||
https://flat.badgen.net/github/checks/invoke-ai/InvokeAI/main?label=CI%20status%20on%20main&cache=900&icon=github
|
||||
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/workflows/test-invoke-conda.yml
|
||||
https://github.com/invoke-ai/InvokeAI/actions/workflows/test-invoke-conda.yml
|
||||
[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
|
||||
https://flat.badgen.net/github/forks/invoke-ai/InvokeAI?icon=github
|
||||
[github forks link]:
|
||||
https://useful-forks.github.io/?repo=lstein%2Fstable-diffusion
|
||||
https://useful-forks.github.io/?repo=lstein%2Fstable-diffusion
|
||||
[github open issues badge]:
|
||||
https://flat.badgen.net/github/open-issues/invoke-ai/InvokeAI?icon=github
|
||||
https://flat.badgen.net/github/open-issues/invoke-ai/InvokeAI?icon=github
|
||||
[github open issues link]:
|
||||
https://github.com/invoke-ai/InvokeAI/issues?q=is%3Aissue+is%3Aopen
|
||||
https://github.com/invoke-ai/InvokeAI/issues?q=is%3Aissue+is%3Aopen
|
||||
[github open prs badge]:
|
||||
https://flat.badgen.net/github/open-prs/invoke-ai/InvokeAI?icon=github
|
||||
https://flat.badgen.net/github/open-prs/invoke-ai/InvokeAI?icon=github
|
||||
[github open prs link]:
|
||||
https://github.com/invoke-ai/InvokeAI/pulls?q=is%3Apr+is%3Aopen
|
||||
https://github.com/invoke-ai/InvokeAI/pulls?q=is%3Apr+is%3Aopen
|
||||
[github stars badge]:
|
||||
https://flat.badgen.net/github/stars/invoke-ai/InvokeAI?icon=github
|
||||
https://flat.badgen.net/github/stars/invoke-ai/InvokeAI?icon=github
|
||||
[github stars link]: https://github.com/invoke-ai/InvokeAI/stargazers
|
||||
[latest commit to dev badge]:
|
||||
https://flat.badgen.net/github/last-commit/invoke-ai/InvokeAI/development?icon=github&color=yellow&label=last%20dev%20commit&cache=900
|
||||
https://flat.badgen.net/github/last-commit/invoke-ai/InvokeAI/development?icon=github&color=yellow&label=last%20dev%20commit&cache=900
|
||||
[latest commit to dev link]:
|
||||
https://github.com/invoke-ai/InvokeAI/commits/development
|
||||
https://github.com/invoke-ai/InvokeAI/commits/development
|
||||
[latest release badge]:
|
||||
https://flat.badgen.net/github/release/invoke-ai/InvokeAI/development?icon=github
|
||||
https://flat.badgen.net/github/release/invoke-ai/InvokeAI/development?icon=github
|
||||
[latest release link]: https://github.com/invoke-ai/InvokeAI/releases
|
||||
|
||||
</div>
|
||||
@ -87,24 +89,24 @@ Q&A</a>]
|
||||
|
||||
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.
|
||||
- :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.
|
||||
|
||||
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
|
||||
- NVIDIA 10xx series cards such as the 1080ti
|
||||
- GTX 1650 series cards
|
||||
- GTX 1660 series cards
|
||||
|
||||
### :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.
|
||||
- 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.
|
||||
|
||||
## :octicons-package-dependencies-24: Installation
|
||||
|
||||
@ -113,133 +115,407 @@ either an Nvidia-based card (with CUDA support) or an AMD card (using the ROCm
|
||||
driver).
|
||||
|
||||
### [Installation Getting Started Guide](installation)
|
||||
|
||||
#### [Automated Installer](installation/010_INSTALL_AUTOMATED.md)
|
||||
|
||||
This method is recommended for 1st time users
|
||||
|
||||
#### [Manual Installation](installation/020_INSTALL_MANUAL.md)
|
||||
|
||||
This method is recommended for experienced users and developers
|
||||
|
||||
#### [Docker Installation](installation/040_INSTALL_DOCKER.md)
|
||||
|
||||
This method is recommended for those familiar with running Docker containers
|
||||
|
||||
### Other Installation Guides
|
||||
- [PyPatchMatch](installation/060_INSTALL_PATCHMATCH.md)
|
||||
- [XFormers](installation/070_INSTALL_XFORMERS.md)
|
||||
- [CUDA and ROCm Drivers](installation/030_INSTALL_CUDA_AND_ROCM.md)
|
||||
- [Installing New Models](installation/050_INSTALLING_MODELS.md)
|
||||
|
||||
- [PyPatchMatch](installation/060_INSTALL_PATCHMATCH.md)
|
||||
- [XFormers](installation/070_INSTALL_XFORMERS.md)
|
||||
- [CUDA and ROCm Drivers](installation/030_INSTALL_CUDA_AND_ROCM.md)
|
||||
- [Installing New Models](installation/050_INSTALLING_MODELS.md)
|
||||
|
||||
## :octicons-gift-24: InvokeAI Features
|
||||
|
||||
### The InvokeAI Web Interface
|
||||
- [WebUI overview](features/WEB.md)
|
||||
- [WebUI hotkey reference guide](features/WEBUIHOTKEYS.md)
|
||||
- [WebUI Unified Canvas for Img2Img, inpainting and outpainting](features/UNIFIED_CANVAS.md)
|
||||
<!-- separator -->
|
||||
### The InvokeAI Command Line Interface
|
||||
- [Command Line Interace Reference Guide](features/CLI.md)
|
||||
<!-- separator -->
|
||||
### Image Management
|
||||
- [Image2Image](features/IMG2IMG.md)
|
||||
- [Inpainting](features/INPAINTING.md)
|
||||
- [Outpainting](features/OUTPAINTING.md)
|
||||
- [Adding custom styles and subjects](features/CONCEPTS.md)
|
||||
- [Upscaling and Face Reconstruction](features/POSTPROCESS.md)
|
||||
- [Embiggen upscaling](features/EMBIGGEN.md)
|
||||
- [Other Features](features/OTHER.md)
|
||||
|
||||
- [WebUI overview](features/WEB.md)
|
||||
- [WebUI hotkey reference guide](features/WEBUIHOTKEYS.md)
|
||||
- [WebUI Unified Canvas for Img2Img, inpainting and outpainting](features/UNIFIED_CANVAS.md)
|
||||
- [Visual Manual for InvokeAI v2.3.1](https://docs.google.com/presentation/d/e/2PACX-1vSE90aC7bVVg0d9KXVMhy-Wve-wModgPFp7AGVTOCgf4xE03SnV24mjdwldolfCr59D_35oheHe4Cow/pub?start=false&loop=true&delayms=60000) (contributed by Statcomm)
|
||||
|
||||
<!-- separator -->
|
||||
|
||||
<!-- separator -->
|
||||
|
||||
### The InvokeAI Command Line Interface
|
||||
|
||||
- [Command Line Interace Reference Guide](features/CLI.md)
|
||||
<!-- separator -->
|
||||
|
||||
### Image Management
|
||||
|
||||
- [Image2Image](features/IMG2IMG.md)
|
||||
- [Inpainting](features/INPAINTING.md)
|
||||
- [Outpainting](features/OUTPAINTING.md)
|
||||
- [Adding custom styles and subjects](features/CONCEPTS.md)
|
||||
- [Using LoRA models](features/LORAS.md)
|
||||
- [Upscaling and Face Reconstruction](features/POSTPROCESS.md)
|
||||
- [Embiggen upscaling](features/EMBIGGEN.md)
|
||||
- [Other Features](features/OTHER.md)
|
||||
|
||||
<!-- separator -->
|
||||
|
||||
### Model Management
|
||||
- [Installing](installation/050_INSTALLING_MODELS.md)
|
||||
- [Model Merging](features/MODEL_MERGING.md)
|
||||
- [Style/Subject Concepts and Embeddings](features/CONCEPTS.md)
|
||||
- [Textual Inversion](features/TEXTUAL_INVERSION.md)
|
||||
- [Not Safe for Work (NSFW) Checker](features/NSFW.md)
|
||||
|
||||
- [Installing](installation/050_INSTALLING_MODELS.md)
|
||||
- [Model Merging](features/MODEL_MERGING.md)
|
||||
- [Adding custom styles and subjects via embeddings](features/CONCEPTS.md)
|
||||
- [Textual Inversion](features/TEXTUAL_INVERSION.md)
|
||||
- [Not Safe for Work (NSFW) Checker](features/NSFW.md)
|
||||
<!-- seperator -->
|
||||
|
||||
### Prompt Engineering
|
||||
- [Prompt Syntax](features/PROMPTS.md)
|
||||
- [Generating Variations](features/VARIATIONS.md)
|
||||
|
||||
- [Prompt Syntax](features/PROMPTS.md)
|
||||
- [Generating Variations](features/VARIATIONS.md)
|
||||
|
||||
## :octicons-log-16: Latest Changes
|
||||
|
||||
### v2.3.3 <small>(29 March 2023)</small>
|
||||
|
||||
#### Bug Fixes
|
||||
1. When using legacy checkpoints with an external VAE, the VAE file is now scanned for malware prior to loading. Previously only the main model weights file was scanned.
|
||||
2. Textual inversion will select an appropriate batchsize based on whether `xformers` is active, and will default to `xformers` enabled if the library is detected.
|
||||
3. The batch script log file names have been fixed to be compatible with Windows.
|
||||
4. Occasional corruption of the `.next_prefix` file (which stores the next output file name in sequence) on Windows systems is now detected and corrected.
|
||||
5. An infinite loop when opening the developer's console from within the `invoke.sh` script has been corrected.
|
||||
|
||||
#### Enhancements
|
||||
1. It is now possible to load and run several community-contributed SD-2.0 based models, including the infamous "Illuminati" model.
|
||||
2. The "NegativePrompts" embedding file, and others like it, can now be loaded by placing it in the InvokeAI `embeddings` directory.
|
||||
3. If no `--model` is specified at launch time, InvokeAI will remember the last model used and restore it the next time it is launched.
|
||||
4. On Linux systems, the `invoke.sh` launcher now uses a prettier console-based interface. To take advantage of it, install the `dialog` package using your package manager (e.g. `sudo apt install dialog`).
|
||||
5. When loading legacy models (safetensors/ckpt) you can specify a custom config file and/or a VAE by placing like-named files in the same directory as the model following this example:
|
||||
```
|
||||
my-favorite-model.ckpt
|
||||
my-favorite-model.yaml
|
||||
my-favorite-model.vae.pt # or my-favorite-model.vae.safetensors
|
||||
```
|
||||
|
||||
### v2.3.2 <small>(13 March 2023)</small>
|
||||
|
||||
#### Bugfixes
|
||||
|
||||
Since version 2.3.1 the following bugs have been fixed:
|
||||
|
||||
1. Black images appearing for potential NSFW images when generating with legacy checkpoint models and both `--no-nsfw_checker` and `--ckpt_convert` turned on.
|
||||
2. Black images appearing when generating from models fine-tuned on Stable-Diffusion-2-1-base. When importing V2-derived models, you may be asked to select whether the model was derived from a "base" model (512 pixels) or the 768-pixel SD-2.1 model.
|
||||
3. The "Use All" button was not restoring the Hi-Res Fix setting on the WebUI
|
||||
4. When using the model installer console app, models failed to import correctly when importing from directories with spaces in their names. A similar issue with the output directory was also fixed.
|
||||
5. Crashes that occurred during model merging.
|
||||
6. Restore previous naming of Stable Diffusion base and 768 models.
|
||||
7. Upgraded to latest versions of `diffusers`, `transformers`, `safetensors` and `accelerate` libraries upstream. We hope that this will fix the `assertion NDArray > 2**32` issue that MacOS users have had when generating images larger than 768x768 pixels. Please report back.
|
||||
|
||||
As part of the upgrade to `diffusers`, the location of the diffusers-based models has changed from `models/diffusers` to `models/hub`. When you launch InvokeAI for the first time, it will prompt you to OK a one-time move. This should be quick and harmless, but if you have modified your `models/diffusers` directory in some way, for example using symlinks, you may wish to cancel the migration and make appropriate adjustments.
|
||||
|
||||
#### New "Invokeai-batch" script
|
||||
|
||||
2.3.2 introduces a new command-line only script called
|
||||
`invokeai-batch` that can be used to generate hundreds of images from
|
||||
prompts and settings that vary systematically. This can be used to try
|
||||
the same prompt across multiple combinations of models, steps, CFG
|
||||
settings and so forth. It also allows you to template prompts and
|
||||
generate a combinatorial list like: ``` a shack in the mountains,
|
||||
photograph a shack in the mountains, watercolor a shack in the
|
||||
mountains, oil painting a chalet in the mountains, photograph a chalet
|
||||
in the mountains, watercolor a chalet in the mountains, oil painting a
|
||||
shack in the desert, photograph ... ```
|
||||
|
||||
If you have a system with multiple GPUs, or a single GPU with lots of
|
||||
VRAM, you can parallelize generation across the combinatorial set,
|
||||
reducing wait times and using your system's resources efficiently
|
||||
(make sure you have good GPU cooling).
|
||||
|
||||
To try `invokeai-batch` out. Launch the "developer's console" using
|
||||
the `invoke` launcher script, or activate the invokeai virtual
|
||||
environment manually. From the console, give the command
|
||||
`invokeai-batch --help` in order to learn how the script works and
|
||||
create your first template file for dynamic prompt generation.
|
||||
|
||||
### v2.3.1 <small>(26 February 2023)</small>
|
||||
|
||||
This is primarily a bugfix release, but it does provide several new features that will improve the user experience.
|
||||
|
||||
#### Enhanced support for model management
|
||||
|
||||
InvokeAI now makes it convenient to add, remove and modify models. You can individually import models that are stored on your local system, scan an entire folder and its subfolders for models and import them automatically, and even directly import models from the internet by providing their download URLs. You also have the option of designating a local folder to scan for new models each time InvokeAI is restarted.
|
||||
|
||||
There are three ways of accessing the model management features:
|
||||
|
||||
1. ***From the WebUI***, click on the cube to the right of the model selection menu. This will bring up a form that allows you to import models individually from your local disk or scan a directory for models to import.
|
||||
|
||||

|
||||
|
||||
2. **Using the Model Installer App**
|
||||
|
||||
Choose option (5) _download and install models_ from the `invoke` launcher script to start a new console-based application for model management. You can use this to select from a curated set of starter models, or import checkpoint, safetensors, and diffusers models from a local disk or the internet. The example below shows importing two checkpoint URLs from popular SD sites and a HuggingFace diffusers model using its Repository ID. It also shows how to designate a folder to be scanned at startup time for new models to import.
|
||||
|
||||
Command-line users can start this app using the command `invokeai-model-install`.
|
||||
|
||||

|
||||
|
||||
3. **Using the Command Line Client (CLI)**
|
||||
|
||||
The `!install_model` and `!convert_model` commands have been enhanced to allow entering of URLs and local directories to scan and import. The first command installs .ckpt and .safetensors files as-is. The second one converts them into the faster diffusers format before installation.
|
||||
|
||||
Internally InvokeAI is able to probe the contents of a .ckpt or .safetensors file to distinguish among v1.x, v2.x and inpainting models. This means that you do **not** need to include "inpaint" in your model names to use an inpainting model. Note that Stable Diffusion v2.x models will be autoconverted into a diffusers model the first time you use it.
|
||||
|
||||
Please see [INSTALLING MODELS](https://invoke-ai.github.io/InvokeAI/installation/050_INSTALLING_MODELS/) for more information on model management.
|
||||
|
||||
#### An Improved Installer Experience
|
||||
|
||||
The installer now launches a console-based UI for setting and changing commonly-used startup options:
|
||||
|
||||

|
||||
|
||||
After selecting the desired options, the installer installs several support models needed by InvokeAI's face reconstruction and upscaling features and then launches the interface for selecting and installing models shown earlier. At any time, you can edit the startup options by launching `invoke.sh`/`invoke.bat` and entering option (6) _change InvokeAI startup options_
|
||||
|
||||
Command-line users can launch the new configure app using `invokeai-configure`.
|
||||
|
||||
This release also comes with a renewed updater. To do an update without going through a whole reinstallation, launch `invoke.sh` or `invoke.bat` and choose option (9) _update InvokeAI_ . This will bring you to a screen that prompts you to update to the latest released version, to the most current development version, or any released or unreleased version you choose by selecting the tag or branch of the desired version.
|
||||
|
||||

|
||||
|
||||
Command-line users can run this interface by typing `invokeai-configure`
|
||||
|
||||
#### Image Symmetry Options
|
||||
|
||||
There are now features to generate horizontal and vertical symmetry during generation. The way these work is to wait until a selected step in the generation process and then to turn on a mirror image effect. In addition to generating some cool images, you can also use this to make side-by-side comparisons of how an image will look with more or fewer steps. Access this option from the WebUI by selecting _Symmetry_ from the image generation settings, or within the CLI by using the options `--h_symmetry_time_pct` and `--v_symmetry_time_pct` (these can be abbreviated to `--h_sym` and `--v_sym` like all other options).
|
||||
|
||||

|
||||
|
||||
#### A New Unified Canvas Look
|
||||
|
||||
This release introduces a beta version of the WebUI Unified Canvas. To try it out, open up the settings dialogue in the WebUI (gear icon) and select _Use Canvas Beta Layout_:
|
||||
|
||||

|
||||
|
||||
Refresh the screen and go to to Unified Canvas (left side of screen, third icon from the top). The new layout is designed to provide more space to work in and to keep the image controls close to the image itself:
|
||||
|
||||

|
||||
|
||||
#### Model conversion and merging within the WebUI
|
||||
|
||||
The WebUI now has an intuitive interface for model merging, as well as for permanent conversion of models from legacy .ckpt/.safetensors formats into diffusers format. These options are also available directly from the `invoke.sh`/`invoke.bat` scripts.
|
||||
|
||||
#### An easier way to contribute translations to the WebUI
|
||||
|
||||
We have migrated our translation efforts to [Weblate](https://hosted.weblate.org/engage/invokeai/), a FOSS translation product. Maintaining the growing project's translations is now far simpler for the maintainers and community. Please review our brief [translation guide](https://github.com/invoke-ai/InvokeAI/blob/v2.3.1/docs/other/TRANSLATION.md) for more information on how to contribute.
|
||||
|
||||
#### Numerous internal bugfixes and performance issues
|
||||
|
||||
This releases quashes multiple bugs that were reported in 2.3.0. Major internal changes include upgrading to `diffusers 0.13.0`, and using the `compel` library for prompt parsing. See [Detailed Change Log](#full-change-log) for a detailed list of bugs caught and squished.
|
||||
|
||||
#### Summary of InvokeAI command line scripts (all accessible via the launcher menu)
|
||||
|
||||
| Command | Description |
|
||||
|--------------------------|---------------------------------------------------------------------|
|
||||
| `invokeai` | Command line interface |
|
||||
| `invokeai --web` | Web interface |
|
||||
| `invokeai-model-install` | Model installer with console forms-based front end |
|
||||
| `invokeai-ti --gui` | Textual inversion, with a console forms-based front end |
|
||||
| `invokeai-merge --gui` | Model merging, with a console forms-based front end |
|
||||
| `invokeai-configure` | Startup configuration; can also be used to reinstall support models |
|
||||
| `invokeai-update` | InvokeAI software updater |
|
||||
|
||||
|
||||
### v2.3.0 <small>(9 February 2023)</small>
|
||||
|
||||
#### Migration to Stable Diffusion `diffusers` models
|
||||
|
||||
Previous versions of InvokeAI supported the original model file format introduced with Stable Diffusion 1.4. In the original format, known variously as "checkpoint", or "legacy" format, there is a single large weights file ending with `.ckpt` or `.safetensors`. Though this format has served the community well, it has a number of disadvantages, including file size, slow loading times, and a variety of non-standard variants that require special-case code to handle. In addition, because checkpoint files are actually a bundle of multiple machine learning sub-models, it is hard to swap different sub-models in and out, or to share common sub-models. A new format, introduced by the StabilityAI company in collaboration with HuggingFace, is called `diffusers` and consists of a directory of individual models. The most immediate benefit of `diffusers` is that they load from disk very quickly. A longer term benefit is that in the near future `diffusers` models will be able to share common sub-models, dramatically reducing disk space when you have multiple fine-tune models derived from the same base.
|
||||
Previous versions of InvokeAI supported the original model file format
|
||||
introduced with Stable Diffusion 1.4. In the original format, known variously as
|
||||
"checkpoint", or "legacy" format, there is a single large weights file ending
|
||||
with `.ckpt` or `.safetensors`. Though this format has served the community
|
||||
well, it has a number of disadvantages, including file size, slow loading times,
|
||||
and a variety of non-standard variants that require special-case code to handle.
|
||||
In addition, because checkpoint files are actually a bundle of multiple machine
|
||||
learning sub-models, it is hard to swap different sub-models in and out, or to
|
||||
share common sub-models. A new format, introduced by the StabilityAI company in
|
||||
collaboration with HuggingFace, is called `diffusers` and consists of a
|
||||
directory of individual models. The most immediate benefit of `diffusers` is
|
||||
that they load from disk very quickly. A longer term benefit is that in the near
|
||||
future `diffusers` models will be able to share common sub-models, dramatically
|
||||
reducing disk space when you have multiple fine-tune models derived from the
|
||||
same base.
|
||||
|
||||
When you perform a new install of version 2.3.0, you will be offered the option to install the `diffusers` versions of a number of popular SD models, including Stable Diffusion versions 1.5 and 2.1 (including the 768x768 pixel version of 2.1). These will act and work just like the checkpoint versions. Do not be concerned if you already have a lot of ".ckpt" or ".safetensors" models on disk! InvokeAI 2.3.0 can still load these and generate images from them without any extra intervention on your part.
|
||||
When you perform a new install of version 2.3.0, you will be offered the option
|
||||
to install the `diffusers` versions of a number of popular SD models, including
|
||||
Stable Diffusion versions 1.5 and 2.1 (including the 768x768 pixel version of
|
||||
2.1). These will act and work just like the checkpoint versions. Do not be
|
||||
concerned if you already have a lot of ".ckpt" or ".safetensors" models on disk!
|
||||
InvokeAI 2.3.0 can still load these and generate images from them without any
|
||||
extra intervention on your part.
|
||||
|
||||
To take advantage of the optimized loading times of `diffusers` models, InvokeAI offers options to convert legacy checkpoint models into optimized `diffusers` models. If you use the `invokeai` command line interface, the relevant commands are:
|
||||
To take advantage of the optimized loading times of `diffusers` models, InvokeAI
|
||||
offers options to convert legacy checkpoint models into optimized `diffusers`
|
||||
models. If you use the `invokeai` command line interface, the relevant commands
|
||||
are:
|
||||
|
||||
* `!convert_model` -- Take the path to a local checkpoint file or a URL that is pointing to one, convert it into a `diffusers` model, and import it into InvokeAI's models registry file.
|
||||
* `!optimize_model` -- If you already have a checkpoint model in your InvokeAI models file, this command will accept its short name and convert it into a like-named `diffusers` model, optionally deleting the original checkpoint file.
|
||||
* `!import_model` -- Take the local path of either a checkpoint file or a `diffusers` model directory and import it into InvokeAI's registry file. You may also provide the ID of any diffusers model that has been published on the [HuggingFace models repository](https://huggingface.co/models?pipeline_tag=text-to-image&sort=downloads) and it will be downloaded and installed automatically.
|
||||
- `!convert_model` -- Take the path to a local checkpoint file or a URL that
|
||||
is pointing to one, convert it into a `diffusers` model, and import it into
|
||||
InvokeAI's models registry file.
|
||||
- `!optimize_model` -- If you already have a checkpoint model in your InvokeAI
|
||||
models file, this command will accept its short name and convert it into a
|
||||
like-named `diffusers` model, optionally deleting the original checkpoint
|
||||
file.
|
||||
- `!import_model` -- Take the local path of either a checkpoint file or a
|
||||
`diffusers` model directory and import it into InvokeAI's registry file. You
|
||||
may also provide the ID of any diffusers model that has been published on
|
||||
the
|
||||
[HuggingFace models repository](https://huggingface.co/models?pipeline_tag=text-to-image&sort=downloads)
|
||||
and it will be downloaded and installed automatically.
|
||||
|
||||
The WebGUI offers similar functionality for model management.
|
||||
|
||||
For advanced users, new command-line options provide additional functionality. Launching `invokeai` with the argument `--autoconvert <path to directory>` takes the path to a directory of checkpoint files, automatically converts them into `diffusers` models and imports them. Each time the script is launched, the directory will be scanned for new checkpoint files to be loaded. Alternatively, the `--ckpt_convert` argument will cause any checkpoint or safetensors model that is already registered with InvokeAI to be converted into a `diffusers` model on the fly, allowing you to take advantage of future diffusers-only features without explicitly converting the model and saving it to disk.
|
||||
For advanced users, new command-line options provide additional functionality.
|
||||
Launching `invokeai` with the argument `--autoconvert <path to directory>` takes
|
||||
the path to a directory of checkpoint files, automatically converts them into
|
||||
`diffusers` models and imports them. Each time the script is launched, the
|
||||
directory will be scanned for new checkpoint files to be loaded. Alternatively,
|
||||
the `--ckpt_convert` argument will cause any checkpoint or safetensors model
|
||||
that is already registered with InvokeAI to be converted into a `diffusers`
|
||||
model on the fly, allowing you to take advantage of future diffusers-only
|
||||
features without explicitly converting the model and saving it to disk.
|
||||
|
||||
Please see [INSTALLING MODELS](https://invoke-ai.github.io/InvokeAI/installation/050_INSTALLING_MODELS/) for more information on model management in both the command-line and Web interfaces.
|
||||
Please see
|
||||
[INSTALLING MODELS](https://invoke-ai.github.io/InvokeAI/installation/050_INSTALLING_MODELS/)
|
||||
for more information on model management in both the command-line and Web
|
||||
interfaces.
|
||||
|
||||
#### Support for the `XFormers` Memory-Efficient Crossattention Package
|
||||
|
||||
On CUDA (Nvidia) systems, version 2.3.0 supports the `XFormers` library. Once installed, the`xformers` package dramatically reduces the memory footprint of loaded Stable Diffusion models files and modestly increases image generation speed. `xformers` will be installed and activated automatically if you specify a CUDA system at install time.
|
||||
On CUDA (Nvidia) systems, version 2.3.0 supports the `XFormers` library. Once
|
||||
installed, the`xformers` package dramatically reduces the memory footprint of
|
||||
loaded Stable Diffusion models files and modestly increases image generation
|
||||
speed. `xformers` will be installed and activated automatically if you specify a
|
||||
CUDA system at install time.
|
||||
|
||||
The caveat with using `xformers` is that it introduces slightly non-deterministic behavior, and images generated using the same seed and other settings will be subtly different between invocations. Generally the changes are unnoticeable unless you rapidly shift back and forth between images, but to disable `xformers` and restore fully deterministic behavior, you may launch InvokeAI using the `--no-xformers` option. This is most conveniently done by opening the file `invokeai/invokeai.init` with a text editor, and adding the line `--no-xformers` at the bottom.
|
||||
The caveat with using `xformers` is that it introduces slightly
|
||||
non-deterministic behavior, and images generated using the same seed and other
|
||||
settings will be subtly different between invocations. Generally the changes are
|
||||
unnoticeable unless you rapidly shift back and forth between images, but to
|
||||
disable `xformers` and restore fully deterministic behavior, you may launch
|
||||
InvokeAI using the `--no-xformers` option. This is most conveniently done by
|
||||
opening the file `invokeai/invokeai.init` with a text editor, and adding the
|
||||
line `--no-xformers` at the bottom.
|
||||
|
||||
#### A Negative Prompt Box in the WebUI
|
||||
|
||||
There is now a separate text input box for negative prompts in the WebUI. This is convenient for stashing frequently-used negative prompts ("mangled limbs, bad anatomy"). The `[negative prompt]` syntax continues to work in the main prompt box as well.
|
||||
There is now a separate text input box for negative prompts in the WebUI. This
|
||||
is convenient for stashing frequently-used negative prompts ("mangled limbs, bad
|
||||
anatomy"). The `[negative prompt]` syntax continues to work in the main prompt
|
||||
box as well.
|
||||
|
||||
To see exactly how your prompts are being parsed, launch `invokeai` with the `--log_tokenization` option. The console window will then display the tokenization process for both positive and negative prompts.
|
||||
To see exactly how your prompts are being parsed, launch `invokeai` with the
|
||||
`--log_tokenization` option. The console window will then display the
|
||||
tokenization process for both positive and negative prompts.
|
||||
|
||||
#### Model Merging
|
||||
|
||||
Version 2.3.0 offers an intuitive user interface for merging up to three Stable Diffusion models using an intuitive user interface. Model merging allows you to mix the behavior of models to achieve very interesting effects. To use this, each of the models must already be imported into InvokeAI and saved in `diffusers` format, then launch the merger using a new menu item in the InvokeAI launcher script (`invoke.sh`, `invoke.bat`) or directly from the command line with `invokeai-merge --gui`. You will be prompted to select the models to merge, the proportions in which to mix them, and the mixing algorithm. The script will create a new merged `diffusers` model and import it into InvokeAI for your use.
|
||||
Version 2.3.0 offers an intuitive user interface for merging up to three Stable
|
||||
Diffusion models using an intuitive user interface. Model merging allows you to
|
||||
mix the behavior of models to achieve very interesting effects. To use this,
|
||||
each of the models must already be imported into InvokeAI and saved in
|
||||
`diffusers` format, then launch the merger using a new menu item in the InvokeAI
|
||||
launcher script (`invoke.sh`, `invoke.bat`) or directly from the command line
|
||||
with `invokeai-merge --gui`. You will be prompted to select the models to merge,
|
||||
the proportions in which to mix them, and the mixing algorithm. The script will
|
||||
create a new merged `diffusers` model and import it into InvokeAI for your use.
|
||||
|
||||
See [MODEL MERGING](https://invoke-ai.github.io/InvokeAI/features/MODEL_MERGING/) for more details.
|
||||
See
|
||||
[MODEL MERGING](https://invoke-ai.github.io/InvokeAI/features/MODEL_MERGING/)
|
||||
for more details.
|
||||
|
||||
#### Textual Inversion Training
|
||||
|
||||
Textual Inversion (TI) is a technique for training a Stable Diffusion model to emit a particular subject or style when triggered by a keyword phrase. You can perform TI training by placing a small number of images of the subject or style in a directory, and choosing a distinctive trigger phrase, such as "pointillist-style". After successful training, The subject or style will be activated by including `<pointillist-style>` in your prompt.
|
||||
Textual Inversion (TI) is a technique for training a Stable Diffusion model to
|
||||
emit a particular subject or style when triggered by a keyword phrase. You can
|
||||
perform TI training by placing a small number of images of the subject or style
|
||||
in a directory, and choosing a distinctive trigger phrase, such as
|
||||
"pointillist-style". After successful training, The subject or style will be
|
||||
activated by including `<pointillist-style>` in your prompt.
|
||||
|
||||
Previous versions of InvokeAI were able to perform TI, but it required using a command-line script with dozens of obscure command-line arguments. Version 2.3.0 features an intuitive TI frontend that will build a TI model on top of any `diffusers` model. To access training you can launch from a new item in the launcher script or from the command line using `invokeai-ti --gui`.
|
||||
Previous versions of InvokeAI were able to perform TI, but it required using a
|
||||
command-line script with dozens of obscure command-line arguments. Version 2.3.0
|
||||
features an intuitive TI frontend that will build a TI model on top of any
|
||||
`diffusers` model. To access training you can launch from a new item in the
|
||||
launcher script or from the command line using `invokeai-ti --gui`.
|
||||
|
||||
See [TEXTUAL INVERSION](https://invoke-ai.github.io/InvokeAI/features/TEXTUAL_INVERSION/) for further details.
|
||||
See
|
||||
[TEXTUAL INVERSION](https://invoke-ai.github.io/InvokeAI/features/TEXTUAL_INVERSION/)
|
||||
for further details.
|
||||
|
||||
#### A New Installer Experience
|
||||
|
||||
The InvokeAI installer has been upgraded in order to provide a smoother and hopefully more glitch-free experience. In addition, InvokeAI is now packaged as a PyPi project, allowing developers and power-users to install InvokeAI with the command `pip install InvokeAI --use-pep517`. Please see [Installation](#installation) for details.
|
||||
The InvokeAI installer has been upgraded in order to provide a smoother and
|
||||
hopefully more glitch-free experience. In addition, InvokeAI is now packaged as
|
||||
a PyPi project, allowing developers and power-users to install InvokeAI with the
|
||||
command `pip install InvokeAI --use-pep517`. Please see
|
||||
[Installation](#installation) for details.
|
||||
|
||||
Developers should be aware that the `pip` installation procedure has been simplified and that the `conda` method is no longer supported at all. Accordingly, the `environments_and_requirements` directory has been deleted from the repository.
|
||||
Developers should be aware that the `pip` installation procedure has been
|
||||
simplified and that the `conda` method is no longer supported at all.
|
||||
Accordingly, the `environments_and_requirements` directory has been deleted from
|
||||
the repository.
|
||||
|
||||
#### Command-line name changes
|
||||
|
||||
All of InvokeAI's functionality, including the WebUI, command-line interface, textual inversion training and model merging, can all be accessed from the `invoke.sh` and `invoke.bat` launcher scripts. The menu of options has been expanded to add the new functionality. For the convenience of developers and power users, we have normalized the names of the InvokeAI command-line scripts:
|
||||
All of InvokeAI's functionality, including the WebUI, command-line interface,
|
||||
textual inversion training and model merging, can all be accessed from the
|
||||
`invoke.sh` and `invoke.bat` launcher scripts. The menu of options has been
|
||||
expanded to add the new functionality. For the convenience of developers and
|
||||
power users, we have normalized the names of the InvokeAI command-line scripts:
|
||||
|
||||
* `invokeai` -- Command-line client
|
||||
* `invokeai --web` -- Web GUI
|
||||
* `invokeai-merge --gui` -- Model merging script with graphical front end
|
||||
* `invokeai-ti --gui` -- Textual inversion script with graphical front end
|
||||
* `invokeai-configure` -- Configuration tool for initializing the `invokeai` directory and selecting popular starter models.
|
||||
- `invokeai` -- Command-line client
|
||||
- `invokeai --web` -- Web GUI
|
||||
- `invokeai-merge --gui` -- Model merging script with graphical front end
|
||||
- `invokeai-ti --gui` -- Textual inversion script with graphical front end
|
||||
- `invokeai-configure` -- Configuration tool for initializing the `invokeai`
|
||||
directory and selecting popular starter models.
|
||||
|
||||
For backward compatibility, the old command names are also recognized, including `invoke.py` and `configure-invokeai.py`. However, these are deprecated and will eventually be removed.
|
||||
For backward compatibility, the old command names are also recognized, including
|
||||
`invoke.py` and `configure-invokeai.py`. However, these are deprecated and will
|
||||
eventually be removed.
|
||||
|
||||
Developers should be aware that the locations of the script's source code has been moved. The new locations are:
|
||||
* `invokeai` => `ldm/invoke/CLI.py`
|
||||
* `invokeai-configure` => `ldm/invoke/config/configure_invokeai.py`
|
||||
* `invokeai-ti`=> `ldm/invoke/training/textual_inversion.py`
|
||||
* `invokeai-merge` => `ldm/invoke/merge_diffusers`
|
||||
Developers should be aware that the locations of the script's source code has
|
||||
been moved. The new locations are:
|
||||
|
||||
Developers are strongly encouraged to perform an "editable" install of InvokeAI using `pip install -e . --use-pep517` in the Git repository, and then to call the scripts using their 2.3.0 names, rather than executing the scripts directly. Developers should also be aware that the several important data files have been relocated into a new directory named `invokeai`. This includes the WebGUI's `frontend` and `backend` directories, and the `INITIAL_MODELS.yaml` files used by the installer to select starter models. Eventually all InvokeAI modules will be in subdirectories of `invokeai`.
|
||||
- `invokeai` => `ldm/invoke/CLI.py`
|
||||
- `invokeai-configure` => `ldm/invoke/config/configure_invokeai.py`
|
||||
- `invokeai-ti`=> `ldm/invoke/training/textual_inversion.py`
|
||||
- `invokeai-merge` => `ldm/invoke/merge_diffusers`
|
||||
|
||||
Please see [2.3.0 Release Notes](https://github.com/invoke-ai/InvokeAI/releases/tag/v2.3.0) for further details.
|
||||
For older changelogs, please visit the
|
||||
Developers are strongly encouraged to perform an "editable" install of InvokeAI
|
||||
using `pip install -e . --use-pep517` in the Git repository, and then to call
|
||||
the scripts using their 2.3.0 names, rather than executing the scripts directly.
|
||||
Developers should also be aware that the several important data files have been
|
||||
relocated into a new directory named `invokeai`. This includes the WebGUI's
|
||||
`frontend` and `backend` directories, and the `INITIAL_MODELS.yaml` files used
|
||||
by the installer to select starter models. Eventually all InvokeAI modules will
|
||||
be in subdirectories of `invokeai`.
|
||||
|
||||
Please see
|
||||
[2.3.0 Release Notes](https://github.com/invoke-ai/InvokeAI/releases/tag/v2.3.0)
|
||||
for further details. For older changelogs, please visit the
|
||||
**[CHANGELOG](CHANGELOG/#v223-2-december-2022)**.
|
||||
|
||||
## :material-target: Troubleshooting
|
||||
|
||||
Please check out our **[:material-frequently-asked-questions:
|
||||
Troubleshooting
|
||||
Guide](installation/010_INSTALL_AUTOMATED.md#troubleshooting)** to
|
||||
get solutions for common installation problems and other issues.
|
||||
Please check out our
|
||||
**[:material-frequently-asked-questions: Troubleshooting Guide](installation/010_INSTALL_AUTOMATED.md#troubleshooting)**
|
||||
to get solutions for common installation problems and other issues.
|
||||
|
||||
## :octicons-repo-push-24: Contributing
|
||||
|
||||
@ -265,8 +541,8 @@ thank them for their time, hard work and effort.
|
||||
For support, please use this repository's GitHub Issues tracking service. Feel
|
||||
free to send me an email if you use and like the script.
|
||||
|
||||
Original portions of the software are Copyright (c) 2022-23
|
||||
by [The InvokeAI Team](https://github.com/invoke-ai).
|
||||
Original portions of the software are Copyright (c) 2022-23 by
|
||||
[The InvokeAI Team](https://github.com/invoke-ai).
|
||||
|
||||
## :octicons-book-24: Further Reading
|
||||
|
||||
|
@ -417,7 +417,7 @@ Then type the following commands:
|
||||
|
||||
=== "AMD System"
|
||||
```bash
|
||||
pip install torch torchvision --force-reinstall --extra-index-url https://download.pytorch.org/whl/rocm5.2
|
||||
pip install torch torchvision --force-reinstall --extra-index-url https://download.pytorch.org/whl/rocm5.4.2
|
||||
```
|
||||
|
||||
### Corrupted configuration file
|
||||
|
@ -77,7 +77,7 @@ machine. To test, open up a terminal window and issue the following
|
||||
command:
|
||||
|
||||
```
|
||||
rocm-smi
|
||||
rocminfo
|
||||
```
|
||||
|
||||
If you get a table labeled "ROCm System Management Interface" the
|
||||
@ -95,9 +95,17 @@ 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
|
||||
After installation, please run `rocminfo` 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.
|
||||
do a reboot in order to load the driver. In addition, if you see
|
||||
errors relating to your username not being a member of the `render`
|
||||
group, you may fix this by adding yourself to this group with the command:
|
||||
|
||||
```
|
||||
sudo usermod -a -G render myUserName
|
||||
```
|
||||
|
||||
(Thanks to @EgoringKosmos for the usermod recipe.)
|
||||
|
||||
### Linux Install with a ROCm-docker Container
|
||||
|
||||
@ -110,7 +118,7 @@ recipes are available
|
||||
|
||||
When installing torch and torchvision manually with `pip`, remember to provide
|
||||
the argument `--extra-index-url
|
||||
https://download.pytorch.org/whl/rocm5.2` as described in the [Manual
|
||||
https://download.pytorch.org/whl/rocm5.4.2` as described in the [Manual
|
||||
Installation Guide](020_INSTALL_MANUAL.md).
|
||||
|
||||
This will be done automatically for you if you use the installer
|
||||
|
@ -11,7 +11,7 @@ The model checkpoint files ('\*.ckpt') are the Stable Diffusion
|
||||
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
|
||||
which many people named `model.ckpt`. Now there are hundreds
|
||||
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
|
||||
@ -29,9 +29,10 @@ 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.
|
||||
|
||||
While InvokeAI will continue to support `.ckpt` and `.safetensors`
|
||||
While InvokeAI will continue to support legacy `.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.
|
||||
be withdrawn in version 3.0, after which all legacy models will be
|
||||
converted into diffusers at the time they are loaded.
|
||||
|
||||
This manual will guide you through installing and configuring model
|
||||
weight files and converting legacy `.ckpt` and `.safetensors` files
|
||||
@ -89,15 +90,18 @@ aware that CIVITAI hosts many models that generate NSFW content.
|
||||
!!! note
|
||||
|
||||
InvokeAI 2.3.x does not support directly importing and
|
||||
running Stable Diffusion version 2 checkpoint models. You may instead
|
||||
convert them into `diffusers` models using the conversion methods
|
||||
described below.
|
||||
running Stable Diffusion version 2 checkpoint models. If you
|
||||
try to import them, they will be automatically
|
||||
converted into `diffusers` models on the fly. This adds about 20s
|
||||
to loading time. To avoid this overhead, you are encouraged to
|
||||
use one of the conversion methods described below to convert them
|
||||
permanently.
|
||||
|
||||
## Installation
|
||||
|
||||
There are multiple ways to install and manage models:
|
||||
|
||||
1. The `invokeai-configure` script which will download and install them for you.
|
||||
1. The `invokeai-model-install` script which will download and install them for you.
|
||||
|
||||
2. The command-line tool (CLI) has commands that allows you to import, configure and modify
|
||||
models files.
|
||||
@ -105,14 +109,41 @@ There are multiple ways to install and manage models:
|
||||
3. The web interface (WebUI) has a GUI for importing and managing
|
||||
models.
|
||||
|
||||
### Installation via `invokeai-configure`
|
||||
### Installation via `invokeai-model-install`
|
||||
|
||||
From the `invoke` launcher, choose option (6) "re-run the configure
|
||||
script to download new 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.
|
||||
From the `invoke` launcher, choose option (5) "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.
|
||||
|
||||
This script allows you to load 3d party models. Look for a large text
|
||||
entry box labeled "IMPORT LOCAL AND REMOTE MODELS." In this box, you
|
||||
can cut and paste one or more of any of the following:
|
||||
|
||||
1. A URL that points to a downloadable .ckpt or .safetensors file.
|
||||
2. A file path pointing to a .ckpt or .safetensors file.
|
||||
3. A diffusers model repo_id (from HuggingFace) in the format
|
||||
"owner/repo_name".
|
||||
4. A directory path pointing to a diffusers model directory.
|
||||
5. A directory path pointing to a directory containing a bunch of
|
||||
.ckpt and .safetensors files. All will be imported.
|
||||
|
||||
You can enter multiple items into the textbox, each one on a separate
|
||||
line. You can paste into the textbox using ctrl-shift-V or by dragging
|
||||
and dropping a file/directory from the desktop into the box.
|
||||
|
||||
The script also lets you designate a directory that will be scanned
|
||||
for new model files each time InvokeAI starts up. These models will be
|
||||
added automatically.
|
||||
|
||||
Lastly, the script gives you a checkbox option to convert legacy models
|
||||
into diffusers, or to run the legacy model directly. If you choose to
|
||||
convert, the original .ckpt/.safetensors file will **not** be deleted,
|
||||
but a new diffusers directory will be created, using twice your disk
|
||||
space. However, the diffusers version will load faster, and will be
|
||||
compatible with InvokeAI 3.0.
|
||||
|
||||
### Installation via the CLI
|
||||
|
||||
@ -144,19 +175,15 @@ invoke> !import_model https://example.org/sd_models/martians.safetensors
|
||||
For this to work, the URL must not be password-protected. Otherwise
|
||||
you will receive a 404 error.
|
||||
|
||||
When you import a legacy model, the CLI will first ask you what type
|
||||
of model this is. You can indicate whether it is a model based on
|
||||
Stable Diffusion 1.x (1.4 or 1.5), one based on Stable Diffusion 2.x,
|
||||
or a 1.x inpainting model. Be careful to indicate the correct model
|
||||
type, or it will not load correctly. You can correct the model type
|
||||
after the fact using the `!edit_model` command.
|
||||
|
||||
The system will then ask you a few other questions about the model,
|
||||
including what size image it was trained on (usually 512x512), what
|
||||
name and description you wish to use for it, and whether you would
|
||||
like to install a custom VAE (variable autoencoder) file for the
|
||||
model. For recent models, the answer to the VAE question is usually
|
||||
"no," but it won't hurt to answer "yes".
|
||||
When you import a legacy model, the CLI will try to figure out what
|
||||
type of model it is and select the correct load configuration file.
|
||||
However, one thing it can't do is to distinguish between Stable
|
||||
Diffusion 2.x models trained on 512x512 vs 768x768 images. In this
|
||||
case, the CLI will pop up a menu of choices, asking you to select
|
||||
which type of model it is. Please consult the model documentation to
|
||||
identify the correct answer, as loading with the wrong configuration
|
||||
will lead to black images. You can correct the model type after the
|
||||
fact using the `!edit_model` command.
|
||||
|
||||
After importing, the model will load. If this is successful, you will
|
||||
be asked if you want to keep the model loaded in memory to start
|
||||
@ -211,109 +238,6 @@ description for the model, whether to make this the default model that
|
||||
is loaded at InvokeAI startup time, and whether to replace its
|
||||
VAE. Generally the answer to the latter question is "no".
|
||||
|
||||
### Converting legacy models into `diffusers`
|
||||
|
||||
The CLI `!convert_model` will convert a `.safetensors` or `.ckpt`
|
||||
models file into `diffusers` and install it.This will enable the model
|
||||
to load and run faster without loss of image quality.
|
||||
|
||||
The usage is identical to `!import_model`. You may point the command
|
||||
to either a downloaded model file on disk, or to a (non-password
|
||||
protected) URL:
|
||||
|
||||
```bash
|
||||
invoke> !convert_model C:/Users/fred/Downloads/martians.safetensors
|
||||
```
|
||||
|
||||
After a successful conversion, the CLI will offer you the option of
|
||||
deleting the original `.ckpt` or `.safetensors` file.
|
||||
|
||||
### Optimizing a previously-installed model
|
||||
|
||||
Lastly, if you have previously installed a `.ckpt` or `.safetensors`
|
||||
file and wish to convert it into a `diffusers` model, you can do this
|
||||
without re-downloading and converting the original file using the
|
||||
`!optimize_model` command. Simply pass the short name of an existing
|
||||
installed model:
|
||||
|
||||
```bash
|
||||
invoke> !optimize_model martians-v1.0
|
||||
```
|
||||
|
||||
The model will be converted into `diffusers` format and replace the
|
||||
previously installed version. You will again be offered the
|
||||
opportunity to delete the original `.ckpt` or `.safetensors` file.
|
||||
|
||||
### Related CLI Commands
|
||||
|
||||
There are a whole series of additional model management commands in
|
||||
the CLI that you can read about in [Command-Line
|
||||
Interface](../features/CLI.md). These include:
|
||||
|
||||
* `!models` - List all installed models
|
||||
* `!switch <model name>` - Switch to the indicated model
|
||||
* `!edit_model <model name>` - Edit the indicated model to change its name, description or other properties
|
||||
* `!del_model <model name>` - Delete the indicated model
|
||||
|
||||
### Manually editing `configs/models.yaml`
|
||||
|
||||
|
||||
If you are comfortable with a text editor then you may simply edit `models.yaml`
|
||||
directly.
|
||||
|
||||
You will need to download the desired `.ckpt/.safetensors` file and
|
||||
place it somewhere on your machine's filesystem. Alternatively, for a
|
||||
`diffusers` model, record the repo_id or download the whole model
|
||||
directory. Then using a **text** editor (e.g. the Windows Notepad
|
||||
application), open the file `configs/models.yaml`, and add a new
|
||||
stanza that follows this model:
|
||||
|
||||
#### A legacy model
|
||||
|
||||
A legacy `.ckpt` or `.safetensors` entry will look like this:
|
||||
|
||||
```yaml
|
||||
arabian-nights-1.0:
|
||||
description: A great fine-tune in Arabian Nights style
|
||||
weights: ./path/to/arabian-nights-1.0.ckpt
|
||||
config: ./configs/stable-diffusion/v1-inference.yaml
|
||||
format: ckpt
|
||||
width: 512
|
||||
height: 512
|
||||
default: false
|
||||
```
|
||||
|
||||
Note that `format` is `ckpt` for both `.ckpt` and `.safetensors` files.
|
||||
|
||||
#### A diffusers model
|
||||
|
||||
A stanza for a `diffusers` model will look like this for a HuggingFace
|
||||
model with a repository ID:
|
||||
|
||||
```yaml
|
||||
arabian-nights-1.1:
|
||||
description: An even better fine-tune of the Arabian Nights
|
||||
repo_id: captahab/arabian-nights-1.1
|
||||
format: diffusers
|
||||
default: true
|
||||
```
|
||||
|
||||
And for a downloaded directory:
|
||||
|
||||
```yaml
|
||||
arabian-nights-1.1:
|
||||
description: An even better fine-tune of the Arabian Nights
|
||||
path: /path/to/captahab-arabian-nights-1.1
|
||||
format: diffusers
|
||||
default: true
|
||||
```
|
||||
|
||||
There is additional syntax for indicating an external VAE to use with
|
||||
this model. See `INITIAL_MODELS.yaml` and `models.yaml` for examples.
|
||||
|
||||
After you save the modified `models.yaml` file relaunch
|
||||
`invokeai`. The new model will now be available for your use.
|
||||
|
||||
### Installation via the WebUI
|
||||
|
||||
To access the WebUI Model Manager, click on the button that looks like
|
||||
@ -393,3 +317,143 @@ And here is what the same argument looks like in `invokeai.init`:
|
||||
--no-nsfw_checker
|
||||
--autoconvert /home/fred/stable-diffusion-checkpoints
|
||||
```
|
||||
|
||||
### Specifying a configuration file for legacy checkpoints
|
||||
|
||||
Some checkpoint files come with instructions to use a specific .yaml
|
||||
configuration file. For InvokeAI load this file correctly, please put
|
||||
the config file in the same directory as the corresponding `.ckpt` or
|
||||
`.safetensors` file and make sure the file has the same basename as
|
||||
the model file. Here is an example:
|
||||
|
||||
```bash
|
||||
wonderful-model-v2.ckpt
|
||||
wonderful-model-v2.yaml
|
||||
```
|
||||
|
||||
This is not needed for `diffusers` models, which come with their own
|
||||
pre-packaged configuration.
|
||||
|
||||
### Specifying a custom VAE file for legacy checkpoints
|
||||
|
||||
To associate a custom VAE with a legacy file, place the VAE file in
|
||||
the same directory as the corresponding `.ckpt` or
|
||||
`.safetensors` file and make sure the file has the same basename as
|
||||
the model file. Use the suffix `.vae.pt` for VAE checkpoint files, and
|
||||
`.vae.safetensors` for VAE safetensors files. There is no requirement
|
||||
that both the model and the VAE follow the same format.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
wonderful-model-v2.pt
|
||||
wonderful-model-v2.vae.safetensors
|
||||
```
|
||||
|
||||
### Converting legacy models into `diffusers`
|
||||
|
||||
The CLI `!convert_model` will convert a `.safetensors` or `.ckpt`
|
||||
models file into `diffusers` and install it.This will enable the model
|
||||
to load and run faster without loss of image quality.
|
||||
|
||||
The usage is identical to `!import_model`. You may point the command
|
||||
to either a downloaded model file on disk, or to a (non-password
|
||||
protected) URL:
|
||||
|
||||
```bash
|
||||
invoke> !convert_model C:/Users/fred/Downloads/martians.safetensors
|
||||
```
|
||||
|
||||
After a successful conversion, the CLI will offer you the option of
|
||||
deleting the original `.ckpt` or `.safetensors` file.
|
||||
|
||||
### Optimizing a previously-installed model
|
||||
|
||||
Lastly, if you have previously installed a `.ckpt` or `.safetensors`
|
||||
file and wish to convert it into a `diffusers` model, you can do this
|
||||
without re-downloading and converting the original file using the
|
||||
`!optimize_model` command. Simply pass the short name of an existing
|
||||
installed model:
|
||||
|
||||
```bash
|
||||
invoke> !optimize_model martians-v1.0
|
||||
```
|
||||
|
||||
The model will be converted into `diffusers` format and replace the
|
||||
previously installed version. You will again be offered the
|
||||
opportunity to delete the original `.ckpt` or `.safetensors` file.
|
||||
|
||||
Alternatively you can use the WebUI's model manager to handle diffusers
|
||||
optimization. Select the legacy model you wish to convert, and then
|
||||
look for a button labeled "Convert to Diffusers" in the upper right of
|
||||
the window.
|
||||
|
||||
### Related CLI Commands
|
||||
|
||||
There are a whole series of additional model management commands in
|
||||
the CLI that you can read about in [Command-Line
|
||||
Interface](../features/CLI.md). These include:
|
||||
|
||||
* `!models` - List all installed models
|
||||
* `!switch <model name>` - Switch to the indicated model
|
||||
* `!edit_model <model name>` - Edit the indicated model to change its name, description or other properties
|
||||
* `!del_model <model name>` - Delete the indicated model
|
||||
|
||||
### Manually editing `configs/models.yaml`
|
||||
|
||||
If you are comfortable with a text editor then you may simply edit `models.yaml`
|
||||
directly.
|
||||
|
||||
You will need to download the desired `.ckpt/.safetensors` file and
|
||||
place it somewhere on your machine's filesystem. Alternatively, for a
|
||||
`diffusers` model, record the repo_id or download the whole model
|
||||
directory. Then using a **text** editor (e.g. the Windows Notepad
|
||||
application), open the file `configs/models.yaml`, and add a new
|
||||
stanza that follows this model:
|
||||
|
||||
#### A legacy model
|
||||
|
||||
A legacy `.ckpt` or `.safetensors` entry will look like this:
|
||||
|
||||
```yaml
|
||||
arabian-nights-1.0:
|
||||
description: A great fine-tune in Arabian Nights style
|
||||
weights: ./path/to/arabian-nights-1.0.ckpt
|
||||
config: ./configs/stable-diffusion/v1-inference.yaml
|
||||
format: ckpt
|
||||
width: 512
|
||||
height: 512
|
||||
default: false
|
||||
```
|
||||
|
||||
Note that `format` is `ckpt` for both `.ckpt` and `.safetensors` files.
|
||||
|
||||
#### A diffusers model
|
||||
|
||||
A stanza for a `diffusers` model will look like this for a HuggingFace
|
||||
model with a repository ID:
|
||||
|
||||
```yaml
|
||||
arabian-nights-1.1:
|
||||
description: An even better fine-tune of the Arabian Nights
|
||||
repo_id: captahab/arabian-nights-1.1
|
||||
format: diffusers
|
||||
default: true
|
||||
```
|
||||
|
||||
And for a downloaded directory:
|
||||
|
||||
```yaml
|
||||
arabian-nights-1.1:
|
||||
description: An even better fine-tune of the Arabian Nights
|
||||
path: /path/to/captahab-arabian-nights-1.1
|
||||
format: diffusers
|
||||
default: true
|
||||
```
|
||||
|
||||
There is additional syntax for indicating an external VAE to use with
|
||||
this model. See `INITIAL_MODELS.yaml` and `models.yaml` for examples.
|
||||
|
||||
After you save the modified `models.yaml` file relaunch
|
||||
`invokeai`. The new model will now be available for your use.
|
||||
|
||||
|
@ -23,14 +23,16 @@ We thank them for all of their time and hard work.
|
||||
* @damian0815 - Attention Systems and Gameplay Engineer
|
||||
* @mauwii (Matthias Wild) - Continuous integration and product maintenance engineer
|
||||
* @Netsvetaev (Artur Netsvetaev) - UI/UX Developer
|
||||
* @tildebyte - General gadfly and resident (self-appointed) know-it-all
|
||||
* @keturn - Lead for Diffusers port
|
||||
* @ebr (Eugene Brodsky) - Cloud/DevOps/Sofware engineer; your friendly neighbourhood cluster-autoscaler
|
||||
* @jpphoto (Jonathan Pollack) - Inference and rendering engine optimization
|
||||
* @genomancer (Gregg Helt) - Model training and merging
|
||||
* @gogurtenjoyer - User support and testing
|
||||
* @whosawwhatsis - User support and testing
|
||||
|
||||
## **Contributions by**
|
||||
|
||||
- [tildebyte](https://github.com/tildebyte)
|
||||
- [Sean McLellan](https://github.com/Oceanswave)
|
||||
- [Kevin Gibbons](https://github.com/bakkot)
|
||||
- [Tesseract Cat](https://github.com/TesseractCat)
|
||||
@ -78,6 +80,7 @@ We thank them for all of their time and hard work.
|
||||
- [psychedelicious](https://github.com/psychedelicious)
|
||||
- [damian0815](https://github.com/damian0815)
|
||||
- [Eugene Brodsky](https://github.com/ebr)
|
||||
- [Statcomm](https://github.com/statcomm)
|
||||
|
||||
## **Original CompVis Authors**
|
||||
|
||||
|
@ -1,5 +0,0 @@
|
||||
mkdocs
|
||||
mkdocs-material>=8, <9
|
||||
mkdocs-git-revision-date-localized-plugin
|
||||
mkdocs-redirects==1.2.0
|
||||
|
@ -144,8 +144,8 @@ class Installer:
|
||||
|
||||
from plumbum import FG, local
|
||||
|
||||
pip = local[get_pip_from_venv(venv_dir)]
|
||||
pip[ "install", "--upgrade", "pip"] & FG
|
||||
python = local[get_python_from_venv(venv_dir)]
|
||||
python[ "-m", "pip", "install", "--upgrade", "pip"] & FG
|
||||
|
||||
return venv_dir
|
||||
|
||||
@ -241,14 +241,18 @@ class InvokeAiInstance:
|
||||
|
||||
from plumbum import FG, local
|
||||
|
||||
# Note that we're installing pinned versions of torch and
|
||||
# torchvision here, which *should* correspond to what is
|
||||
# in pyproject.toml. This is to prevent torch 2.0 from
|
||||
# being installed and immediately uninstalled and replaced with 1.13
|
||||
pip = local[self.pip]
|
||||
|
||||
(
|
||||
pip[
|
||||
"install",
|
||||
"--require-virtualenv",
|
||||
"torch",
|
||||
"torchvision",
|
||||
"torch~=1.13.1",
|
||||
"torchvision~=0.14.1",
|
||||
"--force-reinstall",
|
||||
"--find-links" if find_links is not None else None,
|
||||
find_links,
|
||||
@ -379,6 +383,9 @@ class InvokeAiInstance:
|
||||
shutil.copy(src, dest)
|
||||
os.chmod(dest, 0o0755)
|
||||
|
||||
if OS == "Linux":
|
||||
shutil.copy(Path(__file__).parents[1] / "templates" / "dialogrc", self.runtime / '.dialogrc')
|
||||
|
||||
def update(self):
|
||||
pass
|
||||
|
||||
@ -405,6 +412,22 @@ def get_pip_from_venv(venv_path: Path) -> str:
|
||||
return str(venv_path.expanduser().resolve() / pip)
|
||||
|
||||
|
||||
def get_python_from_venv(venv_path: Path) -> str:
|
||||
"""
|
||||
Given a path to a virtual environment, get the absolute path to the `python` executable
|
||||
in a cross-platform fashion. Does not validate that the python executable
|
||||
actually exists in the virtualenv.
|
||||
|
||||
:param venv_path: Path to the virtual environment
|
||||
:type venv_path: Path
|
||||
:return: Absolute path to the python executable
|
||||
:rtype: str
|
||||
"""
|
||||
|
||||
python = "Scripts\python.exe" if OS == "Windows" else "bin/python"
|
||||
return str(venv_path.expanduser().resolve() / python)
|
||||
|
||||
|
||||
def set_sys_path(venv_path: Path) -> None:
|
||||
"""
|
||||
Given a path to a virtual environment, set the sys.path, in a cross-platform fashion,
|
||||
|
27
installer/templates/dialogrc
Normal file
27
installer/templates/dialogrc
Normal file
@ -0,0 +1,27 @@
|
||||
# Screen
|
||||
use_shadow = OFF
|
||||
use_colors = ON
|
||||
screen_color = (BLACK, BLACK, ON)
|
||||
|
||||
# Box
|
||||
dialog_color = (YELLOW, BLACK , ON)
|
||||
title_color = (YELLOW, BLACK, ON)
|
||||
border_color = (YELLOW, BLACK, OFF)
|
||||
border2_color = (YELLOW, BLACK, OFF)
|
||||
|
||||
# Button
|
||||
button_active_color = (RED, BLACK, OFF)
|
||||
button_inactive_color = (YELLOW, BLACK, OFF)
|
||||
button_label_active_color = (YELLOW,BLACK,ON)
|
||||
button_label_inactive_color = (YELLOW,BLACK,ON)
|
||||
|
||||
# Menu box
|
||||
menubox_color = (BLACK, BLACK, ON)
|
||||
menubox_border_color = (YELLOW, BLACK, OFF)
|
||||
menubox_border2_color = (YELLOW, BLACK, OFF)
|
||||
|
||||
# Menu window
|
||||
item_color = (YELLOW, BLACK, OFF)
|
||||
item_selected_color = (BLACK, YELLOW, OFF)
|
||||
tag_key_color = (YELLOW, BLACK, OFF)
|
||||
tag_key_selected_color = (BLACK, YELLOW, OFF)
|
@ -1,5 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
# MIT License
|
||||
|
||||
# Coauthored by Lincoln Stein, Eugene Brodsky and Joshua Kimsey
|
||||
# Copyright 2023, The InvokeAI Development Team
|
||||
|
||||
####
|
||||
# This launch script assumes that:
|
||||
# 1. it is located in the runtime directory,
|
||||
@ -11,85 +16,168 @@
|
||||
|
||||
set -eu
|
||||
|
||||
# ensure we're in the correct folder in case user's CWD is somewhere else
|
||||
# Ensure we're in the correct folder in case user's CWD is somewhere else
|
||||
scriptdir=$(dirname "$0")
|
||||
cd "$scriptdir"
|
||||
|
||||
. .venv/bin/activate
|
||||
|
||||
export INVOKEAI_ROOT="$scriptdir"
|
||||
PARAMS=$@
|
||||
|
||||
# set required env var for torch on mac MPS
|
||||
# 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
|
||||
if [ "$(uname -s)" == "Darwin" ]; then
|
||||
export PYTORCH_ENABLE_MPS_FALLBACK=1
|
||||
fi
|
||||
|
||||
while true
|
||||
do
|
||||
if [ "$0" != "bash" ]; then
|
||||
echo "Do you want to generate images using the"
|
||||
echo "1. command-line interface"
|
||||
echo "2. browser-based UI"
|
||||
echo "3. run textual inversion training"
|
||||
echo "4. merge models (diffusers type only)"
|
||||
echo "5. download and install models"
|
||||
echo "6. change InvokeAI startup options"
|
||||
echo "7. re-run the configure script to fix a broken install"
|
||||
echo "8. open the developer console"
|
||||
echo "9. update InvokeAI"
|
||||
echo "10. command-line help"
|
||||
echo "Q - Quit"
|
||||
echo ""
|
||||
read -p "Please enter 1-10, Q: [2] " yn
|
||||
choice=${yn:='2'}
|
||||
case $choice in
|
||||
1)
|
||||
echo "Starting the InvokeAI command-line..."
|
||||
invokeai $@
|
||||
;;
|
||||
2)
|
||||
echo "Starting the InvokeAI browser-based UI..."
|
||||
invokeai --web $@
|
||||
;;
|
||||
3)
|
||||
echo "Starting Textual Inversion:"
|
||||
invokeai-ti --gui $@
|
||||
;;
|
||||
4)
|
||||
echo "Merging Models:"
|
||||
invokeai-merge --gui $@
|
||||
;;
|
||||
5)
|
||||
invokeai-model-install --root ${INVOKEAI_ROOT}
|
||||
;;
|
||||
6)
|
||||
invokeai-configure --root ${INVOKEAI_ROOT} --skip-sd-weights --skip-support-models
|
||||
;;
|
||||
7)
|
||||
invokeai-configure --root ${INVOKEAI_ROOT} --yes --default_only
|
||||
;;
|
||||
8)
|
||||
echo "Developer Console:"
|
||||
file_name=$(basename "${BASH_SOURCE[0]}")
|
||||
bash --init-file "$file_name"
|
||||
;;
|
||||
9)
|
||||
echo "Update:"
|
||||
invokeai-update
|
||||
;;
|
||||
10)
|
||||
invokeai --help
|
||||
;;
|
||||
[qQ])
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Invalid selection"
|
||||
exit;;
|
||||
# Primary function for the case statement to determine user input
|
||||
do_choice() {
|
||||
case $1 in
|
||||
1)
|
||||
clear
|
||||
printf "Generate images with a browser-based interface\n"
|
||||
invokeai --web $PARAMS
|
||||
;;
|
||||
2)
|
||||
clear
|
||||
printf "Generate images using a command-line interface\n"
|
||||
invokeai $PARAMS
|
||||
;;
|
||||
3)
|
||||
clear
|
||||
printf "Textual inversion training\n"
|
||||
invokeai-ti --gui $PARAMS
|
||||
;;
|
||||
4)
|
||||
clear
|
||||
printf "Merge models (diffusers type only)\n"
|
||||
invokeai-merge --gui $PARAMS
|
||||
;;
|
||||
5)
|
||||
clear
|
||||
printf "Download and install models\n"
|
||||
invokeai-model-install --root ${INVOKEAI_ROOT}
|
||||
;;
|
||||
6)
|
||||
clear
|
||||
printf "Change InvokeAI startup options\n"
|
||||
invokeai-configure --root ${INVOKEAI_ROOT} --skip-sd-weights --skip-support-models
|
||||
;;
|
||||
7)
|
||||
clear
|
||||
printf "Re-run the configure script to fix a broken install\n"
|
||||
invokeai-configure --root ${INVOKEAI_ROOT} --yes --default_only
|
||||
;;
|
||||
8)
|
||||
clear
|
||||
printf "Open the developer console\n"
|
||||
file_name=$(basename "${BASH_SOURCE[0]}")
|
||||
bash --init-file "$file_name"
|
||||
;;
|
||||
9)
|
||||
clear
|
||||
printf "Update InvokeAI\n"
|
||||
invokeai-update
|
||||
;;
|
||||
10)
|
||||
clear
|
||||
printf "Command-line help\n"
|
||||
invokeai --help
|
||||
;;
|
||||
"HELP 1")
|
||||
clear
|
||||
printf "Command-line help\n"
|
||||
invokeai --help
|
||||
;;
|
||||
*)
|
||||
clear
|
||||
printf "Exiting...\n"
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
clear
|
||||
}
|
||||
|
||||
# Dialog-based TUI for launcing Invoke functions
|
||||
do_dialog() {
|
||||
options=(
|
||||
1 "Generate images with a browser-based interface"
|
||||
2 "Generate images 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"
|
||||
8 "Open the developer console"
|
||||
9 "Update InvokeAI")
|
||||
|
||||
choice=$(dialog --clear \
|
||||
--backtitle "\Zb\Zu\Z3InvokeAI" \
|
||||
--colors \
|
||||
--title "What would you like to run?" \
|
||||
--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 "Do you want to generate images using the\n"
|
||||
printf "1: Browser-based UI\n"
|
||||
printf "2: Command-line interface\n"
|
||||
printf "3: Run textual inversion training\n"
|
||||
printf "4: Merge models (diffusers type only)\n"
|
||||
printf "5: Download and install models\n"
|
||||
printf "6: Change InvokeAI startup options\n"
|
||||
printf "7: Re-run the configure script to fix a broken install\n"
|
||||
printf "8: Open the developer console\n"
|
||||
printf "9: Update InvokeAI\n"
|
||||
printf "10: Command-line help\n"
|
||||
printf "Q: Quit\n\n"
|
||||
read -p "Please enter 1-10, 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
|
||||
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
|
||||
done
|
||||
else # in developer console
|
||||
python --version
|
||||
echo "Press ^D to exit"
|
||||
printf "Press ^D to exit\n"
|
||||
export PS1="(InvokeAI) \u@\h \w> "
|
||||
fi
|
||||
done
|
||||
|
@ -25,14 +25,23 @@ from invokeai.backend.modules.parameters import parameters_to_command
|
||||
import invokeai.frontend.dist as frontend
|
||||
from ldm.generate import Generate
|
||||
from ldm.invoke.args import Args, APP_ID, APP_VERSION, calculate_init_img_hash
|
||||
from ldm.invoke.conditioning import get_tokens_for_prompt_object, get_prompt_structure, split_weighted_subprompts, \
|
||||
get_tokenizer
|
||||
from ldm.invoke.concepts_lib import HuggingFaceConceptsLibrary
|
||||
from ldm.invoke.conditioning import (
|
||||
get_tokens_for_prompt_object,
|
||||
get_prompt_structure,
|
||||
split_weighted_subprompts,
|
||||
get_tokenizer,
|
||||
)
|
||||
from ldm.invoke.generator.diffusers_pipeline import PipelineIntermediateState
|
||||
from ldm.invoke.generator.inpaint import infill_methods
|
||||
from ldm.invoke.globals import Globals, global_converted_ckpts_dir
|
||||
from ldm.invoke.globals import (
|
||||
Globals,
|
||||
global_converted_ckpts_dir,
|
||||
global_models_dir,
|
||||
global_lora_models_dir,
|
||||
)
|
||||
from ldm.invoke.pngwriter import PngWriter, retrieve_metadata
|
||||
from compel.prompt_parser import Blend
|
||||
from ldm.invoke.globals import global_models_dir
|
||||
from ldm.invoke.merge_diffusers import merge_diffusion_models
|
||||
|
||||
# Loading Arguments
|
||||
@ -193,8 +202,7 @@ class InvokeAIWebServer:
|
||||
(width, height) = pil_image.size
|
||||
|
||||
thumbnail_path = save_thumbnail(
|
||||
pil_image, os.path.basename(
|
||||
file_path), self.thumbnail_image_path
|
||||
pil_image, os.path.basename(file_path), self.thumbnail_image_path
|
||||
)
|
||||
|
||||
response = {
|
||||
@ -224,7 +232,7 @@ class InvokeAIWebServer:
|
||||
server="flask_socketio",
|
||||
width=1600,
|
||||
height=1000,
|
||||
port=self.port
|
||||
port=self.port,
|
||||
).run()
|
||||
except KeyboardInterrupt:
|
||||
import sys
|
||||
@ -265,16 +273,14 @@ class InvokeAIWebServer:
|
||||
# location for "finished" images
|
||||
self.result_path = args.outdir
|
||||
# temporary path for intermediates
|
||||
self.intermediate_path = os.path.join(
|
||||
self.result_path, "intermediates/")
|
||||
self.intermediate_path = os.path.join(self.result_path, "intermediates/")
|
||||
# path for user-uploaded init images and masks
|
||||
self.init_image_path = os.path.join(self.result_path, "init-images/")
|
||||
self.mask_image_path = os.path.join(self.result_path, "mask-images/")
|
||||
# path for temp images e.g. gallery generations which are not committed
|
||||
self.temp_image_path = os.path.join(self.result_path, "temp-images/")
|
||||
# path for thumbnail images
|
||||
self.thumbnail_image_path = os.path.join(
|
||||
self.result_path, "thumbnails/")
|
||||
self.thumbnail_image_path = os.path.join(self.result_path, "thumbnails/")
|
||||
# txt log
|
||||
self.log_path = os.path.join(self.result_path, "invoke_log.txt")
|
||||
# make all output paths
|
||||
@ -299,21 +305,22 @@ class InvokeAIWebServer:
|
||||
config["infill_methods"] = infill_methods()
|
||||
socketio.emit("systemConfig", config)
|
||||
|
||||
@socketio.on('searchForModels')
|
||||
@socketio.on("searchForModels")
|
||||
def handle_search_models(search_folder: str):
|
||||
try:
|
||||
if not search_folder:
|
||||
socketio.emit(
|
||||
"foundModels",
|
||||
{'search_folder': None, 'found_models': None},
|
||||
{"search_folder": None, "found_models": None},
|
||||
)
|
||||
else:
|
||||
search_folder, found_models = self.generate.model_manager.search_models(
|
||||
search_folder)
|
||||
(
|
||||
search_folder,
|
||||
found_models,
|
||||
) = self.generate.model_manager.search_models(search_folder)
|
||||
socketio.emit(
|
||||
"foundModels",
|
||||
{'search_folder': search_folder,
|
||||
'found_models': found_models},
|
||||
{"search_folder": search_folder, "found_models": found_models},
|
||||
)
|
||||
except Exception as e:
|
||||
self.handle_exceptions(e)
|
||||
@ -322,11 +329,11 @@ class InvokeAIWebServer:
|
||||
@socketio.on("addNewModel")
|
||||
def handle_add_model(new_model_config: dict):
|
||||
try:
|
||||
model_name = new_model_config['name']
|
||||
del new_model_config['name']
|
||||
model_name = new_model_config["name"]
|
||||
del new_model_config["name"]
|
||||
model_attributes = new_model_config
|
||||
if len(model_attributes['vae']) == 0:
|
||||
del model_attributes['vae']
|
||||
if len(model_attributes["vae"]) == 0:
|
||||
del model_attributes["vae"]
|
||||
update = False
|
||||
current_model_list = self.generate.model_manager.list_models()
|
||||
if model_name in current_model_list:
|
||||
@ -335,14 +342,20 @@ class InvokeAIWebServer:
|
||||
print(f">> Adding New Model: {model_name}")
|
||||
|
||||
self.generate.model_manager.add_model(
|
||||
model_name=model_name, model_attributes=model_attributes, clobber=True)
|
||||
model_name=model_name,
|
||||
model_attributes=model_attributes,
|
||||
clobber=True,
|
||||
)
|
||||
self.generate.model_manager.commit(opt.conf)
|
||||
|
||||
new_model_list = self.generate.model_manager.list_models()
|
||||
socketio.emit(
|
||||
"newModelAdded",
|
||||
{"new_model_name": model_name,
|
||||
"model_list": new_model_list, 'update': update},
|
||||
{
|
||||
"new_model_name": model_name,
|
||||
"model_list": new_model_list,
|
||||
"update": update,
|
||||
},
|
||||
)
|
||||
print(f">> New Model Added: {model_name}")
|
||||
except Exception as e:
|
||||
@ -357,8 +370,10 @@ class InvokeAIWebServer:
|
||||
updated_model_list = self.generate.model_manager.list_models()
|
||||
socketio.emit(
|
||||
"modelDeleted",
|
||||
{"deleted_model_name": model_name,
|
||||
"model_list": updated_model_list},
|
||||
{
|
||||
"deleted_model_name": model_name,
|
||||
"model_list": updated_model_list,
|
||||
},
|
||||
)
|
||||
print(f">> Model Deleted: {model_name}")
|
||||
except Exception as e:
|
||||
@ -383,41 +398,48 @@ class InvokeAIWebServer:
|
||||
except Exception as e:
|
||||
self.handle_exceptions(e)
|
||||
|
||||
@socketio.on('convertToDiffusers')
|
||||
@socketio.on("convertToDiffusers")
|
||||
def convert_to_diffusers(model_to_convert: dict):
|
||||
try:
|
||||
if (model_info := self.generate.model_manager.model_info(model_name=model_to_convert['model_name'])):
|
||||
if 'weights' in model_info:
|
||||
ckpt_path = Path(model_info['weights'])
|
||||
original_config_file = Path(model_info['config'])
|
||||
model_name = model_to_convert['model_name']
|
||||
model_description = model_info['description']
|
||||
if model_info := self.generate.model_manager.model_info(
|
||||
model_name=model_to_convert["model_name"]
|
||||
):
|
||||
if "weights" in model_info:
|
||||
ckpt_path = Path(model_info["weights"])
|
||||
original_config_file = Path(model_info["config"])
|
||||
model_name = model_to_convert["model_name"]
|
||||
model_description = model_info["description"]
|
||||
else:
|
||||
self.socketio.emit(
|
||||
"error", {"message": "Model is not a valid checkpoint file"})
|
||||
"error", {"message": "Model is not a valid checkpoint file"}
|
||||
)
|
||||
else:
|
||||
self.socketio.emit(
|
||||
"error", {"message": "Could not retrieve model info."})
|
||||
"error", {"message": "Could not retrieve model info."}
|
||||
)
|
||||
|
||||
if not ckpt_path.is_absolute():
|
||||
ckpt_path = Path(Globals.root, ckpt_path)
|
||||
|
||||
if original_config_file and not original_config_file.is_absolute():
|
||||
original_config_file = Path(
|
||||
Globals.root, original_config_file)
|
||||
original_config_file = Path(Globals.root, original_config_file)
|
||||
|
||||
diffusers_path = Path(
|
||||
ckpt_path.parent.absolute(),
|
||||
f'{model_name}_diffusers'
|
||||
ckpt_path.parent.absolute(), f"{model_name}_diffusers"
|
||||
)
|
||||
|
||||
if model_to_convert['save_location'] == 'root':
|
||||
if model_to_convert["save_location"] == "root":
|
||||
diffusers_path = Path(
|
||||
global_converted_ckpts_dir(), f'{model_name}_diffusers')
|
||||
global_converted_ckpts_dir(), f"{model_name}_diffusers"
|
||||
)
|
||||
|
||||
if model_to_convert['save_location'] == 'custom' and model_to_convert['custom_location'] is not None:
|
||||
if (
|
||||
model_to_convert["save_location"] == "custom"
|
||||
and model_to_convert["custom_location"] is not None
|
||||
):
|
||||
diffusers_path = Path(
|
||||
model_to_convert['custom_location'], f'{model_name}_diffusers')
|
||||
model_to_convert["custom_location"], f"{model_name}_diffusers"
|
||||
)
|
||||
|
||||
if diffusers_path.exists():
|
||||
shutil.rmtree(diffusers_path)
|
||||
@ -435,54 +457,99 @@ class InvokeAIWebServer:
|
||||
new_model_list = self.generate.model_manager.list_models()
|
||||
socketio.emit(
|
||||
"modelConverted",
|
||||
{"new_model_name": model_name,
|
||||
"model_list": new_model_list, 'update': True},
|
||||
{
|
||||
"new_model_name": model_name,
|
||||
"model_list": new_model_list,
|
||||
"update": True,
|
||||
},
|
||||
)
|
||||
print(f">> Model Converted: {model_name}")
|
||||
except Exception as e:
|
||||
self.handle_exceptions(e)
|
||||
|
||||
@socketio.on('mergeDiffusersModels')
|
||||
@socketio.on("mergeDiffusersModels")
|
||||
def merge_diffusers_models(model_merge_info: dict):
|
||||
try:
|
||||
models_to_merge = model_merge_info['models_to_merge']
|
||||
models_to_merge = model_merge_info["models_to_merge"]
|
||||
model_ids_or_paths = [
|
||||
self.generate.model_manager.model_name_or_path(x) for x in models_to_merge]
|
||||
self.generate.model_manager.model_name_or_path(x)
|
||||
for x in models_to_merge
|
||||
]
|
||||
merged_pipe = merge_diffusion_models(
|
||||
model_ids_or_paths, model_merge_info['alpha'], model_merge_info['interp'], model_merge_info['force'])
|
||||
model_ids_or_paths,
|
||||
model_merge_info["alpha"],
|
||||
model_merge_info["interp"],
|
||||
model_merge_info["force"],
|
||||
)
|
||||
|
||||
dump_path = global_models_dir() / 'merged_models'
|
||||
if model_merge_info['model_merge_save_path'] is not None:
|
||||
dump_path = Path(model_merge_info['model_merge_save_path'])
|
||||
dump_path = global_models_dir() / "merged_models"
|
||||
if model_merge_info["model_merge_save_path"] is not None:
|
||||
dump_path = Path(model_merge_info["model_merge_save_path"])
|
||||
|
||||
os.makedirs(dump_path, exist_ok=True)
|
||||
dump_path = dump_path / model_merge_info['merged_model_name']
|
||||
dump_path = dump_path / model_merge_info["merged_model_name"]
|
||||
merged_pipe.save_pretrained(dump_path, safe_serialization=1)
|
||||
|
||||
merged_model_config = dict(
|
||||
model_name=model_merge_info['merged_model_name'],
|
||||
model_name=model_merge_info["merged_model_name"],
|
||||
description=f'Merge of models {", ".join(models_to_merge)}',
|
||||
commit_to_conf=opt.conf
|
||||
commit_to_conf=opt.conf,
|
||||
)
|
||||
|
||||
if vae := self.generate.model_manager.config[models_to_merge[0]].get("vae", None):
|
||||
print(
|
||||
f">> Using configured VAE assigned to {models_to_merge[0]}")
|
||||
if vae := self.generate.model_manager.config[models_to_merge[0]].get(
|
||||
"vae", None
|
||||
):
|
||||
print(f">> Using configured VAE assigned to {models_to_merge[0]}")
|
||||
merged_model_config.update(vae=vae)
|
||||
|
||||
self.generate.model_manager.import_diffuser_model(
|
||||
dump_path, **merged_model_config)
|
||||
dump_path, **merged_model_config
|
||||
)
|
||||
new_model_list = self.generate.model_manager.list_models()
|
||||
|
||||
socketio.emit(
|
||||
"modelsMerged",
|
||||
{"merged_models": models_to_merge,
|
||||
"merged_model_name": model_merge_info['merged_model_name'],
|
||||
"model_list": new_model_list, 'update': True},
|
||||
{
|
||||
"merged_models": models_to_merge,
|
||||
"merged_model_name": model_merge_info["merged_model_name"],
|
||||
"model_list": new_model_list,
|
||||
"update": True,
|
||||
},
|
||||
)
|
||||
print(f">> Models Merged: {models_to_merge}")
|
||||
print(
|
||||
f">> New Model Added: {model_merge_info['merged_model_name']}")
|
||||
print(f">> New Model Added: {model_merge_info['merged_model_name']}")
|
||||
except Exception as e:
|
||||
self.handle_exceptions(e)
|
||||
|
||||
@socketio.on("getLoraModels")
|
||||
def get_lora_models():
|
||||
try:
|
||||
lora_path = global_lora_models_dir()
|
||||
loras = []
|
||||
for root, _, files in os.walk(lora_path):
|
||||
models = [
|
||||
Path(root, x)
|
||||
for x in files
|
||||
if Path(x).suffix in [".ckpt", ".pt", ".safetensors"]
|
||||
]
|
||||
loras = loras + models
|
||||
|
||||
found_loras = []
|
||||
for lora in sorted(loras, key=lambda s: s.stem.lower()):
|
||||
location = str(lora.resolve()).replace("\\", "/")
|
||||
found_loras.append({"name": lora.stem, "location": location})
|
||||
socketio.emit("foundLoras", found_loras)
|
||||
except Exception as e:
|
||||
self.handle_exceptions(e)
|
||||
|
||||
@socketio.on("getTextualInversionTriggers")
|
||||
def get_ti_triggers():
|
||||
try:
|
||||
local_triggers = self.generate.model.textual_inversion_manager.get_all_trigger_strings()
|
||||
locals = [{'name': x} for x in sorted(local_triggers, key=str.casefold)]
|
||||
concepts = HuggingFaceConceptsLibrary().list_concepts(minimum_likes=5)
|
||||
concepts = [{'name': f'<{x}>'} for x in sorted(concepts, key=str.casefold) if f'<{x}>' not in local_triggers]
|
||||
socketio.emit("foundTextualInversionTriggers", {'local_triggers': locals, 'huggingface_concepts': concepts})
|
||||
except Exception as e:
|
||||
self.handle_exceptions(e)
|
||||
|
||||
@ -500,7 +567,8 @@ class InvokeAIWebServer:
|
||||
os.remove(thumbnail_path)
|
||||
except Exception as e:
|
||||
socketio.emit(
|
||||
"error", {"message": f"Unable to delete {f}: {str(e)}"})
|
||||
"error", {"message": f"Unable to delete {f}: {str(e)}"}
|
||||
)
|
||||
pass
|
||||
|
||||
socketio.emit("tempFolderEmptied")
|
||||
@ -511,8 +579,7 @@ class InvokeAIWebServer:
|
||||
def save_temp_image_to_gallery(url):
|
||||
try:
|
||||
image_path = self.get_image_path_from_url(url)
|
||||
new_path = os.path.join(
|
||||
self.result_path, os.path.basename(image_path))
|
||||
new_path = os.path.join(self.result_path, os.path.basename(image_path))
|
||||
shutil.copy2(image_path, new_path)
|
||||
|
||||
if os.path.splitext(new_path)[1] == ".png":
|
||||
@ -525,8 +592,7 @@ class InvokeAIWebServer:
|
||||
(width, height) = pil_image.size
|
||||
|
||||
thumbnail_path = save_thumbnail(
|
||||
pil_image, os.path.basename(
|
||||
new_path), self.thumbnail_image_path
|
||||
pil_image, os.path.basename(new_path), self.thumbnail_image_path
|
||||
)
|
||||
|
||||
image_array = [
|
||||
@ -585,8 +651,7 @@ class InvokeAIWebServer:
|
||||
(width, height) = pil_image.size
|
||||
|
||||
thumbnail_path = save_thumbnail(
|
||||
pil_image, os.path.basename(
|
||||
path), self.thumbnail_image_path
|
||||
pil_image, os.path.basename(path), self.thumbnail_image_path
|
||||
)
|
||||
|
||||
image_array.append(
|
||||
@ -605,7 +670,8 @@ class InvokeAIWebServer:
|
||||
)
|
||||
except Exception as e:
|
||||
socketio.emit(
|
||||
"error", {"message": f"Unable to load {path}: {str(e)}"})
|
||||
"error", {"message": f"Unable to load {path}: {str(e)}"}
|
||||
)
|
||||
pass
|
||||
|
||||
socketio.emit(
|
||||
@ -655,8 +721,7 @@ class InvokeAIWebServer:
|
||||
(width, height) = pil_image.size
|
||||
|
||||
thumbnail_path = save_thumbnail(
|
||||
pil_image, os.path.basename(
|
||||
path), self.thumbnail_image_path
|
||||
pil_image, os.path.basename(path), self.thumbnail_image_path
|
||||
)
|
||||
|
||||
image_array.append(
|
||||
@ -676,7 +741,8 @@ class InvokeAIWebServer:
|
||||
except Exception as e:
|
||||
print(f">> Unable to load {path}")
|
||||
socketio.emit(
|
||||
"error", {"message": f"Unable to load {path}: {str(e)}"})
|
||||
"error", {"message": f"Unable to load {path}: {str(e)}"}
|
||||
)
|
||||
pass
|
||||
|
||||
socketio.emit(
|
||||
@ -710,10 +776,9 @@ class InvokeAIWebServer:
|
||||
printable_parameters["init_mask"][:64] + "..."
|
||||
)
|
||||
|
||||
print(
|
||||
f'\n>> Image Generation Parameters:\n\n{printable_parameters}\n')
|
||||
print(f'>> ESRGAN Parameters: {esrgan_parameters}')
|
||||
print(f'>> Facetool Parameters: {facetool_parameters}')
|
||||
print(f"\n>> Image Generation Parameters:\n\n{printable_parameters}\n")
|
||||
print(f">> ESRGAN Parameters: {esrgan_parameters}")
|
||||
print(f">> Facetool Parameters: {facetool_parameters}")
|
||||
|
||||
self.generate_images(
|
||||
generation_parameters,
|
||||
@ -750,11 +815,9 @@ class InvokeAIWebServer:
|
||||
if postprocessing_parameters["type"] == "esrgan":
|
||||
progress.set_current_status("common.statusUpscalingESRGAN")
|
||||
elif postprocessing_parameters["type"] == "gfpgan":
|
||||
progress.set_current_status(
|
||||
"common.statusRestoringFacesGFPGAN")
|
||||
progress.set_current_status("common.statusRestoringFacesGFPGAN")
|
||||
elif postprocessing_parameters["type"] == "codeformer":
|
||||
progress.set_current_status(
|
||||
"common.statusRestoringFacesCodeFormer")
|
||||
progress.set_current_status("common.statusRestoringFacesCodeFormer")
|
||||
|
||||
socketio.emit("progressUpdate", progress.to_formatted_dict())
|
||||
eventlet.sleep(0)
|
||||
@ -919,8 +982,7 @@ class InvokeAIWebServer:
|
||||
|
||||
init_img_url = generation_parameters["init_img"]
|
||||
|
||||
original_bounding_box = generation_parameters["bounding_box"].copy(
|
||||
)
|
||||
original_bounding_box = generation_parameters["bounding_box"].copy()
|
||||
|
||||
initial_image = dataURL_to_image(
|
||||
generation_parameters["init_img"]
|
||||
@ -997,8 +1059,9 @@ class InvokeAIWebServer:
|
||||
elif generation_parameters["generation_mode"] == "img2img":
|
||||
init_img_url = generation_parameters["init_img"]
|
||||
init_img_path = self.get_image_path_from_url(init_img_url)
|
||||
generation_parameters["init_img"] = Image.open(
|
||||
init_img_path).convert('RGB')
|
||||
generation_parameters["init_img"] = Image.open(init_img_path).convert(
|
||||
"RGB"
|
||||
)
|
||||
|
||||
def image_progress(sample, step):
|
||||
if self.canceled.is_set():
|
||||
@ -1058,8 +1121,7 @@ class InvokeAIWebServer:
|
||||
)
|
||||
|
||||
if generation_parameters["progress_latents"]:
|
||||
image = self.generate.sample_to_lowres_estimated_image(
|
||||
sample)
|
||||
image = self.generate.sample_to_lowres_estimated_image(sample)
|
||||
(width, height) = image.size
|
||||
width *= 8
|
||||
height *= 8
|
||||
@ -1078,8 +1140,7 @@ class InvokeAIWebServer:
|
||||
},
|
||||
)
|
||||
|
||||
self.socketio.emit(
|
||||
"progressUpdate", progress.to_formatted_dict())
|
||||
self.socketio.emit("progressUpdate", progress.to_formatted_dict())
|
||||
eventlet.sleep(0)
|
||||
|
||||
def image_done(image, seed, first_seed, attention_maps_image=None):
|
||||
@ -1106,8 +1167,7 @@ class InvokeAIWebServer:
|
||||
|
||||
progress.set_current_status("common.statusGenerationComplete")
|
||||
|
||||
self.socketio.emit(
|
||||
"progressUpdate", progress.to_formatted_dict())
|
||||
self.socketio.emit("progressUpdate", progress.to_formatted_dict())
|
||||
eventlet.sleep(0)
|
||||
|
||||
all_parameters = generation_parameters
|
||||
@ -1118,8 +1178,7 @@ class InvokeAIWebServer:
|
||||
and all_parameters["variation_amount"] > 0
|
||||
):
|
||||
first_seed = first_seed or seed
|
||||
this_variation = [
|
||||
[seed, all_parameters["variation_amount"]]]
|
||||
this_variation = [[seed, all_parameters["variation_amount"]]]
|
||||
all_parameters["with_variations"] = (
|
||||
prior_variations + this_variation
|
||||
)
|
||||
@ -1135,14 +1194,13 @@ class InvokeAIWebServer:
|
||||
if esrgan_parameters:
|
||||
progress.set_current_status("common.statusUpscaling")
|
||||
progress.set_current_status_has_steps(False)
|
||||
self.socketio.emit(
|
||||
"progressUpdate", progress.to_formatted_dict())
|
||||
self.socketio.emit("progressUpdate", progress.to_formatted_dict())
|
||||
eventlet.sleep(0)
|
||||
|
||||
image = self.esrgan.process(
|
||||
image=image,
|
||||
upsampler_scale=esrgan_parameters["level"],
|
||||
denoise_str=esrgan_parameters['denoise_str'],
|
||||
denoise_str=esrgan_parameters["denoise_str"],
|
||||
strength=esrgan_parameters["strength"],
|
||||
seed=seed,
|
||||
)
|
||||
@ -1150,7 +1208,7 @@ class InvokeAIWebServer:
|
||||
postprocessing = True
|
||||
all_parameters["upscale"] = [
|
||||
esrgan_parameters["level"],
|
||||
esrgan_parameters['denoise_str'],
|
||||
esrgan_parameters["denoise_str"],
|
||||
esrgan_parameters["strength"],
|
||||
]
|
||||
|
||||
@ -1159,15 +1217,14 @@ class InvokeAIWebServer:
|
||||
|
||||
if facetool_parameters:
|
||||
if facetool_parameters["type"] == "gfpgan":
|
||||
progress.set_current_status(
|
||||
"common.statusRestoringFacesGFPGAN")
|
||||
progress.set_current_status("common.statusRestoringFacesGFPGAN")
|
||||
elif facetool_parameters["type"] == "codeformer":
|
||||
progress.set_current_status(
|
||||
"common.statusRestoringFacesCodeFormer")
|
||||
"common.statusRestoringFacesCodeFormer"
|
||||
)
|
||||
|
||||
progress.set_current_status_has_steps(False)
|
||||
self.socketio.emit(
|
||||
"progressUpdate", progress.to_formatted_dict())
|
||||
self.socketio.emit("progressUpdate", progress.to_formatted_dict())
|
||||
eventlet.sleep(0)
|
||||
|
||||
if facetool_parameters["type"] == "gfpgan":
|
||||
@ -1197,8 +1254,7 @@ class InvokeAIWebServer:
|
||||
all_parameters["facetool_type"] = facetool_parameters["type"]
|
||||
|
||||
progress.set_current_status("common.statusSavingImage")
|
||||
self.socketio.emit(
|
||||
"progressUpdate", progress.to_formatted_dict())
|
||||
self.socketio.emit("progressUpdate", progress.to_formatted_dict())
|
||||
eventlet.sleep(0)
|
||||
|
||||
# restore the stashed URLS and discard the paths, we are about to send the result to client
|
||||
@ -1215,8 +1271,7 @@ class InvokeAIWebServer:
|
||||
if generation_parameters["generation_mode"] == "unifiedCanvas":
|
||||
all_parameters["bounding_box"] = original_bounding_box
|
||||
|
||||
metadata = self.parameters_to_generated_image_metadata(
|
||||
all_parameters)
|
||||
metadata = self.parameters_to_generated_image_metadata(all_parameters)
|
||||
|
||||
command = parameters_to_command(all_parameters)
|
||||
|
||||
@ -1246,22 +1301,27 @@ class InvokeAIWebServer:
|
||||
|
||||
if progress.total_iterations > progress.current_iteration:
|
||||
progress.set_current_step(1)
|
||||
progress.set_current_status(
|
||||
"common.statusIterationComplete")
|
||||
progress.set_current_status("common.statusIterationComplete")
|
||||
progress.set_current_status_has_steps(False)
|
||||
else:
|
||||
progress.mark_complete()
|
||||
|
||||
self.socketio.emit(
|
||||
"progressUpdate", progress.to_formatted_dict())
|
||||
self.socketio.emit("progressUpdate", progress.to_formatted_dict())
|
||||
eventlet.sleep(0)
|
||||
|
||||
parsed_prompt, _ = get_prompt_structure(
|
||||
generation_parameters["prompt"])
|
||||
tokens = None if type(parsed_prompt) is Blend else \
|
||||
get_tokens_for_prompt_object(get_tokenizer(self.generate.model), parsed_prompt)
|
||||
attention_maps_image_base64_url = None if attention_maps_image is None \
|
||||
parsed_prompt, _ = get_prompt_structure(generation_parameters["prompt"])
|
||||
tokens = (
|
||||
None
|
||||
if type(parsed_prompt) is Blend
|
||||
else get_tokens_for_prompt_object(
|
||||
get_tokenizer(self.generate.model), parsed_prompt
|
||||
)
|
||||
)
|
||||
attention_maps_image_base64_url = (
|
||||
None
|
||||
if attention_maps_image is None
|
||||
else image_to_dataURL(attention_maps_image)
|
||||
)
|
||||
|
||||
self.socketio.emit(
|
||||
"generationResult",
|
||||
@ -1293,7 +1353,7 @@ class InvokeAIWebServer:
|
||||
self.generate.prompt2image(
|
||||
**generation_parameters,
|
||||
step_callback=diffusers_step_callback_adapter,
|
||||
image_callback=image_done
|
||||
image_callback=image_done,
|
||||
)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
@ -1416,8 +1476,7 @@ class InvokeAIWebServer:
|
||||
self, parameters, original_image_path
|
||||
):
|
||||
try:
|
||||
current_metadata = retrieve_metadata(
|
||||
original_image_path)["sd-metadata"]
|
||||
current_metadata = retrieve_metadata(original_image_path)["sd-metadata"]
|
||||
postprocessing_metadata = {}
|
||||
|
||||
"""
|
||||
@ -1457,8 +1516,7 @@ class InvokeAIWebServer:
|
||||
postprocessing_metadata
|
||||
)
|
||||
else:
|
||||
current_metadata["image"]["postprocessing"] = [
|
||||
postprocessing_metadata]
|
||||
current_metadata["image"]["postprocessing"] = [postprocessing_metadata]
|
||||
|
||||
return current_metadata
|
||||
|
||||
@ -1554,8 +1612,7 @@ class InvokeAIWebServer:
|
||||
)
|
||||
elif "thumbnails" in url:
|
||||
return os.path.abspath(
|
||||
os.path.join(self.thumbnail_image_path,
|
||||
os.path.basename(url))
|
||||
os.path.join(self.thumbnail_image_path, os.path.basename(url))
|
||||
)
|
||||
else:
|
||||
return os.path.abspath(
|
||||
@ -1601,7 +1658,7 @@ class InvokeAIWebServer:
|
||||
except Exception as e:
|
||||
self.handle_exceptions(e)
|
||||
|
||||
def handle_exceptions(self, exception, emit_key: str = 'error'):
|
||||
def handle_exceptions(self, exception, emit_key: str = "error"):
|
||||
self.socketio.emit(emit_key, {"message": (str(exception))})
|
||||
print("\n")
|
||||
traceback.print_exc()
|
||||
|
@ -13,14 +13,19 @@ sd-inpainting-1.5:
|
||||
vae:
|
||||
repo_id: stabilityai/sd-vae-ft-mse
|
||||
recommended: True
|
||||
stable-diffusion-2.1:
|
||||
stable-diffusion-2.1-768:
|
||||
description: Stable Diffusion version 2.1 diffusers model, trained on 768 pixel images (5.21 GB)
|
||||
repo_id: stabilityai/stable-diffusion-2-1
|
||||
format: diffusers
|
||||
recommended: True
|
||||
stable-diffusion-2.1-base:
|
||||
description: Stable Diffusion version 2.1 diffusers model, trained on 512 pixel images (5.21 GB)
|
||||
repo_id: stabilityai/stable-diffusion-2-1-base
|
||||
format: diffusers
|
||||
recommended: False
|
||||
sd-inpainting-2.0:
|
||||
description: Stable Diffusion version 2.0 inpainting model (5.21 GB)
|
||||
repo_id: stabilityai/stable-diffusion-2-1
|
||||
repo_id: stabilityai/stable-diffusion-2-inpainting
|
||||
format: diffusers
|
||||
recommended: False
|
||||
analog-diffusion-1.0:
|
||||
|
67
invokeai/configs/stable-diffusion/v2-inference.yaml
Normal file
67
invokeai/configs/stable-diffusion/v2-inference.yaml
Normal file
@ -0,0 +1,67 @@
|
||||
model:
|
||||
base_learning_rate: 1.0e-4
|
||||
target: ldm.models.diffusion.ddpm.LatentDiffusion
|
||||
params:
|
||||
linear_start: 0.00085
|
||||
linear_end: 0.0120
|
||||
num_timesteps_cond: 1
|
||||
log_every_t: 200
|
||||
timesteps: 1000
|
||||
first_stage_key: "jpg"
|
||||
cond_stage_key: "txt"
|
||||
image_size: 64
|
||||
channels: 4
|
||||
cond_stage_trainable: false
|
||||
conditioning_key: crossattn
|
||||
monitor: val/loss_simple_ema
|
||||
scale_factor: 0.18215
|
||||
use_ema: False # we set this to false because this is an inference only config
|
||||
|
||||
unet_config:
|
||||
target: ldm.modules.diffusionmodules.openaimodel.UNetModel
|
||||
params:
|
||||
use_checkpoint: True
|
||||
use_fp16: True
|
||||
image_size: 32 # unused
|
||||
in_channels: 4
|
||||
out_channels: 4
|
||||
model_channels: 320
|
||||
attention_resolutions: [ 4, 2, 1 ]
|
||||
num_res_blocks: 2
|
||||
channel_mult: [ 1, 2, 4, 4 ]
|
||||
num_head_channels: 64 # need to fix for flash-attn
|
||||
use_spatial_transformer: True
|
||||
use_linear_in_transformer: True
|
||||
transformer_depth: 1
|
||||
context_dim: 1024
|
||||
legacy: False
|
||||
|
||||
first_stage_config:
|
||||
target: ldm.models.autoencoder.AutoencoderKL
|
||||
params:
|
||||
embed_dim: 4
|
||||
monitor: val/rec_loss
|
||||
ddconfig:
|
||||
#attn_type: "vanilla-xformers"
|
||||
double_z: true
|
||||
z_channels: 4
|
||||
resolution: 256
|
||||
in_channels: 3
|
||||
out_ch: 3
|
||||
ch: 128
|
||||
ch_mult:
|
||||
- 1
|
||||
- 2
|
||||
- 4
|
||||
- 4
|
||||
num_res_blocks: 2
|
||||
attn_resolutions: []
|
||||
dropout: 0.0
|
||||
lossconfig:
|
||||
target: torch.nn.Identity
|
||||
|
||||
cond_stage_config:
|
||||
target: ldm.modules.encoders.modules.FrozenOpenCLIPEmbedder
|
||||
params:
|
||||
freeze: True
|
||||
layer: "penultimate"
|
@ -1,6 +1,7 @@
|
||||
module.exports = {
|
||||
trailingComma: 'es5',
|
||||
tabWidth: 2,
|
||||
endOfLine: 'auto',
|
||||
semi: true,
|
||||
singleQuote: true,
|
||||
overrides: [
|
||||
|
624
invokeai/frontend/dist/assets/index-0e39fbc4.js
vendored
624
invokeai/frontend/dist/assets/index-0e39fbc4.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
invokeai/frontend/dist/assets/index-2ab0eb58.css
vendored
Normal file
1
invokeai/frontend/dist/assets/index-2ab0eb58.css
vendored
Normal file
File diff suppressed because one or more lines are too long
603
invokeai/frontend/dist/assets/index-f56b39bc.js
vendored
Normal file
603
invokeai/frontend/dist/assets/index-f56b39bc.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
invokeai/frontend/dist/index.html
vendored
4
invokeai/frontend/dist/index.html
vendored
@ -5,8 +5,8 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>InvokeAI - A Stable Diffusion Toolkit</title>
|
||||
<link rel="shortcut icon" type="icon" href="./assets/favicon-0d253ced.ico" />
|
||||
<script type="module" crossorigin src="./assets/index-0e39fbc4.js"></script>
|
||||
<link rel="stylesheet" href="./assets/index-14cb2922.css">
|
||||
<script type="module" crossorigin src="./assets/index-f56b39bc.js"></script>
|
||||
<link rel="stylesheet" href="./assets/index-2ab0eb58.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
18
invokeai/frontend/dist/locales/en.json
vendored
18
invokeai/frontend/dist/locales/en.json
vendored
@ -63,7 +63,8 @@
|
||||
"statusConvertingModel": "Converting Model",
|
||||
"statusModelConverted": "Model Converted",
|
||||
"statusMergingModels": "Merging Models",
|
||||
"statusMergedModels": "Models Merged"
|
||||
"statusMergedModels": "Models Merged",
|
||||
"pinOptionsPanel": "Pin Options Panel"
|
||||
},
|
||||
"gallery": {
|
||||
"generations": "Generations",
|
||||
@ -326,6 +327,13 @@
|
||||
"addModel": "Add Model",
|
||||
"updateModel": "Update Model",
|
||||
"availableModels": "Available Models",
|
||||
"addLora": "Add Lora",
|
||||
"clearLoras": "Clear Loras",
|
||||
"noLoraModels": "No Loras Found",
|
||||
"addTextualInversionTrigger": "Add Textual Inversion",
|
||||
"addTIToNegative": "Add To Negative",
|
||||
"clearTextualInversions": "Clear Textual Inversions",
|
||||
"noTextualInversionTriggers": "No Textual Inversions Found",
|
||||
"search": "Search",
|
||||
"load": "Load",
|
||||
"active": "active",
|
||||
@ -364,7 +372,8 @@
|
||||
"convertToDiffusersHelpText6": "Do you wish to convert this model?",
|
||||
"convertToDiffusersSaveLocation": "Save Location",
|
||||
"v1": "v1",
|
||||
"v2": "v2",
|
||||
"v2_base": "v2 (512px)",
|
||||
"v2_768": "v2 (768px)",
|
||||
"inpainting": "v1 Inpainting",
|
||||
"customConfig": "Custom Config",
|
||||
"pathToCustomConfig": "Path To Custom Config",
|
||||
@ -393,7 +402,9 @@
|
||||
"modelMergeInterpAddDifferenceHelp": "In this mode, Model 3 is first subtracted from Model 2. The resulting version is blended with Model 1 with the alpha rate set above.",
|
||||
"inverseSigmoid": "Inverse Sigmoid",
|
||||
"sigmoid": "Sigmoid",
|
||||
"weightedSum": "Weighted Sum"
|
||||
"weightedSum": "Weighted Sum",
|
||||
"none": "none",
|
||||
"addDifference": "Add Difference"
|
||||
},
|
||||
"parameters": {
|
||||
"general": "General",
|
||||
@ -479,6 +490,7 @@
|
||||
"useCanvasBeta": "Use Canvas Beta Layout",
|
||||
"enableImageDebugging": "Enable Image Debugging",
|
||||
"useSlidersForAll": "Use Sliders For All Options",
|
||||
"showHuggingFaceConcepts": "Show Textual Inversions from HF Concepts Library",
|
||||
"resetWebUI": "Reset Web UI",
|
||||
"resetWebUIDesc1": "Resetting the web UI only resets the browser's local cache of your images and remembered settings. It does not delete any images from disk.",
|
||||
"resetWebUIDesc2": "If images aren't showing up in the gallery or something else isn't working, please try resetting before submitting an issue on GitHub.",
|
||||
|
115
invokeai/frontend/dist/locales/es.json
vendored
115
invokeai/frontend/dist/locales/es.json
vendored
@ -15,7 +15,7 @@
|
||||
"langSpanish": "Español",
|
||||
"nodesDesc": "Un sistema de generación de imágenes basado en nodos, actualmente se encuentra en desarrollo. Mantente pendiente a nuestras actualizaciones acerca de esta fabulosa funcionalidad.",
|
||||
"postProcessing": "Post-procesamiento",
|
||||
"postProcessDesc1": "Invoke AI ofrece una gran variedad de funciones de post-procesamiento, El aumento de tamaño y Restauración de Rostros ya se encuentran disponibles en la interfaz web, puedes acceder desde el menú de Opciones Avanzadas en las pestañas de Texto a Imagen y de Imagen a Imagen. También puedes acceder a estas funciones directamente mediante el botón de acciones en el menú superior de la imagen actual o en el visualizador",
|
||||
"postProcessDesc1": "Invoke AI ofrece una gran variedad de funciones de post-procesamiento, El aumento de tamaño y Restauración de Rostros ya se encuentran disponibles en la interfaz web, puedes acceder desde el menú de Opciones Avanzadas en las pestañas de Texto a Imagen y de Imagen a Imagen. También puedes acceder a estas funciones directamente mediante el botón de acciones en el menú superior de la imagen actual o en el visualizador.",
|
||||
"postProcessDesc2": "Una interfaz de usuario dedicada se lanzará pronto para facilitar flujos de trabajo de postprocesamiento más avanzado.",
|
||||
"postProcessDesc3": "La Interfaz de Línea de Comandos de Invoke AI ofrece muchas otras características, incluyendo -Embiggen-.",
|
||||
"training": "Entrenamiento",
|
||||
@ -44,7 +44,26 @@
|
||||
"statusUpscaling": "Aumentando Tamaño",
|
||||
"statusUpscalingESRGAN": "Restaurando Rostros(ESRGAN)",
|
||||
"statusLoadingModel": "Cargando Modelo",
|
||||
"statusModelChanged": "Modelo cambiado"
|
||||
"statusModelChanged": "Modelo cambiado",
|
||||
"statusMergedModels": "Modelos combinados",
|
||||
"githubLabel": "Github",
|
||||
"discordLabel": "Discord",
|
||||
"langEnglish": "Inglés",
|
||||
"langDutch": "Holandés",
|
||||
"langFrench": "Francés",
|
||||
"langGerman": "Alemán",
|
||||
"langItalian": "Italiano",
|
||||
"langArabic": "Árabe",
|
||||
"langJapanese": "Japones",
|
||||
"langPolish": "Polaco",
|
||||
"langBrPortuguese": "Portugués brasileño",
|
||||
"langRussian": "Ruso",
|
||||
"langSimplifiedChinese": "Chino simplificado",
|
||||
"langUkranian": "Ucraniano",
|
||||
"back": "Atrás",
|
||||
"statusConvertingModel": "Convertir el modelo",
|
||||
"statusModelConverted": "Modelo adaptado",
|
||||
"statusMergingModels": "Fusionar modelos"
|
||||
},
|
||||
"gallery": {
|
||||
"generations": "Generaciones",
|
||||
@ -284,16 +303,16 @@
|
||||
"nameValidationMsg": "Introduce un nombre para tu modelo",
|
||||
"description": "Descripción",
|
||||
"descriptionValidationMsg": "Introduce una descripción para tu modelo",
|
||||
"config": "Config",
|
||||
"configValidationMsg": "Ruta del archivo de configuración del modelo",
|
||||
"config": "Configurar",
|
||||
"configValidationMsg": "Ruta del archivo de configuración del modelo.",
|
||||
"modelLocation": "Ubicación del Modelo",
|
||||
"modelLocationValidationMsg": "Ruta del archivo de modelo",
|
||||
"modelLocationValidationMsg": "Ruta del archivo de modelo.",
|
||||
"vaeLocation": "Ubicación VAE",
|
||||
"vaeLocationValidationMsg": "Ruta del archivo VAE",
|
||||
"vaeLocationValidationMsg": "Ruta del archivo VAE.",
|
||||
"width": "Ancho",
|
||||
"widthValidationMsg": "Ancho predeterminado de tu modelo",
|
||||
"widthValidationMsg": "Ancho predeterminado de tu modelo.",
|
||||
"height": "Alto",
|
||||
"heightValidationMsg": "Alto predeterminado de tu modelo",
|
||||
"heightValidationMsg": "Alto predeterminado de tu modelo.",
|
||||
"addModel": "Añadir Modelo",
|
||||
"updateModel": "Actualizar Modelo",
|
||||
"availableModels": "Modelos disponibles",
|
||||
@ -320,7 +339,61 @@
|
||||
"deleteModel": "Eliminar Modelo",
|
||||
"deleteConfig": "Eliminar Configuración",
|
||||
"deleteMsg1": "¿Estás seguro de querer eliminar esta entrada de modelo de InvokeAI?",
|
||||
"deleteMsg2": "El checkpoint del modelo no se eliminará de tu disco. Puedes volver a añadirlo si lo deseas."
|
||||
"deleteMsg2": "El checkpoint del modelo no se eliminará de tu disco. Puedes volver a añadirlo si lo deseas.",
|
||||
"safetensorModels": "SafeTensors",
|
||||
"addDiffuserModel": "Añadir difusores",
|
||||
"inpainting": "v1 Repintado",
|
||||
"repoIDValidationMsg": "Repositorio en línea de tu modelo",
|
||||
"checkpointModels": "Puntos de control",
|
||||
"convertToDiffusersHelpText4": "Este proceso se realiza una sola vez. Puede tardar entre 30 y 60 segundos dependiendo de las especificaciones de tu ordenador.",
|
||||
"diffusersModels": "Difusores",
|
||||
"addCheckpointModel": "Agregar modelo de punto de control/Modelo Safetensor",
|
||||
"vaeRepoID": "Identificador del repositorio de VAE",
|
||||
"vaeRepoIDValidationMsg": "Repositorio en línea de tú VAE",
|
||||
"formMessageDiffusersModelLocation": "Difusores Modelo Ubicación",
|
||||
"formMessageDiffusersModelLocationDesc": "Por favor, introduzca al menos uno.",
|
||||
"formMessageDiffusersVAELocation": "Ubicación VAE",
|
||||
"formMessageDiffusersVAELocationDesc": "Si no se proporciona, InvokeAI buscará el archivo VAE dentro de la ubicación del modelo indicada anteriormente.",
|
||||
"convert": "Convertir",
|
||||
"convertToDiffusers": "Convertir en difusores",
|
||||
"convertToDiffusersHelpText1": "Este modelo se convertirá al formato 🧨 Difusores.",
|
||||
"convertToDiffusersHelpText2": "Este proceso sustituirá su entrada del Gestor de Modelos por la versión de Difusores del mismo modelo.",
|
||||
"convertToDiffusersHelpText3": "Su archivo de puntos de control en el disco NO será borrado ni modificado de ninguna manera. Puede volver a añadir su punto de control al Gestor de Modelos si lo desea.",
|
||||
"convertToDiffusersHelpText5": "Asegúrese de que dispone de suficiente espacio en disco. Los modelos suelen variar entre 4 GB y 7 GB de tamaño.",
|
||||
"convertToDiffusersHelpText6": "¿Desea transformar este modelo?",
|
||||
"convertToDiffusersSaveLocation": "Guardar ubicación",
|
||||
"v1": "v1",
|
||||
"v2": "v2",
|
||||
"statusConverting": "Adaptar",
|
||||
"modelConverted": "Modelo adaptado",
|
||||
"sameFolder": "La misma carpeta",
|
||||
"invokeRoot": "Carpeta InvokeAI",
|
||||
"custom": "Personalizado",
|
||||
"customSaveLocation": "Ubicación personalizada para guardar",
|
||||
"merge": "Fusión",
|
||||
"modelsMerged": "Modelos fusionados",
|
||||
"mergeModels": "Combinar modelos",
|
||||
"modelOne": "Modelo 1",
|
||||
"modelTwo": "Modelo 2",
|
||||
"modelThree": "Modelo 3",
|
||||
"mergedModelName": "Nombre del modelo combinado",
|
||||
"alpha": "Alfa",
|
||||
"interpolationType": "Tipo de interpolación",
|
||||
"mergedModelSaveLocation": "Guardar ubicación",
|
||||
"mergedModelCustomSaveLocation": "Ruta personalizada",
|
||||
"invokeAIFolder": "Invocar carpeta de la inteligencia artificial",
|
||||
"modelMergeHeaderHelp2": "Sólo se pueden fusionar difusores. Si desea fusionar un modelo de punto de control, conviértalo primero en difusores.",
|
||||
"modelMergeAlphaHelp": "Alfa controla la fuerza de mezcla de los modelos. Los valores alfa más bajos reducen la influencia del segundo modelo.",
|
||||
"modelMergeInterpAddDifferenceHelp": "En este modo, el Modelo 3 se sustrae primero del Modelo 2. La versión resultante se mezcla con el Modelo 1 con la tasa alfa establecida anteriormente. La versión resultante se mezcla con el Modelo 1 con la tasa alfa establecida anteriormente.",
|
||||
"ignoreMismatch": "Ignorar discrepancias entre modelos seleccionados",
|
||||
"modelMergeHeaderHelp1": "Puede combinar hasta tres modelos diferentes para crear una mezcla que se adapte a sus necesidades.",
|
||||
"inverseSigmoid": "Sigmoideo inverso",
|
||||
"weightedSum": "Modelo de suma ponderada",
|
||||
"sigmoid": "Función sigmoide",
|
||||
"allModels": "Todos los modelos",
|
||||
"repo_id": "Identificador del repositorio",
|
||||
"pathToCustomConfig": "Ruta a la configuración personalizada",
|
||||
"customConfig": "Configuración personalizada"
|
||||
},
|
||||
"parameters": {
|
||||
"images": "Imágenes",
|
||||
@ -380,7 +453,22 @@
|
||||
"info": "Información",
|
||||
"deleteImage": "Eliminar Imagen",
|
||||
"initialImage": "Imagen Inicial",
|
||||
"showOptionsPanel": "Mostrar panel de opciones"
|
||||
"showOptionsPanel": "Mostrar panel de opciones",
|
||||
"symmetry": "Simetría",
|
||||
"vSymmetryStep": "Paso de simetría V",
|
||||
"hSymmetryStep": "Paso de simetría H",
|
||||
"cancel": {
|
||||
"immediate": "Cancelar inmediatamente",
|
||||
"schedule": "Cancelar tras la iteración actual",
|
||||
"isScheduled": "Cancelando",
|
||||
"setType": "Tipo de cancelación"
|
||||
},
|
||||
"copyImage": "Copiar la imagen",
|
||||
"general": "General",
|
||||
"negativePrompts": "Preguntas negativas",
|
||||
"imageToImage": "Imagen a imagen",
|
||||
"denoisingStrength": "Intensidad de la eliminación del ruido",
|
||||
"hiresStrength": "Alta resistencia"
|
||||
},
|
||||
"settings": {
|
||||
"models": "Modelos",
|
||||
@ -393,7 +481,8 @@
|
||||
"resetWebUI": "Restablecer interfaz web",
|
||||
"resetWebUIDesc1": "Al restablecer la interfaz web, solo se restablece la caché local del navegador de sus imágenes y la configuración guardada. No se elimina ninguna imagen de su disco duro.",
|
||||
"resetWebUIDesc2": "Si las imágenes no se muestran en la galería o algo más no funciona, intente restablecer antes de reportar un incidente en GitHub.",
|
||||
"resetComplete": "La interfaz web se ha restablecido. Actualice la página para recargarla."
|
||||
"resetComplete": "La interfaz web se ha restablecido. Actualice la página para recargarla.",
|
||||
"useSlidersForAll": "Utilice controles deslizantes para todas las opciones"
|
||||
},
|
||||
"toast": {
|
||||
"tempFoldersEmptied": "Directorio temporal vaciado",
|
||||
@ -431,12 +520,12 @@
|
||||
"feature": {
|
||||
"prompt": "Este campo tomará todo el texto de entrada, incluidos tanto los términos de contenido como los estilísticos. Si bien se pueden incluir pesos en la solicitud, los comandos/parámetros estándar de línea de comandos no funcionarán.",
|
||||
"gallery": "Conforme se generan nuevas invocaciones, los archivos del directorio de salida se mostrarán aquí. Las generaciones tienen opciones adicionales para configurar nuevas generaciones.",
|
||||
"other": "Estas opciones habilitarán modos de procesamiento alternativos para Invoke. El modo sin costuras funciona para generar patrones repetitivos en la salida. La optimización de alta resolución realiza un ciclo de generación de dos pasos y debe usarse en resoluciones más altas cuando desee una imagen/composición más coherente.",
|
||||
"other": "Estas opciones habilitarán modos de procesamiento alternativos para Invoke. 'Seamless mosaico' creará patrones repetitivos en la salida. 'Alta resolución' es la generación en dos pasos con img2img: use esta configuración cuando desee una imagen más grande y más coherente sin artefactos. tomar más tiempo de lo habitual txt2img.",
|
||||
"seed": "Los valores de semilla proporcionan un conjunto inicial de ruido que guían el proceso de eliminación de ruido y se pueden aleatorizar o rellenar con una semilla de una invocación anterior. La función Umbral se puede usar para mitigar resultados indeseables a valores CFG más altos (intente entre 0-10), y Perlin se puede usar para agregar ruido Perlin al proceso de eliminación de ruido. Ambos sirven para agregar variación a sus salidas.",
|
||||
"variations": "Pruebe una variación con una cantidad entre 0 y 1 para cambiar la imagen de salida para la semilla establecida. Se encuentran variaciones interesantes en la semilla entre 0.1 y 0.3.",
|
||||
"upscale": "Usando ESRGAN, puede aumentar la resolución de salida sin requerir un ancho/alto más alto en la generación inicial.",
|
||||
"faceCorrection": "Usando GFPGAN o Codeformer, la corrección de rostros intentará identificar rostros en las salidas y corregir cualquier defecto/anormalidad. Los valores de fuerza más altos aplicarán una presión correctiva más fuerte en las salidas, lo que resultará en rostros más atractivos. Con Codeformer, una mayor fidelidad intentará preservar la imagen original, a expensas de la fuerza de corrección de rostros.",
|
||||
"imageToImage": "Imagen a Imagen permite cargar una imagen inicial, que InvokeAI usará para guiar el proceso de generación, junto con una solicitud. Un valor más bajo para esta configuración se parecerá más a la imagen original. Se aceptan valores entre 0-1, y se recomienda un rango de .25-.75.",
|
||||
"imageToImage": "Imagen a Imagen permite cargar una imagen inicial, que InvokeAI usará para guiar el proceso de generación, junto con una solicitud. Un valor más bajo para esta configuración se parecerá más a la imagen original. Se aceptan valores entre 0-1, y se recomienda un rango de .25-.75",
|
||||
"boundingBox": "La caja delimitadora es análoga a las configuraciones de Ancho y Alto para Texto a Imagen o Imagen a Imagen. Solo se procesará el área en la caja.",
|
||||
"seamCorrection": "Controla el manejo de parches visibles que pueden ocurrir cuando se pega una imagen generada de nuevo en el lienzo.",
|
||||
"infillAndScaling": "Administra los métodos de relleno (utilizados en áreas enmascaradas o borradas del lienzo) y la escala (útil para tamaños de caja delimitadora pequeños)."
|
||||
|
76
invokeai/frontend/dist/locales/pt_BR.json
vendored
76
invokeai/frontend/dist/locales/pt_BR.json
vendored
@ -44,7 +44,26 @@
|
||||
"statusUpscaling": "Redimensinando",
|
||||
"statusUpscalingESRGAN": "Redimensinando (ESRGAN)",
|
||||
"statusLoadingModel": "Carregando Modelo",
|
||||
"statusModelChanged": "Modelo Alterado"
|
||||
"statusModelChanged": "Modelo Alterado",
|
||||
"githubLabel": "Github",
|
||||
"discordLabel": "Discord",
|
||||
"langArabic": "Árabe",
|
||||
"langEnglish": "Inglês",
|
||||
"langDutch": "Holandês",
|
||||
"langFrench": "Francês",
|
||||
"langGerman": "Alemão",
|
||||
"langItalian": "Italiano",
|
||||
"langJapanese": "Japonês",
|
||||
"langPolish": "Polonês",
|
||||
"langSimplifiedChinese": "Chinês",
|
||||
"langUkranian": "Ucraniano",
|
||||
"back": "Voltar",
|
||||
"statusConvertingModel": "Convertendo Modelo",
|
||||
"statusModelConverted": "Modelo Convertido",
|
||||
"statusMergingModels": "Mesclando Modelos",
|
||||
"statusMergedModels": "Modelos Mesclados",
|
||||
"langRussian": "Russo",
|
||||
"langSpanish": "Espanhol"
|
||||
},
|
||||
"gallery": {
|
||||
"generations": "Gerações",
|
||||
@ -237,7 +256,7 @@
|
||||
"desc": "Salva a tela atual na galeria"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"title": "Copiar Para a Área de Transferência ",
|
||||
"title": "Copiar para a Área de Transferência",
|
||||
"desc": "Copia a tela atual para a área de transferência"
|
||||
},
|
||||
"downloadImage": {
|
||||
@ -284,7 +303,7 @@
|
||||
"nameValidationMsg": "Insira um nome para o seu modelo",
|
||||
"description": "Descrição",
|
||||
"descriptionValidationMsg": "Adicione uma descrição para o seu modelo",
|
||||
"config": "Config",
|
||||
"config": "Configuração",
|
||||
"configValidationMsg": "Caminho para o arquivo de configuração do seu modelo.",
|
||||
"modelLocation": "Localização do modelo",
|
||||
"modelLocationValidationMsg": "Caminho para onde seu modelo está localizado.",
|
||||
@ -317,7 +336,52 @@
|
||||
"deleteModel": "Excluir modelo",
|
||||
"deleteConfig": "Excluir Config",
|
||||
"deleteMsg1": "Tem certeza de que deseja excluir esta entrada do modelo de InvokeAI?",
|
||||
"deleteMsg2": "Isso não vai excluir o arquivo de modelo checkpoint do seu disco. Você pode lê-los, se desejar."
|
||||
"deleteMsg2": "Isso não vai excluir o arquivo de modelo checkpoint do seu disco. Você pode lê-los, se desejar.",
|
||||
"checkpointModels": "Checkpoints",
|
||||
"diffusersModels": "Diffusers",
|
||||
"safetensorModels": "SafeTensors",
|
||||
"addCheckpointModel": "Adicionar Modelo de Checkpoint/Safetensor",
|
||||
"addDiffuserModel": "Adicionar Diffusers",
|
||||
"repo_id": "Repo ID",
|
||||
"vaeRepoID": "VAE Repo ID",
|
||||
"vaeRepoIDValidationMsg": "Repositório Online do seu VAE",
|
||||
"scanAgain": "Digitalize Novamente",
|
||||
"selectAndAdd": "Selecione e Adicione Modelos Listados Abaixo",
|
||||
"noModelsFound": "Nenhum Modelo Encontrado",
|
||||
"formMessageDiffusersModelLocation": "Localização dos Modelos Diffusers",
|
||||
"formMessageDiffusersModelLocationDesc": "Por favor entre com ao menos um.",
|
||||
"formMessageDiffusersVAELocation": "Localização do VAE",
|
||||
"formMessageDiffusersVAELocationDesc": "Se não provido, InvokeAI irá procurar pelo arquivo VAE dentro do local do modelo.",
|
||||
"convertToDiffusers": "Converter para Diffusers",
|
||||
"convertToDiffusersHelpText1": "Este modelo será convertido para o formato 🧨 Diffusers.",
|
||||
"convertToDiffusersHelpText5": "Por favor, certifique-se de que você tenha espaço suficiente em disco. Os modelos geralmente variam entre 4GB e 7GB de tamanho.",
|
||||
"convertToDiffusersHelpText6": "Você deseja converter este modelo?",
|
||||
"convertToDiffusersSaveLocation": "Local para Salvar",
|
||||
"v1": "v1",
|
||||
"v2": "v2",
|
||||
"inpainting": "v1 Inpainting",
|
||||
"customConfig": "Configuração personalizada",
|
||||
"pathToCustomConfig": "Caminho para configuração personalizada",
|
||||
"convertToDiffusersHelpText3": "Seu arquivo de ponto de verificação no disco NÃO será excluído ou modificado de forma alguma. Você pode adicionar seu ponto de verificação ao Gerenciador de modelos novamente, se desejar.",
|
||||
"convertToDiffusersHelpText4": "Este é um processo único. Pode levar cerca de 30 a 60s, dependendo das especificações do seu computador.",
|
||||
"merge": "Mesclar",
|
||||
"modelsMerged": "Modelos mesclados",
|
||||
"mergeModels": "Mesclar modelos",
|
||||
"modelOne": "Modelo 1",
|
||||
"modelTwo": "Modelo 2",
|
||||
"modelThree": "Modelo 3",
|
||||
"statusConverting": "Convertendo",
|
||||
"modelConverted": "Modelo Convertido",
|
||||
"sameFolder": "Mesma pasta",
|
||||
"invokeRoot": "Pasta do InvokeAI",
|
||||
"custom": "Personalizado",
|
||||
"customSaveLocation": "Local de salvamento personalizado",
|
||||
"mergedModelName": "Nome do modelo mesclado",
|
||||
"alpha": "Alpha",
|
||||
"allModels": "Todos os Modelos",
|
||||
"repoIDValidationMsg": "Repositório Online do seu Modelo",
|
||||
"convert": "Converter",
|
||||
"convertToDiffusersHelpText2": "Este processo irá substituir sua entrada de Gerenciador de Modelos por uma versão Diffusers do mesmo modelo."
|
||||
},
|
||||
"parameters": {
|
||||
"images": "Imagems",
|
||||
@ -442,14 +506,14 @@
|
||||
"move": "Mover",
|
||||
"resetView": "Resetar Visualização",
|
||||
"mergeVisible": "Fundir Visível",
|
||||
"saveToGallery": "Save To Gallery",
|
||||
"saveToGallery": "Salvar na Galeria",
|
||||
"copyToClipboard": "Copiar para a Área de Transferência",
|
||||
"downloadAsImage": "Baixar Como Imagem",
|
||||
"undo": "Desfazer",
|
||||
"redo": "Refazer",
|
||||
"clearCanvas": "Limpar Tela",
|
||||
"canvasSettings": "Configurações de Tela",
|
||||
"showIntermediates": "Show Intermediates",
|
||||
"showIntermediates": "Mostrar Intermediários",
|
||||
"showGrid": "Mostrar Grade",
|
||||
"snapToGrid": "Encaixar na Grade",
|
||||
"darkenOutsideSelection": "Escurecer Seleção Externa",
|
||||
|
1
invokeai/frontend/dist/locales/ro.json
vendored
Normal file
1
invokeai/frontend/dist/locales/ro.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
{}
|
@ -15,8 +15,8 @@
|
||||
"postinstall": "patch-package"
|
||||
},
|
||||
"dependencies": {
|
||||
"@chakra-ui/icons": "^2.0.17",
|
||||
"@chakra-ui/react": "^2.5.1",
|
||||
"@chakra-ui/icons": "^2.0.18",
|
||||
"@chakra-ui/react": "^2.5.5",
|
||||
"@emotion/cache": "^11.10.5",
|
||||
"@emotion/react": "^11.10.6",
|
||||
"@emotion/styled": "^11.10.6",
|
||||
@ -52,6 +52,7 @@
|
||||
"redux-persist": "^6.0.0",
|
||||
"socket.io": "^4.6.0",
|
||||
"socket.io-client": "^4.6.0",
|
||||
"typescript": "^5.0.3",
|
||||
"use-image": "^1.1.0",
|
||||
"uuid": "^9.0.0",
|
||||
"yarn": "^1.22.19"
|
||||
@ -61,8 +62,8 @@
|
||||
"@types/react": "^18.0.28",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
"@types/react-transition-group": "^4.4.5",
|
||||
"@typescript-eslint/eslint-plugin": "^5.52.0",
|
||||
"@typescript-eslint/parser": "^5.52.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.57.0",
|
||||
"@typescript-eslint/parser": "^5.57.0",
|
||||
"babel-plugin-transform-imports": "^2.0.0",
|
||||
"eslint": "^8.34.0",
|
||||
"eslint-config-prettier": "^8.6.0",
|
||||
|
@ -63,7 +63,8 @@
|
||||
"statusConvertingModel": "Converting Model",
|
||||
"statusModelConverted": "Model Converted",
|
||||
"statusMergingModels": "Merging Models",
|
||||
"statusMergedModels": "Models Merged"
|
||||
"statusMergedModels": "Models Merged",
|
||||
"pinOptionsPanel": "Pin Options Panel"
|
||||
},
|
||||
"gallery": {
|
||||
"generations": "Generations",
|
||||
@ -326,6 +327,13 @@
|
||||
"addModel": "Add Model",
|
||||
"updateModel": "Update Model",
|
||||
"availableModels": "Available Models",
|
||||
"addLora": "Add Lora",
|
||||
"clearLoras": "Clear Loras",
|
||||
"noLoraModels": "No Loras Found",
|
||||
"addTextualInversionTrigger": "Add Textual Inversion",
|
||||
"addTIToNegative": "Add To Negative",
|
||||
"clearTextualInversions": "Clear Textual Inversions",
|
||||
"noTextualInversionTriggers": "No Textual Inversions Found",
|
||||
"search": "Search",
|
||||
"load": "Load",
|
||||
"active": "active",
|
||||
@ -364,7 +372,8 @@
|
||||
"convertToDiffusersHelpText6": "Do you wish to convert this model?",
|
||||
"convertToDiffusersSaveLocation": "Save Location",
|
||||
"v1": "v1",
|
||||
"v2": "v2",
|
||||
"v2_base": "v2 (512px)",
|
||||
"v2_768": "v2 (768px)",
|
||||
"inpainting": "v1 Inpainting",
|
||||
"customConfig": "Custom Config",
|
||||
"pathToCustomConfig": "Path To Custom Config",
|
||||
@ -393,7 +402,9 @@
|
||||
"modelMergeInterpAddDifferenceHelp": "In this mode, Model 3 is first subtracted from Model 2. The resulting version is blended with Model 1 with the alpha rate set above.",
|
||||
"inverseSigmoid": "Inverse Sigmoid",
|
||||
"sigmoid": "Sigmoid",
|
||||
"weightedSum": "Weighted Sum"
|
||||
"weightedSum": "Weighted Sum",
|
||||
"none": "none",
|
||||
"addDifference": "Add Difference"
|
||||
},
|
||||
"parameters": {
|
||||
"general": "General",
|
||||
@ -479,6 +490,7 @@
|
||||
"useCanvasBeta": "Use Canvas Beta Layout",
|
||||
"enableImageDebugging": "Enable Image Debugging",
|
||||
"useSlidersForAll": "Use Sliders For All Options",
|
||||
"showHuggingFaceConcepts": "Show Textual Inversions from HF Concepts Library",
|
||||
"resetWebUI": "Reset Web UI",
|
||||
"resetWebUIDesc1": "Resetting the web UI only resets the browser's local cache of your images and remembered settings. It does not delete any images from disk.",
|
||||
"resetWebUIDesc2": "If images aren't showing up in the gallery or something else isn't working, please try resetting before submitting an issue on GitHub.",
|
||||
|
17
invokeai/frontend/src/app/invokeai.d.ts
vendored
17
invokeai/frontend/src/app/invokeai.d.ts
vendored
@ -271,6 +271,23 @@ export declare type FoundModelResponse = {
|
||||
found_models: FoundModel[];
|
||||
};
|
||||
|
||||
export declare type FoundLora = {
|
||||
name: string;
|
||||
location: string;
|
||||
};
|
||||
|
||||
export declare type FoundTextualInversionTriggers = {
|
||||
name: string;
|
||||
location: string;
|
||||
};
|
||||
|
||||
export declare type FoundLorasRsponse = FoundLora[];
|
||||
|
||||
export declare type FoundTextualInversionTriggersResponse = {
|
||||
local_triggers: FoundTextualInversionTriggers[];
|
||||
huggingface_concepts: FoundTextualInversionTriggers[];
|
||||
};
|
||||
|
||||
export declare type SystemStatusResponse = SystemStatus;
|
||||
|
||||
export declare type SystemConfigResponse = SystemConfig;
|
||||
|
@ -52,6 +52,12 @@ export const requestModelChange = createAction<string>(
|
||||
'socketio/requestModelChange'
|
||||
);
|
||||
|
||||
export const getLoraModels = createAction<undefined>('socketio/getLoraModels');
|
||||
|
||||
export const getTextualInversionTriggers = createAction<undefined>(
|
||||
'socketio/getTextualInversionTriggers'
|
||||
);
|
||||
|
||||
export const saveStagingAreaImageToGallery = createAction<string>(
|
||||
'socketio/saveStagingAreaImageToGallery'
|
||||
);
|
||||
|
@ -196,6 +196,12 @@ const makeSocketIOEmitters = (
|
||||
dispatch(modelChangeRequested());
|
||||
socketio.emit('requestModelChange', modelName);
|
||||
},
|
||||
emitGetLoraModels: () => {
|
||||
socketio.emit('getLoraModels');
|
||||
},
|
||||
emitGetTextualInversionTriggers: () => {
|
||||
socketio.emit('getTextualInversionTriggers');
|
||||
},
|
||||
emitSaveStagingAreaImageToGallery: (url: string) => {
|
||||
socketio.emit('requestSaveStagingAreaImageToGallery', url);
|
||||
},
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
errorOccurred,
|
||||
processingCanceled,
|
||||
setCurrentStatus,
|
||||
setFoundLoras,
|
||||
setFoundModels,
|
||||
setIsCancelable,
|
||||
setIsConnected,
|
||||
@ -19,6 +20,8 @@ import {
|
||||
setSearchFolder,
|
||||
setSystemConfig,
|
||||
setSystemStatus,
|
||||
setFoundLocalTextualInversionTriggers,
|
||||
setFoundHuggingFaceTextualInversionTriggers,
|
||||
} from 'features/system/store/systemSlice';
|
||||
|
||||
import {
|
||||
@ -34,8 +37,10 @@ import type { RootState } from 'app/store';
|
||||
import { addImageToStagingArea } from 'features/canvas/store/canvasSlice';
|
||||
import {
|
||||
clearInitialImage,
|
||||
setHuggingFaceTextualInversionConcepts,
|
||||
setInfillMethod,
|
||||
setInitialImage,
|
||||
setLocalTextualInversionTriggers,
|
||||
setMaskPath,
|
||||
} from 'features/parameters/store/generationSlice';
|
||||
import { tabMap } from 'features/ui/store/tabMap';
|
||||
@ -392,7 +397,7 @@ const makeSocketIOListeners = (
|
||||
addLogEntry({
|
||||
timestamp: dateFormat(new Date(), 'isoDateTime'),
|
||||
message: `${i18n.t(
|
||||
'modelmanager:modelAdded'
|
||||
'modelManager.modelAdded'
|
||||
)}: ${deleted_model_name}`,
|
||||
level: 'info',
|
||||
})
|
||||
@ -400,7 +405,7 @@ const makeSocketIOListeners = (
|
||||
dispatch(
|
||||
addToast({
|
||||
title: `${i18n.t(
|
||||
'modelmanager:modelEntryDeleted'
|
||||
'modelManager.modelEntryDeleted'
|
||||
)}: ${deleted_model_name}`,
|
||||
status: 'success',
|
||||
duration: 2500,
|
||||
@ -424,7 +429,7 @@ const makeSocketIOListeners = (
|
||||
dispatch(
|
||||
addToast({
|
||||
title: `${i18n.t(
|
||||
'modelmanager:modelConverted'
|
||||
'modelManager.modelConverted'
|
||||
)}: ${converted_model_name}`,
|
||||
status: 'success',
|
||||
duration: 2500,
|
||||
@ -482,6 +487,37 @@ const makeSocketIOListeners = (
|
||||
})
|
||||
);
|
||||
},
|
||||
onFoundLoras: (data: InvokeAI.FoundLorasRsponse) => {
|
||||
dispatch(setFoundLoras(data));
|
||||
},
|
||||
onFoundTextualInversionTriggers: (
|
||||
data: InvokeAI.FoundTextualInversionTriggersResponse
|
||||
) => {
|
||||
const localTriggers = data.local_triggers;
|
||||
const huggingFaceConcepts = data.huggingface_concepts;
|
||||
|
||||
dispatch(setFoundLocalTextualInversionTriggers(localTriggers));
|
||||
dispatch(
|
||||
setFoundHuggingFaceTextualInversionTriggers(huggingFaceConcepts)
|
||||
);
|
||||
|
||||
// Assign Local TI's
|
||||
const foundLocalTINames: string[] = [];
|
||||
localTriggers.forEach((textualInversion) => {
|
||||
foundLocalTINames.push(textualInversion.name);
|
||||
});
|
||||
dispatch(setLocalTextualInversionTriggers(foundLocalTINames));
|
||||
|
||||
// Assign HuggingFace Concepts
|
||||
const foundHuggingFaceConceptNames: string[] = [];
|
||||
huggingFaceConcepts.forEach((concept) => {
|
||||
foundHuggingFaceConceptNames.push(concept.name);
|
||||
});
|
||||
dispatch(
|
||||
setHuggingFaceTextualInversionConcepts(foundHuggingFaceConceptNames)
|
||||
);
|
||||
},
|
||||
|
||||
onTempFolderEmptied: () => {
|
||||
dispatch(
|
||||
addToast({
|
||||
|
@ -51,6 +51,8 @@ export const socketioMiddleware = () => {
|
||||
onModelConverted,
|
||||
onModelsMerged,
|
||||
onModelChangeFailed,
|
||||
onFoundLoras,
|
||||
onFoundTextualInversionTriggers,
|
||||
onTempFolderEmptied,
|
||||
} = makeSocketIOListeners(store);
|
||||
|
||||
@ -69,6 +71,8 @@ export const socketioMiddleware = () => {
|
||||
emitConvertToDiffusers,
|
||||
emitMergeDiffusersModels,
|
||||
emitRequestModelChange,
|
||||
emitGetLoraModels,
|
||||
emitGetTextualInversionTriggers,
|
||||
emitSaveStagingAreaImageToGallery,
|
||||
emitRequestEmptyTempFolder,
|
||||
} = makeSocketIOEmitters(store, socketio);
|
||||
@ -145,6 +149,17 @@ export const socketioMiddleware = () => {
|
||||
onModelChangeFailed(data);
|
||||
});
|
||||
|
||||
socketio.on('foundLoras', (data: InvokeAI.FoundLorasRsponse) => {
|
||||
onFoundLoras(data);
|
||||
});
|
||||
|
||||
socketio.on(
|
||||
'foundTextualInversionTriggers',
|
||||
(data: InvokeAI.FoundTextualInversionTriggersResponse) => {
|
||||
onFoundTextualInversionTriggers(data);
|
||||
}
|
||||
);
|
||||
|
||||
socketio.on('tempFolderEmptied', () => {
|
||||
onTempFolderEmptied();
|
||||
});
|
||||
@ -226,6 +241,16 @@ export const socketioMiddleware = () => {
|
||||
break;
|
||||
}
|
||||
|
||||
case 'socketio/getLoraModels': {
|
||||
emitGetLoraModels();
|
||||
break;
|
||||
}
|
||||
|
||||
case 'socketio/getTextualInversionTriggers': {
|
||||
emitGetTextualInversionTriggers();
|
||||
break;
|
||||
}
|
||||
|
||||
case 'socketio/saveStagingAreaImageToGallery': {
|
||||
emitSaveStagingAreaImageToGallery(action.payload);
|
||||
break;
|
||||
|
@ -7,13 +7,14 @@ import {
|
||||
MenuButtonProps,
|
||||
MenuListProps,
|
||||
MenuItemProps,
|
||||
Text,
|
||||
} from '@chakra-ui/react';
|
||||
import { MouseEventHandler, ReactNode } from 'react';
|
||||
import { MdArrowDropDown, MdArrowDropUp } from 'react-icons/md';
|
||||
import IAIButton from './IAIButton';
|
||||
import IAIIconButton from './IAIIconButton';
|
||||
|
||||
interface IAIMenuItem {
|
||||
export interface IAIMenuItem {
|
||||
item: ReactNode | string;
|
||||
onClick: MouseEventHandler<HTMLButtonElement> | undefined;
|
||||
}
|
||||
@ -43,6 +44,7 @@ export default function IAISimpleMenu(props: IAIMenuProps) {
|
||||
|
||||
const renderMenuItems = () => {
|
||||
const menuItemsToRender: ReactNode[] = [];
|
||||
|
||||
menuItems.forEach((menuItem, index) => {
|
||||
menuItemsToRender.push(
|
||||
<MenuItem
|
||||
@ -82,12 +84,17 @@ export default function IAISimpleMenu(props: IAIMenuProps) {
|
||||
fontSize="1.5rem"
|
||||
{...menuButtonProps}
|
||||
>
|
||||
{menuType === 'regular' && buttonText}
|
||||
{menuType === 'regular' && (
|
||||
<Text fontSize="0.9rem">{buttonText}</Text>
|
||||
)}
|
||||
</MenuButton>
|
||||
<MenuList
|
||||
zIndex={15}
|
||||
padding={0}
|
||||
borderRadius="0.5rem"
|
||||
overflow="scroll"
|
||||
maxWidth={'22.5rem'}
|
||||
maxHeight={500}
|
||||
backgroundColor="var(--background-color-secondary)"
|
||||
color="var(--text-color-secondary)"
|
||||
borderColor="var(--border-color)"
|
||||
|
@ -144,8 +144,8 @@ export const frontendToBackendParameters = (
|
||||
variationAmount,
|
||||
width,
|
||||
shouldUseSymmetry,
|
||||
horizontalSymmetryTimePercentage,
|
||||
verticalSymmetryTimePercentage,
|
||||
horizontalSymmetrySteps,
|
||||
verticalSymmetrySteps,
|
||||
} = generationState;
|
||||
|
||||
const {
|
||||
@ -185,17 +185,17 @@ export const frontendToBackendParameters = (
|
||||
|
||||
// Symmetry Settings
|
||||
if (shouldUseSymmetry) {
|
||||
if (horizontalSymmetryTimePercentage > 0) {
|
||||
if (horizontalSymmetrySteps > 0) {
|
||||
generationParameters.h_symmetry_time_pct = Math.max(
|
||||
0,
|
||||
Math.min(1, horizontalSymmetryTimePercentage / steps)
|
||||
Math.min(1, horizontalSymmetrySteps / steps)
|
||||
);
|
||||
}
|
||||
|
||||
if (horizontalSymmetryTimePercentage > 0) {
|
||||
if (verticalSymmetrySteps > 0) {
|
||||
generationParameters.v_symmetry_time_pct = Math.max(
|
||||
0,
|
||||
Math.min(1, verticalSymmetryTimePercentage / steps)
|
||||
Math.min(1, verticalSymmetrySteps / steps)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ const IAICanvasStatusText = () => {
|
||||
color: boundingBoxColor,
|
||||
}}
|
||||
>{`${t(
|
||||
'unifiedcanvas:boundingBox'
|
||||
'unifiedCanvas.boundingBox'
|
||||
)}: ${boundingBoxDimensionsString}`}</div>
|
||||
)}
|
||||
{shouldShowScaledBoundingBox && (
|
||||
@ -118,19 +118,19 @@ const IAICanvasStatusText = () => {
|
||||
color: boundingBoxColor,
|
||||
}}
|
||||
>{`${t(
|
||||
'unifiedcanvas:scaledBoundingBox'
|
||||
'unifiedCanvas.scaledBoundingBox'
|
||||
)}: ${scaledBoundingBoxDimensionsString}`}</div>
|
||||
)}
|
||||
{shouldShowCanvasDebugInfo && (
|
||||
<>
|
||||
<div>{`${t(
|
||||
'unifiedcanvas:boundingBoxPosition'
|
||||
'unifiedCanvas.boundingBoxPosition'
|
||||
)}: ${boundingBoxCoordinatesString}`}</div>
|
||||
<div>{`${t(
|
||||
'unifiedcanvas:canvasDimensions'
|
||||
'unifiedCanvas.canvasDimensions'
|
||||
)}: ${canvasDimensionsString}`}</div>
|
||||
<div>{`${t(
|
||||
'unifiedcanvas:canvasPosition'
|
||||
'unifiedCanvas.canvasPosition'
|
||||
)}: ${canvasCoordinatesString}`}</div>
|
||||
<IAICanvasStatusTextCursorPos />
|
||||
</>
|
||||
|
@ -34,7 +34,7 @@ export default function IAICanvasStatusTextCursorPos() {
|
||||
|
||||
return (
|
||||
<div>{`${t(
|
||||
'unifiedcanvas:cursorPosition'
|
||||
'unifiedCanvas.cursorPosition'
|
||||
)}: ${cursorCoordinatesString}`}</div>
|
||||
);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import {
|
||||
setInitialImage,
|
||||
setSeed,
|
||||
} from 'features/parameters/store/generationSlice';
|
||||
import { setAllPostProcessingParameters } from 'features/parameters/store/postprocessingSlice';
|
||||
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
|
||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||
import { SystemState } from 'features/system/store/systemSlice';
|
||||
@ -189,11 +190,12 @@ const CurrentImageButtons = () => {
|
||||
);
|
||||
|
||||
const handleClickUseAllParameters = () => {
|
||||
if (!currentImage) return;
|
||||
currentImage.metadata && dispatch(setAllParameters(currentImage.metadata));
|
||||
if (currentImage.metadata?.image.type === 'img2img') {
|
||||
if (!currentImage?.metadata) return;
|
||||
dispatch(setAllParameters(currentImage.metadata));
|
||||
dispatch(setAllPostProcessingParameters(currentImage.metadata));
|
||||
if (currentImage.metadata.image.type === 'img2img') {
|
||||
dispatch(setActiveTab('img2img'));
|
||||
} else if (currentImage.metadata?.image.type === 'txt2img') {
|
||||
} else if (currentImage.metadata.image.type === 'txt2img') {
|
||||
dispatch(setActiveTab('txt2img'));
|
||||
}
|
||||
};
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
setInitialImage,
|
||||
setSeed,
|
||||
} from 'features/parameters/store/generationSlice';
|
||||
import { setAllPostProcessingParameters } from 'features/parameters/store/postprocessingSlice';
|
||||
import { DragEvent, memo, useState } from 'react';
|
||||
import { FaCheck, FaTrashAlt } from 'react-icons/fa';
|
||||
import DeleteImageModal from './DeleteImageModal';
|
||||
@ -114,7 +115,10 @@ const HoverableImage = memo((props: HoverableImageProps) => {
|
||||
};
|
||||
|
||||
const handleUseAllParameters = () => {
|
||||
metadata && dispatch(setAllParameters(metadata));
|
||||
if (metadata) {
|
||||
dispatch(setAllParameters(metadata));
|
||||
dispatch(setAllPostProcessingParameters(metadata));
|
||||
}
|
||||
toast({
|
||||
title: t('toast.parametersSet'),
|
||||
status: 'success',
|
||||
|
@ -2,18 +2,18 @@ import { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import {
|
||||
setHorizontalSymmetryTimePercentage,
|
||||
setVerticalSymmetryTimePercentage,
|
||||
setHorizontalSymmetrySteps,
|
||||
setVerticalSymmetrySteps,
|
||||
} from 'features/parameters/store/generationSlice';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function SymmetrySettings() {
|
||||
const horizontalSymmetryTimePercentage = useAppSelector(
|
||||
(state: RootState) => state.generation.horizontalSymmetryTimePercentage
|
||||
const horizontalSymmetrySteps = useAppSelector(
|
||||
(state: RootState) => state.generation.horizontalSymmetrySteps
|
||||
);
|
||||
|
||||
const verticalSymmetryTimePercentage = useAppSelector(
|
||||
(state: RootState) => state.generation.verticalSymmetryTimePercentage
|
||||
const verticalSymmetrySteps = useAppSelector(
|
||||
(state: RootState) => state.generation.verticalSymmetrySteps
|
||||
);
|
||||
|
||||
const steps = useAppSelector((state: RootState) => state.generation.steps);
|
||||
@ -26,28 +26,28 @@ export default function SymmetrySettings() {
|
||||
<>
|
||||
<IAISlider
|
||||
label={t('parameters.hSymmetryStep')}
|
||||
value={horizontalSymmetryTimePercentage}
|
||||
onChange={(v) => dispatch(setHorizontalSymmetryTimePercentage(v))}
|
||||
value={horizontalSymmetrySteps}
|
||||
onChange={(v) => dispatch(setHorizontalSymmetrySteps(v))}
|
||||
min={0}
|
||||
max={steps}
|
||||
step={1}
|
||||
withInput
|
||||
withSliderMarks
|
||||
withReset
|
||||
handleReset={() => dispatch(setHorizontalSymmetryTimePercentage(0))}
|
||||
handleReset={() => dispatch(setHorizontalSymmetrySteps(0))}
|
||||
sliderMarkRightOffset={-6}
|
||||
></IAISlider>
|
||||
<IAISlider
|
||||
label={t('parameters.vSymmetryStep')}
|
||||
value={verticalSymmetryTimePercentage}
|
||||
onChange={(v) => dispatch(setVerticalSymmetryTimePercentage(v))}
|
||||
value={verticalSymmetrySteps}
|
||||
onChange={(v) => dispatch(setVerticalSymmetrySteps(v))}
|
||||
min={0}
|
||||
max={steps}
|
||||
step={1}
|
||||
withInput
|
||||
withSliderMarks
|
||||
withReset
|
||||
handleReset={() => dispatch(setVerticalSymmetryTimePercentage(0))}
|
||||
handleReset={() => dispatch(setVerticalSymmetrySteps(0))}
|
||||
sliderMarkRightOffset={-6}
|
||||
></IAISlider>
|
||||
</>
|
||||
|
@ -3,7 +3,10 @@ import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAINumberInput from 'common/components/IAINumberInput';
|
||||
|
||||
import IAISlider from 'common/components/IAISlider';
|
||||
import { setSteps } from 'features/parameters/store/generationSlice';
|
||||
import {
|
||||
clampSymmetrySteps,
|
||||
setSteps,
|
||||
} from 'features/parameters/store/generationSlice';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function MainSteps() {
|
||||
@ -14,7 +17,13 @@ export default function MainSteps() {
|
||||
);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleChangeSteps = (v: number) => dispatch(setSteps(v));
|
||||
const handleChangeSteps = (v: number) => {
|
||||
dispatch(setSteps(v));
|
||||
};
|
||||
|
||||
const handleBlur = () => {
|
||||
dispatch(clampSymmetrySteps());
|
||||
};
|
||||
|
||||
return shouldUseSliders ? (
|
||||
<IAISlider
|
||||
@ -41,6 +50,7 @@ export default function MainSteps() {
|
||||
width="auto"
|
||||
styleClass="main-settings-block"
|
||||
textAlign="center"
|
||||
onBlur={handleBlur}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -34,7 +34,6 @@ export default function MainWidth() {
|
||||
withSliderMarks
|
||||
sliderMarkRightOffset={-8}
|
||||
inputWidth="6.2rem"
|
||||
inputReadOnly
|
||||
sliderNumberInputProps={{ max: 15360 }}
|
||||
/>
|
||||
) : (
|
||||
|
@ -5,6 +5,7 @@ import IAIButton, { IAIButtonProps } from 'common/components/IAIButton';
|
||||
import IAIIconButton, {
|
||||
IAIIconButtonProps,
|
||||
} from 'common/components/IAIIconButton';
|
||||
import { clampSymmetrySteps } from 'features/parameters/store/generationSlice';
|
||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -30,6 +31,7 @@ export default function InvokeButton(props: InvokeButton) {
|
||||
useHotkeys(
|
||||
['ctrl+enter', 'meta+enter'],
|
||||
() => {
|
||||
dispatch(clampSymmetrySteps());
|
||||
dispatch(generateImage(activeTabName));
|
||||
},
|
||||
{
|
||||
|
@ -0,0 +1,86 @@
|
||||
import { Box, Flex } from '@chakra-ui/react';
|
||||
import { getLoraModels } from 'app/socketio/actions';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAIIconButton from 'common/components/IAIIconButton';
|
||||
import IAISimpleMenu, { IAIMenuItem } from 'common/components/IAISimpleMenu';
|
||||
import {
|
||||
setClearLoras,
|
||||
setLorasInUse,
|
||||
} from 'features/parameters/store/generationSlice';
|
||||
import { useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { MdClear } from 'react-icons/md';
|
||||
|
||||
export default function LoraManager() {
|
||||
const dispatch = useAppDispatch();
|
||||
const foundLoras = useAppSelector((state) => state.system.foundLoras);
|
||||
const lorasInUse = useAppSelector((state) => state.generation.lorasInUse);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleLora = (lora: string) => {
|
||||
dispatch(setLorasInUse(lora));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(getLoraModels());
|
||||
}, [dispatch]);
|
||||
|
||||
const renderLoraOption = (lora: string) => {
|
||||
const thisloraExists = lorasInUse.includes(lora);
|
||||
const loraExistsStyle = {
|
||||
fontWeight: 'bold',
|
||||
color: 'var(--context-menu-active-item)',
|
||||
};
|
||||
return <Box style={thisloraExists ? loraExistsStyle : {}}>{lora}</Box>;
|
||||
};
|
||||
|
||||
const numOfActiveLoras = () => {
|
||||
const foundLoraNames: string[] = [];
|
||||
foundLoras?.forEach((lora) => {
|
||||
foundLoraNames.push(lora.name);
|
||||
});
|
||||
return foundLoraNames.filter((lora) => lorasInUse.includes(lora)).length;
|
||||
};
|
||||
|
||||
const makeLoraItems = () => {
|
||||
const lorasFound: IAIMenuItem[] = [];
|
||||
foundLoras?.forEach((lora) => {
|
||||
if (lora.name !== ' ') {
|
||||
const newLoraItem: IAIMenuItem = {
|
||||
item: renderLoraOption(lora.name),
|
||||
onClick: () => handleLora(lora.name),
|
||||
};
|
||||
lorasFound.push(newLoraItem);
|
||||
}
|
||||
});
|
||||
return lorasFound;
|
||||
};
|
||||
|
||||
return foundLoras && foundLoras?.length > 0 ? (
|
||||
<Flex columnGap={2}>
|
||||
<IAISimpleMenu
|
||||
menuItems={makeLoraItems()}
|
||||
menuType="regular"
|
||||
buttonText={`${t('modelManager.addLora')} (${numOfActiveLoras()})`}
|
||||
menuButtonProps={{ width: '100%', padding: '0 1rem' }}
|
||||
/>
|
||||
<IAIIconButton
|
||||
icon={<MdClear />}
|
||||
tooltip={t('modelManager.clearLoras')}
|
||||
aria-label={t('modelManager.clearLoras')}
|
||||
onClick={() => dispatch(setClearLoras())}
|
||||
/>
|
||||
</Flex>
|
||||
) : (
|
||||
<Box
|
||||
background="var(--btn-base-color)"
|
||||
padding={2}
|
||||
textAlign="center"
|
||||
borderRadius={4}
|
||||
fontWeight="bold"
|
||||
>
|
||||
{t('modelManager.noLoraModels')}
|
||||
</Box>
|
||||
);
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import LoraManager from './LoraManager/LoraManager';
|
||||
import TextualInversionManager from './TextualInversionManager/TextualInversionManager';
|
||||
|
||||
export default function PromptExtras() {
|
||||
return (
|
||||
<Flex flexDir="column" rowGap={2}>
|
||||
<LoraManager />
|
||||
<TextualInversionManager />
|
||||
</Flex>
|
||||
);
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
import { Box, Flex } from '@chakra-ui/react';
|
||||
import { getTextualInversionTriggers } from 'app/socketio/actions';
|
||||
import { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import IAIIconButton from 'common/components/IAIIconButton';
|
||||
import IAISimpleMenu, { IAIMenuItem } from 'common/components/IAISimpleMenu';
|
||||
import {
|
||||
setAddTIToNegative,
|
||||
setClearTextualInversions,
|
||||
setTextualInversionsInUse,
|
||||
} from 'features/parameters/store/generationSlice';
|
||||
import { useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { MdArrowDownward, MdClear } from 'react-icons/md';
|
||||
|
||||
export default function TextualInversionManager() {
|
||||
const dispatch = useAppDispatch();
|
||||
const textualInversionsInUse = useAppSelector(
|
||||
(state: RootState) => state.generation.textualInversionsInUse
|
||||
);
|
||||
|
||||
const negativeTextualInversionsInUse = useAppSelector(
|
||||
(state: RootState) => state.generation.negativeTextualInversionsInUse
|
||||
);
|
||||
|
||||
const foundLocalTextualInversionTriggers = useAppSelector(
|
||||
(state) => state.system.foundLocalTextualInversionTriggers
|
||||
);
|
||||
const foundHuggingFaceTextualInversionTriggers = useAppSelector(
|
||||
(state) => state.system.foundHuggingFaceTextualInversionTriggers
|
||||
);
|
||||
|
||||
const localTextualInversionTriggers = useAppSelector(
|
||||
(state) => state.generation.localTextualInversionTriggers
|
||||
);
|
||||
|
||||
const huggingFaceTextualInversionConcepts = useAppSelector(
|
||||
(state) => state.generation.huggingFaceTextualInversionConcepts
|
||||
);
|
||||
|
||||
const shouldShowHuggingFaceConcepts = useAppSelector(
|
||||
(state) => state.ui.shouldShowHuggingFaceConcepts
|
||||
);
|
||||
|
||||
const addTIToNegative = useAppSelector(
|
||||
(state) => state.generation.addTIToNegative
|
||||
);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(getTextualInversionTriggers());
|
||||
}, [dispatch]);
|
||||
|
||||
const handleTextualInversion = (textual_inversion: string) => {
|
||||
dispatch(setTextualInversionsInUse(textual_inversion));
|
||||
};
|
||||
|
||||
const TIPip = ({ color }: { color: string }) => {
|
||||
return (
|
||||
<Box width={2} height={2} borderRadius={9999} backgroundColor={color}>
|
||||
{' '}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const renderTextualInversionOption = (textual_inversion: string) => {
|
||||
return (
|
||||
<Flex alignItems="center" columnGap={1}>
|
||||
{textual_inversion}
|
||||
{textualInversionsInUse.includes(textual_inversion) && (
|
||||
<TIPip color="var(--context-menu-active-item)" />
|
||||
)}
|
||||
{negativeTextualInversionsInUse.includes(textual_inversion) && (
|
||||
<TIPip color="var(--status-bad-color)" />
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
const numOfActiveTextualInversions = () => {
|
||||
const allTextualInversions = localTextualInversionTriggers.concat(
|
||||
huggingFaceTextualInversionConcepts
|
||||
);
|
||||
return allTextualInversions.filter(
|
||||
(ti) =>
|
||||
textualInversionsInUse.includes(ti) ||
|
||||
negativeTextualInversionsInUse.includes(ti)
|
||||
).length;
|
||||
};
|
||||
|
||||
const makeTextualInversionItems = () => {
|
||||
const textualInversionsFound: IAIMenuItem[] = [];
|
||||
foundLocalTextualInversionTriggers?.forEach((textualInversion) => {
|
||||
if (textualInversion.name !== ' ') {
|
||||
const newTextualInversionItem: IAIMenuItem = {
|
||||
item: renderTextualInversionOption(textualInversion.name),
|
||||
onClick: () => handleTextualInversion(textualInversion.name),
|
||||
};
|
||||
textualInversionsFound.push(newTextualInversionItem);
|
||||
}
|
||||
});
|
||||
|
||||
if (shouldShowHuggingFaceConcepts) {
|
||||
foundHuggingFaceTextualInversionTriggers?.forEach((textualInversion) => {
|
||||
if (textualInversion.name !== ' ') {
|
||||
const newTextualInversionItem: IAIMenuItem = {
|
||||
item: renderTextualInversionOption(textualInversion.name),
|
||||
onClick: () => handleTextualInversion(textualInversion.name),
|
||||
};
|
||||
textualInversionsFound.push(newTextualInversionItem);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return textualInversionsFound;
|
||||
};
|
||||
|
||||
return foundLocalTextualInversionTriggers &&
|
||||
(foundLocalTextualInversionTriggers?.length > 0 ||
|
||||
(foundHuggingFaceTextualInversionTriggers &&
|
||||
foundHuggingFaceTextualInversionTriggers?.length > 0 &&
|
||||
shouldShowHuggingFaceConcepts)) ? (
|
||||
<Flex columnGap={2}>
|
||||
<IAISimpleMenu
|
||||
menuItems={makeTextualInversionItems()}
|
||||
menuType="regular"
|
||||
buttonText={`${t(
|
||||
'modelManager.addTextualInversionTrigger'
|
||||
)} (${numOfActiveTextualInversions()})`}
|
||||
menuButtonProps={{
|
||||
width: '100%',
|
||||
padding: '0 1rem',
|
||||
}}
|
||||
/>
|
||||
<IAIIconButton
|
||||
icon={<MdArrowDownward />}
|
||||
style={{
|
||||
backgroundColor: addTIToNegative ? 'var(--btn-delete-image)' : '',
|
||||
}}
|
||||
tooltip={t('modelManager.addTIToNegative')}
|
||||
aria-label={t('modelManager.addTIToNegative')}
|
||||
onClick={() => dispatch(setAddTIToNegative(!addTIToNegative))}
|
||||
/>
|
||||
<IAIIconButton
|
||||
icon={<MdClear />}
|
||||
tooltip={t('modelManager.clearTextualInversions')}
|
||||
aria-label={t('modelManager.clearTextualInversions')}
|
||||
onClick={() => dispatch(setClearTextualInversions())}
|
||||
/>
|
||||
</Flex>
|
||||
) : (
|
||||
<Box
|
||||
background="var(--btn-base-color)"
|
||||
padding={2}
|
||||
textAlign="center"
|
||||
borderRadius={4}
|
||||
fontWeight="bold"
|
||||
>
|
||||
{t('modelManager.noTextualInversionTriggers')}
|
||||
</Box>
|
||||
);
|
||||
}
|
@ -1,24 +1,43 @@
|
||||
import { FormControl, Textarea } from '@chakra-ui/react';
|
||||
import type { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import { setNegativePrompt } from 'features/parameters/store/generationSlice';
|
||||
import {
|
||||
handlePromptCheckers,
|
||||
setNegativePrompt,
|
||||
} from 'features/parameters/store/generationSlice';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ChangeEvent, useState } from 'react';
|
||||
|
||||
const NegativePromptInput = () => {
|
||||
const negativePrompt = useAppSelector(
|
||||
(state: RootState) => state.generation.negativePrompt
|
||||
);
|
||||
|
||||
const [promptTimer, setPromptTimer] = useState<number | undefined>(undefined);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleNegativeChangePrompt = (e: ChangeEvent<HTMLTextAreaElement>) => {
|
||||
dispatch(setNegativePrompt(e.target.value));
|
||||
|
||||
// Debounce Prompt UI Checking
|
||||
clearTimeout(promptTimer);
|
||||
const newPromptTimer = window.setTimeout(() => {
|
||||
dispatch(
|
||||
handlePromptCheckers({ prompt: e.target.value, toNegative: true })
|
||||
);
|
||||
}, 500);
|
||||
setPromptTimer(newPromptTimer);
|
||||
};
|
||||
|
||||
return (
|
||||
<FormControl>
|
||||
<Textarea
|
||||
id="negativePrompt"
|
||||
name="negativePrompt"
|
||||
value={negativePrompt}
|
||||
onChange={(e) => dispatch(setNegativePrompt(e.target.value))}
|
||||
onChange={handleNegativeChangePrompt}
|
||||
background="var(--prompt-bg-color)"
|
||||
placeholder={t('parameters.negativePrompts')}
|
||||
_placeholder={{ fontSize: '0.8rem' }}
|
||||
|
@ -2,12 +2,13 @@ import { FormControl, Textarea } from '@chakra-ui/react';
|
||||
import { generateImage } from 'app/socketio/actions';
|
||||
import { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import { ChangeEvent, KeyboardEvent, useRef } from 'react';
|
||||
import { ChangeEvent, KeyboardEvent, useRef, useState } from 'react';
|
||||
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { readinessSelector } from 'app/selectors/readinessSelector';
|
||||
import {
|
||||
GenerationState,
|
||||
handlePromptCheckers,
|
||||
setPrompt,
|
||||
} from 'features/parameters/store/generationSlice';
|
||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||
@ -40,11 +41,21 @@ const PromptInput = () => {
|
||||
const { isReady } = useAppSelector(readinessSelector);
|
||||
|
||||
const promptRef = useRef<HTMLTextAreaElement>(null);
|
||||
const [promptTimer, setPromptTimer] = useState<number | undefined>(undefined);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleChangePrompt = (e: ChangeEvent<HTMLTextAreaElement>) => {
|
||||
dispatch(setPrompt(e.target.value));
|
||||
|
||||
// Debounce Prompt UI Checking
|
||||
clearTimeout(promptTimer);
|
||||
const newPromptTimer = window.setTimeout(() => {
|
||||
dispatch(
|
||||
handlePromptCheckers({ prompt: e.target.value, toNegative: false })
|
||||
);
|
||||
}, 500);
|
||||
setPromptTimer(newPromptTimer);
|
||||
};
|
||||
|
||||
useHotkeys(
|
||||
|
@ -3,7 +3,11 @@ import { getPromptAndNegative } from 'common/util/getPromptAndNegative';
|
||||
import * as InvokeAI from 'app/invokeai';
|
||||
import promptToString from 'common/util/promptToString';
|
||||
import { useAppDispatch } from 'app/storeHooks';
|
||||
import { setNegativePrompt, setPrompt } from '../store/generationSlice';
|
||||
import {
|
||||
handlePromptCheckers,
|
||||
setNegativePrompt,
|
||||
setPrompt,
|
||||
} from '../store/generationSlice';
|
||||
|
||||
// TECHDEBT: We have two metadata prompt formats and need to handle recalling either of them.
|
||||
// This hook provides a function to do that.
|
||||
@ -20,6 +24,10 @@ const useSetBothPrompts = () => {
|
||||
|
||||
dispatch(setPrompt(prompt));
|
||||
dispatch(setNegativePrompt(negativePrompt));
|
||||
dispatch(handlePromptCheckers({ prompt: prompt, toNegative: false }));
|
||||
dispatch(
|
||||
handlePromptCheckers({ prompt: negativePrompt, toNegative: true })
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||
import { PayloadAction } from '@reduxjs/toolkit';
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import * as InvokeAI from 'app/invokeai';
|
||||
import { getPromptAndNegative } from 'common/util/getPromptAndNegative';
|
||||
import promptToString from 'common/util/promptToString';
|
||||
import { seedWeightsToString } from 'common/util/seedWeightPairs';
|
||||
import { clamp } from 'lodash';
|
||||
|
||||
export interface GenerationState {
|
||||
cfgScale: number;
|
||||
@ -16,6 +17,12 @@ export interface GenerationState {
|
||||
perlin: number;
|
||||
prompt: string;
|
||||
negativePrompt: string;
|
||||
lorasInUse: string[];
|
||||
huggingFaceTextualInversionConcepts: string[];
|
||||
localTextualInversionTriggers: string[];
|
||||
textualInversionsInUse: string[];
|
||||
negativeTextualInversionsInUse: string[];
|
||||
addTIToNegative: boolean;
|
||||
sampler: string;
|
||||
seamBlur: number;
|
||||
seamless: boolean;
|
||||
@ -33,8 +40,8 @@ export interface GenerationState {
|
||||
variationAmount: number;
|
||||
width: number;
|
||||
shouldUseSymmetry: boolean;
|
||||
horizontalSymmetryTimePercentage: number;
|
||||
verticalSymmetryTimePercentage: number;
|
||||
horizontalSymmetrySteps: number;
|
||||
verticalSymmetrySteps: number;
|
||||
}
|
||||
|
||||
const initialGenerationState: GenerationState = {
|
||||
@ -47,6 +54,12 @@ const initialGenerationState: GenerationState = {
|
||||
perlin: 0,
|
||||
prompt: '',
|
||||
negativePrompt: '',
|
||||
lorasInUse: [],
|
||||
huggingFaceTextualInversionConcepts: [],
|
||||
localTextualInversionTriggers: [],
|
||||
textualInversionsInUse: [],
|
||||
negativeTextualInversionsInUse: [],
|
||||
addTIToNegative: false,
|
||||
sampler: 'k_lms',
|
||||
seamBlur: 16,
|
||||
seamless: false,
|
||||
@ -64,18 +77,105 @@ const initialGenerationState: GenerationState = {
|
||||
variationAmount: 0.1,
|
||||
width: 512,
|
||||
shouldUseSymmetry: false,
|
||||
horizontalSymmetryTimePercentage: 0,
|
||||
verticalSymmetryTimePercentage: 0,
|
||||
horizontalSymmetrySteps: 0,
|
||||
verticalSymmetrySteps: 0,
|
||||
};
|
||||
|
||||
const initialState: GenerationState = initialGenerationState;
|
||||
|
||||
const loraExists = (state: GenerationState, lora: string) => {
|
||||
const loraRegex = new RegExp(`withLora\\(${lora},?\\s*([^\\)]+)?\\)`);
|
||||
if (state.prompt.match(loraRegex)) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
const getTIRegex = (textualInversion: string) => {
|
||||
if (textualInversion.includes('<' || '>')) {
|
||||
return new RegExp(`${textualInversion}`);
|
||||
} else {
|
||||
return new RegExp(`\\b${textualInversion}\\b`);
|
||||
}
|
||||
};
|
||||
|
||||
const textualInversionExists = (
|
||||
state: GenerationState,
|
||||
textualInversion: string
|
||||
) => {
|
||||
const textualInversionRegex = getTIRegex(textualInversion);
|
||||
|
||||
if (!state.addTIToNegative) {
|
||||
if (state.prompt.match(textualInversionRegex)) return true;
|
||||
} else {
|
||||
if (state.negativePrompt.match(textualInversionRegex)) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const handleTypedTICheck = (
|
||||
state: GenerationState,
|
||||
newPrompt: string,
|
||||
toNegative: boolean
|
||||
) => {
|
||||
let textualInversionsInUse = !toNegative
|
||||
? [...state.textualInversionsInUse]
|
||||
: [...state.negativeTextualInversionsInUse]; // Get Words In Prompt
|
||||
|
||||
const textualInversionRegex = /([\w<>!@%&*_-]+)/g; // Scan For Each Word
|
||||
|
||||
const textualInversionMatches = [
|
||||
...newPrompt.matchAll(textualInversionRegex),
|
||||
]; // Match All Words
|
||||
|
||||
if (textualInversionMatches.length > 0) {
|
||||
textualInversionsInUse = []; // Reset Textual Inversions In Use
|
||||
|
||||
textualInversionMatches.forEach((textualInversionMatch) => {
|
||||
const textualInversionName = textualInversionMatch[0];
|
||||
if (
|
||||
(!textualInversionsInUse.includes(textualInversionName) &&
|
||||
state.localTextualInversionTriggers.includes(textualInversionName)) ||
|
||||
state.huggingFaceTextualInversionConcepts.includes(textualInversionName)
|
||||
) {
|
||||
textualInversionsInUse.push(textualInversionName); // Add Textual Inversions In Prompt
|
||||
}
|
||||
});
|
||||
} else {
|
||||
textualInversionsInUse = []; // If No Matches, Remove Textual Inversions In Use
|
||||
}
|
||||
|
||||
if (!toNegative) {
|
||||
state.textualInversionsInUse = textualInversionsInUse;
|
||||
} else {
|
||||
state.negativeTextualInversionsInUse = textualInversionsInUse;
|
||||
}
|
||||
};
|
||||
|
||||
const handleTypedLoraCheck = (state: GenerationState, newPrompt: string) => {
|
||||
let lorasInUse = [...state.lorasInUse]; // Get Loras In Prompt
|
||||
|
||||
const loraRegex = /withLora\(([^\\)]+)\)/g; // Scan For Lora Syntax
|
||||
const loraMatches = [...newPrompt.matchAll(loraRegex)]; // Match All Lora Syntaxes
|
||||
|
||||
if (loraMatches.length > 0) {
|
||||
lorasInUse = []; // Reset Loras In Use
|
||||
loraMatches.forEach((loraMatch) => {
|
||||
const loraName = loraMatch[1].split(',')[0];
|
||||
if (!lorasInUse.includes(loraName)) lorasInUse.push(loraName); // Add Loras In Prompt
|
||||
});
|
||||
} else {
|
||||
lorasInUse = []; // If No Matches, Remove Loras In Use
|
||||
}
|
||||
|
||||
state.lorasInUse = lorasInUse;
|
||||
};
|
||||
|
||||
export const generationSlice = createSlice({
|
||||
name: 'generation',
|
||||
initialState,
|
||||
reducers: {
|
||||
setPrompt: (state, action: PayloadAction<string | InvokeAI.Prompt>) => {
|
||||
const newPrompt = action.payload;
|
||||
|
||||
if (typeof newPrompt === 'string') {
|
||||
state.prompt = newPrompt;
|
||||
} else {
|
||||
@ -93,12 +193,154 @@ export const generationSlice = createSlice({
|
||||
state.negativePrompt = promptToString(newPrompt);
|
||||
}
|
||||
},
|
||||
handlePromptCheckers: (
|
||||
state,
|
||||
action: PayloadAction<{
|
||||
prompt: string | InvokeAI.Prompt;
|
||||
toNegative: boolean;
|
||||
}>
|
||||
) => {
|
||||
const newPrompt = action.payload.prompt;
|
||||
|
||||
if (typeof newPrompt === 'string') {
|
||||
if (!action.payload.toNegative) handleTypedLoraCheck(state, newPrompt);
|
||||
handleTypedTICheck(state, newPrompt, action.payload.toNegative);
|
||||
}
|
||||
},
|
||||
setLorasInUse: (state, action: PayloadAction<string>) => {
|
||||
const newLora = action.payload;
|
||||
const loras = [...state.lorasInUse];
|
||||
|
||||
if (loraExists(state, newLora)) {
|
||||
const loraRegex = new RegExp(
|
||||
`withLora\\(${newLora},?\\s*([^\\)]+)?\\)`,
|
||||
'g'
|
||||
);
|
||||
const newPrompt = state.prompt.replaceAll(loraRegex, '');
|
||||
state.prompt = newPrompt.trim();
|
||||
|
||||
if (loras.includes(newLora)) {
|
||||
const newLoraIndex = loras.indexOf(newLora);
|
||||
if (newLoraIndex > -1) loras.splice(newLoraIndex, 1);
|
||||
}
|
||||
} else {
|
||||
state.prompt = `${state.prompt.trim()} withLora(${newLora},0.75)`;
|
||||
if (!loras.includes(newLora)) loras.push(newLora);
|
||||
}
|
||||
state.lorasInUse = loras;
|
||||
},
|
||||
setClearLoras: (state) => {
|
||||
const lorasInUse = [...state.lorasInUse];
|
||||
|
||||
lorasInUse.forEach((lora) => {
|
||||
const loraRegex = new RegExp(
|
||||
`withLora\\(${lora},?\\s*([^\\)]+)?\\)`,
|
||||
'g'
|
||||
);
|
||||
const newPrompt = state.prompt.replaceAll(loraRegex, '');
|
||||
state.prompt = newPrompt.trim();
|
||||
});
|
||||
|
||||
state.lorasInUse = [];
|
||||
},
|
||||
setTextualInversionsInUse: (state, action: PayloadAction<string>) => {
|
||||
const newTextualInversion = action.payload;
|
||||
|
||||
const textualInversions = [...state.textualInversionsInUse];
|
||||
const negativeTextualInversions = [
|
||||
...state.negativeTextualInversionsInUse,
|
||||
];
|
||||
|
||||
if (textualInversionExists(state, newTextualInversion)) {
|
||||
const textualInversionRegex = getTIRegex(newTextualInversion);
|
||||
|
||||
if (!state.addTIToNegative) {
|
||||
const newPrompt = state.prompt.replace(textualInversionRegex, '');
|
||||
state.prompt = newPrompt.trim();
|
||||
|
||||
const newTIIndex = textualInversions.indexOf(newTextualInversion);
|
||||
if (newTIIndex > -1) textualInversions.splice(newTIIndex, 1);
|
||||
} else {
|
||||
const newPrompt = state.negativePrompt.replace(
|
||||
textualInversionRegex,
|
||||
''
|
||||
);
|
||||
state.negativePrompt = newPrompt.trim();
|
||||
|
||||
const newTIIndex =
|
||||
negativeTextualInversions.indexOf(newTextualInversion);
|
||||
if (newTIIndex > -1) negativeTextualInversions.splice(newTIIndex, 1);
|
||||
}
|
||||
} else {
|
||||
if (!state.addTIToNegative) {
|
||||
state.prompt = `${state.prompt.trim()} ${newTextualInversion}`;
|
||||
textualInversions.push(newTextualInversion);
|
||||
} else {
|
||||
state.negativePrompt = `${state.negativePrompt.trim()} ${newTextualInversion}`;
|
||||
negativeTextualInversions.push(newTextualInversion);
|
||||
}
|
||||
}
|
||||
|
||||
state.textualInversionsInUse = textualInversions;
|
||||
state.negativeTextualInversionsInUse = negativeTextualInversions;
|
||||
},
|
||||
setClearTextualInversions: (state) => {
|
||||
const textualInversions = [...state.textualInversionsInUse];
|
||||
const negativeTextualInversions = [
|
||||
...state.negativeTextualInversionsInUse,
|
||||
];
|
||||
|
||||
textualInversions.forEach((ti) => {
|
||||
const textualInversionRegex = getTIRegex(ti);
|
||||
const newPrompt = state.prompt.replace(textualInversionRegex, '');
|
||||
state.prompt = newPrompt.trim();
|
||||
});
|
||||
|
||||
negativeTextualInversions.forEach((ti) => {
|
||||
const textualInversionRegex = getTIRegex(ti);
|
||||
const newPrompt = state.negativePrompt.replace(
|
||||
textualInversionRegex,
|
||||
''
|
||||
);
|
||||
state.negativePrompt = newPrompt.trim();
|
||||
});
|
||||
|
||||
state.textualInversionsInUse = [];
|
||||
state.negativeTextualInversionsInUse = [];
|
||||
},
|
||||
setAddTIToNegative: (state, action: PayloadAction<boolean>) => {
|
||||
state.addTIToNegative = action.payload;
|
||||
},
|
||||
setLocalTextualInversionTriggers: (
|
||||
state,
|
||||
action: PayloadAction<string[]>
|
||||
) => {
|
||||
state.localTextualInversionTriggers = action.payload;
|
||||
},
|
||||
setHuggingFaceTextualInversionConcepts: (
|
||||
state,
|
||||
action: PayloadAction<string[]>
|
||||
) => {
|
||||
state.huggingFaceTextualInversionConcepts = action.payload;
|
||||
},
|
||||
setIterations: (state, action: PayloadAction<number>) => {
|
||||
state.iterations = action.payload;
|
||||
},
|
||||
setSteps: (state, action: PayloadAction<number>) => {
|
||||
state.steps = action.payload;
|
||||
},
|
||||
clampSymmetrySteps: (state) => {
|
||||
state.horizontalSymmetrySteps = clamp(
|
||||
state.horizontalSymmetrySteps,
|
||||
0,
|
||||
state.steps
|
||||
);
|
||||
state.verticalSymmetrySteps = clamp(
|
||||
state.verticalSymmetrySteps,
|
||||
0,
|
||||
state.steps
|
||||
);
|
||||
},
|
||||
setCfgScale: (state, action: PayloadAction<number>) => {
|
||||
state.cfgScale = action.payload;
|
||||
},
|
||||
@ -288,7 +530,6 @@ export const generationSlice = createSlice({
|
||||
state.perlin = perlin;
|
||||
}
|
||||
if (typeof seamless === 'boolean') state.seamless = seamless;
|
||||
// if (typeof hires_fix === 'boolean') state.hiresFix = hires_fix; // TODO: Needs to be fixed after reorg
|
||||
if (width) state.width = width;
|
||||
if (height) state.height = height;
|
||||
|
||||
@ -334,22 +575,17 @@ export const generationSlice = createSlice({
|
||||
setShouldUseSymmetry: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldUseSymmetry = action.payload;
|
||||
},
|
||||
setHorizontalSymmetryTimePercentage: (
|
||||
state,
|
||||
action: PayloadAction<number>
|
||||
) => {
|
||||
state.horizontalSymmetryTimePercentage = action.payload;
|
||||
setHorizontalSymmetrySteps: (state, action: PayloadAction<number>) => {
|
||||
state.horizontalSymmetrySteps = action.payload;
|
||||
},
|
||||
setVerticalSymmetryTimePercentage: (
|
||||
state,
|
||||
action: PayloadAction<number>
|
||||
) => {
|
||||
state.verticalSymmetryTimePercentage = action.payload;
|
||||
setVerticalSymmetrySteps: (state, action: PayloadAction<number>) => {
|
||||
state.verticalSymmetrySteps = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const {
|
||||
clampSymmetrySteps,
|
||||
clearInitialImage,
|
||||
resetParametersState,
|
||||
resetSeed,
|
||||
@ -367,6 +603,14 @@ export const {
|
||||
setPerlin,
|
||||
setPrompt,
|
||||
setNegativePrompt,
|
||||
handlePromptCheckers,
|
||||
setLorasInUse,
|
||||
setClearLoras,
|
||||
setHuggingFaceTextualInversionConcepts,
|
||||
setLocalTextualInversionTriggers,
|
||||
setTextualInversionsInUse,
|
||||
setAddTIToNegative,
|
||||
setClearTextualInversions,
|
||||
setSampler,
|
||||
setSeamBlur,
|
||||
setSeamless,
|
||||
@ -384,8 +628,8 @@ export const {
|
||||
setVariationAmount,
|
||||
setWidth,
|
||||
setShouldUseSymmetry,
|
||||
setHorizontalSymmetryTimePercentage,
|
||||
setVerticalSymmetryTimePercentage,
|
||||
setHorizontalSymmetrySteps,
|
||||
setVerticalSymmetrySteps,
|
||||
} = generationSlice.actions;
|
||||
|
||||
export default generationSlice.reducer;
|
||||
|
@ -1,5 +1,6 @@
|
||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import * as InvokeAI from 'app/invokeai';
|
||||
import { FACETOOL_TYPES } from 'app/constants';
|
||||
|
||||
export type UpscalingLevel = 2 | 4;
|
||||
@ -40,6 +41,17 @@ export const postprocessingSlice = createSlice({
|
||||
name: 'postprocessing',
|
||||
initialState,
|
||||
reducers: {
|
||||
setAllPostProcessingParameters: (
|
||||
state,
|
||||
action: PayloadAction<InvokeAI.Metadata>
|
||||
) => {
|
||||
const { type, hires_fix } = action.payload.image;
|
||||
|
||||
if (type === 'txt2img') {
|
||||
state.hiresFix = Boolean(hires_fix);
|
||||
// Strength of img2img used in hires_fix is not currently exposed in the Metadata for the final image.
|
||||
}
|
||||
},
|
||||
setFacetoolStrength: (state, action: PayloadAction<number>) => {
|
||||
state.facetoolStrength = action.payload;
|
||||
},
|
||||
@ -83,6 +95,7 @@ export const postprocessingSlice = createSlice({
|
||||
});
|
||||
|
||||
export const {
|
||||
setAllPostProcessingParameters,
|
||||
resetPostprocessingState,
|
||||
setCodeformerFidelity,
|
||||
setFacetoolStrength,
|
||||
|
@ -57,19 +57,19 @@ export default function MergeModels() {
|
||||
|
||||
const [modelMergeForce, setModelMergeForce] = useState<boolean>(false);
|
||||
|
||||
const modelOneList = Object.keys(diffusersModels).filter((model) => {
|
||||
if (model !== modelTwo && model !== modelThree) return model;
|
||||
});
|
||||
const modelOneList = Object.keys(diffusersModels).filter(
|
||||
(model) => model !== modelTwo && model !== modelThree
|
||||
);
|
||||
|
||||
const modelTwoList = Object.keys(diffusersModels).filter((model) => {
|
||||
if (model !== modelOne && model !== modelThree) return model;
|
||||
});
|
||||
const modelTwoList = Object.keys(diffusersModels).filter(
|
||||
(model) => model !== modelOne && model !== modelThree
|
||||
);
|
||||
|
||||
const modelThreeList = [
|
||||
'none',
|
||||
...Object.keys(diffusersModels).filter((model) => {
|
||||
if (model !== modelOne && model !== modelTwo) return model;
|
||||
}),
|
||||
{ key: t('modelManager.none'), value: 'none' },
|
||||
...Object.keys(diffusersModels)
|
||||
.filter((model) => model !== modelOne && model !== modelTwo)
|
||||
.map((model) => ({ key: model, value: model })),
|
||||
];
|
||||
|
||||
const isProcessing = useAppSelector(
|
||||
@ -209,18 +209,22 @@ export default function MergeModels() {
|
||||
<Flex columnGap={4}>
|
||||
{modelThree === 'none' ? (
|
||||
<>
|
||||
<Radio value="weighted_sum">weighted_sum</Radio>
|
||||
<Radio value="sigmoid">sigmoid</Radio>
|
||||
<Radio value="inv_sigmoid">inv_sigmoid</Radio>
|
||||
<Radio value="weighted_sum">
|
||||
{t('modelManager.weightedSum')}
|
||||
</Radio>
|
||||
<Radio value="sigmoid">{t('modelManager.sigmoid')}</Radio>
|
||||
<Radio value="inv_sigmoid">
|
||||
{t('modelManager.inverseSigmoid')}
|
||||
</Radio>
|
||||
</>
|
||||
) : (
|
||||
<Radio value="add_difference">
|
||||
<Tooltip
|
||||
label={t(
|
||||
'modelmanager:modelMergeInterpAddDifferenceHelp'
|
||||
'modelManager.modelMergeInterpAddDifferenceHelp'
|
||||
)}
|
||||
>
|
||||
add_difference
|
||||
{t('modelManager.addDifference')}
|
||||
</Tooltip>
|
||||
</Radio>
|
||||
)}
|
||||
|
@ -181,7 +181,8 @@ export default function SearchModels() {
|
||||
|
||||
const configFiles = {
|
||||
v1: 'configs/stable-diffusion/v1-inference.yaml',
|
||||
v2: 'configs/stable-diffusion/v2-inference-v.yaml',
|
||||
v2_base: 'configs/stable-diffusion/v2-inference-v.yaml',
|
||||
v2_768: 'configs/stable-diffusion/v2-inference-v.yaml',
|
||||
inpainting: 'configs/stable-diffusion/v1-inpainting-inference.yaml',
|
||||
custom: pathToConfig,
|
||||
};
|
||||
@ -385,7 +386,8 @@ export default function SearchModels() {
|
||||
>
|
||||
<Flex gap={4}>
|
||||
<Radio value="v1">{t('modelManager.v1')}</Radio>
|
||||
<Radio value="v2">{t('modelManager.v2')}</Radio>
|
||||
<Radio value="v2_base">{t('modelManager.v2_base')}</Radio>
|
||||
<Radio value="v2_768">{t('modelManager.v2_768')}</Radio>
|
||||
<Radio value="inpainting">
|
||||
{t('modelManager.inpainting')}
|
||||
</Radio>
|
||||
|
@ -31,6 +31,7 @@ import {
|
||||
} from 'features/system/store/systemSlice';
|
||||
import { uiSelector } from 'features/ui/store/uiSelectors';
|
||||
import {
|
||||
setShouldShowHuggingFaceConcepts,
|
||||
setShouldUseCanvasBetaLayout,
|
||||
setShouldUseSliders,
|
||||
} from 'features/ui/store/uiSlice';
|
||||
@ -52,7 +53,11 @@ const selector = createSelector(
|
||||
enableImageDebugging,
|
||||
} = system;
|
||||
|
||||
const { shouldUseCanvasBetaLayout, shouldUseSliders } = ui;
|
||||
const {
|
||||
shouldUseCanvasBetaLayout,
|
||||
shouldUseSliders,
|
||||
shouldShowHuggingFaceConcepts,
|
||||
} = ui;
|
||||
|
||||
return {
|
||||
shouldDisplayInProgressType,
|
||||
@ -63,6 +68,7 @@ const selector = createSelector(
|
||||
enableImageDebugging,
|
||||
shouldUseCanvasBetaLayout,
|
||||
shouldUseSliders,
|
||||
shouldShowHuggingFaceConcepts,
|
||||
};
|
||||
},
|
||||
{
|
||||
@ -107,6 +113,7 @@ const SettingsModal = ({ children }: SettingsModalProps) => {
|
||||
enableImageDebugging,
|
||||
shouldUseCanvasBetaLayout,
|
||||
shouldUseSliders,
|
||||
shouldShowHuggingFaceConcepts,
|
||||
} = useAppSelector(selector);
|
||||
|
||||
/**
|
||||
@ -206,6 +213,14 @@ const SettingsModal = ({ children }: SettingsModalProps) => {
|
||||
dispatch(setShouldUseSliders(e.target.checked))
|
||||
}
|
||||
/>
|
||||
<IAISwitch
|
||||
styleClass="settings-modal-item"
|
||||
label={t('settings.showHuggingFaceConcepts')}
|
||||
isChecked={shouldShowHuggingFaceConcepts}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||
dispatch(setShouldShowHuggingFaceConcepts(e.target.checked))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="settings-modal-items">
|
||||
|
@ -51,6 +51,13 @@ export interface SystemState
|
||||
toastQueue: UseToastOptions[];
|
||||
searchFolder: string | null;
|
||||
foundModels: InvokeAI.FoundModel[] | null;
|
||||
foundLoras: InvokeAI.FoundLora[] | null;
|
||||
foundLocalTextualInversionTriggers:
|
||||
| InvokeAI.FoundTextualInversionTriggers[]
|
||||
| null;
|
||||
foundHuggingFaceTextualInversionTriggers:
|
||||
| InvokeAI.FoundTextualInversionTriggers[]
|
||||
| null;
|
||||
openModel: string | null;
|
||||
cancelOptions: {
|
||||
cancelType: CancelType;
|
||||
@ -93,6 +100,9 @@ const initialSystemState: SystemState = {
|
||||
toastQueue: [],
|
||||
searchFolder: null,
|
||||
foundModels: null,
|
||||
foundLoras: null,
|
||||
foundLocalTextualInversionTriggers: null,
|
||||
foundHuggingFaceTextualInversionTriggers: null,
|
||||
openModel: null,
|
||||
cancelOptions: {
|
||||
cancelType: 'immediate',
|
||||
@ -262,6 +272,24 @@ export const systemSlice = createSlice({
|
||||
) => {
|
||||
state.foundModels = action.payload;
|
||||
},
|
||||
setFoundLoras: (
|
||||
state,
|
||||
action: PayloadAction<InvokeAI.FoundLora[] | null>
|
||||
) => {
|
||||
state.foundLoras = action.payload;
|
||||
},
|
||||
setFoundLocalTextualInversionTriggers: (
|
||||
state,
|
||||
action: PayloadAction<InvokeAI.FoundTextualInversionTriggers[] | null>
|
||||
) => {
|
||||
state.foundLocalTextualInversionTriggers = action.payload;
|
||||
},
|
||||
setFoundHuggingFaceTextualInversionTriggers: (
|
||||
state,
|
||||
action: PayloadAction<InvokeAI.FoundTextualInversionTriggers[] | null>
|
||||
) => {
|
||||
state.foundHuggingFaceTextualInversionTriggers = action.payload;
|
||||
},
|
||||
setOpenModel: (state, action: PayloadAction<string | null>) => {
|
||||
state.openModel = action.payload;
|
||||
},
|
||||
@ -303,6 +331,9 @@ export const {
|
||||
setProcessingIndeterminateTask,
|
||||
setSearchFolder,
|
||||
setFoundModels,
|
||||
setFoundLoras,
|
||||
setFoundLocalTextualInversionTriggers,
|
||||
setFoundHuggingFaceTextualInversionTriggers,
|
||||
setOpenModel,
|
||||
setCancelType,
|
||||
setCancelAfter,
|
||||
|
@ -18,6 +18,7 @@ import PromptInput from 'features/parameters/components/PromptInput/PromptInput'
|
||||
import InvokeOptionsPanel from 'features/ui/components/InvokeParametersPanel';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import ImageToImageOptions from './ImageToImageOptions';
|
||||
import PromptExtras from 'features/parameters/components/PromptInput/Extras/PromptExtras';
|
||||
|
||||
export default function ImageToImagePanel() {
|
||||
const { t } = useTranslation();
|
||||
@ -63,6 +64,7 @@ export default function ImageToImagePanel() {
|
||||
<Flex flexDir="column" rowGap="0.5rem">
|
||||
<PromptInput />
|
||||
<NegativePromptInput />
|
||||
<PromptExtras />
|
||||
</Flex>
|
||||
<ProcessButtons />
|
||||
<MainSettings />
|
||||
|
@ -18,6 +18,7 @@ import { setParametersPanelScrollPosition } from 'features/ui/store/uiSlice';
|
||||
import InvokeAILogo from 'assets/images/logo.png';
|
||||
import { isEqual } from 'lodash';
|
||||
import { uiSelector } from '../store/uiSelectors';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
type Props = { children: ReactNode };
|
||||
|
||||
@ -60,6 +61,8 @@ const InvokeOptionsPanel = (props: Props) => {
|
||||
|
||||
const { children } = props;
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
// Hotkeys
|
||||
useHotkeys(
|
||||
'o',
|
||||
@ -176,7 +179,7 @@ const InvokeOptionsPanel = (props: Props) => {
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Tooltip label="Pin Options Panel">
|
||||
<Tooltip label={t('common.pinOptionsPanel')}>
|
||||
<div
|
||||
className="parameters-panel-pin-button"
|
||||
data-selected={shouldPinParametersPanel}
|
||||
|
@ -17,6 +17,7 @@ import NegativePromptInput from 'features/parameters/components/PromptInput/Nega
|
||||
import PromptInput from 'features/parameters/components/PromptInput/PromptInput';
|
||||
import InvokeOptionsPanel from 'features/ui/components/InvokeParametersPanel';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import PromptExtras from 'features/parameters/components/PromptInput/Extras/PromptExtras';
|
||||
|
||||
export default function TextToImagePanel() {
|
||||
const { t } = useTranslation();
|
||||
@ -62,6 +63,7 @@ export default function TextToImagePanel() {
|
||||
<Flex flexDir="column" rowGap="0.5rem">
|
||||
<PromptInput />
|
||||
<NegativePromptInput />
|
||||
<PromptExtras />
|
||||
</Flex>
|
||||
<ProcessButtons />
|
||||
<MainSettings />
|
||||
|
@ -17,6 +17,7 @@ import NegativePromptInput from 'features/parameters/components/PromptInput/Nega
|
||||
import PromptInput from 'features/parameters/components/PromptInput/PromptInput';
|
||||
import InvokeOptionsPanel from 'features/ui/components/InvokeParametersPanel';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import PromptExtras from 'features/parameters/components/PromptInput/Extras/PromptExtras';
|
||||
|
||||
export default function UnifiedCanvasPanel() {
|
||||
const { t } = useTranslation();
|
||||
@ -73,6 +74,7 @@ export default function UnifiedCanvasPanel() {
|
||||
<Flex flexDir="column" rowGap="0.5rem">
|
||||
<PromptInput />
|
||||
<NegativePromptInput />
|
||||
<PromptExtras />
|
||||
</Flex>
|
||||
<ProcessButtons />
|
||||
<MainSettings />
|
||||
|
@ -15,6 +15,7 @@ const initialtabsState: UIState = {
|
||||
shouldUseCanvasBetaLayout: false,
|
||||
shouldShowExistingModelsInSearch: false,
|
||||
shouldUseSliders: false,
|
||||
shouldShowHuggingFaceConcepts: false,
|
||||
addNewModelUIOption: null,
|
||||
};
|
||||
|
||||
@ -70,6 +71,12 @@ export const uiSlice = createSlice({
|
||||
setShouldUseSliders: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldUseSliders = action.payload;
|
||||
},
|
||||
setShouldShowHuggingFaceConcepts: (
|
||||
state,
|
||||
action: PayloadAction<boolean>
|
||||
) => {
|
||||
state.shouldShowHuggingFaceConcepts = action.payload;
|
||||
},
|
||||
setAddNewModelUIOption: (state, action: PayloadAction<AddNewModelType>) => {
|
||||
state.addNewModelUIOption = action.payload;
|
||||
},
|
||||
@ -88,6 +95,7 @@ export const {
|
||||
setShouldUseCanvasBetaLayout,
|
||||
setShouldShowExistingModelsInSearch,
|
||||
setShouldUseSliders,
|
||||
setShouldShowHuggingFaceConcepts,
|
||||
setAddNewModelUIOption,
|
||||
} = uiSlice.actions;
|
||||
|
||||
|
@ -12,5 +12,6 @@ export interface UIState {
|
||||
shouldUseCanvasBetaLayout: boolean;
|
||||
shouldShowExistingModelsInSearch: boolean;
|
||||
shouldUseSliders: boolean;
|
||||
shouldShowHuggingFaceConcepts: boolean;
|
||||
addNewModelUIOption: AddNewModelType;
|
||||
}
|
||||
|
5
invokeai/frontend/src/i18.d.ts
vendored
5
invokeai/frontend/src/i18.d.ts
vendored
@ -1,11 +1,16 @@
|
||||
import 'i18next';
|
||||
|
||||
import en from '../public/locales/en.json';
|
||||
|
||||
declare module 'i18next' {
|
||||
// Extend CustomTypeOptions
|
||||
interface CustomTypeOptions {
|
||||
// Setting Default Namespace As English
|
||||
defaultNS: 'en';
|
||||
// Custom Types For Resources
|
||||
resources: {
|
||||
en: typeof en;
|
||||
};
|
||||
// Never Return Null
|
||||
returnNull: false;
|
||||
}
|
||||
|
@ -8,7 +8,6 @@
|
||||
--accent-color-bright: rgb(104, 60, 230);
|
||||
--accent-color-hover: var(--accent-color-bright);
|
||||
|
||||
// App Colors
|
||||
--root-bg-color: rgb(10, 10, 10);
|
||||
--background-color: rgb(26, 26, 32);
|
||||
--background-color-light: rgb(40, 44, 48);
|
||||
@ -119,6 +118,7 @@
|
||||
--context-menu-bg-color: rgb(46, 48, 58);
|
||||
--context-menu-box-shadow: none;
|
||||
--context-menu-bg-color-hover: rgb(30, 32, 42);
|
||||
--context-menu-active-item: var(--accent-color-bright);
|
||||
|
||||
// Shadows
|
||||
--floating-button-drop-shadow-color: var(--accent-color);
|
||||
|
@ -117,6 +117,7 @@
|
||||
--context-menu-bg-color: rgb(46, 48, 58);
|
||||
--context-menu-box-shadow: none;
|
||||
--context-menu-bg-color-hover: rgb(30, 32, 42);
|
||||
--context-menu-active-item: var(--accent-color-bright);
|
||||
|
||||
// Shadows
|
||||
--floating-button-drop-shadow-color: var(--accent-color);
|
||||
|
@ -114,6 +114,7 @@
|
||||
--context-menu-box-shadow: 0px 10px 38px -10px rgba(22, 23, 24, 0.35),
|
||||
0px 10px 20px -15px rgba(22, 23, 24, 0.2);
|
||||
--context-menu-bg-color-hover: var(--background-color-secondary);
|
||||
--context-menu-active-item: rgb(0, 0, 0);
|
||||
|
||||
// Shadows
|
||||
--floating-button-drop-shadow-color: rgba(0, 0, 0, 0.7);
|
||||
|
File diff suppressed because one or more lines are too long
@ -56,26 +56,26 @@
|
||||
"@babel/helper-validator-identifier" "^7.19.1"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@chakra-ui/accordion@2.1.9":
|
||||
version "2.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/accordion/-/accordion-2.1.9.tgz#20fa86d94dc034251df2f7c8595ae4dd541a29d9"
|
||||
integrity sha512-a9CKIAUHezc0f5FR/SQ4GVxnWuIb2HbDTxTEKTp58w/J9pecIbJaNrJ5TUZ0MVbDU9jkgO9RsZ29jkja8PomAw==
|
||||
"@chakra-ui/accordion@2.1.11":
|
||||
version "2.1.11"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/accordion/-/accordion-2.1.11.tgz#c6df0100c543645d0631df3aefde2ea2b8ed6313"
|
||||
integrity sha512-mfVPmqETp9pyRDHJ33AdF19oHv/LyxVzQJtlxUByuvs8Cj9QQZ2LQLg5kejm+b3mj03A7A6yfbuo3RNaI4Bhsg==
|
||||
dependencies:
|
||||
"@chakra-ui/descendant" "3.0.13"
|
||||
"@chakra-ui/descendant" "3.0.14"
|
||||
"@chakra-ui/icon" "3.0.16"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/react-use-controllable-state" "2.0.8"
|
||||
"@chakra-ui/react-use-merge-refs" "2.0.7"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
"@chakra-ui/transition" "2.0.15"
|
||||
"@chakra-ui/transition" "2.0.16"
|
||||
|
||||
"@chakra-ui/alert@2.0.17":
|
||||
version "2.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/alert/-/alert-2.0.17.tgz#b129732ec308db6a6a1afa7c06a6595ad853c967"
|
||||
integrity sha512-0Y5vw+HkeXpwbL1roVpSSNM6luMRmUbwduUSHEA4OnX1ismvsDb1ZBfpi4Vxp6w8euJ2Uj6df3krbd5tbCP6tg==
|
||||
"@chakra-ui/alert@2.1.0":
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/alert/-/alert-2.1.0.tgz#7a234ac6426231b39243088648455cbcf1cbdf24"
|
||||
integrity sha512-OcfHwoXI5VrmM+tHJTHT62Bx6TfyfCxSa0PWUOueJzSyhlUOKBND5we6UtrOB7D0jwX45qKKEDJOLG5yCG21jQ==
|
||||
dependencies:
|
||||
"@chakra-ui/icon" "3.0.16"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
"@chakra-ui/spinner" "2.0.13"
|
||||
|
||||
@ -84,23 +84,23 @@
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/anatomy/-/anatomy-2.1.2.tgz#ea66b1841e7195da08ddc862daaa3f3e56e565f5"
|
||||
integrity sha512-pKfOS/mztc4sUXHNc8ypJ1gPWSolWT770jrgVRfolVbYlki8y5Y+As996zMF6k5lewTu6j9DQequ7Cc9a69IVQ==
|
||||
|
||||
"@chakra-ui/avatar@2.2.5":
|
||||
version "2.2.5"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/avatar/-/avatar-2.2.5.tgz#50eb7cc5a172d394b301fa0abd5f607b7f5d3563"
|
||||
integrity sha512-TEHXuGE79+fEn61qJ7J/A0Ec+WjyNwobrDTATcLg9Zx2/WEMmZNfrWIAlI5ANQAwVbdSWeGVbyoLAK5mbcrE0A==
|
||||
"@chakra-ui/avatar@2.2.8":
|
||||
version "2.2.8"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/avatar/-/avatar-2.2.8.tgz#a6e16accb2bb9c879f197090ccc9df1ff42992a6"
|
||||
integrity sha512-uBs9PMrqyK111tPIYIKnOM4n3mwgKqGpvYmtwBnnbQLTNLg4gtiWWVbpTuNMpyu1av0xQYomjUt8Doed8w6p8g==
|
||||
dependencies:
|
||||
"@chakra-ui/image" "2.0.15"
|
||||
"@chakra-ui/react-children-utils" "2.0.6"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/breadcrumb@2.1.4":
|
||||
version "2.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/breadcrumb/-/breadcrumb-2.1.4.tgz#0d249dc2a92639bd2bf46d097dd5445112bd2367"
|
||||
integrity sha512-vyBx5TAxPnHhb0b8nyRGfqyjleD//9mySFhk96c9GL+T6YDO4swHw5y/kvDv3Ngc/iRwJ9hdI49PZKwPxLqsEg==
|
||||
"@chakra-ui/breadcrumb@2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/breadcrumb/-/breadcrumb-2.1.5.tgz#a43b22cc8005291a615696a8c88efc37064562f3"
|
||||
integrity sha512-p3eQQrHQBkRB69xOmNyBJqEdfCrMt+e0eOH+Pm/DjFWfIVIbnIaFbmDCeWClqlLa21Ypc6h1hR9jEmvg8kmOog==
|
||||
dependencies:
|
||||
"@chakra-ui/react-children-utils" "2.0.6"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/breakpoint-utils@2.0.8":
|
||||
@ -110,12 +110,12 @@
|
||||
dependencies:
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/button@2.0.16":
|
||||
version "2.0.16"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/button/-/button-2.0.16.tgz#ff315b57ee47c3511a6507fcfb6f00bb93e2ac7d"
|
||||
integrity sha512-NjuTKa7gNhnGSUutKuTc8HoAOe9WWIigpciBG7yj3ok67kg8bXtSzPyQFZlgTY6XGdAckWTT+Do4tvhwa5LA+g==
|
||||
"@chakra-ui/button@2.0.18":
|
||||
version "2.0.18"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/button/-/button-2.0.18.tgz#c13d2e404e22a9873ba5373fde494bedafe32fdd"
|
||||
integrity sha512-E3c99+lOm6ou4nQVOTLkG+IdOPMjsQK+Qe7VyP8A/xeAMFONuibrWPRPpprr4ZkB4kEoLMfNuyH2+aEza3ScUA==
|
||||
dependencies:
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/react-use-merge-refs" "2.0.7"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
"@chakra-ui/spinner" "2.0.13"
|
||||
@ -127,13 +127,13 @@
|
||||
dependencies:
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/checkbox@2.2.10":
|
||||
version "2.2.10"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/checkbox/-/checkbox-2.2.10.tgz#e4f773e7d2464f1d6e9d18dd88b679290cb33171"
|
||||
integrity sha512-vzxEjw99qj7loxAdP1WuHNt4EAvj/t6cc8oxyOB2mEvkAzhxI34rLR+3zWDuHWsmhyUO+XEDh4FiWdR+DK5Siw==
|
||||
"@chakra-ui/checkbox@2.2.14":
|
||||
version "2.2.14"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/checkbox/-/checkbox-2.2.14.tgz#902acc99a9a80c1c304788a230cf36f8116e8260"
|
||||
integrity sha512-uqo6lFWLqYBujPglrvRhTAErtuIXpmdpc5w0W4bjK7kyvLhxOpUh1hlDb2WoqlNpfRn/OaNeF6VinPnf9BJL8w==
|
||||
dependencies:
|
||||
"@chakra-ui/form-control" "2.0.17"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/form-control" "2.0.18"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/react-types" "2.0.7"
|
||||
"@chakra-ui/react-use-callback-ref" "2.0.7"
|
||||
"@chakra-ui/react-use-controllable-state" "2.0.8"
|
||||
@ -142,7 +142,7 @@
|
||||
"@chakra-ui/react-use-update-effect" "2.0.7"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
"@chakra-ui/visually-hidden" "2.0.15"
|
||||
"@zag-js/focus-visible" "0.2.1"
|
||||
"@zag-js/focus-visible" "0.2.2"
|
||||
|
||||
"@chakra-ui/clickable@2.0.14":
|
||||
version "2.0.14"
|
||||
@ -180,17 +180,17 @@
|
||||
"@chakra-ui/react-use-callback-ref" "2.0.7"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/css-reset@2.0.12":
|
||||
version "2.0.12"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/css-reset/-/css-reset-2.0.12.tgz#6eebcbe9e971facd215e174e063ace29f647a045"
|
||||
integrity sha512-Q5OYIMvqTl2vZ947kIYxcS5DhQXeStB84BzzBd6C10wOx1gFUu9pL+jLpOnHR3hhpWRMdX5o7eT+gMJWIYUZ0Q==
|
||||
"@chakra-ui/css-reset@2.1.1":
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/css-reset/-/css-reset-2.1.1.tgz#c61f3d2103c13e62a86fd2d359682092e961852c"
|
||||
integrity sha512-jwEOfIAWmQsnChHQTW/eRE+dfE4MjmhvSvoUug5nkV1pI7veC/20noFlIZxzi82EbiQI8Fs0+Jnusgxr2yaOHA==
|
||||
|
||||
"@chakra-ui/descendant@3.0.13":
|
||||
version "3.0.13"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/descendant/-/descendant-3.0.13.tgz#e883a2233ee07fe1ae6c014567824c0f79df11cf"
|
||||
integrity sha512-9nzxZVxUSMc4xPL5fSaRkEOQjDQWUGjGvrZI7VzWk9eq63cojOtIxtWMSW383G9148PzWJjJYt30Eud5tdZzlg==
|
||||
"@chakra-ui/descendant@3.0.14":
|
||||
version "3.0.14"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/descendant/-/descendant-3.0.14.tgz#fe8bac3f0e1ffe562e3e73eac393dbf222d57e13"
|
||||
integrity sha512-+Ahvp9H4HMpfScIv9w1vaecGz7qWAaK1YFHHolz/SIsGLaLGlbdp+5UNabQC7L6TUnzzJDQDxzwif78rTD7ang==
|
||||
dependencies:
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/react-use-merge-refs" "2.0.7"
|
||||
|
||||
"@chakra-ui/dom-utils@2.0.6":
|
||||
@ -198,12 +198,12 @@
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/dom-utils/-/dom-utils-2.0.6.tgz#68f49f3b4a0bdebd5e416d6fd2c012c9ad64b76a"
|
||||
integrity sha512-PVtDkPrDD5b8aoL6Atg7SLjkwhWb7BwMcLOF1L449L3nZN+DAO3nyAh6iUhZVJyunELj9d0r65CDlnMREyJZmA==
|
||||
|
||||
"@chakra-ui/editable@2.0.19":
|
||||
version "2.0.19"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/editable/-/editable-2.0.19.tgz#1af2fe3c215111f61f7872fb5f599f4d8da24e7d"
|
||||
integrity sha512-YxRJsJ2JQd42zfPBgTKzIhg1HugT+gfQz1ZosmUN+IZT9YZXL2yodHTUz6Lee04Vc/CdEqgBFLuREXEUNBfGtA==
|
||||
"@chakra-ui/editable@2.0.21":
|
||||
version "2.0.21"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/editable/-/editable-2.0.21.tgz#bc74510470d6d455844438e540851896d3879132"
|
||||
integrity sha512-oYuXbHnggxSYJN7P9Pn0Scs9tPC91no4z1y58Oe+ILoJKZ+bFAEHtL7FEISDNJxw++MEukeFu7GU1hVqmdLsKQ==
|
||||
dependencies:
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/react-types" "2.0.7"
|
||||
"@chakra-ui/react-use-callback-ref" "2.0.7"
|
||||
"@chakra-ui/react-use-controllable-state" "2.0.8"
|
||||
@ -226,13 +226,13 @@
|
||||
"@chakra-ui/dom-utils" "2.0.6"
|
||||
react-focus-lock "^2.9.2"
|
||||
|
||||
"@chakra-ui/form-control@2.0.17":
|
||||
version "2.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/form-control/-/form-control-2.0.17.tgz#2f710325e77ce35067337616d440f903b137bdd5"
|
||||
integrity sha512-34ptCaJ2LNvQNOlB6MAKsmH1AkT1xo7E+3Vw10Urr81yTOjDTM/iU6vG3JKPfRDMyXeowPjXmutlnuk72SSjRg==
|
||||
"@chakra-ui/form-control@2.0.18":
|
||||
version "2.0.18"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/form-control/-/form-control-2.0.18.tgz#1923f293afde70b2b07ca731d98fef3660098c56"
|
||||
integrity sha512-I0a0jG01IAtRPccOXSNugyRdUAe8Dy40ctqedZvznMweOXzbMCF1m+sHPLdWeWC/VI13VoAispdPY0/zHOdjsQ==
|
||||
dependencies:
|
||||
"@chakra-ui/icon" "3.0.16"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/react-types" "2.0.7"
|
||||
"@chakra-ui/react-use-merge-refs" "2.0.7"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
@ -254,10 +254,10 @@
|
||||
dependencies:
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/icons@^2.0.17":
|
||||
version "2.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/icons/-/icons-2.0.17.tgz#625a46d169707aad36d65c04a4626a422f92e5ae"
|
||||
integrity sha512-HMJP0WrJgAmFR9+Xh/CBH0nVnGMsJ4ZC8MK6tMgxPKd9/muvn0I4hsicHqdPlLpmB0TlxlhkBAKaVMtOdz6F0w==
|
||||
"@chakra-ui/icons@^2.0.18":
|
||||
version "2.0.18"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/icons/-/icons-2.0.18.tgz#6f859d2e0d8f31fea9cb2e6507d65eb65cb95cf5"
|
||||
integrity sha512-E/+DF/jw7kdN4/XxCZRnr4FdMXhkl50Q34MVwN9rADWMwPK9uSZPGyC7HOx6rilo7q4bFjYDH3yRj9g+VfbVkg==
|
||||
dependencies:
|
||||
"@chakra-ui/icon" "3.0.16"
|
||||
|
||||
@ -269,27 +269,27 @@
|
||||
"@chakra-ui/react-use-safe-layout-effect" "2.0.5"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/input@2.0.20":
|
||||
version "2.0.20"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/input/-/input-2.0.20.tgz#8db3ec46b52be901c94599b3659a9003bdb2dd07"
|
||||
integrity sha512-ypmsy4n4uNBVgn6Gd24Zrpi+qRf/T9WEzWkysuYC9Qfxo+i7yuf3snp7XmBy8KSGVSiXE11eO8ZN5oCg6Xg0jg==
|
||||
"@chakra-ui/input@2.0.21":
|
||||
version "2.0.21"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/input/-/input-2.0.21.tgz#a7e55ea6fa32ae39c0f6ec44ca2189933fda9eb5"
|
||||
integrity sha512-AIWjjg6MgcOtlvKmVoZfPPfgF+sBSWL3Zq2HSCAMvS6h7jfxz/Xv0UTFGPk5F4Wt0YHT7qMySg0Jsm0b78HZJg==
|
||||
dependencies:
|
||||
"@chakra-ui/form-control" "2.0.17"
|
||||
"@chakra-ui/form-control" "2.0.18"
|
||||
"@chakra-ui/object-utils" "2.0.8"
|
||||
"@chakra-ui/react-children-utils" "2.0.6"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/layout@2.1.16":
|
||||
version "2.1.16"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/layout/-/layout-2.1.16.tgz#9d90f25cf9f0537d19cd36a417f7ddc1461e8591"
|
||||
integrity sha512-QFS3feozIGsvB0H74lUocev55aRF26eNrdmhfJifwikZAiq+zzZAMdBdNU9UJhHClnMOU8/iGZ0MF7ti4zQS1A==
|
||||
"@chakra-ui/layout@2.1.18":
|
||||
version "2.1.18"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/layout/-/layout-2.1.18.tgz#f5dba687dfced9145d495f3a21edb5672df6bb73"
|
||||
integrity sha512-F4Gh2e+DGdaWdWT5NZduIFD9NM7Bnuh8sXARFHWPvIu7yvAwZ3ddqC9GK4F3qUngdmkJxDLWQqRSwSh96Lxbhw==
|
||||
dependencies:
|
||||
"@chakra-ui/breakpoint-utils" "2.0.8"
|
||||
"@chakra-ui/icon" "3.0.16"
|
||||
"@chakra-ui/object-utils" "2.0.8"
|
||||
"@chakra-ui/react-children-utils" "2.0.6"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/lazy-utils@2.0.5":
|
||||
@ -311,17 +311,17 @@
|
||||
"@chakra-ui/react-env" "3.0.0"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/menu@2.1.9":
|
||||
version "2.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/menu/-/menu-2.1.9.tgz#2f3239a9b2855fd77fc317d9e6b904c1ad50d7c6"
|
||||
integrity sha512-ue5nD4QJcl3H3UwN0zZNJmH89XUebnvEdW6THAUL41hDjJ0J/Fjpg9Sgzwug2aBbBXBNbVMsUuhcCj6x91d+IQ==
|
||||
"@chakra-ui/menu@2.1.12":
|
||||
version "2.1.12"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/menu/-/menu-2.1.12.tgz#ab83b7a5165bd31a6c68328d7f65a79e3412c48d"
|
||||
integrity sha512-ylNK1VJlr/3/EGg9dLPZ87cBJJjeiYXeU/gOAphsKXMnByrXWhbp4YVnyyyha2KZ0zEw0aPU4nCZ+A69aT9wrg==
|
||||
dependencies:
|
||||
"@chakra-ui/clickable" "2.0.14"
|
||||
"@chakra-ui/descendant" "3.0.13"
|
||||
"@chakra-ui/descendant" "3.0.14"
|
||||
"@chakra-ui/lazy-utils" "2.0.5"
|
||||
"@chakra-ui/popper" "3.0.13"
|
||||
"@chakra-ui/react-children-utils" "2.0.6"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/react-use-animation-state" "2.0.8"
|
||||
"@chakra-ui/react-use-controllable-state" "2.0.8"
|
||||
"@chakra-ui/react-use-disclosure" "2.0.8"
|
||||
@ -330,33 +330,33 @@
|
||||
"@chakra-ui/react-use-outside-click" "2.0.7"
|
||||
"@chakra-ui/react-use-update-effect" "2.0.7"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
"@chakra-ui/transition" "2.0.15"
|
||||
"@chakra-ui/transition" "2.0.16"
|
||||
|
||||
"@chakra-ui/modal@2.2.9":
|
||||
version "2.2.9"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/modal/-/modal-2.2.9.tgz#aad65a2c60aa974e023f8b3facc0e79eb742e006"
|
||||
integrity sha512-nTfNp7XsVwn5+xJOtstoFA8j0kq/9sJj7KesyYzjEDaMKvCZvIOntRYowoydho43jb4+YC7ebKhp0KOIINS0gg==
|
||||
"@chakra-ui/modal@2.2.11":
|
||||
version "2.2.11"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/modal/-/modal-2.2.11.tgz#8a964288759f3d681e23bfc3a837a3e2c7523f8e"
|
||||
integrity sha512-2J0ZUV5tEzkPiawdkgPz6bmex7NXAde1VXooMwdvK+vuT8PV3U61yorTJOZVLdw7TjjI1Yo94mzsp6UwBud43Q==
|
||||
dependencies:
|
||||
"@chakra-ui/close-button" "2.0.17"
|
||||
"@chakra-ui/focus-lock" "2.0.16"
|
||||
"@chakra-ui/portal" "2.0.15"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/portal" "2.0.16"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/react-types" "2.0.7"
|
||||
"@chakra-ui/react-use-merge-refs" "2.0.7"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
"@chakra-ui/transition" "2.0.15"
|
||||
"@chakra-ui/transition" "2.0.16"
|
||||
aria-hidden "^1.2.2"
|
||||
react-remove-scroll "^2.5.5"
|
||||
|
||||
"@chakra-ui/number-input@2.0.18":
|
||||
version "2.0.18"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/number-input/-/number-input-2.0.18.tgz#072a00ef869ebafa4960cfdee8caae8208864289"
|
||||
integrity sha512-cPkyAFFHHzeFBselrT1BtjlzMkJ6TKrTDUnHFlzqXy6aqeXuhrjFhMfXucjedSpOqedsP9ZbKFTdIAhu9DdL/A==
|
||||
"@chakra-ui/number-input@2.0.19":
|
||||
version "2.0.19"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/number-input/-/number-input-2.0.19.tgz#82d4522036904c04d07e7050822fc522f9b32233"
|
||||
integrity sha512-HDaITvtMEqOauOrCPsARDxKD9PSHmhWywpcyCSOX0lMe4xx2aaGhU0QQFhsJsykj8Er6pytMv6t0KZksdDv3YA==
|
||||
dependencies:
|
||||
"@chakra-ui/counter" "2.0.14"
|
||||
"@chakra-ui/form-control" "2.0.17"
|
||||
"@chakra-ui/form-control" "2.0.18"
|
||||
"@chakra-ui/icon" "3.0.16"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/react-types" "2.0.7"
|
||||
"@chakra-ui/react-use-callback-ref" "2.0.7"
|
||||
"@chakra-ui/react-use-event-listener" "2.0.7"
|
||||
@ -376,27 +376,27 @@
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/object-utils/-/object-utils-2.0.8.tgz#307f927f6434f99feb32ba92bdf451a6b59a6199"
|
||||
integrity sha512-2upjT2JgRuiupdrtBWklKBS6tqeGMA77Nh6Q0JaoQuH/8yq+15CGckqn3IUWkWoGI0Fg3bK9LDlbbD+9DLw95Q==
|
||||
|
||||
"@chakra-ui/pin-input@2.0.19":
|
||||
version "2.0.19"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/pin-input/-/pin-input-2.0.19.tgz#f9b196174f0518feec5c1ee3fcaf2134c301148a"
|
||||
integrity sha512-6O7s4vWz4cqQ6zvMov9sYj6ZqWAsTxR/MNGe3DNgu1zWQg8veNCYtj1rNGhNS3eZNUMAa8uM2dXIphGTP53Xow==
|
||||
"@chakra-ui/pin-input@2.0.20":
|
||||
version "2.0.20"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/pin-input/-/pin-input-2.0.20.tgz#5bf115bf4282b69fc6532a9c542cbf41f815d200"
|
||||
integrity sha512-IHVmerrtHN8F+jRB3W1HnMir1S1TUCWhI7qDInxqPtoRffHt6mzZgLZ0izx8p1fD4HkW4c1d4/ZLEz9uH9bBRg==
|
||||
dependencies:
|
||||
"@chakra-ui/descendant" "3.0.13"
|
||||
"@chakra-ui/descendant" "3.0.14"
|
||||
"@chakra-ui/react-children-utils" "2.0.6"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/react-use-controllable-state" "2.0.8"
|
||||
"@chakra-ui/react-use-merge-refs" "2.0.7"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/popover@2.1.8":
|
||||
version "2.1.8"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/popover/-/popover-2.1.8.tgz#e906ce0533693d735b6e13a3a6ffe16d8e0a9ab4"
|
||||
integrity sha512-ob7fAz+WWmXIq7iGHVB3wDKzZTj+T+noYBT/U1Q+jIf+jMr2WOpJLTfb0HTZcfhvn4EBFlfBg7Wk5qbXNaOn7g==
|
||||
"@chakra-ui/popover@2.1.9":
|
||||
version "2.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/popover/-/popover-2.1.9.tgz#890cc0dfc5022757715ccf772ec194e7a409275f"
|
||||
integrity sha512-OMJ12VVs9N32tFaZSOqikkKPtwAVwXYsES/D1pff/amBrE3ngCrpxJSIp4uvTdORfIYDojJqrR52ZplDKS9hRQ==
|
||||
dependencies:
|
||||
"@chakra-ui/close-button" "2.0.17"
|
||||
"@chakra-ui/lazy-utils" "2.0.5"
|
||||
"@chakra-ui/popper" "3.0.13"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/react-types" "2.0.7"
|
||||
"@chakra-ui/react-use-animation-state" "2.0.8"
|
||||
"@chakra-ui/react-use-disclosure" "2.0.8"
|
||||
@ -414,53 +414,53 @@
|
||||
"@chakra-ui/react-use-merge-refs" "2.0.7"
|
||||
"@popperjs/core" "^2.9.3"
|
||||
|
||||
"@chakra-ui/portal@2.0.15":
|
||||
version "2.0.15"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/portal/-/portal-2.0.15.tgz#21e1f97c4407fc15df8c365cb5cf799dac73ce41"
|
||||
integrity sha512-z8v7K3j1/nMuBzp2+wRIIw7s/eipVtnXLdjK5yqbMxMRa44E8Mu5VNJLz3aQFLHXEUST+ifqrjImQeli9do6LQ==
|
||||
"@chakra-ui/portal@2.0.16":
|
||||
version "2.0.16"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/portal/-/portal-2.0.16.tgz#e5ce3f9d9e559f17a95276e0c006d0e9b7703442"
|
||||
integrity sha512-bVID0qbQ0l4xq38LdqAN4EKD4/uFkDnXzFwOlviC9sl0dNhzICDb1ltuH/Adl1d2HTMqyN60O3GO58eHy7plnQ==
|
||||
dependencies:
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/react-use-safe-layout-effect" "2.0.5"
|
||||
|
||||
"@chakra-ui/progress@2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/progress/-/progress-2.1.5.tgz#eb6a47adf2bff93971262d163461d390782a04ff"
|
||||
integrity sha512-jj5Vp4lxUchuwp4RPCepM0yAyKi344bgsOd3Apd+ldxclDcewPc82fbwDu7g/Xv27LqJkT+7E/SlQy04wGrk0g==
|
||||
"@chakra-ui/progress@2.1.6":
|
||||
version "2.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/progress/-/progress-2.1.6.tgz#398db20440979c37adb0a34821f805ae3471873b"
|
||||
integrity sha512-hHh5Ysv4z6bK+j2GJbi/FT9CVyto2PtNUNwBmr3oNMVsoOUMoRjczfXvvYqp0EHr9PCpxqrq7sRwgQXUzhbDSw==
|
||||
dependencies:
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
|
||||
"@chakra-ui/provider@2.1.2":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/provider/-/provider-2.1.2.tgz#b025cb718826b003b3c9535b6961e8f3be70ebd5"
|
||||
integrity sha512-4lLlz8QuJv00BhfyKzWpzfoti9MDOdJ/MqXixJV/EZ02RMBOdE9qy9bSz/WckPC2MVhtRUuwMkxH+0QY21PXuw==
|
||||
"@chakra-ui/provider@2.2.2":
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/provider/-/provider-2.2.2.tgz#a798d1c243f33e00c85763834a7350e0d1c643ad"
|
||||
integrity sha512-UVwnIDnAWq1aKroN5AF+OpNpUqLVeIUk7tKvX3z4CY9FsPFFi6LTEhRHdhpwaU1Tau3Tf9agEu5URegpY7S8BA==
|
||||
dependencies:
|
||||
"@chakra-ui/css-reset" "2.0.12"
|
||||
"@chakra-ui/portal" "2.0.15"
|
||||
"@chakra-ui/css-reset" "2.1.1"
|
||||
"@chakra-ui/portal" "2.0.16"
|
||||
"@chakra-ui/react-env" "3.0.0"
|
||||
"@chakra-ui/system" "2.5.1"
|
||||
"@chakra-ui/system" "2.5.5"
|
||||
"@chakra-ui/utils" "2.0.15"
|
||||
|
||||
"@chakra-ui/radio@2.0.19":
|
||||
version "2.0.19"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/radio/-/radio-2.0.19.tgz#8d5c02eae8eddbced4476b1b50921ade62f0a744"
|
||||
integrity sha512-PlJiV59eGSmeKP4v/4+ccQUWGRd0cjPKkj/p3L+UbOf8pl9dWm8y9kIeL5TYbghQSDv0nzkrH4+yMnnDTZjdMQ==
|
||||
"@chakra-ui/radio@2.0.22":
|
||||
version "2.0.22"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/radio/-/radio-2.0.22.tgz#fad0ce7c9ba4051991ed517cac4cfe526d6d47d9"
|
||||
integrity sha512-GsQ5WAnLwivWl6gPk8P1x+tCcpVakCt5R5T0HumF7DGPXKdJbjS+RaFySrbETmyTJsKY4QrfXn+g8CWVrMjPjw==
|
||||
dependencies:
|
||||
"@chakra-ui/form-control" "2.0.17"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/form-control" "2.0.18"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/react-types" "2.0.7"
|
||||
"@chakra-ui/react-use-merge-refs" "2.0.7"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
"@zag-js/focus-visible" "0.2.1"
|
||||
"@zag-js/focus-visible" "0.2.2"
|
||||
|
||||
"@chakra-ui/react-children-utils@2.0.6":
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/react-children-utils/-/react-children-utils-2.0.6.tgz#6c480c6a60678fcb75cb7d57107c7a79e5179b92"
|
||||
integrity sha512-QVR2RC7QsOsbWwEnq9YduhpqSFnZGvjjGREV8ygKi8ADhXh93C8azLECCUVgRJF2Wc+So1fgxmjLcbZfY2VmBA==
|
||||
|
||||
"@chakra-ui/react-context@2.0.7":
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/react-context/-/react-context-2.0.7.tgz#f79a2b072d04d4280ec8799dc03a8a1af521ca2e"
|
||||
integrity sha512-i7EGmSU+h2GB30cwrKB4t1R5BMHyGoJM5L2Zz7b+ZUX4aAqyPcfe97wPiQB6Rgr1ImGXrUeov4CDVrRZ2FPgLQ==
|
||||
"@chakra-ui/react-context@2.0.8":
|
||||
version "2.0.8"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/react-context/-/react-context-2.0.8.tgz#5e0ed33ac3995875a21dea0e12b0ee5fc4c2e3cc"
|
||||
integrity sha512-tRTKdn6lCTXM6WPjSokAAKCw2ioih7Eg8cNgaYRSwKBck8nkz9YqxgIIEj3dJD7MGtpl24S/SNI98iRWkRwR/A==
|
||||
|
||||
"@chakra-ui/react-env@3.0.0":
|
||||
version "3.0.0"
|
||||
@ -568,12 +568,12 @@
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-safe-layout-effect/-/react-use-safe-layout-effect-2.0.5.tgz#6cf388c37fd2a42b5295a292e149b32f860a00a7"
|
||||
integrity sha512-MwAQBz3VxoeFLaesaSEN87reVNVbjcQBDex2WGexAg6hUB6n4gc1OWYH/iXp4tzp4kuggBNhEHkk9BMYXWfhJQ==
|
||||
|
||||
"@chakra-ui/react-use-size@2.0.9":
|
||||
version "2.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-size/-/react-use-size-2.0.9.tgz#00717867b98a24c3bdcfaa0c3e70732404193486"
|
||||
integrity sha512-Jce7QmO1jlQZq+Y77VKckWzroRnajChzUQ8xhLQZO6VbYvrpg3cu+X2QCz3G+MZzB+1/hnvvAqmZ+uJLd8rEJg==
|
||||
"@chakra-ui/react-use-size@2.0.10":
|
||||
version "2.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-size/-/react-use-size-2.0.10.tgz#6131950852490c06e5fb3760bf64097c8057391f"
|
||||
integrity sha512-fdIkH14GDnKQrtQfxX8N3gxbXRPXEl67Y3zeD9z4bKKcQUAYIMqs0MsPZY+FMpGQw8QqafM44nXfL038aIrC5w==
|
||||
dependencies:
|
||||
"@zag-js/element-size" "0.3.1"
|
||||
"@zag-js/element-size" "0.3.2"
|
||||
|
||||
"@chakra-ui/react-use-timeout@2.0.5":
|
||||
version "2.0.5"
|
||||
@ -594,69 +594,69 @@
|
||||
dependencies:
|
||||
"@chakra-ui/utils" "2.0.15"
|
||||
|
||||
"@chakra-ui/react@^2.5.1":
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/react/-/react-2.5.1.tgz#05414db2b512bd4402e42eecc6b915d85102c576"
|
||||
integrity sha512-ugkaqfcNMb9L4TkalWiF3rnqfr0TlUUD46JZaDIZiORVisaSwXTZTQrVfG40VghhaJT28rnC5WtiE8kd567ZBQ==
|
||||
"@chakra-ui/react@^2.5.5":
|
||||
version "2.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/react/-/react-2.5.5.tgz#5ae2450ec0d10d63e1314747466f21cf542032ff"
|
||||
integrity sha512-aBVMUtdWv2MrptD/tKSqICPsuJ+I+jvauegffO1qPUDlK3RrXIDeOHkLGWohgXNcjY5bGVWguFEzJm97//0ooQ==
|
||||
dependencies:
|
||||
"@chakra-ui/accordion" "2.1.9"
|
||||
"@chakra-ui/alert" "2.0.17"
|
||||
"@chakra-ui/avatar" "2.2.5"
|
||||
"@chakra-ui/breadcrumb" "2.1.4"
|
||||
"@chakra-ui/button" "2.0.16"
|
||||
"@chakra-ui/accordion" "2.1.11"
|
||||
"@chakra-ui/alert" "2.1.0"
|
||||
"@chakra-ui/avatar" "2.2.8"
|
||||
"@chakra-ui/breadcrumb" "2.1.5"
|
||||
"@chakra-ui/button" "2.0.18"
|
||||
"@chakra-ui/card" "2.1.6"
|
||||
"@chakra-ui/checkbox" "2.2.10"
|
||||
"@chakra-ui/checkbox" "2.2.14"
|
||||
"@chakra-ui/close-button" "2.0.17"
|
||||
"@chakra-ui/control-box" "2.0.13"
|
||||
"@chakra-ui/counter" "2.0.14"
|
||||
"@chakra-ui/css-reset" "2.0.12"
|
||||
"@chakra-ui/editable" "2.0.19"
|
||||
"@chakra-ui/css-reset" "2.1.1"
|
||||
"@chakra-ui/editable" "2.0.21"
|
||||
"@chakra-ui/focus-lock" "2.0.16"
|
||||
"@chakra-ui/form-control" "2.0.17"
|
||||
"@chakra-ui/form-control" "2.0.18"
|
||||
"@chakra-ui/hooks" "2.1.6"
|
||||
"@chakra-ui/icon" "3.0.16"
|
||||
"@chakra-ui/image" "2.0.15"
|
||||
"@chakra-ui/input" "2.0.20"
|
||||
"@chakra-ui/layout" "2.1.16"
|
||||
"@chakra-ui/input" "2.0.21"
|
||||
"@chakra-ui/layout" "2.1.18"
|
||||
"@chakra-ui/live-region" "2.0.13"
|
||||
"@chakra-ui/media-query" "3.2.12"
|
||||
"@chakra-ui/menu" "2.1.9"
|
||||
"@chakra-ui/modal" "2.2.9"
|
||||
"@chakra-ui/number-input" "2.0.18"
|
||||
"@chakra-ui/pin-input" "2.0.19"
|
||||
"@chakra-ui/popover" "2.1.8"
|
||||
"@chakra-ui/menu" "2.1.12"
|
||||
"@chakra-ui/modal" "2.2.11"
|
||||
"@chakra-ui/number-input" "2.0.19"
|
||||
"@chakra-ui/pin-input" "2.0.20"
|
||||
"@chakra-ui/popover" "2.1.9"
|
||||
"@chakra-ui/popper" "3.0.13"
|
||||
"@chakra-ui/portal" "2.0.15"
|
||||
"@chakra-ui/progress" "2.1.5"
|
||||
"@chakra-ui/provider" "2.1.2"
|
||||
"@chakra-ui/radio" "2.0.19"
|
||||
"@chakra-ui/portal" "2.0.16"
|
||||
"@chakra-ui/progress" "2.1.6"
|
||||
"@chakra-ui/provider" "2.2.2"
|
||||
"@chakra-ui/radio" "2.0.22"
|
||||
"@chakra-ui/react-env" "3.0.0"
|
||||
"@chakra-ui/select" "2.0.18"
|
||||
"@chakra-ui/select" "2.0.19"
|
||||
"@chakra-ui/skeleton" "2.0.24"
|
||||
"@chakra-ui/slider" "2.0.21"
|
||||
"@chakra-ui/slider" "2.0.23"
|
||||
"@chakra-ui/spinner" "2.0.13"
|
||||
"@chakra-ui/stat" "2.0.17"
|
||||
"@chakra-ui/styled-system" "2.6.1"
|
||||
"@chakra-ui/switch" "2.0.22"
|
||||
"@chakra-ui/system" "2.5.1"
|
||||
"@chakra-ui/table" "2.0.16"
|
||||
"@chakra-ui/tabs" "2.1.8"
|
||||
"@chakra-ui/tag" "2.0.17"
|
||||
"@chakra-ui/textarea" "2.0.18"
|
||||
"@chakra-ui/theme" "2.2.5"
|
||||
"@chakra-ui/theme-utils" "2.0.11"
|
||||
"@chakra-ui/toast" "6.0.1"
|
||||
"@chakra-ui/tooltip" "2.2.6"
|
||||
"@chakra-ui/transition" "2.0.15"
|
||||
"@chakra-ui/stat" "2.0.18"
|
||||
"@chakra-ui/styled-system" "2.8.0"
|
||||
"@chakra-ui/switch" "2.0.26"
|
||||
"@chakra-ui/system" "2.5.5"
|
||||
"@chakra-ui/table" "2.0.17"
|
||||
"@chakra-ui/tabs" "2.1.9"
|
||||
"@chakra-ui/tag" "3.0.0"
|
||||
"@chakra-ui/textarea" "2.0.19"
|
||||
"@chakra-ui/theme" "3.0.1"
|
||||
"@chakra-ui/theme-utils" "2.0.15"
|
||||
"@chakra-ui/toast" "6.1.1"
|
||||
"@chakra-ui/tooltip" "2.2.7"
|
||||
"@chakra-ui/transition" "2.0.16"
|
||||
"@chakra-ui/utils" "2.0.15"
|
||||
"@chakra-ui/visually-hidden" "2.0.15"
|
||||
|
||||
"@chakra-ui/select@2.0.18":
|
||||
version "2.0.18"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/select/-/select-2.0.18.tgz#4eb6092610067c1b4131353fe39b4466e251395b"
|
||||
integrity sha512-1d2lUT5LM6oOs5x4lzBh4GFDuXX62+lr+sgV7099g951/5UNbb0CS2hSZHsO7yZThLNbr7QTWZvAOAayVcGzdw==
|
||||
"@chakra-ui/select@2.0.19":
|
||||
version "2.0.19"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/select/-/select-2.0.19.tgz#957e95a17a890d8c0a851e2f00a8d8dd17932d66"
|
||||
integrity sha512-eAlFh+JhwtJ17OrB6fO6gEAGOMH18ERNrXLqWbYLrs674Le7xuREgtuAYDoxUzvYXYYTTdOJtVbcHGriI3o6rA==
|
||||
dependencies:
|
||||
"@chakra-ui/form-control" "2.0.17"
|
||||
"@chakra-ui/form-control" "2.0.18"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/shared-utils@2.0.5":
|
||||
@ -673,20 +673,20 @@
|
||||
"@chakra-ui/react-use-previous" "2.0.5"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/slider@2.0.21":
|
||||
version "2.0.21"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/slider/-/slider-2.0.21.tgz#f65b15bf0d5f827699ff9a2d6faee35006e2bfce"
|
||||
integrity sha512-Mm76yJxEqJl21+3waEcKg3tM8Y4elJ7mcViN6Brj35PTfzUJfSJxeBGo1nLPJ+X5jLj7o/L4kfBmUk3lY4QYEQ==
|
||||
"@chakra-ui/slider@2.0.23":
|
||||
version "2.0.23"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/slider/-/slider-2.0.23.tgz#9130c7aee8ca876be64d1aeba6b84fe421c8207b"
|
||||
integrity sha512-/eyRUXLla+ZdBUPXpakE3SAS2JS8mIJR6qcUYiPVKSpRAi6tMyYeQijAXn2QC1AUVd2JrG8Pz+1Jy7Po3uA7cA==
|
||||
dependencies:
|
||||
"@chakra-ui/number-utils" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/react-types" "2.0.7"
|
||||
"@chakra-ui/react-use-callback-ref" "2.0.7"
|
||||
"@chakra-ui/react-use-controllable-state" "2.0.8"
|
||||
"@chakra-ui/react-use-latest-ref" "2.0.5"
|
||||
"@chakra-ui/react-use-merge-refs" "2.0.7"
|
||||
"@chakra-ui/react-use-pan-event" "2.0.9"
|
||||
"@chakra-ui/react-use-size" "2.0.9"
|
||||
"@chakra-ui/react-use-size" "2.0.10"
|
||||
"@chakra-ui/react-use-update-effect" "2.0.7"
|
||||
|
||||
"@chakra-ui/spinner@2.0.13":
|
||||
@ -696,82 +696,82 @@
|
||||
dependencies:
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/stat@2.0.17":
|
||||
version "2.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/stat/-/stat-2.0.17.tgz#2cd712cc7e0d58d9cbd542deea911f1b0925074f"
|
||||
integrity sha512-PhD+5oVLWjQmGLfeZSmexp3AtLcaggWBwoMZ4z8QMZIQzf/fJJWMk0bMqxlpTv8ORDkfY/4ImuFB/RJHvcqlcA==
|
||||
"@chakra-ui/stat@2.0.18":
|
||||
version "2.0.18"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/stat/-/stat-2.0.18.tgz#9e5d21d162b7cf2cf92065c19291ead2d4660772"
|
||||
integrity sha512-wKyfBqhVlIs9bkSerUc6F9KJMw0yTIEKArW7dejWwzToCLPr47u+CtYO6jlJHV6lRvkhi4K4Qc6pyvtJxZ3VpA==
|
||||
dependencies:
|
||||
"@chakra-ui/icon" "3.0.16"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/styled-system@2.6.1":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/styled-system/-/styled-system-2.6.1.tgz#302d496d34c0b7b30c646a7e3c9b113a2f4588da"
|
||||
integrity sha512-jy/1dVi1LxjoRCm+Eo5mqBgvPy5SCWMlIcz6GbIZBDpkGeKZwtqrZLjekxxLBCy8ORY+kJlUB0FT6AzVR/1tjw==
|
||||
"@chakra-ui/styled-system@2.8.0":
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/styled-system/-/styled-system-2.8.0.tgz#c02aa7b4a15bd826c19d055cd226bd44f7470f26"
|
||||
integrity sha512-bmRv/8ACJGGKGx84U1npiUddwdNifJ+/ETklGwooS5APM0ymwUtBYZpFxjYNJrqvVYpg3mVY6HhMyBVptLS7iA==
|
||||
dependencies:
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
csstype "^3.0.11"
|
||||
lodash.mergewith "4.6.2"
|
||||
|
||||
"@chakra-ui/switch@2.0.22":
|
||||
version "2.0.22"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/switch/-/switch-2.0.22.tgz#7b35e2b10ea4cf91fb49f5175b4335c61dcd25b3"
|
||||
integrity sha512-+/Yy6y7VFD91uSPruF8ZvePi3tl5D8UNVATtWEQ+QBI92DLSM+PtgJ2F0Y9GMZ9NzMxpZ80DqwY7/kqcPCfLvw==
|
||||
"@chakra-ui/switch@2.0.26":
|
||||
version "2.0.26"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/switch/-/switch-2.0.26.tgz#b93eeafd788e47c21222524adceffe9ef62602d6"
|
||||
integrity sha512-x62lF6VazSZJQuVxosChVR6+0lIJe8Pxgkl/C9vxjhp2yVYb3mew5tcX/sDOu0dYZy8ro/9hMfGkdN4r9xEU8A==
|
||||
dependencies:
|
||||
"@chakra-ui/checkbox" "2.2.10"
|
||||
"@chakra-ui/checkbox" "2.2.14"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/system@2.5.1":
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/system/-/system-2.5.1.tgz#bc03a11ae31e795966c7618280548d5cd866f47e"
|
||||
integrity sha512-4+86OrcSoq7lGkm5fh+sJ3IWXSTzjz+HOllRbCW2Rtnmcg7ritiXVNV2VygEg2DrCcx5+tNqRHDM764zW+AEug==
|
||||
"@chakra-ui/system@2.5.5":
|
||||
version "2.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/system/-/system-2.5.5.tgz#b8b070d07ca9b0190363100396eea02cca754cec"
|
||||
integrity sha512-52BIp/Zyvefgxn5RTByfkTeG4J+y81LWEjWm8jCaRFsLVm8IFgqIrngtcq4I7gD5n/UKbneHlb4eLHo4uc5yDQ==
|
||||
dependencies:
|
||||
"@chakra-ui/color-mode" "2.1.12"
|
||||
"@chakra-ui/object-utils" "2.0.8"
|
||||
"@chakra-ui/react-utils" "2.0.12"
|
||||
"@chakra-ui/styled-system" "2.6.1"
|
||||
"@chakra-ui/theme-utils" "2.0.11"
|
||||
"@chakra-ui/styled-system" "2.8.0"
|
||||
"@chakra-ui/theme-utils" "2.0.15"
|
||||
"@chakra-ui/utils" "2.0.15"
|
||||
react-fast-compare "3.2.0"
|
||||
react-fast-compare "3.2.1"
|
||||
|
||||
"@chakra-ui/table@2.0.16":
|
||||
version "2.0.16"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/table/-/table-2.0.16.tgz#e69736cba5cfb218c5e40592ad9280c6e32f6fe7"
|
||||
integrity sha512-vWDXZ6Ad3Aj66curp1tZBHvCfQHX2FJ4ijLiqGgQszWFIchfhJ5vMgEBJaFMZ+BN1draAjuRTZqaQefOApzvRg==
|
||||
"@chakra-ui/table@2.0.17":
|
||||
version "2.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/table/-/table-2.0.17.tgz#ad394dc6dcbe5a8a9e6d899997ecca3471603977"
|
||||
integrity sha512-OScheTEp1LOYvTki2NFwnAYvac8siAhW9BI5RKm5f5ORL2gVJo4I72RUqE0aKe1oboxgm7CYt5afT5PS5cG61A==
|
||||
dependencies:
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/tabs@2.1.8":
|
||||
version "2.1.8"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/tabs/-/tabs-2.1.8.tgz#e83071380f9a3633810308d45de51be7a74f5eb9"
|
||||
integrity sha512-B7LeFN04Ny2jsSy5TFOQxnbZ6ITxGxLxsB2PE0vvQjMSblBrUryOxdjw80HZhfiw6od0ikK9CeKQOIt9QCguSw==
|
||||
"@chakra-ui/tabs@2.1.9":
|
||||
version "2.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/tabs/-/tabs-2.1.9.tgz#2e5214cb453c6cc0c240e82bd88af1042fc6fe0e"
|
||||
integrity sha512-Yf8e0kRvaGM6jfkJum0aInQ0U3ZlCafmrYYni2lqjcTtThqu+Yosmo3iYlnullXxCw5MVznfrkb9ySvgQowuYg==
|
||||
dependencies:
|
||||
"@chakra-ui/clickable" "2.0.14"
|
||||
"@chakra-ui/descendant" "3.0.13"
|
||||
"@chakra-ui/descendant" "3.0.14"
|
||||
"@chakra-ui/lazy-utils" "2.0.5"
|
||||
"@chakra-ui/react-children-utils" "2.0.6"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/react-use-controllable-state" "2.0.8"
|
||||
"@chakra-ui/react-use-merge-refs" "2.0.7"
|
||||
"@chakra-ui/react-use-safe-layout-effect" "2.0.5"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/tag@2.0.17":
|
||||
version "2.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/tag/-/tag-2.0.17.tgz#97adb86db190ddb3526060b78c590392e0ac8b4c"
|
||||
integrity sha512-A47zE9Ft9qxOJ+5r1cUseKRCoEdqCRzFm0pOtZgRcckqavglk75Xjgz8HbBpUO2zqqd49MlqdOwR8o87fXS1vg==
|
||||
"@chakra-ui/tag@3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/tag/-/tag-3.0.0.tgz#d86cdab59bb3ff7fc628c2dbe7a5ff1b36bd3e96"
|
||||
integrity sha512-YWdMmw/1OWRwNkG9pX+wVtZio+B89odaPj6XeMn5nfNN8+jyhIEpouWv34+CO9G0m1lupJTxPSfgLAd7cqXZMA==
|
||||
dependencies:
|
||||
"@chakra-ui/icon" "3.0.16"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
|
||||
"@chakra-ui/textarea@2.0.18":
|
||||
version "2.0.18"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/textarea/-/textarea-2.0.18.tgz#da6d629b465f65bbc7b48039c2e48a4ae1d853b4"
|
||||
integrity sha512-aGHHb29vVifO0OtcK/k8cMykzjOKo/coDTU0NJqz7OOLAWIMNV2eGenvmO1n9tTZbmbqHiX+Sa1nPRX+pd14lg==
|
||||
"@chakra-ui/textarea@2.0.19":
|
||||
version "2.0.19"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/textarea/-/textarea-2.0.19.tgz#470b459f9cb3255d2abbe07d46b0a5b60a6a32c5"
|
||||
integrity sha512-adJk+qVGsFeJDvfn56CcJKKse8k7oMGlODrmpnpTdF+xvlsiTM+1GfaJvgNSpHHuQFdz/A0z1uJtfGefk0G2ZA==
|
||||
dependencies:
|
||||
"@chakra-ui/form-control" "2.0.17"
|
||||
"@chakra-ui/form-control" "2.0.18"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/theme-tools@2.0.17":
|
||||
@ -783,57 +783,57 @@
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
color2k "^2.0.0"
|
||||
|
||||
"@chakra-ui/theme-utils@2.0.11":
|
||||
version "2.0.11"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/theme-utils/-/theme-utils-2.0.11.tgz#c01b1d14fdd63326d1ad11fd8f0872921ea43872"
|
||||
integrity sha512-lBAay6Sq3/fl7exd3mFxWAbzgdQowytor0fnlHrpNStn1HgFjXukwsf6356XQOie2Vd8qaMM7qZtMh4AiC0dcg==
|
||||
"@chakra-ui/theme-utils@2.0.15":
|
||||
version "2.0.15"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/theme-utils/-/theme-utils-2.0.15.tgz#968a5e8c47bb403323fe67049c7b751a6e47f069"
|
||||
integrity sha512-UuxtEgE7gwMTGDXtUpTOI7F5X0iHB9ekEOG5PWPn2wWBL7rlk2JtPI7UP5Um5Yg6vvBfXYGK1ySahxqsgf+87g==
|
||||
dependencies:
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
"@chakra-ui/styled-system" "2.6.1"
|
||||
"@chakra-ui/theme" "2.2.5"
|
||||
"@chakra-ui/styled-system" "2.8.0"
|
||||
"@chakra-ui/theme" "3.0.1"
|
||||
lodash.mergewith "4.6.2"
|
||||
|
||||
"@chakra-ui/theme@2.2.5":
|
||||
version "2.2.5"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/theme/-/theme-2.2.5.tgz#18ed1755ff27c1ff1f1a77083ffc546c361c926e"
|
||||
integrity sha512-hYASZMwu0NqEv6PPydu+F3I+kMNd44yR4TwjR/lXBz/LEh64L6UPY6kQjebCfgdVtsGdl3HKg+eLlfa7SvfRgw==
|
||||
"@chakra-ui/theme@3.0.1":
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/theme/-/theme-3.0.1.tgz#151fc5d1e23d0fd0cd29d28acf8f6017269c13fc"
|
||||
integrity sha512-92kDm/Ux/51uJqhRKevQo/O/rdwucDYcpHg2QuwzdAxISCeYvgtl2TtgOOl5EnqEP0j3IEAvZHZUlv8TTbawaw==
|
||||
dependencies:
|
||||
"@chakra-ui/anatomy" "2.1.2"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
"@chakra-ui/theme-tools" "2.0.17"
|
||||
|
||||
"@chakra-ui/toast@6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/toast/-/toast-6.0.1.tgz#726b67a57cdd592320bb3f450c66d007a2a1d902"
|
||||
integrity sha512-ej2kJXvu/d2h6qnXU5D8XTyw0qpsfmbiU7hUffo/sPxkz89AUOQ08RUuUmB1ssW/FZcQvNMJ5WgzCTKHGBxtxw==
|
||||
"@chakra-ui/toast@6.1.1":
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/toast/-/toast-6.1.1.tgz#7ca78f38069bc87fa75b64de76c8fc2758bdf419"
|
||||
integrity sha512-JtjIKkPVjEu8okGGCipCxNVgK/15h5AicTATZ6RbG2MsHmr4GfKG3fUCvpbuZseArqmLqGLQZQJjVE9vJzaSkQ==
|
||||
dependencies:
|
||||
"@chakra-ui/alert" "2.0.17"
|
||||
"@chakra-ui/alert" "2.1.0"
|
||||
"@chakra-ui/close-button" "2.0.17"
|
||||
"@chakra-ui/portal" "2.0.15"
|
||||
"@chakra-ui/react-context" "2.0.7"
|
||||
"@chakra-ui/portal" "2.0.16"
|
||||
"@chakra-ui/react-context" "2.0.8"
|
||||
"@chakra-ui/react-use-timeout" "2.0.5"
|
||||
"@chakra-ui/react-use-update-effect" "2.0.7"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
"@chakra-ui/styled-system" "2.6.1"
|
||||
"@chakra-ui/theme" "2.2.5"
|
||||
"@chakra-ui/styled-system" "2.8.0"
|
||||
"@chakra-ui/theme" "3.0.1"
|
||||
|
||||
"@chakra-ui/tooltip@2.2.6":
|
||||
version "2.2.6"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/tooltip/-/tooltip-2.2.6.tgz#a38f9ff2dd8a574c8cf49526c3846533455f8ddd"
|
||||
integrity sha512-4cbneidZ5+HCWge3OZzewRQieIvhDjSsl+scrl4Scx7E0z3OmqlTIESU5nGIZDBLYqKn/UirEZhqaQ33FOS2fw==
|
||||
"@chakra-ui/tooltip@2.2.7":
|
||||
version "2.2.7"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/tooltip/-/tooltip-2.2.7.tgz#7c305efb057a5fe4694b1b8d82395aec776d8f57"
|
||||
integrity sha512-ImUJ6NnVqARaYqpgtO+kzucDRmxo8AF3jMjARw0bx2LxUkKwgRCOEaaRK5p5dHc0Kr6t5/XqjDeUNa19/sLauA==
|
||||
dependencies:
|
||||
"@chakra-ui/popper" "3.0.13"
|
||||
"@chakra-ui/portal" "2.0.15"
|
||||
"@chakra-ui/portal" "2.0.16"
|
||||
"@chakra-ui/react-types" "2.0.7"
|
||||
"@chakra-ui/react-use-disclosure" "2.0.8"
|
||||
"@chakra-ui/react-use-event-listener" "2.0.7"
|
||||
"@chakra-ui/react-use-merge-refs" "2.0.7"
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
"@chakra-ui/transition@2.0.15":
|
||||
version "2.0.15"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/transition/-/transition-2.0.15.tgz#c640df2ea82f5ad58c55a6e1a7c338f377cb96d8"
|
||||
integrity sha512-o9LBK/llQfUDHF/Ty3cQ6nShpekKTqHUoJlUOzNKhoTsNpoRerr9v0jwojrX1YI02KtVjfhFU6PiqXlDfREoNw==
|
||||
"@chakra-ui/transition@2.0.16":
|
||||
version "2.0.16"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/transition/-/transition-2.0.16.tgz#498c91e6835bb5d950fd1d1402f483b85f7dcd87"
|
||||
integrity sha512-E+RkwlPc3H7P1crEXmXwDXMB2lqY2LLia2P5siQ4IEnRWIgZXlIw+8Em+NtHNgusel2N+9yuB0wT9SeZZeZ3CQ==
|
||||
dependencies:
|
||||
"@chakra-ui/shared-utils" "2.0.5"
|
||||
|
||||
@ -1081,6 +1081,18 @@
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz#c5a1a4bfe1b57f0c3e61b29883525c6da3e5c091"
|
||||
integrity sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==
|
||||
|
||||
"@eslint-community/eslint-utils@^4.2.0":
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59"
|
||||
integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==
|
||||
dependencies:
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
"@eslint-community/regexpp@^4.4.0":
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.0.tgz#f6f729b02feee2c749f57e334b7a1b5f40a81724"
|
||||
integrity sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==
|
||||
|
||||
"@eslint/eslintrc@^1.4.1":
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.4.1.tgz#af58772019a2d271b7e2d4c23ff4ddcba3ccfb3e"
|
||||
@ -1768,47 +1780,47 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.0.tgz#53ef263e5239728b56096b0a869595135b7952d2"
|
||||
integrity sha512-kr90f+ERiQtKWMz5rP32ltJ/BtULDI5RVO0uavn1HQUOwjx0R1h0rnDYNL0CepF1zL5bSY6FISAfd9tOdDhU5Q==
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^5.52.0":
|
||||
version "5.52.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.52.0.tgz#5fb0d43574c2411f16ea80f5fc335b8eaa7b28a8"
|
||||
integrity sha512-lHazYdvYVsBokwCdKOppvYJKaJ4S41CgKBcPvyd0xjZNbvQdhn/pnJlGtQksQ/NhInzdaeaSarlBjDXHuclEbg==
|
||||
"@typescript-eslint/eslint-plugin@^5.57.0":
|
||||
version "5.57.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.57.0.tgz#52c8a7a4512f10e7249ca1e2e61f81c62c34365c"
|
||||
integrity sha512-itag0qpN6q2UMM6Xgk6xoHa0D0/P+M17THnr4SVgqn9Rgam5k/He33MA7/D7QoJcdMxHFyX7U9imaBonAX/6qA==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "5.52.0"
|
||||
"@typescript-eslint/type-utils" "5.52.0"
|
||||
"@typescript-eslint/utils" "5.52.0"
|
||||
"@eslint-community/regexpp" "^4.4.0"
|
||||
"@typescript-eslint/scope-manager" "5.57.0"
|
||||
"@typescript-eslint/type-utils" "5.57.0"
|
||||
"@typescript-eslint/utils" "5.57.0"
|
||||
debug "^4.3.4"
|
||||
grapheme-splitter "^1.0.4"
|
||||
ignore "^5.2.0"
|
||||
natural-compare-lite "^1.4.0"
|
||||
regexpp "^3.2.0"
|
||||
semver "^7.3.7"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/parser@^5.52.0":
|
||||
version "5.52.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.52.0.tgz#73c136df6c0133f1d7870de7131ccf356f5be5a4"
|
||||
integrity sha512-e2KiLQOZRo4Y0D/b+3y08i3jsekoSkOYStROYmPUnGMEoA0h+k2qOH5H6tcjIc68WDvGwH+PaOrP1XRzLJ6QlA==
|
||||
"@typescript-eslint/parser@^5.57.0":
|
||||
version "5.57.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.57.0.tgz#f675bf2cd1a838949fd0de5683834417b757e4fa"
|
||||
integrity sha512-orrduvpWYkgLCyAdNtR1QIWovcNZlEm6yL8nwH/eTxWLd8gsP+25pdLHYzL2QdkqrieaDwLpytHqycncv0woUQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "5.52.0"
|
||||
"@typescript-eslint/types" "5.52.0"
|
||||
"@typescript-eslint/typescript-estree" "5.52.0"
|
||||
"@typescript-eslint/scope-manager" "5.57.0"
|
||||
"@typescript-eslint/types" "5.57.0"
|
||||
"@typescript-eslint/typescript-estree" "5.57.0"
|
||||
debug "^4.3.4"
|
||||
|
||||
"@typescript-eslint/scope-manager@5.52.0":
|
||||
version "5.52.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.52.0.tgz#a993d89a0556ea16811db48eabd7c5b72dcb83d1"
|
||||
integrity sha512-AR7sxxfBKiNV0FWBSARxM8DmNxrwgnYMPwmpkC1Pl1n+eT8/I2NAUPuwDy/FmDcC6F8pBfmOcaxcxRHspgOBMw==
|
||||
"@typescript-eslint/scope-manager@5.57.0":
|
||||
version "5.57.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.57.0.tgz#79ccd3fa7bde0758059172d44239e871e087ea36"
|
||||
integrity sha512-NANBNOQvllPlizl9LatX8+MHi7bx7WGIWYjPHDmQe5Si/0YEYfxSljJpoTyTWFTgRy3X8gLYSE4xQ2U+aCozSw==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.52.0"
|
||||
"@typescript-eslint/visitor-keys" "5.52.0"
|
||||
"@typescript-eslint/types" "5.57.0"
|
||||
"@typescript-eslint/visitor-keys" "5.57.0"
|
||||
|
||||
"@typescript-eslint/type-utils@5.52.0":
|
||||
version "5.52.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.52.0.tgz#9fd28cd02e6f21f5109e35496df41893f33167aa"
|
||||
integrity sha512-tEKuUHfDOv852QGlpPtB3lHOoig5pyFQN/cUiZtpw99D93nEBjexRLre5sQZlkMoHry/lZr8qDAt2oAHLKA6Jw==
|
||||
"@typescript-eslint/type-utils@5.57.0":
|
||||
version "5.57.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.57.0.tgz#98e7531c4e927855d45bd362de922a619b4319f2"
|
||||
integrity sha512-kxXoq9zOTbvqzLbdNKy1yFrxLC6GDJFE2Yuo3KqSwTmDOFjUGeWSakgoXT864WcK5/NAJkkONCiKb1ddsqhLXQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/typescript-estree" "5.52.0"
|
||||
"@typescript-eslint/utils" "5.52.0"
|
||||
"@typescript-eslint/typescript-estree" "5.57.0"
|
||||
"@typescript-eslint/utils" "5.57.0"
|
||||
debug "^4.3.4"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
@ -1822,13 +1834,18 @@
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.52.0.tgz#19e9abc6afb5bd37a1a9bea877a1a836c0b3241b"
|
||||
integrity sha512-oV7XU4CHYfBhk78fS7tkum+/Dpgsfi91IIDy7fjCyq2k6KB63M6gMC0YIvy+iABzmXThCRI6xpCEyVObBdWSDQ==
|
||||
|
||||
"@typescript-eslint/typescript-estree@5.52.0", "@typescript-eslint/typescript-estree@^5.13.0":
|
||||
version "5.52.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.52.0.tgz#6408cb3c2ccc01c03c278cb201cf07e73347dfca"
|
||||
integrity sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==
|
||||
"@typescript-eslint/types@5.57.0":
|
||||
version "5.57.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.57.0.tgz#727bfa2b64c73a4376264379cf1f447998eaa132"
|
||||
integrity sha512-mxsod+aZRSyLT+jiqHw1KK6xrANm19/+VFALVFP5qa/aiJnlP38qpyaTd0fEKhWvQk6YeNZ5LGwI1pDpBRBhtQ==
|
||||
|
||||
"@typescript-eslint/typescript-estree@5.57.0":
|
||||
version "5.57.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.57.0.tgz#ebcd0ee3e1d6230e888d88cddf654252d41e2e40"
|
||||
integrity sha512-LTzQ23TV82KpO8HPnWuxM2V7ieXW8O142I7hQTxWIHDcCEIjtkat6H96PFkYBQqGFLW/G/eVVOB9Z8rcvdY/Vw==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.52.0"
|
||||
"@typescript-eslint/visitor-keys" "5.52.0"
|
||||
"@typescript-eslint/types" "5.57.0"
|
||||
"@typescript-eslint/visitor-keys" "5.57.0"
|
||||
debug "^4.3.4"
|
||||
globby "^11.1.0"
|
||||
is-glob "^4.0.3"
|
||||
@ -1848,18 +1865,31 @@
|
||||
semver "^7.3.5"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/utils@5.52.0":
|
||||
"@typescript-eslint/typescript-estree@^5.13.0":
|
||||
version "5.52.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.52.0.tgz#b260bb5a8f6b00a0ed51db66bdba4ed5e4845a72"
|
||||
integrity sha512-As3lChhrbwWQLNk2HC8Ree96hldKIqk98EYvypd3It8Q1f8d5zWyIoaZEp2va5667M4ZyE7X8UUR+azXrFl+NA==
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.52.0.tgz#6408cb3c2ccc01c03c278cb201cf07e73347dfca"
|
||||
integrity sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.52.0"
|
||||
"@typescript-eslint/visitor-keys" "5.52.0"
|
||||
debug "^4.3.4"
|
||||
globby "^11.1.0"
|
||||
is-glob "^4.0.3"
|
||||
semver "^7.3.7"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/utils@5.57.0":
|
||||
version "5.57.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.57.0.tgz#eab8f6563a2ac31f60f3e7024b91bf75f43ecef6"
|
||||
integrity sha512-ps/4WohXV7C+LTSgAL5CApxvxbMkl9B9AUZRtnEFonpIxZDIT7wC1xfvuJONMidrkB9scs4zhtRyIwHh4+18kw==
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils" "^4.2.0"
|
||||
"@types/json-schema" "^7.0.9"
|
||||
"@types/semver" "^7.3.12"
|
||||
"@typescript-eslint/scope-manager" "5.52.0"
|
||||
"@typescript-eslint/types" "5.52.0"
|
||||
"@typescript-eslint/typescript-estree" "5.52.0"
|
||||
"@typescript-eslint/scope-manager" "5.57.0"
|
||||
"@typescript-eslint/types" "5.57.0"
|
||||
"@typescript-eslint/typescript-estree" "5.57.0"
|
||||
eslint-scope "^5.1.1"
|
||||
eslint-utils "^3.0.0"
|
||||
semver "^7.3.7"
|
||||
|
||||
"@typescript-eslint/visitor-keys@4.33.0":
|
||||
@ -1878,6 +1908,14 @@
|
||||
"@typescript-eslint/types" "5.52.0"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@5.57.0":
|
||||
version "5.57.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.57.0.tgz#e2b2f4174aff1d15eef887ce3d019ecc2d7a8ac1"
|
||||
integrity sha512-ery2g3k0hv5BLiKpPuwYt9KBkAp2ugT6VvyShXdLOkax895EC55sP0Tx5L0fZaQueiK3fBLvHVvEl3jFS5ia+g==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.57.0"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
"@vitejs/plugin-react-swc@^3.2.0":
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@vitejs/plugin-react-swc/-/plugin-react-swc-3.2.0.tgz#7c4f6e116a296c27f680d05750f9dbf798cf7709"
|
||||
@ -1890,15 +1928,15 @@
|
||||
resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
|
||||
integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==
|
||||
|
||||
"@zag-js/element-size@0.3.1":
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/element-size/-/element-size-0.3.1.tgz#f9f6ae98355e2250d18d0f6e2f1134a0ae4c6a2f"
|
||||
integrity sha512-jR5j4G//bRzcxwAACWi9EfITnwjNmn10LxF4NmALrdZU7/PNWP3uUCdhCxd/0SCyeiJXUl0yvD57rWAbKPs1nw==
|
||||
"@zag-js/element-size@0.3.2":
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/element-size/-/element-size-0.3.2.tgz#ebb76af2a024230482406db41344598d1a9f54f4"
|
||||
integrity sha512-bVvvigUGvAuj7PCkE5AbzvTJDTw5f3bg9nQdv+ErhVN8SfPPppLJEmmWdxqsRzrHXgx8ypJt/+Ty0kjtISVDsQ==
|
||||
|
||||
"@zag-js/focus-visible@0.2.1":
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/focus-visible/-/focus-visible-0.2.1.tgz#bf4f1009f4fd35a9728dfaa9214d8cb318fe8b1e"
|
||||
integrity sha512-19uTjoZGP4/Ax7kSNhhay9JA83BirKzpqLkeEAilrpdI1hE5xuq6q+tzJOsrMOOqJrm7LkmZp5lbsTQzvK2pYg==
|
||||
"@zag-js/focus-visible@0.2.2":
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@zag-js/focus-visible/-/focus-visible-0.2.2.tgz#56233480ca1275d3218fb2e10696a33d1a6b9e64"
|
||||
integrity sha512-0j2gZq8HiZ51z4zNnSkF1iSkqlwRDvdH+son3wHdoz+7IUdMN/5Exd4TxMJ+gq2Of1DiXReYLL9qqh2PdQ4wgA==
|
||||
|
||||
accepts@~1.3.4:
|
||||
version "1.3.8"
|
||||
@ -4510,10 +4548,10 @@ react-dropzone@^14.2.3:
|
||||
file-selector "^0.6.0"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
react-fast-compare@3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
|
||||
integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==
|
||||
react-fast-compare@3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.1.tgz#53933d9e14f364281d6cba24bfed7a4afb808b5f"
|
||||
integrity sha512-xTYf9zFim2pEif/Fw16dBiXpe0hoy5PxcD8+OwBnTtNLfIm3g6WxhKNurY+6OmdH1u6Ta/W/Vl6vjbYP1MFnDg==
|
||||
|
||||
react-fast-compare@^2.0.1:
|
||||
version "2.0.4"
|
||||
@ -5311,6 +5349,11 @@ typescript@^4.0.0, typescript@^4.5.5:
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
|
||||
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
|
||||
|
||||
typescript@^5.0.3:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.3.tgz#fe976f0c826a88d0a382007681cbb2da44afdedf"
|
||||
integrity sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==
|
||||
|
||||
unbox-primitive@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
|
||||
|
@ -22,6 +22,7 @@ import transformers
|
||||
from diffusers.pipeline_utils import DiffusionPipeline
|
||||
from diffusers.utils.import_utils import is_xformers_available
|
||||
from omegaconf import OmegaConf
|
||||
from pathlib import Path
|
||||
from PIL import Image, ImageOps
|
||||
from pytorch_lightning import logging, seed_everything
|
||||
|
||||
@ -200,6 +201,8 @@ class Generate:
|
||||
# it wasn't actually doing anything. This logic could be reinstated.
|
||||
self.device = torch.device(choose_torch_device())
|
||||
print(f">> Using device_type {self.device.type}")
|
||||
if self.device.type == 'cuda':
|
||||
print(f">> CUDA device '{torch.cuda.get_device_name(torch.cuda.current_device())}' (GPU {os.environ.get('CUDA_VISIBLE_DEVICES') or 0})")
|
||||
if full_precision:
|
||||
if self.precision != "auto":
|
||||
raise ValueError("Remove --full_precision / -F if using --precision")
|
||||
@ -526,6 +529,11 @@ class Generate:
|
||||
log_tokens=self.log_tokenization,
|
||||
)
|
||||
|
||||
|
||||
# untested code, so commented out for now
|
||||
# if self.model.peft_manager:
|
||||
# self.model = self.model.peft_manager.load(self.model, self.model.unet.dtype)
|
||||
|
||||
init_image, mask_image = self._make_images(
|
||||
init_img,
|
||||
init_mask,
|
||||
@ -907,12 +915,8 @@ class Generate:
|
||||
return self._load_generator(".omnibus", "Omnibus")
|
||||
|
||||
def _load_generator(self, module, class_name):
|
||||
if self.is_legacy_model(self.model_name):
|
||||
mn = f"ldm.invoke.ckpt_generator{module}"
|
||||
cn = f"Ckpt{class_name}"
|
||||
else:
|
||||
mn = f"ldm.invoke.generator{module}"
|
||||
cn = class_name
|
||||
mn = f"ldm.invoke.generator{module}"
|
||||
cn = class_name
|
||||
module = importlib.import_module(mn)
|
||||
constructor = getattr(module, cn)
|
||||
return constructor(self.model, self.precision)
|
||||
@ -974,7 +978,7 @@ class Generate:
|
||||
self.generators = {}
|
||||
|
||||
seed_everything(random.randrange(0, np.iinfo(np.uint32).max))
|
||||
if self.embedding_path is not None:
|
||||
if self.embedding_path and not model_data.get("ti_embeddings_loaded"):
|
||||
print(f'>> Loading embeddings from {self.embedding_path}')
|
||||
for root, _, files in os.walk(self.embedding_path):
|
||||
for name in files:
|
||||
@ -982,14 +986,24 @@ class Generate:
|
||||
self.model.textual_inversion_manager.load_textual_inversion(
|
||||
ti_path, defer_injecting_tokens=True
|
||||
)
|
||||
print(
|
||||
f'>> Textual inversion triggers: {", ".join(sorted(self.model.textual_inversion_manager.get_all_trigger_strings()))}'
|
||||
)
|
||||
model_data["ti_embeddings_loaded"] = True
|
||||
print(
|
||||
f'>> Textual inversion triggers: {", ".join(sorted(self.model.textual_inversion_manager.get_all_trigger_strings()))}'
|
||||
)
|
||||
|
||||
self.model_name = model_name
|
||||
self._set_sampler() # requires self.model_name to be set first
|
||||
self._save_last_used_model(model_name)
|
||||
return self.model
|
||||
|
||||
def _save_last_used_model(self,model_name:str):
|
||||
"""
|
||||
Save name of the last model used.
|
||||
"""
|
||||
model_file_path = Path(Globals.root,'.last_model')
|
||||
with open(model_file_path,'w') as f:
|
||||
f.write(model_name)
|
||||
|
||||
def load_huggingface_concepts(self, concepts: list[str]):
|
||||
self.model.textual_inversion_manager.load_huggingface_concepts(concepts)
|
||||
|
||||
@ -1117,9 +1131,6 @@ class Generate:
|
||||
def sample_to_lowres_estimated_image(self, samples):
|
||||
return self._make_base().sample_to_lowres_estimated_image(samples)
|
||||
|
||||
def is_legacy_model(self, model_name) -> bool:
|
||||
return self.model_manager.is_legacy(model_name)
|
||||
|
||||
def _set_sampler(self):
|
||||
if isinstance(self.model, DiffusionPipeline):
|
||||
return self._set_scheduler()
|
||||
|
@ -4,6 +4,7 @@ import shlex
|
||||
import sys
|
||||
import traceback
|
||||
from argparse import Namespace
|
||||
from packaging import version
|
||||
from pathlib import Path
|
||||
from typing import Union
|
||||
|
||||
@ -16,13 +17,15 @@ if sys.platform == "darwin":
|
||||
|
||||
import pyparsing # type: ignore
|
||||
|
||||
print(f'DEBUG: [1] All system modules imported', file=sys.stderr)
|
||||
|
||||
import ldm.invoke
|
||||
|
||||
from ..generate import Generate
|
||||
from .args import (Args, dream_cmd_from_png, metadata_dumps,
|
||||
metadata_from_png)
|
||||
from .generator.diffusers_pipeline import PipelineIntermediateState
|
||||
from .globals import Globals
|
||||
from .globals import Globals, global_config_dir
|
||||
from .image_util import make_grid
|
||||
from .log import write_log
|
||||
from .model_manager import ModelManager
|
||||
@ -30,14 +33,21 @@ from .pngwriter import PngWriter, retrieve_metadata, write_metadata
|
||||
from .readline import Completer, get_completer
|
||||
from ..util import url_attachment_name
|
||||
|
||||
print(f'DEBUG: [2] All invokeai modules imported', file=sys.stderr)
|
||||
|
||||
# global used in multiple functions (fix)
|
||||
infile = None
|
||||
|
||||
|
||||
def main():
|
||||
"""Initialize command-line parsers and the diffusion model"""
|
||||
global infile
|
||||
|
||||
print('DEBUG: [3] Entered main()', file=sys.stderr)
|
||||
print('DEBUG: INVOKEAI ENVIRONMENT:')
|
||||
print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
|
||||
print("\n".join([f'{x}:{os.environ[x]}' for x in os.environ.keys()]))
|
||||
print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
|
||||
|
||||
opt = Args()
|
||||
args = opt.parse_args()
|
||||
if not args:
|
||||
@ -64,7 +74,14 @@ def main():
|
||||
Globals.internet_available = args.internet_available and check_internet()
|
||||
Globals.disable_xformers = not args.xformers
|
||||
Globals.sequential_guidance = args.sequential_guidance
|
||||
Globals.ckpt_convert = args.ckpt_convert
|
||||
Globals.ckpt_convert = True # always true as of 2.3.4 for LoRA support
|
||||
|
||||
print(f'DEBUG: [4] Globals initialized', file=sys.stderr)
|
||||
|
||||
# run any post-install patches needed
|
||||
run_patches()
|
||||
|
||||
print(f'DEBUG: [5] Patches run', file=sys.stderr)
|
||||
|
||||
print(f">> Internet connectivity is {Globals.internet_available}")
|
||||
|
||||
@ -81,8 +98,9 @@ def main():
|
||||
# loading here to avoid long delays on startup
|
||||
# these two lines prevent a horrible warning message from appearing
|
||||
# when the frozen CLIP tokenizer is imported
|
||||
import transformers # type: ignore
|
||||
print(f'DEBUG: [6] Importing torch modules', file=sys.stderr)
|
||||
|
||||
import transformers # type: ignore
|
||||
from ldm.generate import Generate
|
||||
|
||||
transformers.logging.set_verbosity_error()
|
||||
@ -90,6 +108,7 @@ def main():
|
||||
|
||||
diffusers.logging.set_verbosity_error()
|
||||
|
||||
print(f'DEBUG: [7] loading restoration models', file=sys.stderr)
|
||||
# Loading Face Restoration and ESRGAN Modules
|
||||
gfpgan, codeformer, esrgan = load_face_restoration(opt)
|
||||
|
||||
@ -107,7 +126,11 @@ def main():
|
||||
else:
|
||||
embedding_path = None
|
||||
|
||||
if opt.lora_path:
|
||||
Globals.lora_models_dir = opt.lora_path
|
||||
|
||||
# migrate legacy models
|
||||
print(f'DEBUG: [8] migrating models', file=sys.stderr)
|
||||
ModelManager.migrate_models()
|
||||
|
||||
# load the infile as a list of lines
|
||||
@ -123,11 +146,14 @@ def main():
|
||||
print(f"{e}. Aborting.")
|
||||
sys.exit(-1)
|
||||
|
||||
model = opt.model or retrieve_last_used_model()
|
||||
|
||||
print(f'DEBUG: [9] Creating generate object', file=sys.stderr)
|
||||
# creating a Generate object:
|
||||
try:
|
||||
gen = Generate(
|
||||
conf=opt.conf,
|
||||
model=opt.model,
|
||||
model=model,
|
||||
sampler_name=opt.sampler_name,
|
||||
embedding_path=embedding_path,
|
||||
full_precision=opt.full_precision,
|
||||
@ -149,6 +175,7 @@ def main():
|
||||
print(">> changed to seamless tiling mode")
|
||||
|
||||
# preload the model
|
||||
print(f'DEBUG: [10] Loading default model', file=sys.stderr)
|
||||
try:
|
||||
gen.load_model()
|
||||
except KeyError:
|
||||
@ -156,15 +183,20 @@ def main():
|
||||
except Exception as e:
|
||||
report_model_error(opt, e)
|
||||
|
||||
# completer is the readline object
|
||||
completer = get_completer(opt, models=gen.model_manager.list_models())
|
||||
|
||||
# try to autoconvert new models
|
||||
if path := opt.autoimport:
|
||||
gen.model_manager.heuristic_import(
|
||||
str(path), convert=False, commit_to_conf=opt.conf
|
||||
str(path),
|
||||
commit_to_conf=opt.conf,
|
||||
config_file_callback=lambda x: _pick_configuration_file(completer,x),
|
||||
)
|
||||
|
||||
if path := opt.autoconvert:
|
||||
gen.model_manager.heuristic_import(
|
||||
str(path), convert=True, commit_to_conf=opt.conf
|
||||
str(path), commit_to_conf=opt.conf
|
||||
)
|
||||
|
||||
# web server loops forever
|
||||
@ -178,7 +210,7 @@ def main():
|
||||
)
|
||||
|
||||
try:
|
||||
main_loop(gen, opt)
|
||||
main_loop(gen, opt, completer)
|
||||
except KeyboardInterrupt:
|
||||
print(
|
||||
f'\nGoodbye!\nYou can start InvokeAI again by running the "invoke.bat" (or "invoke.sh") script from {Globals.root}'
|
||||
@ -189,8 +221,9 @@ def main():
|
||||
|
||||
|
||||
# TODO: main_loop() has gotten busy. Needs to be refactored.
|
||||
def main_loop(gen, opt):
|
||||
def main_loop(gen, opt, completer):
|
||||
"""prompt/read/execute loop"""
|
||||
print(f'DEBUG: [11] In main loop', file=sys.stderr)
|
||||
global infile
|
||||
done = False
|
||||
doneAfterInFile = infile is not None
|
||||
@ -200,7 +233,6 @@ def main_loop(gen, opt):
|
||||
# The readline completer reads history from the .dream_history file located in the
|
||||
# output directory specified at the time of script launch. We do not currently support
|
||||
# changing the history file midstream when the output directory is changed.
|
||||
completer = get_completer(opt, models=gen.model_manager.list_models())
|
||||
set_default_output_dir(opt, completer)
|
||||
if gen.model:
|
||||
add_embedding_terms(gen, completer)
|
||||
@ -389,6 +421,7 @@ def main_loop(gen, opt):
|
||||
prior_variations,
|
||||
postprocessed,
|
||||
first_seed,
|
||||
gen.model_name,
|
||||
)
|
||||
path = file_writer.save_image_and_prompt_to_png(
|
||||
image=image,
|
||||
@ -402,6 +435,7 @@ def main_loop(gen, opt):
|
||||
else first_seed
|
||||
],
|
||||
model_hash=gen.model_hash,
|
||||
model_id=gen.model_name,
|
||||
),
|
||||
name=filename,
|
||||
compress_level=opt.png_compression,
|
||||
@ -625,7 +659,7 @@ def set_default_output_dir(opt: Args, completer: Completer):
|
||||
completer.set_default_dir(opt.outdir)
|
||||
|
||||
|
||||
def import_model(model_path: str, gen, opt, completer, convert=False):
|
||||
def import_model(model_path: str, gen, opt, completer):
|
||||
"""
|
||||
model_path can be (1) a URL to a .ckpt file; (2) a local .ckpt file path;
|
||||
(3) a huggingface repository id; or (4) a local directory containing a
|
||||
@ -656,11 +690,10 @@ def import_model(model_path: str, gen, opt, completer, convert=False):
|
||||
model_path,
|
||||
model_name=model_name,
|
||||
description=model_desc,
|
||||
convert=convert,
|
||||
config_file_callback=lambda x: _pick_configuration_file(completer,x),
|
||||
)
|
||||
|
||||
if not imported_name:
|
||||
print("** Import failed or was skipped")
|
||||
print("** Aborting import.")
|
||||
return
|
||||
|
||||
if not _verify_load(imported_name, gen):
|
||||
@ -674,6 +707,48 @@ def import_model(model_path: str, gen, opt, completer, convert=False):
|
||||
completer.update_models(gen.model_manager.list_models())
|
||||
print(f">> {imported_name} successfully installed")
|
||||
|
||||
def _pick_configuration_file(completer, checkpoint_path: Path)->Path:
|
||||
print(
|
||||
f"""
|
||||
Please select the type of the model at checkpoint {checkpoint_path}:
|
||||
[1] A Stable Diffusion v1.x ckpt/safetensors model
|
||||
[2] A Stable Diffusion v1.x inpainting ckpt/safetensors model
|
||||
[3] A Stable Diffusion v2.x base model (512 pixels; there should be no 'parameterization:' line in its yaml file)
|
||||
[4] A Stable Diffusion v2.x v-predictive model (768 pixels; look for a 'parameterization: "v"' line in its yaml file)
|
||||
[5] Other (you will be prompted to enter the config file path)
|
||||
[Q] I have no idea! Skip the import.
|
||||
""")
|
||||
choices = [
|
||||
global_config_dir() / 'stable-diffusion' / x
|
||||
for x in [
|
||||
'v1-inference.yaml',
|
||||
'v1-inpainting-inference.yaml',
|
||||
'v2-inference.yaml',
|
||||
'v2-inference-v.yaml',
|
||||
]
|
||||
]
|
||||
|
||||
ok = False
|
||||
while not ok:
|
||||
try:
|
||||
choice = input('select 0-5, Q > ').strip()
|
||||
if choice.startswith(('q','Q')):
|
||||
return
|
||||
if choice == '5':
|
||||
completer.complete_extensions(('.yaml'))
|
||||
choice = Path(input('Select config file for this model> ').strip()).absolute()
|
||||
completer.complete_extensions(None)
|
||||
ok = choice.exists()
|
||||
else:
|
||||
choice = choices[int(choice)-1]
|
||||
ok = True
|
||||
except (ValueError, IndexError):
|
||||
print(f'{choice} is not a valid choice')
|
||||
except EOFError:
|
||||
return
|
||||
return choice
|
||||
|
||||
|
||||
def _verify_load(model_name: str, gen) -> bool:
|
||||
print(">> Verifying that new model loads...")
|
||||
current_model = gen.model_name
|
||||
@ -720,14 +795,10 @@ def convert_model(model_name_or_path: Union[Path, str], gen, opt, completer):
|
||||
original_config_file = Path(model_info["config"])
|
||||
model_name = model_name_or_path
|
||||
model_description = model_info["description"]
|
||||
vae = model_info["vae"]
|
||||
vae_path = model_info.get("vae")
|
||||
else:
|
||||
print(f"** {model_name_or_path} is not a legacy .ckpt weights file")
|
||||
return
|
||||
if vae_repo := ldm.invoke.model_manager.VAE_TO_REPO_ID.get(Path(vae).stem):
|
||||
vae_repo = dict(repo_id=vae_repo)
|
||||
else:
|
||||
vae_repo = None
|
||||
model_name = manager.convert_and_import(
|
||||
ckpt_path,
|
||||
diffusers_path=Path(
|
||||
@ -736,16 +807,16 @@ def convert_model(model_name_or_path: Union[Path, str], gen, opt, completer):
|
||||
model_name=model_name,
|
||||
model_description=model_description,
|
||||
original_config_file=original_config_file,
|
||||
vae=vae_repo,
|
||||
vae_path=vae_path,
|
||||
)
|
||||
else:
|
||||
try:
|
||||
import_model(model_name_or_path, gen, opt, completer, convert=True)
|
||||
import_model(model_name_or_path, gen, opt, completer)
|
||||
except KeyboardInterrupt:
|
||||
return
|
||||
|
||||
manager.commit(opt.conf)
|
||||
if click.confirm(f"Delete the original .ckpt file at {ckpt_path}?", default=False):
|
||||
if ckpt_path and click.confirm(f"Delete the original .ckpt file at {ckpt_path}?", default=False):
|
||||
ckpt_path.unlink(missing_ok=True)
|
||||
print(f"{ckpt_path} deleted")
|
||||
|
||||
@ -782,6 +853,7 @@ def edit_model(model_name: str, gen, opt, completer):
|
||||
print(f"\n>> Editing model {model_name} from configuration file {opt.conf}")
|
||||
new_name = _get_model_name(manager.list_models(), completer, model_name)
|
||||
|
||||
completer.complete_extensions(('.yaml','.ckpt','.safetensors','.pt'))
|
||||
for attribute in info.keys():
|
||||
if type(info[attribute]) != str:
|
||||
continue
|
||||
@ -789,6 +861,7 @@ def edit_model(model_name: str, gen, opt, completer):
|
||||
continue
|
||||
completer.set_line(info[attribute])
|
||||
info[attribute] = input(f"{attribute}: ") or info[attribute]
|
||||
completer.complete_extensions(None)
|
||||
|
||||
if info["format"] == "diffusers":
|
||||
vae = info.get("vae", dict(repo_id=None, path=None, subfolder=None))
|
||||
@ -941,13 +1014,14 @@ def add_postprocessing_to_metadata(opt, original_file, new_file, tool, command):
|
||||
|
||||
|
||||
def prepare_image_metadata(
|
||||
opt,
|
||||
prefix,
|
||||
seed,
|
||||
operation="generate",
|
||||
prior_variations=[],
|
||||
postprocessed=False,
|
||||
first_seed=None,
|
||||
opt,
|
||||
prefix,
|
||||
seed,
|
||||
operation="generate",
|
||||
prior_variations=[],
|
||||
postprocessed=False,
|
||||
first_seed=None,
|
||||
model_id='unknown',
|
||||
):
|
||||
if postprocessed and opt.save_original:
|
||||
filename = choose_postprocess_name(opt, prefix, seed)
|
||||
@ -955,6 +1029,7 @@ def prepare_image_metadata(
|
||||
wildcards = dict(opt.__dict__)
|
||||
wildcards["prefix"] = prefix
|
||||
wildcards["seed"] = seed
|
||||
wildcards["model_id"] = model_id
|
||||
try:
|
||||
filename = opt.fnformat.format(**wildcards)
|
||||
except KeyError as e:
|
||||
@ -972,18 +1047,17 @@ def prepare_image_metadata(
|
||||
first_seed = first_seed or seed
|
||||
this_variation = [[seed, opt.variation_amount]]
|
||||
opt.with_variations = prior_variations + this_variation
|
||||
formatted_dream_prompt = opt.dream_prompt_str(seed=first_seed)
|
||||
formatted_dream_prompt = opt.dream_prompt_str(seed=first_seed,model_id=model_id)
|
||||
elif len(prior_variations) > 0:
|
||||
formatted_dream_prompt = opt.dream_prompt_str(seed=first_seed)
|
||||
formatted_dream_prompt = opt.dream_prompt_str(seed=first_seed,model_id=model_id)
|
||||
elif operation == "postprocess":
|
||||
formatted_dream_prompt = "!fix " + opt.dream_prompt_str(
|
||||
seed=seed, prompt=opt.input_file_path
|
||||
seed=seed, prompt=opt.input_file_path, model_id=model_id,
|
||||
)
|
||||
else:
|
||||
formatted_dream_prompt = opt.dream_prompt_str(seed=seed)
|
||||
formatted_dream_prompt = opt.dream_prompt_str(seed=seed,model_id=model_id)
|
||||
return filename, formatted_dream_prompt
|
||||
|
||||
|
||||
def choose_postprocess_name(opt, prefix, seed) -> str:
|
||||
match = re.search("postprocess:(\w+)", opt.last_operation)
|
||||
if match:
|
||||
@ -1234,6 +1308,75 @@ def check_internet() -> bool:
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
def retrieve_last_used_model()->str:
|
||||
"""
|
||||
Return name of the last model used.
|
||||
"""
|
||||
model_file_path = Path(Globals.root,'.last_model')
|
||||
if not model_file_path.exists():
|
||||
return None
|
||||
with open(model_file_path,'r') as f:
|
||||
return f.readline()
|
||||
|
||||
# This routine performs any patch-ups needed after installation
|
||||
def run_patches():
|
||||
install_missing_config_files()
|
||||
version_file = Path(Globals.root,'.version')
|
||||
if version_file.exists():
|
||||
with open(version_file,'r') as f:
|
||||
root_version = version.parse(f.readline() or 'v2.3.2')
|
||||
else:
|
||||
root_version = version.parse('v2.3.2')
|
||||
app_version = version.parse(ldm.invoke.__version__)
|
||||
if root_version < app_version:
|
||||
try:
|
||||
do_version_update(root_version, ldm.invoke.__version__)
|
||||
with open(version_file,'w') as f:
|
||||
f.write(ldm.invoke.__version__)
|
||||
except:
|
||||
print("** Update failed. Will try again on next launch")
|
||||
|
||||
def install_missing_config_files():
|
||||
"""
|
||||
install ckpt configuration files that may have been added to the
|
||||
distro after original root directory configuration
|
||||
"""
|
||||
pass
|
||||
# import invokeai.configs as conf
|
||||
# from shutil import copyfile
|
||||
|
||||
# root_configs = Path(global_config_dir(), 'stable-diffusion')
|
||||
# repo_configs = Path(conf.__path__[0], 'stable-diffusion')
|
||||
# for src in repo_configs.iterdir():
|
||||
# dest = root_configs / src.name
|
||||
# if not dest.exists():
|
||||
# copyfile(src,dest)
|
||||
|
||||
def do_version_update(root_version: version.Version, app_version: Union[str, version.Version]):
|
||||
"""
|
||||
Make any updates to the launcher .sh and .bat scripts that may be needed
|
||||
from release to release. This is not an elegant solution. Instead, the
|
||||
launcher should be moved into the source tree and installed using pip.
|
||||
"""
|
||||
if root_version < version.Version('v2.3.4'):
|
||||
dest = Path(Globals.root,'loras')
|
||||
dest.mkdir(exist_ok=True)
|
||||
if root_version < version.Version('v2.3.3'):
|
||||
if sys.platform == "linux":
|
||||
print('>> Downloading new version of launcher script and its config file')
|
||||
from ldm.util import download_with_progress_bar
|
||||
url_base = f'https://raw.githubusercontent.com/invoke-ai/InvokeAI/v{str(app_version)}/installer/templates/'
|
||||
|
||||
dest = Path(Globals.root,'invoke.sh.in')
|
||||
assert download_with_progress_bar(url_base+'invoke.sh.in',dest)
|
||||
dest.replace(Path(Globals.root,'invoke.sh'))
|
||||
os.chmod(Path(Globals.root,'invoke.sh'), 0o0755)
|
||||
|
||||
dest = Path(Globals.root,'dialogrc')
|
||||
assert download_with_progress_bar(url_base+'dialogrc',dest)
|
||||
dest.replace(Path(Globals.root,'.dialogrc'))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
@ -1 +1 @@
|
||||
__version__='2.3.1'
|
||||
__version__='2.3.4'
|
||||
|
@ -1,80 +0,0 @@
|
||||
# Copyright (c) 2022 Kyle Schouviller (https://github.com/kyle0654)
|
||||
|
||||
from argparse import Namespace
|
||||
import os
|
||||
|
||||
from ..services.processor import DefaultInvocationProcessor
|
||||
|
||||
from ..services.graph import GraphExecutionState
|
||||
from ..services.sqlite import SqliteItemStorage
|
||||
|
||||
from ...globals import Globals
|
||||
|
||||
from ..services.image_storage import DiskImageStorage
|
||||
from ..services.invocation_queue import MemoryInvocationQueue
|
||||
from ..services.invocation_services import InvocationServices
|
||||
from ..services.invoker import Invoker
|
||||
from ..services.generate_initializer import get_generate
|
||||
from .events import FastAPIEventService
|
||||
|
||||
|
||||
# TODO: is there a better way to achieve this?
|
||||
def check_internet()->bool:
|
||||
'''
|
||||
Return true if the internet is reachable.
|
||||
It does this by pinging huggingface.co.
|
||||
'''
|
||||
import urllib.request
|
||||
host = 'http://huggingface.co'
|
||||
try:
|
||||
urllib.request.urlopen(host,timeout=1)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
class ApiDependencies:
|
||||
"""Contains and initializes all dependencies for the API"""
|
||||
invoker: Invoker = None
|
||||
|
||||
@staticmethod
|
||||
def initialize(
|
||||
args,
|
||||
config,
|
||||
event_handler_id: int
|
||||
):
|
||||
Globals.try_patchmatch = args.patchmatch
|
||||
Globals.always_use_cpu = args.always_use_cpu
|
||||
Globals.internet_available = args.internet_available and check_internet()
|
||||
Globals.disable_xformers = not args.xformers
|
||||
Globals.ckpt_convert = args.ckpt_convert
|
||||
|
||||
# TODO: Use a logger
|
||||
print(f'>> Internet connectivity is {Globals.internet_available}')
|
||||
|
||||
generate = get_generate(args, config)
|
||||
|
||||
events = FastAPIEventService(event_handler_id)
|
||||
|
||||
output_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../outputs'))
|
||||
|
||||
images = DiskImageStorage(output_folder)
|
||||
|
||||
# TODO: build a file/path manager?
|
||||
db_location = os.path.join(output_folder, 'invokeai.db')
|
||||
|
||||
services = InvocationServices(
|
||||
generate = generate,
|
||||
events = events,
|
||||
images = images,
|
||||
queue = MemoryInvocationQueue(),
|
||||
graph_execution_manager = SqliteItemStorage[GraphExecutionState](filename = db_location, table_name = 'graph_executions'),
|
||||
processor = DefaultInvocationProcessor()
|
||||
)
|
||||
|
||||
ApiDependencies.invoker = Invoker(services)
|
||||
|
||||
@staticmethod
|
||||
def shutdown():
|
||||
if ApiDependencies.invoker:
|
||||
ApiDependencies.invoker.stop()
|
@ -1,54 +0,0 @@
|
||||
# Copyright (c) 2022 Kyle Schouviller (https://github.com/kyle0654)
|
||||
|
||||
import asyncio
|
||||
from queue import Empty, Queue
|
||||
from typing import Any
|
||||
from fastapi_events.dispatcher import dispatch
|
||||
from ..services.events import EventServiceBase
|
||||
import threading
|
||||
|
||||
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(dict(
|
||||
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.001)
|
||||
pass
|
||||
|
||||
except asyncio.CancelledError as e:
|
||||
raise e # Raise a proper error
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user