mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-01-23 16:47:56 -05:00
Compare commits
107 Commits
latest-2.3
...
v2.3.0-rc5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c9fd00f98 | ||
|
|
8ab66a211c | ||
|
|
bc03ff8b30 | ||
|
|
0247d63511 | ||
|
|
7604b36577 | ||
|
|
4a026bd46e | ||
|
|
6241fc19e0 | ||
|
|
25d7d71dd8 | ||
|
|
2432adb38f | ||
|
|
a485d45400 | ||
|
|
a40bdef29f | ||
|
|
fc2670b4d6 | ||
|
|
c3807b044d | ||
|
|
b7ab025f40 | ||
|
|
633f702b39 | ||
|
|
0240656361 | ||
|
|
05bb9e444b | ||
|
|
0076757767 | ||
|
|
6ab03c4d08 | ||
|
|
142016827f | ||
|
|
466a82bcc2 | ||
|
|
05349f6cdc | ||
|
|
ab585aefae | ||
|
|
083ce9358b | ||
|
|
f56cf2400a | ||
|
|
fc53f6d47c | ||
|
|
2f70daef8f | ||
|
|
fc2a136eb0 | ||
|
|
ce3da40434 | ||
|
|
7933f27a72 | ||
|
|
1c197c602f | ||
|
|
90656aa7bf | ||
|
|
394b4a771e | ||
|
|
9c3f548900 | ||
|
|
5662d2daa8 | ||
|
|
fc0f966ad2 | ||
|
|
eb702a5049 | ||
|
|
1386d73302 | ||
|
|
6089f33e54 | ||
|
|
3a260cf54f | ||
|
|
9949a438f4 | ||
|
|
84c1122208 | ||
|
|
cc3d431928 | ||
|
|
c44b060a2e | ||
|
|
eff7fb89d8 | ||
|
|
cd5c112fcd | ||
|
|
563867fa99 | ||
|
|
2e230774c2 | ||
|
|
4ada4c9f1f | ||
|
|
9a6966924c | ||
|
|
0d62525f3d | ||
|
|
2ec864e37e | ||
|
|
9307ce3dc3 | ||
|
|
15996446e0 | ||
|
|
7a06c8fd89 | ||
|
|
4895fe8395 | ||
|
|
1e793a2dfe | ||
|
|
9c8fcaaf86 | ||
|
|
bf4344be51 | ||
|
|
f7532cdfd4 | ||
|
|
f1dd76c20b | ||
|
|
3016eeb6fb | ||
|
|
75b62d6ca8 | ||
|
|
82ae2769c8 | ||
|
|
61149abd2f | ||
|
|
eff126af6e | ||
|
|
0ca499cf96 | ||
|
|
3abf85e658 | ||
|
|
5095285854 | ||
|
|
93623a4449 | ||
|
|
0197459b02 | ||
|
|
1578bc68cc | ||
|
|
4ace397a99 | ||
|
|
d85a710211 | ||
|
|
536d534ab4 | ||
|
|
fc752a4e75 | ||
|
|
3c06d114c3 | ||
|
|
00d79c1fe3 | ||
|
|
60213893ab | ||
|
|
3b58413d9f | ||
|
|
1139884493 | ||
|
|
17e8f966d0 | ||
|
|
a42b25339f | ||
|
|
1b0731dd1a | ||
|
|
61c3886843 | ||
|
|
f76d57637e | ||
|
|
6bf73a0cf9 | ||
|
|
5145df21d9 | ||
|
|
e96ac61cb3 | ||
|
|
0e35d829c1 | ||
|
|
d08f048621 | ||
|
|
cfd453c1c7 | ||
|
|
a1b1a48fb3 | ||
|
|
b5160321bf | ||
|
|
0cc2a8176e | ||
|
|
9ac81c1dc4 | ||
|
|
50191774fc | ||
|
|
fcd9b813e3 | ||
|
|
2e3cd03b27 | ||
|
|
d569c9dec6 | ||
|
|
b23664c794 | ||
|
|
7fa3a499bb | ||
|
|
c50b64ec1d | ||
|
|
a32f6e9ea7 | ||
|
|
9ae55c91cc | ||
|
|
9e46badc40 | ||
|
|
ca0f3ec0e4 |
@@ -1,18 +1,21 @@
|
||||
# use this file as a whitelist
|
||||
*
|
||||
!backend
|
||||
!invokeai
|
||||
!ldm
|
||||
!pyproject.toml
|
||||
!README.md
|
||||
!scripts
|
||||
|
||||
# Guard against pulling in any models that might exist in the directory tree
|
||||
**/*.pt*
|
||||
**/*.ckpt
|
||||
|
||||
# whitelist frontend, but ignore node_modules
|
||||
invokeai/frontend/node_modules
|
||||
# ignore frontend but whitelist dist
|
||||
invokeai/frontend/**
|
||||
!invokeai/frontend/dist
|
||||
|
||||
# ignore invokeai/assets but whitelist invokeai/assets/web
|
||||
invokeai/assets
|
||||
!invokeai/assets/web
|
||||
|
||||
# ignore python cache
|
||||
**/__pycache__
|
||||
|
||||
8
.github/workflows/build-container.yml
vendored
8
.github/workflows/build-container.yml
vendored
@@ -47,16 +47,18 @@ jobs:
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=sha
|
||||
type=sha,enable=true,prefix=sha-,suffix=${{ matrix.flavor}},format=short
|
||||
type=raw,value={{branch}}-${{ matrix.flavor }}
|
||||
flavor: |
|
||||
latest=${{ matrix.flavor == 'cuda' && github.ref == 'refs/heads/main' }}
|
||||
suffix=${{ matrix.flavor }},onlatest=false
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
with:
|
||||
platforms: ${{ matrix.platforms }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
if: github.event_name != 'pull_request'
|
||||
@@ -67,7 +69,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build container
|
||||
uses: docker/build-push-action@v3
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
file: ${{ matrix.dockerfile }}
|
||||
|
||||
41
.github/workflows/pypi-release.yml
vendored
Normal file
41
.github/workflows/pypi-release.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
name: PyPI Release
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'ldm/invoke/_version.py'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
release:
|
||||
if: github.repository == 'invoke-ai/InvokeAI'
|
||||
runs-on: ubuntu-22.04
|
||||
env:
|
||||
TWINE_USERNAME: __token__
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
||||
TWINE_NON_INTERACTIVE: 1
|
||||
steps:
|
||||
- name: checkout sources
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: install deps
|
||||
run: pip install --upgrade build twine
|
||||
|
||||
- name: build package
|
||||
run: python3 -m build
|
||||
|
||||
- name: check distribution
|
||||
run: twine check dist/*
|
||||
|
||||
- name: check PyPI versions
|
||||
if: github.ref == 'refs/heads/main'
|
||||
run: |
|
||||
pip install --upgrade requests
|
||||
python -c "\
|
||||
import scripts.pypi_helper; \
|
||||
EXISTS=scripts.pypi_helper.local_on_pypi(); \
|
||||
print(f'PACKAGE_EXISTS={EXISTS}')" >> $GITHUB_ENV
|
||||
|
||||
- name: upload package
|
||||
if: env.PACKAGE_EXISTS == 'False' && env.TWINE_PASSWORD != ''
|
||||
run: twine upload dist/*
|
||||
57
.github/workflows/test-invoke-pip.yml
vendored
57
.github/workflows/test-invoke-pip.yml
vendored
@@ -8,10 +8,11 @@ on:
|
||||
- 'ready_for_review'
|
||||
- 'opened'
|
||||
- 'synchronize'
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
matrix:
|
||||
@@ -62,28 +63,13 @@ jobs:
|
||||
# github-env: $env:GITHUB_ENV
|
||||
name: ${{ matrix.pytorch }} on ${{ matrix.python-version }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
PIP_USE_PEP517: '1'
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
id: checkout-sources
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: setup python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Set Cache-Directory Windows
|
||||
if: runner.os == 'Windows'
|
||||
id: set-cache-dir-windows
|
||||
run: |
|
||||
echo "CACHE_DIR=$HOME\invokeai\models" >> ${{ matrix.github-env }}
|
||||
echo "PIP_NO_CACHE_DIR=1" >> ${{ matrix.github-env }}
|
||||
|
||||
- name: Set Cache-Directory others
|
||||
if: runner.os != 'Windows'
|
||||
id: set-cache-dir-others
|
||||
run: echo "CACHE_DIR=$HOME/invokeai/models" >> ${{ matrix.github-env }}
|
||||
|
||||
- name: set test prompt to main branch validation
|
||||
if: ${{ github.ref == 'refs/heads/main' }}
|
||||
run: echo "TEST_PROMPTS=tests/preflight_prompts.txt" >> ${{ matrix.github-env }}
|
||||
@@ -92,26 +78,29 @@ jobs:
|
||||
if: ${{ github.ref != 'refs/heads/main' }}
|
||||
run: echo "TEST_PROMPTS=tests/validate_pr_prompt.txt" >> ${{ matrix.github-env }}
|
||||
|
||||
- name: setup python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: pip
|
||||
cache-dependency-path: pyproject.toml
|
||||
|
||||
- name: install invokeai
|
||||
env:
|
||||
PIP_EXTRA_INDEX_URL: ${{ matrix.extra-index-url }}
|
||||
run: >
|
||||
pip3 install
|
||||
--use-pep517
|
||||
--editable=".[test]"
|
||||
|
||||
- name: run pytest
|
||||
id: run-pytest
|
||||
run: pytest
|
||||
|
||||
- name: Use Cached models
|
||||
id: cache-sd-model
|
||||
uses: actions/cache@v3
|
||||
env:
|
||||
cache-name: huggingface-models
|
||||
with:
|
||||
path: ${{ env.CACHE_DIR }}
|
||||
key: ${{ env.cache-name }}
|
||||
enableCrossOsArchive: true
|
||||
- name: set INVOKEAI_OUTDIR
|
||||
run: >
|
||||
python -c
|
||||
"import os;from ldm.invoke.globals import Globals;OUTDIR=os.path.join(Globals.root,str('outputs'));print(f'INVOKEAI_OUTDIR={OUTDIR}')"
|
||||
>> ${{ matrix.github-env }}
|
||||
|
||||
- name: run invokeai-configure
|
||||
id: run-preload-models
|
||||
@@ -124,9 +113,8 @@ jobs:
|
||||
--full-precision
|
||||
# can't use fp16 weights without a GPU
|
||||
|
||||
- name: Run the tests
|
||||
if: runner.os != 'Windows'
|
||||
id: run-tests
|
||||
- name: run invokeai
|
||||
id: run-invokeai
|
||||
env:
|
||||
# Set offline mode to make sure configure preloaded successfully.
|
||||
HF_HUB_OFFLINE: 1
|
||||
@@ -137,10 +125,11 @@ jobs:
|
||||
--no-patchmatch
|
||||
--no-nsfw_checker
|
||||
--from_file ${{ env.TEST_PROMPTS }}
|
||||
--outdir ${{ env.INVOKEAI_OUTDIR }}/${{ matrix.python-version }}/${{ matrix.pytorch }}
|
||||
|
||||
- name: Archive results
|
||||
id: archive-results
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: results_${{ matrix.pytorch }}_${{ matrix.python-version }}
|
||||
path: ${{ env.INVOKEAI_ROOT }}/outputs
|
||||
name: results
|
||||
path: ${{ env.INVOKEAI_OUTDIR }}
|
||||
|
||||
@@ -4,21 +4,23 @@
|
||||
|
||||
ARG PYTHON_VERSION=3.9
|
||||
##################
|
||||
### base image ###
|
||||
## base image ##
|
||||
##################
|
||||
FROM python:${PYTHON_VERSION}-slim AS python-base
|
||||
|
||||
# prepare for buildkit cache
|
||||
RUN rm -f /etc/apt/apt.conf.d/docker-clean
|
||||
|
||||
# Install necesarry packages
|
||||
RUN \
|
||||
--mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||
apt-get update \
|
||||
&& apt-get install -y \
|
||||
&& apt-get install \
|
||||
-yqq \
|
||||
--no-install-recommends \
|
||||
libgl1-mesa-glx=20.3.* \
|
||||
libglib2.0-0=2.66.* \
|
||||
libopencv-dev=4.5.* \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# set working directory and path
|
||||
@@ -27,85 +29,58 @@ ARG APPNAME=InvokeAI
|
||||
WORKDIR ${APPDIR}
|
||||
ENV PATH=${APPDIR}/${APPNAME}/bin:$PATH
|
||||
|
||||
######################
|
||||
### build frontend ###
|
||||
######################
|
||||
FROM node:lts as frontend-builder
|
||||
|
||||
# Copy Sources
|
||||
ARG APPDIR=/usr/src
|
||||
WORKDIR ${APPDIR}
|
||||
COPY --link . .
|
||||
|
||||
# install dependencies and build frontend
|
||||
WORKDIR ${APPDIR}/invokeai/frontend
|
||||
RUN \
|
||||
--mount=type=cache,target=/usr/local/share/.cache/yarn/v6 \
|
||||
yarn install \
|
||||
--prefer-offline \
|
||||
--frozen-lockfile \
|
||||
--non-interactive \
|
||||
--production=false \
|
||||
&& yarn build
|
||||
|
||||
###################################
|
||||
### install python dependencies ###
|
||||
###################################
|
||||
#######################
|
||||
## build pyproject ##
|
||||
#######################
|
||||
FROM python-base AS pyproject-builder
|
||||
ENV PIP_USE_PEP517=1
|
||||
|
||||
# prepare for buildkit cache
|
||||
ARG PIP_CACHE_DIR=/var/cache/buildkit/pip
|
||||
ENV PIP_CACHE_DIR ${PIP_CACHE_DIR}
|
||||
RUN mkdir -p ${PIP_CACHE_DIR}
|
||||
|
||||
# Install dependencies
|
||||
RUN \
|
||||
--mount=type=cache,target=${PIP_CACHE_DIR} \
|
||||
--mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||
apt-get update \
|
||||
&& apt-get install -y \
|
||||
&& apt-get install \
|
||||
-yqq \
|
||||
--no-install-recommends \
|
||||
build-essential=12.9 \
|
||||
gcc=4:10.2.* \
|
||||
python3-dev=3.9.* \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# create virtual environment
|
||||
RUN python3 -m venv "${APPNAME}" \
|
||||
RUN --mount=type=cache,target=${PIP_CACHE_DIR} \
|
||||
python3 -m venv "${APPNAME}" \
|
||||
--upgrade-deps
|
||||
|
||||
# copy sources
|
||||
COPY --from=frontend-builder ${APPDIR} .
|
||||
COPY --link . .
|
||||
|
||||
# install pyproject.toml
|
||||
ARG PIP_EXTRA_INDEX_URL
|
||||
ENV PIP_EXTRA_INDEX_URL ${PIP_EXTRA_INDEX_URL}
|
||||
RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \
|
||||
"${APPDIR}/${APPNAME}/bin/pip" install \
|
||||
--use-pep517 \
|
||||
.
|
||||
ARG PIP_PACKAGE=.
|
||||
RUN --mount=type=cache,target=${PIP_CACHE_DIR} \
|
||||
"${APPDIR}/${APPNAME}/bin/pip" install ${PIP_PACKAGE}
|
||||
|
||||
# build patchmatch
|
||||
RUN python3 -c "from patchmatch import patch_match"
|
||||
|
||||
#####################
|
||||
### runtime image ###
|
||||
## runtime image ##
|
||||
#####################
|
||||
FROM python-base AS runtime
|
||||
|
||||
# setup environment
|
||||
COPY --from=pyproject-builder ${APPDIR}/${APPNAME} ${APPDIR}/${APPNAME}
|
||||
COPY --from=pyproject-builder --link ${APPDIR}/${APPNAME} ${APPDIR}/${APPNAME}
|
||||
ENV INVOKEAI_ROOT=/data
|
||||
ENV INVOKE_MODEL_RECONFIGURE="--yes --default_only"
|
||||
|
||||
# build patchmatch
|
||||
RUN \
|
||||
--mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||
apt-get update \
|
||||
&& apt-get install -y \
|
||||
--no-install-recommends \
|
||||
build-essential=12.9 \
|
||||
&& PYTHONDONTWRITEBYTECODE=1 \
|
||||
python3 -c "from patchmatch import patch_match" \
|
||||
&& apt-get remove -y \
|
||||
--autoremove \
|
||||
build-essential \
|
||||
&& apt-get autoclean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# set Entrypoint and default CMD
|
||||
ENTRYPOINT [ "invokeai" ]
|
||||
CMD [ "--web", "--host=0.0.0.0" ]
|
||||
|
||||
@@ -17,14 +17,14 @@ DOCKERFILE=${INVOKE_DOCKERFILE:-Dockerfile}
|
||||
|
||||
# print the settings
|
||||
echo -e "You are using these values:\n"
|
||||
echo -e "Dockerfile: \t${DOCKERFILE}"
|
||||
echo -e "index-url: \t${PIP_EXTRA_INDEX_URL:-none}"
|
||||
echo -e "Volumename: \t${VOLUMENAME}"
|
||||
echo -e "Platform: \t${PLATFORM}"
|
||||
echo -e "Registry: \t${CONTAINER_REGISTRY}"
|
||||
echo -e "Repository: \t${CONTAINER_REPOSITORY}"
|
||||
echo -e "Container Tag: \t${CONTAINER_TAG}"
|
||||
echo -e "Container Image: ${CONTAINER_IMAGE}\n"
|
||||
echo -e "Dockerfile:\t\t${DOCKERFILE}"
|
||||
echo -e "index-url:\t\t${PIP_EXTRA_INDEX_URL:-none}"
|
||||
echo -e "Volumename:\t\t${VOLUMENAME}"
|
||||
echo -e "Platform:\t\t${PLATFORM}"
|
||||
echo -e "Registry:\t\t${CONTAINER_REGISTRY}"
|
||||
echo -e "Repository:\t\t${CONTAINER_REPOSITORY}"
|
||||
echo -e "Container Tag:\t\t${CONTAINER_TAG}"
|
||||
echo -e "Container Image:\t${CONTAINER_IMAGE}\n"
|
||||
|
||||
# Create docker volume
|
||||
if [[ -n "$(docker volume ls -f name="${VOLUMENAME}" -q)" ]]; then
|
||||
@@ -35,9 +35,10 @@ else
|
||||
fi
|
||||
|
||||
# Build Container
|
||||
docker build \
|
||||
DOCKER_BUILDKIT=1 docker build \
|
||||
--platform="${PLATFORM}" \
|
||||
--tag="${CONTAINER_IMAGE}" \
|
||||
${PIP_EXTRA_INDEX_URL:+--build-arg="PIP_EXTRA_INDEX_URL=${PIP_EXTRA_INDEX_URL}"} \
|
||||
${PIP_PACKAGE:+--build-arg="PIP_PACKAGE=${PIP_PACKAGE}"} \
|
||||
--file="${DOCKERFILE}" \
|
||||
..
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
if [[ -z "$PIP_EXTRA_INDEX_URL" ]]; then
|
||||
# Decide which container flavor to build if not specified
|
||||
if [[ -z "$CONTAINER_FLAVOR" ]]; then
|
||||
if [[ -z "$CONTAINER_FLAVOR" ]] && python -c "import torch" &>/dev/null; then
|
||||
# Check for CUDA and ROCm
|
||||
CUDA_AVAILABLE=$(python -c "import torch;print(torch.cuda.is_available())")
|
||||
ROCM_AVAILABLE=$(python -c "import torch;print(torch.version.hip is not None)")
|
||||
if [[ "$(uname -s)" != "Darwin" && "${CUDA_AVAILABLE}" == "True" ]]; then
|
||||
CONTAINER_FLAVOR=cuda
|
||||
if [[ "$(uname -s)" != "Darwin" && "${CUDA_AVAILABLE}" == "True" ]]; then
|
||||
CONTAINER_FLAVOR="cuda"
|
||||
elif [[ "$(uname -s)" != "Darwin" && "${ROCM_AVAILABLE}" == "True" ]]; then
|
||||
CONTAINER_FLAVOR="rocm"
|
||||
else
|
||||
@@ -16,9 +16,11 @@ if [[ -z "$PIP_EXTRA_INDEX_URL" ]]; then
|
||||
fi
|
||||
# Set PIP_EXTRA_INDEX_URL based on container flavor
|
||||
if [[ "$CONTAINER_FLAVOR" == "rocm" ]]; then
|
||||
PIP_EXTRA_INDEX_URL="${PIP_EXTRA_INDEX_URL-"https://download.pytorch.org/whl/rocm"}"
|
||||
elif CONTAINER_FLAVOR=cpu; then
|
||||
PIP_EXTRA_INDEX_URL="${PIP_EXTRA_INDEX_URL-"https://download.pytorch.org/whl/cpu"}"
|
||||
PIP_EXTRA_INDEX_URL="https://download.pytorch.org/whl/rocm"
|
||||
elif [[ "$CONTAINER_FLAVOR" == "cpu" ]]; then
|
||||
PIP_EXTRA_INDEX_URL="https://download.pytorch.org/whl/cpu"
|
||||
# elif [[ -z "$CONTAINER_FLAVOR" || "$CONTAINER_FLAVOR" == "cuda" ]]; then
|
||||
# PIP_PACKAGE=${PIP_PACKAGE-".[xformers]"}
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -30,6 +32,7 @@ PLATFORM="${PLATFORM-Linux/${ARCH}}"
|
||||
INVOKEAI_BRANCH="${INVOKEAI_BRANCH-$(git branch --show)}"
|
||||
CONTAINER_REGISTRY="${CONTAINER_REGISTRY-"ghcr.io"}"
|
||||
CONTAINER_REPOSITORY="${CONTAINER_REPOSITORY-"$(whoami)/${REPOSITORY_NAME}"}"
|
||||
CONTAINER_FLAVOR="${CONTAINER_FLAVOR-cuda}"
|
||||
CONTAINER_TAG="${CONTAINER_TAG-"${INVOKEAI_BRANCH##*/}-${CONTAINER_FLAVOR}"}"
|
||||
CONTAINER_IMAGE="${CONTAINER_REGISTRY}/${CONTAINER_REPOSITORY}:${CONTAINER_TAG}"
|
||||
CONTAINER_IMAGE="${CONTAINER_IMAGE,,}"
|
||||
|
||||
@@ -16,10 +16,6 @@ title: Installing with Docker
|
||||
|
||||
For general use, install locally to leverage your machine's GPU.
|
||||
|
||||
!!! tip "For running on a cloud instance/service"
|
||||
|
||||
Check out the [Running InvokeAI in the cloud with Docker](#running-invokeai-in-the-cloud-with-docker) section below
|
||||
|
||||
## Why containers?
|
||||
|
||||
They provide a flexible, reliable way to build and deploy InvokeAI. You'll also
|
||||
@@ -78,38 +74,40 @@ Some Suggestions of variables you may want to change besides the Token:
|
||||
|
||||
<figure markdown>
|
||||
|
||||
| Environment-Variable | Default value | Description |
|
||||
| -------------------- | ----------------------------- | -------------------------------------------------------------------------------------------- |
|
||||
| `HUGGINGFACE_TOKEN` | No default, but **required**! | This is the only **required** variable, without it you can't download the huggingface models |
|
||||
| `REPOSITORY_NAME` | The Basename of the Repo folder | This name will used as the container repository/image name |
|
||||
| `VOLUMENAME` | `${REPOSITORY_NAME,,}_data` | Name of the Docker Volume where model files will be stored |
|
||||
| `ARCH` | arch of the build machine | can be changed if you want to build the image for another arch |
|
||||
| `INVOKEAI_TAG` | latest | the Container Repository / Tag which will be used |
|
||||
| `PIP_REQUIREMENTS` | `requirements-lin-cuda.txt` | the requirements file to use (from `environments-and-requirements`) |
|
||||
| `CONTAINER_FLAVOR` | cuda | the flavor of the image, which can be changed if you build f.e. with amd requirements file. |
|
||||
| `INVOKE_DOCKERFILE` | `docker-build/Dockerfile` | the Dockerfile which should be built, handy for development |
|
||||
| Environment-Variable <img width="220" align="right"/> | Default value <img width="360" align="right"/> | Description |
|
||||
| ----------------------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `HUGGING_FACE_HUB_TOKEN` | No default, but **required**! | This is the only **required** variable, without it you can't download the huggingface models |
|
||||
| `REPOSITORY_NAME` | The Basename of the Repo folder | This name will used as the container repository/image name |
|
||||
| `VOLUMENAME` | `${REPOSITORY_NAME,,}_data` | Name of the Docker Volume where model files will be stored |
|
||||
| `ARCH` | arch of the build machine | Can be changed if you want to build the image for another arch |
|
||||
| `CONTAINER_REGISTRY` | ghcr.io | Name of the Container Registry to use for the full tag |
|
||||
| `CONTAINER_REPOSITORY` | `$(whoami)/${REPOSITORY_NAME}` | Name of the Container Repository |
|
||||
| `CONTAINER_FLAVOR` | `cuda` | The flavor of the image to built, available options are `cuda`, `rocm` and `cpu`. If you choose `rocm` or `cpu`, the extra-index-url will be selected automatically, unless you set one yourself. |
|
||||
| `CONTAINER_TAG` | `${INVOKEAI_BRANCH##*/}-${CONTAINER_FLAVOR}` | The Container Repository / Tag which will be used |
|
||||
| `INVOKE_DOCKERFILE` | `Dockerfile` | The Dockerfile which should be built, handy for development |
|
||||
| `PIP_EXTRA_INDEX_URL` | | If you want to use a custom pip-extra-index-url |
|
||||
|
||||
</figure>
|
||||
|
||||
#### 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.
|
||||
I provided a build script, which is located next to the Dockerfile in
|
||||
`docker/build.sh`. It can be executed from repository root like this:
|
||||
|
||||
```bash
|
||||
./docker-build/build.sh
|
||||
./docker/build.sh
|
||||
```
|
||||
|
||||
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.
|
||||
volume if not existing yet.
|
||||
|
||||
#### Run the Container
|
||||
|
||||
After the build process is done, you can run the container via the provided
|
||||
`docker-build/run.sh` script
|
||||
`docker/run.sh` script
|
||||
|
||||
```bash
|
||||
./docker-build/run.sh
|
||||
./docker/run.sh
|
||||
```
|
||||
|
||||
When used without arguments, the container will start the webserver and provide
|
||||
@@ -119,7 +117,7 @@ also do so.
|
||||
!!! example "run script example"
|
||||
|
||||
```bash
|
||||
./docker-build/run.sh "banana sushi" -Ak_lms -S42 -s10
|
||||
./docker/run.sh "banana sushi" -Ak_lms -S42 -s10
|
||||
```
|
||||
|
||||
This would generate the legendary "banana sushi" with Seed 42, k_lms Sampler and 10 steps.
|
||||
@@ -130,16 +128,18 @@ also do so.
|
||||
|
||||
## Running the container on your GPU
|
||||
|
||||
If you have an Nvidia GPU, you can enable InvokeAI to run on the GPU by running the container with an extra
|
||||
environment variable to enable GPU usage and have the process run much faster:
|
||||
If you have an Nvidia GPU, you can enable InvokeAI to run on the GPU by running
|
||||
the container with an extra environment variable to enable GPU usage and have
|
||||
the process run much faster:
|
||||
|
||||
```bash
|
||||
GPU_FLAGS=all ./docker-build/run.sh
|
||||
GPU_FLAGS=all ./docker/run.sh
|
||||
```
|
||||
|
||||
This passes the `--gpus all` to docker and uses the GPU.
|
||||
|
||||
If you don't have a GPU (or your host is not yet setup to use it) you will see a message like this:
|
||||
If you don't have a GPU (or your host is not yet setup to use it) you will see a
|
||||
message like this:
|
||||
|
||||
`docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]].`
|
||||
|
||||
@@ -147,84 +147,8 @@ You can use the full set of GPU combinations documented here:
|
||||
|
||||
https://docs.docker.com/config/containers/resource_constraints/#gpu
|
||||
|
||||
For example, use `GPU_FLAGS=device=GPU-3a23c669-1f69-c64e-cf85-44e9b07e7a2a` to choose a specific device identified by a UUID.
|
||||
|
||||
## Running InvokeAI in the cloud with Docker
|
||||
|
||||
We offer an optimized Ubuntu-based image that has been well-tested in cloud deployments. Note: it also works well locally on Linux x86_64 systems with an Nvidia GPU. It *may* also work on Windows under WSL2 and on Intel Mac (not tested).
|
||||
|
||||
An advantage of this method is that it does not need any local setup or additional dependencies.
|
||||
|
||||
See the `docker-build/Dockerfile.cloud` file to familizarize yourself with the image's content.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- a `docker` runtime
|
||||
- `make` (optional but helps for convenience)
|
||||
- Huggingface token to download models, or an existing InvokeAI runtime directory from a previous installation
|
||||
|
||||
Neither local Python nor any dependencies are required. If you don't have `make` (part of `build-essentials` on Ubuntu), or do not wish to install it, the commands from the `docker-build/Makefile` are readily adaptable to be executed directly.
|
||||
|
||||
### Building and running the image locally
|
||||
|
||||
1. Clone this repo and `cd docker-build`
|
||||
1. `make build` - this will build the image. (This does *not* require a GPU-capable system).
|
||||
1. _(skip this step if you already have a complete InvokeAI runtime directory)_
|
||||
- `make configure` (This does *not* require a GPU-capable system)
|
||||
- this will create a local cache of models and configs (a.k.a the _runtime dir_)
|
||||
- enter your Huggingface token when prompted
|
||||
1. `make web`
|
||||
1. Open the `http://localhost:9090` URL in your browser, and enjoy the banana sushi!
|
||||
|
||||
To use InvokeAI on the cli, run `make cli`. To open a Bash shell in the container for arbitraty advanced use, `make shell`.
|
||||
|
||||
#### Building and running without `make`
|
||||
|
||||
(Feel free to adapt paths such as `${HOME}/invokeai` to your liking, and modify the CLI arguments as necessary).
|
||||
|
||||
!!! example "Build the image and configure the runtime directory"
|
||||
```Shell
|
||||
cd docker-build
|
||||
|
||||
DOCKER_BUILDKIT=1 docker build -t local/invokeai:latest -f Dockerfile.cloud ..
|
||||
|
||||
docker run --rm -it -v ${HOME}/invokeai:/mnt/invokeai local/invokeai:latest -c "python scripts/configure_invokeai.py"
|
||||
```
|
||||
|
||||
!!! example "Run the web server"
|
||||
```Shell
|
||||
docker run --runtime=nvidia --gpus=all --rm -it -v ${HOME}/invokeai:/mnt/invokeai -p9090:9090 local/invokeai:latest
|
||||
```
|
||||
|
||||
Access the Web UI at http://localhost:9090
|
||||
|
||||
!!! example "Run the InvokeAI interactive CLI"
|
||||
```
|
||||
docker run --runtime=nvidia --gpus=all --rm -it -v ${HOME}/invokeai:/mnt/invokeai local/invokeai:latest -c "python scripts/invoke.py"
|
||||
```
|
||||
|
||||
### Running the image in the cloud
|
||||
|
||||
This image works anywhere you can run a container with a mounted Docker volume. You may either build this image on a cloud instance, or build and push it to your Docker registry. To manually run this on a cloud instance (such as AWS EC2, GCP or Azure VM):
|
||||
|
||||
1. build this image either in the cloud (you'll need to pull the repo), or locally
|
||||
1. `docker tag` it as `your-registry/invokeai` and push to your registry (i.e. Dockerhub)
|
||||
1. `docker pull` it on your cloud instance
|
||||
1. configure the runtime directory as per above example, using `docker run ... configure_invokeai.py` script
|
||||
1. use either one of the `docker run` commands above, substituting the image name for your own image.
|
||||
|
||||
To run this on Runpod, please refer to the following Runpod template: https://www.runpod.io/console/gpu-secure-cloud?template=vm19ukkycf (you need a Runpod subscription). When launching the template, feel free to set the image to pull your own build.
|
||||
|
||||
The template's `README` provides ample detail, but at a high level, the process is as follows:
|
||||
|
||||
1. create a pod using this Docker image
|
||||
1. ensure the pod has an `INVOKEAI_ROOT=<path_to_your_persistent_volume>` environment variable, and that it corresponds to the path to your pod's persistent volume mount
|
||||
1. Run the pod with `sleep infinity` as the Docker command
|
||||
1. Use Runpod basic SSH to connect to the pod, and run `python scripts/configure_invokeai.py` script
|
||||
1. Stop the pod, and change the Docker command to `python scripts/invoke.py --web --host 0.0.0.0`
|
||||
1. Run the pod again, connect to your pod on HTTP port 9090, and enjoy the banana sushi!
|
||||
|
||||
Running on other cloud providers such as Vast.ai will likely work in a similar fashion.
|
||||
For example, use `GPU_FLAGS=device=GPU-3a23c669-1f69-c64e-cf85-44e9b07e7a2a` to
|
||||
choose a specific device identified by a UUID.
|
||||
|
||||
---
|
||||
|
||||
@@ -240,13 +164,12 @@ Running on other cloud providers such as Vast.ai will likely work in a similar f
|
||||
If you're on a **Linux container** the `invoke` script is **automatically
|
||||
started** and the output dir set to the Docker volume you created earlier.
|
||||
|
||||
If you're **directly on macOS follow these startup instructions**.
|
||||
With the Conda environment activated (`conda activate ldm`), run the interactive
|
||||
If you're **directly on macOS follow these startup instructions**. With the
|
||||
Conda environment activated (`conda activate ldm`), run the interactive
|
||||
interface that combines the functionality of the original scripts `txt2img` and
|
||||
`img2img`:
|
||||
Use the more accurate but VRAM-intensive full precision math because
|
||||
half-precision requires autocast and won't work.
|
||||
By default the images are saved in `outputs/img-samples/`.
|
||||
`img2img`: Use the more accurate but VRAM-intensive full precision math because
|
||||
half-precision requires autocast and won't work. By default the images are saved
|
||||
in `outputs/img-samples/`.
|
||||
|
||||
```Shell
|
||||
python3 scripts/invoke.py --full_precision
|
||||
@@ -262,9 +185,9 @@ invoke> q
|
||||
### Text to Image
|
||||
|
||||
For quick (but bad) image results test with 5 steps (default 50) and 1 sample
|
||||
image. This will let you know that everything is set up correctly.
|
||||
Then increase steps to 100 or more for good (but slower) results.
|
||||
The prompt can be in quotes or not.
|
||||
image. This will let you know that everything is set up correctly. Then increase
|
||||
steps to 100 or more for good (but slower) results. The prompt can be in quotes
|
||||
or not.
|
||||
|
||||
```Shell
|
||||
invoke> The hulk fighting with sheldon cooper -s5 -n1
|
||||
@@ -277,10 +200,9 @@ You'll need to experiment to see if face restoration is making it better or
|
||||
worse for your specific prompt.
|
||||
|
||||
If you're on a container the output is set to the Docker volume. You can copy it
|
||||
wherever you want.
|
||||
You can download it from the Docker Desktop app, Volumes, my-vol, data.
|
||||
Or you can copy it from your Mac terminal. Keep in mind `docker cp` can't expand
|
||||
`*.png` so you'll need to specify the image file name.
|
||||
wherever you want. You can download it from the Docker Desktop app, Volumes,
|
||||
my-vol, data. Or you can copy it from your Mac terminal. Keep in mind
|
||||
`docker cp` can't expand `*.png` so you'll need to specify the image file name.
|
||||
|
||||
On your host Mac (you can use the name of any container that mounted the
|
||||
volume):
|
||||
|
||||
@@ -14,12 +14,13 @@ fi
|
||||
VERSION=$(cd ..; python -c "from ldm.invoke import __version__ as version; print(version)")
|
||||
PATCH=""
|
||||
VERSION="v${VERSION}${PATCH}"
|
||||
LATEST_TAG="v2.3-latest"
|
||||
|
||||
echo Building installer for version $VERSION
|
||||
echo "Be certain that you're in the 'installer' directory before continuing."
|
||||
read -p "Press any key to continue, or CTRL-C to exit..."
|
||||
|
||||
read -e -p "Commit and tag this repo with ${VERSION} and 'latest'? [n]: " input
|
||||
read -e -p "Commit and tag this repo with '${VERSION}' and '${LATEST_TAG}'? [n]: " input
|
||||
RESPONSE=${input:='n'}
|
||||
if [ "$RESPONSE" == 'y' ]; then
|
||||
git commit -a
|
||||
@@ -28,8 +29,9 @@ if [ "$RESPONSE" == 'y' ]; then
|
||||
echo "Existing/invalid tag"
|
||||
exit -1
|
||||
fi
|
||||
git push origin :refs/tags/latest
|
||||
git tag -fa latest
|
||||
|
||||
git push origin :refs/tags/$LATEST_TAG
|
||||
git tag -fa $LATEST_TAG
|
||||
fi
|
||||
|
||||
# ----------------------
|
||||
|
||||
25
installer/install.sh.in
Normal file → Executable file
25
installer/install.sh.in
Normal file → Executable file
@@ -3,5 +3,28 @@
|
||||
# make sure we are not already in a venv
|
||||
# (don't need to check status)
|
||||
deactivate >/dev/null 2>&1
|
||||
scriptdir=$(dirname "$0")
|
||||
cd $scriptdir
|
||||
|
||||
exec python3 $(dirname $0)/main.py ${@}
|
||||
function version { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; }
|
||||
|
||||
MINIMUM_PYTHON_VERSION=3.9.0
|
||||
PYTHON=""
|
||||
for candidate in python3.10 python3.9 python3 python python3.11 ; do
|
||||
if ppath=`which $candidate`; then
|
||||
python_version=$($ppath -V | awk '{ print $2 }')
|
||||
if [ $(version $python_version) -ge $(version "$MINIMUM_PYTHON_VERSION") ]; then
|
||||
PYTHON=$ppath
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$PYTHON" ]; then
|
||||
echo "A suitable Python interpreter could not be found"
|
||||
echo "Please install Python 3.9 or higher before running this script. See instructions at $INSTRUCTIONS for help."
|
||||
read -p "Press any key to exit"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
exec $PYTHON ./main.py ${@}
|
||||
|
||||
@@ -38,7 +38,8 @@ class Installer:
|
||||
self.reqs = INSTALLER_REQS
|
||||
self.preflight()
|
||||
if os.getenv("VIRTUAL_ENV") is not None:
|
||||
raise NotImplementedError("A virtual environment is already activated. Please 'deactivate' before installation.")
|
||||
print("A virtual environment is already activated. Please 'deactivate' before installation.")
|
||||
sys.exit(-1)
|
||||
self.bootstrap()
|
||||
|
||||
def preflight(self) -> None:
|
||||
@@ -248,6 +249,7 @@ class InvokeAiInstance:
|
||||
"--require-virtualenv",
|
||||
"torch",
|
||||
"torchvision",
|
||||
"--force-reinstall",
|
||||
"--find-links" if find_links is not None else None,
|
||||
find_links,
|
||||
"--extra-index-url" if extra_index_url is not None else None,
|
||||
@@ -283,7 +285,7 @@ class InvokeAiInstance:
|
||||
if FF_USE_LOCAL_WHEEL:
|
||||
# if no wheel, try to do a source install before giving up
|
||||
try:
|
||||
src = str(next(Path.cwd().glob("InvokeAI-*.whl")))
|
||||
src = str(next(Path(__file__).parent.glob("InvokeAI-*.whl")))
|
||||
except StopIteration:
|
||||
try:
|
||||
src = Path(__file__).parents[1].expanduser().resolve()
|
||||
@@ -324,6 +326,7 @@ class InvokeAiInstance:
|
||||
Configure the InvokeAI runtime directory
|
||||
"""
|
||||
|
||||
# set sys.argv to a consistent state
|
||||
new_argv = [sys.argv[0]]
|
||||
for i in range(1,len(sys.argv)):
|
||||
el = sys.argv[i]
|
||||
@@ -338,15 +341,12 @@ class InvokeAiInstance:
|
||||
|
||||
introduction()
|
||||
|
||||
from ldm.invoke.config import configure_invokeai
|
||||
from ldm.invoke.config import invokeai_configure
|
||||
|
||||
# NOTE: currently the config script does its own arg parsing! this means the command-line switches
|
||||
# from the installer will also automatically propagate down to the config script.
|
||||
# this may change in the future with config refactoring!
|
||||
|
||||
# set sys.argv to a consistent state
|
||||
|
||||
configure_invokeai.main()
|
||||
invokeai_configure.main()
|
||||
|
||||
def install_user_scripts(self):
|
||||
"""
|
||||
@@ -446,6 +446,7 @@ def get_torch_source() -> (Union[str, None],str):
|
||||
url = "https://download.pytorch.org/whl/cpu"
|
||||
|
||||
if device == 'cuda':
|
||||
url = 'https://download.pytorch.org/whl/cu117'
|
||||
optional_modules = '[xformers]'
|
||||
|
||||
# in all other cases, Torch wheels should be coming from PyPi as of Torch 1.13
|
||||
|
||||
@@ -13,7 +13,7 @@ echo 3. run textual inversion training
|
||||
echo 4. merge models (diffusers type only)
|
||||
echo 5. re-run the configure script to download new models
|
||||
echo 6. open the developer console
|
||||
set /P restore="Please enter 1, 2, 3, 4 or 5: [5] "
|
||||
set /P restore="Please enter 1, 2, 3, 4 or 5: [2] "
|
||||
if not defined restore set restore=2
|
||||
IF /I "%restore%" == "1" (
|
||||
echo Starting the InvokeAI command-line..
|
||||
|
||||
@@ -47,11 +47,11 @@ if [ "$0" != "bash" ]; then
|
||||
;;
|
||||
3)
|
||||
echo "Starting Textual Inversion:"
|
||||
exec textual_inversion --gui $@
|
||||
exec invokeai-ti --gui $@
|
||||
;;
|
||||
4)
|
||||
echo "Merging Models:"
|
||||
exec merge_models --gui $@
|
||||
exec invokeai-merge --gui $@
|
||||
;;
|
||||
5)
|
||||
echo "Developer Console:"
|
||||
|
||||
@@ -626,9 +626,10 @@ class InvokeAIWebServer:
|
||||
printable_parameters["init_mask"][:64] + "..."
|
||||
)
|
||||
|
||||
print(
|
||||
f">> Image generation requested: {printable_parameters}\nESRGAN parameters: {esrgan_parameters}\nFacetool parameters: {facetool_parameters}"
|
||||
)
|
||||
print(f'\n>> Image Generation Parameters:\n\n{printable_parameters}\n')
|
||||
print(f'>> ESRGAN Parameters: {esrgan_parameters}')
|
||||
print(f'>> Facetool Parameters: {facetool_parameters}')
|
||||
|
||||
self.generate_images(
|
||||
generation_parameters,
|
||||
esrgan_parameters,
|
||||
@@ -1154,7 +1155,7 @@ class InvokeAIWebServer:
|
||||
image, os.path.basename(path), self.thumbnail_image_path
|
||||
)
|
||||
|
||||
print(f'>> Image generated: "{path}"')
|
||||
print(f'\n\n>> Image generated: "{path}"\n')
|
||||
self.write_log_message(f'[Generated] "{path}": {command}')
|
||||
|
||||
if progress.total_iterations > progress.current_iteration:
|
||||
@@ -1193,8 +1194,6 @@ class InvokeAIWebServer:
|
||||
|
||||
progress.set_current_iteration(progress.current_iteration + 1)
|
||||
|
||||
print(generation_parameters)
|
||||
|
||||
def diffusers_step_callback_adapter(*cb_args, **kwargs):
|
||||
if isinstance(cb_args[0], PipelineIntermediateState):
|
||||
progress_state: PipelineIntermediateState = cb_args[0]
|
||||
@@ -1209,12 +1208,18 @@ class InvokeAIWebServer:
|
||||
)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
# Clear the CUDA cache on an exception
|
||||
self.empty_cuda_cache()
|
||||
self.socketio.emit("processingCanceled")
|
||||
raise
|
||||
except CanceledException:
|
||||
# Clear the CUDA cache on an exception
|
||||
self.empty_cuda_cache()
|
||||
self.socketio.emit("processingCanceled")
|
||||
pass
|
||||
except Exception as e:
|
||||
# Clear the CUDA cache on an exception
|
||||
self.empty_cuda_cache()
|
||||
print(e)
|
||||
self.socketio.emit("error", {"message": (str(e))})
|
||||
print("\n")
|
||||
@@ -1222,6 +1227,12 @@ class InvokeAIWebServer:
|
||||
traceback.print_exc()
|
||||
print("\n")
|
||||
|
||||
def empty_cuda_cache(self):
|
||||
if self.generate.device.type == "cuda":
|
||||
import torch.cuda
|
||||
|
||||
torch.cuda.empty_cache()
|
||||
|
||||
def parameters_to_generated_image_metadata(self, parameters):
|
||||
try:
|
||||
# top-level metadata minus `image` or `images`
|
||||
@@ -1305,8 +1316,6 @@ class InvokeAIWebServer:
|
||||
|
||||
rfc_dict["variations"] = variations
|
||||
|
||||
print(parameters)
|
||||
|
||||
if rfc_dict["type"] == "img2img":
|
||||
rfc_dict["strength"] = parameters["strength"]
|
||||
rfc_dict["fit"] = parameters["fit"] # TODO: Noncompliant
|
||||
|
||||
@@ -1,28 +1,20 @@
|
||||
# Stable Diffusion Web UI
|
||||
# InvokeAI UI dev setup
|
||||
|
||||
## Run
|
||||
The UI is in `invokeai/frontend`.
|
||||
|
||||
- `python scripts/dream.py --web` serves both frontend and backend at
|
||||
http://localhost:9090
|
||||
## Environment set up
|
||||
|
||||
## Evironment
|
||||
|
||||
Install [node](https://nodejs.org/en/download/) (includes npm) and optionally
|
||||
Install [node](https://nodejs.org/en/download/) (includes npm) and
|
||||
[yarn](https://yarnpkg.com/getting-started/install).
|
||||
|
||||
From `frontend/` run `npm install` / `yarn install` to install the frontend
|
||||
packages.
|
||||
From `invokeai/frontend/` run `yarn install` to get everything set up.
|
||||
|
||||
## Dev
|
||||
|
||||
1. From `frontend/`, run `npm dev` / `yarn dev` to start the dev server.
|
||||
2. Run `python scripts/dream.py --web`.
|
||||
3. Navigate to the dev server address e.g. `http://localhost:5173/`.
|
||||
1. Start the dev server: `yarn dev`
|
||||
2. Start the InvokeAI UI per usual: `invokeai --web`
|
||||
3. Point your browser to the dev server address e.g. `http://localhost:5173/`
|
||||
|
||||
To build for dev: `npm build-dev` / `yarn build-dev`
|
||||
To build for dev: `yarn build-dev`
|
||||
|
||||
To build for production: `npm build` / `yarn build`
|
||||
|
||||
## TODO
|
||||
|
||||
- Search repo for "TODO"
|
||||
To build for production: `yarn build`
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
6
invokeai/frontend/dist/index.html
vendored
6
invokeai/frontend/dist/index.html
vendored
@@ -7,8 +7,8 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>InvokeAI - A Stable Diffusion Toolkit</title>
|
||||
<link rel="shortcut icon" type="icon" href="./assets/favicon.0d253ced.ico" />
|
||||
<script type="module" crossorigin src="./assets/index.2a9ecaa6.js"></script>
|
||||
<link rel="stylesheet" href="./assets/index.8badc8b4.css">
|
||||
<script type="module" crossorigin src="./assets/index.9310184f.js"></script>
|
||||
<link rel="stylesheet" href="./assets/index.1536494e.css">
|
||||
<script type="module">try{import.meta.url;import("_").catch(()=>1);}catch(e){}window.__vite_is_modern_browser=true;</script>
|
||||
<script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy build because dynamic import or import.meta.url is unsupported, syntax error above should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script>
|
||||
</head>
|
||||
@@ -18,6 +18,6 @@
|
||||
|
||||
<script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
|
||||
<script nomodule crossorigin id="vite-legacy-polyfill" src="./assets/polyfills-legacy-dde3a68a.js"></script>
|
||||
<script nomodule crossorigin id="vite-legacy-entry" data-src="./assets/index-legacy-8f3bb5f8.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
|
||||
<script nomodule crossorigin id="vite-legacy-entry" data-src="./assets/index-legacy-a33ada34.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"langSpanish": "Spanish",
|
||||
"langJapanese": "Japanese",
|
||||
"langDutch": "Dutch",
|
||||
"langUkranian": "Ukranian",
|
||||
"text2img": "Text To Image",
|
||||
"img2img": "Image To Image",
|
||||
"unifiedCanvas": "Unified Canvas",
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"langSpanish": "Spanish",
|
||||
"langJapanese": "Japanese",
|
||||
"langDutch": "Dutch",
|
||||
"langUkranian": "Ukranian",
|
||||
"text2img": "Text To Image",
|
||||
"img2img": "Image To Image",
|
||||
"unifiedCanvas": "Unified Canvas",
|
||||
|
||||
63
invokeai/frontend/dist/locales/common/fr.json
vendored
63
invokeai/frontend/dist/locales/common/fr.json
vendored
@@ -1 +1,62 @@
|
||||
{}
|
||||
{
|
||||
"hotkeysLabel": "Raccourcis clavier",
|
||||
"themeLabel": "Thème",
|
||||
"languagePickerLabel": "Sélecteur de langue",
|
||||
"reportBugLabel": "Signaler un bug",
|
||||
"githubLabel": "Github",
|
||||
"discordLabel": "Discord",
|
||||
"settingsLabel": "Paramètres",
|
||||
"darkTheme": "Sombre",
|
||||
"lightTheme": "Clair",
|
||||
"greenTheme": "Vert",
|
||||
"langEnglish": "Anglais",
|
||||
"langRussian": "Russe",
|
||||
"langItalian": "Italien",
|
||||
"langBrPortuguese": "Portugais (Brésilien)",
|
||||
"langGerman": "Allemand",
|
||||
"langPortuguese": "Portugais",
|
||||
"langFrench": "Français",
|
||||
"langPolish": "Polonais",
|
||||
"langSimplifiedChinese": "Chinois simplifié",
|
||||
"langSpanish": "Espagnol",
|
||||
"langJapanese": "Japonais",
|
||||
"langDutch": "Néerlandais",
|
||||
"text2img": "Texte en image",
|
||||
"img2img": "Image en image",
|
||||
"unifiedCanvas": "Canvas unifié",
|
||||
"nodes": "Nœuds",
|
||||
"nodesDesc": "Un système basé sur les nœuds pour la génération d'images est actuellement en développement. Restez à l'écoute pour des mises à jour à ce sujet.",
|
||||
"postProcessing": "Post-traitement",
|
||||
"postProcessDesc1": "Invoke AI offre une grande variété de fonctionnalités de post-traitement. Le redimensionnement d'images et la restauration de visages sont déjà disponibles dans la WebUI. Vous pouvez y accéder à partir du menu Options avancées des onglets Texte en image et Image en image. Vous pouvez également traiter les images directement en utilisant les boutons d'action d'image ci-dessus l'affichage d'image actuel ou dans le visualiseur.",
|
||||
"postProcessDesc2": "Une interface utilisateur dédiée sera bientôt disponible pour faciliter les workflows de post-traitement plus avancés.",
|
||||
"postProcessDesc3": "L'interface en ligne de commande d'Invoke AI offre diverses autres fonctionnalités, notamment Embiggen.",
|
||||
"training": "Formation",
|
||||
"trainingDesc1": "Un workflow dédié pour former vos propres embeddings et checkpoints en utilisant Textual Inversion et Dreambooth depuis l'interface web.",
|
||||
"trainingDesc2": "InvokeAI prend déjà en charge la formation d'embeddings personnalisés en utilisant Textual Inversion en utilisant le script principal.",
|
||||
"upload": "Télécharger",
|
||||
"close": "Fermer",
|
||||
"load": "Charger",
|
||||
"back": "Retour",
|
||||
"statusConnected": "Connecté",
|
||||
"statusDisconnected": "Déconnecté",
|
||||
"statusError": "Erreur",
|
||||
"statusPreparing": "Préparation",
|
||||
"statusProcessingCanceled": "Traitement Annulé",
|
||||
"statusProcessingComplete": "Traitement Terminé",
|
||||
"statusGenerating": "Génération",
|
||||
"statusGeneratingTextToImage": "Génération Texte vers Image",
|
||||
"statusGeneratingImageToImage": "Génération Image vers Image",
|
||||
"statusGeneratingInpainting": "Génération de Réparation",
|
||||
"statusGeneratingOutpainting": "Génération de Completion",
|
||||
"statusGenerationComplete": "Génération Terminée",
|
||||
"statusIterationComplete": "Itération Terminée",
|
||||
"statusSavingImage": "Sauvegarde de l'Image",
|
||||
"statusRestoringFaces": "Restauration des Visages",
|
||||
"statusRestoringFacesGFPGAN": "Restauration des Visages (GFPGAN)",
|
||||
"statusRestoringFacesCodeFormer": "Restauration des Visages (CodeFormer)",
|
||||
"statusUpscaling": "Mise à Échelle",
|
||||
"statusUpscalingESRGAN": "Mise à Échelle (ESRGAN)",
|
||||
"statusLoadingModel": "Chargement du Modèle",
|
||||
"statusModelChanged": "Modèle Changé"
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
"langPolish": "Polacco",
|
||||
"langSimplifiedChinese": "Cinese semplificato",
|
||||
"langSpanish": "Spagnolo",
|
||||
"langJapanese": "Giapponese",
|
||||
"langDutch": "Olandese",
|
||||
"text2img": "Testo a Immagine",
|
||||
"img2img": "Immagine a Immagine",
|
||||
"unifiedCanvas": "Tela unificata",
|
||||
@@ -34,6 +36,7 @@
|
||||
"upload": "Caricamento",
|
||||
"close": "Chiudi",
|
||||
"load": "Carica",
|
||||
"back": "Indietro",
|
||||
"statusConnected": "Collegato",
|
||||
"statusDisconnected": "Disconnesso",
|
||||
"statusError": "Errore",
|
||||
|
||||
53
invokeai/frontend/dist/locales/common/ua.json
vendored
Normal file
53
invokeai/frontend/dist/locales/common/ua.json
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"hotkeysLabel": "Гарячi клавіші",
|
||||
"themeLabel": "Тема",
|
||||
"languagePickerLabel": "Мова",
|
||||
"reportBugLabel": "Повідомити про помилку",
|
||||
"githubLabel": "Github",
|
||||
"discordLabel": "Discord",
|
||||
"settingsLabel": "Налаштування",
|
||||
"darkTheme": "Темна",
|
||||
"lightTheme": "Світла",
|
||||
"greenTheme": "Зелена",
|
||||
"langEnglish": "Англійська",
|
||||
"langRussian": "Російська",
|
||||
"langItalian": "Iталійська",
|
||||
"langPortuguese": "Португальська",
|
||||
"langFrench": "Французька",
|
||||
"text2img": "Зображення із тексту (text2img)",
|
||||
"img2img": "Зображення із зображення (img2img)",
|
||||
"unifiedCanvas": "Універсальне полотно",
|
||||
"nodes": "Вузли",
|
||||
"nodesDesc": "Система генерації зображень на основі нодів (вузлів) вже розробляється. Слідкуйте за новинами про цю чудову функцію.",
|
||||
"postProcessing": "Постобробка",
|
||||
"postProcessDesc1": "Invoke AI пропонує широкий спектр функцій постобробки. Збільшення зображення (upscale) та відновлення облич вже доступні в інтерфейсі. Отримайте доступ до них з меню 'Додаткові параметри' на вкладках 'Зображення із тексту' та 'Зображення із зображення'. Обробляйте зображення безпосередньо, використовуючи кнопки дій із зображеннями над поточним зображенням або в режимі перегляду.",
|
||||
"postProcessDesc2": "Найближчим часом буде випущено спеціальний інтерфейс для більш сучасних процесів постобробки.",
|
||||
"postProcessDesc3": "Інтерфейс командного рядка Invoke AI пропонує різні інші функції, включаючи збільшення Embiggen",
|
||||
"training": "Навчання",
|
||||
"trainingDesc1": "Спеціальний інтерфейс для навчання власних моделей з використанням Textual Inversion та Dreambooth",
|
||||
"trainingDesc2": "InvokeAI вже підтримує навчання моделей за допомогою TI, через інтерфейс командного рядка.",
|
||||
"upload": "Завантажити",
|
||||
"close": "Закрити",
|
||||
"load": "Завантажити",
|
||||
"statusConnected": "Підключено",
|
||||
"statusDisconnected": "Відключено",
|
||||
"statusError": "Помилка",
|
||||
"statusPreparing": "Підготування",
|
||||
"statusProcessingCanceled": "Обробка перервана",
|
||||
"statusProcessingComplete": "Обробка завершена",
|
||||
"statusGenerating": "Генерація",
|
||||
"statusGeneratingTextToImage": "Генерація зображення із тексту",
|
||||
"statusGeneratingImageToImage": "Генерація зображення із зображення",
|
||||
"statusGeneratingInpainting": "Домальовка всередині",
|
||||
"statusGeneratingOutpainting": "Домальовка зовні",
|
||||
"statusGenerationComplete": "Генерація завершена",
|
||||
"statusIterationComplete": "Iтерація завершена",
|
||||
"statusSavingImage": "Збереження зображення",
|
||||
"statusRestoringFaces": "Відновлення облич",
|
||||
"statusRestoringFacesGFPGAN": "Відновлення облич (GFPGAN)",
|
||||
"statusRestoringFacesCodeFormer": "Відновлення облич (CodeFormer)",
|
||||
"statusUpscaling": "Збільшення",
|
||||
"statusUpscalingESRGAN": "Збільшення (ESRGAN)",
|
||||
"statusLoadingModel": "Завантаження моделі",
|
||||
"statusModelChanged": "Модель змінено"
|
||||
}
|
||||
17
invokeai/frontend/dist/locales/gallery/fr.json
vendored
17
invokeai/frontend/dist/locales/gallery/fr.json
vendored
@@ -1 +1,16 @@
|
||||
{}
|
||||
{
|
||||
"generations": "Générations",
|
||||
"showGenerations": "Afficher les générations",
|
||||
"uploads": "Téléchargements",
|
||||
"showUploads": "Afficher les téléchargements",
|
||||
"galleryImageSize": "Taille de l'image",
|
||||
"galleryImageResetSize": "Réinitialiser la taille",
|
||||
"gallerySettings": "Paramètres de la galerie",
|
||||
"maintainAspectRatio": "Maintenir le rapport d'aspect",
|
||||
"autoSwitchNewImages": "Basculer automatiquement vers de nouvelles images",
|
||||
"singleColumnLayout": "Mise en page en colonne unique",
|
||||
"pinGallery": "Épingler la galerie",
|
||||
"allImagesLoaded": "Toutes les images chargées",
|
||||
"loadMore": "Charger plus",
|
||||
"noImagesInGallery": "Aucune image dans la galerie"
|
||||
}
|
||||
|
||||
16
invokeai/frontend/dist/locales/gallery/ua.json
vendored
Normal file
16
invokeai/frontend/dist/locales/gallery/ua.json
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"generations": "Генерації",
|
||||
"showGenerations": "Показувати генерації",
|
||||
"uploads": "Завантаження",
|
||||
"showUploads": "Показувати завантаження",
|
||||
"galleryImageSize": "Розмір зображень",
|
||||
"galleryImageResetSize": "Аатоматичний розмір",
|
||||
"gallerySettings": "Налаштування галереї",
|
||||
"maintainAspectRatio": "Зберігати пропорції",
|
||||
"autoSwitchNewImages": "Автоматично вибирати нові",
|
||||
"singleColumnLayout": "Одна колонка",
|
||||
"pinGallery": "Закріпити галерею",
|
||||
"allImagesLoaded": "Всі зображення завантажені",
|
||||
"loadMore": "Завантажити більше",
|
||||
"noImagesInGallery": "Зображень немає"
|
||||
}
|
||||
208
invokeai/frontend/dist/locales/hotkeys/fr.json
vendored
208
invokeai/frontend/dist/locales/hotkeys/fr.json
vendored
@@ -1 +1,207 @@
|
||||
{}
|
||||
{
|
||||
"keyboardShortcuts": "Raccourcis clavier",
|
||||
"appHotkeys": "Raccourcis de l'application",
|
||||
"GeneralHotkeys": "Raccourcis généraux",
|
||||
"galleryHotkeys": "Raccourcis de la galerie",
|
||||
"unifiedCanvasHotkeys": "Raccourcis du Canvas unifié",
|
||||
"invoke": {
|
||||
"title": "Invoquer",
|
||||
"desc": "Générer une image"
|
||||
},
|
||||
"cancel": {
|
||||
"title": "Annuler",
|
||||
"desc": "Annuler la génération d'image"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"title": "Prompt de Focus",
|
||||
"desc": "Mettre en focus la zone de saisie de la commande"
|
||||
},
|
||||
"toggleOptions": {
|
||||
"title": "Basculer Options",
|
||||
"desc": "Ouvrir et fermer le panneau d'options"
|
||||
},
|
||||
"pinOptions": {
|
||||
"title": "Epingler Options",
|
||||
"desc": "Epingler le panneau d'options"
|
||||
},
|
||||
"toggleViewer": {
|
||||
"title": "Basculer Visionneuse",
|
||||
"desc": "Ouvrir et fermer la visionneuse d'image"
|
||||
},
|
||||
"toggleGallery": {
|
||||
"title": "Basculer Galerie",
|
||||
"desc": "Ouvrir et fermer le tiroir de galerie"
|
||||
},
|
||||
"maximizeWorkSpace": {
|
||||
"title": "Maximiser Espace de travail",
|
||||
"desc": "Fermer les panneaux et maximiser la zone de travail"
|
||||
},
|
||||
"changeTabs": {
|
||||
"title": "Changer d'onglets",
|
||||
"desc": "Passer à un autre espace de travail"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"title": "Bascule de la console",
|
||||
"desc": "Ouvrir et fermer la console"
|
||||
},
|
||||
"setPrompt": {
|
||||
"title": "Définir le prompt",
|
||||
"desc": "Utiliser le prompt de l'image actuelle"
|
||||
},
|
||||
"setSeed": {
|
||||
"title": "Définir la graine",
|
||||
"desc": "Utiliser la graine de l'image actuelle"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "Définir les paramètres",
|
||||
"desc": "Utiliser tous les paramètres de l'image actuelle"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"title": "Restaurer les faces",
|
||||
"desc": "Restaurer l'image actuelle"
|
||||
},
|
||||
"upscale": {
|
||||
"title": "Agrandir",
|
||||
"desc": "Agrandir l'image actuelle"
|
||||
},
|
||||
"showInfo": {
|
||||
"title": "Afficher les informations",
|
||||
"desc": "Afficher les informations de métadonnées de l'image actuelle"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"title": "Envoyer à l'image à l'image",
|
||||
"desc": "Envoyer l'image actuelle à l'image à l'image"
|
||||
},
|
||||
"deleteImage": {
|
||||
"title": "Supprimer l'image",
|
||||
"desc": "Supprimer l'image actuelle"
|
||||
},
|
||||
"closePanels": {
|
||||
"title": "Fermer les panneaux",
|
||||
"desc": "Fermer les panneaux ouverts"
|
||||
},
|
||||
"previousImage": {
|
||||
"title": "Image précédente",
|
||||
"desc": "Afficher l'image précédente dans la galerie"
|
||||
},
|
||||
"nextImage": {
|
||||
"title": "Image suivante",
|
||||
"desc": "Afficher l'image suivante dans la galerie"
|
||||
},
|
||||
"toggleGalleryPin": {
|
||||
"title": "Activer/désactiver l'épinglage de la galerie",
|
||||
"desc": "Épingle ou dépingle la galerie à l'interface utilisateur"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "Augmenter la taille des miniatures de la galerie",
|
||||
"desc": "Augmente la taille des miniatures de la galerie"
|
||||
},
|
||||
"decreaseGalleryThumbSize": {
|
||||
"title": "Diminuer la taille des miniatures de la galerie",
|
||||
"desc": "Diminue la taille des miniatures de la galerie"
|
||||
},
|
||||
"selectBrush": {
|
||||
"title": "Sélectionner un pinceau",
|
||||
"desc": "Sélectionne le pinceau de la toile"
|
||||
},
|
||||
"selectEraser": {
|
||||
"title": "Sélectionner un gomme",
|
||||
"desc": "Sélectionne la gomme de la toile"
|
||||
},
|
||||
"decreaseBrushSize": {
|
||||
"title": "Diminuer la taille du pinceau",
|
||||
"desc": "Diminue la taille du pinceau/gomme de la toile"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"title": "Augmenter la taille du pinceau",
|
||||
"desc": "Augmente la taille du pinceau/gomme de la toile"
|
||||
},
|
||||
"decreaseBrushOpacity": {
|
||||
"title": "Diminuer l'opacité du pinceau",
|
||||
"desc": "Diminue l'opacité du pinceau de la toile"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"title": "Augmenter l'opacité du pinceau",
|
||||
"desc": "Augmente l'opacité du pinceau de la toile"
|
||||
},
|
||||
"moveTool": {
|
||||
"title": "Outil de déplacement",
|
||||
"desc": "Permet la navigation sur la toile"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"title": "Remplir la boîte englobante",
|
||||
"desc": "Remplit la boîte englobante avec la couleur du pinceau"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"title": "Effacer la boîte englobante",
|
||||
"desc": "Efface la zone de la boîte englobante"
|
||||
},
|
||||
"colorPicker": {
|
||||
"title": "Sélectionnez le sélecteur de couleur",
|
||||
"desc": "Sélectionne le sélecteur de couleur de la toile"
|
||||
},
|
||||
"toggleSnap": {
|
||||
"title": "Basculer Snap",
|
||||
"desc": "Basculer Snap à la grille"
|
||||
},
|
||||
"quickToggleMove": {
|
||||
"title": "Basculer rapidement déplacer",
|
||||
"desc": "Basculer temporairement le mode Déplacer"
|
||||
},
|
||||
"toggleLayer": {
|
||||
"title": "Basculer la couche",
|
||||
"desc": "Basculer la sélection de la couche masque/base"
|
||||
},
|
||||
"clearMask": {
|
||||
"title": "Effacer le masque",
|
||||
"desc": "Effacer entièrement le masque"
|
||||
},
|
||||
"hideMask": {
|
||||
"title": "Masquer le masque",
|
||||
"desc": "Masquer et démasquer le masque"
|
||||
},
|
||||
"showHideBoundingBox": {
|
||||
"title": "Afficher/Masquer la boîte englobante",
|
||||
"desc": "Basculer la visibilité de la boîte englobante"
|
||||
},
|
||||
"mergeVisible": {
|
||||
"title": "Fusionner visible",
|
||||
"desc": "Fusionner toutes les couches visibles de la toile"
|
||||
},
|
||||
"saveToGallery": {
|
||||
"title": "Enregistrer dans la galerie",
|
||||
"desc": "Enregistrer la toile actuelle dans la galerie"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"title": "Copier dans le presse-papiers",
|
||||
"desc": "Copier la toile actuelle dans le presse-papiers"
|
||||
},
|
||||
"downloadImage": {
|
||||
"title": "Télécharger l'image",
|
||||
"desc": "Télécharger la toile actuelle"
|
||||
},
|
||||
"undoStroke": {
|
||||
"title": "Annuler le trait",
|
||||
"desc": "Annuler un coup de pinceau"
|
||||
},
|
||||
"redoStroke": {
|
||||
"title": "Rétablir le trait",
|
||||
"desc": "Rétablir un coup de pinceau"
|
||||
},
|
||||
"resetView": {
|
||||
"title": "Réinitialiser la vue",
|
||||
"desc": "Réinitialiser la vue de la toile"
|
||||
},
|
||||
"previousStagingImage": {
|
||||
"title": "Image de mise en scène précédente",
|
||||
"desc": "Image précédente de la zone de mise en scène"
|
||||
},
|
||||
"nextStagingImage": {
|
||||
"title": "Image de mise en scène suivante",
|
||||
"desc": "Image suivante de la zone de mise en scène"
|
||||
},
|
||||
"acceptStagingImage": {
|
||||
"title": "Accepter l'image de mise en scène",
|
||||
"desc": "Accepter l'image actuelle de la zone de mise en scène"
|
||||
}
|
||||
}
|
||||
|
||||
207
invokeai/frontend/dist/locales/hotkeys/ua.json
vendored
Normal file
207
invokeai/frontend/dist/locales/hotkeys/ua.json
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
{
|
||||
"keyboardShortcuts": "Клавіатурні скорочення",
|
||||
"appHotkeys": "Гарячі клавіші програми",
|
||||
"generalHotkeys": "Загальні гарячі клавіші",
|
||||
"galleryHotkeys": "Гарячі клавіші галереї",
|
||||
"unifiedCanvasHotkeys": "Гарячі клавіші універсального полотна",
|
||||
"invoke": {
|
||||
"title": "Invoke",
|
||||
"desc": "Згенерувати зображення"
|
||||
},
|
||||
"cancel": {
|
||||
"title": "Скасувати",
|
||||
"desc": "Скасувати генерацію зображення"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"title": "Переключитися на введення запиту",
|
||||
"desc": "Перемикання на область введення запиту"
|
||||
},
|
||||
"toggleOptions": {
|
||||
"title": "Показати/приховати параметри",
|
||||
"desc": "Відкривати і закривати панель параметрів"
|
||||
},
|
||||
"pinOptions": {
|
||||
"title": "Закріпити параметри",
|
||||
"desc": "Закріпити панель параметрів"
|
||||
},
|
||||
"toggleViewer": {
|
||||
"title": "Показати перегляд",
|
||||
"desc": "Відкривати і закривати переглядач зображень"
|
||||
},
|
||||
"toggleGallery": {
|
||||
"title": "Показати галерею",
|
||||
"desc": "Відкривати і закривати скриньку галереї"
|
||||
},
|
||||
"maximizeWorkSpace": {
|
||||
"title": "Максимізувати робочий простір",
|
||||
"desc": "Приховати панелі і максимізувати робочу область"
|
||||
},
|
||||
"changeTabs": {
|
||||
"title": "Переключити вкладку",
|
||||
"desc": "Переключитися на іншу робочу область"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"title": "Показати консоль",
|
||||
"desc": "Відкривати і закривати консоль"
|
||||
},
|
||||
"setPrompt": {
|
||||
"title": "Використовувати запит",
|
||||
"desc": "Використати запит із поточного зображення"
|
||||
},
|
||||
"setSeed": {
|
||||
"title": "Використовувати сід",
|
||||
"desc": "Використовувати сід поточного зображення"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "Використовувати всі параметри",
|
||||
"desc": "Використовувати всі параметри поточного зображення"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"title": "Відновити обличчя",
|
||||
"desc": "Відновити обличчя на поточному зображенні"
|
||||
},
|
||||
"upscale": {
|
||||
"title": "Збільшення",
|
||||
"desc": "Збільшити поточне зображення"
|
||||
},
|
||||
"showInfo": {
|
||||
"title": "Показати метадані",
|
||||
"desc": "Показати метадані з поточного зображення"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"title": "Відправити в img2img",
|
||||
"desc": "Надіслати поточне зображення в Image To Image"
|
||||
},
|
||||
"deleteImage": {
|
||||
"title": "Видалити зображення",
|
||||
"desc": "Видалити поточне зображення"
|
||||
},
|
||||
"closePanels": {
|
||||
"title": "Закрити панелі",
|
||||
"desc": "Закриває відкриті панелі"
|
||||
},
|
||||
"previousImage": {
|
||||
"title": "Попереднє зображення",
|
||||
"desc": "Відображати попереднє зображення в галереї"
|
||||
},
|
||||
"nextImage": {
|
||||
"title": "Наступне зображення",
|
||||
"desc": "Відображення наступного зображення в галереї"
|
||||
},
|
||||
"toggleGalleryPin": {
|
||||
"title": "Закріпити галерею",
|
||||
"desc": "Закріплює і відкріплює галерею"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "Збільшити розмір мініатюр галереї",
|
||||
"desc": "Збільшує розмір мініатюр галереї"
|
||||
},
|
||||
"reduceGalleryThumbSize": {
|
||||
"title": "Зменшує розмір мініатюр галереї",
|
||||
"desc": "Зменшує розмір мініатюр галереї"
|
||||
},
|
||||
"selectBrush": {
|
||||
"title": "Вибрати пензель",
|
||||
"desc": "Вибирає пензель для полотна"
|
||||
},
|
||||
"selectEraser": {
|
||||
"title": "Вибрати ластик",
|
||||
"desc": "Вибирає ластик для полотна"
|
||||
},
|
||||
"reduceBrushSize": {
|
||||
"title": "Зменшити розмір пензля",
|
||||
"desc": "Зменшує розмір пензля/ластика полотна"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"title": "Збільшити розмір пензля",
|
||||
"desc": "Збільшує розмір пензля/ластика полотна"
|
||||
},
|
||||
"reduceBrushOpacity": {
|
||||
"title": "Зменшити непрозорість пензля",
|
||||
"desc": "Зменшує непрозорість пензля полотна"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"title": "Збільшити непрозорість пензля",
|
||||
"desc": "Збільшує непрозорість пензля полотна"
|
||||
},
|
||||
"moveTool": {
|
||||
"title": "Інструмент переміщення",
|
||||
"desc": "Дозволяє переміщатися по полотну"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"title": "Заповнити обмежувальну рамку",
|
||||
"desc": "Заповнює обмежувальну рамку кольором пензля"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"title": "Стерти обмежувальну рамку",
|
||||
"desc": "Стирає область обмежувальної рамки"
|
||||
},
|
||||
"colorPicker": {
|
||||
"title": "Вибрати колір",
|
||||
"desc": "Вибирає засіб вибору кольору полотна"
|
||||
},
|
||||
"toggleSnap": {
|
||||
"title": "Увімкнути прив'язку",
|
||||
"desc": "Вмикає/вимикає прив'язку до сітки"
|
||||
},
|
||||
"quickToggleMove": {
|
||||
"title": "Швидке перемикання переміщення",
|
||||
"desc": "Тимчасово перемикає режим переміщення"
|
||||
},
|
||||
"toggleLayer": {
|
||||
"title": "Переключити шар",
|
||||
"desc": "Перемикання маски/базового шару"
|
||||
},
|
||||
"clearMask": {
|
||||
"title": "Очистити маску",
|
||||
"desc": "Очистити всю маску"
|
||||
},
|
||||
"hideMask": {
|
||||
"title": "Приховати маску",
|
||||
"desc": "Приховує/показує маску"
|
||||
},
|
||||
"showHideBoundingBox": {
|
||||
"title": "Показати/приховати обмежувальну рамку",
|
||||
"desc": "Переключити видимість обмежувальної рамки"
|
||||
},
|
||||
"mergeVisible": {
|
||||
"title": "Об'єднати видимі",
|
||||
"desc": "Об'єднати всі видимі шари полотна"
|
||||
},
|
||||
"saveToGallery": {
|
||||
"title": "Зберегти в галерею",
|
||||
"desc": "Зберегти поточне полотно в галерею"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"title": "Копіювати в буфер обміну",
|
||||
"desc": "Копіювати поточне полотно в буфер обміну"
|
||||
},
|
||||
"downloadImage": {
|
||||
"title": "Завантажити зображення",
|
||||
"desc": "Завантажити вміст полотна"
|
||||
},
|
||||
"undoStroke": {
|
||||
"title": "Скасувати пензель",
|
||||
"desc": "Скасувати мазок пензля"
|
||||
},
|
||||
"redoStroke": {
|
||||
"title": "Повторити мазок пензля",
|
||||
"desc": "Повторити мазок пензля"
|
||||
},
|
||||
"resetView": {
|
||||
"title": "Вид за замовчуванням",
|
||||
"desc": "Скинути вид полотна"
|
||||
},
|
||||
"previousStagingImage": {
|
||||
"title": "Попереднє зображення",
|
||||
"desc": "Попереднє зображення"
|
||||
},
|
||||
"nextStagingImage": {
|
||||
"title": "Наступне зображення",
|
||||
"desc": "Наступне зображення"
|
||||
},
|
||||
"acceptStagingImage": {
|
||||
"title": "Прийняти зображення",
|
||||
"desc": "Прийняти поточне зображення"
|
||||
}
|
||||
}
|
||||
68
invokeai/frontend/dist/locales/modelmanager/fr.json
vendored
Normal file
68
invokeai/frontend/dist/locales/modelmanager/fr.json
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"modelManager": "Gestionnaire de modèle",
|
||||
"model": "Modèle",
|
||||
"allModels": "Tous les modèles",
|
||||
"checkpointModels": "Points de contrôle",
|
||||
"diffusersModels": "Diffuseurs",
|
||||
"safetensorModels": "SafeTensors",
|
||||
"modelAdded": "Modèle ajouté",
|
||||
"modelUpdated": "Modèle mis à jour",
|
||||
"modelEntryDeleted": "Entrée de modèle supprimée",
|
||||
"cannotUseSpaces": "Ne peut pas utiliser d'espaces",
|
||||
"addNew": "Ajouter un nouveau",
|
||||
"addNewModel": "Ajouter un nouveau modèle",
|
||||
"addCheckpointModel": "Ajouter un modèle de point de contrôle / SafeTensor",
|
||||
"addDiffuserModel": "Ajouter des diffuseurs",
|
||||
"addManually": "Ajouter manuellement",
|
||||
"manual": "Manuel",
|
||||
"name": "Nom",
|
||||
"nameValidationMsg": "Entrez un nom pour votre modèle",
|
||||
"description": "Description",
|
||||
"descriptionValidationMsg": "Ajoutez une description pour votre modèle",
|
||||
"config": "Config",
|
||||
"configValidationMsg": "Chemin vers le fichier de configuration de votre modèle.",
|
||||
"modelLocation": "Emplacement du modèle",
|
||||
"modelLocationValidationMsg": "Chemin vers où votre modèle est situé localement.",
|
||||
"repo_id": "ID de dépôt",
|
||||
"repoIDValidationMsg": "Dépôt en ligne de votre modèle",
|
||||
"vaeLocation": "Emplacement VAE",
|
||||
"vaeLocationValidationMsg": "Chemin vers où votre VAE est situé.",
|
||||
"vaeRepoID": "ID de dépôt VAE",
|
||||
"vaeRepoIDValidationMsg": "Dépôt en ligne de votre VAE",
|
||||
"width": "Largeur",
|
||||
"widthValidationMsg": "Largeur par défaut de votre modèle.",
|
||||
"height": "Hauteur",
|
||||
"heightValidationMsg": "Hauteur par défaut de votre modèle.",
|
||||
"addModel": "Ajouter un modèle",
|
||||
"updateModel": "Mettre à jour le modèle",
|
||||
"availableModels": "Modèles disponibles",
|
||||
"search": "Rechercher",
|
||||
"load": "Charger",
|
||||
"active": "actif",
|
||||
"notLoaded": "non chargé",
|
||||
"cached": "en cache",
|
||||
"checkpointFolder": "Dossier de point de contrôle",
|
||||
"clearCheckpointFolder": "Effacer le dossier de point de contrôle",
|
||||
"findModels": "Trouver des modèles",
|
||||
"scanAgain": "Scanner à nouveau",
|
||||
"modelsFound": "Modèles trouvés",
|
||||
"selectFolder": "Sélectionner un dossier",
|
||||
"selected": "Sélectionné",
|
||||
"selectAll": "Tout sélectionner",
|
||||
"deselectAll": "Tout désélectionner",
|
||||
"showExisting": "Afficher existant",
|
||||
"addSelected": "Ajouter sélectionné",
|
||||
"modelExists": "Modèle existant",
|
||||
"selectAndAdd": "Sélectionner et ajouter les modèles listés ci-dessous",
|
||||
"noModelsFound": "Aucun modèle trouvé",
|
||||
"delete": "Supprimer",
|
||||
"deleteModel": "Supprimer le modèle",
|
||||
"deleteConfig": "Supprimer la configuration",
|
||||
"deleteMsg1": "Êtes-vous sûr de vouloir supprimer cette entrée de modèle dans InvokeAI?",
|
||||
"deleteMsg2": "Cela n'effacera pas le fichier de point de contrôle du modèle de votre disque. Vous pouvez les réajouter si vous le souhaitez.",
|
||||
"formMessageDiffusersModelLocation": "Emplacement du modèle de diffuseurs",
|
||||
"formMessageDiffusersModelLocationDesc": "Veuillez en entrer au moins un.",
|
||||
"formMessageDiffusersVAELocation": "Emplacement VAE",
|
||||
"formMessageDiffusersVAELocationDesc": "Si non fourni, InvokeAI recherchera le fichier VAE à l'emplacement du modèle donné ci-dessus."
|
||||
|
||||
}
|
||||
@@ -1,24 +1,34 @@
|
||||
{
|
||||
"modelManager": "Gestione Modelli",
|
||||
"model": "Modello",
|
||||
"allModels": "Tutti i Modelli",
|
||||
"checkpointModels": "Checkpoint",
|
||||
"diffusersModels": "Diffusori",
|
||||
"safetensorModels": "SafeTensor",
|
||||
"modelAdded": "Modello Aggiunto",
|
||||
"modelUpdated": "Modello Aggiornato",
|
||||
"modelEntryDeleted": "Modello Rimosso",
|
||||
"cannotUseSpaces": "Impossibile utilizzare gli spazi",
|
||||
"addNew": "Aggiungi nuovo",
|
||||
"addNewModel": "Aggiungi nuovo Modello",
|
||||
"addCheckpointModel": "Aggiungi modello Checkpoint / Safetensor",
|
||||
"addDiffuserModel": "Aggiungi Diffusori",
|
||||
"addManually": "Aggiungi manualmente",
|
||||
"manual": "Manuale",
|
||||
"name": "Nome",
|
||||
"nameValidationMsg": "Inserisci un nome per il modello",
|
||||
"description": "Descrizione",
|
||||
"descriptionValidationMsg": "Aggiungi una descrizione per il modello",
|
||||
"config": "Config",
|
||||
"config": "Configurazione",
|
||||
"configValidationMsg": "Percorso del file di configurazione del modello.",
|
||||
"modelLocation": "Posizione del modello",
|
||||
"modelLocationValidationMsg": "Percorso dove si trova il modello.",
|
||||
"repo_id": "Repo ID",
|
||||
"repoIDValidationMsg": "Repository online del modello",
|
||||
"vaeLocation": "Posizione file VAE",
|
||||
"vaeLocationValidationMsg": "Percorso dove si trova il file VAE.",
|
||||
"vaeRepoID": "VAE Repo ID",
|
||||
"vaeRepoIDValidationMsg": "Repository online del file VAE",
|
||||
"width": "Larghezza",
|
||||
"widthValidationMsg": "Larghezza predefinita del modello.",
|
||||
"height": "Altezza",
|
||||
@@ -49,5 +59,9 @@
|
||||
"deleteModel": "Elimina modello",
|
||||
"deleteConfig": "Elimina configurazione",
|
||||
"deleteMsg1": "Sei sicuro di voler eliminare questo modello da InvokeAI?",
|
||||
"deleteMsg2": "Questo non eliminerà il file Checkpoint del modello dal tuo disco. Puoi aggiungerlo nuovamente se lo desideri."
|
||||
"deleteMsg2": "Questo non eliminerà il file Checkpoint del modello dal tuo disco. Puoi aggiungerlo nuovamente se lo desideri.",
|
||||
"formMessageDiffusersModelLocation": "Ubicazione modelli diffusori",
|
||||
"formMessageDiffusersModelLocationDesc": "Inseriscine almeno uno.",
|
||||
"formMessageDiffusersVAELocation": "Ubicazione file VAE",
|
||||
"formMessageDiffusersVAELocationDesc": "Se non fornito, InvokeAI cercherà il file VAE all'interno dell'ubicazione del modello sopra indicata."
|
||||
}
|
||||
|
||||
53
invokeai/frontend/dist/locales/modelmanager/ua.json
vendored
Normal file
53
invokeai/frontend/dist/locales/modelmanager/ua.json
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"modelManager": "Менеджер моделей",
|
||||
"model": "Модель",
|
||||
"modelAdded": "Модель додана",
|
||||
"modelUpdated": "Модель оновлена",
|
||||
"modelEntryDeleted": "Запис про модель видалено",
|
||||
"cannotUseSpaces": "Не можна використовувати пробіли",
|
||||
"addNew": "Додати нову",
|
||||
"addNewModel": "Додати нову модель",
|
||||
"addManually": "Додати вручну",
|
||||
"manual": "Ручне",
|
||||
"name": "Назва",
|
||||
"nameValidationMsg": "Введіть назву моделі",
|
||||
"description": "Опис",
|
||||
"descriptionValidationMsg": "Введіть опис моделі",
|
||||
"config": "Файл конфігурації",
|
||||
"configValidationMsg": "Шлях до файлу конфігурації",
|
||||
"modelLocation": "Розташування моделі",
|
||||
"modelLocationValidationMsg": "Шлях до файлу з моделлю",
|
||||
"vaeLocation": "Розтышування VAE",
|
||||
"vaeLocationValidationMsg": "Шлях до VAE",
|
||||
"width": "Ширина",
|
||||
"widthValidationMsg": "Початкова ширина зображень",
|
||||
"height": "Висота",
|
||||
"heightValidationMsg": "Початкова висота зображень",
|
||||
"addModel": "Додати модель",
|
||||
"updateModel": "Оновити модель",
|
||||
"availableModels": "Доступні моделі",
|
||||
"search": "Шукати",
|
||||
"load": "Завантажити",
|
||||
"active": "активна",
|
||||
"notLoaded": "не завантажена",
|
||||
"cached": "кешована",
|
||||
"checkpointFolder": "Папка з моделями",
|
||||
"clearCheckpointFolder": "Очистити папку з моделями",
|
||||
"findModels": "Знайти моделі",
|
||||
"scanAgain": "Сканувати знову",
|
||||
"modelsFound": "Знайдені моделі",
|
||||
"selectFolder": "Обрати папку",
|
||||
"selected": "Обрані",
|
||||
"selectAll": "Обрати всі",
|
||||
"deselectAll": "Зняти выділення",
|
||||
"showExisting": "Показувати додані",
|
||||
"addSelected": "Додати обрані",
|
||||
"modelExists": "Модель вже додана",
|
||||
"selectAndAdd": "Оберіть і додайте моделі із списку",
|
||||
"noModelsFound": "Моделі не знайдені",
|
||||
"delete": "Видалити",
|
||||
"deleteModel": "Видалити модель",
|
||||
"deleteConfig": "Видалити конфігурацію",
|
||||
"deleteMsg1": "Ви точно хочете видалити модель із InvokeAI?",
|
||||
"deleteMsg2": "Це не призведе до видалення файлу моделі з диску. Позніше ви можете додати його знову."
|
||||
}
|
||||
@@ -43,6 +43,7 @@
|
||||
"invoke": "Invoke",
|
||||
"cancel": "Cancel",
|
||||
"promptPlaceholder": "Type prompt here. [negative tokens], (upweight)++, (downweight)--, swap and blend are available (see docs)",
|
||||
"negativePrompts": "Negative Prompts",
|
||||
"sendTo": "Send to",
|
||||
"sendToImg2Img": "Send to Image to Image",
|
||||
"sendToUnifiedCanvas": "Send To Unified Canvas",
|
||||
|
||||
63
invokeai/frontend/dist/locales/options/fr.json
vendored
63
invokeai/frontend/dist/locales/options/fr.json
vendored
@@ -1 +1,62 @@
|
||||
{}
|
||||
{
|
||||
"images": "Images",
|
||||
"steps": "Etapes",
|
||||
"cfgScale": "CFG Echelle",
|
||||
"width": "Largeur",
|
||||
"height": "Hauteur",
|
||||
"sampler": "Echantillonneur",
|
||||
"seed": "Graine",
|
||||
"randomizeSeed": "Graine Aléatoire",
|
||||
"shuffle": "Mélanger",
|
||||
"noiseThreshold": "Seuil de Bruit",
|
||||
"perlinNoise": "Bruit de Perlin",
|
||||
"variations": "Variations",
|
||||
"variationAmount": "Montant de Variation",
|
||||
"seedWeights": "Poids des Graines",
|
||||
"faceRestoration": "Restauration de Visage",
|
||||
"restoreFaces": "Restaurer les Visages",
|
||||
"type": "Type",
|
||||
"strength": "Force",
|
||||
"upscaling": "Agrandissement",
|
||||
"upscale": "Agrandir",
|
||||
"upscaleImage": "Image en Agrandissement",
|
||||
"scale": "Echelle",
|
||||
"otherOptions": "Autres Options",
|
||||
"seamlessTiling": "Carreau Sans Joint",
|
||||
"hiresOptim": "Optimisation Haute Résolution",
|
||||
"imageFit": "Ajuster Image Initiale à la Taille de Sortie",
|
||||
"codeformerFidelity": "Fidélité",
|
||||
"seamSize": "Taille des Joints",
|
||||
"seamBlur": "Flou des Joints",
|
||||
"seamStrength": "Force des Joints",
|
||||
"seamSteps": "Etapes des Joints",
|
||||
"scaleBeforeProcessing": "Echelle Avant Traitement",
|
||||
"scaledWidth": "Larg. Échelle",
|
||||
"scaledHeight": "Haut. Échelle",
|
||||
"infillMethod": "Méthode de Remplissage",
|
||||
"tileSize": "Taille des Tuiles",
|
||||
"boundingBoxHeader": "Boîte Englobante",
|
||||
"seamCorrectionHeader": "Correction des Joints",
|
||||
"infillScalingHeader": "Remplissage et Mise à l'Échelle",
|
||||
"img2imgStrength": "Force de l'Image à l'Image",
|
||||
"toggleLoopback": "Activer/Désactiver la Boucle",
|
||||
"invoke": "Invoker",
|
||||
"cancel": "Annuler",
|
||||
"promptPlaceholder": "Tapez le prompt ici. [tokens négatifs], (poids positif)++, (poids négatif)--, swap et blend sont disponibles (voir les docs)",
|
||||
"sendTo": "Envoyer à",
|
||||
"sendToImg2Img": "Envoyer à Image à Image",
|
||||
"sendToUnifiedCanvas": "Envoyer au Canvas Unifié",
|
||||
"copyImage": "Copier Image",
|
||||
"copyImageToLink": "Copier l'Image en Lien",
|
||||
"downloadImage": "Télécharger Image",
|
||||
"openInViewer": "Ouvrir dans le visualiseur",
|
||||
"closeViewer": "Fermer le visualiseur",
|
||||
"usePrompt": "Utiliser la suggestion",
|
||||
"useSeed": "Utiliser la graine",
|
||||
"useAll": "Tout utiliser",
|
||||
"useInitImg": "Utiliser l'image initiale",
|
||||
"info": "Info",
|
||||
"deleteImage": "Supprimer l'image",
|
||||
"initialImage": "Image initiale",
|
||||
"showOptionsPanel": "Afficher le panneau d'options"
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
"infillScalingHeader": "Riempimento e ridimensionamento",
|
||||
"img2imgStrength": "Forza da Immagine a Immagine",
|
||||
"toggleLoopback": "Attiva/disattiva elaborazione ricorsiva",
|
||||
"invoke": "Invoca",
|
||||
"invoke": "Invoke",
|
||||
"cancel": "Annulla",
|
||||
"promptPlaceholder": "Digita qui il prompt usando termini in lingua inglese. [token negativi], (aumenta il peso)++, (diminuisci il peso)--, scambia e fondi sono disponibili (consulta la documentazione)",
|
||||
"sendTo": "Invia a",
|
||||
|
||||
62
invokeai/frontend/dist/locales/options/ua.json
vendored
Normal file
62
invokeai/frontend/dist/locales/options/ua.json
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"images": "Зображення",
|
||||
"steps": "Кроки",
|
||||
"cfgScale": "Рівень CFG",
|
||||
"width": "Ширина",
|
||||
"height": "Висота",
|
||||
"sampler": "Семплер",
|
||||
"seed": "Сід",
|
||||
"randomizeSeed": "Випадковий сид",
|
||||
"shuffle": "Оновити",
|
||||
"noiseThreshold": "Поріг шуму",
|
||||
"perlinNoise": "Шум Перліна",
|
||||
"variations": "Варіації",
|
||||
"variationAmount": "Кількість варіацій",
|
||||
"seedWeights": "Вага сіду",
|
||||
"faceRestoration": "Відновлення облич",
|
||||
"restoreFaces": "Відновити обличчя",
|
||||
"type": "Тип",
|
||||
"strength": "Сила",
|
||||
"upscaling": "Збільшення",
|
||||
"upscale": "Збільшити",
|
||||
"upscaleImage": "Збільшити зображення",
|
||||
"scale": "Масштаб",
|
||||
"otherOptions": "інші параметри",
|
||||
"seamlessTiling": "Безшовний узор",
|
||||
"hiresOptim": "Висока роздільна здатність",
|
||||
"imageFit": "Вмістити зображення",
|
||||
"codeformerFidelity": "Точність",
|
||||
"seamSize": "Размір шву",
|
||||
"seamBlur": "Розмиття шву",
|
||||
"seamStrength": "Сила шву",
|
||||
"seamSteps": "Кроки шву",
|
||||
"inpaintReplace": "Inpaint-заміна",
|
||||
"scaleBeforeProcessing": "Масштабувати",
|
||||
"scaledWidth": "Масштаб Ш",
|
||||
"scaledHeight": "Масштаб В",
|
||||
"infillMethod": "Засіб заповнення",
|
||||
"tileSize": "Розмір області",
|
||||
"boundingBoxHeader": "Обмежуюча рамка",
|
||||
"seamCorrectionHeader": "Налаштування шву",
|
||||
"infillScalingHeader": "Заповнення і масштабування",
|
||||
"img2imgStrength": "Сила обробки img2img",
|
||||
"toggleLoopback": "Зациклити обробку",
|
||||
"invoke": "Викликати",
|
||||
"cancel": "Скасувати",
|
||||
"promptPlaceholder": "Введіть запит тут (англійською). [видалені токени], (більш вагомі)++, (менш вагомі)--, swap и blend також доступні (дивіться Github)",
|
||||
"sendTo": "Надіслати",
|
||||
"sendToImg2Img": "Надіслати у img2img",
|
||||
"sendToUnifiedCanvas": "Надіслати на полотно",
|
||||
"copyImageToLink": "Скопіювати посилання",
|
||||
"downloadImage": "Завантажити",
|
||||
"openInViewer": "Відкрити у переглядачі",
|
||||
"closeViewer": "Закрити переглядач",
|
||||
"usePrompt": "Використати запит",
|
||||
"useSeed": "Використати сід",
|
||||
"useAll": "Використати все",
|
||||
"useInitImg": "Використати як початкове",
|
||||
"info": "Метадані",
|
||||
"deleteImage": "Видалити зображення",
|
||||
"initialImage": "Початкове зображення",
|
||||
"showOptionsPanel": "Показати панель налаштувань"
|
||||
}
|
||||
14
invokeai/frontend/dist/locales/settings/fr.json
vendored
14
invokeai/frontend/dist/locales/settings/fr.json
vendored
@@ -1 +1,13 @@
|
||||
{}
|
||||
{
|
||||
"models": "Modèles",
|
||||
"displayInProgress": "Afficher les images en cours",
|
||||
"saveSteps": "Enregistrer les images tous les n étapes",
|
||||
"confirmOnDelete": "Confirmer la suppression",
|
||||
"displayHelpIcons": "Afficher les icônes d'aide",
|
||||
"useCanvasBeta": "Utiliser la mise en page bêta de Canvas",
|
||||
"enableImageDebugging": "Activer le débogage d'image",
|
||||
"resetWebUI": "Réinitialiser l'interface Web",
|
||||
"resetWebUIDesc1": "Réinitialiser l'interface Web ne réinitialise que le cache local du navigateur de vos images et de vos paramètres enregistrés. Cela n'efface pas les images du disque.",
|
||||
"resetWebUIDesc2": "Si les images ne s'affichent pas dans la galerie ou si quelque chose d'autre ne fonctionne pas, veuillez essayer de réinitialiser avant de soumettre une demande sur GitHub.",
|
||||
"resetComplete": "L'interface Web a été réinitialisée. Rafraîchissez la page pour recharger."
|
||||
}
|
||||
|
||||
13
invokeai/frontend/dist/locales/settings/ua.json
vendored
Normal file
13
invokeai/frontend/dist/locales/settings/ua.json
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"models": "Моделі",
|
||||
"displayInProgress": "Показувати процес генерації",
|
||||
"saveSteps": "Зберігати кожні n кроків",
|
||||
"confirmOnDelete": "Підтверджувати видалення",
|
||||
"displayHelpIcons": "Показувати значки підказок",
|
||||
"useCanvasBeta": "Показувати інструменты зліва (Beta UI)",
|
||||
"enableImageDebugging": "Увімкнути налагодження",
|
||||
"resetWebUI": "Повернути початкові",
|
||||
"resetWebUIDesc1": "Скидання настройок веб-інтерфейсу видаляє лише локальний кеш браузера з вашими зображеннями та налаштуваннями. Це не призводить до видалення зображень з диску.",
|
||||
"resetWebUIDesc2": "Якщо зображення не відображаються в галереї або не працює ще щось, спробуйте скинути налаштування, перш ніж повідомляти про проблему на GitHub.",
|
||||
"resetComplete": "Інтерфейс скинуто. Оновіть цю сторінку."
|
||||
}
|
||||
33
invokeai/frontend/dist/locales/toast/fr.json
vendored
33
invokeai/frontend/dist/locales/toast/fr.json
vendored
@@ -1 +1,32 @@
|
||||
{}
|
||||
{
|
||||
"tempFoldersEmptied": "Dossiers temporaires vidés",
|
||||
"uploadFailed": "Téléchargement échoué",
|
||||
"uploadFailedMultipleImagesDesc": "Plusieurs images collées, peut uniquement télécharger une image à la fois",
|
||||
"uploadFailedUnableToLoadDesc": "Impossible de charger le fichier",
|
||||
"downloadImageStarted": "Téléchargement de l'image démarré",
|
||||
"imageCopied": "Image copiée",
|
||||
"imageLinkCopied": "Lien d'image copié",
|
||||
"imageNotLoaded": "Aucune image chargée",
|
||||
"imageNotLoadedDesc": "Aucune image trouvée pour envoyer à module d'image",
|
||||
"imageSavedToGallery": "Image enregistrée dans la galerie",
|
||||
"canvasMerged": "Canvas fusionné",
|
||||
"sentToImageToImage": "Envoyé à Image à Image",
|
||||
"sentToUnifiedCanvas": "Envoyé à Canvas unifié",
|
||||
"parametersSet": "Paramètres définis",
|
||||
"parametersNotSet": "Paramètres non définis",
|
||||
"parametersNotSetDesc": "Aucune métadonnée trouvée pour cette image.",
|
||||
"parametersFailed": "Problème de chargement des paramètres",
|
||||
"parametersFailedDesc": "Impossible de charger l'image d'initiation.",
|
||||
"seedSet": "Graine définie",
|
||||
"seedNotSet": "Graine non définie",
|
||||
"seedNotSetDesc": "Impossible de trouver la graine pour cette image.",
|
||||
"promptSet": "Invite définie",
|
||||
"promptNotSet": "Invite non définie",
|
||||
"promptNotSetDesc": "Impossible de trouver l'invite pour cette image.",
|
||||
"upscalingFailed": "Échec de la mise à l'échelle",
|
||||
"faceRestoreFailed": "Échec de la restauration du visage",
|
||||
"metadataLoadFailed": "Échec du chargement des métadonnées",
|
||||
"initialImageSet": "Image initiale définie",
|
||||
"initialImageNotSet": "Image initiale non définie",
|
||||
"initialImageNotSetDesc": "Impossible de charger l'image initiale"
|
||||
}
|
||||
|
||||
32
invokeai/frontend/dist/locales/toast/ua.json
vendored
Normal file
32
invokeai/frontend/dist/locales/toast/ua.json
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"tempFoldersEmptied": "Тимчасова папка очищена",
|
||||
"uploadFailed": "Не вдалося завантажити",
|
||||
"uploadFailedMultipleImagesDesc": "Можна вставити лише одне зображення (ви спробували вставити декілька)",
|
||||
"uploadFailedUnableToLoadDesc": "Неможливо завантажити файл",
|
||||
"downloadImageStarted": "Завантаження зображення почалося",
|
||||
"imageCopied": "Зображення скопійоване",
|
||||
"imageLinkCopied": "Посилання на зображення скопійовано",
|
||||
"imageNotLoaded": "Зображення не завантажено",
|
||||
"imageNotLoadedDesc": "Не знайдено зображення для надсилання до img2img",
|
||||
"imageSavedToGallery": "Зображення збережено в галерею",
|
||||
"canvasMerged": "Полотно об'єднане",
|
||||
"sentToImageToImage": "Надіслати до img2img",
|
||||
"sentToUnifiedCanvas": "Надіслати на полотно",
|
||||
"parametersSet": "Параметри задані",
|
||||
"parametersNotSet": "Параметри не задані",
|
||||
"parametersNotSetDesc": "Не знайдені метадані цього зображення",
|
||||
"parametersFailed": "Проблема із завантаженням параметрів",
|
||||
"parametersFailedDesc": "Неможливо завантажити початкове зображення",
|
||||
"seedSet": "Сід заданий",
|
||||
"seedNotSet": "Сід не заданий",
|
||||
"seedNotSetDesc": "Не вдалося знайти сід для зображення",
|
||||
"promptSet": "Запит заданий",
|
||||
"promptNotSet": "Запит не заданий",
|
||||
"promptNotSetDesc": "Не вдалося знайти запит для зображення",
|
||||
"upscalingFailed": "Збільшення не вдалося",
|
||||
"faceRestoreFailed": "Відновлення облич не вдалося",
|
||||
"metadataLoadFailed": "Не вдалося завантажити метадані",
|
||||
"initialImageSet": "Початкове зображення задане",
|
||||
"initialImageNotSet": "Початкове зображення не задане",
|
||||
"initialImageNotSetDesc": "Не вдалося завантажити початкове зображення"
|
||||
}
|
||||
15
invokeai/frontend/dist/locales/tooltip/fr.json
vendored
Normal file
15
invokeai/frontend/dist/locales/tooltip/fr.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"feature": {
|
||||
"prompt": "Ceci est le champ prompt. Le prompt inclut des objets de génération et des termes stylistiques. Vous pouvez également ajouter un poids (importance du jeton) dans le prompt, mais les commandes CLI et les paramètres ne fonctionneront pas.",
|
||||
"gallery": "La galerie affiche les générations à partir du dossier de sortie à mesure qu'elles sont créées. Les paramètres sont stockés dans des fichiers et accessibles via le menu contextuel.",
|
||||
"other": "Ces options activent des modes de traitement alternatifs pour Invoke. 'Tuilage seamless' créera des motifs répétitifs dans la sortie. 'Haute résolution' est la génération en deux étapes avec img2img: utilisez ce paramètre lorsque vous souhaitez une image plus grande et plus cohérente sans artefacts. Cela prendra plus de temps que d'habitude txt2img.",
|
||||
"seed": "La valeur de grain affecte le bruit initial à partir duquel l'image est formée. Vous pouvez utiliser les graines déjà existantes provenant d'images précédentes. 'Seuil de bruit' est utilisé pour atténuer les artefacts à des valeurs CFG élevées (essayez la plage de 0 à 10), et Perlin pour ajouter du bruit Perlin pendant la génération: les deux servent à ajouter de la variété à vos sorties.",
|
||||
"variations": "Essayez une variation avec une valeur comprise entre 0,1 et 1,0 pour changer le résultat pour une graine donnée. Des variations intéressantes de la graine sont entre 0,1 et 0,3.",
|
||||
"upscale": "Utilisez ESRGAN pour agrandir l'image immédiatement après la génération.",
|
||||
"faceCorrection": "Correction de visage avec GFPGAN ou Codeformer: l'algorithme détecte les visages dans l'image et corrige tout défaut. La valeur élevée changera plus l'image, ce qui donnera des visages plus attirants. Codeformer avec une fidélité plus élevée préserve l'image originale au prix d'une correction de visage plus forte.",
|
||||
"imageToImage": "Image to Image charge n'importe quelle image en tant qu'initiale, qui est ensuite utilisée pour générer une nouvelle avec le prompt. Plus la valeur est élevée, plus l'image de résultat changera. Des valeurs de 0,0 à 1,0 sont possibles, la plage recommandée est de 0,25 à 0,75",
|
||||
"boundingBox": "La boîte englobante est la même que les paramètres Largeur et Hauteur pour Texte à Image ou Image à Image. Seulement la zone dans la boîte sera traitée.",
|
||||
"seamCorrection": "Contrôle la gestion des coutures visibles qui se produisent entre les images générées sur la toile.",
|
||||
"infillAndScaling": "Gérer les méthodes de remplissage (utilisées sur les zones masquées ou effacées de la toile) et le redimensionnement (utile pour les petites tailles de boîte englobante)."
|
||||
}
|
||||
}
|
||||
15
invokeai/frontend/dist/locales/tooltip/ua.json
vendored
Normal file
15
invokeai/frontend/dist/locales/tooltip/ua.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"feature": {
|
||||
"prompt": "Це поле для тексту запиту, включаючи об'єкти генерації та стилістичні терміни. У запит можна включити і коефіцієнти ваги (значущості токена), але консольні команди та параметри не працюватимуть.",
|
||||
"gallery": "Тут відображаються генерації з папки outputs у міру їх появи.",
|
||||
"other": "Ці опції включають альтернативні режими обробки для Invoke. 'Безшовний узор' створить на виході узори, що повторюються. 'Висока роздільна здатність' - це генерація у два етапи за допомогою img2img: використовуйте це налаштування, коли хочете отримати цільне зображення більшого розміру без артефактів.",
|
||||
"seed": "Значення сіду впливає на початковий шум, з якого сформується зображення. Можна використовувати вже наявний сід із попередніх зображень. 'Поріг шуму' використовується для пом'якшення артефактів при високих значеннях CFG (спробуйте в діапазоні 0-10), а 'Перлін' - для додавання шуму Перліна в процесі генерації: обидва параметри служать для більшої варіативності результатів.",
|
||||
"variations": "Спробуйте варіацію зі значенням від 0.1 до 1.0, щоб змінити результат для заданого сиду. Цікаві варіації сиду знаходяться між 0.1 і 0.3.",
|
||||
"upscale": "Використовуйте ESRGAN, щоб збільшити зображення відразу після генерації.",
|
||||
"faceCorrection": "Корекція облич за допомогою GFPGAN або Codeformer: алгоритм визначає обличчя у готовому зображенні та виправляє будь-які дефекти. Високі значення сили змінюють зображення сильніше, в результаті обличчя будуть виглядати привабливіше. У Codeformer більш висока точність збереже вихідне зображення на шкоду корекції обличчя.",
|
||||
"imageToImage": "'Зображення до зображення' завантажує будь-яке зображення, яке потім використовується для генерації разом із запитом. Чим більше значення, тим сильніше зміниться зображення в результаті. Можливі значення від 0 до 1, рекомендується діапазон 0.25-0.75",
|
||||
"boundingBox": "'Обмежуюча рамка' аналогічна налаштуванням 'Ширина' і 'Висота' для 'Зображення з тексту' або 'Зображення до зображення'. Буде оброблена тільки область у рамці.",
|
||||
"seamCorrection": "Керування обробкою видимих швів, що виникають між зображеннями на полотні.",
|
||||
"infillAndScaling": "Керування методами заповнення (використовується для масок або стертих частин полотна) та масштабування (корисно для малих розмірів обмежуючої рамки)."
|
||||
}
|
||||
}
|
||||
@@ -1 +1,59 @@
|
||||
{}
|
||||
{
|
||||
"layer": "Couche",
|
||||
"base": "Base",
|
||||
"mask": "Masque",
|
||||
"maskingOptions": "Options de masquage",
|
||||
"enableMask": "Activer le masque",
|
||||
"preserveMaskedArea": "Préserver la zone masquée",
|
||||
"clearMask": "Effacer le masque",
|
||||
"brush": "Pinceau",
|
||||
"eraser": "Gomme",
|
||||
"fillBoundingBox": "Remplir la boîte englobante",
|
||||
"eraseBoundingBox": "Effacer la boîte englobante",
|
||||
"colorPicker": "Sélecteur de couleur",
|
||||
"brushOptions": "Options de pinceau",
|
||||
"brushSize": "Taille",
|
||||
"move": "Déplacer",
|
||||
"resetView": "Réinitialiser la vue",
|
||||
"mergeVisible": "Fusionner les visibles",
|
||||
"saveToGallery": "Enregistrer dans la galerie",
|
||||
"copyToClipboard": "Copier dans le presse-papiers",
|
||||
"downloadAsImage": "Télécharger en tant qu'image",
|
||||
"undo": "Annuler",
|
||||
"redo": "Refaire",
|
||||
"clearCanvas": "Effacer le canvas",
|
||||
"canvasSettings": "Paramètres du canvas",
|
||||
"showIntermediates": "Afficher les intermédiaires",
|
||||
"showGrid": "Afficher la grille",
|
||||
"snapToGrid": "Aligner sur la grille",
|
||||
"darkenOutsideSelection": "Assombrir à l'extérieur de la sélection",
|
||||
"autoSaveToGallery": "Enregistrement automatique dans la galerie",
|
||||
"saveBoxRegionOnly": "Enregistrer uniquement la région de la boîte",
|
||||
"limitStrokesToBox": "Limiter les traits à la boîte",
|
||||
"showCanvasDebugInfo": "Afficher les informations de débogage du canvas",
|
||||
"clearCanvasHistory": "Effacer l'historique du canvas",
|
||||
"clearHistory": "Effacer l'historique",
|
||||
"clearCanvasHistoryMessage": "Effacer l'historique du canvas laisse votre canvas actuel intact, mais efface de manière irréversible l'historique annuler et refaire.",
|
||||
"clearCanvasHistoryConfirm": "Êtes-vous sûr de vouloir effacer l'historique du canvas?",
|
||||
"emptyTempImageFolder": "Vider le dossier d'images temporaires",
|
||||
"emptyFolder": "Vider le dossier",
|
||||
"emptyTempImagesFolderMessage": "Vider le dossier d'images temporaires réinitialise également complètement le canvas unifié. Cela inclut tout l'historique annuler/refaire, les images dans la zone de mise en attente et la couche de base du canvas.",
|
||||
"emptyTempImagesFolderConfirm": "Êtes-vous sûr de vouloir vider le dossier temporaire?",
|
||||
"activeLayer": "Calque actif",
|
||||
"canvasScale": "Échelle du canevas",
|
||||
"boundingBox": "Boîte englobante",
|
||||
"scaledBoundingBox": "Boîte englobante mise à l'échelle",
|
||||
"boundingBoxPosition": "Position de la boîte englobante",
|
||||
"canvasDimensions": "Dimensions du canevas",
|
||||
"canvasPosition": "Position du canevas",
|
||||
"cursorPosition": "Position du curseur",
|
||||
"previous": "Précédent",
|
||||
"next": "Suivant",
|
||||
"accept": "Accepter",
|
||||
"showHide": "Afficher/Masquer",
|
||||
"discardAll": "Tout abandonner",
|
||||
"betaClear": "Effacer",
|
||||
"betaDarkenOutside": "Assombrir à l'extérieur",
|
||||
"betaLimitToBox": "Limiter à la boîte",
|
||||
"betaPreserveMasked": "Conserver masqué"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"layer": "Layer",
|
||||
"layer": "Livello",
|
||||
"base": "Base",
|
||||
"mask": "Maschera",
|
||||
"maskingOptions": "Opzioni di mascheramento",
|
||||
|
||||
59
invokeai/frontend/dist/locales/unifiedcanvas/ua.json
vendored
Normal file
59
invokeai/frontend/dist/locales/unifiedcanvas/ua.json
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"layer": "Шар",
|
||||
"base": "Базовий",
|
||||
"mask": "Маска",
|
||||
"maskingOptions": "Параметри маски",
|
||||
"enableMask": "Увiмкнути маску",
|
||||
"preserveMaskedArea": "Зберiгати замасковану область",
|
||||
"clearMask": "Очистити маску",
|
||||
"brush": "Пензель",
|
||||
"eraser": "Гумка",
|
||||
"fillBoundingBox": "Заповнити обмежуючу рамку",
|
||||
"eraseBoundingBox": "Стерти обмежуючу рамку",
|
||||
"colorPicker": "Пiпетка",
|
||||
"brushOptions": "Параметри пензля",
|
||||
"brushSize": "Розмiр",
|
||||
"move": "Перемiстити",
|
||||
"resetView": "Скинути вигляд",
|
||||
"mergeVisible": "Об'єднати видимi",
|
||||
"saveToGallery": "Зберегти до галереї",
|
||||
"copyToClipboard": "Копiювати до буферу обмiну",
|
||||
"downloadAsImage": "Завантажити як зображення",
|
||||
"undo": "Вiдмiнити",
|
||||
"redo": "Повторити",
|
||||
"clearCanvas": "Очистити полотно",
|
||||
"canvasSettings": "Налаштування полотна",
|
||||
"showIntermediates": "Показувати процес",
|
||||
"showGrid": "Показувати сiтку",
|
||||
"snapToGrid": "Прив'язати до сітки",
|
||||
"darkenOutsideSelection": "Затемнити полотно зовні",
|
||||
"autoSaveToGallery": "Автозбереження до галереї",
|
||||
"saveBoxRegionOnly": "Зберiгати тiльки видiлення",
|
||||
"limitStrokesToBox": "Обмежити штрихи виділенням",
|
||||
"showCanvasDebugInfo": "Показати налаштування полотна",
|
||||
"clearCanvasHistory": "Очистити iсторiю полотна",
|
||||
"clearHistory": "Очистити iсторiю",
|
||||
"clearCanvasHistoryMessage": "Очищення історії полотна залишає поточне полотно незайманим, але видаляє історію скасування та повтору",
|
||||
"clearCanvasHistoryConfirm": "Ви впевнені, що хочете очистити історію полотна?",
|
||||
"emptyTempImageFolder": "Очистити тимчасову папку",
|
||||
"emptyFolder": "Очистити папку",
|
||||
"emptyTempImagesFolderMessage": "Очищення папки тимчасових зображень також повністю скидає полотно, включаючи всю історію скасування/повтору, зображення та базовий шар полотна, що розміщуються.",
|
||||
"emptyTempImagesFolderConfirm": "Ви впевнені, що хочете очистити тимчасову папку?",
|
||||
"activeLayer": "Активний шар",
|
||||
"canvasScale": "Масштаб полотна",
|
||||
"boundingBox": "Обмежуюча рамка",
|
||||
"scaledBoundingBox": "Масштабування рамки",
|
||||
"boundingBoxPosition": "Позиція обмежуючої рамки",
|
||||
"canvasDimensions": "Разміри полотна",
|
||||
"canvasPosition": "Розташування полотна",
|
||||
"cursorPosition": "Розташування курсора",
|
||||
"previous": "Попереднє",
|
||||
"next": "Наступне",
|
||||
"принять": "Приняти",
|
||||
"showHide": "Показати/Сховати",
|
||||
"discardAll": "Відмінити все",
|
||||
"betaClear": "Очистити",
|
||||
"betaDarkenOutside": "Затемнити зовні",
|
||||
"betaLimitToBox": "Обмежити виділенням",
|
||||
"betaPreserveMasked": "Зберiгати замасковану область"
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
"langSpanish": "Spanish",
|
||||
"langJapanese": "Japanese",
|
||||
"langDutch": "Dutch",
|
||||
"langUkranian": "Ukranian",
|
||||
"text2img": "Text To Image",
|
||||
"img2img": "Image To Image",
|
||||
"unifiedCanvas": "Unified Canvas",
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"langSpanish": "Spanish",
|
||||
"langJapanese": "Japanese",
|
||||
"langDutch": "Dutch",
|
||||
"langUkranian": "Ukranian",
|
||||
"text2img": "Text To Image",
|
||||
"img2img": "Image To Image",
|
||||
"unifiedCanvas": "Unified Canvas",
|
||||
|
||||
@@ -1 +1,62 @@
|
||||
{}
|
||||
{
|
||||
"hotkeysLabel": "Raccourcis clavier",
|
||||
"themeLabel": "Thème",
|
||||
"languagePickerLabel": "Sélecteur de langue",
|
||||
"reportBugLabel": "Signaler un bug",
|
||||
"githubLabel": "Github",
|
||||
"discordLabel": "Discord",
|
||||
"settingsLabel": "Paramètres",
|
||||
"darkTheme": "Sombre",
|
||||
"lightTheme": "Clair",
|
||||
"greenTheme": "Vert",
|
||||
"langEnglish": "Anglais",
|
||||
"langRussian": "Russe",
|
||||
"langItalian": "Italien",
|
||||
"langBrPortuguese": "Portugais (Brésilien)",
|
||||
"langGerman": "Allemand",
|
||||
"langPortuguese": "Portugais",
|
||||
"langFrench": "Français",
|
||||
"langPolish": "Polonais",
|
||||
"langSimplifiedChinese": "Chinois simplifié",
|
||||
"langSpanish": "Espagnol",
|
||||
"langJapanese": "Japonais",
|
||||
"langDutch": "Néerlandais",
|
||||
"text2img": "Texte en image",
|
||||
"img2img": "Image en image",
|
||||
"unifiedCanvas": "Canvas unifié",
|
||||
"nodes": "Nœuds",
|
||||
"nodesDesc": "Un système basé sur les nœuds pour la génération d'images est actuellement en développement. Restez à l'écoute pour des mises à jour à ce sujet.",
|
||||
"postProcessing": "Post-traitement",
|
||||
"postProcessDesc1": "Invoke AI offre une grande variété de fonctionnalités de post-traitement. Le redimensionnement d'images et la restauration de visages sont déjà disponibles dans la WebUI. Vous pouvez y accéder à partir du menu Options avancées des onglets Texte en image et Image en image. Vous pouvez également traiter les images directement en utilisant les boutons d'action d'image ci-dessus l'affichage d'image actuel ou dans le visualiseur.",
|
||||
"postProcessDesc2": "Une interface utilisateur dédiée sera bientôt disponible pour faciliter les workflows de post-traitement plus avancés.",
|
||||
"postProcessDesc3": "L'interface en ligne de commande d'Invoke AI offre diverses autres fonctionnalités, notamment Embiggen.",
|
||||
"training": "Formation",
|
||||
"trainingDesc1": "Un workflow dédié pour former vos propres embeddings et checkpoints en utilisant Textual Inversion et Dreambooth depuis l'interface web.",
|
||||
"trainingDesc2": "InvokeAI prend déjà en charge la formation d'embeddings personnalisés en utilisant Textual Inversion en utilisant le script principal.",
|
||||
"upload": "Télécharger",
|
||||
"close": "Fermer",
|
||||
"load": "Charger",
|
||||
"back": "Retour",
|
||||
"statusConnected": "Connecté",
|
||||
"statusDisconnected": "Déconnecté",
|
||||
"statusError": "Erreur",
|
||||
"statusPreparing": "Préparation",
|
||||
"statusProcessingCanceled": "Traitement Annulé",
|
||||
"statusProcessingComplete": "Traitement Terminé",
|
||||
"statusGenerating": "Génération",
|
||||
"statusGeneratingTextToImage": "Génération Texte vers Image",
|
||||
"statusGeneratingImageToImage": "Génération Image vers Image",
|
||||
"statusGeneratingInpainting": "Génération de Réparation",
|
||||
"statusGeneratingOutpainting": "Génération de Completion",
|
||||
"statusGenerationComplete": "Génération Terminée",
|
||||
"statusIterationComplete": "Itération Terminée",
|
||||
"statusSavingImage": "Sauvegarde de l'Image",
|
||||
"statusRestoringFaces": "Restauration des Visages",
|
||||
"statusRestoringFacesGFPGAN": "Restauration des Visages (GFPGAN)",
|
||||
"statusRestoringFacesCodeFormer": "Restauration des Visages (CodeFormer)",
|
||||
"statusUpscaling": "Mise à Échelle",
|
||||
"statusUpscalingESRGAN": "Mise à Échelle (ESRGAN)",
|
||||
"statusLoadingModel": "Chargement du Modèle",
|
||||
"statusModelChanged": "Modèle Changé"
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
"langPolish": "Polacco",
|
||||
"langSimplifiedChinese": "Cinese semplificato",
|
||||
"langSpanish": "Spagnolo",
|
||||
"langJapanese": "Giapponese",
|
||||
"langDutch": "Olandese",
|
||||
"text2img": "Testo a Immagine",
|
||||
"img2img": "Immagine a Immagine",
|
||||
"unifiedCanvas": "Tela unificata",
|
||||
@@ -34,6 +36,7 @@
|
||||
"upload": "Caricamento",
|
||||
"close": "Chiudi",
|
||||
"load": "Carica",
|
||||
"back": "Indietro",
|
||||
"statusConnected": "Collegato",
|
||||
"statusDisconnected": "Disconnesso",
|
||||
"statusError": "Errore",
|
||||
|
||||
53
invokeai/frontend/public/locales/common/ua.json
Normal file
53
invokeai/frontend/public/locales/common/ua.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"hotkeysLabel": "Гарячi клавіші",
|
||||
"themeLabel": "Тема",
|
||||
"languagePickerLabel": "Мова",
|
||||
"reportBugLabel": "Повідомити про помилку",
|
||||
"githubLabel": "Github",
|
||||
"discordLabel": "Discord",
|
||||
"settingsLabel": "Налаштування",
|
||||
"darkTheme": "Темна",
|
||||
"lightTheme": "Світла",
|
||||
"greenTheme": "Зелена",
|
||||
"langEnglish": "Англійська",
|
||||
"langRussian": "Російська",
|
||||
"langItalian": "Iталійська",
|
||||
"langPortuguese": "Португальська",
|
||||
"langFrench": "Французька",
|
||||
"text2img": "Зображення із тексту (text2img)",
|
||||
"img2img": "Зображення із зображення (img2img)",
|
||||
"unifiedCanvas": "Універсальне полотно",
|
||||
"nodes": "Вузли",
|
||||
"nodesDesc": "Система генерації зображень на основі нодів (вузлів) вже розробляється. Слідкуйте за новинами про цю чудову функцію.",
|
||||
"postProcessing": "Постобробка",
|
||||
"postProcessDesc1": "Invoke AI пропонує широкий спектр функцій постобробки. Збільшення зображення (upscale) та відновлення облич вже доступні в інтерфейсі. Отримайте доступ до них з меню 'Додаткові параметри' на вкладках 'Зображення із тексту' та 'Зображення із зображення'. Обробляйте зображення безпосередньо, використовуючи кнопки дій із зображеннями над поточним зображенням або в режимі перегляду.",
|
||||
"postProcessDesc2": "Найближчим часом буде випущено спеціальний інтерфейс для більш сучасних процесів постобробки.",
|
||||
"postProcessDesc3": "Інтерфейс командного рядка Invoke AI пропонує різні інші функції, включаючи збільшення Embiggen",
|
||||
"training": "Навчання",
|
||||
"trainingDesc1": "Спеціальний інтерфейс для навчання власних моделей з використанням Textual Inversion та Dreambooth",
|
||||
"trainingDesc2": "InvokeAI вже підтримує навчання моделей за допомогою TI, через інтерфейс командного рядка.",
|
||||
"upload": "Завантажити",
|
||||
"close": "Закрити",
|
||||
"load": "Завантажити",
|
||||
"statusConnected": "Підключено",
|
||||
"statusDisconnected": "Відключено",
|
||||
"statusError": "Помилка",
|
||||
"statusPreparing": "Підготування",
|
||||
"statusProcessingCanceled": "Обробка перервана",
|
||||
"statusProcessingComplete": "Обробка завершена",
|
||||
"statusGenerating": "Генерація",
|
||||
"statusGeneratingTextToImage": "Генерація зображення із тексту",
|
||||
"statusGeneratingImageToImage": "Генерація зображення із зображення",
|
||||
"statusGeneratingInpainting": "Домальовка всередині",
|
||||
"statusGeneratingOutpainting": "Домальовка зовні",
|
||||
"statusGenerationComplete": "Генерація завершена",
|
||||
"statusIterationComplete": "Iтерація завершена",
|
||||
"statusSavingImage": "Збереження зображення",
|
||||
"statusRestoringFaces": "Відновлення облич",
|
||||
"statusRestoringFacesGFPGAN": "Відновлення облич (GFPGAN)",
|
||||
"statusRestoringFacesCodeFormer": "Відновлення облич (CodeFormer)",
|
||||
"statusUpscaling": "Збільшення",
|
||||
"statusUpscalingESRGAN": "Збільшення (ESRGAN)",
|
||||
"statusLoadingModel": "Завантаження моделі",
|
||||
"statusModelChanged": "Модель змінено"
|
||||
}
|
||||
@@ -1 +1,16 @@
|
||||
{}
|
||||
{
|
||||
"generations": "Générations",
|
||||
"showGenerations": "Afficher les générations",
|
||||
"uploads": "Téléchargements",
|
||||
"showUploads": "Afficher les téléchargements",
|
||||
"galleryImageSize": "Taille de l'image",
|
||||
"galleryImageResetSize": "Réinitialiser la taille",
|
||||
"gallerySettings": "Paramètres de la galerie",
|
||||
"maintainAspectRatio": "Maintenir le rapport d'aspect",
|
||||
"autoSwitchNewImages": "Basculer automatiquement vers de nouvelles images",
|
||||
"singleColumnLayout": "Mise en page en colonne unique",
|
||||
"pinGallery": "Épingler la galerie",
|
||||
"allImagesLoaded": "Toutes les images chargées",
|
||||
"loadMore": "Charger plus",
|
||||
"noImagesInGallery": "Aucune image dans la galerie"
|
||||
}
|
||||
|
||||
16
invokeai/frontend/public/locales/gallery/ua.json
Normal file
16
invokeai/frontend/public/locales/gallery/ua.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"generations": "Генерації",
|
||||
"showGenerations": "Показувати генерації",
|
||||
"uploads": "Завантаження",
|
||||
"showUploads": "Показувати завантаження",
|
||||
"galleryImageSize": "Розмір зображень",
|
||||
"galleryImageResetSize": "Аатоматичний розмір",
|
||||
"gallerySettings": "Налаштування галереї",
|
||||
"maintainAspectRatio": "Зберігати пропорції",
|
||||
"autoSwitchNewImages": "Автоматично вибирати нові",
|
||||
"singleColumnLayout": "Одна колонка",
|
||||
"pinGallery": "Закріпити галерею",
|
||||
"allImagesLoaded": "Всі зображення завантажені",
|
||||
"loadMore": "Завантажити більше",
|
||||
"noImagesInGallery": "Зображень немає"
|
||||
}
|
||||
@@ -1 +1,207 @@
|
||||
{}
|
||||
{
|
||||
"keyboardShortcuts": "Raccourcis clavier",
|
||||
"appHotkeys": "Raccourcis de l'application",
|
||||
"GeneralHotkeys": "Raccourcis généraux",
|
||||
"galleryHotkeys": "Raccourcis de la galerie",
|
||||
"unifiedCanvasHotkeys": "Raccourcis du Canvas unifié",
|
||||
"invoke": {
|
||||
"title": "Invoquer",
|
||||
"desc": "Générer une image"
|
||||
},
|
||||
"cancel": {
|
||||
"title": "Annuler",
|
||||
"desc": "Annuler la génération d'image"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"title": "Prompt de Focus",
|
||||
"desc": "Mettre en focus la zone de saisie de la commande"
|
||||
},
|
||||
"toggleOptions": {
|
||||
"title": "Basculer Options",
|
||||
"desc": "Ouvrir et fermer le panneau d'options"
|
||||
},
|
||||
"pinOptions": {
|
||||
"title": "Epingler Options",
|
||||
"desc": "Epingler le panneau d'options"
|
||||
},
|
||||
"toggleViewer": {
|
||||
"title": "Basculer Visionneuse",
|
||||
"desc": "Ouvrir et fermer la visionneuse d'image"
|
||||
},
|
||||
"toggleGallery": {
|
||||
"title": "Basculer Galerie",
|
||||
"desc": "Ouvrir et fermer le tiroir de galerie"
|
||||
},
|
||||
"maximizeWorkSpace": {
|
||||
"title": "Maximiser Espace de travail",
|
||||
"desc": "Fermer les panneaux et maximiser la zone de travail"
|
||||
},
|
||||
"changeTabs": {
|
||||
"title": "Changer d'onglets",
|
||||
"desc": "Passer à un autre espace de travail"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"title": "Bascule de la console",
|
||||
"desc": "Ouvrir et fermer la console"
|
||||
},
|
||||
"setPrompt": {
|
||||
"title": "Définir le prompt",
|
||||
"desc": "Utiliser le prompt de l'image actuelle"
|
||||
},
|
||||
"setSeed": {
|
||||
"title": "Définir la graine",
|
||||
"desc": "Utiliser la graine de l'image actuelle"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "Définir les paramètres",
|
||||
"desc": "Utiliser tous les paramètres de l'image actuelle"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"title": "Restaurer les faces",
|
||||
"desc": "Restaurer l'image actuelle"
|
||||
},
|
||||
"upscale": {
|
||||
"title": "Agrandir",
|
||||
"desc": "Agrandir l'image actuelle"
|
||||
},
|
||||
"showInfo": {
|
||||
"title": "Afficher les informations",
|
||||
"desc": "Afficher les informations de métadonnées de l'image actuelle"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"title": "Envoyer à l'image à l'image",
|
||||
"desc": "Envoyer l'image actuelle à l'image à l'image"
|
||||
},
|
||||
"deleteImage": {
|
||||
"title": "Supprimer l'image",
|
||||
"desc": "Supprimer l'image actuelle"
|
||||
},
|
||||
"closePanels": {
|
||||
"title": "Fermer les panneaux",
|
||||
"desc": "Fermer les panneaux ouverts"
|
||||
},
|
||||
"previousImage": {
|
||||
"title": "Image précédente",
|
||||
"desc": "Afficher l'image précédente dans la galerie"
|
||||
},
|
||||
"nextImage": {
|
||||
"title": "Image suivante",
|
||||
"desc": "Afficher l'image suivante dans la galerie"
|
||||
},
|
||||
"toggleGalleryPin": {
|
||||
"title": "Activer/désactiver l'épinglage de la galerie",
|
||||
"desc": "Épingle ou dépingle la galerie à l'interface utilisateur"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "Augmenter la taille des miniatures de la galerie",
|
||||
"desc": "Augmente la taille des miniatures de la galerie"
|
||||
},
|
||||
"decreaseGalleryThumbSize": {
|
||||
"title": "Diminuer la taille des miniatures de la galerie",
|
||||
"desc": "Diminue la taille des miniatures de la galerie"
|
||||
},
|
||||
"selectBrush": {
|
||||
"title": "Sélectionner un pinceau",
|
||||
"desc": "Sélectionne le pinceau de la toile"
|
||||
},
|
||||
"selectEraser": {
|
||||
"title": "Sélectionner un gomme",
|
||||
"desc": "Sélectionne la gomme de la toile"
|
||||
},
|
||||
"decreaseBrushSize": {
|
||||
"title": "Diminuer la taille du pinceau",
|
||||
"desc": "Diminue la taille du pinceau/gomme de la toile"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"title": "Augmenter la taille du pinceau",
|
||||
"desc": "Augmente la taille du pinceau/gomme de la toile"
|
||||
},
|
||||
"decreaseBrushOpacity": {
|
||||
"title": "Diminuer l'opacité du pinceau",
|
||||
"desc": "Diminue l'opacité du pinceau de la toile"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"title": "Augmenter l'opacité du pinceau",
|
||||
"desc": "Augmente l'opacité du pinceau de la toile"
|
||||
},
|
||||
"moveTool": {
|
||||
"title": "Outil de déplacement",
|
||||
"desc": "Permet la navigation sur la toile"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"title": "Remplir la boîte englobante",
|
||||
"desc": "Remplit la boîte englobante avec la couleur du pinceau"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"title": "Effacer la boîte englobante",
|
||||
"desc": "Efface la zone de la boîte englobante"
|
||||
},
|
||||
"colorPicker": {
|
||||
"title": "Sélectionnez le sélecteur de couleur",
|
||||
"desc": "Sélectionne le sélecteur de couleur de la toile"
|
||||
},
|
||||
"toggleSnap": {
|
||||
"title": "Basculer Snap",
|
||||
"desc": "Basculer Snap à la grille"
|
||||
},
|
||||
"quickToggleMove": {
|
||||
"title": "Basculer rapidement déplacer",
|
||||
"desc": "Basculer temporairement le mode Déplacer"
|
||||
},
|
||||
"toggleLayer": {
|
||||
"title": "Basculer la couche",
|
||||
"desc": "Basculer la sélection de la couche masque/base"
|
||||
},
|
||||
"clearMask": {
|
||||
"title": "Effacer le masque",
|
||||
"desc": "Effacer entièrement le masque"
|
||||
},
|
||||
"hideMask": {
|
||||
"title": "Masquer le masque",
|
||||
"desc": "Masquer et démasquer le masque"
|
||||
},
|
||||
"showHideBoundingBox": {
|
||||
"title": "Afficher/Masquer la boîte englobante",
|
||||
"desc": "Basculer la visibilité de la boîte englobante"
|
||||
},
|
||||
"mergeVisible": {
|
||||
"title": "Fusionner visible",
|
||||
"desc": "Fusionner toutes les couches visibles de la toile"
|
||||
},
|
||||
"saveToGallery": {
|
||||
"title": "Enregistrer dans la galerie",
|
||||
"desc": "Enregistrer la toile actuelle dans la galerie"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"title": "Copier dans le presse-papiers",
|
||||
"desc": "Copier la toile actuelle dans le presse-papiers"
|
||||
},
|
||||
"downloadImage": {
|
||||
"title": "Télécharger l'image",
|
||||
"desc": "Télécharger la toile actuelle"
|
||||
},
|
||||
"undoStroke": {
|
||||
"title": "Annuler le trait",
|
||||
"desc": "Annuler un coup de pinceau"
|
||||
},
|
||||
"redoStroke": {
|
||||
"title": "Rétablir le trait",
|
||||
"desc": "Rétablir un coup de pinceau"
|
||||
},
|
||||
"resetView": {
|
||||
"title": "Réinitialiser la vue",
|
||||
"desc": "Réinitialiser la vue de la toile"
|
||||
},
|
||||
"previousStagingImage": {
|
||||
"title": "Image de mise en scène précédente",
|
||||
"desc": "Image précédente de la zone de mise en scène"
|
||||
},
|
||||
"nextStagingImage": {
|
||||
"title": "Image de mise en scène suivante",
|
||||
"desc": "Image suivante de la zone de mise en scène"
|
||||
},
|
||||
"acceptStagingImage": {
|
||||
"title": "Accepter l'image de mise en scène",
|
||||
"desc": "Accepter l'image actuelle de la zone de mise en scène"
|
||||
}
|
||||
}
|
||||
|
||||
207
invokeai/frontend/public/locales/hotkeys/ua.json
Normal file
207
invokeai/frontend/public/locales/hotkeys/ua.json
Normal file
@@ -0,0 +1,207 @@
|
||||
{
|
||||
"keyboardShortcuts": "Клавіатурні скорочення",
|
||||
"appHotkeys": "Гарячі клавіші програми",
|
||||
"generalHotkeys": "Загальні гарячі клавіші",
|
||||
"galleryHotkeys": "Гарячі клавіші галереї",
|
||||
"unifiedCanvasHotkeys": "Гарячі клавіші універсального полотна",
|
||||
"invoke": {
|
||||
"title": "Invoke",
|
||||
"desc": "Згенерувати зображення"
|
||||
},
|
||||
"cancel": {
|
||||
"title": "Скасувати",
|
||||
"desc": "Скасувати генерацію зображення"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"title": "Переключитися на введення запиту",
|
||||
"desc": "Перемикання на область введення запиту"
|
||||
},
|
||||
"toggleOptions": {
|
||||
"title": "Показати/приховати параметри",
|
||||
"desc": "Відкривати і закривати панель параметрів"
|
||||
},
|
||||
"pinOptions": {
|
||||
"title": "Закріпити параметри",
|
||||
"desc": "Закріпити панель параметрів"
|
||||
},
|
||||
"toggleViewer": {
|
||||
"title": "Показати перегляд",
|
||||
"desc": "Відкривати і закривати переглядач зображень"
|
||||
},
|
||||
"toggleGallery": {
|
||||
"title": "Показати галерею",
|
||||
"desc": "Відкривати і закривати скриньку галереї"
|
||||
},
|
||||
"maximizeWorkSpace": {
|
||||
"title": "Максимізувати робочий простір",
|
||||
"desc": "Приховати панелі і максимізувати робочу область"
|
||||
},
|
||||
"changeTabs": {
|
||||
"title": "Переключити вкладку",
|
||||
"desc": "Переключитися на іншу робочу область"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"title": "Показати консоль",
|
||||
"desc": "Відкривати і закривати консоль"
|
||||
},
|
||||
"setPrompt": {
|
||||
"title": "Використовувати запит",
|
||||
"desc": "Використати запит із поточного зображення"
|
||||
},
|
||||
"setSeed": {
|
||||
"title": "Використовувати сід",
|
||||
"desc": "Використовувати сід поточного зображення"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "Використовувати всі параметри",
|
||||
"desc": "Використовувати всі параметри поточного зображення"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"title": "Відновити обличчя",
|
||||
"desc": "Відновити обличчя на поточному зображенні"
|
||||
},
|
||||
"upscale": {
|
||||
"title": "Збільшення",
|
||||
"desc": "Збільшити поточне зображення"
|
||||
},
|
||||
"showInfo": {
|
||||
"title": "Показати метадані",
|
||||
"desc": "Показати метадані з поточного зображення"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"title": "Відправити в img2img",
|
||||
"desc": "Надіслати поточне зображення в Image To Image"
|
||||
},
|
||||
"deleteImage": {
|
||||
"title": "Видалити зображення",
|
||||
"desc": "Видалити поточне зображення"
|
||||
},
|
||||
"closePanels": {
|
||||
"title": "Закрити панелі",
|
||||
"desc": "Закриває відкриті панелі"
|
||||
},
|
||||
"previousImage": {
|
||||
"title": "Попереднє зображення",
|
||||
"desc": "Відображати попереднє зображення в галереї"
|
||||
},
|
||||
"nextImage": {
|
||||
"title": "Наступне зображення",
|
||||
"desc": "Відображення наступного зображення в галереї"
|
||||
},
|
||||
"toggleGalleryPin": {
|
||||
"title": "Закріпити галерею",
|
||||
"desc": "Закріплює і відкріплює галерею"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "Збільшити розмір мініатюр галереї",
|
||||
"desc": "Збільшує розмір мініатюр галереї"
|
||||
},
|
||||
"reduceGalleryThumbSize": {
|
||||
"title": "Зменшує розмір мініатюр галереї",
|
||||
"desc": "Зменшує розмір мініатюр галереї"
|
||||
},
|
||||
"selectBrush": {
|
||||
"title": "Вибрати пензель",
|
||||
"desc": "Вибирає пензель для полотна"
|
||||
},
|
||||
"selectEraser": {
|
||||
"title": "Вибрати ластик",
|
||||
"desc": "Вибирає ластик для полотна"
|
||||
},
|
||||
"reduceBrushSize": {
|
||||
"title": "Зменшити розмір пензля",
|
||||
"desc": "Зменшує розмір пензля/ластика полотна"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"title": "Збільшити розмір пензля",
|
||||
"desc": "Збільшує розмір пензля/ластика полотна"
|
||||
},
|
||||
"reduceBrushOpacity": {
|
||||
"title": "Зменшити непрозорість пензля",
|
||||
"desc": "Зменшує непрозорість пензля полотна"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"title": "Збільшити непрозорість пензля",
|
||||
"desc": "Збільшує непрозорість пензля полотна"
|
||||
},
|
||||
"moveTool": {
|
||||
"title": "Інструмент переміщення",
|
||||
"desc": "Дозволяє переміщатися по полотну"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"title": "Заповнити обмежувальну рамку",
|
||||
"desc": "Заповнює обмежувальну рамку кольором пензля"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"title": "Стерти обмежувальну рамку",
|
||||
"desc": "Стирає область обмежувальної рамки"
|
||||
},
|
||||
"colorPicker": {
|
||||
"title": "Вибрати колір",
|
||||
"desc": "Вибирає засіб вибору кольору полотна"
|
||||
},
|
||||
"toggleSnap": {
|
||||
"title": "Увімкнути прив'язку",
|
||||
"desc": "Вмикає/вимикає прив'язку до сітки"
|
||||
},
|
||||
"quickToggleMove": {
|
||||
"title": "Швидке перемикання переміщення",
|
||||
"desc": "Тимчасово перемикає режим переміщення"
|
||||
},
|
||||
"toggleLayer": {
|
||||
"title": "Переключити шар",
|
||||
"desc": "Перемикання маски/базового шару"
|
||||
},
|
||||
"clearMask": {
|
||||
"title": "Очистити маску",
|
||||
"desc": "Очистити всю маску"
|
||||
},
|
||||
"hideMask": {
|
||||
"title": "Приховати маску",
|
||||
"desc": "Приховує/показує маску"
|
||||
},
|
||||
"showHideBoundingBox": {
|
||||
"title": "Показати/приховати обмежувальну рамку",
|
||||
"desc": "Переключити видимість обмежувальної рамки"
|
||||
},
|
||||
"mergeVisible": {
|
||||
"title": "Об'єднати видимі",
|
||||
"desc": "Об'єднати всі видимі шари полотна"
|
||||
},
|
||||
"saveToGallery": {
|
||||
"title": "Зберегти в галерею",
|
||||
"desc": "Зберегти поточне полотно в галерею"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"title": "Копіювати в буфер обміну",
|
||||
"desc": "Копіювати поточне полотно в буфер обміну"
|
||||
},
|
||||
"downloadImage": {
|
||||
"title": "Завантажити зображення",
|
||||
"desc": "Завантажити вміст полотна"
|
||||
},
|
||||
"undoStroke": {
|
||||
"title": "Скасувати пензель",
|
||||
"desc": "Скасувати мазок пензля"
|
||||
},
|
||||
"redoStroke": {
|
||||
"title": "Повторити мазок пензля",
|
||||
"desc": "Повторити мазок пензля"
|
||||
},
|
||||
"resetView": {
|
||||
"title": "Вид за замовчуванням",
|
||||
"desc": "Скинути вид полотна"
|
||||
},
|
||||
"previousStagingImage": {
|
||||
"title": "Попереднє зображення",
|
||||
"desc": "Попереднє зображення"
|
||||
},
|
||||
"nextStagingImage": {
|
||||
"title": "Наступне зображення",
|
||||
"desc": "Наступне зображення"
|
||||
},
|
||||
"acceptStagingImage": {
|
||||
"title": "Прийняти зображення",
|
||||
"desc": "Прийняти поточне зображення"
|
||||
}
|
||||
}
|
||||
68
invokeai/frontend/public/locales/modelmanager/fr.json
Normal file
68
invokeai/frontend/public/locales/modelmanager/fr.json
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"modelManager": "Gestionnaire de modèle",
|
||||
"model": "Modèle",
|
||||
"allModels": "Tous les modèles",
|
||||
"checkpointModels": "Points de contrôle",
|
||||
"diffusersModels": "Diffuseurs",
|
||||
"safetensorModels": "SafeTensors",
|
||||
"modelAdded": "Modèle ajouté",
|
||||
"modelUpdated": "Modèle mis à jour",
|
||||
"modelEntryDeleted": "Entrée de modèle supprimée",
|
||||
"cannotUseSpaces": "Ne peut pas utiliser d'espaces",
|
||||
"addNew": "Ajouter un nouveau",
|
||||
"addNewModel": "Ajouter un nouveau modèle",
|
||||
"addCheckpointModel": "Ajouter un modèle de point de contrôle / SafeTensor",
|
||||
"addDiffuserModel": "Ajouter des diffuseurs",
|
||||
"addManually": "Ajouter manuellement",
|
||||
"manual": "Manuel",
|
||||
"name": "Nom",
|
||||
"nameValidationMsg": "Entrez un nom pour votre modèle",
|
||||
"description": "Description",
|
||||
"descriptionValidationMsg": "Ajoutez une description pour votre modèle",
|
||||
"config": "Config",
|
||||
"configValidationMsg": "Chemin vers le fichier de configuration de votre modèle.",
|
||||
"modelLocation": "Emplacement du modèle",
|
||||
"modelLocationValidationMsg": "Chemin vers où votre modèle est situé localement.",
|
||||
"repo_id": "ID de dépôt",
|
||||
"repoIDValidationMsg": "Dépôt en ligne de votre modèle",
|
||||
"vaeLocation": "Emplacement VAE",
|
||||
"vaeLocationValidationMsg": "Chemin vers où votre VAE est situé.",
|
||||
"vaeRepoID": "ID de dépôt VAE",
|
||||
"vaeRepoIDValidationMsg": "Dépôt en ligne de votre VAE",
|
||||
"width": "Largeur",
|
||||
"widthValidationMsg": "Largeur par défaut de votre modèle.",
|
||||
"height": "Hauteur",
|
||||
"heightValidationMsg": "Hauteur par défaut de votre modèle.",
|
||||
"addModel": "Ajouter un modèle",
|
||||
"updateModel": "Mettre à jour le modèle",
|
||||
"availableModels": "Modèles disponibles",
|
||||
"search": "Rechercher",
|
||||
"load": "Charger",
|
||||
"active": "actif",
|
||||
"notLoaded": "non chargé",
|
||||
"cached": "en cache",
|
||||
"checkpointFolder": "Dossier de point de contrôle",
|
||||
"clearCheckpointFolder": "Effacer le dossier de point de contrôle",
|
||||
"findModels": "Trouver des modèles",
|
||||
"scanAgain": "Scanner à nouveau",
|
||||
"modelsFound": "Modèles trouvés",
|
||||
"selectFolder": "Sélectionner un dossier",
|
||||
"selected": "Sélectionné",
|
||||
"selectAll": "Tout sélectionner",
|
||||
"deselectAll": "Tout désélectionner",
|
||||
"showExisting": "Afficher existant",
|
||||
"addSelected": "Ajouter sélectionné",
|
||||
"modelExists": "Modèle existant",
|
||||
"selectAndAdd": "Sélectionner et ajouter les modèles listés ci-dessous",
|
||||
"noModelsFound": "Aucun modèle trouvé",
|
||||
"delete": "Supprimer",
|
||||
"deleteModel": "Supprimer le modèle",
|
||||
"deleteConfig": "Supprimer la configuration",
|
||||
"deleteMsg1": "Êtes-vous sûr de vouloir supprimer cette entrée de modèle dans InvokeAI?",
|
||||
"deleteMsg2": "Cela n'effacera pas le fichier de point de contrôle du modèle de votre disque. Vous pouvez les réajouter si vous le souhaitez.",
|
||||
"formMessageDiffusersModelLocation": "Emplacement du modèle de diffuseurs",
|
||||
"formMessageDiffusersModelLocationDesc": "Veuillez en entrer au moins un.",
|
||||
"formMessageDiffusersVAELocation": "Emplacement VAE",
|
||||
"formMessageDiffusersVAELocationDesc": "Si non fourni, InvokeAI recherchera le fichier VAE à l'emplacement du modèle donné ci-dessus."
|
||||
|
||||
}
|
||||
@@ -1,24 +1,34 @@
|
||||
{
|
||||
"modelManager": "Gestione Modelli",
|
||||
"model": "Modello",
|
||||
"allModels": "Tutti i Modelli",
|
||||
"checkpointModels": "Checkpoint",
|
||||
"diffusersModels": "Diffusori",
|
||||
"safetensorModels": "SafeTensor",
|
||||
"modelAdded": "Modello Aggiunto",
|
||||
"modelUpdated": "Modello Aggiornato",
|
||||
"modelEntryDeleted": "Modello Rimosso",
|
||||
"cannotUseSpaces": "Impossibile utilizzare gli spazi",
|
||||
"addNew": "Aggiungi nuovo",
|
||||
"addNewModel": "Aggiungi nuovo Modello",
|
||||
"addCheckpointModel": "Aggiungi modello Checkpoint / Safetensor",
|
||||
"addDiffuserModel": "Aggiungi Diffusori",
|
||||
"addManually": "Aggiungi manualmente",
|
||||
"manual": "Manuale",
|
||||
"name": "Nome",
|
||||
"nameValidationMsg": "Inserisci un nome per il modello",
|
||||
"description": "Descrizione",
|
||||
"descriptionValidationMsg": "Aggiungi una descrizione per il modello",
|
||||
"config": "Config",
|
||||
"config": "Configurazione",
|
||||
"configValidationMsg": "Percorso del file di configurazione del modello.",
|
||||
"modelLocation": "Posizione del modello",
|
||||
"modelLocationValidationMsg": "Percorso dove si trova il modello.",
|
||||
"repo_id": "Repo ID",
|
||||
"repoIDValidationMsg": "Repository online del modello",
|
||||
"vaeLocation": "Posizione file VAE",
|
||||
"vaeLocationValidationMsg": "Percorso dove si trova il file VAE.",
|
||||
"vaeRepoID": "VAE Repo ID",
|
||||
"vaeRepoIDValidationMsg": "Repository online del file VAE",
|
||||
"width": "Larghezza",
|
||||
"widthValidationMsg": "Larghezza predefinita del modello.",
|
||||
"height": "Altezza",
|
||||
@@ -49,5 +59,9 @@
|
||||
"deleteModel": "Elimina modello",
|
||||
"deleteConfig": "Elimina configurazione",
|
||||
"deleteMsg1": "Sei sicuro di voler eliminare questo modello da InvokeAI?",
|
||||
"deleteMsg2": "Questo non eliminerà il file Checkpoint del modello dal tuo disco. Puoi aggiungerlo nuovamente se lo desideri."
|
||||
"deleteMsg2": "Questo non eliminerà il file Checkpoint del modello dal tuo disco. Puoi aggiungerlo nuovamente se lo desideri.",
|
||||
"formMessageDiffusersModelLocation": "Ubicazione modelli diffusori",
|
||||
"formMessageDiffusersModelLocationDesc": "Inseriscine almeno uno.",
|
||||
"formMessageDiffusersVAELocation": "Ubicazione file VAE",
|
||||
"formMessageDiffusersVAELocationDesc": "Se non fornito, InvokeAI cercherà il file VAE all'interno dell'ubicazione del modello sopra indicata."
|
||||
}
|
||||
|
||||
53
invokeai/frontend/public/locales/modelmanager/ua.json
Normal file
53
invokeai/frontend/public/locales/modelmanager/ua.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"modelManager": "Менеджер моделей",
|
||||
"model": "Модель",
|
||||
"modelAdded": "Модель додана",
|
||||
"modelUpdated": "Модель оновлена",
|
||||
"modelEntryDeleted": "Запис про модель видалено",
|
||||
"cannotUseSpaces": "Не можна використовувати пробіли",
|
||||
"addNew": "Додати нову",
|
||||
"addNewModel": "Додати нову модель",
|
||||
"addManually": "Додати вручну",
|
||||
"manual": "Ручне",
|
||||
"name": "Назва",
|
||||
"nameValidationMsg": "Введіть назву моделі",
|
||||
"description": "Опис",
|
||||
"descriptionValidationMsg": "Введіть опис моделі",
|
||||
"config": "Файл конфігурації",
|
||||
"configValidationMsg": "Шлях до файлу конфігурації",
|
||||
"modelLocation": "Розташування моделі",
|
||||
"modelLocationValidationMsg": "Шлях до файлу з моделлю",
|
||||
"vaeLocation": "Розтышування VAE",
|
||||
"vaeLocationValidationMsg": "Шлях до VAE",
|
||||
"width": "Ширина",
|
||||
"widthValidationMsg": "Початкова ширина зображень",
|
||||
"height": "Висота",
|
||||
"heightValidationMsg": "Початкова висота зображень",
|
||||
"addModel": "Додати модель",
|
||||
"updateModel": "Оновити модель",
|
||||
"availableModels": "Доступні моделі",
|
||||
"search": "Шукати",
|
||||
"load": "Завантажити",
|
||||
"active": "активна",
|
||||
"notLoaded": "не завантажена",
|
||||
"cached": "кешована",
|
||||
"checkpointFolder": "Папка з моделями",
|
||||
"clearCheckpointFolder": "Очистити папку з моделями",
|
||||
"findModels": "Знайти моделі",
|
||||
"scanAgain": "Сканувати знову",
|
||||
"modelsFound": "Знайдені моделі",
|
||||
"selectFolder": "Обрати папку",
|
||||
"selected": "Обрані",
|
||||
"selectAll": "Обрати всі",
|
||||
"deselectAll": "Зняти выділення",
|
||||
"showExisting": "Показувати додані",
|
||||
"addSelected": "Додати обрані",
|
||||
"modelExists": "Модель вже додана",
|
||||
"selectAndAdd": "Оберіть і додайте моделі із списку",
|
||||
"noModelsFound": "Моделі не знайдені",
|
||||
"delete": "Видалити",
|
||||
"deleteModel": "Видалити модель",
|
||||
"deleteConfig": "Видалити конфігурацію",
|
||||
"deleteMsg1": "Ви точно хочете видалити модель із InvokeAI?",
|
||||
"deleteMsg2": "Це не призведе до видалення файлу моделі з диску. Позніше ви можете додати його знову."
|
||||
}
|
||||
@@ -43,6 +43,7 @@
|
||||
"invoke": "Invoke",
|
||||
"cancel": "Cancel",
|
||||
"promptPlaceholder": "Type prompt here. [negative tokens], (upweight)++, (downweight)--, swap and blend are available (see docs)",
|
||||
"negativePrompts": "Negative Prompts",
|
||||
"sendTo": "Send to",
|
||||
"sendToImg2Img": "Send to Image to Image",
|
||||
"sendToUnifiedCanvas": "Send To Unified Canvas",
|
||||
|
||||
@@ -1 +1,62 @@
|
||||
{}
|
||||
{
|
||||
"images": "Images",
|
||||
"steps": "Etapes",
|
||||
"cfgScale": "CFG Echelle",
|
||||
"width": "Largeur",
|
||||
"height": "Hauteur",
|
||||
"sampler": "Echantillonneur",
|
||||
"seed": "Graine",
|
||||
"randomizeSeed": "Graine Aléatoire",
|
||||
"shuffle": "Mélanger",
|
||||
"noiseThreshold": "Seuil de Bruit",
|
||||
"perlinNoise": "Bruit de Perlin",
|
||||
"variations": "Variations",
|
||||
"variationAmount": "Montant de Variation",
|
||||
"seedWeights": "Poids des Graines",
|
||||
"faceRestoration": "Restauration de Visage",
|
||||
"restoreFaces": "Restaurer les Visages",
|
||||
"type": "Type",
|
||||
"strength": "Force",
|
||||
"upscaling": "Agrandissement",
|
||||
"upscale": "Agrandir",
|
||||
"upscaleImage": "Image en Agrandissement",
|
||||
"scale": "Echelle",
|
||||
"otherOptions": "Autres Options",
|
||||
"seamlessTiling": "Carreau Sans Joint",
|
||||
"hiresOptim": "Optimisation Haute Résolution",
|
||||
"imageFit": "Ajuster Image Initiale à la Taille de Sortie",
|
||||
"codeformerFidelity": "Fidélité",
|
||||
"seamSize": "Taille des Joints",
|
||||
"seamBlur": "Flou des Joints",
|
||||
"seamStrength": "Force des Joints",
|
||||
"seamSteps": "Etapes des Joints",
|
||||
"scaleBeforeProcessing": "Echelle Avant Traitement",
|
||||
"scaledWidth": "Larg. Échelle",
|
||||
"scaledHeight": "Haut. Échelle",
|
||||
"infillMethod": "Méthode de Remplissage",
|
||||
"tileSize": "Taille des Tuiles",
|
||||
"boundingBoxHeader": "Boîte Englobante",
|
||||
"seamCorrectionHeader": "Correction des Joints",
|
||||
"infillScalingHeader": "Remplissage et Mise à l'Échelle",
|
||||
"img2imgStrength": "Force de l'Image à l'Image",
|
||||
"toggleLoopback": "Activer/Désactiver la Boucle",
|
||||
"invoke": "Invoker",
|
||||
"cancel": "Annuler",
|
||||
"promptPlaceholder": "Tapez le prompt ici. [tokens négatifs], (poids positif)++, (poids négatif)--, swap et blend sont disponibles (voir les docs)",
|
||||
"sendTo": "Envoyer à",
|
||||
"sendToImg2Img": "Envoyer à Image à Image",
|
||||
"sendToUnifiedCanvas": "Envoyer au Canvas Unifié",
|
||||
"copyImage": "Copier Image",
|
||||
"copyImageToLink": "Copier l'Image en Lien",
|
||||
"downloadImage": "Télécharger Image",
|
||||
"openInViewer": "Ouvrir dans le visualiseur",
|
||||
"closeViewer": "Fermer le visualiseur",
|
||||
"usePrompt": "Utiliser la suggestion",
|
||||
"useSeed": "Utiliser la graine",
|
||||
"useAll": "Tout utiliser",
|
||||
"useInitImg": "Utiliser l'image initiale",
|
||||
"info": "Info",
|
||||
"deleteImage": "Supprimer l'image",
|
||||
"initialImage": "Image initiale",
|
||||
"showOptionsPanel": "Afficher le panneau d'options"
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
"infillScalingHeader": "Riempimento e ridimensionamento",
|
||||
"img2imgStrength": "Forza da Immagine a Immagine",
|
||||
"toggleLoopback": "Attiva/disattiva elaborazione ricorsiva",
|
||||
"invoke": "Invoca",
|
||||
"invoke": "Invoke",
|
||||
"cancel": "Annulla",
|
||||
"promptPlaceholder": "Digita qui il prompt usando termini in lingua inglese. [token negativi], (aumenta il peso)++, (diminuisci il peso)--, scambia e fondi sono disponibili (consulta la documentazione)",
|
||||
"sendTo": "Invia a",
|
||||
|
||||
62
invokeai/frontend/public/locales/options/ua.json
Normal file
62
invokeai/frontend/public/locales/options/ua.json
Normal file
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"images": "Зображення",
|
||||
"steps": "Кроки",
|
||||
"cfgScale": "Рівень CFG",
|
||||
"width": "Ширина",
|
||||
"height": "Висота",
|
||||
"sampler": "Семплер",
|
||||
"seed": "Сід",
|
||||
"randomizeSeed": "Випадковий сид",
|
||||
"shuffle": "Оновити",
|
||||
"noiseThreshold": "Поріг шуму",
|
||||
"perlinNoise": "Шум Перліна",
|
||||
"variations": "Варіації",
|
||||
"variationAmount": "Кількість варіацій",
|
||||
"seedWeights": "Вага сіду",
|
||||
"faceRestoration": "Відновлення облич",
|
||||
"restoreFaces": "Відновити обличчя",
|
||||
"type": "Тип",
|
||||
"strength": "Сила",
|
||||
"upscaling": "Збільшення",
|
||||
"upscale": "Збільшити",
|
||||
"upscaleImage": "Збільшити зображення",
|
||||
"scale": "Масштаб",
|
||||
"otherOptions": "інші параметри",
|
||||
"seamlessTiling": "Безшовний узор",
|
||||
"hiresOptim": "Висока роздільна здатність",
|
||||
"imageFit": "Вмістити зображення",
|
||||
"codeformerFidelity": "Точність",
|
||||
"seamSize": "Размір шву",
|
||||
"seamBlur": "Розмиття шву",
|
||||
"seamStrength": "Сила шву",
|
||||
"seamSteps": "Кроки шву",
|
||||
"inpaintReplace": "Inpaint-заміна",
|
||||
"scaleBeforeProcessing": "Масштабувати",
|
||||
"scaledWidth": "Масштаб Ш",
|
||||
"scaledHeight": "Масштаб В",
|
||||
"infillMethod": "Засіб заповнення",
|
||||
"tileSize": "Розмір області",
|
||||
"boundingBoxHeader": "Обмежуюча рамка",
|
||||
"seamCorrectionHeader": "Налаштування шву",
|
||||
"infillScalingHeader": "Заповнення і масштабування",
|
||||
"img2imgStrength": "Сила обробки img2img",
|
||||
"toggleLoopback": "Зациклити обробку",
|
||||
"invoke": "Викликати",
|
||||
"cancel": "Скасувати",
|
||||
"promptPlaceholder": "Введіть запит тут (англійською). [видалені токени], (більш вагомі)++, (менш вагомі)--, swap и blend також доступні (дивіться Github)",
|
||||
"sendTo": "Надіслати",
|
||||
"sendToImg2Img": "Надіслати у img2img",
|
||||
"sendToUnifiedCanvas": "Надіслати на полотно",
|
||||
"copyImageToLink": "Скопіювати посилання",
|
||||
"downloadImage": "Завантажити",
|
||||
"openInViewer": "Відкрити у переглядачі",
|
||||
"closeViewer": "Закрити переглядач",
|
||||
"usePrompt": "Використати запит",
|
||||
"useSeed": "Використати сід",
|
||||
"useAll": "Використати все",
|
||||
"useInitImg": "Використати як початкове",
|
||||
"info": "Метадані",
|
||||
"deleteImage": "Видалити зображення",
|
||||
"initialImage": "Початкове зображення",
|
||||
"showOptionsPanel": "Показати панель налаштувань"
|
||||
}
|
||||
@@ -1 +1,13 @@
|
||||
{}
|
||||
{
|
||||
"models": "Modèles",
|
||||
"displayInProgress": "Afficher les images en cours",
|
||||
"saveSteps": "Enregistrer les images tous les n étapes",
|
||||
"confirmOnDelete": "Confirmer la suppression",
|
||||
"displayHelpIcons": "Afficher les icônes d'aide",
|
||||
"useCanvasBeta": "Utiliser la mise en page bêta de Canvas",
|
||||
"enableImageDebugging": "Activer le débogage d'image",
|
||||
"resetWebUI": "Réinitialiser l'interface Web",
|
||||
"resetWebUIDesc1": "Réinitialiser l'interface Web ne réinitialise que le cache local du navigateur de vos images et de vos paramètres enregistrés. Cela n'efface pas les images du disque.",
|
||||
"resetWebUIDesc2": "Si les images ne s'affichent pas dans la galerie ou si quelque chose d'autre ne fonctionne pas, veuillez essayer de réinitialiser avant de soumettre une demande sur GitHub.",
|
||||
"resetComplete": "L'interface Web a été réinitialisée. Rafraîchissez la page pour recharger."
|
||||
}
|
||||
|
||||
13
invokeai/frontend/public/locales/settings/ua.json
Normal file
13
invokeai/frontend/public/locales/settings/ua.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"models": "Моделі",
|
||||
"displayInProgress": "Показувати процес генерації",
|
||||
"saveSteps": "Зберігати кожні n кроків",
|
||||
"confirmOnDelete": "Підтверджувати видалення",
|
||||
"displayHelpIcons": "Показувати значки підказок",
|
||||
"useCanvasBeta": "Показувати інструменты зліва (Beta UI)",
|
||||
"enableImageDebugging": "Увімкнути налагодження",
|
||||
"resetWebUI": "Повернути початкові",
|
||||
"resetWebUIDesc1": "Скидання настройок веб-інтерфейсу видаляє лише локальний кеш браузера з вашими зображеннями та налаштуваннями. Це не призводить до видалення зображень з диску.",
|
||||
"resetWebUIDesc2": "Якщо зображення не відображаються в галереї або не працює ще щось, спробуйте скинути налаштування, перш ніж повідомляти про проблему на GitHub.",
|
||||
"resetComplete": "Інтерфейс скинуто. Оновіть цю сторінку."
|
||||
}
|
||||
@@ -1 +1,32 @@
|
||||
{}
|
||||
{
|
||||
"tempFoldersEmptied": "Dossiers temporaires vidés",
|
||||
"uploadFailed": "Téléchargement échoué",
|
||||
"uploadFailedMultipleImagesDesc": "Plusieurs images collées, peut uniquement télécharger une image à la fois",
|
||||
"uploadFailedUnableToLoadDesc": "Impossible de charger le fichier",
|
||||
"downloadImageStarted": "Téléchargement de l'image démarré",
|
||||
"imageCopied": "Image copiée",
|
||||
"imageLinkCopied": "Lien d'image copié",
|
||||
"imageNotLoaded": "Aucune image chargée",
|
||||
"imageNotLoadedDesc": "Aucune image trouvée pour envoyer à module d'image",
|
||||
"imageSavedToGallery": "Image enregistrée dans la galerie",
|
||||
"canvasMerged": "Canvas fusionné",
|
||||
"sentToImageToImage": "Envoyé à Image à Image",
|
||||
"sentToUnifiedCanvas": "Envoyé à Canvas unifié",
|
||||
"parametersSet": "Paramètres définis",
|
||||
"parametersNotSet": "Paramètres non définis",
|
||||
"parametersNotSetDesc": "Aucune métadonnée trouvée pour cette image.",
|
||||
"parametersFailed": "Problème de chargement des paramètres",
|
||||
"parametersFailedDesc": "Impossible de charger l'image d'initiation.",
|
||||
"seedSet": "Graine définie",
|
||||
"seedNotSet": "Graine non définie",
|
||||
"seedNotSetDesc": "Impossible de trouver la graine pour cette image.",
|
||||
"promptSet": "Invite définie",
|
||||
"promptNotSet": "Invite non définie",
|
||||
"promptNotSetDesc": "Impossible de trouver l'invite pour cette image.",
|
||||
"upscalingFailed": "Échec de la mise à l'échelle",
|
||||
"faceRestoreFailed": "Échec de la restauration du visage",
|
||||
"metadataLoadFailed": "Échec du chargement des métadonnées",
|
||||
"initialImageSet": "Image initiale définie",
|
||||
"initialImageNotSet": "Image initiale non définie",
|
||||
"initialImageNotSetDesc": "Impossible de charger l'image initiale"
|
||||
}
|
||||
|
||||
32
invokeai/frontend/public/locales/toast/ua.json
Normal file
32
invokeai/frontend/public/locales/toast/ua.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"tempFoldersEmptied": "Тимчасова папка очищена",
|
||||
"uploadFailed": "Не вдалося завантажити",
|
||||
"uploadFailedMultipleImagesDesc": "Можна вставити лише одне зображення (ви спробували вставити декілька)",
|
||||
"uploadFailedUnableToLoadDesc": "Неможливо завантажити файл",
|
||||
"downloadImageStarted": "Завантаження зображення почалося",
|
||||
"imageCopied": "Зображення скопійоване",
|
||||
"imageLinkCopied": "Посилання на зображення скопійовано",
|
||||
"imageNotLoaded": "Зображення не завантажено",
|
||||
"imageNotLoadedDesc": "Не знайдено зображення для надсилання до img2img",
|
||||
"imageSavedToGallery": "Зображення збережено в галерею",
|
||||
"canvasMerged": "Полотно об'єднане",
|
||||
"sentToImageToImage": "Надіслати до img2img",
|
||||
"sentToUnifiedCanvas": "Надіслати на полотно",
|
||||
"parametersSet": "Параметри задані",
|
||||
"parametersNotSet": "Параметри не задані",
|
||||
"parametersNotSetDesc": "Не знайдені метадані цього зображення",
|
||||
"parametersFailed": "Проблема із завантаженням параметрів",
|
||||
"parametersFailedDesc": "Неможливо завантажити початкове зображення",
|
||||
"seedSet": "Сід заданий",
|
||||
"seedNotSet": "Сід не заданий",
|
||||
"seedNotSetDesc": "Не вдалося знайти сід для зображення",
|
||||
"promptSet": "Запит заданий",
|
||||
"promptNotSet": "Запит не заданий",
|
||||
"promptNotSetDesc": "Не вдалося знайти запит для зображення",
|
||||
"upscalingFailed": "Збільшення не вдалося",
|
||||
"faceRestoreFailed": "Відновлення облич не вдалося",
|
||||
"metadataLoadFailed": "Не вдалося завантажити метадані",
|
||||
"initialImageSet": "Початкове зображення задане",
|
||||
"initialImageNotSet": "Початкове зображення не задане",
|
||||
"initialImageNotSetDesc": "Не вдалося завантажити початкове зображення"
|
||||
}
|
||||
15
invokeai/frontend/public/locales/tooltip/fr.json
Normal file
15
invokeai/frontend/public/locales/tooltip/fr.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"feature": {
|
||||
"prompt": "Ceci est le champ prompt. Le prompt inclut des objets de génération et des termes stylistiques. Vous pouvez également ajouter un poids (importance du jeton) dans le prompt, mais les commandes CLI et les paramètres ne fonctionneront pas.",
|
||||
"gallery": "La galerie affiche les générations à partir du dossier de sortie à mesure qu'elles sont créées. Les paramètres sont stockés dans des fichiers et accessibles via le menu contextuel.",
|
||||
"other": "Ces options activent des modes de traitement alternatifs pour Invoke. 'Tuilage seamless' créera des motifs répétitifs dans la sortie. 'Haute résolution' est la génération en deux étapes avec img2img: utilisez ce paramètre lorsque vous souhaitez une image plus grande et plus cohérente sans artefacts. Cela prendra plus de temps que d'habitude txt2img.",
|
||||
"seed": "La valeur de grain affecte le bruit initial à partir duquel l'image est formée. Vous pouvez utiliser les graines déjà existantes provenant d'images précédentes. 'Seuil de bruit' est utilisé pour atténuer les artefacts à des valeurs CFG élevées (essayez la plage de 0 à 10), et Perlin pour ajouter du bruit Perlin pendant la génération: les deux servent à ajouter de la variété à vos sorties.",
|
||||
"variations": "Essayez une variation avec une valeur comprise entre 0,1 et 1,0 pour changer le résultat pour une graine donnée. Des variations intéressantes de la graine sont entre 0,1 et 0,3.",
|
||||
"upscale": "Utilisez ESRGAN pour agrandir l'image immédiatement après la génération.",
|
||||
"faceCorrection": "Correction de visage avec GFPGAN ou Codeformer: l'algorithme détecte les visages dans l'image et corrige tout défaut. La valeur élevée changera plus l'image, ce qui donnera des visages plus attirants. Codeformer avec une fidélité plus élevée préserve l'image originale au prix d'une correction de visage plus forte.",
|
||||
"imageToImage": "Image to Image charge n'importe quelle image en tant qu'initiale, qui est ensuite utilisée pour générer une nouvelle avec le prompt. Plus la valeur est élevée, plus l'image de résultat changera. Des valeurs de 0,0 à 1,0 sont possibles, la plage recommandée est de 0,25 à 0,75",
|
||||
"boundingBox": "La boîte englobante est la même que les paramètres Largeur et Hauteur pour Texte à Image ou Image à Image. Seulement la zone dans la boîte sera traitée.",
|
||||
"seamCorrection": "Contrôle la gestion des coutures visibles qui se produisent entre les images générées sur la toile.",
|
||||
"infillAndScaling": "Gérer les méthodes de remplissage (utilisées sur les zones masquées ou effacées de la toile) et le redimensionnement (utile pour les petites tailles de boîte englobante)."
|
||||
}
|
||||
}
|
||||
15
invokeai/frontend/public/locales/tooltip/ua.json
Normal file
15
invokeai/frontend/public/locales/tooltip/ua.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"feature": {
|
||||
"prompt": "Це поле для тексту запиту, включаючи об'єкти генерації та стилістичні терміни. У запит можна включити і коефіцієнти ваги (значущості токена), але консольні команди та параметри не працюватимуть.",
|
||||
"gallery": "Тут відображаються генерації з папки outputs у міру їх появи.",
|
||||
"other": "Ці опції включають альтернативні режими обробки для Invoke. 'Безшовний узор' створить на виході узори, що повторюються. 'Висока роздільна здатність' - це генерація у два етапи за допомогою img2img: використовуйте це налаштування, коли хочете отримати цільне зображення більшого розміру без артефактів.",
|
||||
"seed": "Значення сіду впливає на початковий шум, з якого сформується зображення. Можна використовувати вже наявний сід із попередніх зображень. 'Поріг шуму' використовується для пом'якшення артефактів при високих значеннях CFG (спробуйте в діапазоні 0-10), а 'Перлін' - для додавання шуму Перліна в процесі генерації: обидва параметри служать для більшої варіативності результатів.",
|
||||
"variations": "Спробуйте варіацію зі значенням від 0.1 до 1.0, щоб змінити результат для заданого сиду. Цікаві варіації сиду знаходяться між 0.1 і 0.3.",
|
||||
"upscale": "Використовуйте ESRGAN, щоб збільшити зображення відразу після генерації.",
|
||||
"faceCorrection": "Корекція облич за допомогою GFPGAN або Codeformer: алгоритм визначає обличчя у готовому зображенні та виправляє будь-які дефекти. Високі значення сили змінюють зображення сильніше, в результаті обличчя будуть виглядати привабливіше. У Codeformer більш висока точність збереже вихідне зображення на шкоду корекції обличчя.",
|
||||
"imageToImage": "'Зображення до зображення' завантажує будь-яке зображення, яке потім використовується для генерації разом із запитом. Чим більше значення, тим сильніше зміниться зображення в результаті. Можливі значення від 0 до 1, рекомендується діапазон 0.25-0.75",
|
||||
"boundingBox": "'Обмежуюча рамка' аналогічна налаштуванням 'Ширина' і 'Висота' для 'Зображення з тексту' або 'Зображення до зображення'. Буде оброблена тільки область у рамці.",
|
||||
"seamCorrection": "Керування обробкою видимих швів, що виникають між зображеннями на полотні.",
|
||||
"infillAndScaling": "Керування методами заповнення (використовується для масок або стертих частин полотна) та масштабування (корисно для малих розмірів обмежуючої рамки)."
|
||||
}
|
||||
}
|
||||
@@ -1 +1,59 @@
|
||||
{}
|
||||
{
|
||||
"layer": "Couche",
|
||||
"base": "Base",
|
||||
"mask": "Masque",
|
||||
"maskingOptions": "Options de masquage",
|
||||
"enableMask": "Activer le masque",
|
||||
"preserveMaskedArea": "Préserver la zone masquée",
|
||||
"clearMask": "Effacer le masque",
|
||||
"brush": "Pinceau",
|
||||
"eraser": "Gomme",
|
||||
"fillBoundingBox": "Remplir la boîte englobante",
|
||||
"eraseBoundingBox": "Effacer la boîte englobante",
|
||||
"colorPicker": "Sélecteur de couleur",
|
||||
"brushOptions": "Options de pinceau",
|
||||
"brushSize": "Taille",
|
||||
"move": "Déplacer",
|
||||
"resetView": "Réinitialiser la vue",
|
||||
"mergeVisible": "Fusionner les visibles",
|
||||
"saveToGallery": "Enregistrer dans la galerie",
|
||||
"copyToClipboard": "Copier dans le presse-papiers",
|
||||
"downloadAsImage": "Télécharger en tant qu'image",
|
||||
"undo": "Annuler",
|
||||
"redo": "Refaire",
|
||||
"clearCanvas": "Effacer le canvas",
|
||||
"canvasSettings": "Paramètres du canvas",
|
||||
"showIntermediates": "Afficher les intermédiaires",
|
||||
"showGrid": "Afficher la grille",
|
||||
"snapToGrid": "Aligner sur la grille",
|
||||
"darkenOutsideSelection": "Assombrir à l'extérieur de la sélection",
|
||||
"autoSaveToGallery": "Enregistrement automatique dans la galerie",
|
||||
"saveBoxRegionOnly": "Enregistrer uniquement la région de la boîte",
|
||||
"limitStrokesToBox": "Limiter les traits à la boîte",
|
||||
"showCanvasDebugInfo": "Afficher les informations de débogage du canvas",
|
||||
"clearCanvasHistory": "Effacer l'historique du canvas",
|
||||
"clearHistory": "Effacer l'historique",
|
||||
"clearCanvasHistoryMessage": "Effacer l'historique du canvas laisse votre canvas actuel intact, mais efface de manière irréversible l'historique annuler et refaire.",
|
||||
"clearCanvasHistoryConfirm": "Êtes-vous sûr de vouloir effacer l'historique du canvas?",
|
||||
"emptyTempImageFolder": "Vider le dossier d'images temporaires",
|
||||
"emptyFolder": "Vider le dossier",
|
||||
"emptyTempImagesFolderMessage": "Vider le dossier d'images temporaires réinitialise également complètement le canvas unifié. Cela inclut tout l'historique annuler/refaire, les images dans la zone de mise en attente et la couche de base du canvas.",
|
||||
"emptyTempImagesFolderConfirm": "Êtes-vous sûr de vouloir vider le dossier temporaire?",
|
||||
"activeLayer": "Calque actif",
|
||||
"canvasScale": "Échelle du canevas",
|
||||
"boundingBox": "Boîte englobante",
|
||||
"scaledBoundingBox": "Boîte englobante mise à l'échelle",
|
||||
"boundingBoxPosition": "Position de la boîte englobante",
|
||||
"canvasDimensions": "Dimensions du canevas",
|
||||
"canvasPosition": "Position du canevas",
|
||||
"cursorPosition": "Position du curseur",
|
||||
"previous": "Précédent",
|
||||
"next": "Suivant",
|
||||
"accept": "Accepter",
|
||||
"showHide": "Afficher/Masquer",
|
||||
"discardAll": "Tout abandonner",
|
||||
"betaClear": "Effacer",
|
||||
"betaDarkenOutside": "Assombrir à l'extérieur",
|
||||
"betaLimitToBox": "Limiter à la boîte",
|
||||
"betaPreserveMasked": "Conserver masqué"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"layer": "Layer",
|
||||
"layer": "Livello",
|
||||
"base": "Base",
|
||||
"mask": "Maschera",
|
||||
"maskingOptions": "Opzioni di mascheramento",
|
||||
|
||||
59
invokeai/frontend/public/locales/unifiedcanvas/ua.json
Normal file
59
invokeai/frontend/public/locales/unifiedcanvas/ua.json
Normal file
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"layer": "Шар",
|
||||
"base": "Базовий",
|
||||
"mask": "Маска",
|
||||
"maskingOptions": "Параметри маски",
|
||||
"enableMask": "Увiмкнути маску",
|
||||
"preserveMaskedArea": "Зберiгати замасковану область",
|
||||
"clearMask": "Очистити маску",
|
||||
"brush": "Пензель",
|
||||
"eraser": "Гумка",
|
||||
"fillBoundingBox": "Заповнити обмежуючу рамку",
|
||||
"eraseBoundingBox": "Стерти обмежуючу рамку",
|
||||
"colorPicker": "Пiпетка",
|
||||
"brushOptions": "Параметри пензля",
|
||||
"brushSize": "Розмiр",
|
||||
"move": "Перемiстити",
|
||||
"resetView": "Скинути вигляд",
|
||||
"mergeVisible": "Об'єднати видимi",
|
||||
"saveToGallery": "Зберегти до галереї",
|
||||
"copyToClipboard": "Копiювати до буферу обмiну",
|
||||
"downloadAsImage": "Завантажити як зображення",
|
||||
"undo": "Вiдмiнити",
|
||||
"redo": "Повторити",
|
||||
"clearCanvas": "Очистити полотно",
|
||||
"canvasSettings": "Налаштування полотна",
|
||||
"showIntermediates": "Показувати процес",
|
||||
"showGrid": "Показувати сiтку",
|
||||
"snapToGrid": "Прив'язати до сітки",
|
||||
"darkenOutsideSelection": "Затемнити полотно зовні",
|
||||
"autoSaveToGallery": "Автозбереження до галереї",
|
||||
"saveBoxRegionOnly": "Зберiгати тiльки видiлення",
|
||||
"limitStrokesToBox": "Обмежити штрихи виділенням",
|
||||
"showCanvasDebugInfo": "Показати налаштування полотна",
|
||||
"clearCanvasHistory": "Очистити iсторiю полотна",
|
||||
"clearHistory": "Очистити iсторiю",
|
||||
"clearCanvasHistoryMessage": "Очищення історії полотна залишає поточне полотно незайманим, але видаляє історію скасування та повтору",
|
||||
"clearCanvasHistoryConfirm": "Ви впевнені, що хочете очистити історію полотна?",
|
||||
"emptyTempImageFolder": "Очистити тимчасову папку",
|
||||
"emptyFolder": "Очистити папку",
|
||||
"emptyTempImagesFolderMessage": "Очищення папки тимчасових зображень також повністю скидає полотно, включаючи всю історію скасування/повтору, зображення та базовий шар полотна, що розміщуються.",
|
||||
"emptyTempImagesFolderConfirm": "Ви впевнені, що хочете очистити тимчасову папку?",
|
||||
"activeLayer": "Активний шар",
|
||||
"canvasScale": "Масштаб полотна",
|
||||
"boundingBox": "Обмежуюча рамка",
|
||||
"scaledBoundingBox": "Масштабування рамки",
|
||||
"boundingBoxPosition": "Позиція обмежуючої рамки",
|
||||
"canvasDimensions": "Разміри полотна",
|
||||
"canvasPosition": "Розташування полотна",
|
||||
"cursorPosition": "Розташування курсора",
|
||||
"previous": "Попереднє",
|
||||
"next": "Наступне",
|
||||
"принять": "Приняти",
|
||||
"showHide": "Показати/Сховати",
|
||||
"discardAll": "Відмінити все",
|
||||
"betaClear": "Очистити",
|
||||
"betaDarkenOutside": "Затемнити зовні",
|
||||
"betaLimitToBox": "Обмежити виділенням",
|
||||
"betaPreserveMasked": "Зберiгати замасковану область"
|
||||
}
|
||||
@@ -11,7 +11,6 @@ const useClickOutsideWatcher = () => {
|
||||
function handleClickOutside(e: MouseEvent) {
|
||||
watchers.forEach(({ ref, enable, callback }) => {
|
||||
if (enable && ref.current && !ref.current.contains(e.target as Node)) {
|
||||
console.log('callback');
|
||||
callback();
|
||||
}
|
||||
});
|
||||
|
||||
20
invokeai/frontend/src/common/util/getPromptAndNegative.ts
Normal file
20
invokeai/frontend/src/common/util/getPromptAndNegative.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import * as InvokeAI from 'app/invokeai';
|
||||
import promptToString from './promptToString';
|
||||
|
||||
export function getPromptAndNegative(input_prompt: InvokeAI.Prompt) {
|
||||
let prompt: string = promptToString(input_prompt);
|
||||
let negativePrompt: string | null = null;
|
||||
|
||||
const negativePromptRegExp = new RegExp(/(?<=\[)[^\][]*(?=])/, 'gi');
|
||||
const negativePromptMatches = [...prompt.matchAll(negativePromptRegExp)];
|
||||
|
||||
if (negativePromptMatches && negativePromptMatches.length > 0) {
|
||||
negativePrompt = negativePromptMatches.join(', ');
|
||||
prompt = prompt
|
||||
.replaceAll(negativePromptRegExp, '')
|
||||
.replaceAll('[]', '')
|
||||
.trim();
|
||||
}
|
||||
|
||||
return [prompt, negativePrompt];
|
||||
}
|
||||
@@ -106,6 +106,7 @@ export const frontendToBackendParameters = (
|
||||
iterations,
|
||||
perlin,
|
||||
prompt,
|
||||
negativePrompt,
|
||||
sampler,
|
||||
seamBlur,
|
||||
seamless,
|
||||
@@ -155,6 +156,10 @@ export const frontendToBackendParameters = (
|
||||
let esrganParameters: false | BackendEsrGanParameters = false;
|
||||
let facetoolParameters: false | BackendFacetoolParameters = false;
|
||||
|
||||
if (negativePrompt !== '') {
|
||||
generationParameters.prompt = `${prompt} [${negativePrompt}]`;
|
||||
}
|
||||
|
||||
generationParameters.seed = shouldRandomizeSeed
|
||||
? randomInt(NUMPY_RAND_MIN, NUMPY_RAND_MAX)
|
||||
: seed;
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
setAllParameters,
|
||||
setInitialImage,
|
||||
setIsLightBoxOpen,
|
||||
setNegativePrompt,
|
||||
setPrompt,
|
||||
setSeed,
|
||||
setShouldShowImageDetails,
|
||||
@@ -44,6 +45,7 @@ import { GalleryState } from 'features/gallery/store/gallerySlice';
|
||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
||||
import IAIPopover from 'common/components/IAIPopover';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getPromptAndNegative } from 'common/util/getPromptAndNegative';
|
||||
|
||||
const systemSelector = createSelector(
|
||||
[
|
||||
@@ -241,9 +243,18 @@ const CurrentImageButtons = () => {
|
||||
[currentImage]
|
||||
);
|
||||
|
||||
const handleClickUsePrompt = () =>
|
||||
currentImage?.metadata?.image?.prompt &&
|
||||
dispatch(setPrompt(currentImage.metadata.image.prompt));
|
||||
const handleClickUsePrompt = () => {
|
||||
if (currentImage?.metadata?.image?.prompt) {
|
||||
const [prompt, negativePrompt] = getPromptAndNegative(
|
||||
currentImage?.metadata?.image?.prompt
|
||||
);
|
||||
|
||||
prompt && dispatch(setPrompt(prompt));
|
||||
negativePrompt
|
||||
? dispatch(setNegativePrompt(negativePrompt))
|
||||
: dispatch(setNegativePrompt(''));
|
||||
}
|
||||
};
|
||||
|
||||
useHotkeys(
|
||||
'p',
|
||||
|
||||
@@ -10,9 +10,10 @@ import { DragEvent, memo, useState } from 'react';
|
||||
import {
|
||||
setActiveTab,
|
||||
setAllImageToImageParameters,
|
||||
setAllTextToImageParameters,
|
||||
setAllParameters,
|
||||
setInitialImage,
|
||||
setIsLightBoxOpen,
|
||||
setNegativePrompt,
|
||||
setPrompt,
|
||||
setSeed,
|
||||
} from 'features/options/store/optionsSlice';
|
||||
@@ -24,6 +25,7 @@ import {
|
||||
} from 'features/canvas/store/canvasSlice';
|
||||
import { hoverableImageSelector } from 'features/gallery/store/gallerySliceSelectors';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getPromptAndNegative } from 'common/util/getPromptAndNegative';
|
||||
|
||||
interface HoverableImageProps {
|
||||
image: InvokeAI.Image;
|
||||
@@ -62,7 +64,17 @@ const HoverableImage = memo((props: HoverableImageProps) => {
|
||||
const handleMouseOut = () => setIsHovered(false);
|
||||
|
||||
const handleUsePrompt = () => {
|
||||
image.metadata && dispatch(setPrompt(image.metadata.image.prompt));
|
||||
if (image.metadata) {
|
||||
const [prompt, negativePrompt] = getPromptAndNegative(
|
||||
image.metadata?.image?.prompt
|
||||
);
|
||||
|
||||
prompt && dispatch(setPrompt(prompt));
|
||||
negativePrompt
|
||||
? dispatch(setNegativePrompt(negativePrompt))
|
||||
: dispatch(setNegativePrompt(''));
|
||||
}
|
||||
|
||||
toast({
|
||||
title: t('toast:promptSet'),
|
||||
status: 'success',
|
||||
@@ -115,7 +127,7 @@ const HoverableImage = memo((props: HoverableImageProps) => {
|
||||
};
|
||||
|
||||
const handleUseAllParameters = () => {
|
||||
metadata && dispatch(setAllTextToImageParameters(metadata));
|
||||
metadata && dispatch(setAllParameters(metadata));
|
||||
toast({
|
||||
title: t('toast:parametersSet'),
|
||||
status: 'success',
|
||||
|
||||
@@ -38,7 +38,6 @@ export const uploadImage =
|
||||
});
|
||||
|
||||
const image = (await response.json()) as InvokeAI.ImageUploadResponse;
|
||||
console.log(image);
|
||||
const newImage: InvokeAI.Image = {
|
||||
uuid: uuidv4(),
|
||||
category: 'user',
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { FormControl, Textarea } from '@chakra-ui/react';
|
||||
import type { RootState } from 'app/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import { setNegativePrompt } from 'features/options/store/optionsSlice';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export function NegativePromptInput() {
|
||||
const negativePrompt = useAppSelector(
|
||||
(state: RootState) => state.options.negativePrompt
|
||||
);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<FormControl>
|
||||
<Textarea
|
||||
id="negativePrompt"
|
||||
name="negativePrompt"
|
||||
value={negativePrompt}
|
||||
onChange={(e) => dispatch(setNegativePrompt(e.target.value))}
|
||||
background="var(--prompt-bg-color)"
|
||||
placeholder={t('options:negativePrompts')}
|
||||
_placeholder={{ fontSize: '0.8rem' }}
|
||||
borderColor="var(--border-color)"
|
||||
_hover={{
|
||||
borderColor: 'var(--border-color-light)',
|
||||
}}
|
||||
_focusVisible={{
|
||||
borderColor: 'var(--border-color-invalid)',
|
||||
boxShadow: '0 0 10px var(--box-shadow-color-invalid)',
|
||||
}}
|
||||
fontSize="0.9rem"
|
||||
color="var(--text-color-secondary)"
|
||||
/>
|
||||
</FormControl>
|
||||
);
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import promptToString from 'common/util/promptToString';
|
||||
import { seedWeightsToString } from 'common/util/seedWeightPairs';
|
||||
import { FACETOOL_TYPES } from 'app/constants';
|
||||
import { InvokeTabName, tabMap } from 'features/tabs/tabMap';
|
||||
import { getPromptAndNegative } from 'common/util/getPromptAndNegative';
|
||||
|
||||
export type UpscalingLevel = 2 | 4;
|
||||
|
||||
@@ -28,6 +29,7 @@ export interface OptionsState {
|
||||
optionsPanelScrollPosition: number;
|
||||
perlin: number;
|
||||
prompt: string;
|
||||
negativePrompt: string;
|
||||
sampler: string;
|
||||
seamBlur: number;
|
||||
seamless: boolean;
|
||||
@@ -77,6 +79,7 @@ const initialOptionsState: OptionsState = {
|
||||
optionsPanelScrollPosition: 0,
|
||||
perlin: 0,
|
||||
prompt: '',
|
||||
negativePrompt: '',
|
||||
sampler: 'k_lms',
|
||||
seamBlur: 16,
|
||||
seamless: false,
|
||||
@@ -123,6 +126,17 @@ export const optionsSlice = createSlice({
|
||||
state.prompt = promptToString(newPrompt);
|
||||
}
|
||||
},
|
||||
setNegativePrompt: (
|
||||
state,
|
||||
action: PayloadAction<string | InvokeAI.Prompt>
|
||||
) => {
|
||||
const newPrompt = action.payload;
|
||||
if (typeof newPrompt === 'string') {
|
||||
state.negativePrompt = newPrompt;
|
||||
} else {
|
||||
state.negativePrompt = promptToString(newPrompt);
|
||||
}
|
||||
},
|
||||
setIterations: (state, action: PayloadAction<number>) => {
|
||||
state.iterations = action.payload;
|
||||
},
|
||||
@@ -307,7 +321,14 @@ export const optionsSlice = createSlice({
|
||||
state.shouldRandomizeSeed = false;
|
||||
}
|
||||
|
||||
if (prompt) state.prompt = promptToString(prompt);
|
||||
if (prompt) {
|
||||
const [promptOnly, negativePrompt] = getPromptAndNegative(prompt);
|
||||
if (promptOnly) state.prompt = promptOnly;
|
||||
negativePrompt
|
||||
? (state.negativePrompt = negativePrompt)
|
||||
: (state.negativePrompt = '');
|
||||
}
|
||||
|
||||
if (sampler) state.sampler = sampler;
|
||||
if (steps) state.steps = steps;
|
||||
if (cfg_scale) state.cfgScale = cfg_scale;
|
||||
@@ -448,6 +469,7 @@ export const {
|
||||
setParameter,
|
||||
setPerlin,
|
||||
setPrompt,
|
||||
setNegativePrompt,
|
||||
setSampler,
|
||||
setSeamBlur,
|
||||
setSeamless,
|
||||
|
||||
@@ -13,15 +13,17 @@ export default function LanguagePicker() {
|
||||
|
||||
const LANGUAGES = {
|
||||
en: t('common:langEnglish'),
|
||||
ru: t('common:langRussian'),
|
||||
it: t('common:langItalian'),
|
||||
pt_br: t('common:langBrPortuguese'),
|
||||
nl: t('common:langDutch'),
|
||||
fr: t('common:langFrench'),
|
||||
de: t('common:langGerman'),
|
||||
it: t('common:langItalian'),
|
||||
ja: t('common:langJapanese'),
|
||||
pl: t('common:langPolish'),
|
||||
pt_br: t('common:langBrPortuguese'),
|
||||
ru: t('common:langRussian'),
|
||||
zh_cn: t('common:langSimplifiedChinese'),
|
||||
es: t('common:langSpanish'),
|
||||
ja: t('common:langJapanese'),
|
||||
nl: t('common:langDutch'),
|
||||
ua: t('common:langUkranian'),
|
||||
};
|
||||
|
||||
const renderLanguagePicker = () => {
|
||||
|
||||
@@ -316,7 +316,6 @@ export default function CheckpointModelEdit() {
|
||||
) : (
|
||||
<Flex
|
||||
width="100%"
|
||||
height="250px"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
backgroundColor="var(--background-color)"
|
||||
|
||||
@@ -271,7 +271,6 @@ export default function DiffusersModelEdit() {
|
||||
) : (
|
||||
<Flex
|
||||
width="100%"
|
||||
height="250px"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
backgroundColor="var(--background-color)"
|
||||
|
||||
@@ -19,6 +19,8 @@ import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||
import InvokeOptionsPanel from 'features/tabs/components/InvokeOptionsPanel';
|
||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { NegativePromptInput } from 'features/options/components/PromptInput/NegativePromptInput';
|
||||
|
||||
export default function ImageToImagePanel() {
|
||||
const { t } = useTranslation();
|
||||
@@ -67,7 +69,10 @@ export default function ImageToImagePanel() {
|
||||
|
||||
return (
|
||||
<InvokeOptionsPanel>
|
||||
<PromptInput />
|
||||
<Flex flexDir="column" rowGap="0.5rem">
|
||||
<PromptInput />
|
||||
<NegativePromptInput />
|
||||
</Flex>
|
||||
<ProcessButtons />
|
||||
<MainOptions />
|
||||
<ImageToImageStrength
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
&[aria-selected='true'] {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { Feature } from 'app/features';
|
||||
import FaceRestoreOptions from 'features/options/components/AdvancedOptions/FaceRestore/FaceRestoreOptions';
|
||||
import FaceRestoreToggle from 'features/options/components/AdvancedOptions/FaceRestore/FaceRestoreToggle';
|
||||
@@ -10,6 +11,7 @@ import VariationsOptions from 'features/options/components/AdvancedOptions/Varia
|
||||
import MainOptions from 'features/options/components/MainOptions/MainOptions';
|
||||
import OptionsAccordion from 'features/options/components/OptionsAccordion';
|
||||
import ProcessButtons from 'features/options/components/ProcessButtons/ProcessButtons';
|
||||
import { NegativePromptInput } from 'features/options/components/PromptInput/NegativePromptInput';
|
||||
import PromptInput from 'features/options/components/PromptInput/PromptInput';
|
||||
import InvokeOptionsPanel from 'features/tabs/components/InvokeOptionsPanel';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -50,7 +52,10 @@ export default function TextToImagePanel() {
|
||||
|
||||
return (
|
||||
<InvokeOptionsPanel>
|
||||
<PromptInput />
|
||||
<Flex flexDir="column" rowGap="0.5rem">
|
||||
<PromptInput />
|
||||
<NegativePromptInput />
|
||||
</Flex>
|
||||
<ProcessButtons />
|
||||
<MainOptions />
|
||||
<OptionsAccordion accordionInfo={textToImageAccordions} />
|
||||
|
||||
@@ -13,6 +13,8 @@ import InvokeOptionsPanel from 'features/tabs/components/InvokeOptionsPanel';
|
||||
import BoundingBoxSettings from 'features/options/components/AdvancedOptions/Canvas/BoundingBoxSettings/BoundingBoxSettings';
|
||||
import InfillAndScalingOptions from 'features/options/components/AdvancedOptions/Canvas/InfillAndScalingOptions';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { NegativePromptInput } from 'features/options/components/PromptInput/NegativePromptInput';
|
||||
|
||||
export default function UnifiedCanvasPanel() {
|
||||
const { t } = useTranslation();
|
||||
@@ -48,7 +50,10 @@ export default function UnifiedCanvasPanel() {
|
||||
|
||||
return (
|
||||
<InvokeOptionsPanel>
|
||||
<PromptInput />
|
||||
<Flex flexDir="column" rowGap="0.5rem">
|
||||
<PromptInput />
|
||||
<NegativePromptInput />
|
||||
</Flex>
|
||||
<ProcessButtons />
|
||||
<MainOptions />
|
||||
<ImageToImageStrength
|
||||
|
||||
@@ -211,7 +211,7 @@ class Generate:
|
||||
print('>> xformers memory-efficient attention is available but disabled')
|
||||
else:
|
||||
print('>> xformers not installed')
|
||||
|
||||
|
||||
# model caching system for fast switching
|
||||
self.model_manager = ModelManager(mconfig,self.device,self.precision,max_loaded_models=max_loaded_models)
|
||||
# don't accept invalid models
|
||||
@@ -565,16 +565,24 @@ class Generate:
|
||||
image_callback = image_callback)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
# Clear the CUDA cache on an exception
|
||||
if self._has_cuda():
|
||||
torch.cuda.empty_cache()
|
||||
|
||||
if catch_interrupts:
|
||||
print('**Interrupted** Partial results will be returned.')
|
||||
else:
|
||||
raise KeyboardInterrupt
|
||||
except RuntimeError:
|
||||
# Clear the CUDA cache on an exception
|
||||
if self._has_cuda():
|
||||
torch.cuda.empty_cache()
|
||||
|
||||
print(traceback.format_exc(), file=sys.stderr)
|
||||
print('>> Could not generate image.')
|
||||
|
||||
toc = time.time()
|
||||
print('>> Usage stats:')
|
||||
print('\n>> Usage stats:')
|
||||
print(
|
||||
f'>> {len(results)} image(s) generated in', '%4.2fs' % (
|
||||
toc - tic)
|
||||
|
||||
@@ -4,6 +4,13 @@ import sys
|
||||
import shlex
|
||||
import traceback
|
||||
|
||||
from argparse import Namespace
|
||||
from pathlib import Path
|
||||
from typing import Optional, Union
|
||||
|
||||
if sys.platform == "darwin":
|
||||
os.environ["PYTORCH_ENABLE_MPS_FALLBACK"] = "1"
|
||||
|
||||
from ldm.invoke.globals import Globals
|
||||
from ldm.generate import Generate
|
||||
from ldm.invoke.prompt_parser import PromptParser
|
||||
@@ -13,17 +20,14 @@ from ldm.invoke.pngwriter import PngWriter, retrieve_metadata, write_metadata
|
||||
from ldm.invoke.image_util import make_grid
|
||||
from ldm.invoke.log import write_log
|
||||
from ldm.invoke.model_manager import ModelManager
|
||||
from pathlib import Path
|
||||
from argparse import Namespace
|
||||
import pyparsing
|
||||
|
||||
import click # type: ignore
|
||||
import ldm.invoke
|
||||
import pyparsing # type: ignore
|
||||
|
||||
# global used in multiple functions (fix)
|
||||
infile = None
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
os.environ["PYTORCH_ENABLE_MPS_FALLBACK"] = "1"
|
||||
|
||||
def main():
|
||||
"""Initialize command-line parsers and the diffusion model"""
|
||||
global infile
|
||||
@@ -69,8 +73,10 @@ def main():
|
||||
|
||||
# these two lines prevent a horrible warning message from appearing
|
||||
# when the frozen CLIP tokenizer is imported
|
||||
import transformers
|
||||
import transformers # type: ignore
|
||||
transformers.logging.set_verbosity_error()
|
||||
import diffusers
|
||||
diffusers.logging.set_verbosity_error()
|
||||
|
||||
# Loading Face Restoration and ESRGAN Modules
|
||||
gfpgan,codeformer,esrgan = load_face_restoration(opt)
|
||||
@@ -570,7 +576,7 @@ def set_default_output_dir(opt:Args, completer:Completer):
|
||||
completer.set_default_dir(opt.outdir)
|
||||
|
||||
|
||||
def import_model(model_path:str, gen, opt, completer):
|
||||
def import_model(model_path: str, gen, opt, completer):
|
||||
'''
|
||||
model_path can be (1) a URL to a .ckpt file; (2) a local .ckpt file path; or
|
||||
(3) a huggingface repository id
|
||||
@@ -579,12 +585,28 @@ def import_model(model_path:str, gen, opt, completer):
|
||||
|
||||
if model_path.startswith(('http:','https:','ftp:')):
|
||||
model_name = import_ckpt_model(model_path, gen, opt, completer)
|
||||
|
||||
elif os.path.exists(model_path) and model_path.endswith(('.ckpt','.safetensors')) and os.path.isfile(model_path):
|
||||
model_name = import_ckpt_model(model_path, gen, opt, completer)
|
||||
elif re.match('^[\w.+-]+/[\w.+-]+$',model_path):
|
||||
model_name = import_diffuser_model(model_path, gen, opt, completer)
|
||||
|
||||
elif os.path.isdir(model_path):
|
||||
model_name = import_diffuser_model(Path(model_path), gen, opt, completer)
|
||||
|
||||
# Allow for a directory containing multiple models.
|
||||
models = list(Path(model_path).rglob('*.ckpt')) + list(Path(model_path).rglob('*.safetensors'))
|
||||
|
||||
if models:
|
||||
# Only the last model name will be used below.
|
||||
for model in sorted(models):
|
||||
|
||||
if click.confirm(f'Import {model.stem} ?', default=True):
|
||||
model_name = import_ckpt_model(model, gen, opt, completer)
|
||||
print()
|
||||
else:
|
||||
model_name = import_diffuser_model(Path(model_path), gen, opt, completer)
|
||||
|
||||
elif re.match(r'^[\w.+-]+/[\w.+-]+$', model_path):
|
||||
model_name = import_diffuser_model(model_path, gen, opt, completer)
|
||||
|
||||
else:
|
||||
print(f'** {model_path} is neither the path to a .ckpt file nor a diffusers repository id. Can\'t import.')
|
||||
|
||||
@@ -602,7 +624,7 @@ def import_model(model_path:str, gen, opt, completer):
|
||||
completer.update_models(gen.model_manager.list_models())
|
||||
print(f'>> {model_name} successfully installed')
|
||||
|
||||
def import_diffuser_model(path_or_repo:str, gen, opt, completer)->str:
|
||||
def import_diffuser_model(path_or_repo: Union[Path, str], gen, _, completer) -> Optional[str]:
|
||||
manager = gen.model_manager
|
||||
default_name = Path(path_or_repo).stem
|
||||
default_description = f'Imported model {default_name}'
|
||||
@@ -625,7 +647,7 @@ def import_diffuser_model(path_or_repo:str, gen, opt, completer)->str:
|
||||
return None
|
||||
return model_name
|
||||
|
||||
def import_ckpt_model(path_or_url:str, gen, opt, completer)->str:
|
||||
def import_ckpt_model(path_or_url: Union[Path, str], gen, opt, completer) -> Optional[str]:
|
||||
manager = gen.model_manager
|
||||
default_name = Path(path_or_url).stem
|
||||
default_description = f'Imported model {default_name}'
|
||||
@@ -1133,8 +1155,8 @@ def report_model_error(opt:Namespace, e:Exception):
|
||||
for arg in yes_to_all.split():
|
||||
sys.argv.append(arg)
|
||||
|
||||
from ldm.invoke.config import configure_invokeai
|
||||
configure_invokeai.main()
|
||||
from ldm.invoke.config import invokeai_configure
|
||||
invokeai_configure.main()
|
||||
print('** InvokeAI will now restart')
|
||||
sys.argv = previous_args
|
||||
main() # would rather do a os.exec(), but doesn't exist?
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__='2.3.0-rc2'
|
||||
__version__='2.3.0-rc5'
|
||||
|
||||
@@ -196,6 +196,7 @@ class Args(object):
|
||||
elif os.path.exists(legacyinit):
|
||||
print(f'>> WARNING: Old initialization file found at {legacyinit}. This location is deprecated. Please move it to {Globals.root}/invokeai.init.')
|
||||
sysargs.insert(0,f'@{legacyinit}')
|
||||
Globals.log_tokenization = self._arg_parser.parse_args(sysargs).log_tokenization
|
||||
|
||||
self._arg_switches = self._arg_parser.parse_args(sysargs)
|
||||
return self._arg_switches
|
||||
@@ -599,6 +600,12 @@ class Args(object):
|
||||
help=f'Set the default sampler. Supported samplers: {", ".join(SAMPLER_CHOICES)}',
|
||||
default='k_lms',
|
||||
)
|
||||
render_group.add_argument(
|
||||
'--log_tokenization',
|
||||
'-t',
|
||||
action='store_true',
|
||||
help='shows how the prompt is split into tokens'
|
||||
)
|
||||
render_group.add_argument(
|
||||
'-f',
|
||||
'--strength',
|
||||
@@ -744,7 +751,7 @@ class Args(object):
|
||||
invoke> !fetch 0000015.8929913.png
|
||||
invoke> a fantastic alien landscape -W 576 -H 512 -s 60 -A plms -C 7.5
|
||||
invoke> !fetch /path/to/images/*.png prompts.txt
|
||||
|
||||
|
||||
!replay /path/to/prompts.txt
|
||||
Replays all the prompts contained in the file prompts.txt.
|
||||
|
||||
@@ -756,6 +763,7 @@ class Args(object):
|
||||
!models -- list models in configs/models.yaml
|
||||
!switch <model_name> -- switch to model named <model_name>
|
||||
!import_model /path/to/weights/file.ckpt -- adds a .ckpt model to your config
|
||||
!import_model /path/to/weights/ -- interactively import models from a directory
|
||||
!import_model http://path_to_model.ckpt -- downloads and adds a .ckpt model to your config
|
||||
!import_model hakurei/waifu-diffusion -- downloads and adds a diffusers model to your config
|
||||
!optimize_model <model_name> -- converts a .ckpt model to a diffusers model
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
import os
|
||||
import re
|
||||
import torch
|
||||
import warnings
|
||||
from pathlib import Path
|
||||
from ldm.invoke.globals import Globals, global_cache_dir
|
||||
from safetensors.torch import load_file
|
||||
@@ -44,6 +45,7 @@ from diffusers import (
|
||||
PNDMScheduler,
|
||||
StableDiffusionPipeline,
|
||||
UNet2DConditionModel,
|
||||
logging as dlogging,
|
||||
)
|
||||
from diffusers.pipelines.latent_diffusion.pipeline_latent_diffusion import LDMBertConfig, LDMBertModel
|
||||
from diffusers.pipelines.paint_by_example import PaintByExampleImageEncoder, PaintByExamplePipeline
|
||||
@@ -795,8 +797,9 @@ def load_pipeline_from_original_stable_diffusion_ckpt(
|
||||
prediction_type:str=None,
|
||||
extract_ema:bool=True,
|
||||
upcast_attn:bool=False,
|
||||
vae:AutoencoderKL=None
|
||||
)->StableDiffusionGeneratorPipeline:
|
||||
vae:AutoencoderKL=None,
|
||||
return_generator_pipeline:bool=False,
|
||||
)->Union[StableDiffusionPipeline,StableDiffusionGeneratorPipeline]:
|
||||
'''
|
||||
Load a Stable Diffusion pipeline object from a CompVis-style `.ckpt`/`.safetensors` file and (ideally) a `.yaml`
|
||||
config file.
|
||||
@@ -823,166 +826,173 @@ def load_pipeline_from_original_stable_diffusion_ckpt(
|
||||
:param upcast_attention: Whether the attention computation should always be upcasted. This is necessary when
|
||||
running stable diffusion 2.1.
|
||||
'''
|
||||
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore')
|
||||
verbosity = dlogging.get_verbosity()
|
||||
dlogging.set_verbosity_error()
|
||||
|
||||
checkpoint = load_file(checkpoint_path) if Path(checkpoint_path).suffix == '.safetensors' else torch.load(checkpoint_path)
|
||||
cache_dir = global_cache_dir('hub')
|
||||
checkpoint = load_file(checkpoint_path) if Path(checkpoint_path).suffix == '.safetensors' else torch.load(checkpoint_path)
|
||||
cache_dir = global_cache_dir('hub')
|
||||
pipeline_class = StableDiffusionGeneratorPipeline if return_generator_pipeline else StableDiffusionPipeline
|
||||
|
||||
# Sometimes models don't have the global_step item
|
||||
if "global_step" in checkpoint:
|
||||
global_step = checkpoint["global_step"]
|
||||
else:
|
||||
print(" | global_step key not found in model")
|
||||
global_step = None
|
||||
|
||||
# sometimes there is a state_dict key and sometimes not
|
||||
if 'state_dict' in checkpoint:
|
||||
checkpoint = checkpoint["state_dict"]
|
||||
|
||||
upcast_attention = False
|
||||
if original_config_file is None:
|
||||
key_name = "model.diffusion_model.input_blocks.2.1.transformer_blocks.0.attn2.to_k.weight"
|
||||
|
||||
if key_name in checkpoint and checkpoint[key_name].shape[-1] == 1024:
|
||||
original_config_file = os.path.join(Globals.root,'configs','stable-diffusion','v2-inference-v.yaml')
|
||||
|
||||
if global_step == 110000:
|
||||
# v2.1 needs to upcast attention
|
||||
upcast_attention = True
|
||||
# Sometimes models don't have the global_step item
|
||||
if "global_step" in checkpoint:
|
||||
global_step = checkpoint["global_step"]
|
||||
else:
|
||||
original_config_file = os.path.join(Globals.root,'configs','stable-diffusion','v1-inference.yaml')
|
||||
print(" | global_step key not found in model")
|
||||
global_step = None
|
||||
|
||||
original_config = OmegaConf.load(original_config_file)
|
||||
# sometimes there is a state_dict key and sometimes not
|
||||
if 'state_dict' in checkpoint:
|
||||
checkpoint = checkpoint["state_dict"]
|
||||
|
||||
if num_in_channels is not None:
|
||||
original_config["model"]["params"]["unet_config"]["params"]["in_channels"] = num_in_channels
|
||||
upcast_attention = False
|
||||
if original_config_file is None:
|
||||
key_name = "model.diffusion_model.input_blocks.2.1.transformer_blocks.0.attn2.to_k.weight"
|
||||
|
||||
if (
|
||||
"parameterization" in original_config["model"]["params"]
|
||||
and original_config["model"]["params"]["parameterization"] == "v"
|
||||
):
|
||||
if prediction_type is None:
|
||||
# NOTE: For stable diffusion 2 base it is recommended to pass `prediction_type=="epsilon"`
|
||||
# as it relies on a brittle global step parameter here
|
||||
prediction_type = "epsilon" if global_step == 875000 else "v_prediction"
|
||||
if image_size is None:
|
||||
# NOTE: For stable diffusion 2 base one has to pass `image_size==512`
|
||||
# as it relies on a brittle global step parameter here
|
||||
image_size = 512 if global_step == 875000 else 768
|
||||
else:
|
||||
if prediction_type is None:
|
||||
prediction_type = "epsilon"
|
||||
if image_size is None:
|
||||
image_size = 512
|
||||
if key_name in checkpoint and checkpoint[key_name].shape[-1] == 1024:
|
||||
original_config_file = os.path.join(Globals.root,'configs','stable-diffusion','v2-inference-v.yaml')
|
||||
|
||||
num_train_timesteps = original_config.model.params.timesteps
|
||||
beta_start = original_config.model.params.linear_start
|
||||
beta_end = original_config.model.params.linear_end
|
||||
if global_step == 110000:
|
||||
# v2.1 needs to upcast attention
|
||||
upcast_attention = True
|
||||
else:
|
||||
original_config_file = os.path.join(Globals.root,'configs','stable-diffusion','v1-inference.yaml')
|
||||
|
||||
scheduler = DDIMScheduler(
|
||||
beta_end=beta_end,
|
||||
beta_schedule="scaled_linear",
|
||||
beta_start=beta_start,
|
||||
num_train_timesteps=num_train_timesteps,
|
||||
steps_offset=1,
|
||||
clip_sample=False,
|
||||
set_alpha_to_one=False,
|
||||
prediction_type=prediction_type,
|
||||
)
|
||||
# make sure scheduler works correctly with DDIM
|
||||
scheduler.register_to_config(clip_sample=False)
|
||||
original_config = OmegaConf.load(original_config_file)
|
||||
|
||||
if scheduler_type == "pndm":
|
||||
config = dict(scheduler.config)
|
||||
config["skip_prk_steps"] = True
|
||||
scheduler = PNDMScheduler.from_config(config)
|
||||
elif scheduler_type == "lms":
|
||||
scheduler = LMSDiscreteScheduler.from_config(scheduler.config)
|
||||
elif scheduler_type == "heun":
|
||||
scheduler = HeunDiscreteScheduler.from_config(scheduler.config)
|
||||
elif scheduler_type == "euler":
|
||||
scheduler = EulerDiscreteScheduler.from_config(scheduler.config)
|
||||
elif scheduler_type == "euler-ancestral":
|
||||
scheduler = EulerAncestralDiscreteScheduler.from_config(scheduler.config)
|
||||
elif scheduler_type == "dpm":
|
||||
scheduler = DPMSolverMultistepScheduler.from_config(scheduler.config)
|
||||
elif scheduler_type == "ddim":
|
||||
scheduler = scheduler
|
||||
else:
|
||||
raise ValueError(f"Scheduler of type {scheduler_type} doesn't exist!")
|
||||
if num_in_channels is not None:
|
||||
original_config["model"]["params"]["unet_config"]["params"]["in_channels"] = num_in_channels
|
||||
|
||||
# Convert the UNet2DConditionModel model.
|
||||
unet_config = create_unet_diffusers_config(original_config, image_size=image_size)
|
||||
unet_config["upcast_attention"] = upcast_attention
|
||||
unet = UNet2DConditionModel(**unet_config)
|
||||
if (
|
||||
"parameterization" in original_config["model"]["params"]
|
||||
and original_config["model"]["params"]["parameterization"] == "v"
|
||||
):
|
||||
if prediction_type is None:
|
||||
# NOTE: For stable diffusion 2 base it is recommended to pass `prediction_type=="epsilon"`
|
||||
# as it relies on a brittle global step parameter here
|
||||
prediction_type = "epsilon" if global_step == 875000 else "v_prediction"
|
||||
if image_size is None:
|
||||
# NOTE: For stable diffusion 2 base one has to pass `image_size==512`
|
||||
# as it relies on a brittle global step parameter here
|
||||
image_size = 512 if global_step == 875000 else 768
|
||||
else:
|
||||
if prediction_type is None:
|
||||
prediction_type = "epsilon"
|
||||
if image_size is None:
|
||||
image_size = 512
|
||||
|
||||
converted_unet_checkpoint = convert_ldm_unet_checkpoint(
|
||||
checkpoint, unet_config, path=checkpoint_path, extract_ema=extract_ema
|
||||
)
|
||||
num_train_timesteps = original_config.model.params.timesteps
|
||||
beta_start = original_config.model.params.linear_start
|
||||
beta_end = original_config.model.params.linear_end
|
||||
|
||||
unet.load_state_dict(converted_unet_checkpoint)
|
||||
|
||||
# Convert the VAE model, or use the one passed
|
||||
if not vae:
|
||||
print(f' | Using checkpoint model\'s original VAE')
|
||||
vae_config = create_vae_diffusers_config(original_config, image_size=image_size)
|
||||
converted_vae_checkpoint = convert_ldm_vae_checkpoint(checkpoint, vae_config)
|
||||
|
||||
vae = AutoencoderKL(**vae_config)
|
||||
vae.load_state_dict(converted_vae_checkpoint)
|
||||
else:
|
||||
print(f' | Using external VAE specified in config')
|
||||
|
||||
# Convert the text model.
|
||||
model_type = pipeline_type
|
||||
if model_type is None:
|
||||
model_type = original_config.model.params.cond_stage_config.target.split(".")[-1]
|
||||
|
||||
if model_type == "FrozenOpenCLIPEmbedder":
|
||||
text_model = convert_open_clip_checkpoint(checkpoint)
|
||||
tokenizer = CLIPTokenizer.from_pretrained("stabilityai/stable-diffusion-2",
|
||||
subfolder="tokenizer",
|
||||
cache_dir=global_cache_dir('diffusers')
|
||||
)
|
||||
pipe = StableDiffusionGeneratorPipeline(
|
||||
vae=vae,
|
||||
text_encoder=text_model,
|
||||
tokenizer=tokenizer,
|
||||
unet=unet,
|
||||
scheduler=scheduler,
|
||||
safety_checker=None,
|
||||
feature_extractor=None,
|
||||
requires_safety_checker=False,
|
||||
scheduler = DDIMScheduler(
|
||||
beta_end=beta_end,
|
||||
beta_schedule="scaled_linear",
|
||||
beta_start=beta_start,
|
||||
num_train_timesteps=num_train_timesteps,
|
||||
steps_offset=1,
|
||||
clip_sample=False,
|
||||
set_alpha_to_one=False,
|
||||
prediction_type=prediction_type,
|
||||
)
|
||||
elif model_type == "PaintByExample":
|
||||
vision_model = convert_paint_by_example_checkpoint(checkpoint)
|
||||
tokenizer = CLIPTokenizer.from_pretrained("openai/clip-vit-large-patch14",cache_dir=cache_dir)
|
||||
feature_extractor = AutoFeatureExtractor.from_pretrained("CompVis/stable-diffusion-safety-checker",cache_dir=cache_dir)
|
||||
pipe = PaintByExamplePipeline(
|
||||
vae=vae,
|
||||
image_encoder=vision_model,
|
||||
unet=unet,
|
||||
scheduler=scheduler,
|
||||
safety_checker=None,
|
||||
feature_extractor=feature_extractor,
|
||||
# make sure scheduler works correctly with DDIM
|
||||
scheduler.register_to_config(clip_sample=False)
|
||||
|
||||
if scheduler_type == "pndm":
|
||||
config = dict(scheduler.config)
|
||||
config["skip_prk_steps"] = True
|
||||
scheduler = PNDMScheduler.from_config(config)
|
||||
elif scheduler_type == "lms":
|
||||
scheduler = LMSDiscreteScheduler.from_config(scheduler.config)
|
||||
elif scheduler_type == "heun":
|
||||
scheduler = HeunDiscreteScheduler.from_config(scheduler.config)
|
||||
elif scheduler_type == "euler":
|
||||
scheduler = EulerDiscreteScheduler.from_config(scheduler.config)
|
||||
elif scheduler_type == "euler-ancestral":
|
||||
scheduler = EulerAncestralDiscreteScheduler.from_config(scheduler.config)
|
||||
elif scheduler_type == "dpm":
|
||||
scheduler = DPMSolverMultistepScheduler.from_config(scheduler.config)
|
||||
elif scheduler_type == "ddim":
|
||||
scheduler = scheduler
|
||||
else:
|
||||
raise ValueError(f"Scheduler of type {scheduler_type} doesn't exist!")
|
||||
|
||||
# Convert the UNet2DConditionModel model.
|
||||
unet_config = create_unet_diffusers_config(original_config, image_size=image_size)
|
||||
unet_config["upcast_attention"] = upcast_attention
|
||||
unet = UNet2DConditionModel(**unet_config)
|
||||
|
||||
converted_unet_checkpoint = convert_ldm_unet_checkpoint(
|
||||
checkpoint, unet_config, path=checkpoint_path, extract_ema=extract_ema
|
||||
)
|
||||
elif model_type in ['FrozenCLIPEmbedder','WeightedFrozenCLIPEmbedder']:
|
||||
text_model = convert_ldm_clip_checkpoint(checkpoint)
|
||||
tokenizer = CLIPTokenizer.from_pretrained("openai/clip-vit-large-patch14",cache_dir=cache_dir)
|
||||
feature_extractor = AutoFeatureExtractor.from_pretrained("CompVis/stable-diffusion-safety-checker",cache_dir=cache_dir)
|
||||
pipe = StableDiffusionGeneratorPipeline(
|
||||
vae=vae,
|
||||
text_encoder=text_model,
|
||||
tokenizer=tokenizer,
|
||||
unet=unet,
|
||||
scheduler=scheduler,
|
||||
safety_checker=None,
|
||||
feature_extractor=feature_extractor,
|
||||
)
|
||||
else:
|
||||
text_config = create_ldm_bert_config(original_config)
|
||||
text_model = convert_ldm_bert_checkpoint(checkpoint, text_config)
|
||||
tokenizer = BertTokenizerFast.from_pretrained("bert-base-uncased",cache_dir=cache_dir)
|
||||
pipe = LDMTextToImagePipeline(vqvae=vae, bert=text_model, tokenizer=tokenizer, unet=unet, scheduler=scheduler)
|
||||
|
||||
unet.load_state_dict(converted_unet_checkpoint)
|
||||
|
||||
# Convert the VAE model, or use the one passed
|
||||
if not vae:
|
||||
print(' | Using checkpoint model\'s original VAE')
|
||||
vae_config = create_vae_diffusers_config(original_config, image_size=image_size)
|
||||
converted_vae_checkpoint = convert_ldm_vae_checkpoint(checkpoint, vae_config)
|
||||
|
||||
vae = AutoencoderKL(**vae_config)
|
||||
vae.load_state_dict(converted_vae_checkpoint)
|
||||
else:
|
||||
print(' | Using external VAE specified in config')
|
||||
|
||||
# Convert the text model.
|
||||
model_type = pipeline_type
|
||||
if model_type is None:
|
||||
model_type = original_config.model.params.cond_stage_config.target.split(".")[-1]
|
||||
|
||||
if model_type == "FrozenOpenCLIPEmbedder":
|
||||
text_model = convert_open_clip_checkpoint(checkpoint)
|
||||
tokenizer = CLIPTokenizer.from_pretrained("stabilityai/stable-diffusion-2",
|
||||
subfolder="tokenizer",
|
||||
cache_dir=global_cache_dir('diffusers')
|
||||
)
|
||||
pipe = pipeline_class(
|
||||
vae=vae,
|
||||
text_encoder=text_model,
|
||||
tokenizer=tokenizer,
|
||||
unet=unet,
|
||||
scheduler=scheduler,
|
||||
safety_checker=None,
|
||||
feature_extractor=None,
|
||||
requires_safety_checker=False,
|
||||
)
|
||||
elif model_type == "PaintByExample":
|
||||
vision_model = convert_paint_by_example_checkpoint(checkpoint)
|
||||
tokenizer = CLIPTokenizer.from_pretrained("openai/clip-vit-large-patch14",cache_dir=cache_dir)
|
||||
feature_extractor = AutoFeatureExtractor.from_pretrained("CompVis/stable-diffusion-safety-checker",cache_dir=cache_dir)
|
||||
pipe = PaintByExamplePipeline(
|
||||
vae=vae,
|
||||
image_encoder=vision_model,
|
||||
unet=unet,
|
||||
scheduler=scheduler,
|
||||
safety_checker=None,
|
||||
feature_extractor=feature_extractor,
|
||||
)
|
||||
elif model_type in ['FrozenCLIPEmbedder','WeightedFrozenCLIPEmbedder']:
|
||||
text_model = convert_ldm_clip_checkpoint(checkpoint)
|
||||
tokenizer = CLIPTokenizer.from_pretrained("openai/clip-vit-large-patch14",cache_dir=cache_dir)
|
||||
feature_extractor = AutoFeatureExtractor.from_pretrained("CompVis/stable-diffusion-safety-checker",cache_dir=cache_dir)
|
||||
pipe = pipeline_class(
|
||||
vae=vae,
|
||||
text_encoder=text_model,
|
||||
tokenizer=tokenizer,
|
||||
unet=unet,
|
||||
scheduler=scheduler,
|
||||
safety_checker=None,
|
||||
feature_extractor=feature_extractor,
|
||||
)
|
||||
else:
|
||||
text_config = create_ldm_bert_config(original_config)
|
||||
text_model = convert_ldm_bert_checkpoint(checkpoint, text_config)
|
||||
tokenizer = BertTokenizerFast.from_pretrained("bert-base-uncased",cache_dir=cache_dir)
|
||||
pipe = LDMTextToImagePipeline(vqvae=vae, bert=text_model, tokenizer=tokenizer, unet=unet, scheduler=scheduler)
|
||||
dlogging.set_verbosity(verbosity)
|
||||
|
||||
return pipe
|
||||
|
||||
@@ -1000,6 +1010,7 @@ def convert_ckpt_to_diffuser(
|
||||
checkpoint_path,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
pipe.save_pretrained(
|
||||
dump_path,
|
||||
safe_serialization=is_safetensors_available(),
|
||||
|
||||
@@ -17,6 +17,7 @@ from ..models.diffusion import cross_attention_control
|
||||
from ..models.diffusion.shared_invokeai_diffusion import InvokeAIDiffuserComponent
|
||||
from ..modules.encoders.modules import WeightedFrozenCLIPEmbedder
|
||||
from ..modules.prompt_to_embeddings_converter import WeightedPromptFragmentsToEmbeddingsConverter
|
||||
from ldm.invoke.globals import Globals
|
||||
|
||||
|
||||
def get_uc_and_c_and_ec(prompt_string, model, log_tokens=False, skip_normalize_legacy_blend=False):
|
||||
@@ -92,9 +93,9 @@ def _get_conditioning_for_prompt(parsed_prompt: Union[Blend, FlattenedPrompt], p
|
||||
Process prompt structure and tokens, and return (conditioning, unconditioning, extra_conditioning_info)
|
||||
"""
|
||||
|
||||
if log_tokens:
|
||||
print(f">> Parsed prompt to {parsed_prompt}")
|
||||
print(f">> Parsed negative prompt to {parsed_negative_prompt}")
|
||||
if log_tokens or Globals.log_tokenization:
|
||||
print(f"\n>> [TOKENLOG] Parsed Prompt: {parsed_prompt}")
|
||||
print(f"\n>> [TOKENLOG] Parsed Negative Prompt: {parsed_negative_prompt}")
|
||||
|
||||
conditioning = None
|
||||
cac_args: cross_attention_control.Arguments = None
|
||||
@@ -235,7 +236,7 @@ def _get_embeddings_and_tokens_for_prompt(model, flattened_prompt: FlattenedProm
|
||||
fragments = [x.text for x in flattened_prompt.children]
|
||||
weights = [x.weight for x in flattened_prompt.children]
|
||||
embeddings, tokens = model.get_learned_conditioning([fragments], return_tokens=True, fragment_weights=[weights])
|
||||
if log_tokens:
|
||||
if log_tokens or Globals.log_tokenization:
|
||||
text = " ".join(fragments)
|
||||
log_tokenization(text, model, display_label=log_display_label)
|
||||
|
||||
@@ -273,12 +274,12 @@ def log_tokenization(text, model, display_label=None):
|
||||
# usually tokens have '</w>' to indicate end-of-word,
|
||||
# but for readability it has been replaced with ' '
|
||||
"""
|
||||
|
||||
tokens = model.cond_stage_model.tokenizer.tokenize(text)
|
||||
tokenized = ""
|
||||
discarded = ""
|
||||
usedTokens = 0
|
||||
totalTokens = len(tokens)
|
||||
|
||||
for i in range(0, totalTokens):
|
||||
token = tokens[i].replace('</w>', ' ')
|
||||
# alternate color
|
||||
@@ -288,8 +289,11 @@ def log_tokenization(text, model, display_label=None):
|
||||
usedTokens += 1
|
||||
else: # over max token length
|
||||
discarded = discarded + f"\x1b[0;3{s};40m{token}"
|
||||
print(f"\n>> Tokens {display_label or ''} ({usedTokens}):\n{tokenized}\x1b[0m")
|
||||
|
||||
if usedTokens > 0:
|
||||
print(f'\n>> [TOKENLOG] Tokens {display_label or ""} ({usedTokens}):')
|
||||
print(f'{tokenized}\x1b[0m')
|
||||
|
||||
if discarded != "":
|
||||
print(
|
||||
f">> Tokens Discarded ({totalTokens - usedTokens}):\n{discarded}\x1b[0m"
|
||||
)
|
||||
print(f'\n>> [TOKENLOG] Tokens Discarded ({totalTokens - usedTokens}):')
|
||||
print(f'{discarded}\x1b[0m')
|
||||
@@ -127,8 +127,8 @@ script do it for you. Manual installation is described at:
|
||||
|
||||
https://invoke-ai.github.io/InvokeAI/installation/020_INSTALL_MANUAL/
|
||||
|
||||
You may download the recommended models (about 10GB total), select a customized set, or
|
||||
completely skip this step.
|
||||
You may download the recommended models (about 15GB total), install all models (40 GB!!)
|
||||
select a customized set, or completely skip this step.
|
||||
"""
|
||||
)
|
||||
completer.set_options(["recommended", "customized", "skip"])
|
||||
@@ -320,6 +320,8 @@ You may re-run the configuration script again in the future if you do not wish t
|
||||
while again:
|
||||
try:
|
||||
access_token = getpass_asterisk.getpass_asterisk(prompt="HF Token ❯ ")
|
||||
if access_token is None or len(access_token)==0:
|
||||
raise EOFError
|
||||
HfLogin(access_token)
|
||||
access_token = HfFolder.get_token()
|
||||
again = False
|
||||
@@ -433,9 +435,7 @@ def _download_diffusion_weights(
|
||||
)
|
||||
except OSError as e:
|
||||
if str(e).startswith("fp16 is not a valid"):
|
||||
print(
|
||||
f"Could not fetch half-precision version of model {repo_id}; fetching full-precision instead"
|
||||
)
|
||||
pass
|
||||
else:
|
||||
print(f"An unexpected error occurred while downloading the model: {e})")
|
||||
if path:
|
||||
@@ -866,7 +866,7 @@ def initialize_rootdir(root: str, yes_to_all: bool = False):
|
||||
):
|
||||
os.makedirs(os.path.join(root, name), exist_ok=True)
|
||||
|
||||
configs_src = Path(configs.__path__[-1])
|
||||
configs_src = Path(configs.__path__[0])
|
||||
configs_dest = Path(root) / "configs"
|
||||
if not os.path.samefile(configs_src, configs_dest):
|
||||
shutil.copytree(configs_src, configs_dest, dirs_exist_ok=True)
|
||||
@@ -122,6 +122,10 @@ class Generator:
|
||||
|
||||
seed = self.new_seed()
|
||||
|
||||
# Free up memory from the last generation.
|
||||
if self.model.device.type == 'cuda':
|
||||
torch.cuda.empty_cache()
|
||||
|
||||
return results
|
||||
|
||||
def sample_to_image(self,samples)->Image.Image:
|
||||
@@ -240,7 +244,12 @@ class Generator:
|
||||
|
||||
def get_perlin_noise(self,width,height):
|
||||
fixdevice = 'cpu' if (self.model.device.type == 'mps') else self.model.device
|
||||
noise = torch.stack([rand_perlin_2d((height, width), (8, 8), device = self.model.device).to(fixdevice) for _ in range(self.latent_channels)], dim=0).to(self.model.device)
|
||||
# limit noise to only the diffusion image channels, not the mask channels
|
||||
input_channels = min(self.latent_channels, 4)
|
||||
noise = torch.stack([
|
||||
rand_perlin_2d((height, width),
|
||||
(8, 8),
|
||||
device = self.model.device).to(fixdevice) for _ in range(input_channels)], dim=0).to(self.model.device)
|
||||
return noise
|
||||
|
||||
def new_seed(self):
|
||||
@@ -341,3 +350,27 @@ class Generator:
|
||||
|
||||
def torch_dtype(self)->torch.dtype:
|
||||
return torch.float16 if self.precision == 'float16' else torch.float32
|
||||
|
||||
# returns a tensor filled with random numbers from a normal distribution
|
||||
def get_noise(self,width,height):
|
||||
device = self.model.device
|
||||
# limit noise to only the diffusion image channels, not the mask channels
|
||||
input_channels = min(self.latent_channels, 4)
|
||||
if self.use_mps_noise or device.type == 'mps':
|
||||
x = torch.randn([1,
|
||||
input_channels,
|
||||
height // self.downsampling_factor,
|
||||
width // self.downsampling_factor],
|
||||
dtype=self.torch_dtype(),
|
||||
device='cpu').to(device)
|
||||
else:
|
||||
x = torch.randn([1,
|
||||
input_channels,
|
||||
height // self.downsampling_factor,
|
||||
width // self.downsampling_factor],
|
||||
dtype=self.torch_dtype(),
|
||||
device=device)
|
||||
if self.perlin > 0.0:
|
||||
perlin_noise = self.get_perlin_noise(width // self.downsampling_factor, height // self.downsampling_factor)
|
||||
x = (1-self.perlin)*x + self.perlin*perlin_noise
|
||||
return x
|
||||
|
||||
@@ -4,7 +4,6 @@ import dataclasses
|
||||
import inspect
|
||||
import secrets
|
||||
import sys
|
||||
import warnings
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List, Optional, Union, Callable, Type, TypeVar, Generic, Any
|
||||
|
||||
@@ -641,7 +640,6 @@ class StableDiffusionGeneratorPipeline(StableDiffusionPipeline):
|
||||
|
||||
@property
|
||||
def cond_stage_model(self):
|
||||
warnings.warn("legacy compatibility layer", DeprecationWarning)
|
||||
return self.prompt_fragments_to_embeddings_converter
|
||||
|
||||
@torch.inference_mode()
|
||||
|
||||
@@ -63,22 +63,3 @@ class Img2Img(Generator):
|
||||
shape = like.shape
|
||||
x = (1-self.perlin)*x + self.perlin*self.get_perlin_noise(shape[3], shape[2])
|
||||
return x
|
||||
|
||||
def get_noise(self,width,height):
|
||||
# copy of the Txt2Img.get_noise
|
||||
device = self.model.device
|
||||
if self.use_mps_noise or device.type == 'mps':
|
||||
x = torch.randn([1,
|
||||
self.latent_channels,
|
||||
height // self.downsampling_factor,
|
||||
width // self.downsampling_factor],
|
||||
device='cpu').to(device)
|
||||
else:
|
||||
x = torch.randn([1,
|
||||
self.latent_channels,
|
||||
height // self.downsampling_factor,
|
||||
width // self.downsampling_factor],
|
||||
device=device)
|
||||
if self.perlin > 0.0:
|
||||
x = (1-self.perlin)*x + self.perlin*self.get_perlin_noise(width // self.downsampling_factor, height // self.downsampling_factor)
|
||||
return x
|
||||
|
||||
@@ -194,7 +194,8 @@ class Inpaint(Img2Img):
|
||||
"""
|
||||
|
||||
self.enable_image_debugging = enable_image_debugging
|
||||
self.infill_method = infill_method or infill_methods()[0], # The infill method to use
|
||||
infill_method = infill_method or infill_methods()[0]
|
||||
self.infill_method = infill_method
|
||||
|
||||
self.inpaint_width = inpaint_width
|
||||
self.inpaint_height = inpaint_height
|
||||
|
||||
@@ -51,26 +51,4 @@ class Txt2Img(Generator):
|
||||
return make_image
|
||||
|
||||
|
||||
# returns a tensor filled with random numbers from a normal distribution
|
||||
def get_noise(self,width,height):
|
||||
device = self.model.device
|
||||
# limit noise to only the diffusion image channels, not the mask channels
|
||||
input_channels = min(self.latent_channels, 4)
|
||||
if self.use_mps_noise or device.type == 'mps':
|
||||
x = torch.randn([1,
|
||||
input_channels,
|
||||
height // self.downsampling_factor,
|
||||
width // self.downsampling_factor],
|
||||
dtype=self.torch_dtype(),
|
||||
device='cpu').to(device)
|
||||
else:
|
||||
x = torch.randn([1,
|
||||
input_channels,
|
||||
height // self.downsampling_factor,
|
||||
width // self.downsampling_factor],
|
||||
dtype=self.torch_dtype(),
|
||||
device=device)
|
||||
if self.perlin > 0.0:
|
||||
x = (1-self.perlin)*x + self.perlin*self.get_perlin_noise(width // self.downsampling_factor, height // self.downsampling_factor)
|
||||
return x
|
||||
|
||||
|
||||
@@ -65,6 +65,10 @@ class Txt2Img2Img(Generator):
|
||||
mode="bilinear"
|
||||
)
|
||||
|
||||
# Free up memory from the last generation.
|
||||
if self.model.device.type == 'cuda':
|
||||
torch.cuda.empty_cache()
|
||||
|
||||
second_pass_noise = self.get_noise_like(resized_latents)
|
||||
|
||||
verbosity = get_verbosity()
|
||||
|
||||
@@ -8,26 +8,25 @@ import argparse
|
||||
import curses
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
import warnings
|
||||
from argparse import Namespace
|
||||
from pathlib import Path
|
||||
from typing import List, Union
|
||||
|
||||
import npyscreen
|
||||
import warnings
|
||||
from diffusers import DiffusionPipeline
|
||||
from diffusers import logging as dlogging
|
||||
from npyscreen import widget
|
||||
from omegaconf import OmegaConf
|
||||
|
||||
from ldm.invoke.globals import (
|
||||
Globals,
|
||||
global_cache_dir,
|
||||
global_config_file,
|
||||
global_models_dir,
|
||||
global_set_root,
|
||||
)
|
||||
from ldm.invoke.globals import (Globals, global_cache_dir, global_config_file,
|
||||
global_models_dir, global_set_root)
|
||||
from ldm.invoke.model_manager import ModelManager
|
||||
|
||||
DEST_MERGED_MODEL_DIR = "merged_models"
|
||||
|
||||
|
||||
def merge_diffusion_models(
|
||||
model_ids_or_paths: List[Union[str, Path]],
|
||||
alpha: float = 0.5,
|
||||
@@ -46,18 +45,24 @@ def merge_diffusion_models(
|
||||
**kwargs - the default DiffusionPipeline.get_config_dict kwargs:
|
||||
cache_dir, resume_download, force_download, proxies, local_files_only, use_auth_token, revision, torch_dtype, device_map
|
||||
"""
|
||||
pipe = DiffusionPipeline.from_pretrained(
|
||||
model_ids_or_paths[0],
|
||||
cache_dir=kwargs.get("cache_dir", global_cache_dir()),
|
||||
custom_pipeline="checkpoint_merger",
|
||||
)
|
||||
merged_pipe = pipe.merge(
|
||||
pretrained_model_name_or_path_list=model_ids_or_paths,
|
||||
alpha=alpha,
|
||||
interp=interp,
|
||||
force=force,
|
||||
**kwargs,
|
||||
)
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore")
|
||||
verbosity = dlogging.get_verbosity()
|
||||
dlogging.set_verbosity_error()
|
||||
|
||||
pipe = DiffusionPipeline.from_pretrained(
|
||||
model_ids_or_paths[0],
|
||||
cache_dir=kwargs.get("cache_dir", global_cache_dir()),
|
||||
custom_pipeline="checkpoint_merger",
|
||||
)
|
||||
merged_pipe = pipe.merge(
|
||||
pretrained_model_name_or_path_list=model_ids_or_paths,
|
||||
alpha=alpha,
|
||||
interp=interp,
|
||||
force=force,
|
||||
**kwargs,
|
||||
)
|
||||
dlogging.set_verbosity(verbosity)
|
||||
return merged_pipe
|
||||
|
||||
|
||||
@@ -181,13 +186,12 @@ class FloatTitleSlider(npyscreen.TitleText):
|
||||
|
||||
|
||||
class mergeModelsForm(npyscreen.FormMultiPageAction):
|
||||
|
||||
interpolations = ["weighted_sum", "sigmoid", "inv_sigmoid", "add_difference"]
|
||||
|
||||
def __init__(self, parentApp, name):
|
||||
self.parentApp = parentApp
|
||||
self.ALLOW_RESIZE=True
|
||||
self.FIX_MINIMUM_SIZE_WHEN_CREATED=False
|
||||
self.ALLOW_RESIZE = True
|
||||
self.FIX_MINIMUM_SIZE_WHEN_CREATED = False
|
||||
super().__init__(parentApp, name)
|
||||
|
||||
@property
|
||||
@@ -198,29 +202,29 @@ class mergeModelsForm(npyscreen.FormMultiPageAction):
|
||||
self.parentApp.setNextForm(None)
|
||||
|
||||
def create(self):
|
||||
window_height,window_width=curses.initscr().getmaxyx()
|
||||
|
||||
window_height, window_width = curses.initscr().getmaxyx()
|
||||
|
||||
self.model_names = self.get_model_names()
|
||||
max_width = max([len(x) for x in self.model_names])
|
||||
max_width += 6
|
||||
horizontal_layout = max_width*3 < window_width
|
||||
|
||||
horizontal_layout = max_width * 3 < window_width
|
||||
|
||||
self.add_widget_intelligent(
|
||||
npyscreen.FixedText,
|
||||
color='CONTROL',
|
||||
color="CONTROL",
|
||||
value=f"Select two models to merge and optionally a third.",
|
||||
editable=False,
|
||||
)
|
||||
self.add_widget_intelligent(
|
||||
npyscreen.FixedText,
|
||||
color='CONTROL',
|
||||
color="CONTROL",
|
||||
value=f"Use up and down arrows to move, <space> to select an item, <tab> and <shift-tab> to move from one field to the next.",
|
||||
editable=False,
|
||||
)
|
||||
self.add_widget_intelligent(
|
||||
npyscreen.FixedText,
|
||||
value='MODEL 1',
|
||||
color='GOOD',
|
||||
value="MODEL 1",
|
||||
color="GOOD",
|
||||
editable=False,
|
||||
rely=4 if horizontal_layout else None,
|
||||
)
|
||||
@@ -235,57 +239,57 @@ class mergeModelsForm(npyscreen.FormMultiPageAction):
|
||||
)
|
||||
self.add_widget_intelligent(
|
||||
npyscreen.FixedText,
|
||||
value='MODEL 2',
|
||||
color='GOOD',
|
||||
value="MODEL 2",
|
||||
color="GOOD",
|
||||
editable=False,
|
||||
relx=max_width+3 if horizontal_layout else None,
|
||||
relx=max_width + 3 if horizontal_layout else None,
|
||||
rely=4 if horizontal_layout else None,
|
||||
)
|
||||
self.model2 = self.add_widget_intelligent(
|
||||
npyscreen.SelectOne,
|
||||
name='(2)',
|
||||
name="(2)",
|
||||
values=self.model_names,
|
||||
value=1,
|
||||
max_height=len(self.model_names),
|
||||
max_width=max_width,
|
||||
relx=max_width+3 if horizontal_layout else None,
|
||||
relx=max_width + 3 if horizontal_layout else None,
|
||||
rely=5 if horizontal_layout else None,
|
||||
scroll_exit=True,
|
||||
)
|
||||
self.add_widget_intelligent(
|
||||
npyscreen.FixedText,
|
||||
value='MODEL 3',
|
||||
color='GOOD',
|
||||
value="MODEL 3",
|
||||
color="GOOD",
|
||||
editable=False,
|
||||
relx=max_width*2+3 if horizontal_layout else None,
|
||||
relx=max_width * 2 + 3 if horizontal_layout else None,
|
||||
rely=4 if horizontal_layout else None,
|
||||
)
|
||||
models_plus_none = self.model_names.copy()
|
||||
models_plus_none.insert(0,'None')
|
||||
models_plus_none.insert(0, "None")
|
||||
self.model3 = self.add_widget_intelligent(
|
||||
npyscreen.SelectOne,
|
||||
name='(3)',
|
||||
name="(3)",
|
||||
values=models_plus_none,
|
||||
value=0,
|
||||
max_height=len(self.model_names)+1,
|
||||
max_height=len(self.model_names) + 1,
|
||||
max_width=max_width,
|
||||
scroll_exit=True,
|
||||
relx=max_width*2+3 if horizontal_layout else None,
|
||||
relx=max_width * 2 + 3 if horizontal_layout else None,
|
||||
rely=5 if horizontal_layout else None,
|
||||
)
|
||||
for m in [self.model1,self.model2,self.model3]:
|
||||
for m in [self.model1, self.model2, self.model3]:
|
||||
m.when_value_edited = self.models_changed
|
||||
self.merged_model_name = self.add_widget_intelligent(
|
||||
npyscreen.TitleText,
|
||||
name="Name for merged model:",
|
||||
labelColor='CONTROL',
|
||||
labelColor="CONTROL",
|
||||
value="",
|
||||
scroll_exit=True,
|
||||
)
|
||||
self.force = self.add_widget_intelligent(
|
||||
npyscreen.Checkbox,
|
||||
name="Force merge of incompatible models",
|
||||
labelColor='CONTROL',
|
||||
labelColor="CONTROL",
|
||||
value=False,
|
||||
scroll_exit=True,
|
||||
)
|
||||
@@ -294,7 +298,7 @@ class mergeModelsForm(npyscreen.FormMultiPageAction):
|
||||
name="Merge Method:",
|
||||
values=self.interpolations,
|
||||
value=0,
|
||||
labelColor='CONTROL',
|
||||
labelColor="CONTROL",
|
||||
max_height=len(self.interpolations) + 1,
|
||||
scroll_exit=True,
|
||||
)
|
||||
@@ -305,7 +309,7 @@ class mergeModelsForm(npyscreen.FormMultiPageAction):
|
||||
step=0.05,
|
||||
lowest=0,
|
||||
value=0.5,
|
||||
labelColor='CONTROL',
|
||||
labelColor="CONTROL",
|
||||
scroll_exit=True,
|
||||
)
|
||||
self.model1.editing = True
|
||||
@@ -315,43 +319,43 @@ class mergeModelsForm(npyscreen.FormMultiPageAction):
|
||||
selected_model1 = self.model1.value[0]
|
||||
selected_model2 = self.model2.value[0]
|
||||
selected_model3 = self.model3.value[0]
|
||||
merged_model_name = f'{models[selected_model1]}+{models[selected_model2]}'
|
||||
merged_model_name = f"{models[selected_model1]}+{models[selected_model2]}"
|
||||
self.merged_model_name.value = merged_model_name
|
||||
|
||||
|
||||
if selected_model3 > 0:
|
||||
self.merge_method.values=['add_difference'],
|
||||
self.merged_model_name.value += f'+{models[selected_model3]}'
|
||||
self.merge_method.values = (["add_difference"],)
|
||||
self.merged_model_name.value += f"+{models[selected_model3]}"
|
||||
else:
|
||||
self.merge_method.values=self.interpolations
|
||||
self.merge_method.value=0
|
||||
self.merge_method.values = self.interpolations
|
||||
self.merge_method.value = 0
|
||||
|
||||
def on_ok(self):
|
||||
if self.validate_field_values() and self.check_for_overwrite():
|
||||
self.parentApp.setNextForm(None)
|
||||
self.editing = False
|
||||
self.parentApp.merge_arguments = self.marshall_arguments()
|
||||
npyscreen.notify('Starting the merge...')
|
||||
npyscreen.notify("Starting the merge...")
|
||||
else:
|
||||
self.editing = True
|
||||
|
||||
def on_cancel(self):
|
||||
sys.exit(0)
|
||||
|
||||
def marshall_arguments(self)->dict:
|
||||
def marshall_arguments(self) -> dict:
|
||||
model_names = self.model_names
|
||||
models = [
|
||||
model_names[self.model1.value[0]],
|
||||
model_names[self.model2.value[0]],
|
||||
]
|
||||
]
|
||||
if self.model3.value[0] > 0:
|
||||
models.append(model_names[self.model3.value[0]-1])
|
||||
models.append(model_names[self.model3.value[0] - 1])
|
||||
|
||||
args = dict(
|
||||
models=models,
|
||||
alpha = self.alpha.value,
|
||||
interp = self.interpolations[self.merge_method.value[0]],
|
||||
force = self.force.value,
|
||||
merged_model_name = self.merged_model_name.value,
|
||||
alpha=self.alpha.value,
|
||||
interp=self.interpolations[self.merge_method.value[0]],
|
||||
force=self.force.value,
|
||||
merged_model_name=self.merged_model_name.value,
|
||||
)
|
||||
return args
|
||||
|
||||
@@ -364,18 +368,22 @@ class mergeModelsForm(npyscreen.FormMultiPageAction):
|
||||
f"The chosen merged model destination, {model_out}, is already in use. Overwrite?"
|
||||
)
|
||||
|
||||
def validate_field_values(self)->bool:
|
||||
def validate_field_values(self) -> bool:
|
||||
bad_fields = []
|
||||
model_names = self.model_names
|
||||
selected_models = set((model_names[self.model1.value[0]],model_names[self.model2.value[0]]))
|
||||
selected_models = set(
|
||||
(model_names[self.model1.value[0]], model_names[self.model2.value[0]])
|
||||
)
|
||||
if self.model3.value[0] > 0:
|
||||
selected_models.add(model_names[self.model3.value[0]-1])
|
||||
selected_models.add(model_names[self.model3.value[0] - 1])
|
||||
if len(selected_models) < 2:
|
||||
bad_fields.append(f'Please select two or three DIFFERENT models to compare. You selected {selected_models}')
|
||||
bad_fields.append(
|
||||
f"Please select two or three DIFFERENT models to compare. You selected {selected_models}"
|
||||
)
|
||||
if len(bad_fields) > 0:
|
||||
message = 'The following problems were detected and must be corrected:'
|
||||
message = "The following problems were detected and must be corrected:"
|
||||
for problem in bad_fields:
|
||||
message += f'\n* {problem}'
|
||||
message += f"\n* {problem}"
|
||||
npyscreen.notify_confirm(message)
|
||||
return False
|
||||
else:
|
||||
@@ -403,6 +411,7 @@ class Mergeapp(npyscreen.NPSAppManaged):
|
||||
npyscreen.setTheme(npyscreen.Themes.ElegantTheme)
|
||||
self.main = self.addForm("MAIN", mergeModelsForm, name="Merge Models Settings")
|
||||
|
||||
|
||||
def run_gui(args: Namespace):
|
||||
mergeapp = Mergeapp()
|
||||
mergeapp.run()
|
||||
@@ -443,22 +452,27 @@ def main():
|
||||
] = cache_dir # because not clear the merge pipeline is honoring cache_dir
|
||||
args.cache_dir = cache_dir
|
||||
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore')
|
||||
try:
|
||||
if args.front_end:
|
||||
run_gui(args)
|
||||
else:
|
||||
run_cli(args)
|
||||
print(f'>> Conversion successful.')
|
||||
except Exception as e:
|
||||
if str(e).startswith('Not enough space'):
|
||||
print('** Not enough horizontal space! Try making the window wider, or relaunch with a smaller starting size.')
|
||||
else:
|
||||
print(f"** An error occurred while merging the pipelines: {str(e)}")
|
||||
sys.exit(-1)
|
||||
except KeyboardInterrupt:
|
||||
sys.exit(-1)
|
||||
try:
|
||||
if args.front_end:
|
||||
run_gui(args)
|
||||
else:
|
||||
run_cli(args)
|
||||
print(f">> Conversion successful. New model is named {args.merged_model_name}")
|
||||
except widget.NotEnoughSpaceForWidget as e:
|
||||
if str(e).startswith("Height of 1 allocated"):
|
||||
print(
|
||||
"** You need to have at least two diffusers models defined in models.yaml in order to merge"
|
||||
)
|
||||
else:
|
||||
print(f"** A layout error has occurred: {str(e)}")
|
||||
sys.exit(-1)
|
||||
except Exception as e:
|
||||
print(">> An error occurred:")
|
||||
traceback.print_exc()
|
||||
sys.exit(-1)
|
||||
except KeyboardInterrupt:
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -18,7 +18,7 @@ import warnings
|
||||
import safetensors.torch
|
||||
from pathlib import Path
|
||||
from shutil import move, rmtree
|
||||
from typing import Union, Any
|
||||
from typing import Any, Optional, Union
|
||||
from huggingface_hub import scan_cache_dir
|
||||
from ldm.util import download_with_progress_bar
|
||||
|
||||
@@ -356,6 +356,7 @@ class ModelManager(object):
|
||||
checkpoint_path = weights,
|
||||
original_config_file = config,
|
||||
vae = vae,
|
||||
return_generator_pipeline=True,
|
||||
)
|
||||
return (
|
||||
pipeline.to(self.device).to(torch.float16 if self.precision == 'float16' else torch.float32),
|
||||
@@ -483,12 +484,11 @@ class ModelManager(object):
|
||||
**pipeline_args,
|
||||
**fp_args,
|
||||
)
|
||||
|
||||
except OSError as e:
|
||||
if str(e).startswith('fp16 is not a valid'):
|
||||
print(f'Could not fetch half-precision version of model {name_or_path}; fetching full-precision instead')
|
||||
pass
|
||||
else:
|
||||
print(f'An unexpected error occurred while downloading the model: {e})')
|
||||
print(f'** An unexpected error occurred while downloading the model: {e})')
|
||||
if pipeline:
|
||||
break
|
||||
|
||||
@@ -753,7 +753,7 @@ class ModelManager(object):
|
||||
return search_folder, found_models
|
||||
|
||||
def _choose_diffusers_vae(self, model_name:str, vae:str=None)->Union[dict,str]:
|
||||
|
||||
|
||||
# In the event that the original entry is using a custom ckpt VAE, we try to
|
||||
# map that VAE onto a diffuser VAE using a hard-coded dictionary.
|
||||
# I would prefer to do this differently: We load the ckpt model into memory, swap the
|
||||
@@ -880,14 +880,14 @@ class ModelManager(object):
|
||||
print('** Migration is done. Continuing...')
|
||||
|
||||
|
||||
def _resolve_path(self, source:Union[str,Path], dest_directory:str)->Path:
|
||||
def _resolve_path(self, source: Union[str, Path], dest_directory: str) -> Optional[Path]:
|
||||
resolved_path = None
|
||||
if source.startswith(('http:','https:','ftp:')):
|
||||
if str(source).startswith(('http:','https:','ftp:')):
|
||||
basename = os.path.basename(source)
|
||||
if not os.path.isabs(dest_directory):
|
||||
dest_directory = os.path.join(Globals.root,dest_directory)
|
||||
dest = os.path.join(dest_directory,basename)
|
||||
if download_with_progress_bar(source,dest):
|
||||
if download_with_progress_bar(str(source), Path(dest)):
|
||||
resolved_path = Path(dest)
|
||||
else:
|
||||
if not os.path.isabs(source):
|
||||
@@ -954,7 +954,7 @@ class ModelManager(object):
|
||||
def _has_cuda(self) -> bool:
|
||||
return self.device.type == 'cuda'
|
||||
|
||||
def _diffuser_sha256(self,name_or_path:Union[str, Path])->Union[str,bytes]:
|
||||
def _diffuser_sha256(self,name_or_path:Union[str, Path],chunksize=4096)->Union[str,bytes]:
|
||||
path = None
|
||||
if isinstance(name_or_path,Path):
|
||||
path = name_or_path
|
||||
@@ -976,7 +976,8 @@ class ModelManager(object):
|
||||
for name in files:
|
||||
count += 1
|
||||
with open(os.path.join(root,name),'rb') as f:
|
||||
sha.update(f.read())
|
||||
while chunk := f.read(chunksize):
|
||||
sha.update(chunk)
|
||||
hash = sha.hexdigest()
|
||||
toc = time.time()
|
||||
print(f' | sha256 = {hash} ({count} files hashed in','%4.2fs)' % (toc - tic))
|
||||
@@ -1039,7 +1040,7 @@ class ModelManager(object):
|
||||
vae = AutoencoderKL.from_pretrained(name_or_path, **vae_args, **fp_args)
|
||||
except OSError as e:
|
||||
if str(e).startswith('fp16 is not a valid'):
|
||||
print(' | Half-precision version of model not available; fetching full-precision instead')
|
||||
pass
|
||||
else:
|
||||
deferred_error = e
|
||||
if vae:
|
||||
|
||||
@@ -17,6 +17,7 @@ from pathlib import Path
|
||||
from typing import List, Tuple
|
||||
|
||||
import npyscreen
|
||||
from npyscreen import widget
|
||||
from omegaconf import OmegaConf
|
||||
|
||||
from ldm.invoke.globals import Globals, global_set_root
|
||||
@@ -295,7 +296,8 @@ class textualInversionForm(npyscreen.FormMultiPageAction):
|
||||
for idx in range(len(model_names))
|
||||
if "default" in conf[model_names[idx]]
|
||||
]
|
||||
return (model_names, defaults[0])
|
||||
default = defaults[0] if len(defaults) > 0 else 0
|
||||
return (model_names, default)
|
||||
|
||||
def marshall_arguments(self) -> dict:
|
||||
args = dict()
|
||||
@@ -437,11 +439,20 @@ def main():
|
||||
do_front_end(args)
|
||||
else:
|
||||
do_textual_inversion_training(**vars(args))
|
||||
except widget.NotEnoughSpaceForWidget as e:
|
||||
if str(e).startswith("Height of 1 allocated"):
|
||||
print(
|
||||
"** You need to have at least one diffusers models defined in models.yaml in order to train"
|
||||
)
|
||||
else:
|
||||
print(f"** A layout error has occurred: {str(e)}")
|
||||
sys.exit(-1)
|
||||
except AssertionError as e:
|
||||
print(str(e))
|
||||
sys.exit(-1)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user