Compare commits
145 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ca842ad87 | ||
|
|
12e7e6e8df | ||
|
|
152b7fc2bc | ||
|
|
4bb6c8180e | ||
|
|
a338616ced | ||
|
|
65a99c47d3 | ||
|
|
e4bb49b4f0 | ||
|
|
2ad489a1ef | ||
|
|
ecb904f8b7 | ||
|
|
61ead2c92d | ||
|
|
c5a8c499ab | ||
|
|
bd6278c361 | ||
|
|
e24d4dc15b | ||
|
|
3d4c70604d | ||
|
|
d73aea43b7 | ||
|
|
358f0af79a | ||
|
|
0650735f74 | ||
|
|
e469bbb89e | ||
|
|
a46633a355 | ||
|
|
7275006c37 | ||
|
|
e438d46314 | ||
|
|
bf8d6d8908 | ||
|
|
b9e1aeb2dd | ||
|
|
fd81a69b4d | ||
|
|
5a15ad3148 | ||
|
|
22a37ef714 | ||
|
|
59c8024f0c | ||
|
|
22b3a59f16 | ||
|
|
48e21486cb | ||
|
|
a6fa882b7c | ||
|
|
aa12adccf3 | ||
|
|
282a2f642b | ||
|
|
d211c34f7b | ||
|
|
e995e97690 | ||
|
|
aa247e68be | ||
|
|
895c47fd11 | ||
|
|
0c32d7b507 | ||
|
|
09625eae66 | ||
|
|
76249b3d4e | ||
|
|
d85cd99f17 | ||
|
|
f4576dcc2d | ||
|
|
62fe308f84 | ||
|
|
9b984e0d1e | ||
|
|
5502b29340 | ||
|
|
15fa246ccf | ||
|
|
4929ae6c1d | ||
|
|
16a52a607d | ||
|
|
7c68eff99f | ||
|
|
2048a47b85 | ||
|
|
f73d5a647d | ||
|
|
365e2dde1b | ||
|
|
a48e021c0b | ||
|
|
825fa6977d | ||
|
|
e332529fbd | ||
|
|
0f6aa7fe19 | ||
|
|
b8870d8290 | ||
|
|
ffa91be3f1 | ||
|
|
2d5294bca1 | ||
|
|
2468a28e66 | ||
|
|
e3ed748191 | ||
|
|
3f5bf7ac44 | ||
|
|
00378e1ea6 | ||
|
|
b45e632f23 | ||
|
|
57be9ae6c3 | ||
|
|
6c9a2761f5 | ||
|
|
2bdd738f03 | ||
|
|
7782760541 | ||
|
|
de2686d323 | ||
|
|
0b72a4a35e | ||
|
|
942a202945 | ||
|
|
1379642fc6 | ||
|
|
408cf5e092 | ||
|
|
ce298d32b5 | ||
|
|
d7107d931a | ||
|
|
147dcc2961 | ||
|
|
efd7f42414 | ||
|
|
4e1b619ad7 | ||
|
|
f26199d377 | ||
|
|
90cd791e76 | ||
|
|
5a95ce5625 | ||
|
|
89da42ad79 | ||
|
|
e8aba99c92 | ||
|
|
ced9c83e96 | ||
|
|
247816db9a | ||
|
|
80f2cfe3e3 | ||
|
|
9a15a89e20 | ||
|
|
c73a61b785 | ||
|
|
88203d8db2 | ||
|
|
881c69e905 | ||
|
|
c40278dae7 | ||
|
|
7b329b7c91 | ||
|
|
c19b02ab21 | ||
|
|
6ebddf09c2 | ||
|
|
5841e1b5be | ||
|
|
5f09ffa276 | ||
|
|
9e70c216f6 | ||
|
|
cbe8a9550c | ||
|
|
259ecb7b71 | ||
|
|
002791ef68 | ||
|
|
21e491f878 | ||
|
|
12c4c715aa | ||
|
|
fe700d27df | ||
|
|
7a4ceb0f7c | ||
|
|
bb5d77a9fb | ||
|
|
3c55baf06b | ||
|
|
ca882ad5ff | ||
|
|
6a7b4ef63f | ||
|
|
f60d22b29b | ||
|
|
6a6fbe24a3 | ||
|
|
5efd2ed7a8 | ||
|
|
62c346850c | ||
|
|
f6fafe3eb3 | ||
|
|
6547c320a9 | ||
|
|
2d32cf4eeb | ||
|
|
7a4e358d53 | ||
|
|
ac1469bbd3 | ||
|
|
c0c32d9daa | ||
|
|
52e74fef7c | ||
|
|
e431d296c0 | ||
|
|
1e7a5fda24 | ||
|
|
050d72478e | ||
|
|
d3a09f1284 | ||
|
|
e096eef049 | ||
|
|
62c97dd7e6 | ||
|
|
e58b7a7ef9 | ||
|
|
dc556cb1a7 | ||
|
|
0c8f0e3386 | ||
|
|
98f03053ba | ||
|
|
59ef2471e1 | ||
|
|
ce7651944d | ||
|
|
a3e0b285d8 | ||
|
|
3cdfedc649 | ||
|
|
531f596bd1 | ||
|
|
8683426041 | ||
|
|
631592ec99 | ||
|
|
4cd29420ef | ||
|
|
582fee6c3a | ||
|
|
2b39d1677c | ||
|
|
47342277dd | ||
|
|
f7ce6fae9a | ||
|
|
8566490e51 | ||
|
|
6151968cd3 | ||
|
|
ba4691dae8 | ||
|
|
7d16af3aa7 | ||
|
|
61ff90d1fd |
102
.github/ISSUE_TEMPLATE/BUG_REPORT.yml
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
name: 🐞 Bug Report
|
||||
|
||||
description: File a bug report
|
||||
|
||||
title: '[bug]: '
|
||||
|
||||
labels: ['bug']
|
||||
|
||||
# assignees:
|
||||
# - moderator_bot
|
||||
# - lstein
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this Bug Report!
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
description: |
|
||||
Please use the [search function](https://github.com/invoke-ai/InvokeAI/issues?q=is%3Aissue+is%3Aopen+label%3Abug)
|
||||
irst to see if an issue already exists for the bug you encountered.
|
||||
options:
|
||||
- label: I have searched the existing issues
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: __Describe your environment__
|
||||
|
||||
- type: dropdown
|
||||
id: os_dropdown
|
||||
attributes:
|
||||
label: OS
|
||||
description: Which operating System did you use when the bug occured
|
||||
multiple: false
|
||||
options:
|
||||
- 'Linux'
|
||||
- 'Windows'
|
||||
- 'macOS'
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: gpu_dropdown
|
||||
attributes:
|
||||
label: GPU
|
||||
description: Which kind of Graphic-Adapter is your System using
|
||||
multiple: false
|
||||
options:
|
||||
- 'cuda'
|
||||
- 'amd'
|
||||
- 'mps'
|
||||
- 'cpu'
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: vram
|
||||
attributes:
|
||||
label: VRAM
|
||||
description: Size of the VRAM if known
|
||||
placeholder: 8GB
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: |
|
||||
Briefly describe what happened, what you expected to happen and how to reproduce this bug.
|
||||
placeholder: When using the webinterface and right-clicking on button X instead of the popup-menu there error Y appears
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Screenshots
|
||||
description: If applicable, add screenshots to help explain your problem
|
||||
placeholder: this is what the result looked like <screenshot>
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context about the problem here
|
||||
placeholder: Only happens when there is full moon and Friday the 13th on Christmas Eve 🎅🏻
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: input
|
||||
id: contact
|
||||
attributes:
|
||||
label: Contact Details
|
||||
description: __OPTIONAL__ How can we get in touch with you if we need more info (besides this issue)?
|
||||
placeholder: ex. email@example.com, discordname, twitter, ...
|
||||
validations:
|
||||
required: false
|
||||
56
.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
name: Feature Request
|
||||
description: Commit a idea or Request a new feature
|
||||
title: '[enhancement]: '
|
||||
labels: ['enhancement']
|
||||
# assignees:
|
||||
# - lstein
|
||||
# - tildebyte
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this Feature request!
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
description: |
|
||||
Please make use of the [search function](https://github.com/invoke-ai/InvokeAI/labels/enhancement)
|
||||
to see if a simmilar issue already exists for the feature you want to request
|
||||
options:
|
||||
- label: I have searched the existing issues
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: contact
|
||||
attributes:
|
||||
label: Contact Details
|
||||
description: __OPTIONAL__ How could we get in touch with you if we need more info (besides this issue)?
|
||||
placeholder: ex. email@example.com, discordname, twitter, ...
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: whatisexpected
|
||||
attributes:
|
||||
label: What should this feature add?
|
||||
description: Please try to explain the functionality this feature should add
|
||||
placeholder: |
|
||||
Instead of one huge textfield, it would be nice to have forms for bug-reports, feature-requests, ...
|
||||
Great benefits with automatic labeling, assigning and other functionalitys not available in that form
|
||||
via old-fashioned markdown-templates. I would also love to see the use of a moderator bot 🤖 like
|
||||
https://github.com/marketplace/actions/issue-moderator-with-commands to auto close old issues and other things
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Alternatives
|
||||
description: Describe alternatives you've considered
|
||||
placeholder: A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Aditional Content
|
||||
description: Add any other context or screenshots about the feature request here.
|
||||
placeholder: This is a Mockup of the design how I imagine it <screenshot>
|
||||
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,36 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe your environment**
|
||||
- GPU: [cuda/amd/mps/cpu]
|
||||
- VRAM: [if known]
|
||||
- CPU arch: [x86/arm]
|
||||
- OS: [Linux/Windows/macOS]
|
||||
- Python: [Anaconda/miniconda/miniforge/pyenv/other (explain)]
|
||||
- Branch: [if `git status` says anything other than "On branch main" paste it here]
|
||||
- Commit: [run `git show` and paste the line that starts with "Merge" here]
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
14
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Project-Documentation
|
||||
url: https://invoke-ai.github.io/InvokeAI/
|
||||
about: Should be your first place to go when looking for manuals/FAQs regarding our InvokeAI Toolkit
|
||||
- name: Discord
|
||||
url: https://discord.gg/ZmtBAhwWhy
|
||||
about: Our Discord Community could maybe help you out via live-chat
|
||||
- name: GitHub Community Support
|
||||
url: https://github.com/orgs/community/discussions
|
||||
about: Please ask and answer questions regarding the GitHub Platform here.
|
||||
- name: GitHub Security Bug Bounty
|
||||
url: https://bounty.github.com/
|
||||
about: Please report security vulnerabilities of the GitHub Platform here.
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
28
.github/workflows/mkdocs-flow.yml
vendored
@@ -1,28 +0,0 @@
|
||||
name: Deploy
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
# pull_request:
|
||||
# branches:
|
||||
# - main
|
||||
jobs:
|
||||
build:
|
||||
name: Deploy docs to GitHub Pages
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build
|
||||
uses: Tiryoh/actions-mkdocs@v0
|
||||
with:
|
||||
mkdocs_version: 'latest' # option
|
||||
requirements: '/requirements-mkdocs.txt' # option
|
||||
configfile: '/mkdocs.yml' # option
|
||||
- name: Deploy
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./site
|
||||
12
.github/workflows/test-invoke-conda.yml
vendored
@@ -4,6 +4,7 @@ on:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'development'
|
||||
- 'fix-gh-actions-fork'
|
||||
pull_request:
|
||||
branches:
|
||||
- 'main'
|
||||
@@ -15,7 +16,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
stable-diffusion-model:
|
||||
- 'https://huggingface.co/CompVis/stable-diffusion-v-1-4-original/resolve/main/sd-v1-4.ckpt'
|
||||
# - 'https://huggingface.co/CompVis/stable-diffusion-v-1-4-original/resolve/main/sd-v1-4.ckpt'
|
||||
- 'https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.ckpt'
|
||||
os:
|
||||
- ubuntu-latest
|
||||
@@ -27,9 +28,9 @@ jobs:
|
||||
- os: macOS-12
|
||||
environment-file: environment-mac.yml
|
||||
default-shell: bash -l {0}
|
||||
- stable-diffusion-model: https://huggingface.co/CompVis/stable-diffusion-v-1-4-original/resolve/main/sd-v1-4.ckpt
|
||||
stable-diffusion-model-dl-path: models/ldm/stable-diffusion-v1/model.ckpt
|
||||
stable-diffusion-model-switch: stable-diffusion-1.4
|
||||
# - stable-diffusion-model: https://huggingface.co/CompVis/stable-diffusion-v-1-4-original/resolve/main/sd-v1-4.ckpt
|
||||
# stable-diffusion-model-dl-path: models/ldm/stable-diffusion-v1/sd-v1-4.ckpt
|
||||
# stable-diffusion-model-switch: stable-diffusion-1.4
|
||||
- stable-diffusion-model: https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.ckpt
|
||||
stable-diffusion-model-dl-path: models/ldm/stable-diffusion-v1/v1-5-pruned-emaonly.ckpt
|
||||
stable-diffusion-model-switch: stable-diffusion-1.5
|
||||
@@ -45,6 +46,9 @@ jobs:
|
||||
id: checkout-sources
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: create models.yaml from example
|
||||
run: cp configs/models.yaml.example configs/models.yaml
|
||||
|
||||
- name: Use cached conda packages
|
||||
id: use-cached-conda-packages
|
||||
uses: actions/cache@v3
|
||||
|
||||
3
.gitignore
vendored
@@ -2,7 +2,6 @@
|
||||
outputs/
|
||||
models/ldm/stable-diffusion-v1/model.ckpt
|
||||
ldm/invoke/restoration/codeformer/weights
|
||||
|
||||
# ignore user models config
|
||||
configs/models.user.yaml
|
||||
config/models.user.yml
|
||||
@@ -184,7 +183,7 @@ src
|
||||
**/__pycache__/
|
||||
outputs
|
||||
|
||||
# Logs and associated folders
|
||||
# Logs and associated folders
|
||||
# created from generated embeddings.
|
||||
logs
|
||||
testtube
|
||||
|
||||
13
LICENSE
@@ -1,17 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Lincoln Stein and InvokeAI Organization
|
||||
|
||||
This software is derived from a fork of the source code available from
|
||||
https://github.com/pesser/stable-diffusion and
|
||||
https://github.com/CompViz/stable-diffusion. They carry the following
|
||||
copyrights:
|
||||
|
||||
Copyright (c) 2022 Machine Vision and Learning Group, LMU Munich
|
||||
Copyright (c) 2022 Robin Rombach and Patrick Esser and contributors
|
||||
|
||||
Please see individual source code files for copyright and authorship
|
||||
attributions.
|
||||
Copyright (c) 2022 InvokeAI Team
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
82
README.md
@@ -42,7 +42,7 @@ generation process. It runs on Windows, Mac and Linux machines, with
|
||||
GPU cards with as little as 4 GB of RAM. It provides both a polished
|
||||
Web interface (see below), and an easy-to-use command-line interface.
|
||||
|
||||
**Quick links**: [<a href="https://discord.gg/NwVCmKwY">Discord Server</a>] [<a href="https://invoke-ai.github.io/InvokeAI/">Documentation and Tutorials</a>] [<a href="https://github.com/invoke-ai/InvokeAI/">Code and Downloads</a>] [<a href="https://github.com/invoke-ai/InvokeAI/issues">Bug Reports</a>] [<a href="https://github.com/invoke-ai/InvokeAI/discussions">Discussion, Ideas & Q&A</a>]
|
||||
**Quick links**: [<a href="https://discord.gg/ZmtBAhwWhy">Discord Server</a>] [<a href="https://invoke-ai.github.io/InvokeAI/">Documentation and Tutorials</a>] [<a href="https://github.com/invoke-ai/InvokeAI/">Code and Downloads</a>] [<a href="https://github.com/invoke-ai/InvokeAI/issues">Bug Reports</a>] [<a href="https://github.com/invoke-ai/InvokeAI/discussions">Discussion, Ideas & Q&A</a>]
|
||||
|
||||
<div align="center"><img src="docs/assets/invoke-web-server-1.png" width=640></div>
|
||||
|
||||
@@ -68,11 +68,11 @@ requests. Be sure to use the provided templates. They will help aid diagnose iss
|
||||
This fork is supported across multiple platforms. You can find individual installation instructions
|
||||
below.
|
||||
|
||||
- #### [Linux](docs/installation/INSTALL_LINUX.md)
|
||||
- #### [Linux](https://invoke-ai.github.io/InvokeAI/installation/INSTALL_LINUX/)
|
||||
|
||||
- #### [Windows](docs/installation/INSTALL_WINDOWS.md)
|
||||
- #### [Windows](https://invoke-ai.github.io/InvokeAI/installation/INSTALL_WINDOWS/)
|
||||
|
||||
- #### [Macintosh](docs/installation/INSTALL_MAC.md)
|
||||
- #### [Macintosh](https://invoke-ai.github.io/InvokeAI/installation/INSTALL_MAC/)
|
||||
|
||||
### Hardware Requirements
|
||||
|
||||
@@ -103,37 +103,49 @@ errors like 'expected type Float but found Half' or 'not implemented for Half'
|
||||
you can try starting `invoke.py` with the `--precision=float32` flag:
|
||||
|
||||
```bash
|
||||
(ldm) ~/stable-diffusion$ python scripts/invoke.py --precision=float32
|
||||
(invokeai) ~/InvokeAI$ python scripts/invoke.py --precision=float32
|
||||
```
|
||||
|
||||
### Features
|
||||
|
||||
#### Major Features
|
||||
|
||||
- [Web Server](docs/features/WEB.md)
|
||||
- [Interactive Command Line Interface](docs/features/CLI.md)
|
||||
- [Image To Image](docs/features/IMG2IMG.md)
|
||||
- [Inpainting Support](docs/features/INPAINTING.md)
|
||||
- [Outpainting Support](docs/features/OUTPAINTING.md)
|
||||
- [Upscaling, face-restoration and outpainting](docs/features/POSTPROCESS.md)
|
||||
- [Seamless Tiling](docs/features/OTHER.md#seamless-tiling)
|
||||
- [Google Colab](docs/features/OTHER.md#google-colab)
|
||||
- [Reading Prompts From File](docs/features/PROMPTS.md#reading-prompts-from-a-file)
|
||||
- [Shortcut: Reusing Seeds](docs/features/OTHER.md#shortcuts-reusing-seeds)
|
||||
- [Prompt Blending](docs/features/PROMPTS.md#prompt-blending)
|
||||
- [Thresholding and Perlin Noise Initialization Options](/docs/features/OTHER.md#thresholding-and-perlin-noise-initialization-options)
|
||||
- [Negative/Unconditioned Prompts](docs/features/PROMPTS.md#negative-and-unconditioned-prompts)
|
||||
- [Variations](docs/features/VARIATIONS.md)
|
||||
- [Personalizing Text-to-Image Generation](docs/features/TEXTUAL_INVERSION.md)
|
||||
- [Simplified API for text to image generation](docs/features/OTHER.md#simplified-api)
|
||||
- [Web Server](https://invoke-ai.github.io/InvokeAI/features/WEB/)
|
||||
- [Interactive Command Line Interface](https://invoke-ai.github.io/InvokeAI/features/CLI/)
|
||||
- [Image To Image](https://invoke-ai.github.io/InvokeAI/features/IMG2IMG/)
|
||||
- [Inpainting Support](https://invoke-ai.github.io/InvokeAI/features/INPAINTING/)
|
||||
- [Outpainting Support](https://invoke-ai.github.io/InvokeAI/features/OUTPAINTING/)
|
||||
- [Upscaling, face-restoration and outpainting](https://invoke-ai.github.io/InvokeAI/features/POSTPROCESS/)
|
||||
- [Reading Prompts From File](https://invoke-ai.github.io/InvokeAI/features/PROMPTS/#reading-prompts-from-a-file)
|
||||
- [Prompt Blending](https://invoke-ai.github.io/InvokeAI/features/PROMPTS/#prompt-blending)
|
||||
- [Thresholding and Perlin Noise Initialization Options](https://invoke-ai.github.io/InvokeAI/features/OTHER/#thresholding-and-perlin-noise-initialization-options)
|
||||
- [Negative/Unconditioned Prompts](https://invoke-ai.github.io/InvokeAI/features/PROMPTS/#negative-and-unconditioned-prompts)
|
||||
- [Variations](https://invoke-ai.github.io/InvokeAI/features/VARIATIONS/)
|
||||
- [Personalizing Text-to-Image Generation](https://invoke-ai.github.io/InvokeAI/features/TEXTUAL_INVERSION/)
|
||||
- [Simplified API for text to image generation](https://invoke-ai.github.io/InvokeAI/features/OTHER/#simplified-api)
|
||||
|
||||
#### Other Features
|
||||
|
||||
- [Creating Transparent Regions for Inpainting](docs/features/INPAINTING.md#creating-transparent-regions-for-inpainting)
|
||||
- [Preload Models](docs/features/OTHER.md#preload-models)
|
||||
- [Google Colab](https://invoke-ai.github.io/InvokeAI/features/OTHER/#google-colab)
|
||||
- [Seamless Tiling](https://invoke-ai.github.io/InvokeAI/features/OTHER/#seamless-tiling)
|
||||
- [Shortcut: Reusing Seeds](https://invoke-ai.github.io/InvokeAI/features/OTHER/#shortcuts-reusing-seeds)
|
||||
- [Preload Models](https://invoke-ai.github.io/InvokeAI/features/OTHER/#preload-models)
|
||||
|
||||
### Latest Changes
|
||||
|
||||
### v2.1.0 major changes <small>(2 November 2022)</small>
|
||||
|
||||
- [Inpainting](https://invoke-ai.github.io/InvokeAI/features/INPAINTING/) support in the WebGUI
|
||||
- Greatly improved navigation and user experience in the [WebGUI](https://invoke-ai.github.io/InvokeAI/features/WEB/)
|
||||
- The prompt syntax has been enhanced with [prompt weighting, cross-attention and prompt merging](https://invoke-ai.github.io/InvokeAI/features/PROMPTS/).
|
||||
- You can now load [multiple models and switch among them quickly](https://docs.google.com/presentation/d/1WywGA1rny7bpFh7CLSdTr4nNpVKdlUeT0Bj0jCsILyU/edit?usp=sharing) without leaving the CLI.
|
||||
- The installation process (via `scripts/preload_models.py`) now lets you select among several popular [Stable Diffusion models](https://invoke-ai.github.io/InvokeAI/installation/INSTALLING_MODELS/) and downloads and installs them on your behalf. Among other models, this script will install the current Stable Diffusion 1.5 model as well as a StabilityAI variable autoencoder (VAE) which improves face generation.
|
||||
- Tired of struggling with photoeditors to get the masked region of for inpainting just right? Let the AI make the mask for you using [text masking](https://docs.google.com/presentation/d/1pWoY510hCVjz0M6X9CBbTznZgW2W5BYNKrmZm7B45q8/edit#slide=id.p). This feature allows you to specify the part of the image to paint over using just English-language phrases.
|
||||
- Tired of seeing the head of your subjects cropped off? Uncrop them in the CLI with the [outcrop feature](https://invoke-ai.github.io/InvokeAI/features/OUTPAINTING/#outcrop).
|
||||
- Tired of seeing your subject's bodies duplicated or mangled when generating larger-dimension images? Check out the `--hires` option in the CLI, or select the corresponding toggle in the WebGUI.
|
||||
- We now support textual inversion and fine-tune .bin styles and subjects from the Hugging Face archive of [SD Concepts](https://huggingface.co/sd-concepts-library). Load the .bin file using the `--embedding_path` option. (The next version will support merging and loading of multiple simultaneous models).
|
||||
<a href="https://invoke-ai.github.io/InvokeAI/CHANGELOG/>Complete Changelog</a>
|
||||
|
||||
- v2.0.1 (13 October 2022)
|
||||
- fix noisy images at high step count when using k* samplers
|
||||
- dream.py script now calls invoke.py module directly rather than
|
||||
@@ -144,33 +156,33 @@ you can try starting `invoke.py` with the `--precision=float32` flag:
|
||||
- `dream.py` script renamed `invoke.py`. A `dream.py` script wrapper remains
|
||||
for backward compatibility.
|
||||
- Completely new WebGUI - launch with `python3 scripts/invoke.py --web`
|
||||
- Support for <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/INPAINTING.md">inpainting</a> and <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/OUTPAINTING.md">outpainting</a>
|
||||
- Support for <a href="https://invoke-ai.github.io/InvokeAI/features/INPAINTING/">inpainting</a> and <a href="https://invoke-ai.github.io/InvokeAI/features/OUTPAINTING/">outpainting</a>
|
||||
- img2img runs on all k* samplers
|
||||
- Support for <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/PROMPTS.md#negative-and-unconditioned-prompts">negative prompts</a>
|
||||
- Support for <a href="https://invoke-ai.github.io/InvokeAI/features/PROMPTS/#negative-and-unconditioned-prompts">negative prompts</a>
|
||||
- Support for CodeFormer face reconstruction
|
||||
- Support for Textual Inversion on Macintoshes
|
||||
- Support in both WebGUI and CLI for <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/POSTPROCESS.md">post-processing of previously-generated images</a>
|
||||
- Support in both WebGUI and CLI for <a href="https://invoke-ai.github.io/InvokeAI/features/POSTPROCESS/">post-processing of previously-generated images</a>
|
||||
using facial reconstruction, ESRGAN upscaling, outcropping (similar to DALL-E infinite canvas),
|
||||
and "embiggen" upscaling. See the `!fix` command.
|
||||
- New `--hires` option on `invoke>` line allows <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/CLI.md#this-is-an-example-of-txt2img">larger images to be created without duplicating elements</a>, at the cost of some performance.
|
||||
- New `--hires` option on `invoke>` line allows <a href="https://invoke-ai.github.io/InvokeAI/features/CLI/#txt2img">larger images to be created without duplicating elements</a>, at the cost of some performance.
|
||||
- New `--perlin` and `--threshold` options allow you to add and control variation
|
||||
during image generation (see <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/OTHER.md#thresholding-and-perlin-noise-initialization-options">Thresholding and Perlin Noise Initialization</a>
|
||||
- Extensive metadata now written into PNG files, allowing reliable regeneration of images
|
||||
and tweaking of previous settings.
|
||||
- Command-line completion in `invoke.py` now works on Windows, Linux and Mac platforms.
|
||||
- Improved <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/CLI.md">command-line completion behavior</a>.
|
||||
- Improved <a href="https://invoke-ai.github.io/InvokeAI/features/CLI/">command-line completion behavior</a>.
|
||||
New commands added:
|
||||
* List command-line history with `!history`
|
||||
* Search command-line history with `!search`
|
||||
* Clear history with `!clear`
|
||||
- List command-line history with `!history`
|
||||
- Search command-line history with `!search`
|
||||
- Clear history with `!clear`
|
||||
- Deprecated `--full_precision` / `-F`. Simply omit it and `invoke.py` will auto
|
||||
configure. To switch away from auto use the new flag like `--precision=float32`.
|
||||
|
||||
For older changelogs, please visit the **[CHANGELOG](docs/features/CHANGELOG.md)**.
|
||||
For older changelogs, please visit the **[CHANGELOG](https://invoke-ai.github.io/InvokeAI/CHANGELOG#v114-11-september-2022)**.
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
Please check out our **[Q&A](docs/help/TROUBLESHOOT.md)** to get solutions for common installation
|
||||
Please check out our **[Q&A](https://invoke-ai.github.io/InvokeAI/help/TROUBLESHOOT/#faq)** to get solutions for common installation
|
||||
problems and other issues.
|
||||
|
||||
# Contributing
|
||||
@@ -188,7 +200,7 @@ changes.
|
||||
### Contributors
|
||||
|
||||
This fork is a combined effort of various people from across the world.
|
||||
[Check out the list of all these amazing people](docs/other/CONTRIBUTORS.md). We thank them for
|
||||
[Check out the list of all these amazing people](https://invoke-ai.github.io/InvokeAI/other/CONTRIBUTORS/). We thank them for
|
||||
their time, hard work and effort.
|
||||
|
||||
### Support
|
||||
@@ -202,4 +214,4 @@ Original portions of the software are Copyright (c) 2020
|
||||
### Further Reading
|
||||
|
||||
Please see the original README for more information on this software and underlying algorithm,
|
||||
located in the file [README-CompViz.md](docs/other/README-CompViz.md).
|
||||
located in the file [README-CompViz.md](https://invoke-ai.github.io/InvokeAI/other/README-CompViz/).
|
||||
|
||||
@@ -187,7 +187,10 @@ class InvokeAIWebServer:
|
||||
base_path = (
|
||||
self.result_path if category == "result" else self.init_image_path
|
||||
)
|
||||
paths = glob.glob(os.path.join(base_path, "*.png"))
|
||||
|
||||
paths = []
|
||||
for ext in ("*.png", "*.jpg", "*.jpeg"):
|
||||
paths.extend(glob.glob(os.path.join(base_path, ext)))
|
||||
|
||||
image_paths = sorted(
|
||||
paths, key=lambda x: os.path.getmtime(x), reverse=True
|
||||
@@ -203,13 +206,19 @@ class InvokeAIWebServer:
|
||||
image_array = []
|
||||
|
||||
for path in image_paths:
|
||||
metadata = retrieve_metadata(path)
|
||||
if os.path.splitext(path)[1] == ".png":
|
||||
metadata = retrieve_metadata(path)
|
||||
sd_metadata = metadata["sd-metadata"]
|
||||
else:
|
||||
sd_metadata = {}
|
||||
|
||||
(width, height) = Image.open(path).size
|
||||
|
||||
image_array.append(
|
||||
{
|
||||
"url": self.get_url_from_image_path(path),
|
||||
"mtime": os.path.getmtime(path),
|
||||
"metadata": metadata["sd-metadata"],
|
||||
"metadata": sd_metadata,
|
||||
"width": width,
|
||||
"height": height,
|
||||
"category": category,
|
||||
@@ -236,7 +245,9 @@ class InvokeAIWebServer:
|
||||
self.result_path if category == "result" else self.init_image_path
|
||||
)
|
||||
|
||||
paths = glob.glob(os.path.join(base_path, "*.png"))
|
||||
paths = []
|
||||
for ext in ("*.png", "*.jpg", "*.jpeg"):
|
||||
paths.extend(glob.glob(os.path.join(base_path, ext)))
|
||||
|
||||
image_paths = sorted(
|
||||
paths, key=lambda x: os.path.getmtime(x), reverse=True
|
||||
@@ -254,9 +265,12 @@ class InvokeAIWebServer:
|
||||
image_paths = image_paths[slice(0, page_size)]
|
||||
|
||||
image_array = []
|
||||
|
||||
for path in image_paths:
|
||||
metadata = retrieve_metadata(path)
|
||||
if os.path.splitext(path)[1] == ".png":
|
||||
metadata = retrieve_metadata(path)
|
||||
sd_metadata = metadata["sd-metadata"]
|
||||
else:
|
||||
sd_metadata = {}
|
||||
|
||||
(width, height) = Image.open(path).size
|
||||
|
||||
@@ -264,7 +278,7 @@ class InvokeAIWebServer:
|
||||
{
|
||||
"url": self.get_url_from_image_path(path),
|
||||
"mtime": os.path.getmtime(path),
|
||||
"metadata": metadata["sd-metadata"],
|
||||
"metadata": sd_metadata,
|
||||
"width": width,
|
||||
"height": height,
|
||||
"category": category,
|
||||
@@ -336,7 +350,8 @@ class InvokeAIWebServer:
|
||||
|
||||
seed = (
|
||||
original_image["metadata"]["seed"]
|
||||
if "seed" in original_image["metadata"]
|
||||
if "metadata" in original_image
|
||||
and "seed" in original_image["metadata"]
|
||||
else "unknown_seed"
|
||||
)
|
||||
|
||||
@@ -561,20 +576,18 @@ class InvokeAIWebServer:
|
||||
)
|
||||
generation_parameters["init_img"] = cropped_init_image
|
||||
|
||||
# grab an Image of the mask
|
||||
mask_image = Image.open(
|
||||
io.BytesIO(
|
||||
base64.decodebytes(
|
||||
bytes(generation_parameters["init_mask"], "utf-8")
|
||||
if generation_parameters["is_mask_empty"]:
|
||||
generation_parameters["init_mask"] = None
|
||||
else:
|
||||
# grab an Image of the mask
|
||||
mask_image = Image.open(
|
||||
io.BytesIO(
|
||||
base64.decodebytes(
|
||||
bytes(generation_parameters["init_mask"], "utf-8")
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
# crop the mask image
|
||||
cropped_mask_image = copy_image_from_bounding_box(
|
||||
mask_image, **generation_parameters["bounding_box"]
|
||||
)
|
||||
generation_parameters["init_mask"] = cropped_mask_image
|
||||
generation_parameters["init_mask"] = mask_image
|
||||
|
||||
totalSteps = self.calculate_real_steps(
|
||||
steps=generation_parameters["steps"],
|
||||
@@ -603,7 +616,7 @@ class InvokeAIWebServer:
|
||||
|
||||
if (
|
||||
generation_parameters["progress_images"]
|
||||
and step % 5 == 0
|
||||
and step % generation_parameters['save_intermediates'] == 0
|
||||
and step < generation_parameters["steps"] - 1
|
||||
):
|
||||
image = self.generate.sample_to_image(sample)
|
||||
@@ -634,6 +647,29 @@ class InvokeAIWebServer:
|
||||
"height": height,
|
||||
},
|
||||
)
|
||||
|
||||
if generation_parameters["progress_latents"]:
|
||||
image = self.generate.sample_to_lowres_estimated_image(sample)
|
||||
(width, height) = image.size
|
||||
width *= 8
|
||||
height *= 8
|
||||
buffered = io.BytesIO()
|
||||
image.save(buffered, format="PNG")
|
||||
img_base64 = "data:image/png;base64," + base64.b64encode(
|
||||
buffered.getvalue()
|
||||
).decode("UTF-8")
|
||||
self.socketio.emit(
|
||||
"intermediateResult",
|
||||
{
|
||||
"url": img_base64,
|
||||
"isBase64": True,
|
||||
"mtime": 0,
|
||||
"metadata": {},
|
||||
"width": width,
|
||||
"height": height,
|
||||
},
|
||||
)
|
||||
|
||||
self.socketio.emit("progressUpdate", progress.to_formatted_dict())
|
||||
eventlet.sleep(0)
|
||||
|
||||
@@ -649,6 +685,14 @@ class InvokeAIWebServer:
|
||||
step_index = 1
|
||||
nonlocal prior_variations
|
||||
|
||||
# paste the inpainting image back onto the original
|
||||
if "init_mask" in generation_parameters:
|
||||
image = paste_image_into_bounding_box(
|
||||
Image.open(init_img_path),
|
||||
image,
|
||||
**generation_parameters["bounding_box"],
|
||||
)
|
||||
|
||||
progress.set_current_status("Generation Complete")
|
||||
|
||||
self.socketio.emit("progressUpdate", progress.to_formatted_dict())
|
||||
@@ -737,20 +781,12 @@ class InvokeAIWebServer:
|
||||
self.socketio.emit("progressUpdate", progress.to_formatted_dict())
|
||||
eventlet.sleep(0)
|
||||
|
||||
# paste the inpainting image back onto the original
|
||||
if "init_mask" in generation_parameters:
|
||||
image = paste_image_into_bounding_box(
|
||||
Image.open(init_img_path),
|
||||
image,
|
||||
**generation_parameters["bounding_box"],
|
||||
)
|
||||
|
||||
# restore the stashed URLS and discard the paths, we are about to send the result to client
|
||||
if "init_img" in all_parameters:
|
||||
all_parameters["init_img"] = init_img_url
|
||||
|
||||
if "init_mask" in all_parameters:
|
||||
all_parameters["init_mask"] = "" #
|
||||
all_parameters["init_mask"] = "" # TODO: store the mask in metadata
|
||||
|
||||
metadata = self.parameters_to_generated_image_metadata(all_parameters)
|
||||
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
# This file describes the alternative machine learning models
|
||||
# available to InvokeAI script.
|
||||
#
|
||||
# To add a new model, follow the examples below. Each
|
||||
# model requires a model config file, a weights file,
|
||||
# and the width and height of the images it
|
||||
# was trained on.
|
||||
stable-diffusion-1.4:
|
||||
config: ./configs/stable-diffusion/v1-inference.yaml
|
||||
weights: ./models/ldm/stable-diffusion-v1/sd-v1-4.ckpt
|
||||
vae: ./models/ldm/stable-diffusion-v1/vae-ft-mse-840000-ema-pruned.ckpt
|
||||
description: The original Stable Diffusion version 1.4 weight file (4.27 GB)
|
||||
width: 512
|
||||
height: 512
|
||||
stable-diffusion-1.5:
|
||||
description: The newest Stable Diffusion version 1.5 weight file (4.27 GB)
|
||||
weights: ./models/ldm/stable-diffusion-v1/v1-5-pruned-emaonly.ckpt
|
||||
config: ./configs/stable-diffusion/v1-inference.yaml
|
||||
width: 512
|
||||
height: 512
|
||||
vae: ./models/ldm/stable-diffusion-v1/vae-ft-mse-840000-ema-pruned.ckpt
|
||||
default: true
|
||||
inpainting-1.5:
|
||||
description: RunwayML SD 1.5 model optimized for inpainting (4.27 GB)
|
||||
weights: ./models/ldm/stable-diffusion-v1/sd-v1-5-inpainting.ckpt
|
||||
config: ./configs/stable-diffusion/v1-inpainting-inference.yaml
|
||||
width: 512
|
||||
height: 512
|
||||
vae: ./models/ldm/stable-diffusion-v1/vae-ft-mse-840000-ema-pruned.ckpt
|
||||
waifu-diffusion-1.3:
|
||||
description: Stable Diffusion 1.4 fine tuned on anime-styled images (4.27)
|
||||
weights: ./models/ldm/stable-diffusion-v1/model-epoch09-float32.ckpt
|
||||
config: ./configs/stable-diffusion/v1-inference.yaml
|
||||
width: 512
|
||||
height: 512
|
||||
vae: ./models/ldm/stable-diffusion-v1/vae-ft-mse-840000-ema-pruned.ckpt
|
||||
27
configs/models.yaml.example
Normal file
@@ -0,0 +1,27 @@
|
||||
# This file describes the alternative machine learning models
|
||||
# available to InvokeAI script.
|
||||
#
|
||||
# To add a new model, follow the examples below. Each
|
||||
# model requires a model config file, a weights file,
|
||||
# and the width and height of the images it
|
||||
# was trained on.
|
||||
stable-diffusion-1.5:
|
||||
description: The newest Stable Diffusion version 1.5 weight file (4.27 GB)
|
||||
weights: ./models/ldm/stable-diffusion-v1/v1-5-pruned-emaonly.ckpt
|
||||
config: ./configs/stable-diffusion/v1-inference.yaml
|
||||
width: 512
|
||||
height: 512
|
||||
vae: ./models/ldm/stable-diffusion-v1/vae-ft-mse-840000-ema-pruned.ckpt
|
||||
default: true
|
||||
stable-diffusion-1.4:
|
||||
description: Stable Diffusion inference model version 1.4
|
||||
config: configs/stable-diffusion/v1-inference.yaml
|
||||
weights: models/ldm/stable-diffusion-v1/sd-v1-4.ckpt
|
||||
vae: models/ldm/stable-diffusion-v1/vae-ft-mse-840000-ema-pruned.ckpt
|
||||
width: 512
|
||||
height: 512
|
||||
inpainting-1.5:
|
||||
weights: models/ldm/stable-diffusion-v1/sd-v1-5-inpainting.ckpt
|
||||
config: configs/stable-diffusion/v1-inpainting-inference.yaml
|
||||
vae: models/ldm/stable-diffusion-v1/vae-ft-mse-840000-ema-pruned.ckpt
|
||||
description: RunwayML SD 1.5 model optimized for inpainting
|
||||
@@ -4,66 +4,154 @@ title: Changelog
|
||||
|
||||
# :octicons-log-16: **Changelog**
|
||||
|
||||
## v2.1.0 (2 November 2022)
|
||||
- update mac instructions to use invokeai for env name by @willwillems in https://github.com/invoke-ai/InvokeAI/pull/1030
|
||||
- Update .gitignore by @blessedcoolant in https://github.com/invoke-ai/InvokeAI/pull/1040
|
||||
- reintroduce fix for m1 from https://github.com/invoke-ai/InvokeAI/pull/579 missing after merge by @skurovec in https://github.com/invoke-ai/InvokeAI/pull/1056
|
||||
- Update Stable_Diffusion_AI_Notebook.ipynb (Take 2) by @ChloeL19 in https://github.com/invoke-ai/InvokeAI/pull/1060
|
||||
- Print out the device type which is used by @manzke in https://github.com/invoke-ai/InvokeAI/pull/1073
|
||||
- Hires Addition by @hipsterusername in https://github.com/invoke-ai/InvokeAI/pull/1063
|
||||
- fix for "1 leaked semaphore objects to clean up at shutdown" on M1 by @skurovec in https://github.com/invoke-ai/InvokeAI/pull/1081
|
||||
- Forward dream.py to invoke.py using the same interpreter, add deprecation warning by @db3000 in https://github.com/invoke-ai/InvokeAI/pull/1077
|
||||
- fix noisy images at high step counts by @lstein in https://github.com/invoke-ai/InvokeAI/pull/1086
|
||||
- Generalize facetool strength argument by @db3000 in https://github.com/invoke-ai/InvokeAI/pull/1078
|
||||
- Enable fast switching among models at the invoke> command line by @lstein in https://github.com/invoke-ai/InvokeAI/pull/1066
|
||||
- Fix Typo, committed changing ldm environment to invokeai by @jdries3 in https://github.com/invoke-ai/InvokeAI/pull/1095
|
||||
- Update generate.py by @unreleased in https://github.com/invoke-ai/InvokeAI/pull/1109
|
||||
- Update 'ldm' env to 'invokeai' in troubleshooting steps by @19wolf in https://github.com/invoke-ai/InvokeAI/pull/1125
|
||||
- Fixed documentation typos and resolved merge conflicts by @rupeshs in https://github.com/invoke-ai/InvokeAI/pull/1123
|
||||
- Fix broken doc links, fix malaprop in the project subtitle by @majick in https://github.com/invoke-ai/InvokeAI/pull/1131
|
||||
- Only output facetool parameters if enhancing faces by @db3000 in https://github.com/invoke-ai/InvokeAI/pull/1119
|
||||
- Update gitignore to ignore codeformer weights at new location by @spezialspezial in https://github.com/invoke-ai/InvokeAI/pull/1136
|
||||
- fix links to point to invoke-ai.github.io #1117 by @mauwii in https://github.com/invoke-ai/InvokeAI/pull/1143
|
||||
- Rework-mkdocs by @mauwii in https://github.com/invoke-ai/InvokeAI/pull/1144
|
||||
- add option to CLI and pngwriter that allows user to set PNG compression level by @lstein in https://github.com/invoke-ai/InvokeAI/pull/1127
|
||||
- Fix img2img DDIM index out of bound by @wfng92 in https://github.com/invoke-ai/InvokeAI/pull/1137
|
||||
- Fix gh actions by @mauwii in https://github.com/invoke-ai/InvokeAI/pull/1128
|
||||
- update mac instructions to use invokeai for env name by @willwillems in https://github.com/invoke-ai/InvokeAI/pull/1030
|
||||
- Update .gitignore by @blessedcoolant in https://github.com/invoke-ai/InvokeAI/pull/1040
|
||||
- reintroduce fix for m1 from https://github.com/invoke-ai/InvokeAI/pull/579 missing after merge by @skurovec in https://github.com/invoke-ai/InvokeAI/pull/1056
|
||||
- Update Stable_Diffusion_AI_Notebook.ipynb (Take 2) by @ChloeL19 in https://github.com/invoke-ai/InvokeAI/pull/1060
|
||||
- Print out the device type which is used by @manzke in https://github.com/invoke-ai/InvokeAI/pull/1073
|
||||
- Hires Addition by @hipsterusername in https://github.com/invoke-ai/InvokeAI/pull/1063
|
||||
- fix for "1 leaked semaphore objects to clean up at shutdown" on M1 by @skurovec in https://github.com/invoke-ai/InvokeAI/pull/1081
|
||||
- Forward dream.py to invoke.py using the same interpreter, add deprecation warning by @db3000 in https://github.com/invoke-ai/InvokeAI/pull/1077
|
||||
- fix noisy images at high step counts by @lstein in https://github.com/invoke-ai/InvokeAI/pull/1086
|
||||
- Generalize facetool strength argument by @db3000 in https://github.com/invoke-ai/InvokeAI/pull/1078
|
||||
- Enable fast switching among models at the invoke> command line by @lstein in https://github.com/invoke-ai/InvokeAI/pull/1066
|
||||
- Fix Typo, committed changing ldm environment to invokeai by @jdries3 in https://github.com/invoke-ai/InvokeAI/pull/1095
|
||||
- Fixed documentation typos and resolved merge conflicts by @rupeshs in https://github.com/invoke-ai/InvokeAI/pull/1123
|
||||
- Only output facetool parameters if enhancing faces by @db3000 in https://github.com/invoke-ai/InvokeAI/pull/1119
|
||||
- add option to CLI and pngwriter that allows user to set PNG compression level by @lstein in https://github.com/invoke-ai/InvokeAI/pull/1127
|
||||
- Fix img2img DDIM index out of bound by @wfng92 in https://github.com/invoke-ai/InvokeAI/pull/1137
|
||||
- Add text prompt to inpaint mask support by @lstein in https://github.com/invoke-ai/InvokeAI/pull/1133
|
||||
- Respect http[s] protocol when making socket.io middleware by @damian0815 in https://github.com/invoke-ai/InvokeAI/pull/976
|
||||
- WebUI: Adds Codeformer support by @psychedelicious in https://github.com/invoke-ai/InvokeAI/pull/1151
|
||||
- Skips normalizing prompts for web UI metadata by @psychedelicious in https://github.com/invoke-ai/InvokeAI/pull/1165
|
||||
- Add Asymmetric Tiling by @carson-katri in https://github.com/invoke-ai/InvokeAI/pull/1132
|
||||
- Web UI: Increases max CFG Scale to 200 by @psychedelicious in https://github.com/invoke-ai/InvokeAI/pull/1172
|
||||
- Corrects color channels in face restoration; Fixes #1167 by @psychedelicious in https://github.com/invoke-ai/InvokeAI/pull/1175
|
||||
- Flips channels using array slicing instead of using OpenCV by @psychedelicious in https://github.com/invoke-ai/InvokeAI/pull/1178
|
||||
- Fix typo in docs: s/Formally/Formerly by @noodlebox in https://github.com/invoke-ai/InvokeAI/pull/1176
|
||||
- fix clipseg loading problems by @lstein in https://github.com/invoke-ai/InvokeAI/pull/1177
|
||||
- Correct color channels in upscale using array slicing by @wfng92 in https://github.com/invoke-ai/InvokeAI/pull/1181
|
||||
- Web UI: Filters existing images when adding new images; Fixes #1085 by @psychedelicious in https://github.com/invoke-ai/InvokeAI/pull/1171
|
||||
- fix a number of bugs in textual inversion by @lstein in https://github.com/invoke-ai/InvokeAI/pull/1190
|
||||
- Improve !fetch, add !replay command by @ArDiouscuros in https://github.com/invoke-ai/InvokeAI/pull/882
|
||||
- Fix generation of image with s>1000 by @holstvoogd in https://github.com/invoke-ai/InvokeAI/pull/951
|
||||
- Web UI: Gallery improvements by @psychedelicious in https://github.com/invoke-ai/InvokeAI/pull/1198
|
||||
- Update CLI.md by @krummrey in https://github.com/invoke-ai/InvokeAI/pull/1211
|
||||
- outcropping improvements by @lstein in https://github.com/invoke-ai/InvokeAI/pull/1207
|
||||
- add support for loading VAE autoencoders by @lstein in https://github.com/invoke-ai/InvokeAI/pull/1216
|
||||
- remove duplicate fix_func for MPS by @wfng92 in https://github.com/invoke-ai/InvokeAI/pull/1210
|
||||
- Metadata storage and retrieval fixes by @lstein in https://github.com/invoke-ai/InvokeAI/pull/1204
|
||||
- nix: add shell.nix file by @Cloudef in https://github.com/invoke-ai/InvokeAI/pull/1170
|
||||
- Web UI: Changes vite dist asset paths to relative by @psychedelicious in https://github.com/invoke-ai/InvokeAI/pull/1185
|
||||
- Web UI: Removes isDisabled from PromptInput by @psychedelicious in https://github.com/invoke-ai/InvokeAI/pull/1187
|
||||
- Allow user to generate images with initial noise as on M1 / mps system by @ArDiouscuros in https://github.com/invoke-ai/InvokeAI/pull/981
|
||||
- feat: adding filename format template by @plucked in https://github.com/invoke-ai/InvokeAI/pull/968
|
||||
- Web UI: Fixes broken bundle by @psychedelicious in https://github.com/invoke-ai/InvokeAI/pull/1242
|
||||
- Support runwayML custom inpainting model by @lstein in https://github.com/invoke-ai/InvokeAI/pull/1243
|
||||
- Update IMG2IMG.md by @talitore in https://github.com/invoke-ai/InvokeAI/pull/1262
|
||||
- New dockerfile - including a build- and a run- script as well as a GH-Action by @mauwii in https://github.com/invoke-ai/InvokeAI/pull/1233
|
||||
- cut over from karras to model noise schedule for higher steps by @lstein in https://github.com/invoke-ai/InvokeAI/pull/1222
|
||||
- Prompt tweaks by @lstein in https://github.com/invoke-ai/InvokeAI/pull/1268
|
||||
- Outpainting implementation by @Kyle0654 in https://github.com/invoke-ai/InvokeAI/pull/1251
|
||||
- fixing aspect ratio on hires by @tjennings in https://github.com/invoke-ai/InvokeAI/pull/1249
|
||||
- Fix-build-container-action by @mauwii in https://github.com/invoke-ai/InvokeAI/pull/1274
|
||||
- handle all unicode characters by @damian0815 in https://github.com/invoke-ai/InvokeAI/pull/1276
|
||||
- adds models.user.yml to .gitignore by @JakeHL in https://github.com/invoke-ai/InvokeAI/pull/1281
|
||||
- remove debug branch, set fail-fast to false by @mauwii in https://github.com/invoke-ai/InvokeAI/pull/1284
|
||||
- Protect-secrets-on-pr by @mauwii in https://github.com/invoke-ai/InvokeAI/pull/1285
|
||||
- Web UI: Adds initial inpainting implementation by @psychedelicious in https://github.com/invoke-ai/InvokeAI/pull/1225
|
||||
- fix environment-mac.yml - tested on x64 and arm64 by @mauwii in https://github.com/invoke-ai/InvokeAI/pull/1289
|
||||
- Use proper authentication to download model by @mauwii in https://github.com/invoke-ai/InvokeAI/pull/1287
|
||||
- Prevent indexing error for mode RGB by @spezialspezial in https://github.com/invoke-ai/InvokeAI/pull/1294
|
||||
- Integrate sd-v1-5 model into test matrix (easily expandable), remove unecesarry caches by @mauwii in https://github.com/invoke-ai/InvokeAI/pull/1293
|
||||
- add --no-interactive to preload_models step by @mauwii in https://github.com/invoke-ai/InvokeAI/pull/1302
|
||||
- 1-click installer and updater. Uses micromamba to install git and conda into a contained environment (if necessary) before running the normal installation script by @cmdr2 in https://github.com/invoke-ai/InvokeAI/pull/1253
|
||||
- preload_models.py script downloads the weight files by @lstein in https://github.com/invoke-ai/InvokeAI/pull/1290
|
||||
|
||||
## v2.0.1 (13 October 2022)
|
||||
|
||||
- fix noisy images at high step count when using k* samplers
|
||||
- dream.py script now calls invoke.py module directly rather than
|
||||
- fix noisy images at high step count when using k* samplers
|
||||
- dream.py script now calls invoke.py module directly rather than
|
||||
via a new python process (which could break the environment)
|
||||
|
||||
## v2.0.0 <small>(9 October 2022)</small>
|
||||
|
||||
- `dream.py` script renamed `invoke.py`. A `dream.py` script wrapper remains
|
||||
- `dream.py` script renamed `invoke.py`. A `dream.py` script wrapper remains
|
||||
for backward compatibility.
|
||||
- Completely new WebGUI - launch with `python3 scripts/invoke.py --web`
|
||||
- Support for <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/INPAINTING.md">inpainting</a> and <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/OUTPAINTING.md">outpainting</a>
|
||||
- img2img runs on all k* samplers
|
||||
- Support for <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/PROMPTS.md#negative-and-unconditioned-prompts">negative prompts</a>
|
||||
- Support for CodeFormer face reconstruction
|
||||
- Support for Textual Inversion on Macintoshes
|
||||
- Support in both WebGUI and CLI for <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/POSTPROCESS.md">post-processing of previously-generated images</a>
|
||||
- Completely new WebGUI - launch with `python3 scripts/invoke.py --web`
|
||||
- Support for [inpainting](features/INPAINTING.md) and [outpainting](features/OUTPAINTING.md)
|
||||
- img2img runs on all k* samplers
|
||||
- Support for [negative prompts](features/PROMPTS.md#negative-and-unconditioned-prompts)
|
||||
- Support for CodeFormer face reconstruction
|
||||
- Support for Textual Inversion on Macintoshes
|
||||
- Support in both WebGUI and CLI for [post-processing of previously-generated images](features/POSTPROCESS.md)
|
||||
using facial reconstruction, ESRGAN upscaling, outcropping (similar to DALL-E infinite canvas),
|
||||
and "embiggen" upscaling. See the `!fix` command.
|
||||
- New `--hires` option on `invoke>` line allows <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/CLI.m#this-is-an-example-of-txt2img">larger images to be created without duplicating elements</a>, at the cost of some performance.
|
||||
- New `--perlin` and `--threshold` options allow you to add and control variation
|
||||
during image generation (see <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/OTHER.md#thresholding-and-perlin-noise-initialization-options">Thresholding and Perlin Noise Initialization</a>
|
||||
- Extensive metadata now written into PNG files, allowing reliable regeneration of images
|
||||
- New `--hires` option on `invoke>` line allows [larger images to be created without duplicating elements](features/CLI.md#this-is-an-example-of-txt2img), at the cost of some performance.
|
||||
- New `--perlin` and `--threshold` options allow you to add and control variation
|
||||
during image generation (see [Thresholding and Perlin Noise Initialization](features/OTHER.md#thresholding-and-perlin-noise-initialization-options))
|
||||
- Extensive metadata now written into PNG files, allowing reliable regeneration of images
|
||||
and tweaking of previous settings.
|
||||
- Command-line completion in `invoke.py` now works on Windows, Linux and Mac platforms.
|
||||
- Improved <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/CLI.m">command-line completion behavior</a>.
|
||||
- Command-line completion in `invoke.py` now works on Windows, Linux and Mac platforms.
|
||||
- Improved [command-line completion behavior](features/CLI.md)
|
||||
New commands added:
|
||||
* List command-line history with `!history`
|
||||
* Search command-line history with `!search`
|
||||
* Clear history with `!clear`
|
||||
- Deprecated `--full_precision` / `-F`. Simply omit it and `invoke.py` will auto
|
||||
- List command-line history with `!history`
|
||||
- Search command-line history with `!search`
|
||||
- Clear history with `!clear`
|
||||
- Deprecated `--full_precision` / `-F`. Simply omit it and `invoke.py` will auto
|
||||
configure. To switch away from auto use the new flag like `--precision=float32`.
|
||||
|
||||
## v1.14 <small>(11 September 2022)</small>
|
||||
|
||||
- Memory optimizations for small-RAM cards. 512x512 now possible on 4 GB GPUs.
|
||||
- Full support for Apple hardware with M1 or M2 chips.
|
||||
- Add "seamless mode" for circular tiling of image. Generates beautiful effects.
|
||||
- Memory optimizations for small-RAM cards. 512x512 now possible on 4 GB GPUs.
|
||||
- Full support for Apple hardware with M1 or M2 chips.
|
||||
- Add "seamless mode" for circular tiling of image. Generates beautiful effects.
|
||||
([prixt](https://github.com/prixt)).
|
||||
- Inpainting support.
|
||||
- Improved web server GUI.
|
||||
- Lots of code and documentation cleanups.
|
||||
- Inpainting support.
|
||||
- Improved web server GUI.
|
||||
- Lots of code and documentation cleanups.
|
||||
|
||||
## v1.13 <small>(3 September 2022)</small>
|
||||
|
||||
- Support image variations (see [VARIATIONS](features/VARIATIONS.md)
|
||||
- Support image variations (see [VARIATIONS](features/VARIATIONS.md)
|
||||
([Kevin Gibbons](https://github.com/bakkot) and many contributors and reviewers)
|
||||
- Supports a Google Colab notebook for a standalone server running on Google hardware
|
||||
- Supports a Google Colab notebook for a standalone server running on Google hardware
|
||||
[Arturo Mendivil](https://github.com/artmen1516)
|
||||
- WebUI supports GFPGAN/ESRGAN facial reconstruction and upscaling
|
||||
- WebUI supports GFPGAN/ESRGAN facial reconstruction and upscaling
|
||||
[Kevin Gibbons](https://github.com/bakkot)
|
||||
- WebUI supports incremental display of in-progress images during generation
|
||||
- WebUI supports incremental display of in-progress images during generation
|
||||
[Kevin Gibbons](https://github.com/bakkot)
|
||||
- A new configuration file scheme that allows new models (including upcoming
|
||||
- A new configuration file scheme that allows new models (including upcoming
|
||||
stable-diffusion-v1.5) to be added without altering the code.
|
||||
([David Wager](https://github.com/maddavid12))
|
||||
- Can specify --grid on invoke.py command line as the default.
|
||||
- Miscellaneous internal bug and stability fixes.
|
||||
- Works on M1 Apple hardware.
|
||||
- Multiple bug fixes.
|
||||
- Can specify --grid on invoke.py command line as the default.
|
||||
- Miscellaneous internal bug and stability fixes.
|
||||
- Works on M1 Apple hardware.
|
||||
- Multiple bug fixes.
|
||||
|
||||
---
|
||||
|
||||
@@ -88,7 +176,7 @@ title: Changelog
|
||||
Seed memory only extends back to the previous command, but will work on all images generated with the -n# switch.
|
||||
- Variant generation support temporarily disabled pending more general solution.
|
||||
- Created a feature branch named **yunsaki-morphing-invoke** which adds experimental support for
|
||||
iteratively modifying the prompt and its parameters. Please see[ Pull Request #86](https://github.com/lstein/stable-diffusion/pull/86)
|
||||
iteratively modifying the prompt and its parameters. Please see[Pull Request #86](https://github.com/lstein/stable-diffusion/pull/86)
|
||||
for a synopsis of how this works. Note that when this feature is eventually added to the main branch, it will may be modified
|
||||
significantly.
|
||||
|
||||
|
||||
BIN
docs/assets/outpainting/curly-outcrop-2.png
Normal file
|
After Width: | Height: | Size: 635 KiB |
|
After Width: | Height: | Size: 284 KiB |
BIN
docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png
Normal file
|
After Width: | Height: | Size: 252 KiB |
BIN
docs/assets/preflight-checks/inputs/curly.png
Normal file
|
After Width: | Height: | Size: 428 KiB |
BIN
docs/assets/preflight-checks/outputs/000001.1863159593.png
Normal file
|
After Width: | Height: | Size: 331 KiB |
BIN
docs/assets/preflight-checks/outputs/000002.1151955949.png
Normal file
|
After Width: | Height: | Size: 369 KiB |
BIN
docs/assets/preflight-checks/outputs/000003.2736230502.png
Normal file
|
After Width: | Height: | Size: 362 KiB |
BIN
docs/assets/preflight-checks/outputs/000004.42.png
Normal file
|
After Width: | Height: | Size: 329 KiB |
BIN
docs/assets/preflight-checks/outputs/000005.42.png
Normal file
|
After Width: | Height: | Size: 329 KiB |
BIN
docs/assets/preflight-checks/outputs/000006.478163327.png
Normal file
|
After Width: | Height: | Size: 377 KiB |
BIN
docs/assets/preflight-checks/outputs/000007.2407640369.png
Normal file
|
After Width: | Height: | Size: 328 KiB |
BIN
docs/assets/preflight-checks/outputs/000008.2772421987.png
Normal file
|
After Width: | Height: | Size: 380 KiB |
BIN
docs/assets/preflight-checks/outputs/000009.3532317557.png
Normal file
|
After Width: | Height: | Size: 372 KiB |
BIN
docs/assets/preflight-checks/outputs/000010.2028635318.png
Normal file
|
After Width: | Height: | Size: 401 KiB |
BIN
docs/assets/preflight-checks/outputs/000011.1111168647.png
Normal file
|
After Width: | Height: | Size: 441 KiB |
BIN
docs/assets/preflight-checks/outputs/000012.1476370516.png
Normal file
|
After Width: | Height: | Size: 451 KiB |
BIN
docs/assets/preflight-checks/outputs/000013.4281108706.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/assets/preflight-checks/outputs/000014.2396987386.png
Normal file
|
After Width: | Height: | Size: 338 KiB |
BIN
docs/assets/preflight-checks/outputs/000015.1252923272.png
Normal file
|
After Width: | Height: | Size: 271 KiB |
BIN
docs/assets/preflight-checks/outputs/000016.2633891320.png
Normal file
|
After Width: | Height: | Size: 353 KiB |
BIN
docs/assets/preflight-checks/outputs/000017.1134411920.png
Normal file
|
After Width: | Height: | Size: 330 KiB |
BIN
docs/assets/preflight-checks/outputs/000018.47.png
Normal file
|
After Width: | Height: | Size: 439 KiB |
BIN
docs/assets/preflight-checks/outputs/000019.47.png
Normal file
|
After Width: | Height: | Size: 463 KiB |
BIN
docs/assets/preflight-checks/outputs/000020.47.png
Normal file
|
After Width: | Height: | Size: 444 KiB |
BIN
docs/assets/preflight-checks/outputs/000021.47.png
Normal file
|
After Width: | Height: | Size: 468 KiB |
BIN
docs/assets/preflight-checks/outputs/000022.47.png
Normal file
|
After Width: | Height: | Size: 466 KiB |
BIN
docs/assets/preflight-checks/outputs/000023.47.png
Normal file
|
After Width: | Height: | Size: 475 KiB |
BIN
docs/assets/preflight-checks/outputs/000024.1029061431.png
Normal file
|
After Width: | Height: | Size: 429 KiB |
BIN
docs/assets/preflight-checks/outputs/000025.1284519352.png
Normal file
|
After Width: | Height: | Size: 429 KiB |
BIN
docs/assets/preflight-checks/outputs/curly.942491079.gfpgan.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 477 KiB |
BIN
docs/assets/preflight-checks/outputs/curly.942491079.outcrop.png
Normal file
|
After Width: | Height: | Size: 476 KiB |
|
After Width: | Height: | Size: 434 KiB |
116
docs/assets/preflight-checks/outputs/invoke_log.md
Normal file
@@ -0,0 +1,116 @@
|
||||
## 000001.1863159593.png
|
||||

|
||||
|
||||
banana sushi -s 50 -S 1863159593 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
## 000002.1151955949.png
|
||||

|
||||
|
||||
banana sushi -s 50 -S 1151955949 -W 512 -H 512 -C 7.5 -A plms
|
||||
## 000003.2736230502.png
|
||||

|
||||
|
||||
banana sushi -s 50 -S 2736230502 -W 512 -H 512 -C 7.5 -A ddim
|
||||
## 000004.42.png
|
||||

|
||||
|
||||
banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
## 000005.42.png
|
||||

|
||||
|
||||
banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
## 000006.478163327.png
|
||||

|
||||
|
||||
banana sushi -s 50 -S 478163327 -W 640 -H 448 -C 7.5 -A k_lms
|
||||
## 000007.2407640369.png
|
||||

|
||||
|
||||
banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 2407640369:0.1
|
||||
## 000008.2772421987.png
|
||||

|
||||
|
||||
banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 2772421987:0.1
|
||||
## 000009.3532317557.png
|
||||

|
||||
|
||||
banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 3532317557:0.1
|
||||
## 000010.2028635318.png
|
||||

|
||||
|
||||
banana sushi -s 50 -S 2028635318 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
## 000011.1111168647.png
|
||||

|
||||
|
||||
pond with waterlillies -s 50 -S 1111168647 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
## 000012.1476370516.png
|
||||

|
||||
|
||||
pond with waterlillies -s 50 -S 1476370516 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
## 000013.4281108706.png
|
||||

|
||||
|
||||
banana sushi -s 50 -S 4281108706 -W 960 -H 960 -C 7.5 -A k_lms
|
||||
## 000014.2396987386.png
|
||||

|
||||
|
||||
old sea captain with crow on shoulder -s 50 -S 2396987386 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A k_lms -f 0.75
|
||||
## 000015.1252923272.png
|
||||

|
||||
|
||||
old sea captain with crow on shoulder -s 50 -S 1252923272 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512-transparent.png -A k_lms -f 0.75
|
||||
## 000016.2633891320.png
|
||||

|
||||
|
||||
old sea captain with crow on shoulder -s 50 -S 2633891320 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A plms -f 0.75
|
||||
## 000017.1134411920.png
|
||||

|
||||
|
||||
old sea captain with crow on shoulder -s 50 -S 1134411920 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A k_euler_a -f 0.75
|
||||
## 000018.47.png
|
||||

|
||||
|
||||
big red dog playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
## 000019.47.png
|
||||

|
||||
|
||||
big red++++ dog playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
## 000020.47.png
|
||||

|
||||
|
||||
big red dog playing with cat+++ -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
## 000021.47.png
|
||||

|
||||
|
||||
big (red dog).swap(tiger) playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
## 000022.47.png
|
||||

|
||||
|
||||
dog:1,cat:2 -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
## 000023.47.png
|
||||

|
||||
|
||||
dog:2,cat:1 -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
## 000024.1029061431.png
|
||||

|
||||
|
||||
medusa with cobras -s 50 -S 1029061431 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/curly.png -A k_lms -f 0.75 -tm hair
|
||||
## 000025.1284519352.png
|
||||

|
||||
|
||||
bearded man -s 50 -S 1284519352 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/curly.png -A k_lms -f 0.75 -tm face
|
||||
## curly.942491079.gfpgan.png
|
||||

|
||||
|
||||
!fix ./docs/assets/preflight-checks/inputs/curly.png -s 50 -S 942491079 -W 512 -H 512 -C 7.5 -A k_lms -G 0.8 -ft gfpgan -U 2.0 0.75
|
||||
## curly.942491079.outcrop.png
|
||||

|
||||
|
||||
!fix ./docs/assets/preflight-checks/inputs/curly.png -s 50 -S 942491079 -W 512 -H 512 -C 7.5 -A k_lms -c top 64
|
||||
## curly.942491079.outpaint.png
|
||||

|
||||
|
||||
!fix ./docs/assets/preflight-checks/inputs/curly.png -s 50 -S 942491079 -W 512 -H 512 -C 7.5 -A k_lms -D top 64
|
||||
## curly.942491079.outcrop-01.png
|
||||

|
||||
|
||||
!fix ./docs/assets/preflight-checks/inputs/curly.png -s 50 -S 942491079 -W 512 -H 512 -C 7.5 -A k_lms -c top 64
|
||||
29
docs/assets/preflight-checks/outputs/invoke_log.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
outputs/preflight/000001.1863159593.png: banana sushi -s 50 -S 1863159593 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
outputs/preflight/000002.1151955949.png: banana sushi -s 50 -S 1151955949 -W 512 -H 512 -C 7.5 -A plms
|
||||
outputs/preflight/000003.2736230502.png: banana sushi -s 50 -S 2736230502 -W 512 -H 512 -C 7.5 -A ddim
|
||||
outputs/preflight/000004.42.png: banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
outputs/preflight/000005.42.png: banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
outputs/preflight/000006.478163327.png: banana sushi -s 50 -S 478163327 -W 640 -H 448 -C 7.5 -A k_lms
|
||||
outputs/preflight/000007.2407640369.png: banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 2407640369:0.1
|
||||
outputs/preflight/000008.2772421987.png: banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 2772421987:0.1
|
||||
outputs/preflight/000009.3532317557.png: banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 3532317557:0.1
|
||||
outputs/preflight/000010.2028635318.png: banana sushi -s 50 -S 2028635318 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
outputs/preflight/000011.1111168647.png: pond with waterlillies -s 50 -S 1111168647 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
outputs/preflight/000012.1476370516.png: pond with waterlillies -s 50 -S 1476370516 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
outputs/preflight/000013.4281108706.png: banana sushi -s 50 -S 4281108706 -W 960 -H 960 -C 7.5 -A k_lms
|
||||
outputs/preflight/000014.2396987386.png: old sea captain with crow on shoulder -s 50 -S 2396987386 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A k_lms -f 0.75
|
||||
outputs/preflight/000015.1252923272.png: old sea captain with crow on shoulder -s 50 -S 1252923272 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512-transparent.png -A k_lms -f 0.75
|
||||
outputs/preflight/000016.2633891320.png: old sea captain with crow on shoulder -s 50 -S 2633891320 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A plms -f 0.75
|
||||
outputs/preflight/000017.1134411920.png: old sea captain with crow on shoulder -s 50 -S 1134411920 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A k_euler_a -f 0.75
|
||||
outputs/preflight/000018.47.png: big red dog playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
outputs/preflight/000019.47.png: big red++++ dog playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
outputs/preflight/000020.47.png: big red dog playing with cat+++ -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
outputs/preflight/000021.47.png: big (red dog).swap(tiger) playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
outputs/preflight/000022.47.png: dog:1,cat:2 -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
outputs/preflight/000023.47.png: dog:2,cat:1 -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
outputs/preflight/000024.1029061431.png: medusa with cobras -s 50 -S 1029061431 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/curly.png -A k_lms -f 0.75 -tm hair
|
||||
outputs/preflight/000025.1284519352.png: bearded man -s 50 -S 1284519352 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/curly.png -A k_lms -f 0.75 -tm face
|
||||
outputs/preflight/curly.942491079.gfpgan.png: !fix ./docs/assets/preflight-checks/inputs/curly.png -s 50 -S 942491079 -W 512 -H 512 -C 7.5 -A k_lms -G 0.8 -ft gfpgan -U 2.0 0.75
|
||||
outputs/preflight/curly.942491079.outcrop.png: !fix ./docs/assets/preflight-checks/inputs/curly.png -s 50 -S 942491079 -W 512 -H 512 -C 7.5 -A k_lms -c top 64
|
||||
outputs/preflight/curly.942491079.outpaint.png: !fix ./docs/assets/preflight-checks/inputs/curly.png -s 50 -S 942491079 -W 512 -H 512 -C 7.5 -A k_lms -D top 64
|
||||
outputs/preflight/curly.942491079.outcrop-01.png: !fix ./docs/assets/preflight-checks/inputs/curly.png -s 50 -S 942491079 -W 512 -H 512 -C 7.5 -A k_lms -c top 64
|
||||
61
docs/assets/preflight-checks/preflight_prompts.txt
Normal file
@@ -0,0 +1,61 @@
|
||||
# outputs/preflight/000001.1863159593.png
|
||||
banana sushi -s 50 -S 1863159593 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
# outputs/preflight/000002.1151955949.png
|
||||
banana sushi -s 50 -S 1151955949 -W 512 -H 512 -C 7.5 -A plms
|
||||
# outputs/preflight/000003.2736230502.png
|
||||
banana sushi -s 50 -S 2736230502 -W 512 -H 512 -C 7.5 -A ddim
|
||||
# outputs/preflight/000004.42.png
|
||||
banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
# outputs/preflight/000005.42.png
|
||||
banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
# outputs/preflight/000006.478163327.png
|
||||
banana sushi -s 50 -S 478163327 -W 640 -H 448 -C 7.5 -A k_lms
|
||||
# outputs/preflight/000007.2407640369.png
|
||||
banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 2407640369:0.1
|
||||
# outputs/preflight/000007.2772421987.png
|
||||
banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 2772421987:0.1
|
||||
# outputs/preflight/000007.3532317557.png
|
||||
banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms -V 3532317557:0.1
|
||||
# outputs/preflight/000008.2028635318.png
|
||||
banana sushi -s 50 -S 2028635318 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
# outputs/preflight/000009.1111168647.png
|
||||
pond with waterlillies -s 50 -S 1111168647 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
# outputs/preflight/000010.1476370516.png
|
||||
pond with waterlillies -s 50 -S 1476370516 -W 512 -H 512 -C 7.5 -A k_lms --seamless
|
||||
# outputs/preflight/000011.4281108706.png
|
||||
banana sushi -s 50 -S 4281108706 -W 960 -H 960 -C 7.5 -A k_lms
|
||||
# outputs/preflight/000012.2396987386.png
|
||||
old sea captain with crow on shoulder -s 50 -S 2396987386 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A k_lms -f 0.75
|
||||
# outputs/preflight/000013.1252923272.png
|
||||
old sea captain with crow on shoulder -s 50 -S 1252923272 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512-transparent.png -A k_lms -f 0.75
|
||||
# outputs/preflight/000014.2633891320.png
|
||||
old sea captain with crow on shoulder -s 50 -S 2633891320 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A plms -f 0.75
|
||||
# outputs/preflight/000015.1134411920.png
|
||||
old sea captain with crow on shoulder -s 50 -S 1134411920 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/Lincoln-and-Parrot-512.png -A k_euler_a -f 0.75
|
||||
# outputs/preflight/000016.42.png
|
||||
big red dog playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
# outputs/preflight/000017.42.png
|
||||
big red++++ dog playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
# outputs/preflight/000018.42.png
|
||||
big red dog playing with cat+++ -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
# outputs/preflight/000019.42.png
|
||||
big (red dog).swap(tiger) playing with cat -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
# outputs/preflight/000020.42.png
|
||||
dog:1,cat:2 -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
# outputs/preflight/000021.42.png
|
||||
dog:2,cat:1 -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||
# outputs/preflight/000022.1029061431.png
|
||||
medusa with cobras -s 50 -S 1029061431 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/curly.png -A k_lms -f 0.75 -tm hair
|
||||
# outputs/preflight/000023.1284519352.png
|
||||
bearded man -s 50 -S 1284519352 -W 512 -H 512 -C 7.5 -I docs/assets/preflight-checks/inputs/curly.png -A k_lms -f 0.75 -tm face
|
||||
# outputs/preflight/000024.curly.hair.deselected.png
|
||||
!mask -I docs/assets/preflight-checks/inputs/curly.png -tm hair
|
||||
# outputs/preflight/curly.942491079.gfpgan.png
|
||||
!fix ./docs/assets/preflight-checks/inputs/curly.png -U2 -G0.8
|
||||
# outputs/preflight/curly.942491079.outcrop.png
|
||||
!fix ./docs/assets/preflight-checks/inputs/curly.png -c top 64
|
||||
# outputs/preflight/curly.942491079.outpaint.png
|
||||
!fix ./docs/assets/preflight-checks/inputs/curly.png -D top 64
|
||||
# outputs/preflight/curly.942491079.outcrop-01.png
|
||||
!switch inpainting-1.5
|
||||
!fix ./docs/assets/preflight-checks/inputs/curly.png -c top 64
|
||||
@@ -1,143 +0,0 @@
|
||||
---
|
||||
title: Changelog
|
||||
---
|
||||
|
||||
# :octicons-log-16: Changelog
|
||||
|
||||
## v1.13
|
||||
|
||||
- Supports a Google Colab notebook for a standalone server running on Google
|
||||
hardware [Arturo Mendivil](https://github.com/artmen1516)
|
||||
- WebUI supports GFPGAN/ESRGAN facial reconstruction and upscaling
|
||||
[Kevin Gibbons](https://github.com/bakkot)
|
||||
- WebUI supports incremental display of in-progress images during generation
|
||||
[Kevin Gibbons](https://github.com/bakkot)
|
||||
- Output directory can be specified on the invoke> command line.
|
||||
- The grid was displaying duplicated images when not enough images to fill the
|
||||
final row [Muhammad Usama](https://github.com/SMUsamaShah)
|
||||
- Can specify --grid on invoke.py command line as the default.
|
||||
- Miscellaneous internal bug and stability fixes.
|
||||
|
||||
---
|
||||
|
||||
## v1.12 <small>(28 August 2022)</small>
|
||||
|
||||
- Improved file handling, including ability to read prompts from standard input.
|
||||
(kudos to [Yunsaki](https://github.com/yunsaki)
|
||||
- The web server is now integrated with the invoke.py script. Invoke by adding
|
||||
--web to the invoke.py command arguments.
|
||||
- Face restoration and upscaling via GFPGAN and Real-ESGAN are now automatically
|
||||
enabled if the GFPGAN directory is located as a sibling to Stable Diffusion.
|
||||
VRAM requirements are modestly reduced. Thanks to both
|
||||
[Blessedcoolant](https://github.com/blessedcoolant) and
|
||||
[Oceanswave](https://github.com/oceanswave) for their work on this.
|
||||
- You can now swap samplers on the invoke> command line.
|
||||
[Blessedcoolant](https://github.com/blessedcoolant)
|
||||
|
||||
---
|
||||
|
||||
## v1.11 <small>(26 August 2022)</small>
|
||||
|
||||
- NEW FEATURE: Support upscaling and face enhancement using the GFPGAN module.
|
||||
(kudos to [Oceanswave](https://github.com/Oceanswave))
|
||||
- You now can specify a seed of -1 to use the previous image's seed, -2 to use
|
||||
the seed for the image generated before that, etc. Seed memory only extends
|
||||
back to the previous command, but will work on all images generated with the
|
||||
-n# switch.
|
||||
- Variant generation support temporarily disabled pending more general solution.
|
||||
- Created a feature branch named **yunsaki-morphing-invoke** which adds
|
||||
experimental support for iteratively modifying the prompt and its parameters.
|
||||
Please
|
||||
see[ Pull Request #86](https://github.com/lstein/stable-diffusion/pull/86) for
|
||||
a synopsis of how this works. Note that when this feature is eventually added
|
||||
to the main branch, it will may be modified significantly.
|
||||
|
||||
---
|
||||
|
||||
## v1.10 <small>(25 August 2022)</small>
|
||||
|
||||
- A barebones but fully functional interactive web server for online generation
|
||||
of txt2img and img2img.
|
||||
|
||||
---
|
||||
|
||||
## v1.09 <small>(24 August 2022)</small>
|
||||
|
||||
- A new -v option allows you to generate multiple variants of an initial image
|
||||
in img2img mode. (kudos to [Oceanswave](https://github.com/Oceanswave).
|
||||
- [See this discussion in the PR for examples and details on use](https://github.com/lstein/stable-diffusion/pull/71#issuecomment-1226700810))
|
||||
- Added ability to personalize text to image generation (kudos to
|
||||
[Oceanswave](https://github.com/Oceanswave) and
|
||||
[nicolai256](https://github.com/nicolai256))
|
||||
- Enabled all of the samplers from k_diffusion
|
||||
|
||||
---
|
||||
|
||||
## v1.08 <small>(24 August 2022)</small>
|
||||
|
||||
- Escape single quotes on the invoke> command before trying to parse. This avoids
|
||||
parse errors.
|
||||
- Removed instruction to get Python3.8 as first step in Windows install.
|
||||
Anaconda3 does it for you.
|
||||
- Added bounds checks for numeric arguments that could cause crashes.
|
||||
- Cleaned up the copyright and license agreement files.
|
||||
|
||||
---
|
||||
|
||||
## v1.07 <small>(23 August 2022)</small>
|
||||
|
||||
- Image filenames will now never fill gaps in the sequence, but will be assigned
|
||||
the next higher name in the chosen directory. This ensures that the alphabetic
|
||||
and chronological sort orders are the same.
|
||||
|
||||
---
|
||||
|
||||
## v1.06 <small>(23 August 2022)</small>
|
||||
|
||||
- Added weighted prompt support contributed by
|
||||
[xraxra](https://github.com/xraxra)
|
||||
- Example of using weighted prompts to tweak a demonic figure contributed by
|
||||
[bmaltais](https://github.com/bmaltais)
|
||||
|
||||
---
|
||||
|
||||
## v1.05 <small>(22 August 2022 - after the drop)</small>
|
||||
|
||||
- Filenames now use the following formats: 000010.95183149.png -- Two files
|
||||
produced by the same command (e.g. -n2), 000010.26742632.png -- distinguished
|
||||
by a different seed.
|
||||
000011.455191342.01.png -- Two files produced by the same command using
|
||||
000011.455191342.02.png -- a batch size>1 (e.g. -b2). They have the same seed.
|
||||
000011.4160627868.grid#1-4.png -- a grid of four images (-g); the whole grid
|
||||
can be regenerated with the indicated key
|
||||
|
||||
- It should no longer be possible for one image to overwrite another
|
||||
- You can use the "cd" and "pwd" commands at the invoke> prompt to set and
|
||||
retrieve the path of the output directory.
|
||||
|
||||
## v1.04 <small>(22 August 2022 - after the drop)</small>
|
||||
|
||||
- Updated README to reflect installation of the released weights.
|
||||
- Suppressed very noisy and inconsequential warning when loading the frozen CLIP
|
||||
tokenizer.
|
||||
|
||||
## v1.03 <small>(22 August 2022)</small>
|
||||
|
||||
- The original txt2img and img2img scripts from the CompViz repository have been
|
||||
moved into a subfolder named "orig_scripts", to reduce confusion.
|
||||
|
||||
## v1.02 <small>(21 August 2022)</small>
|
||||
|
||||
- A copy of the prompt and all of its switches and options is now stored in the
|
||||
corresponding image in a tEXt metadata field named "Dream". You can read the
|
||||
prompt using scripts/images2prompt.py, or an image editor that allows you to
|
||||
explore the full metadata. **Please run "conda env update -f environment.yaml"
|
||||
to load the k_lms dependencies!!**
|
||||
|
||||
## v1.01 <small>(21 August 2022)</small>
|
||||
|
||||
- added k_lms sampling. **Please run "conda env update -f environment.yaml" to
|
||||
load the k_lms dependencies!!**
|
||||
- use half precision arithmetic by default, resulting in faster execution and
|
||||
lower memory requirements Pass argument --full_precision to invoke.py to get
|
||||
slower but more accurate image generation
|
||||
@@ -101,9 +101,7 @@ overridden on a per-prompt basis (see [List of prompt arguments](#list-of-prompt
|
||||
| `--free_gpu_mem` | | `False` | Free GPU memory after sampling, to allow image decoding and saving in low VRAM conditions |
|
||||
| `--precision` | | `auto` | Set model precision, default is selected by device. Options: auto, float32, float16, autocast |
|
||||
|
||||
!!! warning deprecated
|
||||
|
||||
These arguments are deprecated but still work:
|
||||
!!! warning "These arguments are deprecated but still work"
|
||||
|
||||
<div align="center" markdown>
|
||||
|
||||
@@ -132,7 +130,7 @@ from text ([txt2img](#txt2img)), to embellish an existing image or sketch
|
||||
|
||||
### txt2img
|
||||
|
||||
!!! example
|
||||
!!! example ""
|
||||
|
||||
```bash
|
||||
invoke> waterfall and rainbow -W640 -H480
|
||||
@@ -200,7 +198,7 @@ accepts additional options:
|
||||
|
||||
### inpainting
|
||||
|
||||
!!! example
|
||||
!!! example ""
|
||||
|
||||
```bash
|
||||
invoke> waterfall and rainbow -I./vacation-photo.png -M./vacation-mask.png -W640 -H480 --fit
|
||||
|
||||
@@ -17,15 +17,15 @@ tree on a hill with a river, nature photograph, national geographic -I./test-pic
|
||||
|
||||
This will take the original image shown here:
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||
<img src="https://user-images.githubusercontent.com/50542132/193946000-c42a96d8-5a74-4f8a-b4c3-5213e6cadcce.png" width=350>
|
||||
</div>
|
||||
</figure>
|
||||
|
||||
and generate a new image based on it as shown here:
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||
<img src="https://user-images.githubusercontent.com/111189/194135515-53d4c060-e994-4016-8121-7c685e281ac9.png" width=350>
|
||||
</div>
|
||||
</figure>
|
||||
|
||||
The `--init_img` (`-I`) option gives the path to the seed picture. `--strength` (`-f`) controls how much
|
||||
the original will be modified, ranging from `0.0` (keep the original intact), to `1.0` (ignore the
|
||||
@@ -41,11 +41,10 @@ interesting variants.
|
||||
Note that the prompt makes a big difference. For example, this slight variation on the prompt produces
|
||||
a very different image:
|
||||
|
||||
`photograph of a tree on a hill with a river`
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||
<img src="https://user-images.githubusercontent.com/111189/194135220-16b62181-b60c-4248-8989-4834a8fd7fbd.png" width=350>
|
||||
</div>
|
||||
<caption markdown>photograph of a tree on a hill with a river</caption>
|
||||
</figure>
|
||||
|
||||
!!! tip
|
||||
|
||||
@@ -79,9 +78,9 @@ gaussian noise and progressively refines it over the requested number of steps,
|
||||
invoke> "fire" -s10 -W384 -H384 -S1592514025
|
||||
```
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||

|
||||
</div>
|
||||
</figure>
|
||||
|
||||
Put simply: starting from a frame of fuzz/static, SD finds details in each frame that it thinks look like "fire" and brings them a little bit more into focus, gradually scrubbing out the fuzz until a clear image remains.
|
||||
|
||||
@@ -91,21 +90,21 @@ Put simply: starting from a frame of fuzz/static, SD finds details in each frame
|
||||
|
||||
I want SD to draw a fire based on this hand-drawn image:
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||

|
||||
</div>
|
||||
</figure>
|
||||
|
||||
Let's only do 10 steps, to make it easier to see what's happening. If strength is `0.7`, this is what the internal steps the algorithm has to take will look like:
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||

|
||||
</div>
|
||||
</figure>
|
||||
|
||||
With strength `0.4`, the steps look more like this:
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||

|
||||
</div>
|
||||
</figure>
|
||||
|
||||
Notice how much more fuzzy the starting image is for strength `0.7` compared to `0.4`, and notice also how much longer the sequence is with `0.7`:
|
||||
|
||||
@@ -137,9 +136,9 @@ Here's strength `0.4` (note step count `50`, which is `20 ÷ 0.4` to make sure S
|
||||
invoke> "fire" -s50 -W384 -H384 -S1592514025 -I /tmp/fire-drawing.png -f 0.4
|
||||
```
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||

|
||||
</div>
|
||||
</figure>
|
||||
|
||||
and here is strength `0.7` (note step count `30`, which is roughly `20 ÷ 0.7` to make sure SD does `20` steps from my image):
|
||||
|
||||
@@ -147,29 +146,38 @@ and here is strength `0.7` (note step count `30`, which is roughly `20 ÷ 0.7` t
|
||||
invoke> "fire" -s30 -W384 -H384 -S1592514025 -I /tmp/fire-drawing.png -f 0.7
|
||||
```
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||

|
||||
</div>
|
||||
</figure>
|
||||
|
||||
In both cases the image is nice and clean and "finished", but because at strength `0.7` Stable Diffusion has been give so much more freedom to improve on my badly-drawn flames, they've come out looking much better. You can really see the difference when looking at the latent steps. There's more noise on the first image with strength `0.7`:
|
||||
|
||||
<figure markdown>
|
||||

|
||||
</figure>
|
||||
|
||||
than there is for strength `0.4`:
|
||||
|
||||
<figure markdown>
|
||||

|
||||
</figure>
|
||||
|
||||
and that extra noise gives the algorithm more choices when it is evaluating how to denoise any particular pixel in the image.
|
||||
|
||||
Unfortunately, it seems that `img2img` is very sensitive to the step count. Here's strength `0.7` with a step count of `29` (SD did 19 steps from my image):
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||

|
||||
</div>
|
||||
</figure>
|
||||
|
||||
By comparing the latents we can sort of see that something got interpreted differently enough on the third or fourth step to lead to a rather different interpretation of the flames.
|
||||
|
||||
<figure markdown>
|
||||

|
||||
</figure>
|
||||
|
||||
<figure markdown>
|
||||

|
||||
</figure>
|
||||
|
||||
This is the result of a difference in the de-noising "schedule" - basically the noise has to be cleaned by a certain degree each step or the model won't "converge" on the image properly (see [stable diffusion blog](https://huggingface.co/blog/stable_diffusion) for more about that). A different step count means a different schedule, which means things get interpreted slightly differently at every step.
|
||||
|
||||
@@ -9,7 +9,7 @@ title: Inpainting
|
||||
Inpainting is really cool. To do it, you start with an initial image
|
||||
and use a photoeditor to make one or more regions transparent
|
||||
(i.e. they have a "hole" in them). You then provide the path to this
|
||||
image at the dream> command line using the `-I` switch. Stable
|
||||
image at the invoke> command line using the `-I` switch. Stable
|
||||
Diffusion will only paint within the transparent region.
|
||||
|
||||
There's a catch. In the current implementation, you have to prepare
|
||||
@@ -25,7 +25,7 @@ color information is preserved. There is often an option in the export
|
||||
dialog that lets you specify this.
|
||||
|
||||
If your photoeditor is erasing the underlying color information,
|
||||
`dream.py` will give you a big fat warning. If you can't find a way to
|
||||
`invoke.py` will give you a big fat warning. If you can't find a way to
|
||||
coax your photoeditor to retain color values under transparent areas,
|
||||
then you can combine the `-I` and `-M` switches to provide both the
|
||||
original unedited image and the masked (partially transparent) image:
|
||||
@@ -257,28 +257,40 @@ surrounding unmasked regions as well.
|
||||
|
||||
1. Open image in Photoshop
|
||||
|
||||
<div align="center" markdown></div>
|
||||
<figure markdown>
|
||||

|
||||
</figure>
|
||||
|
||||
2. Use any of the selection tools (Marquee, Lasso, or Wand) to select the area you desire to inpaint.
|
||||
|
||||
<div align="center" markdown></div>
|
||||
<figure markdown>
|
||||

|
||||
</figure>
|
||||
|
||||
3. Because we'll be applying a mask over the area we want to preserve, you should now select the inverse by using the ++shift+ctrl+i++ shortcut, or right clicking and using the "Select Inverse" option.
|
||||
|
||||
4. You'll now create a mask by selecting the image layer, and Masking the selection. Make sure that you don't delete any of the underlying image, or your inpainting results will be dramatically impacted.
|
||||
|
||||
<div align="center" markdown></div>
|
||||
<figure markdown>
|
||||

|
||||
</figure>
|
||||
|
||||
5. Make sure to hide any background layers that are present. You should see the mask applied to your image layer, and the image on your canvas should display the checkered background.
|
||||
|
||||
<div align="center" markdown></div>
|
||||
<figure markdown>
|
||||

|
||||
</figure>
|
||||
|
||||
6. Save the image as a transparent PNG by using `File`-->`Save a Copy` from the menu bar, or by using the keyboard shortcut ++alt+ctrl+s++
|
||||
|
||||
<div align="center" markdown></div>
|
||||
<figure markdown>
|
||||

|
||||
</figure>
|
||||
|
||||
7. After following the inpainting instructions above (either through the CLI or the Web UI), marvel at your newfound ability to selectively invoke. Lookin' good!
|
||||
|
||||
<div align="center" markdown></div>
|
||||
<figure markdown>
|
||||

|
||||
</figure>
|
||||
|
||||
8. In the export dialogue, Make sure the "Save colour values from transparent pixels" checkbox is selected.
|
||||
|
||||
@@ -64,31 +64,32 @@ model](INPAINTING.md#using-the-runwayml-inpainting-model).
|
||||
|
||||
Consider this image:
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||

|
||||
</div>
|
||||
</figure>
|
||||
|
||||
Pretty nice, but it's annoying that the top of her head is cut
|
||||
off. She's also a bit off center. Let's fix that!
|
||||
|
||||
```bash
|
||||
invoke> !fix images/curly.png --outcrop top 64 right 64
|
||||
invoke> !fix images/curly.png --outcrop top 128 right 64 bottom 64
|
||||
```
|
||||
|
||||
This is saying to apply the `outcrop` extension by extending the top
|
||||
of the image by 64 pixels, and the right of the image by the same
|
||||
amount. You can use any combination of top|left|right|bottom, and
|
||||
of the image by 128 pixels, and the right and bottom of the image by
|
||||
64 pixels. You can use any combination of top|left|right|bottom, and
|
||||
specify any number of pixels to extend. You can also abbreviate
|
||||
`--outcrop` to `-c`.
|
||||
|
||||
The result looks like this:
|
||||
|
||||
<div align="center" markdown>
|
||||

|
||||
</div>
|
||||
<figure markdown>
|
||||

|
||||
</figure>
|
||||
|
||||
The new image is actually slightly larger than the original (576x576,
|
||||
because 64 pixels were added to the top and right sides.)
|
||||
The new image is larger than the original (576x704)
|
||||
because 64 pixels were added to the top and right sides. You will
|
||||
need enough VRAM to process an image of this size.
|
||||
|
||||
A number of caveats:
|
||||
|
||||
@@ -103,3 +104,53 @@ you'll get a slightly different result. You can run it repeatedly
|
||||
until you get an image you like. Unfortunately `!fix` does not
|
||||
currently respect the `-n` (`--iterations`) argument.
|
||||
|
||||
3. Your results will be _much_ better if you use the `inpaint-1.5`
|
||||
model released by runwayML and installed by default by
|
||||
`scripts/preload_models.py`. This model was trained specifically to
|
||||
harmoniously fill in image gaps. The standard model will work as well,
|
||||
but you may notice color discontinuities at the border.
|
||||
|
||||
4. When using the `inpaint-1.5` model, you may notice subtle changes
|
||||
to the area within the original image. This is because the model
|
||||
performs an encoding/decoding on the image as a whole. This does not
|
||||
occur with the standard model.
|
||||
|
||||
## Outpaint
|
||||
|
||||
The `outpaint` extension does the same thing, but with subtle
|
||||
differences. Starting with the same image, here is how we would add an
|
||||
additional 64 pixels to the top of the image:
|
||||
|
||||
```bash
|
||||
invoke> !fix images/curly.png --out_direction top 64
|
||||
```
|
||||
|
||||
(you can abbreviate `--out_direction` as `-D`.
|
||||
|
||||
The result is shown here:
|
||||
|
||||
<figure markdown>
|
||||

|
||||
</figure>
|
||||
|
||||
Although the effect is similar, there are significant differences from
|
||||
outcropping:
|
||||
|
||||
- You can only specify one direction to extend at a time.
|
||||
- The image is **not** resized. Instead, the image is shifted by the specified
|
||||
number of pixels. If you look carefully, you'll see that less of the lady's
|
||||
torso is visible in the image.
|
||||
- Because the image dimensions remain the same, there's no rounding
|
||||
to multiples of 64.
|
||||
- Attempting to outpaint larger areas will frequently give rise to ugly
|
||||
ghosting effects.
|
||||
- For best results, try increasing the step number.
|
||||
- If you don't specify a pixel value in `-D`, it will default to half
|
||||
of the whole image, which is likely not what you want.
|
||||
|
||||
!!! tip
|
||||
|
||||
Neither `outpaint` nor `outcrop` are perfect, but we continue to tune
|
||||
and improve them. If one doesn't work, try the other. You may also
|
||||
wish to experiment with other `img2img` arguments, such as `-C`, `-f`
|
||||
and `-s`.
|
||||
|
||||
@@ -47,33 +47,33 @@ original prompt:
|
||||
|
||||
`#!bash "A fantastical translucent pony made of water and foam, ethereal, radiant, hyperalism, scottish folklore, digital painting, artstation, concept art, smooth, 8 k frostbite 3 engine, ultra detailed, art by artgerm and greg rutkowski and magali villeneuve" -s 20 -W 512 -H 768 -C 7.5 -A k_euler_a -S 1654590180`
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||

|
||||
</div>
|
||||
</figure>
|
||||
|
||||
That image has a woman, so if we want the horse without a rider, we can influence the image not to have a woman by putting [woman] in the prompt, like this:
|
||||
|
||||
`#!bash "A fantastical translucent poney made of water and foam, ethereal, radiant, hyperalism, scottish folklore, digital painting, artstation, concept art, smooth, 8 k frostbite 3 engine, ultra detailed, art by artgerm and greg rutkowski and magali villeneuve [woman]" -s 20 -W 512 -H 768 -C 7.5 -A k_euler_a -S 1654590180`
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||

|
||||
</div>
|
||||
</figure>
|
||||
|
||||
That's nice - but say we also don't want the image to be quite so blue. We can add "blue" to the list of negative prompts, so it's now [woman blue]:
|
||||
|
||||
`#!bash "A fantastical translucent poney made of water and foam, ethereal, radiant, hyperalism, scottish folklore, digital painting, artstation, concept art, smooth, 8 k frostbite 3 engine, ultra detailed, art by artgerm and greg rutkowski and magali villeneuve [woman blue]" -s 20 -W 512 -H 768 -C 7.5 -A k_euler_a -S 1654590180`
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||

|
||||
</div>
|
||||
</figure>
|
||||
|
||||
Getting close - but there's no sense in having a saddle when our horse doesn't have a rider, so we'll add one more negative prompt: [woman blue saddle].
|
||||
|
||||
`#!bash "A fantastical translucent poney made of water and foam, ethereal, radiant, hyperalism, scottish folklore, digital painting, artstation, concept art, smooth, 8 k frostbite 3 engine, ultra detailed, art by artgerm and greg rutkowski and magali villeneuve [woman blue saddle]" -s 20 -W 512 -H 768 -C 7.5 -A k_euler_a -S 1654590180`
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||

|
||||
</div>
|
||||
</figure>
|
||||
|
||||
!!! notes "Notes about this feature:"
|
||||
|
||||
@@ -215,56 +215,56 @@ different results each time you run them.
|
||||
|
||||
---
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||
### "blue sphere, red cube, hybrid"
|
||||
</div>
|
||||
</figure>
|
||||
|
||||
This example doesn't use melding at all and represents the default way
|
||||
of mixing concepts.
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||

|
||||
</div>
|
||||
</figure>
|
||||
|
||||
It's interesting to see how the AI expressed the concept of "cube" as
|
||||
the four quadrants of the enclosing frame. If you look closely, there
|
||||
is depth there, so the enclosing frame is actually a cube.
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||
### "blue sphere:0.25 red cube:0.75 hybrid"
|
||||
|
||||

|
||||
</div>
|
||||
</figure>
|
||||
|
||||
Now that's interesting. We get neither a blue sphere nor a red cube,
|
||||
but a red sphere embedded in a brick wall, which represents a melding
|
||||
of concepts within the AI's "latent space" of semantic
|
||||
representations. Where is Ludwig Wittgenstein when you need him?
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||
### "blue sphere:0.75 red cube:0.25 hybrid"
|
||||
|
||||

|
||||
</div>
|
||||
</figure>
|
||||
|
||||
Definitely more blue-spherey. The cube is gone entirely, but it's
|
||||
really cool abstract art.
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||
### "blue sphere:0.5 red cube:0.5 hybrid"
|
||||
|
||||

|
||||
</div>
|
||||
</figure>
|
||||
|
||||
Whoa...! I see blue and red, but no spheres or cubes. Is the word
|
||||
"hybrid" summoning up the concept of some sort of scifi creature?
|
||||
Let's find out.
|
||||
|
||||
<div align="center" markdown>
|
||||
<figure markdown>
|
||||
### "blue sphere:0.5 red cube:0.5"
|
||||
|
||||

|
||||
</div>
|
||||
</figure>
|
||||
|
||||
Indeed, removing the word "hybrid" produces an image that is more like
|
||||
what we'd expect.
|
||||
|
||||
@@ -86,74 +86,69 @@ You wil need one of the following:
|
||||
|
||||
- At least 12 GB of free disk space for the machine learning model, Python, and all its dependencies.
|
||||
|
||||
!!! note
|
||||
!!! info
|
||||
|
||||
If you are have a Nvidia 10xx series card (e.g. the 1080ti), please run the invoke script in
|
||||
full-precision mode as shown below.
|
||||
|
||||
Similarly, specify full-precision mode on Apple M1 hardware.
|
||||
|
||||
To run in full-precision mode, start `invoke.py` with the `--full_precision` flag:
|
||||
Precision is auto configured based on the device. If however you encounter errors like
|
||||
`expected type Float but found Half` or `not implemented for Half` you can try starting
|
||||
`invoke.py` with the `--precision=float32` flag:
|
||||
|
||||
```bash
|
||||
(invokeai) ~/InvokeAI$ python scripts/invoke.py --full_precision
|
||||
```
|
||||
|
||||
## :octicons-log-16: Latest Changes
|
||||
|
||||
### v2.1.0 <small>(2 November 2022)</small>
|
||||
|
||||
- [Inpainting](https://invoke-ai.github.io/InvokeAI/features/INPAINTING/) support in the WebGUI
|
||||
- Greatly improved navigation and user experience in the [WebGUI](https://invoke-ai.github.io/InvokeAI/features/WEB/)
|
||||
- The prompt syntax has been enhanced with [prompt weighting, cross-attention and prompt merging](https://invoke-ai.github.io/InvokeAI/features/PROMPTS/).
|
||||
- You can now load [multiple models and switch among them quickly](https://docs.google.com/presentation/d/1WywGA1rny7bpFh7CLSdTr4nNpVKdlUeT0Bj0jCsILyU/edit?usp=sharing) without leaving the CLI.
|
||||
- The installation process (via `scripts/preload_models.py`) now lets you select among several popular [Stable Diffusion models](https://invoke-ai.github.io/InvokeAI/installation/INSTALLING_MODELS/) and downloads and installs them on your behalf. Among other models, this script will install the current Stable Diffusion 1.5 model as well as a StabilityAI variable autoencoder (VAE) which improves face generation.
|
||||
- Tired of struggling with photoeditors to get the masked region of for inpainting just right? Let the AI make the mask for you using [text masking](https://docs.google.com/presentation/d/1pWoY510hCVjz0M6X9CBbTznZgW2W5BYNKrmZm7B45q8/edit#slide=id.p). This feature allows you to specify the part of the image to paint over using just English-language phrases.
|
||||
- Tired of seeing the head of your subjects cropped off? Uncrop them in the CLI with the [outcrop feature](https://invoke-ai.github.io/InvokeAI/features/OUTPAINTING/#outcrop).
|
||||
- Tired of seeing your subject's bodies duplicated or mangled when generating larger-dimension images? Check out the `--hires` option in the CLI, or select the corresponding toggle in the WebGUI.
|
||||
- We now support textual inversion and fine-tune .bin styles and subjects from the Hugging Face archive of [SD Concepts](https://huggingface.co/sd-concepts-library). Load the .bin file using the `--embedding_path` option. (The next version will support merging and loading of multiple simultaneous models).
|
||||
|
||||
### v2.0.1 <small>(13 October 2022)</small>
|
||||
|
||||
- fix noisy images at high step count when using k* samplers
|
||||
- dream.py script now calls invoke.py module directly rather than
|
||||
via a new python process (which could break the environment)
|
||||
|
||||
### v2.0.0 <small>(9 October 2022)</small>
|
||||
|
||||
- `dream.py` script renamed `invoke.py`. A `dream.py` script wrapper remains
|
||||
for backward compatibility.
|
||||
for backward compatibility.
|
||||
- Completely new WebGUI - launch with `python3 scripts/invoke.py --web`
|
||||
- Support for <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/INPAINTING.md">inpainting</a> and <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/OUTPAINTING.md">outpainting</a>
|
||||
- Support for <a href="https://invoke-ai.github.io/InvokeAI/features/INPAINTING/">inpainting</a> and <a href="https://invoke-ai.github.io/InvokeAI/features/OUTPAINTING/">outpainting</a>
|
||||
- img2img runs on all k* samplers
|
||||
- Support for <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/PROMPTS.md#negative-and-unconditioned-prompts">negative prompts</a>
|
||||
- Support for <a href="https://invoke-ai.github.io/InvokeAI/features/PROMPTS/#negative-and-unconditioned-prompts">negative prompts</a>
|
||||
- Support for CodeFormer face reconstruction
|
||||
- Support for Textual Inversion on Macintoshes
|
||||
- Support in both WebGUI and CLI for <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/POSTPROCESS.md">post-processing of previously-generated images</a>
|
||||
using facial reconstruction, ESRGAN upscaling, outcropping (similar to DALL-E infinite canvas),
|
||||
and "embiggen" upscaling. See the `!fix` command.
|
||||
- New `--hires` option on `invoke>` line allows <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/CLI.m#this-is-an-example-of-txt2img">larger images to be created without duplicating elements</a>, at the cost of some performance.
|
||||
- Support in both WebGUI and CLI for <a href="https://invoke-ai.github.io/InvokeAI/features/POSTPROCESS/">post-processing of previously-generated images</a>
|
||||
using facial reconstruction, ESRGAN upscaling, outcropping (similar to DALL-E infinite canvas),
|
||||
and "embiggen" upscaling. See the `!fix` command.
|
||||
- New `--hires` option on `invoke>` line allows <a href="https://invoke-ai.github.io/InvokeAI/features/CLI/#txt2img">larger images to be created without duplicating elements</a>, at the cost of some performance.
|
||||
- New `--perlin` and `--threshold` options allow you to add and control variation
|
||||
during image generation (see <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/OTHER.md#thresholding-and-perlin-noise-initialization-options">Thresholding and Perlin Noise Initialization</a>
|
||||
during image generation (see <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/OTHER.md#thresholding-and-perlin-noise-initialization-options">Thresholding and Perlin Noise Initialization</a>
|
||||
- Extensive metadata now written into PNG files, allowing reliable regeneration of images
|
||||
and tweaking of previous settings.
|
||||
and tweaking of previous settings.
|
||||
- Command-line completion in `invoke.py` now works on Windows, Linux and Mac platforms.
|
||||
- Improved <a href="https://github.com/invoke-ai/InvokeAI/blob/main/docs/features/CLI.m">command-line completion behavior</a>.
|
||||
New commands added:
|
||||
* List command-line history with `!history`
|
||||
* Search command-line history with `!search`
|
||||
* Clear history with `!clear`
|
||||
- Improved <a href="https://invoke-ai.github.io/InvokeAI/features/CLI/">command-line completion behavior</a>.
|
||||
New commands added:
|
||||
- List command-line history with `!history`
|
||||
- Search command-line history with `!search`
|
||||
- Clear history with `!clear`
|
||||
- Deprecated `--full_precision` / `-F`. Simply omit it and `invoke.py` will auto
|
||||
configure. To switch away from auto use the new flag like `--precision=float32`.
|
||||
configure. To switch away from auto use the new flag like `--precision=float32`.
|
||||
|
||||
### v1.14 <small>(11 September 2022)</small>
|
||||
|
||||
- Memory optimizations for small-RAM cards. 512x512 now possible on 4 GB GPUs.
|
||||
- Full support for Apple hardware with M1 or M2 chips.
|
||||
- Add "seamless mode" for circular tiling of image. Generates beautiful effects.
|
||||
([prixt](https://github.com/prixt)).
|
||||
- Inpainting support.
|
||||
- Improved web server GUI.
|
||||
- Lots of code and documentation cleanups.
|
||||
|
||||
### v1.13 <small>(3 September 2022</small>
|
||||
|
||||
- Support image variations (see [VARIATIONS](features/VARIATIONS.md)
|
||||
([Kevin Gibbons](https://github.com/bakkot) and many contributors and reviewers)
|
||||
- Supports a Google Colab notebook for a standalone server running on Google hardware
|
||||
[Arturo Mendivil](https://github.com/artmen1516)
|
||||
- WebUI supports GFPGAN/ESRGAN facial reconstruction and upscaling
|
||||
[Kevin Gibbons](https://github.com/bakkot)
|
||||
- WebUI supports incremental display of in-progress images during generation
|
||||
[Kevin Gibbons](https://github.com/bakkot)
|
||||
- A new configuration file scheme that allows new models (including upcoming stable-diffusion-v1.5)
|
||||
to be added without altering the code. ([David Wager](https://github.com/maddavid12))
|
||||
- Can specify --grid on invoke.py command line as the default.
|
||||
- Miscellaneous internal bug and stability fixes.
|
||||
- Works on M1 Apple hardware.
|
||||
- Multiple bug fixes.
|
||||
|
||||
For older changelogs, please visit the **[CHANGELOG](features/CHANGELOG.md)**.
|
||||
For older changelogs, please visit the **[CHANGELOG](CHANGELOG.md#v114-11-september-2022)**.
|
||||
|
||||
## :material-target: Troubleshooting
|
||||
|
||||
@@ -167,9 +162,7 @@ cleanup, testing, or code reviews, is very much encouraged to do so. If you are
|
||||
to contribute to GitHub projects, here is a
|
||||
[Getting Started Guide](https://opensource.com/article/19/7/create-pull-request-github).
|
||||
|
||||
A full set of contribution guidelines, along with templates, are in progress, but for now the most
|
||||
important thing is to **make your pull request against the "development" branch**, and not against
|
||||
"main". This will help keep public breakage to a minimum and will allow you to propose more radical
|
||||
The most important thing is to know about contributing code is to **make your pull request against the "development" branch**, and not against "main". This will help keep public breakage to a minimum and will allow you to propose more radical
|
||||
changes.
|
||||
|
||||
## :octicons-person-24: Contributors
|
||||
@@ -180,10 +173,9 @@ time, hard work and effort.
|
||||
|
||||
## :octicons-question-24: Support
|
||||
|
||||
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.
|
||||
For support, please use this repository's GitHub [Issues tracking service](https://github.com/invoke-ai/InvokeAI/issues). Live support is also available on the [InvokeAI Discord server](https://discord.gg/ZmtBAhwWhy).
|
||||
|
||||
Original portions of the software are Copyright (c) 2020
|
||||
Original portions of the software are Copyright (c) 2022
|
||||
[Lincoln D. Stein](https://github.com/lstein)
|
||||
|
||||
## :octicons-book-24: Further Reading
|
||||
|
||||
@@ -43,6 +43,7 @@ title: Manual Installation, Linux
|
||||
environment named `invokeai` and activate the environment.
|
||||
|
||||
```bash
|
||||
(base) rm -rf src # (this is a precaution in case there is already a src directory)
|
||||
(base) ~/InvokeAI$ conda env create
|
||||
(base) ~/InvokeAI$ conda activate invokeai
|
||||
(invokeai) ~/InvokeAI$
|
||||
@@ -51,50 +52,54 @@ title: Manual Installation, Linux
|
||||
After these steps, your command prompt will be prefixed by `(invokeai)` as shown
|
||||
above.
|
||||
|
||||
6. Load a couple of small machine-learning models required by stable diffusion:
|
||||
6. Load the big stable diffusion weights files and a couple of smaller machine-learning models:
|
||||
|
||||
```bash
|
||||
(invokeai) ~/InvokeAI$ python3 scripts/preload_models.py
|
||||
```
|
||||
|
||||
!!! note
|
||||
This script will lead you through the process of creating an account on Hugging Face,
|
||||
accepting the terms and conditions of the Stable Diffusion model license, and
|
||||
obtaining an access token for downloading. It will then download and install the
|
||||
weights files for you.
|
||||
|
||||
This step is necessary because I modified the original just-in-time
|
||||
model loading scheme to allow the script to work on GPU machines that are not
|
||||
internet connected. See [Preload Models](../features/OTHER.md#preload-models)
|
||||
Please see [../features/INSTALLING_MODELS.md] for a manual process for doing the
|
||||
same thing.
|
||||
|
||||
7. Install the weights for the stable diffusion model.
|
||||
7. Start generating images!
|
||||
|
||||
- Sign up at https://huggingface.co
|
||||
- Go to the [Stable diffusion diffusion model page](https://huggingface.co/CompVis/stable-diffusion-v-1-4-original)
|
||||
- Accept the terms and click Access Repository
|
||||
- Download [v1-5-pruned-emaonly.ckpt (4.27 GB)](https://huggingface.co/runwayml/stable-diffusion-v1-5/blob/main/v1-5-pruned-emaonly.ckpt)
|
||||
and move it into this directory under `models/ldm/stable_diffusion_v1/v1-5-pruned-emaonly.ckpt`
|
||||
# Command-line interface
|
||||
(invokeai) python scripts/invoke.py
|
||||
|
||||
There are many other models that you can use. Please see [../features/INSTALLING_MODELS.md]
|
||||
for details.
|
||||
# or run the web interface on localhost:9090!
|
||||
(invokeai) python scripts/invoke.py --web
|
||||
|
||||
8. Start generating images!
|
||||
# or run the web interface on your machine's network interface!
|
||||
(invokeai) python scripts/invoke.py --web --host 0.0.0.0
|
||||
|
||||
```bash
|
||||
# for the pre-release weights use the -l or --liaon400m switch
|
||||
(invokeai) ~/InvokeAI$ python3 scripts/invoke.py -l
|
||||
To use an alternative model you may invoke the `!switch` command in
|
||||
the CLI, or pass `--model <model_name>` during `invoke.py` launch for
|
||||
either the CLI or the Web UI. See [Command Line
|
||||
Client](../features/CLI.md#model-selection-and-importation). The
|
||||
model names are defined in `configs/models.yaml`.
|
||||
|
||||
# for the post-release weights do not use the switch
|
||||
(invokeai) ~/InvokeAI$ python3 scripts/invoke.py
|
||||
|
||||
# for additional configuration switches and arguments, use -h or --help
|
||||
(invokeai) ~/InvokeAI$ python3 scripts/invoke.py -h
|
||||
```
|
||||
|
||||
9. Subsequently, to relaunch the script, be sure to run "conda activate invokeai" (step 5, second command), enter the `InvokeAI` directory, and then launch the invoke script (step 8). If you forget to activate the 'invokeai' environment, the script will fail with multiple `ModuleNotFound` errors.
|
||||
9. Subsequently, to relaunch the script, be sure to run "conda
|
||||
activate invokeai" (step 5, second command), enter the `InvokeAI`
|
||||
directory, and then launch the invoke script (step 8). If you forget
|
||||
to activate the 'invokeai' environment, the script will fail with
|
||||
multiple `ModuleNotFound` errors.
|
||||
|
||||
## Updating to newer versions of the script
|
||||
|
||||
This distribution is changing rapidly. If you used the `git clone` method (step 5) to download the InvokeAI directory, then to update to the latest and greatest version, launch the Anaconda window, enter `InvokeAI` and type:
|
||||
This distribution is changing rapidly. If you used the `git clone`
|
||||
method (step 5) to download the InvokeAI directory, then to update to
|
||||
the latest and greatest version, launch the Anaconda window, enter
|
||||
`InvokeAI` and type:
|
||||
|
||||
```bash
|
||||
(invokeai) ~/InvokeAI$ git pull
|
||||
(invokeai) ~/InvokeAI$ rm -rf src # prevents conda freezing errors
|
||||
(invokeai) ~/InvokeAI$ conda env update -f environment.yml
|
||||
```
|
||||
|
||||
|
||||
@@ -19,24 +19,9 @@ an issue on Github and we will do our best to help.
|
||||
|
||||
## Installation
|
||||
|
||||
First you need to download a large checkpoint file.
|
||||
|
||||
1. Sign up at https://huggingface.co
|
||||
2. Go to the [Stable diffusion diffusion model page](https://huggingface.co/CompVis/stable-diffusion-v-1-4-original)
|
||||
3. Accept the terms and click Access Repository
|
||||
4. Download [v1-5-pruned-emaonly.ckpt (4.27 GB)](https://huggingface.co/runwayml/stable-diffusion-v1-5/blob/main/v1-5-pruned-emaonly.ckpt)
|
||||
and move it into this directory under `models/ldm/stable_diffusion_v1/v1-5-pruned-emaonly.ckpt`
|
||||
|
||||
There are many other models that you can try. Please see [../features/INSTALLING_MODELS.md]
|
||||
for details.
|
||||
|
||||
While that is downloading, open Terminal and run the following
|
||||
commands one at a time, reading the comments and taking care to run
|
||||
the appropriate command for your Mac's architecture (Intel or M1).
|
||||
|
||||
!!! todo "Homebrew"
|
||||
|
||||
If you have no brew installation yet (otherwise skip):
|
||||
First you will install the "brew" package manager. Skip this if brew is already installed.
|
||||
|
||||
```bash title="install brew (and Xcode command line tools)"
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
@@ -95,30 +80,11 @@ the appropriate command for your Mac's architecture (Intel or M1).
|
||||
|
||||
!!! todo "Clone the Invoke AI repo"
|
||||
|
||||
```bash
|
||||
```bash
|
||||
git clone https://github.com/invoke-ai/InvokeAI.git
|
||||
cd InvokeAI
|
||||
```
|
||||
|
||||
!!! todo "Wait until the checkpoint-file download finished, then proceed"
|
||||
|
||||
We will leave the big checkpoint wherever you stashed it for long-term storage,
|
||||
and make a link to it from the repo's folder. This allows you to use it for
|
||||
other repos, or if you need to delete Invoke AI, you won't have to download it again.
|
||||
|
||||
```{.bash .annotate}
|
||||
# Make the directory in the repo for the symlink
|
||||
mkdir -p models/ldm/stable-diffusion-v1/
|
||||
|
||||
# This is the folder where you put the checkpoint file `sd-v1-4.ckpt`
|
||||
PATH_TO_CKPT="$HOME/Downloads" # (1)!
|
||||
|
||||
# Create a link to the checkpoint
|
||||
ln -s "$PATH_TO_CKPT/sd-v1-4.ckpt" models/ldm/stable-diffusion-v1/model.ckpt
|
||||
```
|
||||
|
||||
1. replace `$HOME/Downloads` with the Location where you actually stored the Checkppoint (`sd-v1-4.ckpt`)
|
||||
|
||||
!!! todo "Create the environment & install packages"
|
||||
|
||||
=== "M1 Mac"
|
||||
@@ -137,25 +103,40 @@ the appropriate command for your Mac's architecture (Intel or M1).
|
||||
# Activate the environment (you need to do this every time you want to run SD)
|
||||
conda activate invokeai
|
||||
|
||||
# This will download some bits and pieces and make take a while
|
||||
(invokeai) python scripts/preload_models.py
|
||||
|
||||
# Run SD!
|
||||
(invokeai) python scripts/dream.py
|
||||
|
||||
# or run the web interface!
|
||||
(invokeai) python scripts/invoke.py --web
|
||||
|
||||
# The original scripts should work as well.
|
||||
(invokeai) python scripts/orig_scripts/txt2img.py \
|
||||
--prompt "a photograph of an astronaut riding a horse" \
|
||||
--plms
|
||||
```
|
||||
!!! info
|
||||
|
||||
`export PIP_EXISTS_ACTION=w` is a precaution to fix `conda env
|
||||
create -f environment-mac.yml` never finishing in some situations. So
|
||||
it isn't required but wont hurt.
|
||||
it isn't required but won't hurt.
|
||||
|
||||
!!! todo "Download the model weight files"
|
||||
|
||||
The `preload_models.py` script downloads and installs the model weight
|
||||
files for you. It will lead you through the process of getting a Hugging Face
|
||||
account, accepting the Stable Diffusion model weight license agreement, and
|
||||
creating a download token:
|
||||
|
||||
# This will take some time, depending on the speed of your internet connection
|
||||
# and will consume about 10GB of space
|
||||
(invokeai) python scripts/preload_models.py
|
||||
|
||||
!! todo "Run InvokeAI!"
|
||||
|
||||
# Command-line interface
|
||||
(invokeai) python scripts/invoke.py
|
||||
|
||||
# or run the web interface on localhost:9090!
|
||||
(invokeai) python scripts/invoke.py --web
|
||||
|
||||
# or run the web interface on your machine's network interface!
|
||||
(invokeai) python scripts/invoke.py --web --host 0.0.0.0
|
||||
|
||||
To use an alternative model you may invoke the `!switch` command in
|
||||
the CLI, or pass `--model <model_name>` during `invoke.py` launch for
|
||||
either the CLI or the Web UI. See [Command Line
|
||||
Client](../features/CLI.md#model-selection-and-importation). The
|
||||
model names are defined in `configs/models.yaml`.
|
||||
|
||||
---
|
||||
|
||||
## Common problems
|
||||
@@ -238,7 +219,7 @@ There are several causes of these errors:
|
||||
conda env remove -n invokeai
|
||||
conda env create -f environment-mac.yml
|
||||
```
|
||||
|
||||
|
||||
4. If you have activated the invokeai virtual environment and tried rebuilding it,
|
||||
maybe the problem could be that I have something installed that you don't and
|
||||
you'll just need to manually install it. Make sure you activate the virtual
|
||||
|
||||
@@ -69,40 +69,42 @@ in the wiki
|
||||
environment file isn't specified, conda will default to `environment.yml`. You will need
|
||||
to provide the `-f` option if you wish to load a different environment file at any point.
|
||||
|
||||
7. Run the command:
|
||||
7. Load the big stable diffusion weights files and a couple of smaller machine-learning models:
|
||||
|
||||
```batch
|
||||
python scripts\preload_models.py
|
||||
```bash
|
||||
(invokeai) ~/InvokeAI$ python3 scripts/preload_models.py
|
||||
```
|
||||
|
||||
This installs several machine learning models that stable diffusion requires.
|
||||
!!! note
|
||||
This script will lead you through the process of creating an account on Hugging Face,
|
||||
accepting the terms and conditions of the Stable Diffusion model license, and
|
||||
obtaining an access token for downloading. It will then download and install the
|
||||
weights files for you.
|
||||
|
||||
Note: This step is required. This was done because some users may might be
|
||||
blocked by firewalls or have limited internet connectivity for the models to
|
||||
be downloaded just-in-time.
|
||||
Please see [../features/INSTALLING_MODELS.md] for a manual process for doing the
|
||||
same thing.
|
||||
|
||||
8. Now you need to install the weights for the big stable diffusion model.
|
||||
8. Start generating images!
|
||||
|
||||
- Sign up at https://huggingface.co
|
||||
- Go to the [Stable diffusion diffusion model page](https://huggingface.co/CompVis/stable-diffusion-v-1-4-original)
|
||||
- Accept the terms and click Access Repository
|
||||
- Download [v1-5-pruned-emaonly.ckpt (4.27 GB)](https://huggingface.co/runwayml/stable-diffusion-v1-5/blob/main/v1-5-pruned-emaonly.ckpt)
|
||||
and move it into this directory under `models/ldm/stable_diffusion_v1/v1-5-pruned-emaonly.ckpt`
|
||||
# Command-line interface
|
||||
(invokeai) python scripts/invoke.py
|
||||
|
||||
There are many other models that you can use. Please see [../features/INSTALLING_MODELS.md]
|
||||
for details.
|
||||
# or run the web interface on localhost:9090!
|
||||
(invokeai) python scripts/invoke.py --web
|
||||
|
||||
9. Start generating images!
|
||||
# or run the web interface on your machine's network interface!
|
||||
(invokeai) python scripts/invoke.py --web --host 0.0.0.0
|
||||
|
||||
```batch title="for the pre-release weights"
|
||||
python scripts\invoke.py -l
|
||||
```
|
||||
To use an alternative model you may invoke the `!switch` command in
|
||||
the CLI, or pass `--model <model_name>` during `invoke.py` launch for
|
||||
either the CLI or the Web UI. See [Command Line
|
||||
Client](../features/CLI.md#model-selection-and-importation). The
|
||||
model names are defined in `configs/models.yaml`.
|
||||
|
||||
```batch title="for the post-release weights"
|
||||
python scripts\invoke.py
|
||||
```
|
||||
|
||||
10. Subsequently, to relaunch the script, first activate the Anaconda command window (step 3),enter the InvokeAI directory (step 5, `cd \path\to\InvokeAI`), run `conda activate invokeai` (step 6b), and then launch the invoke script (step 9).
|
||||
9. Subsequently, to relaunch the script, first activate the Anaconda
|
||||
command window (step 3),enter the InvokeAI directory (step 5, `cd
|
||||
\path\to\InvokeAI`), run `conda activate invokeai` (step 6b), and then
|
||||
launch the invoke script (step 9).
|
||||
|
||||
!!! tip "Tildebyte has written an alternative"
|
||||
|
||||
|
||||
@@ -59,6 +59,8 @@ We thank them for all of their time and hard work.
|
||||
- [Dominic Letz](https://github.com/dominicletz)
|
||||
- [Dmitry T.](https://github.com/ArDiouscuros)
|
||||
- [Kent Keirsey](https://github.com/hipsterusername)
|
||||
- [psychedelicious](https://github.com/psychedelicious)
|
||||
- [damian0815](https://github.com/damian0815)
|
||||
|
||||
## **Original CompVis Authors:**
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ dependencies:
|
||||
- numpy=1.19
|
||||
- imageio=2.9.0
|
||||
- opencv=4.6.0
|
||||
- getpass_asterisk
|
||||
- pillow=8.*
|
||||
- flask=2.1.*
|
||||
- flask_cors=3.0.10
|
||||
|
||||
@@ -51,6 +51,7 @@ dependencies:
|
||||
- transformers=4.23.1
|
||||
- torch-fidelity=0.3.0
|
||||
- pip:
|
||||
- getpass_asterisk
|
||||
- dependency_injector==4.40.0
|
||||
- realesrgan==0.2.5.0
|
||||
- test-tube==0.7.5
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
name: invokeai
|
||||
channels:
|
||||
- pytorch
|
||||
- nvidia
|
||||
- defaults
|
||||
dependencies:
|
||||
- python>=3.9
|
||||
- pip=20.3
|
||||
- cudatoolkit=11.3
|
||||
- pytorch=1.11.0
|
||||
- torchvision=0.12.0
|
||||
- numpy=1.19.2
|
||||
- pip=22.2.2
|
||||
- numpy=1.23.3
|
||||
- torchvision=0.14.0
|
||||
- pytorch-cuda=11.7
|
||||
- pip:
|
||||
- albumentations==0.4.3
|
||||
- opencv-python==4.5.5.64
|
||||
@@ -33,6 +33,7 @@ dependencies:
|
||||
- flask_cors==3.0.10
|
||||
- dependency_injector==4.40.0
|
||||
- eventlet
|
||||
- getpass_asterisk
|
||||
- kornia==0.6.0
|
||||
- -e git+https://github.com/openai/CLIP.git@main#egg=clip
|
||||
- -e git+https://github.com/CompVis/taming-transformers.git@master#egg=taming-transformers
|
||||
|
||||
501
frontend/dist/assets/index.1fc0290b.js
vendored
Normal file
1
frontend/dist/assets/index.352e4760.css
vendored
1
frontend/dist/assets/index.40a72c80.css
vendored
Normal file
829
frontend/dist/assets/index.4488003f.js
vendored
Normal file
517
frontend/dist/assets/index.64b87783.js
vendored
690
frontend/dist/assets/index.ae92a637.js
vendored
Normal file
517
frontend/dist/assets/index.cc049b93.js
vendored
Normal file
517
frontend/dist/assets/index.e2832fd4.js
vendored
Normal file
4
frontend/dist/index.html
vendored
@@ -6,8 +6,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.64b87783.js"></script>
|
||||
<link rel="stylesheet" href="./assets/index.352e4760.css">
|
||||
<script type="module" crossorigin src="./assets/index.1fc0290b.js"></script>
|
||||
<link rel="stylesheet" href="./assets/index.40a72c80.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
10651
frontend/package-lock.json
generated
Normal file
@@ -9,13 +9,9 @@
|
||||
|
||||
.app-content {
|
||||
display: grid;
|
||||
row-gap: 0.5rem;
|
||||
row-gap: 1rem;
|
||||
padding: $app-padding;
|
||||
grid-auto-rows: max-content;
|
||||
grid-auto-rows: min-content auto;
|
||||
width: $app-width;
|
||||
height: $app-height;
|
||||
}
|
||||
|
||||
.app-console {
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
@@ -1,27 +1,91 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import ProgressBar from '../features/system/ProgressBar';
|
||||
import SiteHeader from '../features/system/SiteHeader';
|
||||
import Console from '../features/system/Console';
|
||||
import Loading from '../Loading';
|
||||
import { useAppDispatch } from './store';
|
||||
import { requestSystemConfig } from './socketio/actions';
|
||||
import { keepGUIAlive } from './utils';
|
||||
import InvokeTabs from '../features/tabs/InvokeTabs';
|
||||
import ImageUploader from '../common/components/ImageUploader';
|
||||
import { RootState, useAppSelector } from '../app/store';
|
||||
|
||||
import FloatingGalleryButton from '../features/tabs/FloatingGalleryButton';
|
||||
import FloatingOptionsPanelButtons from '../features/tabs/FloatingOptionsPanelButtons';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { GalleryState } from '../features/gallery/gallerySlice';
|
||||
import { OptionsState } from '../features/options/optionsSlice';
|
||||
import { activeTabNameSelector } from '../features/options/optionsSelectors';
|
||||
import { SystemState } from '../features/system/systemSlice';
|
||||
import _ from 'lodash';
|
||||
import { Model } from './invokeai';
|
||||
|
||||
keepGUIAlive();
|
||||
|
||||
const appSelector = createSelector(
|
||||
[
|
||||
(state: RootState) => state.gallery,
|
||||
(state: RootState) => state.options,
|
||||
(state: RootState) => state.system,
|
||||
activeTabNameSelector,
|
||||
],
|
||||
(
|
||||
gallery: GalleryState,
|
||||
options: OptionsState,
|
||||
system: SystemState,
|
||||
activeTabName
|
||||
) => {
|
||||
const { shouldShowGallery, shouldHoldGalleryOpen, shouldPinGallery } =
|
||||
gallery;
|
||||
const {
|
||||
shouldShowOptionsPanel,
|
||||
shouldHoldOptionsPanelOpen,
|
||||
shouldPinOptionsPanel,
|
||||
} = options;
|
||||
|
||||
const modelStatusText = _.reduce(
|
||||
system.model_list,
|
||||
(acc: string, cur: Model, key: string) => {
|
||||
if (cur.status === 'active') acc = key;
|
||||
return acc;
|
||||
},
|
||||
''
|
||||
);
|
||||
|
||||
const shouldShowGalleryButton = !(
|
||||
shouldShowGallery ||
|
||||
(shouldHoldGalleryOpen && !shouldPinGallery)
|
||||
);
|
||||
|
||||
const shouldShowOptionsPanelButton =
|
||||
!(
|
||||
shouldShowOptionsPanel ||
|
||||
(shouldHoldOptionsPanelOpen && !shouldPinOptionsPanel)
|
||||
) && ['txt2img', 'img2img', 'inpainting'].includes(activeTabName);
|
||||
|
||||
return {
|
||||
modelStatusText,
|
||||
shouldShowGalleryButton,
|
||||
shouldShowOptionsPanelButton,
|
||||
};
|
||||
},
|
||||
{
|
||||
memoizeOptions: {
|
||||
resultEqualityCheck: _.isEqual,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const App = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const [isReady, setIsReady] = useState<boolean>(false);
|
||||
const { shouldShowGalleryButton, shouldShowOptionsPanelButton } =
|
||||
useAppSelector(appSelector);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(requestSystemConfig());
|
||||
setIsReady(true);
|
||||
}, [dispatch]);
|
||||
|
||||
return isReady ? (
|
||||
return (
|
||||
<div className="App">
|
||||
<ImageUploader>
|
||||
<ProgressBar />
|
||||
@@ -32,10 +96,10 @@ const App = () => {
|
||||
<div className="app-console">
|
||||
<Console />
|
||||
</div>
|
||||
{shouldShowGalleryButton && <FloatingGalleryButton />}
|
||||
{shouldShowOptionsPanelButton && <FloatingOptionsPanelButtons />}
|
||||
</ImageUploader>
|
||||
</div>
|
||||
) : (
|
||||
<Loading />
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// TODO: use Enums?
|
||||
|
||||
import { InProgressImageType } from '../features/system/systemSlice';
|
||||
|
||||
// Valid samplers
|
||||
export const SAMPLERS: Array<string> = [
|
||||
'ddim',
|
||||
@@ -37,3 +39,12 @@ export const NUMPY_RAND_MIN = 0;
|
||||
export const NUMPY_RAND_MAX = 4294967295;
|
||||
|
||||
export const FACETOOL_TYPES = ['gfpgan', 'codeformer'] as const;
|
||||
|
||||
export const IN_PROGRESS_IMAGE_TYPES: Array<{
|
||||
key: string;
|
||||
value: InProgressImageType;
|
||||
}> = [
|
||||
{ key: 'None', value: 'none' },
|
||||
{ key: 'Fast', value: 'latents' },
|
||||
{ key: 'Accurate', value: 'full-res' },
|
||||
];
|
||||
|
||||
3
frontend/src/app/invokeai.d.ts
vendored
@@ -115,7 +115,8 @@ export declare type Image = {
|
||||
metadata?: Metadata;
|
||||
width: number;
|
||||
height: number;
|
||||
category: GalleryCategory;
|
||||
category: GalleryCategory;
|
||||
isBase64: boolean;
|
||||
};
|
||||
|
||||
// GalleryImages is an array of Image.
|
||||
|
||||
96
frontend/src/app/selectors/readinessSelector.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import _ from 'lodash';
|
||||
import { RootState } from '../store';
|
||||
import { activeTabNameSelector } from '../../features/options/optionsSelectors';
|
||||
import { OptionsState } from '../../features/options/optionsSlice';
|
||||
|
||||
import { SystemState } from '../../features/system/systemSlice';
|
||||
import { InpaintingState } from '../../features/tabs/Inpainting/inpaintingSlice';
|
||||
import { validateSeedWeights } from '../../common/util/seedWeightPairs';
|
||||
|
||||
export const readinessSelector = createSelector(
|
||||
[
|
||||
(state: RootState) => state.options,
|
||||
(state: RootState) => state.system,
|
||||
(state: RootState) => state.inpainting,
|
||||
activeTabNameSelector,
|
||||
],
|
||||
(
|
||||
options: OptionsState,
|
||||
system: SystemState,
|
||||
inpainting: InpaintingState,
|
||||
activeTabName
|
||||
) => {
|
||||
const {
|
||||
prompt,
|
||||
shouldGenerateVariations,
|
||||
seedWeights,
|
||||
// maskPath,
|
||||
initialImage,
|
||||
seed,
|
||||
} = options;
|
||||
|
||||
const { isProcessing, isConnected } = system;
|
||||
|
||||
const { imageToInpaint } = inpainting;
|
||||
|
||||
let isReady = true;
|
||||
const reasonsWhyNotReady: string[] = [];
|
||||
|
||||
// Cannot generate without a prompt
|
||||
if (!prompt || Boolean(prompt.match(/^[\s\r\n]+$/))) {
|
||||
isReady = false;
|
||||
reasonsWhyNotReady.push('Missing prompt');
|
||||
}
|
||||
|
||||
if (activeTabName === 'img2img' && !initialImage) {
|
||||
isReady = false;
|
||||
reasonsWhyNotReady.push('No initial image selected');
|
||||
}
|
||||
|
||||
if (activeTabName === 'inpainting' && !imageToInpaint) {
|
||||
isReady = false;
|
||||
reasonsWhyNotReady.push('No inpainting image selected');
|
||||
}
|
||||
|
||||
// // We don't use mask paths now.
|
||||
// // Cannot generate with a mask without img2img
|
||||
// if (maskPath && !initialImage) {
|
||||
// isReady = false;
|
||||
// reasonsWhyNotReady.push(
|
||||
// 'On ImageToImage tab, but no mask is provided.'
|
||||
// );
|
||||
// }
|
||||
|
||||
// TODO: job queue
|
||||
// Cannot generate if already processing an image
|
||||
if (isProcessing) {
|
||||
isReady = false;
|
||||
reasonsWhyNotReady.push('System Busy');
|
||||
}
|
||||
|
||||
// Cannot generate if not connected
|
||||
if (!isConnected) {
|
||||
isReady = false;
|
||||
reasonsWhyNotReady.push('System Disconnected');
|
||||
}
|
||||
|
||||
// Cannot generate variations without valid seed weights
|
||||
if (
|
||||
shouldGenerateVariations &&
|
||||
(!(validateSeedWeights(seedWeights) || seedWeights === '') || seed === -1)
|
||||
) {
|
||||
isReady = false;
|
||||
reasonsWhyNotReady.push('Seed-Weights badly formatted.');
|
||||
}
|
||||
|
||||
// All good
|
||||
return { isReady, reasonsWhyNotReady };
|
||||
},
|
||||
{
|
||||
memoizeOptions: {
|
||||
equalityCheck: _.isEqual,
|
||||
resultEqualityCheck: _.isEqual,
|
||||
},
|
||||
}
|
||||
);
|
||||
@@ -8,13 +8,13 @@ import {
|
||||
import {
|
||||
GalleryCategory,
|
||||
GalleryState,
|
||||
removeImage,
|
||||
} from '../../features/gallery/gallerySlice';
|
||||
import { OptionsState } from '../../features/options/optionsSlice';
|
||||
import {
|
||||
addLogEntry,
|
||||
errorOccurred,
|
||||
setCurrentStatus,
|
||||
setIsCancelable,
|
||||
modelChangeRequested,
|
||||
setIsProcessing,
|
||||
} from '../../features/system/systemSlice';
|
||||
import { inpaintingImageElementRef } from '../../features/tabs/Inpainting/InpaintingCanvas';
|
||||
@@ -163,6 +163,7 @@ const makeSocketIOEmitters = (
|
||||
},
|
||||
emitDeleteImage: (imageToDelete: InvokeAI.Image) => {
|
||||
const { url, uuid, category } = imageToDelete;
|
||||
dispatch(removeImage(imageToDelete));
|
||||
socketio.emit('deleteImage', url, uuid, category);
|
||||
},
|
||||
emitRequestImages: (category: GalleryCategory) => {
|
||||
@@ -189,9 +190,7 @@ const makeSocketIOEmitters = (
|
||||
socketio.emit('requestSystemConfig');
|
||||
},
|
||||
emitRequestModelChange: (modelName: string) => {
|
||||
dispatch(setCurrentStatus('Changing Model'));
|
||||
dispatch(setIsProcessing(true));
|
||||
dispatch(setIsCancelable(false));
|
||||
dispatch(modelChangeRequested());
|
||||
socketio.emit('requestModelChange', modelName);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -33,7 +33,11 @@ import {
|
||||
setMaskPath,
|
||||
} from '../../features/options/optionsSlice';
|
||||
import { requestImages, requestNewImages } from './actions';
|
||||
import { clearImageToInpaint, setImageToInpaint } from '../../features/tabs/Inpainting/inpaintingSlice';
|
||||
import {
|
||||
clearImageToInpaint,
|
||||
setImageToInpaint,
|
||||
} from '../../features/tabs/Inpainting/inpaintingSlice';
|
||||
import { tabMap } from '../../features/tabs/InvokeTabs';
|
||||
|
||||
/**
|
||||
* Returns an object containing listener callbacks for socketio events.
|
||||
@@ -93,15 +97,34 @@ const makeSocketIOListeners = (
|
||||
*/
|
||||
onGenerationResult: (data: InvokeAI.ImageResultResponse) => {
|
||||
try {
|
||||
const { shouldLoopback, activeTab } = getState().options;
|
||||
const newImage = {
|
||||
uuid: uuidv4(),
|
||||
...data,
|
||||
category: 'result',
|
||||
};
|
||||
|
||||
dispatch(
|
||||
addImage({
|
||||
category: 'result',
|
||||
image: {
|
||||
uuid: uuidv4(),
|
||||
...data,
|
||||
},
|
||||
image: newImage,
|
||||
})
|
||||
);
|
||||
|
||||
if (shouldLoopback) {
|
||||
const activeTabName = tabMap[activeTab];
|
||||
switch (activeTabName) {
|
||||
case 'img2img': {
|
||||
dispatch(setInitialImage(newImage));
|
||||
break;
|
||||
}
|
||||
case 'inpainting': {
|
||||
dispatch(setImageToInpaint(newImage));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dispatch(
|
||||
addLogEntry({
|
||||
timestamp: dateFormat(new Date(), 'isoDateTime'),
|
||||
@@ -123,12 +146,14 @@ const makeSocketIOListeners = (
|
||||
...data,
|
||||
})
|
||||
);
|
||||
dispatch(
|
||||
addLogEntry({
|
||||
timestamp: dateFormat(new Date(), 'isoDateTime'),
|
||||
message: `Intermediate image generated: ${data.url}`,
|
||||
})
|
||||
);
|
||||
if (!data.isBase64) {
|
||||
dispatch(
|
||||
addLogEntry({
|
||||
timestamp: dateFormat(new Date(), 'isoDateTime'),
|
||||
message: `Intermediate image generated: ${data.url}`,
|
||||
})
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
@@ -144,6 +169,7 @@ const makeSocketIOListeners = (
|
||||
image: {
|
||||
uuid: uuidv4(),
|
||||
...data,
|
||||
category: 'result',
|
||||
},
|
||||
})
|
||||
);
|
||||
@@ -237,18 +263,20 @@ const makeSocketIOListeners = (
|
||||
const { intermediateImage } = getState().gallery;
|
||||
|
||||
if (intermediateImage) {
|
||||
dispatch(
|
||||
addImage({
|
||||
category: 'result',
|
||||
image: intermediateImage,
|
||||
})
|
||||
);
|
||||
dispatch(
|
||||
addLogEntry({
|
||||
timestamp: dateFormat(new Date(), 'isoDateTime'),
|
||||
message: `Intermediate image saved: ${intermediateImage.url}`,
|
||||
})
|
||||
);
|
||||
if (!intermediateImage.isBase64) {
|
||||
dispatch(
|
||||
addImage({
|
||||
category: 'result',
|
||||
image: intermediateImage,
|
||||
})
|
||||
);
|
||||
dispatch(
|
||||
addLogEntry({
|
||||
timestamp: dateFormat(new Date(), 'isoDateTime'),
|
||||
message: `Intermediate image saved: ${intermediateImage.url}`,
|
||||
})
|
||||
);
|
||||
}
|
||||
dispatch(clearIntermediateImage());
|
||||
}
|
||||
|
||||
@@ -264,7 +292,7 @@ const makeSocketIOListeners = (
|
||||
* Callback to run when we receive a 'imageDeleted' event.
|
||||
*/
|
||||
onImageDeleted: (data: InvokeAI.ImageDeletedResponse) => {
|
||||
const { url, uuid, category } = data;
|
||||
const { url } = data;
|
||||
|
||||
// remove image from gallery
|
||||
dispatch(removeImage(data));
|
||||
@@ -348,7 +376,7 @@ const makeSocketIOListeners = (
|
||||
dispatch(setModelList(model_list));
|
||||
dispatch(setCurrentStatus('Model Changed'));
|
||||
dispatch(setIsProcessing(false));
|
||||
dispatch(setIsCancelable(false));
|
||||
dispatch(setIsCancelable(true));
|
||||
dispatch(
|
||||
addLogEntry({
|
||||
timestamp: dateFormat(new Date(), 'isoDateTime'),
|
||||
@@ -361,7 +389,7 @@ const makeSocketIOListeners = (
|
||||
const { model_name, model_list } = data;
|
||||
dispatch(setModelList(model_list));
|
||||
dispatch(setIsProcessing(false));
|
||||
dispatch(setIsCancelable(false));
|
||||
dispatch(setIsCancelable(true));
|
||||
dispatch(errorOccurred());
|
||||
dispatch(
|
||||
addLogEntry({
|
||||
|
||||
@@ -5,12 +5,16 @@ import type { TypedUseSelectorHook } from 'react-redux';
|
||||
import { persistReducer } from 'redux-persist';
|
||||
import storage from 'redux-persist/lib/storage'; // defaults to localStorage for web
|
||||
|
||||
import optionsReducer from '../features/options/optionsSlice';
|
||||
import galleryReducer from '../features/gallery/gallerySlice';
|
||||
import inpaintingReducer from '../features/tabs/Inpainting/inpaintingSlice';
|
||||
import optionsReducer, { OptionsState } from '../features/options/optionsSlice';
|
||||
import galleryReducer, { GalleryState } from '../features/gallery/gallerySlice';
|
||||
import inpaintingReducer, {
|
||||
InpaintingState,
|
||||
} from '../features/tabs/Inpainting/inpaintingSlice';
|
||||
|
||||
import systemReducer from '../features/system/systemSlice';
|
||||
import systemReducer, { SystemState } from '../features/system/systemSlice';
|
||||
import { socketioMiddleware } from './socketio/middleware';
|
||||
import autoMergeLevel2 from 'redux-persist/es/stateReconciler/autoMergeLevel2';
|
||||
import { PersistPartial } from 'redux-persist/es/persistReducer';
|
||||
|
||||
/**
|
||||
* redux-persist provides an easy and reliable way to persist state across reloads.
|
||||
@@ -33,12 +37,14 @@ import { socketioMiddleware } from './socketio/middleware';
|
||||
const rootPersistConfig = {
|
||||
key: 'root',
|
||||
storage,
|
||||
stateReconciler: autoMergeLevel2,
|
||||
blacklist: ['gallery', 'system', 'inpainting'],
|
||||
};
|
||||
|
||||
const systemPersistConfig = {
|
||||
key: 'system',
|
||||
storage,
|
||||
stateReconciler: autoMergeLevel2,
|
||||
blacklist: [
|
||||
'isCancelable',
|
||||
'isConnected',
|
||||
@@ -58,6 +64,7 @@ const systemPersistConfig = {
|
||||
const galleryPersistConfig = {
|
||||
key: 'gallery',
|
||||
storage,
|
||||
stateReconciler: autoMergeLevel2,
|
||||
whitelist: [
|
||||
'galleryWidth',
|
||||
'shouldPinGallery',
|
||||
@@ -71,17 +78,26 @@ const galleryPersistConfig = {
|
||||
const inpaintingPersistConfig = {
|
||||
key: 'inpainting',
|
||||
storage,
|
||||
stateReconciler: autoMergeLevel2,
|
||||
blacklist: ['pastLines', 'futuresLines', 'cursorPosition'],
|
||||
};
|
||||
|
||||
const reducers = combineReducers({
|
||||
options: optionsReducer,
|
||||
gallery: persistReducer(galleryPersistConfig, galleryReducer),
|
||||
system: persistReducer(systemPersistConfig, systemReducer),
|
||||
inpainting: persistReducer(inpaintingPersistConfig, inpaintingReducer),
|
||||
gallery: persistReducer<GalleryState>(galleryPersistConfig, galleryReducer),
|
||||
system: persistReducer<SystemState>(systemPersistConfig, systemReducer),
|
||||
inpainting: persistReducer<InpaintingState>(
|
||||
inpaintingPersistConfig,
|
||||
inpaintingReducer
|
||||
),
|
||||
});
|
||||
|
||||
const persistedReducer = persistReducer(rootPersistConfig, reducers);
|
||||
const persistedReducer = persistReducer<{
|
||||
options: OptionsState;
|
||||
gallery: GalleryState & PersistPartial;
|
||||
system: SystemState & PersistPartial;
|
||||
inpainting: InpaintingState & PersistPartial;
|
||||
}>(rootPersistConfig, reducers);
|
||||
|
||||
// Continue with store setup
|
||||
export const store = configureStore({
|
||||
|
||||
3
frontend/src/common/components/IAIButton.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
.invokeai__button {
|
||||
justify-content: space-between;
|
||||
}
|
||||
@@ -1,24 +1,32 @@
|
||||
import { Button, ButtonProps, Tooltip } from '@chakra-ui/react';
|
||||
import {
|
||||
Button,
|
||||
ButtonProps,
|
||||
forwardRef,
|
||||
Tooltip,
|
||||
TooltipProps,
|
||||
} from '@chakra-ui/react';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
interface Props extends ButtonProps {
|
||||
label: string;
|
||||
export interface IAIButtonProps extends ButtonProps {
|
||||
tooltip?: string;
|
||||
tooltipProps?: Omit<TooltipProps, 'children'>;
|
||||
styleClass?: string;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reusable customized button component. Originally was more customized - now probably unecessary.
|
||||
*
|
||||
* TODO: Get rid of this.
|
||||
*/
|
||||
const IAIButton = (props: Props) => {
|
||||
const { label, tooltip = '', size = 'sm', ...rest } = props;
|
||||
const IAIButton = forwardRef((props: IAIButtonProps, forwardedRef) => {
|
||||
const { children, tooltip = '', tooltipProps, styleClass, ...rest } = props;
|
||||
return (
|
||||
<Tooltip label={tooltip}>
|
||||
<Button size={size} {...rest}>
|
||||
{label}
|
||||
<Tooltip label={tooltip} {...tooltipProps}>
|
||||
<Button
|
||||
ref={forwardedRef}
|
||||
className={['invokeai__button', styleClass].join(' ')}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default IAIButton;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@use '../../styles/Mixins/' as *;
|
||||
|
||||
.icon-button {
|
||||
.invokeai__icon-button {
|
||||
background-color: var(--btn-grey);
|
||||
cursor: pointer;
|
||||
|
||||
@@ -8,13 +8,68 @@
|
||||
background-color: var(--btn-grey-hover);
|
||||
}
|
||||
|
||||
&[data-selected=true] {
|
||||
&[data-selected='true'] {
|
||||
background-color: var(--accent-color);
|
||||
&:hover {
|
||||
background-color: var(--accent-color-hover);
|
||||
}
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&[data-variant='link'] {
|
||||
background: none !important;
|
||||
&:hover {
|
||||
background: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
&[data-selected='true'] {
|
||||
border-color: var(--accent-color);
|
||||
&:hover {
|
||||
border-color: var(--accent-color-hover);
|
||||
}
|
||||
}
|
||||
|
||||
&[data-alert='true'] {
|
||||
animation-name: pulseColor;
|
||||
animation-duration: 1s;
|
||||
animation-timing-function: ease-in-out;
|
||||
animation-iteration-count: infinite;
|
||||
&:hover {
|
||||
animation: none;
|
||||
background-color: var(--accent-color-hover);
|
||||
}
|
||||
}
|
||||
|
||||
&[data-as-checkbox='true'] {
|
||||
background-color: var(--btn-grey);
|
||||
border: 3px solid var(--btn-grey);
|
||||
|
||||
svg {
|
||||
fill: var(--text-color);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--btn-grey);
|
||||
border-color: var(--btn-checkbox-border-hover);
|
||||
svg {
|
||||
fill: var(--text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pulseColor {
|
||||
0% {
|
||||
background-color: var(--accent-color);
|
||||
}
|
||||
50% {
|
||||
background-color: var(--accent-color-dim);
|
||||
}
|
||||
100% {
|
||||
background-color: var(--accent-color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,38 +2,40 @@ import {
|
||||
IconButtonProps,
|
||||
IconButton,
|
||||
Tooltip,
|
||||
PlacementWithLogical,
|
||||
TooltipProps,
|
||||
forwardRef,
|
||||
} from '@chakra-ui/react';
|
||||
|
||||
interface Props extends IconButtonProps {
|
||||
tooltip?: string;
|
||||
tooltipPlacement?: PlacementWithLogical | undefined;
|
||||
export type IAIIconButtonProps = IconButtonProps & {
|
||||
styleClass?: string;
|
||||
}
|
||||
tooltip?: string;
|
||||
tooltipProps?: Omit<TooltipProps, 'children'>;
|
||||
asCheckbox?: boolean;
|
||||
isChecked?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reusable customized button component. Originally was more customized - now probably unecessary.
|
||||
*/
|
||||
const IAIIconButton = (props: Props) => {
|
||||
const IAIIconButton = forwardRef((props: IAIIconButtonProps, forwardedRef) => {
|
||||
const {
|
||||
tooltip = '',
|
||||
tooltipPlacement = 'bottom',
|
||||
styleClass,
|
||||
onClick,
|
||||
cursor,
|
||||
tooltipProps,
|
||||
asCheckbox,
|
||||
isChecked,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Tooltip label={tooltip} hasArrow placement={tooltipPlacement}>
|
||||
<Tooltip label={tooltip} hasArrow {...tooltipProps}>
|
||||
<IconButton
|
||||
className={`icon-button ${styleClass}`}
|
||||
ref={forwardedRef}
|
||||
className={`invokeai__icon-button ${styleClass}`}
|
||||
data-as-checkbox={asCheckbox}
|
||||
data-selected={isChecked !== undefined ? isChecked : undefined}
|
||||
style={props.onClick ? { cursor: 'pointer' } : {}}
|
||||
{...rest}
|
||||
cursor={cursor ? cursor : onClick ? 'pointer' : 'unset'}
|
||||
onClick={onClick}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default IAIIconButton;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
.invokeai__number-input-form-control {
|
||||
display: grid;
|
||||
grid-template-columns: max-content auto;
|
||||
column-gap: 1rem;
|
||||
align-items: center;
|
||||
|
||||
.invokeai__number-input-form-label {
|
||||
@@ -11,6 +10,7 @@
|
||||
margin-bottom: 0;
|
||||
flex-grow: 2;
|
||||
white-space: nowrap;
|
||||
padding-right: 1rem;
|
||||
|
||||
&[data-focus] + .invokeai__number-input-root {
|
||||
outline: none;
|
||||
|
||||
@@ -123,13 +123,15 @@ const IAINumberInput = (props: Props) => {
|
||||
}
|
||||
{...formControlProps}
|
||||
>
|
||||
<FormLabel
|
||||
className="invokeai__number-input-form-label"
|
||||
style={{ display: label ? 'block' : 'none' }}
|
||||
{...formLabelProps}
|
||||
>
|
||||
{label}
|
||||
</FormLabel>
|
||||
{label && (
|
||||
<FormLabel
|
||||
className="invokeai__number-input-form-label"
|
||||
style={{ display: label ? 'block' : 'none' }}
|
||||
{...formLabelProps}
|
||||
>
|
||||
{label}
|
||||
</FormLabel>
|
||||
)}
|
||||
<NumberInput
|
||||
className="invokeai__number-input-root"
|
||||
value={valueAsString}
|
||||
@@ -145,19 +147,18 @@ const IAINumberInput = (props: Props) => {
|
||||
textAlign={textAlign}
|
||||
{...numberInputFieldProps}
|
||||
/>
|
||||
<div
|
||||
className="invokeai__number-input-stepper"
|
||||
style={showStepper ? { display: 'block' } : { display: 'none' }}
|
||||
>
|
||||
<NumberIncrementStepper
|
||||
{...numberInputStepperProps}
|
||||
className="invokeai__number-input-stepper-button"
|
||||
/>
|
||||
<NumberDecrementStepper
|
||||
{...numberInputStepperProps}
|
||||
className="invokeai__number-input-stepper-button"
|
||||
/>
|
||||
</div>
|
||||
{showStepper && (
|
||||
<div className="invokeai__number-input-stepper">
|
||||
<NumberIncrementStepper
|
||||
{...numberInputStepperProps}
|
||||
className="invokeai__number-input-stepper-button"
|
||||
/>
|
||||
<NumberDecrementStepper
|
||||
{...numberInputStepperProps}
|
||||
className="invokeai__number-input-stepper-button"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</NumberInput>
|
||||
</FormControl>
|
||||
</Tooltip>
|
||||
|
||||
@@ -3,13 +3,14 @@ import {
|
||||
PopoverArrow,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
Box,
|
||||
BoxProps,
|
||||
} from '@chakra-ui/react';
|
||||
import { PopoverProps } from '@chakra-ui/react';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
type IAIPopoverProps = PopoverProps & {
|
||||
triggerComponent: ReactNode;
|
||||
triggerContainerProps?: BoxProps;
|
||||
children: ReactNode;
|
||||
styleClass?: string;
|
||||
hasArrow?: boolean;
|
||||
@@ -23,11 +24,10 @@ const IAIPopover = (props: IAIPopoverProps) => {
|
||||
hasArrow = true,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Popover {...rest}>
|
||||
<PopoverTrigger>
|
||||
<Box>{triggerComponent}</Box>
|
||||
</PopoverTrigger>
|
||||
<PopoverTrigger>{triggerComponent}</PopoverTrigger>
|
||||
<PopoverContent className={`invokeai__popover-content ${styleClass}`}>
|
||||
{hasArrow && <PopoverArrow className={'invokeai__popover-arrow'} />}
|
||||
{children}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
@use '../../styles/Mixins/' as *;
|
||||
|
||||
.invokeai__select {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, max-content);
|
||||
display: flex;
|
||||
column-gap: 1rem;
|
||||
align-items: center;
|
||||
width: max-content;
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import { FormControl, FormLabel, Select, SelectProps } from '@chakra-ui/react';
|
||||
import { MouseEvent } from 'react';
|
||||
|
||||
interface Props extends SelectProps {
|
||||
type IAISelectProps = SelectProps & {
|
||||
label: string;
|
||||
styleClass?: string;
|
||||
validValues:
|
||||
| Array<number | string>
|
||||
| Array<{ key: string; value: string | number }>;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Customized Chakra FormControl + Select multi-part component.
|
||||
*/
|
||||
const IAISelect = (props: Props) => {
|
||||
const IAISelect = (props: IAISelectProps) => {
|
||||
const {
|
||||
label,
|
||||
isDisabled,
|
||||
@@ -21,21 +22,30 @@ const IAISelect = (props: Props) => {
|
||||
...rest
|
||||
} = props;
|
||||
return (
|
||||
<FormControl isDisabled={isDisabled} className={`invokeai__select ${styleClass}`}>
|
||||
<FormControl
|
||||
isDisabled={isDisabled}
|
||||
className={`invokeai__select ${styleClass}`}
|
||||
onClick={(e: MouseEvent<HTMLDivElement>) => {
|
||||
e.stopPropagation();
|
||||
e.nativeEvent.stopImmediatePropagation();
|
||||
e.nativeEvent.stopPropagation();
|
||||
e.nativeEvent.cancelBubble = true;
|
||||
}}
|
||||
>
|
||||
<FormLabel
|
||||
className="invokeai__select-label"
|
||||
fontSize={fontSize}
|
||||
marginBottom={1}
|
||||
flexGrow={2}
|
||||
whiteSpace="nowrap"
|
||||
className="invokeai__select-label"
|
||||
>
|
||||
{label}
|
||||
</FormLabel>
|
||||
<Select
|
||||
className="invokeai__select-picker"
|
||||
fontSize={fontSize}
|
||||
size={size}
|
||||
{...rest}
|
||||
className="invokeai__select-picker"
|
||||
>
|
||||
{validValues.map((opt) => {
|
||||
return typeof opt === 'string' || typeof opt === 'number' ? (
|
||||
@@ -43,7 +53,11 @@ const IAISelect = (props: Props) => {
|
||||
{opt}
|
||||
</option>
|
||||
) : (
|
||||
<option key={opt.value} value={opt.value}>
|
||||
<option
|
||||
key={opt.value}
|
||||
value={opt.value}
|
||||
className="invokeai__select-option"
|
||||
>
|
||||
{opt.key}
|
||||
</option>
|
||||
);
|
||||
|
||||
@@ -22,8 +22,6 @@ const IAISwitch = (props: Props) => {
|
||||
const {
|
||||
label,
|
||||
isDisabled = false,
|
||||
// fontSize = 'md',
|
||||
// size = 'md',
|
||||
width = 'auto',
|
||||
formControlProps,
|
||||
formLabelProps,
|
||||
@@ -39,17 +37,11 @@ const IAISwitch = (props: Props) => {
|
||||
>
|
||||
<FormLabel
|
||||
className="invokeai__switch-form-label"
|
||||
// fontSize={fontSize}
|
||||
whiteSpace="nowrap"
|
||||
{...formLabelProps}
|
||||
>
|
||||
{label}
|
||||
<Switch
|
||||
className="invokeai__switch-root"
|
||||
// size={size}
|
||||
// className="switch-button"
|
||||
{...rest}
|
||||
/>
|
||||
<Switch className="invokeai__switch-root" {...rest} />
|
||||
</FormLabel>
|
||||
</FormControl>
|
||||
);
|
||||
|
||||
39
frontend/src/common/components/ImageUploadOverlay.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import { Heading } from '@chakra-ui/react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
|
||||
type ImageUploadOverlayProps = {
|
||||
isDragAccept: boolean;
|
||||
isDragReject: boolean;
|
||||
overlaySecondaryText: string;
|
||||
setIsHandlingUpload: (isHandlingUpload: boolean) => void;
|
||||
};
|
||||
|
||||
const ImageUploadOverlay = (props: ImageUploadOverlayProps) => {
|
||||
const {
|
||||
isDragAccept,
|
||||
isDragReject,
|
||||
overlaySecondaryText,
|
||||
setIsHandlingUpload,
|
||||
} = props;
|
||||
|
||||
useHotkeys('esc', () => {
|
||||
setIsHandlingUpload(false);
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="dropzone-container">
|
||||
{isDragAccept && (
|
||||
<div className="dropzone-overlay is-drag-accept">
|
||||
<Heading size={'lg'}>Upload Image{overlaySecondaryText}</Heading>
|
||||
</div>
|
||||
)}
|
||||
{isDragReject && (
|
||||
<div className="dropzone-overlay is-drag-reject">
|
||||
<Heading size={'lg'}>Invalid Upload</Heading>
|
||||
<Heading size={'md'}>Must be single JPEG or PNG image</Heading>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export default ImageUploadOverlay;
|
||||
@@ -16,9 +16,10 @@
|
||||
row-gap: 1rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: var(--background-color);
|
||||
|
||||
&.is-drag-accept {
|
||||
box-shadow: inset 0 0 20rem 1rem var(--status-good-color);
|
||||
box-shadow: inset 0 0 20rem 1rem var(--accent-color);
|
||||
}
|
||||
|
||||
&.is-drag-reject {
|
||||
@@ -32,6 +33,7 @@
|
||||
}
|
||||
|
||||
.image-uploader-button-outer {
|
||||
min-width: 20rem;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
@@ -39,10 +41,11 @@
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
border-radius: 0.5rem;
|
||||
color: var(--subtext-color-bright);
|
||||
color: var(--tab-list-text-inactive);
|
||||
background-color: var(--btn-grey);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--inpaint-bg-color);
|
||||
background-color: var(--btn-grey-hover);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,13 @@
|
||||
import { useCallback, ReactNode, useState, useEffect } from 'react';
|
||||
import { RootState, useAppDispatch, useAppSelector } from '../../app/store';
|
||||
import { tabMap } from '../../features/tabs/InvokeTabs';
|
||||
import { useAppDispatch, useAppSelector } from '../../app/store';
|
||||
import { FileRejection, useDropzone } from 'react-dropzone';
|
||||
import { Heading, Spinner, useToast } from '@chakra-ui/react';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { OptionsState } from '../../features/options/optionsSlice';
|
||||
import { useToast } from '@chakra-ui/react';
|
||||
import { uploadImage } from '../../app/socketio/actions';
|
||||
import { ImageUploadDestination, UploadImagePayload } from '../../app/invokeai';
|
||||
import { ImageUploaderTriggerContext } from '../../app/contexts/ImageUploaderTriggerContext';
|
||||
|
||||
const appSelector = createSelector(
|
||||
(state: RootState) => state.options,
|
||||
(options: OptionsState) => {
|
||||
const { activeTab } = options;
|
||||
return {
|
||||
activeTabName: tabMap[activeTab],
|
||||
};
|
||||
}
|
||||
);
|
||||
import { activeTabNameSelector } from '../../features/options/optionsSelectors';
|
||||
import { tabDict } from '../../features/tabs/InvokeTabs';
|
||||
import ImageUploadOverlay from './ImageUploadOverlay';
|
||||
|
||||
type ImageUploaderProps = {
|
||||
children: ReactNode;
|
||||
@@ -26,7 +16,7 @@ type ImageUploaderProps = {
|
||||
const ImageUploader = (props: ImageUploaderProps) => {
|
||||
const { children } = props;
|
||||
const dispatch = useAppDispatch();
|
||||
const { activeTabName } = useAppSelector(appSelector);
|
||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
||||
const toast = useToast({});
|
||||
const [isHandlingUpload, setIsHandlingUpload] = useState<boolean>(false);
|
||||
|
||||
@@ -83,6 +73,7 @@ const ImageUploader = (props: ImageUploaderProps) => {
|
||||
accept: { 'image/png': ['.png'], 'image/jpeg': ['.jpg', '.jpeg', '.png'] },
|
||||
noClick: true,
|
||||
onDrop,
|
||||
onDragOver: () => setIsHandlingUpload(true),
|
||||
maxFiles: 1,
|
||||
});
|
||||
|
||||
@@ -140,30 +131,22 @@ const ImageUploader = (props: ImageUploaderProps) => {
|
||||
};
|
||||
}, [dispatch, toast, activeTabName]);
|
||||
|
||||
const overlaySecondaryText = ['img2img', 'inpainting'].includes(activeTabName)
|
||||
? ` to ${tabDict[activeTabName as keyof typeof tabDict].tooltip}`
|
||||
: ``;
|
||||
|
||||
return (
|
||||
<ImageUploaderTriggerContext.Provider value={open}>
|
||||
<div {...getRootProps({ style: {} })}>
|
||||
<input {...getInputProps()} />
|
||||
{children}
|
||||
{isDragActive && (
|
||||
<div className="dropzone-container">
|
||||
{isDragAccept && (
|
||||
<div className="dropzone-overlay is-drag-accept">
|
||||
<Heading size={'lg'}>Drop Images</Heading>
|
||||
</div>
|
||||
)}
|
||||
{isDragReject && (
|
||||
<div className="dropzone-overlay is-drag-reject">
|
||||
<Heading size={'lg'}>Invalid Upload</Heading>
|
||||
<Heading size={'md'}>Must be single JPEG or PNG image</Heading>
|
||||
</div>
|
||||
)}
|
||||
{isHandlingUpload && (
|
||||
<div className="dropzone-overlay is-handling-upload">
|
||||
<Spinner />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{isDragActive && isHandlingUpload && (
|
||||
<ImageUploadOverlay
|
||||
isDragAccept={isDragAccept}
|
||||
isDragReject={isDragReject}
|
||||
overlaySecondaryText={overlaySecondaryText}
|
||||
setIsHandlingUpload={setIsHandlingUpload}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</ImageUploaderTriggerContext.Provider>
|
||||
|
||||
19
frontend/src/common/components/ImageUploaderIconButton.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import { useContext } from 'react';
|
||||
import { FaUpload } from 'react-icons/fa';
|
||||
import { ImageUploaderTriggerContext } from '../../app/contexts/ImageUploaderTriggerContext';
|
||||
import IAIIconButton from './IAIIconButton';
|
||||
|
||||
const ImageUploaderIconButton = () => {
|
||||
const openImageUploader = useContext(ImageUploaderTriggerContext);
|
||||
|
||||
return (
|
||||
<IAIIconButton
|
||||
aria-label="Upload Image"
|
||||
tooltip="Upload Image"
|
||||
icon={<FaUpload />}
|
||||
onClick={openImageUploader || undefined}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageUploaderIconButton;
|
||||
@@ -1,114 +0,0 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import _ from 'lodash';
|
||||
import { useMemo } from 'react';
|
||||
import { useAppSelector } from '../../app/store';
|
||||
import { RootState } from '../../app/store';
|
||||
import { OptionsState } from '../../features/options/optionsSlice';
|
||||
|
||||
import { SystemState } from '../../features/system/systemSlice';
|
||||
import { InpaintingState } from '../../features/tabs/Inpainting/inpaintingSlice';
|
||||
import { tabMap } from '../../features/tabs/InvokeTabs';
|
||||
import { validateSeedWeights } from '../util/seedWeightPairs';
|
||||
|
||||
export const useCheckParametersSelector = createSelector(
|
||||
[
|
||||
(state: RootState) => state.options,
|
||||
(state: RootState) => state.system,
|
||||
(state: RootState) => state.inpainting,
|
||||
],
|
||||
(options: OptionsState, system: SystemState, inpainting: InpaintingState) => {
|
||||
return {
|
||||
// options
|
||||
prompt: options.prompt,
|
||||
shouldGenerateVariations: options.shouldGenerateVariations,
|
||||
seedWeights: options.seedWeights,
|
||||
maskPath: options.maskPath,
|
||||
initialImage: options.initialImage,
|
||||
seed: options.seed,
|
||||
activeTabName: tabMap[options.activeTab],
|
||||
// system
|
||||
isProcessing: system.isProcessing,
|
||||
isConnected: system.isConnected,
|
||||
// inpainting
|
||||
hasInpaintingImage: Boolean(inpainting.imageToInpaint),
|
||||
};
|
||||
},
|
||||
{
|
||||
memoizeOptions: {
|
||||
resultEqualityCheck: _.isEqual,
|
||||
},
|
||||
}
|
||||
);
|
||||
/**
|
||||
* Checks relevant pieces of state to confirm generation will not deterministically fail.
|
||||
* This is used to prevent the 'Generate' button from being clicked.
|
||||
*/
|
||||
const useCheckParameters = (): boolean => {
|
||||
const {
|
||||
prompt,
|
||||
shouldGenerateVariations,
|
||||
seedWeights,
|
||||
maskPath,
|
||||
initialImage,
|
||||
seed,
|
||||
activeTabName,
|
||||
isProcessing,
|
||||
isConnected,
|
||||
hasInpaintingImage,
|
||||
} = useAppSelector(useCheckParametersSelector);
|
||||
|
||||
return useMemo(() => {
|
||||
// Cannot generate without a prompt
|
||||
if (!prompt || Boolean(prompt.match(/^[\s\r\n]+$/))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (activeTabName === 'img2img' && !initialImage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (activeTabName === 'inpainting' && !hasInpaintingImage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cannot generate with a mask without img2img
|
||||
if (maskPath && !initialImage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: job queue
|
||||
// Cannot generate if already processing an image
|
||||
if (isProcessing) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cannot generate if not connected
|
||||
if (!isConnected) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cannot generate variations without valid seed weights
|
||||
if (
|
||||
shouldGenerateVariations &&
|
||||
(!(validateSeedWeights(seedWeights) || seedWeights === '') || seed === -1)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// All good
|
||||
return true;
|
||||
}, [
|
||||
prompt,
|
||||
maskPath,
|
||||
isProcessing,
|
||||
initialImage,
|
||||
isConnected,
|
||||
shouldGenerateVariations,
|
||||
seedWeights,
|
||||
seed,
|
||||
activeTabName,
|
||||
hasInpaintingImage,
|
||||
]);
|
||||
};
|
||||
|
||||
export default useCheckParameters;
|
||||
25
frontend/src/common/hooks/useClickOutsideWatcher.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { RefObject, useEffect } from 'react';
|
||||
|
||||
const useClickOutsideWatcher = (
|
||||
ref: RefObject<HTMLElement>,
|
||||
callback: () => void,
|
||||
req = true
|
||||
) => {
|
||||
useEffect(() => {
|
||||
function handleClickOutside(e: MouseEvent) {
|
||||
if (ref.current && !ref.current.contains(e.target as Node)) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
if (req) {
|
||||
document.addEventListener('mousedown', handleClickOutside);
|
||||
}
|
||||
return () => {
|
||||
if (req) {
|
||||
document.removeEventListener('mousedown', handleClickOutside);
|
||||
}
|
||||
};
|
||||
}, [ref, req, callback]);
|
||||
};
|
||||
|
||||
export default useClickOutsideWatcher;
|
||||
@@ -62,11 +62,13 @@ export const frontendToBackendParameters = (
|
||||
shouldRandomizeSeed,
|
||||
} = optionsState;
|
||||
|
||||
const { shouldDisplayInProgress } = systemState;
|
||||
const { shouldDisplayInProgressType, saveIntermediatesInterval } =
|
||||
systemState;
|
||||
|
||||
const generationParameters: { [k: string]: any } = {
|
||||
prompt,
|
||||
iterations,
|
||||
iterations:
|
||||
shouldRandomizeSeed || shouldGenerateVariations ? iterations : 1,
|
||||
steps,
|
||||
cfg_scale: cfgScale,
|
||||
threshold,
|
||||
@@ -75,7 +77,9 @@ export const frontendToBackendParameters = (
|
||||
width,
|
||||
sampler_name: sampler,
|
||||
seed,
|
||||
progress_images: shouldDisplayInProgress,
|
||||
progress_images: shouldDisplayInProgressType === 'full-res',
|
||||
progress_latents: shouldDisplayInProgressType === 'latents',
|
||||
save_intermediates: saveIntermediatesInterval,
|
||||
};
|
||||
|
||||
generationParameters.seed = shouldRandomizeSeed
|
||||
@@ -100,47 +104,41 @@ export const frontendToBackendParameters = (
|
||||
if (generationMode === 'inpainting' && maskImageElement) {
|
||||
const {
|
||||
lines,
|
||||
boundingBoxCoordinate: { x, y },
|
||||
boundingBoxDimensions: { width, height },
|
||||
shouldShowBoundingBox,
|
||||
boundingBoxCoordinate,
|
||||
boundingBoxDimensions,
|
||||
inpaintReplace,
|
||||
shouldUseInpaintReplace,
|
||||
} = inpaintingState;
|
||||
|
||||
let bx = x,
|
||||
by = y,
|
||||
bwidth = width,
|
||||
bheight = height;
|
||||
|
||||
if (!shouldShowBoundingBox) {
|
||||
bx = 0;
|
||||
by = 0;
|
||||
bwidth = maskImageElement.width;
|
||||
bheight = maskImageElement.height;
|
||||
}
|
||||
|
||||
const boundingBox = {
|
||||
x: bx,
|
||||
y: by,
|
||||
width: bwidth,
|
||||
height: bheight,
|
||||
...boundingBoxCoordinate,
|
||||
...boundingBoxDimensions,
|
||||
};
|
||||
|
||||
if (shouldUseInpaintReplace) {
|
||||
generationParameters.inpaint_replace = inpaintReplace;
|
||||
}
|
||||
|
||||
generationParameters.init_img = imageToProcessUrl;
|
||||
generationParameters.strength = img2imgStrength;
|
||||
generationParameters.fit = false;
|
||||
|
||||
const maskDataURL = generateMask(maskImageElement, lines, boundingBox);
|
||||
const { maskDataURL, isMaskEmpty } = generateMask(
|
||||
maskImageElement,
|
||||
lines,
|
||||
boundingBox
|
||||
);
|
||||
|
||||
generationParameters.is_mask_empty = isMaskEmpty;
|
||||
|
||||
generationParameters.init_mask = maskDataURL.split(
|
||||
'data:image/png;base64,'
|
||||
)[1];
|
||||
|
||||
if (shouldUseInpaintReplace) {
|
||||
generationParameters.inpaint_replace = inpaintReplace;
|
||||
}
|
||||
|
||||
generationParameters.bounding_box = boundingBox;
|
||||
|
||||
// TODO: The server metadata generation needs to be changed to fix this.
|
||||
generationParameters.progress_images = false;
|
||||
}
|
||||
|
||||
if (shouldGenerateVariations) {
|
||||
|
||||
25
frontend/src/features/gallery/CurrentImageButtons.scss
Normal file
@@ -0,0 +1,25 @@
|
||||
.current-image-options {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
column-gap: 0.5em;
|
||||
|
||||
.current-image-send-to-popover,
|
||||
.current-image-postprocessing-popover {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 0.5rem;
|
||||
max-width: 25rem;
|
||||
}
|
||||
|
||||
.chakra-popover__popper {
|
||||
z-index: 11;
|
||||
}
|
||||
|
||||
.delete-image-btn {
|
||||
svg {
|
||||
fill: var(--btn-delete-image);
|
||||
}
|
||||
}
|
||||
}
|
||||