Bring main back into a consistent state with other branches
- Due to misuse of rebase command, main was transiently in an inconsistent state. - This repairs the damage, and adds a few post-release patches that ensure stable conda installs on Mac and Windows.
3
.dockerignore
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
*
|
||||||
|
!environment*.yml
|
||||||
|
!docker-build
|
42
.github/workflows/build-container.yml
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# Building the Image without pushing to confirm it is still buildable
|
||||||
|
# confirum functionality would unfortunately need way more resources
|
||||||
|
name: build container image
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
- 'development'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
- 'development'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: prepare docker-tag
|
||||||
|
env:
|
||||||
|
repository: ${{ github.repository }}
|
||||||
|
run: echo "dockertag=${repository,,}" >> $GITHUB_ENV
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
- name: Cache Docker layers
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: /tmp/.buildx-cache
|
||||||
|
key: buildx-${{ hashFiles('docker-build/Dockerfile') }}
|
||||||
|
- name: Build container
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: docker-build/Dockerfile
|
||||||
|
platforms: linux/amd64
|
||||||
|
push: false
|
||||||
|
tags: ${{ env.dockertag }}:latest
|
||||||
|
cache-from: type=local,src=/tmp/.buildx-cache
|
||||||
|
cache-to: type=local,dest=/tmp/.buildx-cache
|
25
.github/workflows/create-caches.yml
vendored
@ -54,27 +54,10 @@ jobs:
|
|||||||
[[ -d models/ldm/stable-diffusion-v1 ]] \
|
[[ -d models/ldm/stable-diffusion-v1 ]] \
|
||||||
|| mkdir -p models/ldm/stable-diffusion-v1
|
|| mkdir -p models/ldm/stable-diffusion-v1
|
||||||
[[ -r models/ldm/stable-diffusion-v1/model.ckpt ]] \
|
[[ -r models/ldm/stable-diffusion-v1/model.ckpt ]] \
|
||||||
|| curl -o models/ldm/stable-diffusion-v1/model.ckpt ${{ secrets.SD_V1_4_URL }}
|
|| curl \
|
||||||
|
-H "Authorization: Bearer ${{ secrets.HUGGINGFACE_TOKEN }}" \
|
||||||
- name: Use cached Conda Environment
|
-o models/ldm/stable-diffusion-v1/model.ckpt \
|
||||||
uses: actions/cache@v3
|
-L https://huggingface.co/CompVis/stable-diffusion-v-1-4-original/resolve/main/sd-v1-4.ckpt
|
||||||
env:
|
|
||||||
cache-name: cache-conda-env-${{ env.CONDA_ENV_NAME }}
|
|
||||||
conda-env-file: ${{ matrix.environment-file }}
|
|
||||||
with:
|
|
||||||
path: ${{ env.CONDA_ROOT }}/envs/${{ env.CONDA_ENV_NAME }}
|
|
||||||
key: ${{ env.cache-name }}
|
|
||||||
restore-keys: ${{ env.cache-name }}-${{ runner.os }}-${{ hashFiles(env.conda-env-file) }}
|
|
||||||
|
|
||||||
- name: Use cached Conda Packages
|
|
||||||
uses: actions/cache@v3
|
|
||||||
env:
|
|
||||||
cache-name: cache-conda-env-${{ env.CONDA_ENV_NAME }}
|
|
||||||
conda-env-file: ${{ matrix.environment-file }}
|
|
||||||
with:
|
|
||||||
path: ${{ env.CONDA_PKGS_DIR }}
|
|
||||||
key: ${{ env.cache-name }}
|
|
||||||
restore-keys: ${{ env.cache-name }}-${{ runner.os }}-${{ hashFiles(env.conda-env-file) }}
|
|
||||||
|
|
||||||
- name: Activate Conda Env
|
- name: Activate Conda Env
|
||||||
uses: conda-incubator/setup-miniconda@v2
|
uses: conda-incubator/setup-miniconda@v2
|
||||||
|
117
.github/workflows/test-invoke-conda.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: Test Invoke with Conda
|
name: Test invoke.py
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
@ -11,31 +11,57 @@ on:
|
|||||||
- 'development'
|
- 'development'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
os_matrix:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest]
|
strategy:
|
||||||
|
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/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.ckpt'
|
||||||
|
os:
|
||||||
|
- ubuntu-latest
|
||||||
|
- macOS-12
|
||||||
include:
|
include:
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
environment-file: environment.yml
|
environment-file: environment.yml
|
||||||
default-shell: bash -l {0}
|
default-shell: bash -l {0}
|
||||||
- os: macos-latest
|
- os: macOS-12
|
||||||
environment-file: environment-mac.yml
|
environment-file: environment-mac.yml
|
||||||
default-shell: bash -l {0}
|
default-shell: bash -l {0}
|
||||||
name: Test invoke.py on ${{ matrix.os }} with conda
|
# - 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
|
||||||
|
name: ${{ matrix.os }} with ${{ matrix.stable-diffusion-model-switch }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
env:
|
||||||
|
CONDA_ENV_NAME: invokeai
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
shell: ${{ matrix.default-shell }}
|
shell: ${{ matrix.default-shell }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
|
id: checkout-sources
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: setup miniconda
|
- 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
|
||||||
|
with:
|
||||||
|
path: ~/conda_pkgs_dir
|
||||||
|
key: conda-pkgs-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles(matrix.environment-file) }}
|
||||||
|
|
||||||
|
- name: Activate Conda Env
|
||||||
|
id: activate-conda-env
|
||||||
uses: conda-incubator/setup-miniconda@v2
|
uses: conda-incubator/setup-miniconda@v2
|
||||||
with:
|
with:
|
||||||
auto-activate-base: false
|
activate-environment: ${{ env.CONDA_ENV_NAME }}
|
||||||
auto-update-conda: false
|
environment-file: ${{ matrix.environment-file }}
|
||||||
miniconda-version: latest
|
miniconda-version: latest
|
||||||
|
|
||||||
- name: set test prompt to main branch validation
|
- name: set test prompt to main branch validation
|
||||||
@ -48,79 +74,40 @@ jobs:
|
|||||||
|
|
||||||
- name: set test prompt to Pull Request validation
|
- name: set test prompt to Pull Request validation
|
||||||
if: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/development' }}
|
if: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/development' }}
|
||||||
run: echo "TEST_PROMPTS=tests/pr_prompt.txt" >> $GITHUB_ENV
|
run: echo "TEST_PROMPTS=tests/validate_pr_prompt.txt" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: set conda environment name
|
- name: Download ${{ matrix.stable-diffusion-model-switch }}
|
||||||
run: echo "CONDA_ENV_NAME=invokeai" >> $GITHUB_ENV
|
id: download-stable-diffusion-model
|
||||||
|
|
||||||
- name: Use Cached Stable Diffusion v1.4 Model
|
|
||||||
id: cache-sd-v1-4
|
|
||||||
uses: actions/cache@v3
|
|
||||||
env:
|
|
||||||
cache-name: cache-sd-v1-4
|
|
||||||
with:
|
|
||||||
path: models/ldm/stable-diffusion-v1/model.ckpt
|
|
||||||
key: ${{ env.cache-name }}
|
|
||||||
restore-keys: ${{ env.cache-name }}
|
|
||||||
|
|
||||||
- name: Download Stable Diffusion v1.4 Model
|
|
||||||
if: ${{ steps.cache-sd-v1-4.outputs.cache-hit != 'true' }}
|
|
||||||
run: |
|
run: |
|
||||||
[[ -d models/ldm/stable-diffusion-v1 ]] \
|
[[ -d models/ldm/stable-diffusion-v1 ]] \
|
||||||
|| mkdir -p models/ldm/stable-diffusion-v1
|
|| mkdir -p models/ldm/stable-diffusion-v1
|
||||||
[[ -r models/ldm/stable-diffusion-v1/model.ckpt ]] \
|
curl \
|
||||||
|| curl -o models/ldm/stable-diffusion-v1/model.ckpt ${{ secrets.SD_V1_4_URL }}
|
-H "Authorization: Bearer ${{ secrets.HUGGINGFACE_TOKEN }}" \
|
||||||
|
-o ${{ matrix.stable-diffusion-model-dl-path }} \
|
||||||
- name: Use cached Conda Environment
|
-L ${{ matrix.stable-diffusion-model }}
|
||||||
uses: actions/cache@v3
|
|
||||||
env:
|
|
||||||
cache-name: cache-conda-env-${{ env.CONDA_ENV_NAME }}
|
|
||||||
conda-env-file: ${{ matrix.environment-file }}
|
|
||||||
with:
|
|
||||||
path: ${{ env.CONDA }}/envs/${{ env.CONDA_ENV_NAME }}
|
|
||||||
key: env-${{ env.cache-name }}-${{ runner.os }}-${{ hashFiles(env.conda-env-file) }}
|
|
||||||
|
|
||||||
- name: Use cached Conda Packages
|
|
||||||
uses: actions/cache@v3
|
|
||||||
env:
|
|
||||||
cache-name: cache-conda-pkgs-${{ env.CONDA_ENV_NAME }}
|
|
||||||
conda-env-file: ${{ matrix.environment-file }}
|
|
||||||
with:
|
|
||||||
path: ${{ env.CONDA_PKGS_DIR }}
|
|
||||||
key: pkgs-${{ env.cache-name }}-${{ runner.os }}-${{ hashFiles(env.conda-env-file) }}
|
|
||||||
|
|
||||||
- name: Activate Conda Env
|
|
||||||
uses: conda-incubator/setup-miniconda@v2
|
|
||||||
with:
|
|
||||||
activate-environment: ${{ env.CONDA_ENV_NAME }}
|
|
||||||
environment-file: ${{ matrix.environment-file }}
|
|
||||||
|
|
||||||
- name: Use Cached Huggingface and Torch models
|
|
||||||
id: cache-hugginface-torch
|
|
||||||
uses: actions/cache@v3
|
|
||||||
env:
|
|
||||||
cache-name: cache-hugginface-torch
|
|
||||||
with:
|
|
||||||
path: ~/.cache
|
|
||||||
key: ${{ env.cache-name }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ env.cache-name }}-${{ hashFiles('scripts/preload_models.py') }}
|
|
||||||
|
|
||||||
- name: run preload_models.py
|
- name: run preload_models.py
|
||||||
run: python scripts/preload_models.py
|
id: run-preload-models
|
||||||
|
run: |
|
||||||
|
python scripts/preload_models.py \
|
||||||
|
--no-interactive
|
||||||
|
|
||||||
- name: Run the tests
|
- name: Run the tests
|
||||||
|
id: run-tests
|
||||||
run: |
|
run: |
|
||||||
time python scripts/invoke.py \
|
time python scripts/invoke.py \
|
||||||
|
--model ${{ matrix.stable-diffusion-model-switch }} \
|
||||||
--from_file ${{ env.TEST_PROMPTS }}
|
--from_file ${{ env.TEST_PROMPTS }}
|
||||||
|
|
||||||
- name: export conda env
|
- name: export conda env
|
||||||
|
id: export-conda-env
|
||||||
run: |
|
run: |
|
||||||
mkdir -p outputs/img-samples
|
mkdir -p outputs/img-samples
|
||||||
conda env export --name ${{ env.CONDA_ENV_NAME }} > outputs/img-samples/environment-${{ runner.os }}.yml
|
conda env export --name ${{ env.CONDA_ENV_NAME }} > outputs/img-samples/environment-${{ runner.os }}-${{ runner.arch }}.yml
|
||||||
|
|
||||||
- name: Archive results
|
- name: Archive results
|
||||||
|
id: archive-results
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: results_${{ matrix.os }}
|
name: results_${{ matrix.os }}_${{ matrix.stable-diffusion-model-switch }}
|
||||||
path: outputs/img-samples
|
path: outputs/img-samples
|
||||||
|
12
.gitignore
vendored
@ -3,6 +3,10 @@ outputs/
|
|||||||
models/ldm/stable-diffusion-v1/model.ckpt
|
models/ldm/stable-diffusion-v1/model.ckpt
|
||||||
**/restoration/codeformer/weights
|
**/restoration/codeformer/weights
|
||||||
|
|
||||||
|
# ignore user models config
|
||||||
|
configs/models.user.yaml
|
||||||
|
config/models.user.yml
|
||||||
|
|
||||||
# ignore the Anaconda/Miniconda installer used while building Docker image
|
# ignore the Anaconda/Miniconda installer used while building Docker image
|
||||||
anaconda.sh
|
anaconda.sh
|
||||||
|
|
||||||
@ -195,7 +199,13 @@ checkpoints
|
|||||||
.scratch/
|
.scratch/
|
||||||
.vscode/
|
.vscode/
|
||||||
gfpgan/
|
gfpgan/
|
||||||
models/ldm/stable-diffusion-v1/model.sha256
|
models/ldm/stable-diffusion-v1/*.sha256
|
||||||
|
|
||||||
# GFPGAN model files
|
# GFPGAN model files
|
||||||
gfpgan/
|
gfpgan/
|
||||||
|
|
||||||
|
# config file (will be created by installer)
|
||||||
|
configs/models.yaml
|
||||||
|
|
||||||
|
# weights (will be created by installer)
|
||||||
|
models/ldm/stable-diffusion-v1/*.ckpt
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# InvokeAI: A Stable Diffusion Toolkit
|
# InvokeAI: A Stable Diffusion Toolkit
|
||||||
|
|
||||||
_Formally known as lstein/stable-diffusion_
|
_Formerly known as lstein/stable-diffusion_
|
||||||
|
|
||||||
![project logo](docs/assets/logo.png)
|
![project logo](docs/assets/logo.png)
|
||||||
|
|
||||||
|
BIN
assets/caution.png
Normal file
After Width: | Height: | Size: 33 KiB |
@ -1,822 +0,0 @@
|
|||||||
import mimetypes
|
|
||||||
import transformers
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import traceback
|
|
||||||
import eventlet
|
|
||||||
import glob
|
|
||||||
import shlex
|
|
||||||
import math
|
|
||||||
import shutil
|
|
||||||
import sys
|
|
||||||
|
|
||||||
sys.path.append(".")
|
|
||||||
|
|
||||||
from argparse import ArgumentTypeError
|
|
||||||
from modules.create_cmd_parser import create_cmd_parser
|
|
||||||
|
|
||||||
parser = create_cmd_parser()
|
|
||||||
opt = parser.parse_args()
|
|
||||||
|
|
||||||
|
|
||||||
from flask_socketio import SocketIO
|
|
||||||
from flask import Flask, send_from_directory, url_for, jsonify
|
|
||||||
from pathlib import Path
|
|
||||||
from PIL import Image
|
|
||||||
from pytorch_lightning import logging
|
|
||||||
from threading import Event
|
|
||||||
from uuid import uuid4
|
|
||||||
from send2trash import send2trash
|
|
||||||
|
|
||||||
|
|
||||||
from ldm.generate import Generate
|
|
||||||
from ldm.invoke.restoration import Restoration
|
|
||||||
from ldm.invoke.pngwriter import PngWriter, retrieve_metadata
|
|
||||||
from ldm.invoke.args import APP_ID, APP_VERSION, calculate_init_img_hash
|
|
||||||
from ldm.invoke.conditioning import split_weighted_subprompts
|
|
||||||
|
|
||||||
from modules.parameters import parameters_to_command
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
USER CONFIG
|
|
||||||
"""
|
|
||||||
if opt.cors and "*" in opt.cors:
|
|
||||||
raise ArgumentTypeError('"*" is not an allowed CORS origin')
|
|
||||||
|
|
||||||
|
|
||||||
output_dir = "outputs/" # Base output directory for images
|
|
||||||
host = opt.host # Web & socket.io host
|
|
||||||
port = opt.port # Web & socket.io port
|
|
||||||
verbose = opt.verbose # enables copious socket.io logging
|
|
||||||
precision = opt.precision
|
|
||||||
free_gpu_mem = opt.free_gpu_mem
|
|
||||||
embedding_path = opt.embedding_path
|
|
||||||
additional_allowed_origins = (
|
|
||||||
opt.cors if opt.cors else []
|
|
||||||
) # additional CORS allowed origins
|
|
||||||
model = "stable-diffusion-1.4"
|
|
||||||
|
|
||||||
"""
|
|
||||||
END USER CONFIG
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
print("* Initializing, be patient...\n")
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
SERVER SETUP
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
# fix missing mimetypes on windows due to registry wonkiness
|
|
||||||
mimetypes.add_type("application/javascript", ".js")
|
|
||||||
mimetypes.add_type("text/css", ".css")
|
|
||||||
|
|
||||||
app = Flask(__name__, static_url_path="", static_folder="../frontend/dist/")
|
|
||||||
|
|
||||||
|
|
||||||
app.config["OUTPUTS_FOLDER"] = "../outputs"
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/outputs/<path:filename>")
|
|
||||||
def outputs(filename):
|
|
||||||
return send_from_directory(app.config["OUTPUTS_FOLDER"], filename)
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/", defaults={"path": ""})
|
|
||||||
def serve(path):
|
|
||||||
return send_from_directory(app.static_folder, "index.html")
|
|
||||||
|
|
||||||
|
|
||||||
logger = True if verbose else False
|
|
||||||
engineio_logger = True if verbose else False
|
|
||||||
|
|
||||||
# default 1,000,000, needs to be higher for socketio to accept larger images
|
|
||||||
max_http_buffer_size = 10000000
|
|
||||||
|
|
||||||
cors_allowed_origins = [f"http://{host}:{port}"] + additional_allowed_origins
|
|
||||||
|
|
||||||
socketio = SocketIO(
|
|
||||||
app,
|
|
||||||
logger=logger,
|
|
||||||
engineio_logger=engineio_logger,
|
|
||||||
max_http_buffer_size=max_http_buffer_size,
|
|
||||||
cors_allowed_origins=cors_allowed_origins,
|
|
||||||
ping_interval=(50, 50),
|
|
||||||
ping_timeout=60,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
END SERVER SETUP
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
APP SETUP
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class CanceledException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
gfpgan, codeformer, esrgan = None, None, None
|
|
||||||
from ldm.invoke.restoration.base import Restoration
|
|
||||||
|
|
||||||
restoration = Restoration()
|
|
||||||
gfpgan, codeformer = restoration.load_face_restore_models()
|
|
||||||
esrgan = restoration.load_esrgan()
|
|
||||||
|
|
||||||
# coreformer.process(self, image, strength, device, seed=None, fidelity=0.75)
|
|
||||||
|
|
||||||
except (ModuleNotFoundError, ImportError):
|
|
||||||
print(traceback.format_exc(), file=sys.stderr)
|
|
||||||
print(">> You may need to install the ESRGAN and/or GFPGAN modules")
|
|
||||||
|
|
||||||
canceled = Event()
|
|
||||||
|
|
||||||
# reduce logging outputs to error
|
|
||||||
transformers.logging.set_verbosity_error()
|
|
||||||
logging.getLogger("pytorch_lightning").setLevel(logging.ERROR)
|
|
||||||
|
|
||||||
# Initialize and load model
|
|
||||||
generate = Generate(
|
|
||||||
model,
|
|
||||||
precision=precision,
|
|
||||||
embedding_path=embedding_path,
|
|
||||||
)
|
|
||||||
generate.free_gpu_mem = free_gpu_mem
|
|
||||||
generate.load_model()
|
|
||||||
|
|
||||||
|
|
||||||
# location for "finished" images
|
|
||||||
result_path = os.path.join(output_dir, "img-samples/")
|
|
||||||
|
|
||||||
# temporary path for intermediates
|
|
||||||
intermediate_path = os.path.join(result_path, "intermediates/")
|
|
||||||
|
|
||||||
# path for user-uploaded init images and masks
|
|
||||||
init_image_path = os.path.join(result_path, "init-images/")
|
|
||||||
mask_image_path = os.path.join(result_path, "mask-images/")
|
|
||||||
|
|
||||||
# txt log
|
|
||||||
log_path = os.path.join(result_path, "invoke_log.txt")
|
|
||||||
|
|
||||||
# make all output paths
|
|
||||||
[
|
|
||||||
os.makedirs(path, exist_ok=True)
|
|
||||||
for path in [result_path, intermediate_path, init_image_path, mask_image_path]
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
END APP SETUP
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
SOCKET.IO LISTENERS
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
@socketio.on("requestSystemConfig")
|
|
||||||
def handle_request_capabilities():
|
|
||||||
print(f">> System config requested")
|
|
||||||
config = get_system_config()
|
|
||||||
socketio.emit("systemConfig", config)
|
|
||||||
|
|
||||||
|
|
||||||
@socketio.on("requestImages")
|
|
||||||
def handle_request_images(page=1, offset=0, last_mtime=None):
|
|
||||||
chunk_size = 50
|
|
||||||
|
|
||||||
if last_mtime:
|
|
||||||
print(f">> Latest images requested")
|
|
||||||
else:
|
|
||||||
print(
|
|
||||||
f">> Page {page} of images requested (page size {chunk_size} offset {offset})"
|
|
||||||
)
|
|
||||||
|
|
||||||
paths = glob.glob(os.path.join(result_path, "*.png"))
|
|
||||||
sorted_paths = sorted(paths, key=lambda x: os.path.getmtime(x), reverse=True)
|
|
||||||
|
|
||||||
if last_mtime:
|
|
||||||
image_paths = filter(lambda x: os.path.getmtime(x) > last_mtime, sorted_paths)
|
|
||||||
else:
|
|
||||||
|
|
||||||
image_paths = sorted_paths[
|
|
||||||
slice(chunk_size * (page - 1) + offset, chunk_size * page + offset)
|
|
||||||
]
|
|
||||||
page = page + 1
|
|
||||||
|
|
||||||
image_array = []
|
|
||||||
|
|
||||||
for path in image_paths:
|
|
||||||
metadata = retrieve_metadata(path)
|
|
||||||
image_array.append(
|
|
||||||
{
|
|
||||||
"url": path,
|
|
||||||
"mtime": os.path.getmtime(path),
|
|
||||||
"metadata": metadata["sd-metadata"],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
socketio.emit(
|
|
||||||
"galleryImages",
|
|
||||||
{
|
|
||||||
"images": image_array,
|
|
||||||
"nextPage": page,
|
|
||||||
"offset": offset,
|
|
||||||
"onlyNewImages": True if last_mtime else False,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@socketio.on("generateImage")
|
|
||||||
def handle_generate_image_event(
|
|
||||||
generation_parameters, esrgan_parameters, gfpgan_parameters
|
|
||||||
):
|
|
||||||
print(
|
|
||||||
f">> Image generation requested: {generation_parameters}\nESRGAN parameters: {esrgan_parameters}\nGFPGAN parameters: {gfpgan_parameters}"
|
|
||||||
)
|
|
||||||
generate_images(generation_parameters, esrgan_parameters, gfpgan_parameters)
|
|
||||||
|
|
||||||
|
|
||||||
@socketio.on("runESRGAN")
|
|
||||||
def handle_run_esrgan_event(original_image, esrgan_parameters):
|
|
||||||
print(
|
|
||||||
f'>> ESRGAN upscale requested for "{original_image["url"]}": {esrgan_parameters}'
|
|
||||||
)
|
|
||||||
progress = {
|
|
||||||
"currentStep": 1,
|
|
||||||
"totalSteps": 1,
|
|
||||||
"currentIteration": 1,
|
|
||||||
"totalIterations": 1,
|
|
||||||
"currentStatus": "Preparing",
|
|
||||||
"isProcessing": True,
|
|
||||||
"currentStatusHasSteps": False,
|
|
||||||
}
|
|
||||||
|
|
||||||
socketio.emit("progressUpdate", progress)
|
|
||||||
eventlet.sleep(0)
|
|
||||||
|
|
||||||
image = Image.open(original_image["url"])
|
|
||||||
|
|
||||||
seed = (
|
|
||||||
original_image["metadata"]["seed"]
|
|
||||||
if "seed" in original_image["metadata"]
|
|
||||||
else "unknown_seed"
|
|
||||||
)
|
|
||||||
|
|
||||||
progress["currentStatus"] = "Upscaling"
|
|
||||||
socketio.emit("progressUpdate", progress)
|
|
||||||
eventlet.sleep(0)
|
|
||||||
|
|
||||||
image = esrgan.process(
|
|
||||||
image=image,
|
|
||||||
upsampler_scale=esrgan_parameters["upscale"][0],
|
|
||||||
strength=esrgan_parameters["upscale"][1],
|
|
||||||
seed=seed,
|
|
||||||
)
|
|
||||||
|
|
||||||
progress["currentStatus"] = "Saving image"
|
|
||||||
socketio.emit("progressUpdate", progress)
|
|
||||||
eventlet.sleep(0)
|
|
||||||
|
|
||||||
esrgan_parameters["seed"] = seed
|
|
||||||
metadata = parameters_to_post_processed_image_metadata(
|
|
||||||
parameters=esrgan_parameters,
|
|
||||||
original_image_path=original_image["url"],
|
|
||||||
type="esrgan",
|
|
||||||
)
|
|
||||||
command = parameters_to_command(esrgan_parameters)
|
|
||||||
|
|
||||||
path = save_image(image, command, metadata, result_path, postprocessing="esrgan")
|
|
||||||
|
|
||||||
write_log_message(f'[Upscaled] "{original_image["url"]}" > "{path}": {command}')
|
|
||||||
|
|
||||||
progress["currentStatus"] = "Finished"
|
|
||||||
progress["currentStep"] = 0
|
|
||||||
progress["totalSteps"] = 0
|
|
||||||
progress["currentIteration"] = 0
|
|
||||||
progress["totalIterations"] = 0
|
|
||||||
progress["isProcessing"] = False
|
|
||||||
socketio.emit("progressUpdate", progress)
|
|
||||||
eventlet.sleep(0)
|
|
||||||
|
|
||||||
socketio.emit(
|
|
||||||
"esrganResult",
|
|
||||||
{
|
|
||||||
"url": os.path.relpath(path),
|
|
||||||
"mtime": os.path.getmtime(path),
|
|
||||||
"metadata": metadata,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@socketio.on("runGFPGAN")
|
|
||||||
def handle_run_gfpgan_event(original_image, gfpgan_parameters):
|
|
||||||
print(
|
|
||||||
f'>> GFPGAN face fix requested for "{original_image["url"]}": {gfpgan_parameters}'
|
|
||||||
)
|
|
||||||
progress = {
|
|
||||||
"currentStep": 1,
|
|
||||||
"totalSteps": 1,
|
|
||||||
"currentIteration": 1,
|
|
||||||
"totalIterations": 1,
|
|
||||||
"currentStatus": "Preparing",
|
|
||||||
"isProcessing": True,
|
|
||||||
"currentStatusHasSteps": False,
|
|
||||||
}
|
|
||||||
|
|
||||||
socketio.emit("progressUpdate", progress)
|
|
||||||
eventlet.sleep(0)
|
|
||||||
|
|
||||||
image = Image.open(original_image["url"])
|
|
||||||
|
|
||||||
seed = (
|
|
||||||
original_image["metadata"]["seed"]
|
|
||||||
if "seed" in original_image["metadata"]
|
|
||||||
else "unknown_seed"
|
|
||||||
)
|
|
||||||
|
|
||||||
progress["currentStatus"] = "Fixing faces"
|
|
||||||
socketio.emit("progressUpdate", progress)
|
|
||||||
eventlet.sleep(0)
|
|
||||||
|
|
||||||
image = gfpgan.process(
|
|
||||||
image=image, strength=gfpgan_parameters["facetool_strength"], seed=seed
|
|
||||||
)
|
|
||||||
|
|
||||||
progress["currentStatus"] = "Saving image"
|
|
||||||
socketio.emit("progressUpdate", progress)
|
|
||||||
eventlet.sleep(0)
|
|
||||||
|
|
||||||
gfpgan_parameters["seed"] = seed
|
|
||||||
metadata = parameters_to_post_processed_image_metadata(
|
|
||||||
parameters=gfpgan_parameters,
|
|
||||||
original_image_path=original_image["url"],
|
|
||||||
type="gfpgan",
|
|
||||||
)
|
|
||||||
command = parameters_to_command(gfpgan_parameters)
|
|
||||||
|
|
||||||
path = save_image(image, command, metadata, result_path, postprocessing="gfpgan")
|
|
||||||
|
|
||||||
write_log_message(f'[Fixed faces] "{original_image["url"]}" > "{path}": {command}')
|
|
||||||
|
|
||||||
progress["currentStatus"] = "Finished"
|
|
||||||
progress["currentStep"] = 0
|
|
||||||
progress["totalSteps"] = 0
|
|
||||||
progress["currentIteration"] = 0
|
|
||||||
progress["totalIterations"] = 0
|
|
||||||
progress["isProcessing"] = False
|
|
||||||
socketio.emit("progressUpdate", progress)
|
|
||||||
eventlet.sleep(0)
|
|
||||||
|
|
||||||
socketio.emit(
|
|
||||||
"gfpganResult",
|
|
||||||
{
|
|
||||||
"url": os.path.relpath(path),
|
|
||||||
"mtime": os.path.mtime(path),
|
|
||||||
"metadata": metadata,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@socketio.on("cancel")
|
|
||||||
def handle_cancel():
|
|
||||||
print(f">> Cancel processing requested")
|
|
||||||
canceled.set()
|
|
||||||
socketio.emit("processingCanceled")
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: I think this needs a safety mechanism.
|
|
||||||
@socketio.on("deleteImage")
|
|
||||||
def handle_delete_image(path, uuid):
|
|
||||||
print(f'>> Delete requested "{path}"')
|
|
||||||
send2trash(path)
|
|
||||||
socketio.emit("imageDeleted", {"url": path, "uuid": uuid})
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: I think this needs a safety mechanism.
|
|
||||||
@socketio.on("uploadInitialImage")
|
|
||||||
def handle_upload_initial_image(bytes, name):
|
|
||||||
print(f'>> Init image upload requested "{name}"')
|
|
||||||
uuid = uuid4().hex
|
|
||||||
split = os.path.splitext(name)
|
|
||||||
name = f"{split[0]}.{uuid}{split[1]}"
|
|
||||||
file_path = os.path.join(init_image_path, name)
|
|
||||||
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
|
||||||
newFile = open(file_path, "wb")
|
|
||||||
newFile.write(bytes)
|
|
||||||
socketio.emit("initialImageUploaded", {"url": file_path, "uuid": ""})
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: I think this needs a safety mechanism.
|
|
||||||
@socketio.on("uploadMaskImage")
|
|
||||||
def handle_upload_mask_image(bytes, name):
|
|
||||||
print(f'>> Mask image upload requested "{name}"')
|
|
||||||
uuid = uuid4().hex
|
|
||||||
split = os.path.splitext(name)
|
|
||||||
name = f"{split[0]}.{uuid}{split[1]}"
|
|
||||||
file_path = os.path.join(mask_image_path, name)
|
|
||||||
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
|
||||||
newFile = open(file_path, "wb")
|
|
||||||
newFile.write(bytes)
|
|
||||||
socketio.emit("maskImageUploaded", {"url": file_path, "uuid": ""})
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
END SOCKET.IO LISTENERS
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
ADDITIONAL FUNCTIONS
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def get_system_config():
|
|
||||||
return {
|
|
||||||
"model": "stable diffusion",
|
|
||||||
"model_id": model,
|
|
||||||
"model_hash": generate.model_hash,
|
|
||||||
"app_id": APP_ID,
|
|
||||||
"app_version": APP_VERSION,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def parameters_to_post_processed_image_metadata(parameters, original_image_path, type):
|
|
||||||
# top-level metadata minus `image` or `images`
|
|
||||||
metadata = get_system_config()
|
|
||||||
|
|
||||||
orig_hash = calculate_init_img_hash(original_image_path)
|
|
||||||
|
|
||||||
image = {"orig_path": original_image_path, "orig_hash": orig_hash}
|
|
||||||
|
|
||||||
if type == "esrgan":
|
|
||||||
image["type"] = "esrgan"
|
|
||||||
image["scale"] = parameters["upscale"][0]
|
|
||||||
image["strength"] = parameters["upscale"][1]
|
|
||||||
elif type == "gfpgan":
|
|
||||||
image["type"] = "gfpgan"
|
|
||||||
image["strength"] = parameters["facetool_strength"]
|
|
||||||
else:
|
|
||||||
raise TypeError(f"Invalid type: {type}")
|
|
||||||
|
|
||||||
metadata["image"] = image
|
|
||||||
return metadata
|
|
||||||
|
|
||||||
|
|
||||||
def parameters_to_generated_image_metadata(parameters):
|
|
||||||
# top-level metadata minus `image` or `images`
|
|
||||||
|
|
||||||
metadata = get_system_config()
|
|
||||||
# remove any image keys not mentioned in RFC #266
|
|
||||||
rfc266_img_fields = [
|
|
||||||
"type",
|
|
||||||
"postprocessing",
|
|
||||||
"sampler",
|
|
||||||
"prompt",
|
|
||||||
"seed",
|
|
||||||
"variations",
|
|
||||||
"steps",
|
|
||||||
"cfg_scale",
|
|
||||||
"threshold",
|
|
||||||
"perlin",
|
|
||||||
"step_number",
|
|
||||||
"width",
|
|
||||||
"height",
|
|
||||||
"extra",
|
|
||||||
"seamless",
|
|
||||||
"hires_fix",
|
|
||||||
]
|
|
||||||
|
|
||||||
rfc_dict = {}
|
|
||||||
|
|
||||||
for item in parameters.items():
|
|
||||||
key, value = item
|
|
||||||
if key in rfc266_img_fields:
|
|
||||||
rfc_dict[key] = value
|
|
||||||
|
|
||||||
postprocessing = []
|
|
||||||
|
|
||||||
# 'postprocessing' is either null or an
|
|
||||||
if "facetool_strength" in parameters:
|
|
||||||
|
|
||||||
postprocessing.append(
|
|
||||||
{"type": "gfpgan", "strength": float(parameters["facetool_strength"])}
|
|
||||||
)
|
|
||||||
|
|
||||||
if "upscale" in parameters:
|
|
||||||
postprocessing.append(
|
|
||||||
{
|
|
||||||
"type": "esrgan",
|
|
||||||
"scale": int(parameters["upscale"][0]),
|
|
||||||
"strength": float(parameters["upscale"][1]),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
rfc_dict["postprocessing"] = postprocessing if len(postprocessing) > 0 else None
|
|
||||||
|
|
||||||
# semantic drift
|
|
||||||
rfc_dict["sampler"] = parameters["sampler_name"]
|
|
||||||
|
|
||||||
# display weighted subprompts (liable to change)
|
|
||||||
subprompts = split_weighted_subprompts(parameters["prompt"])
|
|
||||||
subprompts = [{"prompt": x[0], "weight": x[1]} for x in subprompts]
|
|
||||||
rfc_dict["prompt"] = subprompts
|
|
||||||
|
|
||||||
# 'variations' should always exist and be an array, empty or consisting of {'seed': seed, 'weight': weight} pairs
|
|
||||||
variations = []
|
|
||||||
|
|
||||||
if "with_variations" in parameters:
|
|
||||||
variations = [
|
|
||||||
{"seed": x[0], "weight": x[1]} for x in parameters["with_variations"]
|
|
||||||
]
|
|
||||||
|
|
||||||
rfc_dict["variations"] = variations
|
|
||||||
|
|
||||||
if "init_img" in parameters:
|
|
||||||
rfc_dict["type"] = "img2img"
|
|
||||||
rfc_dict["strength"] = parameters["strength"]
|
|
||||||
rfc_dict["fit"] = parameters["fit"] # TODO: Noncompliant
|
|
||||||
rfc_dict["orig_hash"] = calculate_init_img_hash(parameters["init_img"])
|
|
||||||
rfc_dict["init_image_path"] = parameters["init_img"] # TODO: Noncompliant
|
|
||||||
rfc_dict["sampler"] = "ddim" # TODO: FIX ME WHEN IMG2IMG SUPPORTS ALL SAMPLERS
|
|
||||||
if "init_mask" in parameters:
|
|
||||||
rfc_dict["mask_hash"] = calculate_init_img_hash(
|
|
||||||
parameters["init_mask"]
|
|
||||||
) # TODO: Noncompliant
|
|
||||||
rfc_dict["mask_image_path"] = parameters["init_mask"] # TODO: Noncompliant
|
|
||||||
else:
|
|
||||||
rfc_dict["type"] = "txt2img"
|
|
||||||
|
|
||||||
metadata["image"] = rfc_dict
|
|
||||||
|
|
||||||
return metadata
|
|
||||||
|
|
||||||
|
|
||||||
def make_unique_init_image_filename(name):
|
|
||||||
uuid = uuid4().hex
|
|
||||||
split = os.path.splitext(name)
|
|
||||||
name = f"{split[0]}.{uuid}{split[1]}"
|
|
||||||
return name
|
|
||||||
|
|
||||||
|
|
||||||
def write_log_message(message, log_path=log_path):
|
|
||||||
"""Logs the filename and parameters used to generate or process that image to log file"""
|
|
||||||
message = f"{message}\n"
|
|
||||||
with open(log_path, "a", encoding="utf-8") as file:
|
|
||||||
file.writelines(message)
|
|
||||||
|
|
||||||
|
|
||||||
def save_image(
|
|
||||||
image, command, metadata, output_dir, step_index=None, postprocessing=False
|
|
||||||
):
|
|
||||||
pngwriter = PngWriter(output_dir)
|
|
||||||
prefix = pngwriter.unique_prefix()
|
|
||||||
|
|
||||||
seed = "unknown_seed"
|
|
||||||
|
|
||||||
if "image" in metadata:
|
|
||||||
if "seed" in metadata["image"]:
|
|
||||||
seed = metadata["image"]["seed"]
|
|
||||||
|
|
||||||
filename = f"{prefix}.{seed}"
|
|
||||||
|
|
||||||
if step_index:
|
|
||||||
filename += f".{step_index}"
|
|
||||||
if postprocessing:
|
|
||||||
filename += f".postprocessed"
|
|
||||||
|
|
||||||
filename += ".png"
|
|
||||||
|
|
||||||
path = pngwriter.save_image_and_prompt_to_png(
|
|
||||||
image=image, dream_prompt=command, metadata=metadata, name=filename
|
|
||||||
)
|
|
||||||
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def calculate_real_steps(steps, strength, has_init_image):
|
|
||||||
return math.floor(strength * steps) if has_init_image else steps
|
|
||||||
|
|
||||||
|
|
||||||
def generate_images(generation_parameters, esrgan_parameters, gfpgan_parameters):
|
|
||||||
canceled.clear()
|
|
||||||
|
|
||||||
step_index = 1
|
|
||||||
prior_variations = (
|
|
||||||
generation_parameters["with_variations"]
|
|
||||||
if "with_variations" in generation_parameters
|
|
||||||
else []
|
|
||||||
)
|
|
||||||
"""
|
|
||||||
If a result image is used as an init image, and then deleted, we will want to be
|
|
||||||
able to use it as an init image in the future. Need to copy it.
|
|
||||||
|
|
||||||
If the init/mask image doesn't exist in the init_image_path/mask_image_path,
|
|
||||||
make a unique filename for it and copy it there.
|
|
||||||
"""
|
|
||||||
if "init_img" in generation_parameters:
|
|
||||||
filename = os.path.basename(generation_parameters["init_img"])
|
|
||||||
if not os.path.exists(os.path.join(init_image_path, filename)):
|
|
||||||
unique_filename = make_unique_init_image_filename(filename)
|
|
||||||
new_path = os.path.join(init_image_path, unique_filename)
|
|
||||||
shutil.copy(generation_parameters["init_img"], new_path)
|
|
||||||
generation_parameters["init_img"] = new_path
|
|
||||||
if "init_mask" in generation_parameters:
|
|
||||||
filename = os.path.basename(generation_parameters["init_mask"])
|
|
||||||
if not os.path.exists(os.path.join(mask_image_path, filename)):
|
|
||||||
unique_filename = make_unique_init_image_filename(filename)
|
|
||||||
new_path = os.path.join(init_image_path, unique_filename)
|
|
||||||
shutil.copy(generation_parameters["init_img"], new_path)
|
|
||||||
generation_parameters["init_mask"] = new_path
|
|
||||||
|
|
||||||
totalSteps = calculate_real_steps(
|
|
||||||
steps=generation_parameters["steps"],
|
|
||||||
strength=generation_parameters["strength"]
|
|
||||||
if "strength" in generation_parameters
|
|
||||||
else None,
|
|
||||||
has_init_image="init_img" in generation_parameters,
|
|
||||||
)
|
|
||||||
|
|
||||||
progress = {
|
|
||||||
"currentStep": 1,
|
|
||||||
"totalSteps": totalSteps,
|
|
||||||
"currentIteration": 1,
|
|
||||||
"totalIterations": generation_parameters["iterations"],
|
|
||||||
"currentStatus": "Preparing",
|
|
||||||
"isProcessing": True,
|
|
||||||
"currentStatusHasSteps": False,
|
|
||||||
}
|
|
||||||
|
|
||||||
socketio.emit("progressUpdate", progress)
|
|
||||||
eventlet.sleep(0)
|
|
||||||
|
|
||||||
def image_progress(sample, step):
|
|
||||||
if canceled.is_set():
|
|
||||||
raise CanceledException
|
|
||||||
|
|
||||||
nonlocal step_index
|
|
||||||
nonlocal generation_parameters
|
|
||||||
nonlocal progress
|
|
||||||
|
|
||||||
progress["currentStep"] = step + 1
|
|
||||||
progress["currentStatus"] = "Generating"
|
|
||||||
progress["currentStatusHasSteps"] = True
|
|
||||||
|
|
||||||
if (
|
|
||||||
generation_parameters["progress_images"]
|
|
||||||
and step % 5 == 0
|
|
||||||
and step < generation_parameters["steps"] - 1
|
|
||||||
):
|
|
||||||
image = generate.sample_to_image(sample)
|
|
||||||
|
|
||||||
metadata = parameters_to_generated_image_metadata(generation_parameters)
|
|
||||||
command = parameters_to_command(generation_parameters)
|
|
||||||
path = save_image(image, command, metadata, intermediate_path, step_index=step_index, postprocessing=False)
|
|
||||||
|
|
||||||
step_index += 1
|
|
||||||
socketio.emit(
|
|
||||||
"intermediateResult",
|
|
||||||
{
|
|
||||||
"url": os.path.relpath(path),
|
|
||||||
"mtime": os.path.getmtime(path),
|
|
||||||
"metadata": metadata,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
socketio.emit("progressUpdate", progress)
|
|
||||||
eventlet.sleep(0)
|
|
||||||
|
|
||||||
def image_done(image, seed, first_seed):
|
|
||||||
nonlocal generation_parameters
|
|
||||||
nonlocal esrgan_parameters
|
|
||||||
nonlocal gfpgan_parameters
|
|
||||||
nonlocal progress
|
|
||||||
|
|
||||||
step_index = 1
|
|
||||||
nonlocal prior_variations
|
|
||||||
|
|
||||||
progress["currentStatus"] = "Generation complete"
|
|
||||||
socketio.emit("progressUpdate", progress)
|
|
||||||
eventlet.sleep(0)
|
|
||||||
|
|
||||||
all_parameters = generation_parameters
|
|
||||||
postprocessing = False
|
|
||||||
|
|
||||||
if (
|
|
||||||
"variation_amount" in all_parameters
|
|
||||||
and all_parameters["variation_amount"] > 0
|
|
||||||
):
|
|
||||||
first_seed = first_seed or seed
|
|
||||||
this_variation = [[seed, all_parameters["variation_amount"]]]
|
|
||||||
all_parameters["with_variations"] = prior_variations + this_variation
|
|
||||||
all_parameters["seed"] = first_seed
|
|
||||||
elif ("with_variations" in all_parameters):
|
|
||||||
all_parameters["seed"] = first_seed
|
|
||||||
else:
|
|
||||||
all_parameters["seed"] = seed
|
|
||||||
|
|
||||||
if esrgan_parameters:
|
|
||||||
progress["currentStatus"] = "Upscaling"
|
|
||||||
progress["currentStatusHasSteps"] = False
|
|
||||||
socketio.emit("progressUpdate", progress)
|
|
||||||
eventlet.sleep(0)
|
|
||||||
|
|
||||||
image = esrgan.process(
|
|
||||||
image=image,
|
|
||||||
upsampler_scale=esrgan_parameters["level"],
|
|
||||||
strength=esrgan_parameters["strength"],
|
|
||||||
seed=seed,
|
|
||||||
)
|
|
||||||
|
|
||||||
postprocessing = True
|
|
||||||
all_parameters["upscale"] = [
|
|
||||||
esrgan_parameters["level"],
|
|
||||||
esrgan_parameters["strength"],
|
|
||||||
]
|
|
||||||
|
|
||||||
if gfpgan_parameters:
|
|
||||||
progress["currentStatus"] = "Fixing faces"
|
|
||||||
progress["currentStatusHasSteps"] = False
|
|
||||||
socketio.emit("progressUpdate", progress)
|
|
||||||
eventlet.sleep(0)
|
|
||||||
|
|
||||||
image = gfpgan.process(
|
|
||||||
image=image, strength=gfpgan_parameters["strength"], seed=seed
|
|
||||||
)
|
|
||||||
postprocessing = True
|
|
||||||
all_parameters["facetool_strength"] = gfpgan_parameters["strength"]
|
|
||||||
|
|
||||||
progress["currentStatus"] = "Saving image"
|
|
||||||
socketio.emit("progressUpdate", progress)
|
|
||||||
eventlet.sleep(0)
|
|
||||||
|
|
||||||
metadata = parameters_to_generated_image_metadata(all_parameters)
|
|
||||||
command = parameters_to_command(all_parameters)
|
|
||||||
|
|
||||||
path = save_image(
|
|
||||||
image, command, metadata, result_path, postprocessing=postprocessing
|
|
||||||
)
|
|
||||||
|
|
||||||
print(f'>> Image generated: "{path}"')
|
|
||||||
write_log_message(f'[Generated] "{path}": {command}')
|
|
||||||
|
|
||||||
if progress["totalIterations"] > progress["currentIteration"]:
|
|
||||||
progress["currentStep"] = 1
|
|
||||||
progress["currentIteration"] += 1
|
|
||||||
progress["currentStatus"] = "Iteration finished"
|
|
||||||
progress["currentStatusHasSteps"] = False
|
|
||||||
else:
|
|
||||||
progress["currentStep"] = 0
|
|
||||||
progress["totalSteps"] = 0
|
|
||||||
progress["currentIteration"] = 0
|
|
||||||
progress["totalIterations"] = 0
|
|
||||||
progress["currentStatus"] = "Finished"
|
|
||||||
progress["isProcessing"] = False
|
|
||||||
|
|
||||||
socketio.emit("progressUpdate", progress)
|
|
||||||
eventlet.sleep(0)
|
|
||||||
|
|
||||||
socketio.emit(
|
|
||||||
"generationResult",
|
|
||||||
{
|
|
||||||
"url": os.path.relpath(path),
|
|
||||||
"mtime": os.path.getmtime(path),
|
|
||||||
"metadata": metadata,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
eventlet.sleep(0)
|
|
||||||
|
|
||||||
try:
|
|
||||||
generate.prompt2image(
|
|
||||||
**generation_parameters,
|
|
||||||
step_callback=image_progress,
|
|
||||||
image_callback=image_done,
|
|
||||||
)
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
raise
|
|
||||||
except CanceledException:
|
|
||||||
pass
|
|
||||||
except Exception as e:
|
|
||||||
socketio.emit("error", {"message": (str(e))})
|
|
||||||
print("\n")
|
|
||||||
traceback.print_exc()
|
|
||||||
print("\n")
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
END ADDITIONAL FUNCTIONS
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
print(f">> Starting server at http://{host}:{port}")
|
|
||||||
socketio.run(app, host=host, port=port)
|
|
@ -1,54 +0,0 @@
|
|||||||
model:
|
|
||||||
base_learning_rate: 4.5e-6
|
|
||||||
target: ldm.models.autoencoder.AutoencoderKL
|
|
||||||
params:
|
|
||||||
monitor: "val/rec_loss"
|
|
||||||
embed_dim: 16
|
|
||||||
lossconfig:
|
|
||||||
target: ldm.modules.losses.LPIPSWithDiscriminator
|
|
||||||
params:
|
|
||||||
disc_start: 50001
|
|
||||||
kl_weight: 0.000001
|
|
||||||
disc_weight: 0.5
|
|
||||||
|
|
||||||
ddconfig:
|
|
||||||
double_z: True
|
|
||||||
z_channels: 16
|
|
||||||
resolution: 256
|
|
||||||
in_channels: 3
|
|
||||||
out_ch: 3
|
|
||||||
ch: 128
|
|
||||||
ch_mult: [ 1,1,2,2,4] # num_down = len(ch_mult)-1
|
|
||||||
num_res_blocks: 2
|
|
||||||
attn_resolutions: [16]
|
|
||||||
dropout: 0.0
|
|
||||||
|
|
||||||
|
|
||||||
data:
|
|
||||||
target: main.DataModuleFromConfig
|
|
||||||
params:
|
|
||||||
batch_size: 12
|
|
||||||
wrap: True
|
|
||||||
train:
|
|
||||||
target: ldm.data.imagenet.ImageNetSRTrain
|
|
||||||
params:
|
|
||||||
size: 256
|
|
||||||
degradation: pil_nearest
|
|
||||||
validation:
|
|
||||||
target: ldm.data.imagenet.ImageNetSRValidation
|
|
||||||
params:
|
|
||||||
size: 256
|
|
||||||
degradation: pil_nearest
|
|
||||||
|
|
||||||
lightning:
|
|
||||||
callbacks:
|
|
||||||
image_logger:
|
|
||||||
target: main.ImageLogger
|
|
||||||
params:
|
|
||||||
batch_frequency: 1000
|
|
||||||
max_images: 8
|
|
||||||
increase_log_steps: True
|
|
||||||
|
|
||||||
trainer:
|
|
||||||
benchmark: True
|
|
||||||
accumulate_grad_batches: 2
|
|
@ -1,53 +0,0 @@
|
|||||||
model:
|
|
||||||
base_learning_rate: 4.5e-6
|
|
||||||
target: ldm.models.autoencoder.AutoencoderKL
|
|
||||||
params:
|
|
||||||
monitor: "val/rec_loss"
|
|
||||||
embed_dim: 4
|
|
||||||
lossconfig:
|
|
||||||
target: ldm.modules.losses.LPIPSWithDiscriminator
|
|
||||||
params:
|
|
||||||
disc_start: 50001
|
|
||||||
kl_weight: 0.000001
|
|
||||||
disc_weight: 0.5
|
|
||||||
|
|
||||||
ddconfig:
|
|
||||||
double_z: True
|
|
||||||
z_channels: 4
|
|
||||||
resolution: 256
|
|
||||||
in_channels: 3
|
|
||||||
out_ch: 3
|
|
||||||
ch: 128
|
|
||||||
ch_mult: [ 1,2,4,4 ] # num_down = len(ch_mult)-1
|
|
||||||
num_res_blocks: 2
|
|
||||||
attn_resolutions: [ ]
|
|
||||||
dropout: 0.0
|
|
||||||
|
|
||||||
data:
|
|
||||||
target: main.DataModuleFromConfig
|
|
||||||
params:
|
|
||||||
batch_size: 12
|
|
||||||
wrap: True
|
|
||||||
train:
|
|
||||||
target: ldm.data.imagenet.ImageNetSRTrain
|
|
||||||
params:
|
|
||||||
size: 256
|
|
||||||
degradation: pil_nearest
|
|
||||||
validation:
|
|
||||||
target: ldm.data.imagenet.ImageNetSRValidation
|
|
||||||
params:
|
|
||||||
size: 256
|
|
||||||
degradation: pil_nearest
|
|
||||||
|
|
||||||
lightning:
|
|
||||||
callbacks:
|
|
||||||
image_logger:
|
|
||||||
target: main.ImageLogger
|
|
||||||
params:
|
|
||||||
batch_frequency: 1000
|
|
||||||
max_images: 8
|
|
||||||
increase_log_steps: True
|
|
||||||
|
|
||||||
trainer:
|
|
||||||
benchmark: True
|
|
||||||
accumulate_grad_batches: 2
|
|
@ -1,54 +0,0 @@
|
|||||||
model:
|
|
||||||
base_learning_rate: 4.5e-6
|
|
||||||
target: ldm.models.autoencoder.AutoencoderKL
|
|
||||||
params:
|
|
||||||
monitor: "val/rec_loss"
|
|
||||||
embed_dim: 3
|
|
||||||
lossconfig:
|
|
||||||
target: ldm.modules.losses.LPIPSWithDiscriminator
|
|
||||||
params:
|
|
||||||
disc_start: 50001
|
|
||||||
kl_weight: 0.000001
|
|
||||||
disc_weight: 0.5
|
|
||||||
|
|
||||||
ddconfig:
|
|
||||||
double_z: True
|
|
||||||
z_channels: 3
|
|
||||||
resolution: 256
|
|
||||||
in_channels: 3
|
|
||||||
out_ch: 3
|
|
||||||
ch: 128
|
|
||||||
ch_mult: [ 1,2,4 ] # num_down = len(ch_mult)-1
|
|
||||||
num_res_blocks: 2
|
|
||||||
attn_resolutions: [ ]
|
|
||||||
dropout: 0.0
|
|
||||||
|
|
||||||
|
|
||||||
data:
|
|
||||||
target: main.DataModuleFromConfig
|
|
||||||
params:
|
|
||||||
batch_size: 12
|
|
||||||
wrap: True
|
|
||||||
train:
|
|
||||||
target: ldm.data.imagenet.ImageNetSRTrain
|
|
||||||
params:
|
|
||||||
size: 256
|
|
||||||
degradation: pil_nearest
|
|
||||||
validation:
|
|
||||||
target: ldm.data.imagenet.ImageNetSRValidation
|
|
||||||
params:
|
|
||||||
size: 256
|
|
||||||
degradation: pil_nearest
|
|
||||||
|
|
||||||
lightning:
|
|
||||||
callbacks:
|
|
||||||
image_logger:
|
|
||||||
target: main.ImageLogger
|
|
||||||
params:
|
|
||||||
batch_frequency: 1000
|
|
||||||
max_images: 8
|
|
||||||
increase_log_steps: True
|
|
||||||
|
|
||||||
trainer:
|
|
||||||
benchmark: True
|
|
||||||
accumulate_grad_batches: 2
|
|
@ -1,53 +0,0 @@
|
|||||||
model:
|
|
||||||
base_learning_rate: 4.5e-6
|
|
||||||
target: ldm.models.autoencoder.AutoencoderKL
|
|
||||||
params:
|
|
||||||
monitor: "val/rec_loss"
|
|
||||||
embed_dim: 64
|
|
||||||
lossconfig:
|
|
||||||
target: ldm.modules.losses.LPIPSWithDiscriminator
|
|
||||||
params:
|
|
||||||
disc_start: 50001
|
|
||||||
kl_weight: 0.000001
|
|
||||||
disc_weight: 0.5
|
|
||||||
|
|
||||||
ddconfig:
|
|
||||||
double_z: True
|
|
||||||
z_channels: 64
|
|
||||||
resolution: 256
|
|
||||||
in_channels: 3
|
|
||||||
out_ch: 3
|
|
||||||
ch: 128
|
|
||||||
ch_mult: [ 1,1,2,2,4,4] # num_down = len(ch_mult)-1
|
|
||||||
num_res_blocks: 2
|
|
||||||
attn_resolutions: [16,8]
|
|
||||||
dropout: 0.0
|
|
||||||
|
|
||||||
data:
|
|
||||||
target: main.DataModuleFromConfig
|
|
||||||
params:
|
|
||||||
batch_size: 12
|
|
||||||
wrap: True
|
|
||||||
train:
|
|
||||||
target: ldm.data.imagenet.ImageNetSRTrain
|
|
||||||
params:
|
|
||||||
size: 256
|
|
||||||
degradation: pil_nearest
|
|
||||||
validation:
|
|
||||||
target: ldm.data.imagenet.ImageNetSRValidation
|
|
||||||
params:
|
|
||||||
size: 256
|
|
||||||
degradation: pil_nearest
|
|
||||||
|
|
||||||
lightning:
|
|
||||||
callbacks:
|
|
||||||
image_logger:
|
|
||||||
target: main.ImageLogger
|
|
||||||
params:
|
|
||||||
batch_frequency: 1000
|
|
||||||
max_images: 8
|
|
||||||
increase_log_steps: True
|
|
||||||
|
|
||||||
trainer:
|
|
||||||
benchmark: True
|
|
||||||
accumulate_grad_batches: 2
|
|
@ -1,86 +0,0 @@
|
|||||||
model:
|
|
||||||
base_learning_rate: 2.0e-06
|
|
||||||
target: ldm.models.diffusion.ddpm.LatentDiffusion
|
|
||||||
params:
|
|
||||||
linear_start: 0.0015
|
|
||||||
linear_end: 0.0195
|
|
||||||
num_timesteps_cond: 1
|
|
||||||
log_every_t: 200
|
|
||||||
timesteps: 1000
|
|
||||||
first_stage_key: image
|
|
||||||
image_size: 64
|
|
||||||
channels: 3
|
|
||||||
monitor: val/loss_simple_ema
|
|
||||||
|
|
||||||
unet_config:
|
|
||||||
target: ldm.modules.diffusionmodules.openaimodel.UNetModel
|
|
||||||
params:
|
|
||||||
image_size: 64
|
|
||||||
in_channels: 3
|
|
||||||
out_channels: 3
|
|
||||||
model_channels: 224
|
|
||||||
attention_resolutions:
|
|
||||||
# note: this isn\t actually the resolution but
|
|
||||||
# the downsampling factor, i.e. this corresnponds to
|
|
||||||
# attention on spatial resolution 8,16,32, as the
|
|
||||||
# spatial reolution of the latents is 64 for f4
|
|
||||||
- 8
|
|
||||||
- 4
|
|
||||||
- 2
|
|
||||||
num_res_blocks: 2
|
|
||||||
channel_mult:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- 3
|
|
||||||
- 4
|
|
||||||
num_head_channels: 32
|
|
||||||
first_stage_config:
|
|
||||||
target: ldm.models.autoencoder.VQModelInterface
|
|
||||||
params:
|
|
||||||
embed_dim: 3
|
|
||||||
n_embed: 8192
|
|
||||||
ckpt_path: models/first_stage_models/vq-f4/model.ckpt
|
|
||||||
ddconfig:
|
|
||||||
double_z: false
|
|
||||||
z_channels: 3
|
|
||||||
resolution: 256
|
|
||||||
in_channels: 3
|
|
||||||
out_ch: 3
|
|
||||||
ch: 128
|
|
||||||
ch_mult:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- 4
|
|
||||||
num_res_blocks: 2
|
|
||||||
attn_resolutions: []
|
|
||||||
dropout: 0.0
|
|
||||||
lossconfig:
|
|
||||||
target: torch.nn.Identity
|
|
||||||
cond_stage_config: __is_unconditional__
|
|
||||||
data:
|
|
||||||
target: main.DataModuleFromConfig
|
|
||||||
params:
|
|
||||||
batch_size: 48
|
|
||||||
num_workers: 5
|
|
||||||
wrap: false
|
|
||||||
train:
|
|
||||||
target: taming.data.faceshq.CelebAHQTrain
|
|
||||||
params:
|
|
||||||
size: 256
|
|
||||||
validation:
|
|
||||||
target: taming.data.faceshq.CelebAHQValidation
|
|
||||||
params:
|
|
||||||
size: 256
|
|
||||||
|
|
||||||
|
|
||||||
lightning:
|
|
||||||
callbacks:
|
|
||||||
image_logger:
|
|
||||||
target: main.ImageLogger
|
|
||||||
params:
|
|
||||||
batch_frequency: 5000
|
|
||||||
max_images: 8
|
|
||||||
increase_log_steps: False
|
|
||||||
|
|
||||||
trainer:
|
|
||||||
benchmark: True
|
|
@ -1,98 +0,0 @@
|
|||||||
model:
|
|
||||||
base_learning_rate: 1.0e-06
|
|
||||||
target: ldm.models.diffusion.ddpm.LatentDiffusion
|
|
||||||
params:
|
|
||||||
linear_start: 0.0015
|
|
||||||
linear_end: 0.0195
|
|
||||||
num_timesteps_cond: 1
|
|
||||||
log_every_t: 200
|
|
||||||
timesteps: 1000
|
|
||||||
first_stage_key: image
|
|
||||||
cond_stage_key: class_label
|
|
||||||
image_size: 32
|
|
||||||
channels: 4
|
|
||||||
cond_stage_trainable: true
|
|
||||||
conditioning_key: crossattn
|
|
||||||
monitor: val/loss_simple_ema
|
|
||||||
unet_config:
|
|
||||||
target: ldm.modules.diffusionmodules.openaimodel.UNetModel
|
|
||||||
params:
|
|
||||||
image_size: 32
|
|
||||||
in_channels: 4
|
|
||||||
out_channels: 4
|
|
||||||
model_channels: 256
|
|
||||||
attention_resolutions:
|
|
||||||
#note: this isn\t actually the resolution but
|
|
||||||
# the downsampling factor, i.e. this corresnponds to
|
|
||||||
# attention on spatial resolution 8,16,32, as the
|
|
||||||
# spatial reolution of the latents is 32 for f8
|
|
||||||
- 4
|
|
||||||
- 2
|
|
||||||
- 1
|
|
||||||
num_res_blocks: 2
|
|
||||||
channel_mult:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- 4
|
|
||||||
num_head_channels: 32
|
|
||||||
use_spatial_transformer: true
|
|
||||||
transformer_depth: 1
|
|
||||||
context_dim: 512
|
|
||||||
first_stage_config:
|
|
||||||
target: ldm.models.autoencoder.VQModelInterface
|
|
||||||
params:
|
|
||||||
embed_dim: 4
|
|
||||||
n_embed: 16384
|
|
||||||
ckpt_path: configs/first_stage_models/vq-f8/model.yaml
|
|
||||||
ddconfig:
|
|
||||||
double_z: false
|
|
||||||
z_channels: 4
|
|
||||||
resolution: 256
|
|
||||||
in_channels: 3
|
|
||||||
out_ch: 3
|
|
||||||
ch: 128
|
|
||||||
ch_mult:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- 2
|
|
||||||
- 4
|
|
||||||
num_res_blocks: 2
|
|
||||||
attn_resolutions:
|
|
||||||
- 32
|
|
||||||
dropout: 0.0
|
|
||||||
lossconfig:
|
|
||||||
target: torch.nn.Identity
|
|
||||||
cond_stage_config:
|
|
||||||
target: ldm.modules.encoders.modules.ClassEmbedder
|
|
||||||
params:
|
|
||||||
embed_dim: 512
|
|
||||||
key: class_label
|
|
||||||
data:
|
|
||||||
target: main.DataModuleFromConfig
|
|
||||||
params:
|
|
||||||
batch_size: 64
|
|
||||||
num_workers: 12
|
|
||||||
wrap: false
|
|
||||||
train:
|
|
||||||
target: ldm.data.imagenet.ImageNetTrain
|
|
||||||
params:
|
|
||||||
config:
|
|
||||||
size: 256
|
|
||||||
validation:
|
|
||||||
target: ldm.data.imagenet.ImageNetValidation
|
|
||||||
params:
|
|
||||||
config:
|
|
||||||
size: 256
|
|
||||||
|
|
||||||
|
|
||||||
lightning:
|
|
||||||
callbacks:
|
|
||||||
image_logger:
|
|
||||||
target: main.ImageLogger
|
|
||||||
params:
|
|
||||||
batch_frequency: 5000
|
|
||||||
max_images: 8
|
|
||||||
increase_log_steps: False
|
|
||||||
|
|
||||||
trainer:
|
|
||||||
benchmark: True
|
|
@ -1,68 +0,0 @@
|
|||||||
model:
|
|
||||||
base_learning_rate: 0.0001
|
|
||||||
target: ldm.models.diffusion.ddpm.LatentDiffusion
|
|
||||||
params:
|
|
||||||
linear_start: 0.0015
|
|
||||||
linear_end: 0.0195
|
|
||||||
num_timesteps_cond: 1
|
|
||||||
log_every_t: 200
|
|
||||||
timesteps: 1000
|
|
||||||
first_stage_key: image
|
|
||||||
cond_stage_key: class_label
|
|
||||||
image_size: 64
|
|
||||||
channels: 3
|
|
||||||
cond_stage_trainable: true
|
|
||||||
conditioning_key: crossattn
|
|
||||||
monitor: val/loss
|
|
||||||
use_ema: False
|
|
||||||
|
|
||||||
unet_config:
|
|
||||||
target: ldm.modules.diffusionmodules.openaimodel.UNetModel
|
|
||||||
params:
|
|
||||||
image_size: 64
|
|
||||||
in_channels: 3
|
|
||||||
out_channels: 3
|
|
||||||
model_channels: 192
|
|
||||||
attention_resolutions:
|
|
||||||
- 8
|
|
||||||
- 4
|
|
||||||
- 2
|
|
||||||
num_res_blocks: 2
|
|
||||||
channel_mult:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- 3
|
|
||||||
- 5
|
|
||||||
num_heads: 1
|
|
||||||
use_spatial_transformer: true
|
|
||||||
transformer_depth: 1
|
|
||||||
context_dim: 512
|
|
||||||
|
|
||||||
first_stage_config:
|
|
||||||
target: ldm.models.autoencoder.VQModelInterface
|
|
||||||
params:
|
|
||||||
embed_dim: 3
|
|
||||||
n_embed: 8192
|
|
||||||
ddconfig:
|
|
||||||
double_z: false
|
|
||||||
z_channels: 3
|
|
||||||
resolution: 256
|
|
||||||
in_channels: 3
|
|
||||||
out_ch: 3
|
|
||||||
ch: 128
|
|
||||||
ch_mult:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- 4
|
|
||||||
num_res_blocks: 2
|
|
||||||
attn_resolutions: []
|
|
||||||
dropout: 0.0
|
|
||||||
lossconfig:
|
|
||||||
target: torch.nn.Identity
|
|
||||||
|
|
||||||
cond_stage_config:
|
|
||||||
target: ldm.modules.encoders.modules.ClassEmbedder
|
|
||||||
params:
|
|
||||||
n_classes: 1001
|
|
||||||
embed_dim: 512
|
|
||||||
key: class_label
|
|
@ -1,85 +0,0 @@
|
|||||||
model:
|
|
||||||
base_learning_rate: 2.0e-06
|
|
||||||
target: ldm.models.diffusion.ddpm.LatentDiffusion
|
|
||||||
params:
|
|
||||||
linear_start: 0.0015
|
|
||||||
linear_end: 0.0195
|
|
||||||
num_timesteps_cond: 1
|
|
||||||
log_every_t: 200
|
|
||||||
timesteps: 1000
|
|
||||||
first_stage_key: image
|
|
||||||
image_size: 64
|
|
||||||
channels: 3
|
|
||||||
monitor: val/loss_simple_ema
|
|
||||||
unet_config:
|
|
||||||
target: ldm.modules.diffusionmodules.openaimodel.UNetModel
|
|
||||||
params:
|
|
||||||
image_size: 64
|
|
||||||
in_channels: 3
|
|
||||||
out_channels: 3
|
|
||||||
model_channels: 224
|
|
||||||
attention_resolutions:
|
|
||||||
# note: this isn\t actually the resolution but
|
|
||||||
# the downsampling factor, i.e. this corresnponds to
|
|
||||||
# attention on spatial resolution 8,16,32, as the
|
|
||||||
# spatial reolution of the latents is 64 for f4
|
|
||||||
- 8
|
|
||||||
- 4
|
|
||||||
- 2
|
|
||||||
num_res_blocks: 2
|
|
||||||
channel_mult:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- 3
|
|
||||||
- 4
|
|
||||||
num_head_channels: 32
|
|
||||||
first_stage_config:
|
|
||||||
target: ldm.models.autoencoder.VQModelInterface
|
|
||||||
params:
|
|
||||||
embed_dim: 3
|
|
||||||
n_embed: 8192
|
|
||||||
ckpt_path: configs/first_stage_models/vq-f4/model.yaml
|
|
||||||
ddconfig:
|
|
||||||
double_z: false
|
|
||||||
z_channels: 3
|
|
||||||
resolution: 256
|
|
||||||
in_channels: 3
|
|
||||||
out_ch: 3
|
|
||||||
ch: 128
|
|
||||||
ch_mult:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- 4
|
|
||||||
num_res_blocks: 2
|
|
||||||
attn_resolutions: []
|
|
||||||
dropout: 0.0
|
|
||||||
lossconfig:
|
|
||||||
target: torch.nn.Identity
|
|
||||||
cond_stage_config: __is_unconditional__
|
|
||||||
data:
|
|
||||||
target: main.DataModuleFromConfig
|
|
||||||
params:
|
|
||||||
batch_size: 42
|
|
||||||
num_workers: 5
|
|
||||||
wrap: false
|
|
||||||
train:
|
|
||||||
target: taming.data.faceshq.FFHQTrain
|
|
||||||
params:
|
|
||||||
size: 256
|
|
||||||
validation:
|
|
||||||
target: taming.data.faceshq.FFHQValidation
|
|
||||||
params:
|
|
||||||
size: 256
|
|
||||||
|
|
||||||
|
|
||||||
lightning:
|
|
||||||
callbacks:
|
|
||||||
image_logger:
|
|
||||||
target: main.ImageLogger
|
|
||||||
params:
|
|
||||||
batch_frequency: 5000
|
|
||||||
max_images: 8
|
|
||||||
increase_log_steps: False
|
|
||||||
|
|
||||||
trainer:
|
|
||||||
benchmark: True
|
|
@ -1,85 +0,0 @@
|
|||||||
model:
|
|
||||||
base_learning_rate: 2.0e-06
|
|
||||||
target: ldm.models.diffusion.ddpm.LatentDiffusion
|
|
||||||
params:
|
|
||||||
linear_start: 0.0015
|
|
||||||
linear_end: 0.0195
|
|
||||||
num_timesteps_cond: 1
|
|
||||||
log_every_t: 200
|
|
||||||
timesteps: 1000
|
|
||||||
first_stage_key: image
|
|
||||||
image_size: 64
|
|
||||||
channels: 3
|
|
||||||
monitor: val/loss_simple_ema
|
|
||||||
unet_config:
|
|
||||||
target: ldm.modules.diffusionmodules.openaimodel.UNetModel
|
|
||||||
params:
|
|
||||||
image_size: 64
|
|
||||||
in_channels: 3
|
|
||||||
out_channels: 3
|
|
||||||
model_channels: 224
|
|
||||||
attention_resolutions:
|
|
||||||
# note: this isn\t actually the resolution but
|
|
||||||
# the downsampling factor, i.e. this corresnponds to
|
|
||||||
# attention on spatial resolution 8,16,32, as the
|
|
||||||
# spatial reolution of the latents is 64 for f4
|
|
||||||
- 8
|
|
||||||
- 4
|
|
||||||
- 2
|
|
||||||
num_res_blocks: 2
|
|
||||||
channel_mult:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- 3
|
|
||||||
- 4
|
|
||||||
num_head_channels: 32
|
|
||||||
first_stage_config:
|
|
||||||
target: ldm.models.autoencoder.VQModelInterface
|
|
||||||
params:
|
|
||||||
ckpt_path: configs/first_stage_models/vq-f4/model.yaml
|
|
||||||
embed_dim: 3
|
|
||||||
n_embed: 8192
|
|
||||||
ddconfig:
|
|
||||||
double_z: false
|
|
||||||
z_channels: 3
|
|
||||||
resolution: 256
|
|
||||||
in_channels: 3
|
|
||||||
out_ch: 3
|
|
||||||
ch: 128
|
|
||||||
ch_mult:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- 4
|
|
||||||
num_res_blocks: 2
|
|
||||||
attn_resolutions: []
|
|
||||||
dropout: 0.0
|
|
||||||
lossconfig:
|
|
||||||
target: torch.nn.Identity
|
|
||||||
cond_stage_config: __is_unconditional__
|
|
||||||
data:
|
|
||||||
target: main.DataModuleFromConfig
|
|
||||||
params:
|
|
||||||
batch_size: 48
|
|
||||||
num_workers: 5
|
|
||||||
wrap: false
|
|
||||||
train:
|
|
||||||
target: ldm.data.lsun.LSUNBedroomsTrain
|
|
||||||
params:
|
|
||||||
size: 256
|
|
||||||
validation:
|
|
||||||
target: ldm.data.lsun.LSUNBedroomsValidation
|
|
||||||
params:
|
|
||||||
size: 256
|
|
||||||
|
|
||||||
|
|
||||||
lightning:
|
|
||||||
callbacks:
|
|
||||||
image_logger:
|
|
||||||
target: main.ImageLogger
|
|
||||||
params:
|
|
||||||
batch_frequency: 5000
|
|
||||||
max_images: 8
|
|
||||||
increase_log_steps: False
|
|
||||||
|
|
||||||
trainer:
|
|
||||||
benchmark: True
|
|
@ -1,91 +0,0 @@
|
|||||||
model:
|
|
||||||
base_learning_rate: 5.0e-5 # set to target_lr by starting main.py with '--scale_lr False'
|
|
||||||
target: ldm.models.diffusion.ddpm.LatentDiffusion
|
|
||||||
params:
|
|
||||||
linear_start: 0.0015
|
|
||||||
linear_end: 0.0155
|
|
||||||
num_timesteps_cond: 1
|
|
||||||
log_every_t: 200
|
|
||||||
timesteps: 1000
|
|
||||||
loss_type: l1
|
|
||||||
first_stage_key: "image"
|
|
||||||
cond_stage_key: "image"
|
|
||||||
image_size: 32
|
|
||||||
channels: 4
|
|
||||||
cond_stage_trainable: False
|
|
||||||
concat_mode: False
|
|
||||||
scale_by_std: True
|
|
||||||
monitor: 'val/loss_simple_ema'
|
|
||||||
|
|
||||||
scheduler_config: # 10000 warmup steps
|
|
||||||
target: ldm.lr_scheduler.LambdaLinearScheduler
|
|
||||||
params:
|
|
||||||
warm_up_steps: [10000]
|
|
||||||
cycle_lengths: [10000000000000]
|
|
||||||
f_start: [1.e-6]
|
|
||||||
f_max: [1.]
|
|
||||||
f_min: [ 1.]
|
|
||||||
|
|
||||||
unet_config:
|
|
||||||
target: ldm.modules.diffusionmodules.openaimodel.UNetModel
|
|
||||||
params:
|
|
||||||
image_size: 32
|
|
||||||
in_channels: 4
|
|
||||||
out_channels: 4
|
|
||||||
model_channels: 192
|
|
||||||
attention_resolutions: [ 1, 2, 4, 8 ] # 32, 16, 8, 4
|
|
||||||
num_res_blocks: 2
|
|
||||||
channel_mult: [ 1,2,2,4,4 ] # 32, 16, 8, 4, 2
|
|
||||||
num_heads: 8
|
|
||||||
use_scale_shift_norm: True
|
|
||||||
resblock_updown: True
|
|
||||||
|
|
||||||
first_stage_config:
|
|
||||||
target: ldm.models.autoencoder.AutoencoderKL
|
|
||||||
params:
|
|
||||||
embed_dim: 4
|
|
||||||
monitor: "val/rec_loss"
|
|
||||||
ckpt_path: "models/first_stage_models/kl-f8/model.ckpt"
|
|
||||||
ddconfig:
|
|
||||||
double_z: True
|
|
||||||
z_channels: 4
|
|
||||||
resolution: 256
|
|
||||||
in_channels: 3
|
|
||||||
out_ch: 3
|
|
||||||
ch: 128
|
|
||||||
ch_mult: [ 1,2,4,4 ] # num_down = len(ch_mult)-1
|
|
||||||
num_res_blocks: 2
|
|
||||||
attn_resolutions: [ ]
|
|
||||||
dropout: 0.0
|
|
||||||
lossconfig:
|
|
||||||
target: torch.nn.Identity
|
|
||||||
|
|
||||||
cond_stage_config: "__is_unconditional__"
|
|
||||||
|
|
||||||
data:
|
|
||||||
target: main.DataModuleFromConfig
|
|
||||||
params:
|
|
||||||
batch_size: 96
|
|
||||||
num_workers: 5
|
|
||||||
wrap: False
|
|
||||||
train:
|
|
||||||
target: ldm.data.lsun.LSUNChurchesTrain
|
|
||||||
params:
|
|
||||||
size: 256
|
|
||||||
validation:
|
|
||||||
target: ldm.data.lsun.LSUNChurchesValidation
|
|
||||||
params:
|
|
||||||
size: 256
|
|
||||||
|
|
||||||
lightning:
|
|
||||||
callbacks:
|
|
||||||
image_logger:
|
|
||||||
target: main.ImageLogger
|
|
||||||
params:
|
|
||||||
batch_frequency: 5000
|
|
||||||
max_images: 8
|
|
||||||
increase_log_steps: False
|
|
||||||
|
|
||||||
|
|
||||||
trainer:
|
|
||||||
benchmark: True
|
|
@ -1,71 +0,0 @@
|
|||||||
model:
|
|
||||||
base_learning_rate: 5.0e-05
|
|
||||||
target: ldm.models.diffusion.ddpm.LatentDiffusion
|
|
||||||
params:
|
|
||||||
linear_start: 0.00085
|
|
||||||
linear_end: 0.012
|
|
||||||
num_timesteps_cond: 1
|
|
||||||
log_every_t: 200
|
|
||||||
timesteps: 1000
|
|
||||||
first_stage_key: image
|
|
||||||
cond_stage_key: caption
|
|
||||||
image_size: 32
|
|
||||||
channels: 4
|
|
||||||
cond_stage_trainable: true
|
|
||||||
conditioning_key: crossattn
|
|
||||||
monitor: val/loss_simple_ema
|
|
||||||
scale_factor: 0.18215
|
|
||||||
use_ema: False
|
|
||||||
|
|
||||||
unet_config:
|
|
||||||
target: ldm.modules.diffusionmodules.openaimodel.UNetModel
|
|
||||||
params:
|
|
||||||
image_size: 32
|
|
||||||
in_channels: 4
|
|
||||||
out_channels: 4
|
|
||||||
model_channels: 320
|
|
||||||
attention_resolutions:
|
|
||||||
- 4
|
|
||||||
- 2
|
|
||||||
- 1
|
|
||||||
num_res_blocks: 2
|
|
||||||
channel_mult:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- 4
|
|
||||||
- 4
|
|
||||||
num_heads: 8
|
|
||||||
use_spatial_transformer: true
|
|
||||||
transformer_depth: 1
|
|
||||||
context_dim: 1280
|
|
||||||
use_checkpoint: true
|
|
||||||
legacy: False
|
|
||||||
|
|
||||||
first_stage_config:
|
|
||||||
target: ldm.models.autoencoder.AutoencoderKL
|
|
||||||
params:
|
|
||||||
embed_dim: 4
|
|
||||||
monitor: val/rec_loss
|
|
||||||
ddconfig:
|
|
||||||
double_z: true
|
|
||||||
z_channels: 4
|
|
||||||
resolution: 256
|
|
||||||
in_channels: 3
|
|
||||||
out_ch: 3
|
|
||||||
ch: 128
|
|
||||||
ch_mult:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- 4
|
|
||||||
- 4
|
|
||||||
num_res_blocks: 2
|
|
||||||
attn_resolutions: []
|
|
||||||
dropout: 0.0
|
|
||||||
lossconfig:
|
|
||||||
target: torch.nn.Identity
|
|
||||||
|
|
||||||
cond_stage_config:
|
|
||||||
target: ldm.modules.encoders.modules.BERTEmbedder
|
|
||||||
params:
|
|
||||||
n_embed: 1280
|
|
||||||
n_layer: 32
|
|
@ -1,20 +0,0 @@
|
|||||||
# This file describes the alternative machine learning models
|
|
||||||
# available to the dream 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.
|
|
||||||
|
|
||||||
laion400m:
|
|
||||||
config: configs/latent-diffusion/txt2img-1p4B-eval.yaml
|
|
||||||
weights: models/ldm/text2img-large/model.ckpt
|
|
||||||
description: Latent Diffusion LAION400M model
|
|
||||||
width: 256
|
|
||||||
height: 256
|
|
||||||
stable-diffusion-1.4:
|
|
||||||
config: configs/stable-diffusion/v1-inference.yaml
|
|
||||||
weights: models/ldm/stable-diffusion-v1/model.ckpt
|
|
||||||
description: Stable Diffusion inference model version 1.4
|
|
||||||
width: 512
|
|
||||||
height: 512
|
|
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
|
@ -1,68 +0,0 @@
|
|||||||
model:
|
|
||||||
base_learning_rate: 0.0001
|
|
||||||
target: ldm.models.diffusion.ddpm.LatentDiffusion
|
|
||||||
params:
|
|
||||||
linear_start: 0.0015
|
|
||||||
linear_end: 0.015
|
|
||||||
num_timesteps_cond: 1
|
|
||||||
log_every_t: 200
|
|
||||||
timesteps: 1000
|
|
||||||
first_stage_key: jpg
|
|
||||||
cond_stage_key: nix
|
|
||||||
image_size: 48
|
|
||||||
channels: 16
|
|
||||||
cond_stage_trainable: false
|
|
||||||
conditioning_key: crossattn
|
|
||||||
monitor: val/loss_simple_ema
|
|
||||||
scale_by_std: false
|
|
||||||
scale_factor: 0.22765929
|
|
||||||
unet_config:
|
|
||||||
target: ldm.modules.diffusionmodules.openaimodel.UNetModel
|
|
||||||
params:
|
|
||||||
image_size: 48
|
|
||||||
in_channels: 16
|
|
||||||
out_channels: 16
|
|
||||||
model_channels: 448
|
|
||||||
attention_resolutions:
|
|
||||||
- 4
|
|
||||||
- 2
|
|
||||||
- 1
|
|
||||||
num_res_blocks: 2
|
|
||||||
channel_mult:
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- 3
|
|
||||||
- 4
|
|
||||||
use_scale_shift_norm: false
|
|
||||||
resblock_updown: false
|
|
||||||
num_head_channels: 32
|
|
||||||
use_spatial_transformer: true
|
|
||||||
transformer_depth: 1
|
|
||||||
context_dim: 768
|
|
||||||
use_checkpoint: true
|
|
||||||
first_stage_config:
|
|
||||||
target: ldm.models.autoencoder.AutoencoderKL
|
|
||||||
params:
|
|
||||||
monitor: val/rec_loss
|
|
||||||
embed_dim: 16
|
|
||||||
ddconfig:
|
|
||||||
double_z: true
|
|
||||||
z_channels: 16
|
|
||||||
resolution: 256
|
|
||||||
in_channels: 3
|
|
||||||
out_ch: 3
|
|
||||||
ch: 128
|
|
||||||
ch_mult:
|
|
||||||
- 1
|
|
||||||
- 1
|
|
||||||
- 2
|
|
||||||
- 2
|
|
||||||
- 4
|
|
||||||
num_res_blocks: 2
|
|
||||||
attn_resolutions:
|
|
||||||
- 16
|
|
||||||
dropout: 0.0
|
|
||||||
lossconfig:
|
|
||||||
target: torch.nn.Identity
|
|
||||||
cond_stage_config:
|
|
||||||
target: torch.nn.Identity
|
|
@ -76,4 +76,4 @@ model:
|
|||||||
target: torch.nn.Identity
|
target: torch.nn.Identity
|
||||||
|
|
||||||
cond_stage_config:
|
cond_stage_config:
|
||||||
target: ldm.modules.encoders.modules.FrozenCLIPEmbedder
|
target: ldm.modules.encoders.modules.WeightedFrozenCLIPEmbedder
|
||||||
|
79
configs/stable-diffusion/v1-inpainting-inference.yaml
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
model:
|
||||||
|
base_learning_rate: 7.5e-05
|
||||||
|
target: ldm.models.diffusion.ddpm.LatentInpaintDiffusion
|
||||||
|
params:
|
||||||
|
linear_start: 0.00085
|
||||||
|
linear_end: 0.0120
|
||||||
|
num_timesteps_cond: 1
|
||||||
|
log_every_t: 200
|
||||||
|
timesteps: 1000
|
||||||
|
first_stage_key: "jpg"
|
||||||
|
cond_stage_key: "txt"
|
||||||
|
image_size: 64
|
||||||
|
channels: 4
|
||||||
|
cond_stage_trainable: false # Note: different from the one we trained before
|
||||||
|
conditioning_key: hybrid # important
|
||||||
|
monitor: val/loss_simple_ema
|
||||||
|
scale_factor: 0.18215
|
||||||
|
finetune_keys: null
|
||||||
|
|
||||||
|
scheduler_config: # 10000 warmup steps
|
||||||
|
target: ldm.lr_scheduler.LambdaLinearScheduler
|
||||||
|
params:
|
||||||
|
warm_up_steps: [ 2500 ] # NOTE for resuming. use 10000 if starting from scratch
|
||||||
|
cycle_lengths: [ 10000000000000 ] # incredibly large number to prevent corner cases
|
||||||
|
f_start: [ 1.e-6 ]
|
||||||
|
f_max: [ 1. ]
|
||||||
|
f_min: [ 1. ]
|
||||||
|
|
||||||
|
personalization_config:
|
||||||
|
target: ldm.modules.embedding_manager.EmbeddingManager
|
||||||
|
params:
|
||||||
|
placeholder_strings: ["*"]
|
||||||
|
initializer_words: ['face', 'man', 'photo', 'africanmale']
|
||||||
|
per_image_tokens: false
|
||||||
|
num_vectors_per_token: 1
|
||||||
|
progressive_words: False
|
||||||
|
|
||||||
|
unet_config:
|
||||||
|
target: ldm.modules.diffusionmodules.openaimodel.UNetModel
|
||||||
|
params:
|
||||||
|
image_size: 32 # unused
|
||||||
|
in_channels: 9 # 4 data + 4 downscaled image + 1 mask
|
||||||
|
out_channels: 4
|
||||||
|
model_channels: 320
|
||||||
|
attention_resolutions: [ 4, 2, 1 ]
|
||||||
|
num_res_blocks: 2
|
||||||
|
channel_mult: [ 1, 2, 4, 4 ]
|
||||||
|
num_heads: 8
|
||||||
|
use_spatial_transformer: True
|
||||||
|
transformer_depth: 1
|
||||||
|
context_dim: 768
|
||||||
|
use_checkpoint: True
|
||||||
|
legacy: False
|
||||||
|
|
||||||
|
first_stage_config:
|
||||||
|
target: ldm.models.autoencoder.AutoencoderKL
|
||||||
|
params:
|
||||||
|
embed_dim: 4
|
||||||
|
monitor: val/rec_loss
|
||||||
|
ddconfig:
|
||||||
|
double_z: true
|
||||||
|
z_channels: 4
|
||||||
|
resolution: 256
|
||||||
|
in_channels: 3
|
||||||
|
out_ch: 3
|
||||||
|
ch: 128
|
||||||
|
ch_mult:
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
- 4
|
||||||
|
- 4
|
||||||
|
num_res_blocks: 2
|
||||||
|
attn_resolutions: []
|
||||||
|
dropout: 0.0
|
||||||
|
lossconfig:
|
||||||
|
target: torch.nn.Identity
|
||||||
|
|
||||||
|
cond_stage_config:
|
||||||
|
target: ldm.modules.encoders.modules.WeightedFrozenCLIPEmbedder
|
@ -1,57 +1,74 @@
|
|||||||
FROM debian
|
FROM ubuntu AS get_miniconda
|
||||||
|
|
||||||
ARG gsd
|
|
||||||
ENV GITHUB_STABLE_DIFFUSION $gsd
|
|
||||||
|
|
||||||
ARG rsd
|
|
||||||
ENV REQS $rsd
|
|
||||||
|
|
||||||
ARG cs
|
|
||||||
ENV CONDA_SUBDIR $cs
|
|
||||||
|
|
||||||
ENV PIP_EXISTS_ACTION="w"
|
|
||||||
|
|
||||||
# TODO: Optimize image size
|
|
||||||
|
|
||||||
SHELL ["/bin/bash", "-c"]
|
SHELL ["/bin/bash", "-c"]
|
||||||
|
|
||||||
WORKDIR /
|
# install wget
|
||||||
RUN apt update && apt upgrade -y \
|
RUN apt-get update \
|
||||||
&& apt install -y \
|
&& apt-get install -y \
|
||||||
|
wget \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# download and install miniconda
|
||||||
|
ARG conda_version=py39_4.12.0-Linux-x86_64
|
||||||
|
ARG conda_prefix=/opt/conda
|
||||||
|
RUN wget --progress=dot:giga -O /miniconda.sh \
|
||||||
|
https://repo.anaconda.com/miniconda/Miniconda3-${conda_version}.sh \
|
||||||
|
&& bash /miniconda.sh -b -p ${conda_prefix} \
|
||||||
|
&& rm -f /miniconda.sh
|
||||||
|
|
||||||
|
FROM ubuntu AS invokeai
|
||||||
|
|
||||||
|
# use bash
|
||||||
|
SHELL [ "/bin/bash", "-c" ]
|
||||||
|
|
||||||
|
# clean bashrc
|
||||||
|
RUN echo "" > ~/.bashrc
|
||||||
|
|
||||||
|
# Install necesarry packages
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y \
|
||||||
|
--no-install-recommends \
|
||||||
|
gcc \
|
||||||
git \
|
git \
|
||||||
libgl1-mesa-glx \
|
libgl1-mesa-glx \
|
||||||
libglib2.0-0 \
|
libglib2.0-0 \
|
||||||
pip \
|
pip \
|
||||||
python3 \
|
python3 \
|
||||||
&& git clone $GITHUB_STABLE_DIFFUSION
|
python3-dev \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Install Anaconda or Miniconda
|
# clone repository and create symlinks
|
||||||
COPY anaconda.sh .
|
ARG invokeai_git=https://github.com/invoke-ai/InvokeAI.git
|
||||||
RUN bash anaconda.sh -b -u -p /anaconda && /anaconda/bin/conda init bash
|
ARG project_name=invokeai
|
||||||
|
RUN git clone ${invokeai_git} /${project_name} \
|
||||||
|
&& mkdir /${project_name}/models/ldm/stable-diffusion-v1 \
|
||||||
|
&& ln -s /data/models/sd-v1-4.ckpt /${project_name}/models/ldm/stable-diffusion-v1/model.ckpt \
|
||||||
|
&& ln -s /data/outputs/ /${project_name}/outputs
|
||||||
|
|
||||||
# SD
|
# set workdir
|
||||||
WORKDIR /stable-diffusion
|
WORKDIR /${project_name}
|
||||||
RUN source ~/.bashrc \
|
|
||||||
&& conda create -y --name ldm && conda activate ldm \
|
|
||||||
&& conda config --env --set subdir $CONDA_SUBDIR \
|
|
||||||
&& pip3 install -r $REQS \
|
|
||||||
&& pip3 install basicsr facexlib realesrgan \
|
|
||||||
&& mkdir models/ldm/stable-diffusion-v1 \
|
|
||||||
&& ln -s "/data/sd-v1-4.ckpt" models/ldm/stable-diffusion-v1/model.ckpt
|
|
||||||
|
|
||||||
# Face restoreation
|
# install conda env and preload models
|
||||||
# by default expected in a sibling directory to stable-diffusion
|
ARG conda_prefix=/opt/conda
|
||||||
WORKDIR /
|
ARG conda_env_file=environment.yml
|
||||||
RUN git clone https://github.com/TencentARC/GFPGAN.git
|
COPY --from=get_miniconda ${conda_prefix} ${conda_prefix}
|
||||||
|
RUN source ${conda_prefix}/etc/profile.d/conda.sh \
|
||||||
|
&& conda init bash \
|
||||||
|
&& source ~/.bashrc \
|
||||||
|
&& conda env create \
|
||||||
|
--name ${project_name} \
|
||||||
|
--file ${conda_env_file} \
|
||||||
|
&& rm -Rf ~/.cache \
|
||||||
|
&& conda clean -afy \
|
||||||
|
&& echo "conda activate ${project_name}" >> ~/.bashrc \
|
||||||
|
&& ln -s /data/models/GFPGANv1.4.pth ./src/gfpgan/experiments/pretrained_models/GFPGANv1.4.pth \
|
||||||
|
&& conda activate ${project_name} \
|
||||||
|
&& python scripts/preload_models.py
|
||||||
|
|
||||||
WORKDIR /GFPGAN
|
# Copy entrypoint and set env
|
||||||
RUN pip3 install -r requirements.txt \
|
ENV CONDA_PREFIX=${conda_prefix}
|
||||||
&& python3 setup.py develop \
|
ENV PROJECT_NAME=${project_name}
|
||||||
&& ln -s "/data/GFPGANv1.4.pth" experiments/pretrained_models/GFPGANv1.4.pth
|
COPY docker-build/entrypoint.sh /
|
||||||
|
|
||||||
WORKDIR /stable-diffusion
|
|
||||||
RUN python3 scripts/preload_models.py
|
|
||||||
|
|
||||||
WORKDIR /
|
|
||||||
COPY entrypoint.sh .
|
|
||||||
ENTRYPOINT [ "/entrypoint.sh" ]
|
ENTRYPOINT [ "/entrypoint.sh" ]
|
81
docker-build/build.sh
Executable file
@ -0,0 +1,81 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
# IMPORTANT: You need to have a token on huggingface.co to be able to download the checkpoint!!!
|
||||||
|
# configure values by using env when executing build.sh
|
||||||
|
# f.e. env ARCH=aarch64 GITHUB_INVOKE_AI=https://github.com/yourname/yourfork.git ./build.sh
|
||||||
|
|
||||||
|
source ./docker-build/env.sh || echo "please run from repository root" || exit 1
|
||||||
|
|
||||||
|
invokeai_conda_version=${INVOKEAI_CONDA_VERSION:-py39_4.12.0-${platform/\//-}}
|
||||||
|
invokeai_conda_prefix=${INVOKEAI_CONDA_PREFIX:-\/opt\/conda}
|
||||||
|
invokeai_conda_env_file=${INVOKEAI_CONDA_ENV_FILE:-environment.yml}
|
||||||
|
invokeai_git=${INVOKEAI_GIT:-https://github.com/invoke-ai/InvokeAI.git}
|
||||||
|
huggingface_token=${HUGGINGFACE_TOKEN?}
|
||||||
|
|
||||||
|
# print the settings
|
||||||
|
echo "You are using these values:"
|
||||||
|
echo -e "project_name:\t\t ${project_name}"
|
||||||
|
echo -e "volumename:\t\t ${volumename}"
|
||||||
|
echo -e "arch:\t\t\t ${arch}"
|
||||||
|
echo -e "platform:\t\t ${platform}"
|
||||||
|
echo -e "invokeai_conda_version:\t ${invokeai_conda_version}"
|
||||||
|
echo -e "invokeai_conda_prefix:\t ${invokeai_conda_prefix}"
|
||||||
|
echo -e "invokeai_conda_env_file: ${invokeai_conda_env_file}"
|
||||||
|
echo -e "invokeai_git:\t\t ${invokeai_git}"
|
||||||
|
echo -e "invokeai_tag:\t\t ${invokeai_tag}\n"
|
||||||
|
|
||||||
|
_runAlpine() {
|
||||||
|
docker run \
|
||||||
|
--rm \
|
||||||
|
--interactive \
|
||||||
|
--tty \
|
||||||
|
--mount source="$volumename",target=/data \
|
||||||
|
--workdir /data \
|
||||||
|
alpine "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
_copyCheckpoints() {
|
||||||
|
echo "creating subfolders for models and outputs"
|
||||||
|
_runAlpine mkdir models
|
||||||
|
_runAlpine mkdir outputs
|
||||||
|
echo -n "downloading sd-v1-4.ckpt"
|
||||||
|
_runAlpine wget --header="Authorization: Bearer ${huggingface_token}" -O models/sd-v1-4.ckpt https://huggingface.co/CompVis/stable-diffusion-v-1-4-original/resolve/main/sd-v1-4.ckpt
|
||||||
|
echo "done"
|
||||||
|
echo "downloading GFPGANv1.4.pth"
|
||||||
|
_runAlpine wget -O models/GFPGANv1.4.pth https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.4.pth
|
||||||
|
}
|
||||||
|
|
||||||
|
_checkVolumeContent() {
|
||||||
|
_runAlpine ls -lhA /data/models
|
||||||
|
}
|
||||||
|
|
||||||
|
_getModelMd5s() {
|
||||||
|
_runAlpine \
|
||||||
|
alpine sh -c "md5sum /data/models/*"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ -n "$(docker volume ls -f name="${volumename}" -q)" ]]; then
|
||||||
|
echo "Volume already exists"
|
||||||
|
if [[ -z "$(_checkVolumeContent)" ]]; then
|
||||||
|
echo "looks empty, copying checkpoint"
|
||||||
|
_copyCheckpoints
|
||||||
|
fi
|
||||||
|
echo "Models in ${volumename}:"
|
||||||
|
_checkVolumeContent
|
||||||
|
else
|
||||||
|
echo -n "createing docker volume "
|
||||||
|
docker volume create "${volumename}"
|
||||||
|
_copyCheckpoints
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build Container
|
||||||
|
docker build \
|
||||||
|
--platform="${platform}" \
|
||||||
|
--tag "${invokeai_tag}" \
|
||||||
|
--build-arg project_name="${project_name}" \
|
||||||
|
--build-arg conda_version="${invokeai_conda_version}" \
|
||||||
|
--build-arg conda_prefix="${invokeai_conda_prefix}" \
|
||||||
|
--build-arg conda_env_file="${invokeai_conda_env_file}" \
|
||||||
|
--build-arg invokeai_git="${invokeai_git}" \
|
||||||
|
--file ./docker-build/Dockerfile \
|
||||||
|
.
|
@ -1,10 +1,8 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
cd /stable-diffusion
|
source "${CONDA_PREFIX}/etc/profile.d/conda.sh"
|
||||||
|
conda activate "${PROJECT_NAME}"
|
||||||
|
|
||||||
if [ $# -eq 0 ]; then
|
python scripts/invoke.py \
|
||||||
python3 scripts/dream.py --full_precision -o /data
|
${@:---web --host=0.0.0.0}
|
||||||
# bash
|
|
||||||
else
|
|
||||||
python3 scripts/dream.py --full_precision -o /data "$@"
|
|
||||||
fi
|
|
||||||
|
13
docker-build/env.sh
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
project_name=${PROJECT_NAME:-invokeai}
|
||||||
|
volumename=${VOLUMENAME:-${project_name}_data}
|
||||||
|
arch=${ARCH:-x86_64}
|
||||||
|
platform=${PLATFORM:-Linux/${arch}}
|
||||||
|
invokeai_tag=${INVOKEAI_TAG:-${project_name}-${arch}}
|
||||||
|
|
||||||
|
export project_name
|
||||||
|
export volumename
|
||||||
|
export arch
|
||||||
|
export platform
|
||||||
|
export invokeai_tag
|
15
docker-build/run.sh
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
source ./docker-build/env.sh || echo "please run from repository root" || exit 1
|
||||||
|
|
||||||
|
docker run \
|
||||||
|
--interactive \
|
||||||
|
--tty \
|
||||||
|
--rm \
|
||||||
|
--platform "$platform" \
|
||||||
|
--name "$project_name" \
|
||||||
|
--hostname "$project_name" \
|
||||||
|
--mount source="$volumename",target=/data \
|
||||||
|
--publish 9090:9090 \
|
||||||
|
"$invokeai_tag" ${1:+$@}
|
BIN
docs/assets/inpainting/000019.curly.hair.deselected.png
Normal file
After Width: | Height: | Size: 519 KiB |
BIN
docs/assets/inpainting/000019.curly.hair.masked.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
docs/assets/inpainting/000019.curly.hair.selected.png
Normal file
After Width: | Height: | Size: 519 KiB |
BIN
docs/assets/inpainting/000024.801380492.png
Normal file
After Width: | Height: | Size: 439 KiB |
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
|
||||||
|
![](000001.1863159593.png)
|
||||||
|
|
||||||
|
banana sushi -s 50 -S 1863159593 -W 512 -H 512 -C 7.5 -A k_lms
|
||||||
|
## 000002.1151955949.png
|
||||||
|
![](000002.1151955949.png)
|
||||||
|
|
||||||
|
banana sushi -s 50 -S 1151955949 -W 512 -H 512 -C 7.5 -A plms
|
||||||
|
## 000003.2736230502.png
|
||||||
|
![](000003.2736230502.png)
|
||||||
|
|
||||||
|
banana sushi -s 50 -S 2736230502 -W 512 -H 512 -C 7.5 -A ddim
|
||||||
|
## 000004.42.png
|
||||||
|
![](000004.42.png)
|
||||||
|
|
||||||
|
banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms
|
||||||
|
## 000005.42.png
|
||||||
|
![](000005.42.png)
|
||||||
|
|
||||||
|
banana sushi -s 50 -S 42 -W 512 -H 512 -C 7.5 -A k_lms
|
||||||
|
## 000006.478163327.png
|
||||||
|
![](000006.478163327.png)
|
||||||
|
|
||||||
|
banana sushi -s 50 -S 478163327 -W 640 -H 448 -C 7.5 -A k_lms
|
||||||
|
## 000007.2407640369.png
|
||||||
|
![](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
|
||||||
|
![](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
|
||||||
|
![](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
|
||||||
|
![](000010.2028635318.png)
|
||||||
|
|
||||||
|
banana sushi -s 50 -S 2028635318 -W 512 -H 512 -C 7.5 -A k_lms
|
||||||
|
## 000011.1111168647.png
|
||||||
|
![](000011.1111168647.png)
|
||||||
|
|
||||||
|
pond with waterlillies -s 50 -S 1111168647 -W 512 -H 512 -C 7.5 -A k_lms
|
||||||
|
## 000012.1476370516.png
|
||||||
|
![](000012.1476370516.png)
|
||||||
|
|
||||||
|
pond with waterlillies -s 50 -S 1476370516 -W 512 -H 512 -C 7.5 -A k_lms
|
||||||
|
## 000013.4281108706.png
|
||||||
|
![](000013.4281108706.png)
|
||||||
|
|
||||||
|
banana sushi -s 50 -S 4281108706 -W 960 -H 960 -C 7.5 -A k_lms
|
||||||
|
## 000014.2396987386.png
|
||||||
|
![](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
|
||||||
|
![](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
|
||||||
|
![](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
|
||||||
|
![](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
|
||||||
|
![](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
|
||||||
|
![](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
|
||||||
|
![](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
|
||||||
|
![](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
|
||||||
|
![](000022.47.png)
|
||||||
|
|
||||||
|
dog:1,cat:2 -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||||
|
## 000023.47.png
|
||||||
|
![](000023.47.png)
|
||||||
|
|
||||||
|
dog:2,cat:1 -s 50 -S 47 -W 512 -H 512 -C 7.5 -A k_lms
|
||||||
|
## 000024.1029061431.png
|
||||||
|
![](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
|
||||||
|
![](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
|
||||||
|
![](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
|
||||||
|
![](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
|
||||||
|
![](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
|
||||||
|
![](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
|
BIN
docs/assets/prompt_syntax/apricots--1.png
Normal file
After Width: | Height: | Size: 587 KiB |
BIN
docs/assets/prompt_syntax/apricots--2.png
Normal file
After Width: | Height: | Size: 572 KiB |
BIN
docs/assets/prompt_syntax/apricots--3.png
Normal file
After Width: | Height: | Size: 557 KiB |
BIN
docs/assets/prompt_syntax/apricots-0.png
Normal file
After Width: | Height: | Size: 571 KiB |
BIN
docs/assets/prompt_syntax/apricots-1.png
Normal file
After Width: | Height: | Size: 570 KiB |
BIN
docs/assets/prompt_syntax/apricots-2.png
Normal file
After Width: | Height: | Size: 568 KiB |
BIN
docs/assets/prompt_syntax/apricots-3.png
Normal file
After Width: | Height: | Size: 527 KiB |
BIN
docs/assets/prompt_syntax/apricots-4.png
Normal file
After Width: | Height: | Size: 489 KiB |
BIN
docs/assets/prompt_syntax/apricots-5.png
Normal file
After Width: | Height: | Size: 503 KiB |
BIN
docs/assets/prompt_syntax/mountain-man.png
Normal file
After Width: | Height: | Size: 488 KiB |
BIN
docs/assets/prompt_syntax/mountain-man1.png
Normal file
After Width: | Height: | Size: 499 KiB |
BIN
docs/assets/prompt_syntax/mountain-man2.png
Normal file
After Width: | Height: | Size: 524 KiB |
BIN
docs/assets/prompt_syntax/mountain-man3.png
Normal file
After Width: | Height: | Size: 593 KiB |
BIN
docs/assets/prompt_syntax/mountain-man4.png
Normal file
After Width: | Height: | Size: 598 KiB |
BIN
docs/assets/prompt_syntax/mountain1-man.png
Normal file
After Width: | Height: | Size: 488 KiB |
BIN
docs/assets/prompt_syntax/mountain2-man.png
Normal file
After Width: | Height: | Size: 487 KiB |
BIN
docs/assets/prompt_syntax/mountain3-man.png
Normal file
After Width: | Height: | Size: 489 KiB |
BIN
docs/assets/still-life-inpainted.png
Normal file
After Width: | Height: | Size: 338 KiB |
BIN
docs/assets/still-life-scaled.jpg
Normal file
After Width: | Height: | Size: 59 KiB |
@ -8,7 +8,7 @@ hide:
|
|||||||
|
|
||||||
## **Interactive Command Line Interface**
|
## **Interactive Command Line Interface**
|
||||||
|
|
||||||
The `invoke.py` script, located in `scripts/dream.py`, provides an interactive
|
The `invoke.py` script, located in `scripts/`, provides an interactive
|
||||||
interface to image generation similar to the "invoke mothership" bot that Stable
|
interface to image generation similar to the "invoke mothership" bot that Stable
|
||||||
AI provided on its Discord server.
|
AI provided on its Discord server.
|
||||||
|
|
||||||
@ -86,6 +86,7 @@ overridden on a per-prompt basis (see [List of prompt arguments](#list-of-prompt
|
|||||||
| `--model <modelname>` | | `stable-diffusion-1.4` | Loads model specified in configs/models.yaml. Currently one of "stable-diffusion-1.4" or "laion400m" |
|
| `--model <modelname>` | | `stable-diffusion-1.4` | Loads model specified in configs/models.yaml. Currently one of "stable-diffusion-1.4" or "laion400m" |
|
||||||
| `--full_precision` | `-F` | `False` | Run in slower full-precision mode. Needed for Macintosh M1/M2 hardware and some older video cards. |
|
| `--full_precision` | `-F` | `False` | Run in slower full-precision mode. Needed for Macintosh M1/M2 hardware and some older video cards. |
|
||||||
| `--png_compression <0-9>` | `-z<0-9>` | 6 | Select level of compression for output files, from 0 (no compression) to 9 (max compression) |
|
| `--png_compression <0-9>` | `-z<0-9>` | 6 | Select level of compression for output files, from 0 (no compression) to 9 (max compression) |
|
||||||
|
| `--safety-checker` | | False | Activate safety checker for NSFW and other potentially disturbing imagery |
|
||||||
| `--web` | | `False` | Start in web server mode |
|
| `--web` | | `False` | Start in web server mode |
|
||||||
| `--host <ip addr>` | | `localhost` | Which network interface web server should listen on. Set to 0.0.0.0 to listen on any. |
|
| `--host <ip addr>` | | `localhost` | Which network interface web server should listen on. Set to 0.0.0.0 to listen on any. |
|
||||||
| `--port <port>` | | `9090` | Which port web server should listen for requests on. |
|
| `--port <port>` | | `9090` | Which port web server should listen for requests on. |
|
||||||
@ -97,7 +98,6 @@ overridden on a per-prompt basis (see [List of prompt arguments](#list-of-prompt
|
|||||||
| `--embedding_path <path>` | | `None` | Path to pre-trained embedding manager checkpoints, for custom models |
|
| `--embedding_path <path>` | | `None` | Path to pre-trained embedding manager checkpoints, for custom models |
|
||||||
| `--gfpgan_dir` | | `src/gfpgan` | Path to where GFPGAN is installed. |
|
| `--gfpgan_dir` | | `src/gfpgan` | Path to where GFPGAN is installed. |
|
||||||
| `--gfpgan_model_path` | | `experiments/pretrained_models/GFPGANv1.4.pth` | Path to GFPGAN model file, relative to `--gfpgan_dir`. |
|
| `--gfpgan_model_path` | | `experiments/pretrained_models/GFPGANv1.4.pth` | Path to GFPGAN model file, relative to `--gfpgan_dir`. |
|
||||||
| `--device <device>` | `-d<device>` | `torch.cuda.current_device()` | Device to run SD on, e.g. "cuda:0" |
|
|
||||||
| `--free_gpu_mem` | | `False` | Free GPU memory after sampling, to allow image decoding and saving in low VRAM conditions |
|
| `--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 |
|
| `--precision` | | `auto` | Set model precision, default is selected by device. Options: auto, float32, float16, autocast |
|
||||||
|
|
||||||
@ -151,12 +151,14 @@ Here are the invoke> command that apply to txt2img:
|
|||||||
| --cfg_scale <float>| -C<float> | 7.5 | How hard to try to match the prompt to the generated image; any number greater than 1.0 works, but the useful range is roughly 5.0 to 20.0 |
|
| --cfg_scale <float>| -C<float> | 7.5 | How hard to try to match the prompt to the generated image; any number greater than 1.0 works, but the useful range is roughly 5.0 to 20.0 |
|
||||||
| --seed <int> | -S<int> | None | Set the random seed for the next series of images. This can be used to recreate an image generated previously.|
|
| --seed <int> | -S<int> | None | Set the random seed for the next series of images. This can be used to recreate an image generated previously.|
|
||||||
| --sampler <sampler>| -A<sampler>| k_lms | Sampler to use. Use -h to get list of available samplers. |
|
| --sampler <sampler>| -A<sampler>| k_lms | Sampler to use. Use -h to get list of available samplers. |
|
||||||
|
| --karras_max <int> | | 29 | When using k_* samplers, set the maximum number of steps before shifting from using the Karras noise schedule (good for low step counts) to the LatentDiffusion noise schedule (good for high step counts) This value is sticky. [29] |
|
||||||
| --hires_fix | | | Larger images often have duplication artefacts. This option suppresses duplicates by generating the image at low res, and then using img2img to increase the resolution |
|
| --hires_fix | | | Larger images often have duplication artefacts. This option suppresses duplicates by generating the image at low res, and then using img2img to increase the resolution |
|
||||||
| `--png_compression <0-9>` | `-z<0-9>` | 6 | Select level of compression for output files, from 0 (no compression) to 9 (max compression) |
|
| --png_compression <0-9> | -z<0-9> | 6 | Select level of compression for output files, from 0 (no compression) to 9 (max compression) |
|
||||||
| --grid | -g | False | Turn on grid mode to return a single image combining all the images generated by this prompt |
|
| --grid | -g | False | Turn on grid mode to return a single image combining all the images generated by this prompt |
|
||||||
| --individual | -i | True | Turn off grid mode (deprecated; leave off --grid instead) |
|
| --individual | -i | True | Turn off grid mode (deprecated; leave off --grid instead) |
|
||||||
| --outdir <path> | -o<path> | outputs/img_samples | Temporarily change the location of these images |
|
| --outdir <path> | -o<path> | outputs/img_samples | Temporarily change the location of these images |
|
||||||
| --seamless | | False | Activate seamless tiling for interesting effects |
|
| --seamless | | False | Activate seamless tiling for interesting effects |
|
||||||
|
| --seamless_axes | | x,y | Specify which axes to use circular convolution on. |
|
||||||
| --log_tokenization | -t | False | Display a color-coded list of the parsed tokens derived from the prompt |
|
| --log_tokenization | -t | False | Display a color-coded list of the parsed tokens derived from the prompt |
|
||||||
| --skip_normalization| -x | False | Weighted subprompts will not be normalized. See [Weighted Prompts](./OTHER.md#weighted-prompts) |
|
| --skip_normalization| -x | False | Weighted subprompts will not be normalized. See [Weighted Prompts](./OTHER.md#weighted-prompts) |
|
||||||
| --upscale <int> <float> | -U <int> <float> | -U 1 0.75| Upscale image by magnification factor (2, 4), and set strength of upscaling (0.0-1.0). If strength not set, will default to 0.75. |
|
| --upscale <int> <float> | -U <int> <float> | -U 1 0.75| Upscale image by magnification factor (2, 4), and set strength of upscaling (0.0-1.0). If strength not set, will default to 0.75. |
|
||||||
@ -210,11 +212,40 @@ accepts additional options:
|
|||||||
[Inpainting](./INPAINTING.md) for details.
|
[Inpainting](./INPAINTING.md) for details.
|
||||||
|
|
||||||
inpainting accepts all the arguments used for txt2img and img2img, as
|
inpainting accepts all the arguments used for txt2img and img2img, as
|
||||||
well as the --mask (-M) argument:
|
well as the --mask (-M) and --text_mask (-tm) arguments:
|
||||||
|
|
||||||
| Argument <img width="100" align="right"/> | Shortcut | Default | Description |
|
| Argument <img width="100" align="right"/> | Shortcut | Default | Description |
|
||||||
|--------------------|------------|---------------------|--------------|
|
|--------------------|------------|---------------------|--------------|
|
||||||
| `--init_mask <path>` | `-M<path>` | `None` |Path to an image the same size as the initial_image, with areas for inpainting made transparent.|
|
| `--init_mask <path>` | `-M<path>` | `None` |Path to an image the same size as the initial_image, with areas for inpainting made transparent.|
|
||||||
|
| `--invert_mask ` | | False |If true, invert the mask so that transparent areas are opaque and vice versa.|
|
||||||
|
| `--text_mask <prompt> [<float>]` | `-tm <prompt> [<float>]` | <none> | Create a mask from a text prompt describing part of the image|
|
||||||
|
|
||||||
|
The mask may either be an image with transparent areas, in which case
|
||||||
|
the inpainting will occur in the transparent areas only, or a black
|
||||||
|
and white image, in which case all black areas will be painted into.
|
||||||
|
|
||||||
|
`--text_mask` (short form `-tm`) is a way to generate a mask using a
|
||||||
|
text description of the part of the image to replace. For example, if
|
||||||
|
you have an image of a breakfast plate with a bagel, toast and
|
||||||
|
scrambled eggs, you can selectively mask the bagel and replace it with
|
||||||
|
a piece of cake this way:
|
||||||
|
|
||||||
|
~~~
|
||||||
|
invoke> a piece of cake -I /path/to/breakfast.png -tm bagel
|
||||||
|
~~~
|
||||||
|
|
||||||
|
The algorithm uses <a
|
||||||
|
href="https://github.com/timojl/clipseg">clipseg</a> to classify
|
||||||
|
different regions of the image. The classifier puts out a confidence
|
||||||
|
score for each region it identifies. Generally regions that score
|
||||||
|
above 0.5 are reliable, but if you are getting too much or too little
|
||||||
|
masking you can adjust the threshold down (to get more mask), or up
|
||||||
|
(to get less). In this example, by passing `-tm` a higher value, we
|
||||||
|
are insisting on a more stringent classification.
|
||||||
|
|
||||||
|
~~~
|
||||||
|
invoke> a piece of cake -I /path/to/breakfast.png -tm bagel 0.6
|
||||||
|
~~~
|
||||||
|
|
||||||
# Other Commands
|
# Other Commands
|
||||||
|
|
||||||
@ -256,12 +287,20 @@ Some examples:
|
|||||||
Outputs:
|
Outputs:
|
||||||
[1] outputs/img-samples/000017.4829112.gfpgan-00.png: !fix "outputs/img-samples/0000045.4829112.png" -s 50 -S -W 512 -H 512 -C 7.5 -A k_lms -G 0.8
|
[1] outputs/img-samples/000017.4829112.gfpgan-00.png: !fix "outputs/img-samples/0000045.4829112.png" -s 50 -S -W 512 -H 512 -C 7.5 -A k_lms -G 0.8
|
||||||
|
|
||||||
# Model selection and importation
|
### !mask
|
||||||
|
|
||||||
|
This command takes an image, a text prompt, and uses the `clipseg`
|
||||||
|
algorithm to automatically generate a mask of the area that matches
|
||||||
|
the text prompt. It is useful for debugging the text masking process
|
||||||
|
prior to inpainting with the `--text_mask` argument. See
|
||||||
|
[INPAINTING.md] for details.
|
||||||
|
|
||||||
|
## Model selection and importation
|
||||||
|
|
||||||
The CLI allows you to add new models on the fly, as well as to switch
|
The CLI allows you to add new models on the fly, as well as to switch
|
||||||
among them rapidly without leaving the script.
|
among them rapidly without leaving the script.
|
||||||
|
|
||||||
## !models
|
### !models
|
||||||
|
|
||||||
This prints out a list of the models defined in `config/models.yaml'.
|
This prints out a list of the models defined in `config/models.yaml'.
|
||||||
The active model is bold-faced
|
The active model is bold-faced
|
||||||
@ -273,7 +312,7 @@ laion400m not loaded <no description>
|
|||||||
waifu-diffusion not loaded Waifu Diffusion v1.3
|
waifu-diffusion not loaded Waifu Diffusion v1.3
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## !switch <model>
|
### !switch <model>
|
||||||
|
|
||||||
This quickly switches from one model to another without leaving the
|
This quickly switches from one model to another without leaving the
|
||||||
CLI script. `invoke.py` uses a memory caching system; once a model
|
CLI script. `invoke.py` uses a memory caching system; once a model
|
||||||
@ -319,7 +358,7 @@ laion400m not loaded <no description>
|
|||||||
waifu-diffusion cached Waifu Diffusion v1.3
|
waifu-diffusion cached Waifu Diffusion v1.3
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## !import_model <path/to/model/weights>
|
### !import_model <path/to/model/weights>
|
||||||
|
|
||||||
This command imports a new model weights file into InvokeAI, makes it
|
This command imports a new model weights file into InvokeAI, makes it
|
||||||
available for image generation within the script, and writes out the
|
available for image generation within the script, and writes out the
|
||||||
@ -371,7 +410,7 @@ OK to import [n]? <b>y</b>
|
|||||||
invoke>
|
invoke>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
##!edit_model <name_of_model>
|
###!edit_model <name_of_model>
|
||||||
|
|
||||||
The `!edit_model` command can be used to modify a model that is
|
The `!edit_model` command can be used to modify a model that is
|
||||||
already defined in `config/models.yaml`. Call it with the short
|
already defined in `config/models.yaml`. Call it with the short
|
||||||
@ -407,20 +446,12 @@ OK to import [n]? y
|
|||||||
Outputs:
|
Outputs:
|
||||||
[2] outputs/img-samples/000018.2273800735.embiggen-00.png: !fix "outputs/img-samples/000017.243781548.gfpgan-00.png" -s 50 -S 2273800735 -W 512 -H 512 -C 7.5 -A k_lms --embiggen 3.0 0.75 0.25
|
[2] outputs/img-samples/000018.2273800735.embiggen-00.png: !fix "outputs/img-samples/000017.243781548.gfpgan-00.png" -s 50 -S 2273800735 -W 512 -H 512 -C 7.5 -A k_lms --embiggen 3.0 0.75 0.25
|
||||||
```
|
```
|
||||||
# History processing
|
## History processing
|
||||||
|
|
||||||
The CLI provides a series of convenient commands for reviewing previous
|
The CLI provides a series of convenient commands for reviewing previous
|
||||||
actions, retrieving them, modifying them, and re-running them.
|
actions, retrieving them, modifying them, and re-running them.
|
||||||
```bash
|
|
||||||
invoke> !fetch 0000015.8929913.png
|
|
||||||
# the script returns the next line, ready for editing and running:
|
|
||||||
invoke> a fantastic alien landscape -W 576 -H 512 -s 60 -A plms -C 7.5
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that this command may behave unexpectedly if given a PNG file that
|
### !history
|
||||||
was not generated by InvokeAI.
|
|
||||||
|
|
||||||
### `!history`
|
|
||||||
|
|
||||||
The invoke script keeps track of all the commands you issue during a
|
The invoke script keeps track of all the commands you issue during a
|
||||||
session, allowing you to re-run them. On Mac and Linux systems, it
|
session, allowing you to re-run them. On Mac and Linux systems, it
|
||||||
@ -445,20 +476,41 @@ invoke> !20
|
|||||||
invoke> watercolor of beautiful woman sitting under tree wearing broad hat and flowing garment -v0.2 -n6 -S2878767194
|
invoke> watercolor of beautiful woman sitting under tree wearing broad hat and flowing garment -v0.2 -n6 -S2878767194
|
||||||
```
|
```
|
||||||
|
|
||||||
## !fetch
|
### !fetch
|
||||||
|
|
||||||
This command retrieves the generation parameters from a previously
|
This command retrieves the generation parameters from a previously
|
||||||
generated image and either loads them into the command line. You may
|
generated image and either loads them into the command line
|
||||||
provide either the name of a file in the current output directory, or
|
(Linux|Mac), or prints them out in a comment for copy-and-paste
|
||||||
a full file path.
|
(Windows). You may provide either the name of a file in the current
|
||||||
|
output directory, or a full file path. Specify path to a folder with
|
||||||
|
image png files, and wildcard *.png to retrieve the dream command used
|
||||||
|
to generate the images, and save them to a file commands.txt for
|
||||||
|
further processing.
|
||||||
|
|
||||||
~~~
|
This example loads the generation command for a single png file:
|
||||||
|
|
||||||
|
```bash
|
||||||
invoke> !fetch 0000015.8929913.png
|
invoke> !fetch 0000015.8929913.png
|
||||||
# the script returns the next line, ready for editing and running:
|
# the script returns the next line, ready for editing and running:
|
||||||
invoke> a fantastic alien landscape -W 576 -H 512 -s 60 -A plms -C 7.5
|
invoke> a fantastic alien landscape -W 576 -H 512 -s 60 -A plms -C 7.5
|
||||||
|
```
|
||||||
|
|
||||||
|
This one fetches the generation commands from a batch of files and
|
||||||
|
stores them into `selected.txt`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
invoke> !fetch outputs\selected-imgs\*.png selected.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
### !replay
|
||||||
|
|
||||||
|
This command replays a text file generated by !fetch or created manually
|
||||||
|
|
||||||
|
~~~
|
||||||
|
invoke> !replay outputs\selected-imgs\selected.txt
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
Note that this command may behave unexpectedly if given a PNG file that
|
Note that these commands may behave unexpectedly if given a PNG file that
|
||||||
was not generated by InvokeAI.
|
was not generated by InvokeAI.
|
||||||
|
|
||||||
### !search <search string>
|
### !search <search string>
|
||||||
|
@ -120,8 +120,6 @@ Both of the outputs look kind of like what I was thinking of. With the strength
|
|||||||
|
|
||||||
If you want to try this out yourself, all of these are using a seed of `1592514025` with a width/height of `384`, step count `10`, the default sampler (`k_lms`), and the single-word prompt `"fire"`:
|
If you want to try this out yourself, all of these are using a seed of `1592514025` with a width/height of `384`, step count `10`, the default sampler (`k_lms`), and the single-word prompt `"fire"`:
|
||||||
|
|
||||||
If you want to try this out yourself, all of these are using a seed of `1592514025` with a width/height of `384`, step count `10`, the default sampler (`k_lms`), and the single-word prompt `fire`:
|
|
||||||
|
|
||||||
```commandline
|
```commandline
|
||||||
invoke> "fire" -s10 -W384 -H384 -S1592514025 -I /tmp/fire-drawing.png --strength 0.7
|
invoke> "fire" -s10 -W384 -H384 -S1592514025 -I /tmp/fire-drawing.png --strength 0.7
|
||||||
```
|
```
|
||||||
|
@ -34,9 +34,188 @@ original unedited image and the masked (partially transparent) image:
|
|||||||
invoke> "man with cat on shoulder" -I./images/man.png -M./images/man-transparent.png
|
invoke> "man with cat on shoulder" -I./images/man.png -M./images/man-transparent.png
|
||||||
```
|
```
|
||||||
|
|
||||||
We are hoping to get rid of the need for this workaround in an upcoming release.
|
## **Masking using Text**
|
||||||
|
|
||||||
### Inpainting is not changing the masked region enough!
|
You can also create a mask using a text prompt to select the part of
|
||||||
|
the image you want to alter, using the <a
|
||||||
|
href="https://github.com/timojl/clipseg">clipseg</a> algorithm. This
|
||||||
|
works on any image, not just ones generated by InvokeAI.
|
||||||
|
|
||||||
|
The `--text_mask` (short form `-tm`) option takes two arguments. The
|
||||||
|
first argument is a text description of the part of the image you wish
|
||||||
|
to mask (paint over). If the text description contains a space, you must
|
||||||
|
surround it with quotation marks. The optional second argument is the
|
||||||
|
minimum threshold for the mask classifier's confidence score, described
|
||||||
|
in more detail below.
|
||||||
|
|
||||||
|
To see how this works in practice, here's an image of a still life
|
||||||
|
painting that I got off the web.
|
||||||
|
|
||||||
|
<img src="../assets/still-life-scaled.jpg">
|
||||||
|
|
||||||
|
You can selectively mask out the
|
||||||
|
orange and replace it with a baseball in this way:
|
||||||
|
|
||||||
|
~~~
|
||||||
|
invoke> a baseball -I /path/to/still_life.png -tm orange
|
||||||
|
~~~
|
||||||
|
|
||||||
|
<img src="../assets/still-life-inpainted.png">
|
||||||
|
|
||||||
|
The clipseg classifier produces a confidence score for each region it
|
||||||
|
identifies. Generally regions that score above 0.5 are reliable, but
|
||||||
|
if you are getting too much or too little masking you can adjust the
|
||||||
|
threshold down (to get more mask), or up (to get less). In this
|
||||||
|
example, by passing `-tm` a higher value, we are insisting on a tigher
|
||||||
|
mask. However, if you make it too high, the orange may not be picked
|
||||||
|
up at all!
|
||||||
|
|
||||||
|
~~~
|
||||||
|
invoke> a baseball -I /path/to/breakfast.png -tm orange 0.6
|
||||||
|
~~~
|
||||||
|
|
||||||
|
The `!mask` command may be useful for debugging problems with the
|
||||||
|
text2mask feature. The syntax is `!mask /path/to/image.png -tm <text>
|
||||||
|
<threshold>`
|
||||||
|
|
||||||
|
It will generate three files:
|
||||||
|
|
||||||
|
- The image with the selected area highlighted.
|
||||||
|
- it will be named XXXXX.<imagename>.<prompt>.selected.png
|
||||||
|
- The image with the un-selected area highlighted.
|
||||||
|
- it will be named XXXXX.<imagename>.<prompt>.deselected.png
|
||||||
|
- The image with the selected area converted into a black and white
|
||||||
|
image according to the threshold level
|
||||||
|
- it will be named XXXXX.<imagename>.<prompt>.masked.png
|
||||||
|
|
||||||
|
The `.masked.png` file can then be directly passed to the `invoke>`
|
||||||
|
prompt in the CLI via the `-M` argument. Do not attempt this with
|
||||||
|
the `selected.png` or `deselected.png` files, as they contain some
|
||||||
|
transparency throughout the image and will not produce the desired
|
||||||
|
results.
|
||||||
|
|
||||||
|
Here is an example of how `!mask` works:
|
||||||
|
|
||||||
|
```
|
||||||
|
invoke> !mask ./test-pictures/curly.png -tm hair 0.5
|
||||||
|
>> generating masks from ./test-pictures/curly.png
|
||||||
|
>> Initializing clipseg model for text to mask inference
|
||||||
|
Outputs:
|
||||||
|
[941.1] outputs/img-samples/000019.curly.hair.deselected.png: !mask ./test-pictures/curly.png -tm hair 0.5
|
||||||
|
[941.2] outputs/img-samples/000019.curly.hair.selected.png: !mask ./test-pictures/curly.png -tm hair 0.5
|
||||||
|
[941.3] outputs/img-samples/000019.curly.hair.masked.png: !mask ./test-pictures/curly.png -tm hair 0.5
|
||||||
|
```
|
||||||
|
|
||||||
|
**Original image "curly.png"**
|
||||||
|
<img src="../assets/outpainting/curly.png">
|
||||||
|
|
||||||
|
**000019.curly.hair.selected.png**
|
||||||
|
<img src="../assets/inpainting/000019.curly.hair.selected.png">
|
||||||
|
|
||||||
|
**000019.curly.hair.deselected.png**
|
||||||
|
<img src="../assets/inpainting/000019.curly.hair.deselected.png">
|
||||||
|
|
||||||
|
**000019.curly.hair.masked.png**
|
||||||
|
<img src="../assets/inpainting/000019.curly.hair.masked.png">
|
||||||
|
|
||||||
|
It looks like we selected the hair pretty well at the 0.5 threshold
|
||||||
|
(which is the default, so we didn't actually have to specify it), so
|
||||||
|
let's have some fun:
|
||||||
|
|
||||||
|
```
|
||||||
|
invoke> medusa with cobras -I ./test-pictures/curly.png -M 000019.curly.hair.masked.png -C20
|
||||||
|
>> loaded input image of size 512x512 from ./test-pictures/curly.png
|
||||||
|
...
|
||||||
|
Outputs:
|
||||||
|
[946] outputs/img-samples/000024.801380492.png: "medusa with cobras" -s 50 -S 801380492 -W 512 -H 512 -C 20.0 -I ./test-pictures/curly.png -A k_lms -f 0.75
|
||||||
|
```
|
||||||
|
|
||||||
|
<img src="../assets/inpainting/000024.801380492.png">
|
||||||
|
|
||||||
|
You can also skip the `!mask` creation step and just select the masked
|
||||||
|
|
||||||
|
region directly:
|
||||||
|
```
|
||||||
|
invoke> medusa with cobras -I ./test-pictures/curly.png -tm hair -C20
|
||||||
|
```
|
||||||
|
|
||||||
|
## Using the RunwayML inpainting model
|
||||||
|
|
||||||
|
The [RunwayML Inpainting Model
|
||||||
|
v1.5](https://huggingface.co/runwayml/stable-diffusion-inpainting) is
|
||||||
|
a specialized version of [Stable Diffusion
|
||||||
|
v1.5](https://huggingface.co/spaces/runwayml/stable-diffusion-v1-5)
|
||||||
|
that contains extra channels specifically designed to enhance
|
||||||
|
inpainting and outpainting. While it can do regular `txt2img` and
|
||||||
|
`img2img`, it really shines when filling in missing regions. It has an
|
||||||
|
almost uncanny ability to blend the new regions with existing ones in
|
||||||
|
a semantically coherent way.
|
||||||
|
|
||||||
|
To install the inpainting model, follow the
|
||||||
|
[instructions](INSTALLING-MODELS.md) for installing a new model. You
|
||||||
|
may use either the CLI (`invoke.py` script) or directly edit the
|
||||||
|
`configs/models.yaml` configuration file to do this. The main thing to
|
||||||
|
watch out for is that the the model `config` option must be set up to
|
||||||
|
use `v1-inpainting-inference.yaml` rather than the `v1-inference.yaml`
|
||||||
|
file that is used by Stable Diffusion 1.4 and 1.5.
|
||||||
|
|
||||||
|
After installation, your `models.yaml` should contain an entry that
|
||||||
|
looks like this one:
|
||||||
|
|
||||||
|
inpainting-1.5:
|
||||||
|
weights: models/ldm/stable-diffusion-v1/sd-v1-5-inpainting.ckpt
|
||||||
|
description: SD inpainting v1.5
|
||||||
|
config: configs/stable-diffusion/v1-inpainting-inference.yaml
|
||||||
|
vae: models/ldm/stable-diffusion-v1/vae-ft-mse-840000-ema-pruned.ckpt
|
||||||
|
width: 512
|
||||||
|
height: 512
|
||||||
|
|
||||||
|
As shown in the example, you may include a VAE fine-tuning weights
|
||||||
|
file as well. This is strongly recommended.
|
||||||
|
|
||||||
|
To use the custom inpainting model, launch `invoke.py` with the
|
||||||
|
argument `--model inpainting-1.5` or alternatively from within the
|
||||||
|
script use the `!switch inpainting-1.5` command to load and switch to
|
||||||
|
the inpainting model.
|
||||||
|
|
||||||
|
You can now do inpainting and outpainting exactly as described above,
|
||||||
|
but there will (likely) be a noticeable improvement in
|
||||||
|
coherence. Txt2img and Img2img will work as well.
|
||||||
|
|
||||||
|
There are a few caveats to be aware of:
|
||||||
|
|
||||||
|
1. The inpainting model is larger than the standard model, and will
|
||||||
|
use nearly 4 GB of GPU VRAM. This makes it unlikely to run on
|
||||||
|
a 4 GB graphics card.
|
||||||
|
|
||||||
|
2. When operating in Img2img mode, the inpainting model is much less
|
||||||
|
steerable than the standard model. It is great for making small
|
||||||
|
changes, such as changing the pattern of a fabric, or slightly
|
||||||
|
changing a subject's expression or hair, but the model will
|
||||||
|
resist making the dramatic alterations that the standard
|
||||||
|
model lets you do.
|
||||||
|
|
||||||
|
3. While the `--hires` option works fine with the inpainting model,
|
||||||
|
some special features, such as `--embiggen` are disabled.
|
||||||
|
|
||||||
|
4. Prompt weighting (`banana++ sushi`) and merging work well with
|
||||||
|
the inpainting model, but prompt swapping (a ("fluffy cat").swap("smiling dog") eating a hotdog`)
|
||||||
|
will not have any effect due to the way the model is set up.
|
||||||
|
You may use text masking (with `-tm thing-to-mask`) as an
|
||||||
|
effective replacement.
|
||||||
|
|
||||||
|
5. The model tends to oversharpen image if you use high step or CFG
|
||||||
|
values. If you need to do large steps, use the standard model.
|
||||||
|
|
||||||
|
6. The `--strength` (`-f`) option has no effect on the inpainting
|
||||||
|
model due to its fundamental differences with the standard
|
||||||
|
model. It will always take the full number of steps you specify.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
Here are some troubleshooting tips for inpainting and outpainting.
|
||||||
|
|
||||||
|
## Inpainting is not changing the masked region enough!
|
||||||
|
|
||||||
One of the things to understand about how inpainting works is that it
|
One of the things to understand about how inpainting works is that it
|
||||||
is equivalent to running img2img on just the masked (transparent)
|
is equivalent to running img2img on just the masked (transparent)
|
||||||
|
@ -26,6 +26,12 @@ for each `invoke>` prompt as shown here:
|
|||||||
invoke> "pond garden with lotus by claude monet" --seamless -s100 -n4
|
invoke> "pond garden with lotus by claude monet" --seamless -s100 -n4
|
||||||
```
|
```
|
||||||
|
|
||||||
|
By default this will tile on both the X and Y axes. However, you can also specify specific axes to tile on with `--seamless_axes`.
|
||||||
|
Possible values are `x`, `y`, and `x,y`:
|
||||||
|
```python
|
||||||
|
invoke> "pond garden with lotus by claude monet" --seamless --seamless_axes=x -s100 -n4
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## **Shortcuts: Reusing Seeds**
|
## **Shortcuts: Reusing Seeds**
|
||||||
@ -69,6 +75,23 @@ combination of integers and floating point numbers, and they do not need to add
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## **Filename Format**
|
||||||
|
|
||||||
|
The argument `--fnformat` allows to specify the filename of the
|
||||||
|
image. Supported wildcards are all arguments what can be set such as
|
||||||
|
`perlin`, `seed`, `threshold`, `height`, `width`, `gfpgan_strength`,
|
||||||
|
`sampler_name`, `steps`, `model`, `upscale`, `prompt`, `cfg_scale`,
|
||||||
|
`prefix`.
|
||||||
|
|
||||||
|
The following prompt
|
||||||
|
```bash
|
||||||
|
dream> a red car --steps 25 -C 9.8 --perlin 0.1 --fnformat {prompt}_steps.{steps}_cfg.{cfg_scale}_perlin.{perlin}.png
|
||||||
|
```
|
||||||
|
|
||||||
|
generates a file with the name: `outputs/img-samples/a red car_steps.25_cfg.9.8_perlin.0.1.png`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## **Thresholding and Perlin Noise Initialization Options**
|
## **Thresholding and Perlin Noise Initialization Options**
|
||||||
|
|
||||||
Two new options are the thresholding (`--threshold`) and the perlin noise initialization (`--perlin`) options. Thresholding limits the range of the latent values during optimization, which helps combat oversaturation with higher CFG scale values. Perlin noise initialization starts with a percentage (a value ranging from 0 to 1) of perlin noise mixed into the initial noise. Both features allow for more variations and options in the course of generating images.
|
Two new options are the thresholding (`--threshold`) and the perlin noise initialization (`--perlin`) options. Thresholding limits the range of the latent values during optimization, which helps combat oversaturation with higher CFG scale values. Perlin noise initialization starts with a percentage (a value ranging from 0 to 1) of perlin noise mixed into the initial noise. Both features allow for more variations and options in the course of generating images.
|
||||||
|
@ -15,13 +15,52 @@ InvokeAI supports two versions of outpainting, one called "outpaint"
|
|||||||
and the other "outcrop." They work slightly differently and each has
|
and the other "outcrop." They work slightly differently and each has
|
||||||
its advantages and drawbacks.
|
its advantages and drawbacks.
|
||||||
|
|
||||||
|
### Outpainting
|
||||||
|
|
||||||
|
Outpainting is the same as inpainting, except that the painting occurs
|
||||||
|
in the regions outside of the original image. To outpaint using the
|
||||||
|
`invoke.py` command line script, prepare an image in which the borders
|
||||||
|
to be extended are pure black. Add an alpha channel (if there isn't one
|
||||||
|
already), and make the borders completely transparent and the interior
|
||||||
|
completely opaque. If you wish to modify the interior as well, you may
|
||||||
|
create transparent holes in the transparency layer, which `img2img` will
|
||||||
|
paint into as usual.
|
||||||
|
|
||||||
|
Pass the image as the argument to the `-I` switch as you would for
|
||||||
|
regular inpainting:
|
||||||
|
|
||||||
|
invoke> a stream by a river -I /path/to/transparent_img.png
|
||||||
|
|
||||||
|
You'll likely be delighted by the results.
|
||||||
|
|
||||||
|
### Tips
|
||||||
|
|
||||||
|
1. Do not try to expand the image too much at once. Generally it is best
|
||||||
|
to expand the margins in 64-pixel increments. 128 pixels often works,
|
||||||
|
but your mileage may vary depending on the nature of the image you are
|
||||||
|
trying to outpaint into.
|
||||||
|
|
||||||
|
2. There are a series of switches that can be used to adjust how the
|
||||||
|
inpainting algorithm operates. In particular, you can use these to
|
||||||
|
minimize the seam that sometimes appears between the original image
|
||||||
|
and the extended part. These switches are:
|
||||||
|
|
||||||
|
--seam_size SEAM_SIZE Size of the mask around the seam between original and outpainted image (0)
|
||||||
|
--seam_blur SEAM_BLUR The amount to blur the seam inwards (0)
|
||||||
|
--seam_strength STRENGTH The img2img strength to use when filling the seam (0.7)
|
||||||
|
--seam_steps SEAM_STEPS The number of steps to use to fill the seam. (10)
|
||||||
|
--tile_size TILE_SIZE The tile size to use for filling outpaint areas (32)
|
||||||
|
|
||||||
### Outcrop
|
### Outcrop
|
||||||
|
|
||||||
The `outcrop` extension allows you to extend the image in 64 pixel
|
The `outcrop` extension gives you a convenient `!fix` postprocessing
|
||||||
increments in any dimension. You can apply the module to any image
|
command that allows you to extend a previously-generated image in 64
|
||||||
previously-generated by InvokeAI. Note that it will **not** work with
|
pixel increments in any direction. You can apply the module to any
|
||||||
arbitrary photographs or Stable Diffusion images created by other
|
image previously-generated by InvokeAI. Note that it works with
|
||||||
implementations.
|
arbitrary PNG photographs, but not currently with JPG or other
|
||||||
|
formats. Outcropping is particularly effective when combined with the
|
||||||
|
[runwayML custom inpainting
|
||||||
|
model](INPAINTING.md#using-the-runwayml-inpainting-model).
|
||||||
|
|
||||||
Consider this image:
|
Consider this image:
|
||||||
|
|
||||||
@ -33,23 +72,24 @@ 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!
|
off. She's also a bit off center. Let's fix that!
|
||||||
|
|
||||||
```bash
|
```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
|
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
|
of the image by 128 pixels, and the right and bottom of the image by
|
||||||
amount. You can use any combination of top|left|right|bottom, and
|
64 pixels. You can use any combination of top|left|right|bottom, and
|
||||||
specify any number of pixels to extend. You can also abbreviate
|
specify any number of pixels to extend. You can also abbreviate
|
||||||
`--outcrop` to `-c`.
|
`--outcrop` to `-c`.
|
||||||
|
|
||||||
The result looks like this:
|
The result looks like this:
|
||||||
|
|
||||||
<figure markdown>
|
<figure markdown>
|
||||||
![curly_woman_outcrop](../assets/outpainting/curly-outcrop.png)
|
![curly_woman_outcrop](../assets/outpainting/curly-outcrop-2.png)
|
||||||
</figure>
|
</figure>
|
||||||
|
|
||||||
The new image is actually slightly larger than the original (576x576,
|
The new image is larger than the original (576x704)
|
||||||
because 64 pixels were added to the top and right sides.)
|
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:
|
A number of caveats:
|
||||||
|
|
||||||
@ -64,6 +104,17 @@ you'll get a slightly different result. You can run it repeatedly
|
|||||||
until you get an image you like. Unfortunately `!fix` does not
|
until you get an image you like. Unfortunately `!fix` does not
|
||||||
currently respect the `-n` (`--iterations`) argument.
|
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
|
## Outpaint
|
||||||
|
|
||||||
The `outpaint` extension does the same thing, but with subtle
|
The `outpaint` extension does the same thing, but with subtle
|
||||||
|
@ -45,7 +45,7 @@ Here's a prompt that depicts what it does.
|
|||||||
|
|
||||||
original prompt:
|
original prompt:
|
||||||
|
|
||||||
`#!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" -s 20 -W 512 -H 768 -C 7.5 -A k_euler_a -S 1654590180`
|
`#!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`
|
||||||
|
|
||||||
<figure markdown>
|
<figure markdown>
|
||||||
![step1](../assets/negative_prompt_walkthru/step1.png)
|
![step1](../assets/negative_prompt_walkthru/step1.png)
|
||||||
@ -84,6 +84,109 @@ Getting close - but there's no sense in having a saddle when our horse doesn't h
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## **Prompt Syntax Features**
|
||||||
|
|
||||||
|
The InvokeAI prompting language has the following features:
|
||||||
|
|
||||||
|
### Attention weighting
|
||||||
|
Append a word or phrase with `-` or `+`, or a weight between `0` and `2` (`1`=default), to decrease or increase "attention" (= a mix of per-token CFG weighting multiplier and, for `-`, a weighted blend with the prompt without the term).
|
||||||
|
|
||||||
|
The following syntax is recognised:
|
||||||
|
* single words without parentheses: `a tall thin man picking apricots+`
|
||||||
|
* single or multiple words with parentheses: `a tall thin man picking (apricots)+` `a tall thin man picking (apricots)-` `a tall thin man (picking apricots)+` `a tall thin man (picking apricots)-`
|
||||||
|
* more effect with more symbols `a tall thin man (picking apricots)++`
|
||||||
|
* nesting `a tall thin man (picking apricots+)++` (`apricots` effectively gets `+++`)
|
||||||
|
* all of the above with explicit numbers `a tall thin man picking (apricots)1.1` `a tall thin man (picking (apricots)1.3)1.1`. (`+` is equivalent to 1.1, `++` is pow(1.1,2), `+++` is pow(1.1,3), etc; `-` means 0.9, `--` means pow(0.9,2), etc.)
|
||||||
|
* attention also applies to `[unconditioning]` so `a tall thin man picking apricots [(ladder)0.01]` will *very gently* nudge SD away from trying to draw the man on a ladder
|
||||||
|
|
||||||
|
You can use this to increase or decrease the amount of something. Starting from this prompt of `a man picking apricots from a tree`, let's see what happens if we increase and decrease how much attention we want Stable Diffusion to pay to the word `apricots`:
|
||||||
|
|
||||||
|
![an AI generated image of a man picking apricots from a tree](../assets/prompt_syntax/apricots-0.png)
|
||||||
|
|
||||||
|
Using `-` to reduce apricot-ness:
|
||||||
|
|
||||||
|
| `a man picking apricots- from a tree` | `a man picking apricots-- from a tree` | `a man picking apricots--- from a tree` |
|
||||||
|
| -- | -- | -- |
|
||||||
|
| ![an AI generated image of a man picking apricots from a tree, with smaller apricots](../assets/prompt_syntax/apricots--1.png) | ![an AI generated image of a man picking apricots from a tree, with even smaller and fewer apricots](../assets/prompt_syntax/apricots--2.png) | ![an AI generated image of a man picking apricots from a tree, with very few very small apricots](../assets/prompt_syntax/apricots--3.png) |
|
||||||
|
|
||||||
|
Using `+` to increase apricot-ness:
|
||||||
|
|
||||||
|
| `a man picking apricots+ from a tree` | `a man picking apricots++ from a tree` | `a man picking apricots+++ from a tree` | `a man picking apricots++++ from a tree` | `a man picking apricots+++++ from a tree` |
|
||||||
|
| -- | -- | -- | -- | -- |
|
||||||
|
| ![an AI generated image of a man picking apricots from a tree, with larger, more vibrant apricots](../assets/prompt_syntax/apricots-1.png) | ![an AI generated image of a man picking apricots from a tree with even larger, even more vibrant apricots](../assets/prompt_syntax/apricots-2.png) | ![an AI generated image of a man picking apricots from a tree, but the man has been replaced by a pile of apricots](../assets/prompt_syntax/apricots-3.png) | ![an AI generated image of a man picking apricots from a tree, but the man has been replaced by a mound of giant melting-looking apricots](../assets/prompt_syntax/apricots-4.png) | ![an AI generated image of a man picking apricots from a tree, but the man and the leaves and parts of the ground have all been replaced by giant melting-looking apricots](../assets/prompt_syntax/apricots-5.png) |
|
||||||
|
|
||||||
|
You can also change the balance between different parts of a prompt. For example, below is a `mountain man`:
|
||||||
|
|
||||||
|
![an AI generated image of a mountain man](../assets/prompt_syntax/mountain-man.png)
|
||||||
|
|
||||||
|
And here he is with more mountain:
|
||||||
|
|
||||||
|
| `mountain+ man` | `mountain++ man` | `mountain+++ man` |
|
||||||
|
| -- | -- | -- |
|
||||||
|
| ![](../assets/prompt_syntax/mountain1-man.png) | ![](../assets/prompt_syntax/mountain2-man.png) | ![](../assets/prompt_syntax/mountain3-man.png) |
|
||||||
|
|
||||||
|
Or, alternatively, with more man:
|
||||||
|
|
||||||
|
| `mountain man+` | `mountain man++` | `mountain man+++` | `mountain man++++` |
|
||||||
|
| -- | -- | -- | -- |
|
||||||
|
| ![](../assets/prompt_syntax/mountain-man1.png) | ![](../assets/prompt_syntax/mountain-man2.png) | ![](../assets/prompt_syntax/mountain-man3.png) | ![](../assets/prompt_syntax/mountain-man4.png) |
|
||||||
|
|
||||||
|
### Blending between prompts
|
||||||
|
|
||||||
|
* `("a tall thin man picking apricots", "a tall thin man picking pears").blend(1,1)`
|
||||||
|
* The existing prompt blending using `:<weight>` will continue to be supported - `("a tall thin man picking apricots", "a tall thin man picking pears").blend(1,1)` is equivalent to `a tall thin man picking apricots:1 a tall thin man picking pears:1` in the old syntax.
|
||||||
|
* Attention weights can be nested inside blends.
|
||||||
|
* Non-normalized blends are supported by passing `no_normalize` as an additional argument to the blend weights, eg `("a tall thin man picking apricots", "a tall thin man picking pears").blend(1,-1,no_normalize)`. very fun to explore local maxima in the feature space, but also easy to produce garbage output.
|
||||||
|
|
||||||
|
See the section below on "Prompt Blending" for more information about how this works.
|
||||||
|
|
||||||
|
### Cross-Attention Control ('prompt2prompt')
|
||||||
|
|
||||||
|
Sometimes an image you generate is almost right, and you just want to
|
||||||
|
change one detail without affecting the rest. You could use a photo editor and inpainting
|
||||||
|
to overpaint the area, but that's a pain. Here's where `prompt2prompt`
|
||||||
|
comes in handy.
|
||||||
|
|
||||||
|
Generate an image with a given prompt, record the seed of the image,
|
||||||
|
and then use the `prompt2prompt` syntax to substitute words in the
|
||||||
|
original prompt for words in a new prompt. This works for `img2img` as well.
|
||||||
|
|
||||||
|
* `a ("fluffy cat").swap("smiling dog") eating a hotdog`.
|
||||||
|
* quotes optional: `a (fluffy cat).swap(smiling dog) eating a hotdog`.
|
||||||
|
* for single word substitutions parentheses are also optional: `a cat.swap(dog) eating a hotdog`.
|
||||||
|
* Supports options `s_start`, `s_end`, `t_start`, `t_end` (each 0-1) loosely corresponding to bloc97's `prompt_edit_spatial_start/_end` and `prompt_edit_tokens_start/_end` but with the math swapped to make it easier to intuitively understand.
|
||||||
|
* Example usage:`a (cat).swap(dog, s_end=0.3) eating a hotdog` - the `s_end` argument means that the "spatial" (self-attention) edit will stop having any effect after 30% (=0.3) of the steps have been done, leaving Stable Diffusion with 70% of the steps where it is free to decide for itself how to reshape the cat-form into a dog form.
|
||||||
|
* The numbers represent a percentage through the step sequence where the edits should happen. 0 means the start (noisy starting image), 1 is the end (final image).
|
||||||
|
* For img2img, the step sequence does not start at 0 but instead at (1-strength) - so if strength is 0.7, s_start and s_end must both be greater than 0.3 (1-0.7) to have any effect.
|
||||||
|
* Convenience option `shape_freedom` (0-1) to specify how much "freedom" Stable Diffusion should have to change the shape of the subject being swapped.
|
||||||
|
* `a (cat).swap(dog, shape_freedom=0.5) eating a hotdog`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The `prompt2prompt` code is based off [bloc97's
|
||||||
|
colab](https://github.com/bloc97/CrossAttentionControl).
|
||||||
|
|
||||||
|
Note that `prompt2prompt` is not currently working with the runwayML
|
||||||
|
inpainting model, and may never work due to the way this model is set
|
||||||
|
up. If you attempt to use `prompt2prompt` you will get the original
|
||||||
|
image back. However, since this model is so good at inpainting, a
|
||||||
|
good substitute is to use the `clipseg` text masking option:
|
||||||
|
|
||||||
|
```
|
||||||
|
invoke> a fluffy cat eating a hotdot
|
||||||
|
Outputs:
|
||||||
|
[1010] outputs/000025.2182095108.png: a fluffy cat eating a hotdog
|
||||||
|
invoke> a smiling dog eating a hotdog -I 000025.2182095108.png -tm cat
|
||||||
|
```
|
||||||
|
|
||||||
|
### Escaping parantheses () and speech marks ""
|
||||||
|
|
||||||
|
If the model you are using has parentheses () or speech marks "" as
|
||||||
|
part of its syntax, you will need to "escape" these using a backslash,
|
||||||
|
so that`(my_keyword)` becomes `\(my_keyword\)`. Otherwise, the prompt
|
||||||
|
parser will attempt to interpret the parentheses as part of the prompt
|
||||||
|
syntax and it will get confused.
|
||||||
|
|
||||||
## **Prompt Blending**
|
## **Prompt Blending**
|
||||||
|
|
||||||
You may blend together different sections of the prompt to explore the
|
You may blend together different sections of the prompt to explore the
|
||||||
|
58
docs/features/WEBUIHOTKEYS.md
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# **WebUI Hotkey List**
|
||||||
|
|
||||||
|
## General
|
||||||
|
|
||||||
|
| Setting | Hotkey |
|
||||||
|
| ------------ | ---------------------- |
|
||||||
|
| a | Set All Parameters |
|
||||||
|
| s | Set Seed |
|
||||||
|
| u | Upscale |
|
||||||
|
| r | Restoration |
|
||||||
|
| i | Show Metadata |
|
||||||
|
| Ddl | Delete Image |
|
||||||
|
| alt + a | Focus prompt input |
|
||||||
|
| shift + i | Send To Image to Image |
|
||||||
|
| ctrl + enter | Start processing |
|
||||||
|
| shift + x | cancel Processing |
|
||||||
|
| shift + d | Toggle Dark Mode |
|
||||||
|
| ` | Toggle console |
|
||||||
|
|
||||||
|
## Tabs
|
||||||
|
|
||||||
|
| Setting | Hotkey |
|
||||||
|
| ------- | ------------------------- |
|
||||||
|
| 1 | Go to Text To Image Tab |
|
||||||
|
| 2 | Go to Image to Image Tab |
|
||||||
|
| 3 | Go to Inpainting Tab |
|
||||||
|
| 4 | Go to Outpainting Tab |
|
||||||
|
| 5 | Go to Nodes Tab |
|
||||||
|
| 6 | Go to Post Processing Tab |
|
||||||
|
|
||||||
|
## Gallery
|
||||||
|
|
||||||
|
| Setting | Hotkey |
|
||||||
|
| ------------ | ------------------------------- |
|
||||||
|
| g | Toggle Gallery |
|
||||||
|
| left arrow | Go to previous image in gallery |
|
||||||
|
| right arrow | Go to next image in gallery |
|
||||||
|
| shift + p | Pin gallery |
|
||||||
|
| shift + up | Increase gallery image size |
|
||||||
|
| shift + down | Decrease gallery image size |
|
||||||
|
| shift + r | Reset image gallery size |
|
||||||
|
|
||||||
|
## Inpainting
|
||||||
|
|
||||||
|
| Setting | Hotkey |
|
||||||
|
| -------------------------- | --------------------- |
|
||||||
|
| [ | Decrease brush size |
|
||||||
|
| ] | Increase brush size |
|
||||||
|
| alt + [ | Decrease mask opacity |
|
||||||
|
| alt + ] | Increase mask opacity |
|
||||||
|
| b | Select brush |
|
||||||
|
| e | Select eraser |
|
||||||
|
| ctrl + z | Undo brush stroke |
|
||||||
|
| ctrl + shift + z, ctrl + y | Redo brush stroke |
|
||||||
|
| h | Hide mask |
|
||||||
|
| shift + m | Invert mask |
|
||||||
|
| shift + c | Clear mask |
|
||||||
|
| shift + j | Expand canvas |
|
267
docs/installation/INSTALLING_MODELS.md
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
---
|
||||||
|
title: Installing Models
|
||||||
|
---
|
||||||
|
|
||||||
|
# :octicons-paintbrush-16: Installing Models
|
||||||
|
|
||||||
|
## Model Weight Files
|
||||||
|
|
||||||
|
The model weight files ('*.ckpt') are the Stable Diffusion "secret
|
||||||
|
sauce". They are the product of training the AI on millions of
|
||||||
|
captioned images gathered from multiple sources.
|
||||||
|
|
||||||
|
Originally there was only a single Stable Diffusion weights file,
|
||||||
|
which many people named `model.ckpt`. Now there are dozens or more
|
||||||
|
that have been "fine tuned" to provide particulary styles, genres, or
|
||||||
|
other features. InvokeAI allows you to install and run multiple model
|
||||||
|
weight files and switch between them quickly in the command-line and
|
||||||
|
web interfaces.
|
||||||
|
|
||||||
|
This manual will guide you through installing and configuring model
|
||||||
|
weight files.
|
||||||
|
|
||||||
|
## Base Models
|
||||||
|
|
||||||
|
InvokeAI comes with support for a good initial set of models listed in
|
||||||
|
the model configuration file `configs/models.yaml`. They are:
|
||||||
|
|
||||||
|
| Model | Weight File | Description | DOWNLOAD FROM |
|
||||||
|
| ---------------------- | ----------------------------- |--------------------------------- | ----------------|
|
||||||
|
| stable-diffusion-1.5 | v1-5-pruned-emaonly.ckpt | Most recent version of base Stable Diffusion model| https://huggingface.co/runwayml/stable-diffusion-v1-5 |
|
||||||
|
| stable-diffusion-1.4 | sd-v1-4.ckpt | Previous version of base Stable Diffusion model | https://huggingface.co/CompVis/stable-diffusion-v-1-4-original |
|
||||||
|
| inpainting-1.5 | sd-v1-5-inpainting.ckpt | Stable Diffusion 1.5 model specialized for inpainting | https://huggingface.co/runwayml/stable-diffusion-inpainting |
|
||||||
|
| waifu-diffusion-1.3 | model-epoch09-float32.ckpt | Stable Diffusion 1.4 trained to produce anime images | https://huggingface.co/hakurei/waifu-diffusion-v1-3 |
|
||||||
|
| <all models> | vae-ft-mse-840000-ema-pruned.ckpt | A fine-tune file add-on file that improves face generation | https://huggingface.co/stabilityai/sd-vae-ft-mse-original/ |
|
||||||
|
|
||||||
|
|
||||||
|
Note that these files are covered by an "Ethical AI" license which
|
||||||
|
forbids certain uses. You will need to create an account on the
|
||||||
|
Hugging Face website and accept the license terms before you can
|
||||||
|
access the files.
|
||||||
|
|
||||||
|
The predefined configuration file for InvokeAI (located at
|
||||||
|
`configs/models.yaml`) provides entries for each of these weights
|
||||||
|
files. `stable-diffusion-1.5` is the default model used, and we
|
||||||
|
strongly recommend that you install this weights file if nothing else.
|
||||||
|
|
||||||
|
## Community-Contributed Models
|
||||||
|
|
||||||
|
There are too many to list here and more are being contributed every
|
||||||
|
day. Hugging Face maintains a [fast-growing
|
||||||
|
repository](https://huggingface.co/sd-concepts-library) of fine-tune
|
||||||
|
(".bin") models that can be imported into InvokeAI by passing the
|
||||||
|
`--embedding_path` option to the `invoke.py` command.
|
||||||
|
|
||||||
|
[This page](https://rentry.org/sdmodels) hosts a large list of
|
||||||
|
official and unofficial Stable Diffusion models and where they can be
|
||||||
|
obtained.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
There are three ways to install weights files:
|
||||||
|
|
||||||
|
1. During InvokeAI installation, the `preload_models.py` script can
|
||||||
|
download them for you.
|
||||||
|
|
||||||
|
2. You can use the command-line interface (CLI) to import, configure
|
||||||
|
and modify new models files.
|
||||||
|
|
||||||
|
3. You can download the files manually and add the appropriate entries
|
||||||
|
to `models.yaml`.
|
||||||
|
|
||||||
|
### Installation via `preload_models.py`
|
||||||
|
|
||||||
|
This is the most automatic way. Run `scripts/preload_models.py` from
|
||||||
|
the console. It will ask you to select which models to download and
|
||||||
|
lead you through the steps of setting up a Hugging Face account if you
|
||||||
|
haven't done so already.
|
||||||
|
|
||||||
|
To start, from within the InvokeAI directory run the command `python
|
||||||
|
scripts/preload_models.py` (Linux/MacOS) or `python
|
||||||
|
scripts\preload_models.py` (Windows):
|
||||||
|
|
||||||
|
```
|
||||||
|
Loading Python libraries...
|
||||||
|
|
||||||
|
** INTRODUCTION **
|
||||||
|
Welcome to InvokeAI. This script will help download the Stable Diffusion weight files
|
||||||
|
and other large models that are needed for text to image generation. At any point you may interrupt
|
||||||
|
this program and resume later.
|
||||||
|
|
||||||
|
** WEIGHT SELECTION **
|
||||||
|
Would you like to download the Stable Diffusion model weights now? [y]
|
||||||
|
|
||||||
|
Choose the weight file(s) you wish to download. Before downloading you
|
||||||
|
will be given the option to view and change your selections.
|
||||||
|
|
||||||
|
[1] stable-diffusion-1.5:
|
||||||
|
The newest Stable Diffusion version 1.5 weight file (4.27 GB) (recommended)
|
||||||
|
Download? [y]
|
||||||
|
[2] inpainting-1.5:
|
||||||
|
RunwayML SD 1.5 model optimized for inpainting (4.27 GB) (recommended)
|
||||||
|
Download? [y]
|
||||||
|
[3] stable-diffusion-1.4:
|
||||||
|
The original Stable Diffusion version 1.4 weight file (4.27 GB)
|
||||||
|
Download? [n] n
|
||||||
|
[4] waifu-diffusion-1.3:
|
||||||
|
Stable Diffusion 1.4 fine tuned on anime-styled images (4.27)
|
||||||
|
Download? [n] y
|
||||||
|
[5] ft-mse-improved-autoencoder-840000:
|
||||||
|
StabilityAI improved autoencoder fine-tuned for human faces (recommended; 335 MB) (recommended)
|
||||||
|
Download? [y] y
|
||||||
|
The following weight files will be downloaded:
|
||||||
|
[1] stable-diffusion-1.5*
|
||||||
|
[2] inpainting-1.5
|
||||||
|
[4] waifu-diffusion-1.3
|
||||||
|
[5] ft-mse-improved-autoencoder-840000
|
||||||
|
*default
|
||||||
|
Ok to download? [y]
|
||||||
|
** LICENSE AGREEMENT FOR WEIGHT FILES **
|
||||||
|
|
||||||
|
1. To download the Stable Diffusion weight files you need to read and accept the
|
||||||
|
CreativeML Responsible AI license. If you have not already done so, please
|
||||||
|
create an account using the "Sign Up" button:
|
||||||
|
|
||||||
|
https://huggingface.co
|
||||||
|
|
||||||
|
You will need to verify your email address as part of the HuggingFace
|
||||||
|
registration process.
|
||||||
|
|
||||||
|
2. After creating the account, login under your account and accept
|
||||||
|
the license terms located here:
|
||||||
|
|
||||||
|
https://huggingface.co/CompVis/stable-diffusion-v-1-4-original
|
||||||
|
|
||||||
|
Press <enter> when you are ready to continue:
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
When the script is complete, you will find the downloaded weights
|
||||||
|
files in `models/ldm/stable-diffusion-v1` and a matching configuration
|
||||||
|
file in `configs/models.yaml`.
|
||||||
|
|
||||||
|
You can run the script again to add any models you didn't select the
|
||||||
|
first time. Note that as a safety measure the script will _never_
|
||||||
|
remove a previously-installed weights file. You will have to do this
|
||||||
|
manually.
|
||||||
|
|
||||||
|
### Installation via the CLI
|
||||||
|
|
||||||
|
You can install a new model, including any of the community-supported
|
||||||
|
ones, via the command-line client's `!import_model` command.
|
||||||
|
|
||||||
|
1. First download the desired model weights file and place it under `models/ldm/stable-diffusion-v1/`.
|
||||||
|
You may rename the weights file to something more memorable if you wish. Record the path of the
|
||||||
|
weights file (e.g. `models/ldm/stable-diffusion-v1/arabian-nights-1.0.ckpt`)
|
||||||
|
|
||||||
|
2. Launch the `invoke.py` CLI with `python scripts/invoke.py`.
|
||||||
|
|
||||||
|
3. At the `invoke>` command-line, enter the command `!import_model <path to model>`.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
`invoke> !import_model models/ldm/stable-diffusion-v1/arabian-nights-1.0.ckpt`
|
||||||
|
|
||||||
|
(Hint - the CLI supports file path autocompletion. Type a bit of the path
|
||||||
|
name and hit <tab> in order to get a choice of possible completions.)
|
||||||
|
|
||||||
|
4. Follow the wizard's instructions to complete installation as shown in the example
|
||||||
|
here:
|
||||||
|
|
||||||
|
```
|
||||||
|
invoke> <b>!import_model models/ldm/stable-diffusion-v1/arabian-nights-1.0.ckpt</b>
|
||||||
|
>> Model import in process. Please enter the values needed to configure this model:
|
||||||
|
|
||||||
|
Name for this model: <b>arabian-nights</b>
|
||||||
|
Description of this model: <b>Arabian Nights Fine Tune v1.0</b>
|
||||||
|
Configuration file for this model: <b>configs/stable-diffusion/v1-inference.yaml</b>
|
||||||
|
Default image width: <b>512</b>
|
||||||
|
Default image height: <b>512</b>
|
||||||
|
>> New configuration:
|
||||||
|
arabian-nights:
|
||||||
|
config: configs/stable-diffusion/v1-inference.yaml
|
||||||
|
description: Arabian Nights Fine Tune v1.0
|
||||||
|
height: 512
|
||||||
|
weights: models/ldm/stable-diffusion-v1/arabian-nights-1.0.ckpt
|
||||||
|
width: 512
|
||||||
|
OK to import [n]? <b>y</b>
|
||||||
|
>> Caching model stable-diffusion-1.4 in system RAM
|
||||||
|
>> Loading waifu-diffusion from models/ldm/stable-diffusion-v1/arabian-nights-1.0.ckpt
|
||||||
|
| LatentDiffusion: Running in eps-prediction mode
|
||||||
|
| DiffusionWrapper has 859.52 M params.
|
||||||
|
| Making attention of type 'vanilla' with 512 in_channels
|
||||||
|
| Working with z of shape (1, 4, 32, 32) = 4096 dimensions.
|
||||||
|
| Making attention of type 'vanilla' with 512 in_channels
|
||||||
|
| Using faster float16 precision
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
If you've previously installed the fine-tune VAE file `vae-ft-mse-840000-ema-pruned.ckpt`,
|
||||||
|
the wizard will also ask you if you want to add this VAE to the model.
|
||||||
|
|
||||||
|
The appropriate entry for this model will be added to `configs/models.yaml` and it will
|
||||||
|
be available to use in the CLI immediately.
|
||||||
|
|
||||||
|
The CLI has additional commands for switching among, viewing, editing,
|
||||||
|
deleting the available models. These are described in [Command Line
|
||||||
|
Client](../features/CLI.md#model-selection-and-importation), but the two most
|
||||||
|
frequently-used are `!models` and `!switch <name of model>`. The first
|
||||||
|
prints a table of models that InvokeAI knows about and their load
|
||||||
|
status. The second will load the requested model and lets you switch
|
||||||
|
back and forth quickly among loaded models.
|
||||||
|
|
||||||
|
### Manually editing of `configs/models.yaml`
|
||||||
|
|
||||||
|
If you are comfortable with a text editor then you may simply edit
|
||||||
|
`models.yaml` directly.
|
||||||
|
|
||||||
|
First you need to download the desired .ckpt file and place it in
|
||||||
|
`models/ldm/stable-diffusion-v1` as descirbed in step #1 in the
|
||||||
|
previous section. Record the path to the weights file,
|
||||||
|
e.g. `models/ldm/stable-diffusion-v1/arabian-nights-1.0.ckpt`
|
||||||
|
|
||||||
|
Then using a **text** editor (e.g. the Windows Notepad application),
|
||||||
|
open the file `configs/models.yaml`, and add a new stanza that follows
|
||||||
|
this model:
|
||||||
|
|
||||||
|
```
|
||||||
|
arabian-nights-1.0:
|
||||||
|
description: A great fine-tune in Arabian Nights style
|
||||||
|
weights: ./models/ldm/stable-diffusion-v1/arabian-nights-1.0.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: false
|
||||||
|
```
|
||||||
|
|
||||||
|
* arabian-nights-1.0
|
||||||
|
- This is the name of the model that you will refer to from within the
|
||||||
|
CLI and the WebGUI when you need to load and use the model.
|
||||||
|
|
||||||
|
* description
|
||||||
|
- Any description that you want to add to the model to remind you what
|
||||||
|
it is.
|
||||||
|
|
||||||
|
* weights
|
||||||
|
- Relative path to the .ckpt weights file for this model.
|
||||||
|
|
||||||
|
* config
|
||||||
|
- This is the confusingly-named configuration file for the model itself.
|
||||||
|
Use `./configs/stable-diffusion/v1-inference.yaml` unless the model happens
|
||||||
|
to need a custom configuration, in which case the place you downloaded it
|
||||||
|
from will tell you what to use instead. For example, the runwayML custom
|
||||||
|
inpainting model requires the file `configs/stable-diffusion/v1-inpainting-inference.yaml`.
|
||||||
|
This is already inclued in the InvokeAI distribution and is configured automatically
|
||||||
|
for you by the `preload_models.py` script.
|
||||||
|
|
||||||
|
* vae
|
||||||
|
- If you want to add a VAE file to the model, then enter its path here.
|
||||||
|
|
||||||
|
* width, height
|
||||||
|
- This is the width and height of the images used to train the model.
|
||||||
|
Currently they are always 512 and 512.
|
||||||
|
|
||||||
|
Save the `models.yaml` and relaunch InvokeAI. The new model should now be
|
||||||
|
available for your use.
|
||||||
|
|
||||||
|
|
@ -36,20 +36,6 @@ another environment with NVIDIA GPUs on-premises or in the cloud.
|
|||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
#### Get the data files
|
|
||||||
|
|
||||||
Go to
|
|
||||||
[Hugging Face](https://huggingface.co/CompVis/stable-diffusion-v-1-4-original),
|
|
||||||
and click "Access repository" to Download the model file `sd-v1-4.ckpt` (~4 GB)
|
|
||||||
to `~/Downloads`. You'll need to create an account but it's quick and free.
|
|
||||||
|
|
||||||
Also download the face restoration model.
|
|
||||||
|
|
||||||
```Shell
|
|
||||||
cd ~/Downloads
|
|
||||||
wget https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.4.pth
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Install [Docker](https://github.com/santisbon/guides#docker)
|
#### Install [Docker](https://github.com/santisbon/guides#docker)
|
||||||
|
|
||||||
On the Docker Desktop app, go to Preferences, Resources, Advanced. Increase the
|
On the Docker Desktop app, go to Preferences, Resources, Advanced. Increase the
|
||||||
@ -57,86 +43,61 @@ CPUs and Memory to avoid this
|
|||||||
[Issue](https://github.com/invoke-ai/InvokeAI/issues/342). You may need to
|
[Issue](https://github.com/invoke-ai/InvokeAI/issues/342). You may need to
|
||||||
increase Swap and Disk image size too.
|
increase Swap and Disk image size too.
|
||||||
|
|
||||||
|
#### Get a Huggingface-Token
|
||||||
|
|
||||||
|
Go to [Hugging Face](https://huggingface.co/settings/tokens), create a token and
|
||||||
|
temporary place it somewhere like a open texteditor window (but dont save it!,
|
||||||
|
only keep it open, we need it in the next step)
|
||||||
|
|
||||||
### Setup
|
### Setup
|
||||||
|
|
||||||
Set the fork you want to use and other variables.
|
Set the fork you want to use and other variables.
|
||||||
|
|
||||||
```Shell
|
!!! tip
|
||||||
TAG_STABLE_DIFFUSION="santisbon/stable-diffusion"
|
|
||||||
PLATFORM="linux/arm64"
|
|
||||||
GITHUB_STABLE_DIFFUSION="-b orig-gfpgan https://github.com/santisbon/stable-diffusion.git"
|
|
||||||
REQS_STABLE_DIFFUSION="requirements-linux-arm64.txt"
|
|
||||||
CONDA_SUBDIR="osx-arm64"
|
|
||||||
|
|
||||||
echo $TAG_STABLE_DIFFUSION
|
I preffer to save my env vars
|
||||||
echo $PLATFORM
|
in the repository root in a `.env` (or `.envrc`) file to automatically re-apply
|
||||||
echo $GITHUB_STABLE_DIFFUSION
|
them when I come back.
|
||||||
echo $REQS_STABLE_DIFFUSION
|
|
||||||
echo $CONDA_SUBDIR
|
The build- and run- scripts contain default values for almost everything,
|
||||||
|
besides the [Hugging Face Token](https://huggingface.co/settings/tokens) you
|
||||||
|
created in the last step.
|
||||||
|
|
||||||
|
Some Suggestions of variables you may want to change besides the Token:
|
||||||
|
|
||||||
|
| Environment-Variable | Description |
|
||||||
|
| ------------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
||||||
|
| `HUGGINGFACE_TOKEN="hg_aewirhghlawrgkjbarug2"` | This is the only required variable, without you can't get the checkpoint |
|
||||||
|
| `ARCH=aarch64` | if you are using a ARM based CPU |
|
||||||
|
| `INVOKEAI_TAG=yourname/invokeai:latest` | the Container Repository / Tag which will be used |
|
||||||
|
| `INVOKEAI_CONDA_ENV_FILE=environment-linux-aarch64.yml` | since environment.yml wouldn't work with aarch |
|
||||||
|
| `INVOKEAI_GIT="-b branchname https://github.com/username/reponame"` | if you want to use your own fork |
|
||||||
|
|
||||||
|
#### Build the Image
|
||||||
|
|
||||||
|
I provided a build script, which is located in `docker-build/build.sh` but still
|
||||||
|
needs to be executed from the Repository root.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-build/build.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Create a Docker volume for the downloaded model files.
|
The build Script not only builds the container, but also creates the docker
|
||||||
|
volume if not existing yet, or if empty it will just download the models. When
|
||||||
|
it is done you can run the container via the run script
|
||||||
|
|
||||||
```Shell
|
```bash
|
||||||
docker volume create my-vol
|
docker-build/run.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Copy the data files to the Docker volume using a lightweight Linux container.
|
When used without arguments, the container will start the website and provide
|
||||||
We'll need the models at run time. You just need to create the container with
|
you the link to open it. But if you want to use some other parameters you can
|
||||||
the mountpoint; no need to run this dummy container.
|
also do so.
|
||||||
|
|
||||||
```Shell
|
!!! warning "Deprecated"
|
||||||
cd ~/Downloads # or wherever you saved the files
|
|
||||||
|
|
||||||
docker create --platform $PLATFORM --name dummy --mount source=my-vol,target=/data alpine
|
From here on it is the rest of the previous Docker-Docs, which will still
|
||||||
|
provide usefull informations for one or the other.
|
||||||
docker cp sd-v1-4.ckpt dummy:/data
|
|
||||||
docker cp GFPGANv1.4.pth dummy:/data
|
|
||||||
```
|
|
||||||
|
|
||||||
Get the repo and download the Miniconda installer (we'll need it at build time).
|
|
||||||
Replace the URL with the version matching your container OS and the architecture
|
|
||||||
it will run on.
|
|
||||||
|
|
||||||
```Shell
|
|
||||||
cd ~
|
|
||||||
git clone $GITHUB_STABLE_DIFFUSION
|
|
||||||
|
|
||||||
cd stable-diffusion/docker-build
|
|
||||||
chmod +x entrypoint.sh
|
|
||||||
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-aarch64.sh -O anaconda.sh && chmod +x anaconda.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
Build the Docker image. Give it any tag `-t` that you want.
|
|
||||||
Choose the Linux container's host platform: x86-64/Intel is `amd64`. Apple
|
|
||||||
silicon is `arm64`. If deploying the container to the cloud to leverage powerful
|
|
||||||
GPU instances you'll be on amd64 hardware but if you're just trying this out
|
|
||||||
locally on Apple silicon choose arm64.
|
|
||||||
The application uses libraries that need to match the host environment so use
|
|
||||||
the appropriate requirements file.
|
|
||||||
Tip: Check that your shell session has the env variables set above.
|
|
||||||
|
|
||||||
```Shell
|
|
||||||
docker build -t $TAG_STABLE_DIFFUSION \
|
|
||||||
--platform $PLATFORM \
|
|
||||||
--build-arg gsd=$GITHUB_STABLE_DIFFUSION \
|
|
||||||
--build-arg rsd=$REQS_STABLE_DIFFUSION \
|
|
||||||
--build-arg cs=$CONDA_SUBDIR \
|
|
||||||
.
|
|
||||||
```
|
|
||||||
|
|
||||||
Run a container using your built image.
|
|
||||||
Tip: Make sure you've created and populated the Docker volume (above).
|
|
||||||
|
|
||||||
```Shell
|
|
||||||
docker run -it \
|
|
||||||
--rm \
|
|
||||||
--platform $PLATFORM \
|
|
||||||
--name stable-diffusion \
|
|
||||||
--hostname stable-diffusion \
|
|
||||||
--mount source=my-vol,target=/data \
|
|
||||||
$TAG_STABLE_DIFFUSION
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage (time to have fun)
|
## Usage (time to have fun)
|
||||||
|
|
||||||
@ -240,7 +201,8 @@ server with:
|
|||||||
python3 scripts/invoke.py --full_precision --web
|
python3 scripts/invoke.py --full_precision --web
|
||||||
```
|
```
|
||||||
|
|
||||||
If it's running on your Mac point your Mac web browser to http://127.0.0.1:9090
|
If it's running on your Mac point your Mac web browser to
|
||||||
|
<http://127.0.0.1:9090>
|
||||||
|
|
||||||
Press Control-C at the command line to stop the web server.
|
Press Control-C at the command line to stop the web server.
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: Linux
|
title: Manual Installation, Linux
|
||||||
---
|
---
|
||||||
|
|
||||||
# :fontawesome-brands-linux: Linux
|
# :fontawesome-brands-linux: Linux
|
||||||
@ -43,6 +43,7 @@ title: Linux
|
|||||||
environment named `invokeai` and activate the environment.
|
environment named `invokeai` and activate the environment.
|
||||||
|
|
||||||
```bash
|
```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 env create
|
||||||
(base) ~/InvokeAI$ conda activate invokeai
|
(base) ~/InvokeAI$ conda activate invokeai
|
||||||
(invokeai) ~/InvokeAI$
|
(invokeai) ~/InvokeAI$
|
||||||
@ -51,58 +52,54 @@ title: Linux
|
|||||||
After these steps, your command prompt will be prefixed by `(invokeai)` as shown
|
After these steps, your command prompt will be prefixed by `(invokeai)` as shown
|
||||||
above.
|
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
|
```bash
|
||||||
(invokeai) ~/InvokeAI$ python3 scripts/preload_models.py
|
(invokeai) ~/InvokeAI$ python3 scripts/preload_models.py
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! note
|
!!! 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
|
Please see [../features/INSTALLING_MODELS.md] for a manual process for doing the
|
||||||
model loading scheme to allow the script to work on GPU machines that are not
|
same thing.
|
||||||
internet connected. See [Preload Models](../features/OTHER.md#preload-models)
|
|
||||||
|
|
||||||
7. Now you need to install the weights for the stable diffusion model.
|
7. Start generating images!
|
||||||
|
|
||||||
- For running with the released weights, you will first need to set up an acount
|
# Command-line interface
|
||||||
with [Hugging Face](https://huggingface.co).
|
(invokeai) python scripts/invoke.py
|
||||||
- Use your credentials to log in, and then point your browser [here](https://huggingface.co/CompVis/stable-diffusion-v-1-4-original).
|
|
||||||
- You may be asked to sign a license agreement at this point.
|
|
||||||
- Click on "Files and versions" near the top of the page, and then click on the
|
|
||||||
file named "sd-v1-4.ckpt". You'll be taken to a page that prompts you to click
|
|
||||||
the "download" link. Save the file somewhere safe on your local machine.
|
|
||||||
|
|
||||||
Now run the following commands from within the stable-diffusion directory.
|
# or run the web interface on localhost:9090!
|
||||||
This will create a symbolic link from the stable-diffusion model.ckpt file, to
|
(invokeai) python scripts/invoke.py --web
|
||||||
the true location of the `sd-v1-4.ckpt` file.
|
|
||||||
|
|
||||||
```bash
|
# or run the web interface on your machine's network interface!
|
||||||
(invokeai) ~/InvokeAI$ mkdir -p models/ldm/stable-diffusion-v1
|
(invokeai) python scripts/invoke.py --web --host 0.0.0.0
|
||||||
(invokeai) ~/InvokeAI$ ln -sf /path/to/sd-v1-4.ckpt models/ldm/stable-diffusion-v1/model.ckpt
|
|
||||||
```
|
|
||||||
|
|
||||||
8. Start generating images!
|
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`.
|
||||||
|
|
||||||
```bash
|
9. Subsequently, to relaunch the script, be sure to run "conda
|
||||||
# for the pre-release weights use the -l or --liaon400m switch
|
activate invokeai" (step 5, second command), enter the `InvokeAI`
|
||||||
(invokeai) ~/InvokeAI$ python3 scripts/invoke.py -l
|
directory, and then launch the invoke script (step 8). If you forget
|
||||||
|
to activate the 'invokeai' environment, the script will fail with
|
||||||
# for the post-release weights do not use the switch
|
multiple `ModuleNotFound` errors.
|
||||||
(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.
|
|
||||||
|
|
||||||
## Updating to newer versions of the script
|
## 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
|
```bash
|
||||||
(invokeai) ~/InvokeAI$ git pull
|
(invokeai) ~/InvokeAI$ git pull
|
||||||
|
(invokeai) ~/InvokeAI$ rm -rf src # prevents conda freezing errors
|
||||||
(invokeai) ~/InvokeAI$ conda env update -f environment.yml
|
(invokeai) ~/InvokeAI$ conda env update -f environment.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: macOS
|
title: Manual Installation, macOS
|
||||||
---
|
---
|
||||||
|
|
||||||
# :fontawesome-brands-apple: macOS
|
# :fontawesome-brands-apple: macOS
|
||||||
@ -19,18 +19,9 @@ an issue on Github and we will do our best to help.
|
|||||||
|
|
||||||
## Installation
|
## 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 [sd-v1-4.ckpt (4.27 GB)](https://huggingface.co/CompVis/stable-diffusion-v-1-4-original/blob/main/sd-v1-4.ckpt) and note where you have saved it (probably the Downloads folder). You may want to move it somewhere else for longer term storage - SD needs this file to run.
|
|
||||||
|
|
||||||
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"
|
!!! 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)"
|
```bash title="install brew (and Xcode command line tools)"
|
||||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||||
@ -94,25 +85,6 @@ While that is downloading, open Terminal and run the following commands one at a
|
|||||||
cd InvokeAI
|
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"
|
!!! todo "Create the environment & install packages"
|
||||||
|
|
||||||
=== "M1 Mac"
|
=== "M1 Mac"
|
||||||
@ -131,25 +103,40 @@ While that is downloading, open Terminal and run the following commands one at a
|
|||||||
# Activate the environment (you need to do this every time you want to run SD)
|
# Activate the environment (you need to do this every time you want to run SD)
|
||||||
conda activate invokeai
|
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
|
!!! info
|
||||||
|
|
||||||
`export PIP_EXISTS_ACTION=w` is a precaution to fix `conda env
|
`export PIP_EXISTS_ACTION=w` is a precaution to fix `conda env
|
||||||
create -f environment-mac.yml` never finishing in some situations. So
|
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
|
## Common problems
|
||||||
|