aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAUTOMATIC1111 <16777216c@gmail.com>2023-01-04 17:40:19 +0300
committerGitHub <noreply@github.com>2023-01-04 17:40:19 +0300
commitda5c1e8a732c173ed8ccda9fa32f9a194ff91ab6 (patch)
treea2eec9c47e820e7ab351337f73c99d874b4b904f
parentcffc240a7327ae60671ff533469fc4ed4bf605de (diff)
parent47df0849019abac6722c49512f4dd2285bff5b7d (diff)
Merge branch 'master' into inpaint_textual_inversion
-rw-r--r--.github/workflows/run_tests.yaml31
-rw-r--r--.gitignore1
-rw-r--r--CODEOWNERS23
-rw-r--r--README.md37
-rw-r--r--configs/alt-diffusion-inference.yaml72
-rw-r--r--configs/v1-inference.yaml70
-rw-r--r--extensions-builtin/LDSR/ldsr_model_arch.py (renamed from modules/ldsr_model_arch.py)68
-rw-r--r--extensions-builtin/LDSR/preload.py6
-rw-r--r--extensions-builtin/LDSR/scripts/ldsr_model.py (renamed from modules/ldsr_model.py)23
-rw-r--r--extensions-builtin/LDSR/sd_hijack_autoencoder.py286
-rw-r--r--extensions-builtin/LDSR/sd_hijack_ddpm_v1.py1449
-rw-r--r--extensions-builtin/ScuNET/preload.py6
-rw-r--r--extensions-builtin/ScuNET/scripts/scunet_model.py (renamed from modules/scunet_model.py)8
-rw-r--r--extensions-builtin/ScuNET/scunet_model_arch.py (renamed from modules/scunet_model_arch.py)0
-rw-r--r--extensions-builtin/SwinIR/preload.py6
-rw-r--r--extensions-builtin/SwinIR/scripts/swinir_model.py (renamed from modules/swinir_model.py)41
-rw-r--r--extensions-builtin/SwinIR/swinir_model_arch.py (renamed from modules/swinir_model_arch.py)0
-rw-r--r--extensions-builtin/SwinIR/swinir_model_arch_v2.py (renamed from modules/swinir_model_arch_v2.py)0
-rw-r--r--extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js107
-rw-r--r--extensions-builtin/roll-artist/scripts/roll-artist.py50
-rw-r--r--html/footer.html9
-rw-r--r--html/licenses.html392
-rw-r--r--javascript/contextMenus.js24
-rw-r--r--javascript/dragdrop.js10
-rw-r--r--javascript/edit-attention.js3
-rw-r--r--javascript/generationParams.js33
-rw-r--r--javascript/hints.js11
-rw-r--r--javascript/notification.js2
-rw-r--r--javascript/progressbar.js58
-rw-r--r--javascript/ui.js32
-rw-r--r--launch.py126
-rw-r--r--localizations/ar_AR.json518
-rw-r--r--localizations/de_DE.json458
-rw-r--r--localizations/es_ES.json418
-rw-r--r--localizations/fr_FR.json415
-rw-r--r--localizations/it_IT.json1173
-rw-r--r--localizations/ja_JP.json482
-rw-r--r--localizations/ko_KR.json577
-rw-r--r--localizations/pt_BR.json468
-rw-r--r--localizations/ru_RU.json475
-rw-r--r--localizations/tr_TR.json423
-rw-r--r--localizations/zh_CN.json488
-rw-r--r--localizations/zh_TW.json488
-rw-r--r--models/VAE-approx/model.ptbin0 -> 213777 bytes
-rw-r--r--models/VAE/Put VAE here.txt0
-rw-r--r--modules/api/api.py371
-rw-r--r--modules/api/models.py108
-rw-r--r--modules/call_queue.py98
-rw-r--r--modules/codeformer/vqgan_arch.py4
-rw-r--r--modules/codeformer_model.py3
-rw-r--r--modules/deepbooru.py260
-rw-r--r--modules/deepbooru_model.py676
-rw-r--r--modules/devices.py115
-rw-r--r--modules/errors.py25
-rw-r--r--modules/esrgan_model.py19
-rw-r--r--modules/extensions.py38
-rw-r--r--modules/extras.py149
-rw-r--r--modules/generation_parameters_copypaste.py147
-rw-r--r--modules/gfpgan_model.py4
-rw-r--r--modules/hypernetworks/hypernetwork.py411
-rw-r--r--modules/hypernetworks/ui.py31
-rw-r--r--modules/images.py166
-rw-r--r--modules/img2img.py40
-rw-r--r--modules/import_hook.py5
-rw-r--r--modules/interrogate.py24
-rw-r--r--modules/localization.py6
-rw-r--r--modules/lowvram.py20
-rw-r--r--modules/masking.py2
-rw-r--r--modules/memmon.py3
-rw-r--r--modules/modelloader.py44
-rw-r--r--modules/ngrok.py15
-rw-r--r--modules/paths.py2
-rw-r--r--modules/processing.py345
-rw-r--r--modules/safe.py113
-rw-r--r--modules/safety.py42
-rw-r--r--modules/script_callbacks.py182
-rw-r--r--modules/script_loading.py34
-rw-r--r--modules/scripts.py194
-rw-r--r--modules/sd_hijack.py355
-rw-r--r--modules/sd_hijack_checkpoint.py10
-rw-r--r--modules/sd_hijack_clip.py303
-rw-r--r--modules/sd_hijack_inpainting.py244
-rw-r--r--modules/sd_hijack_open_clip.py37
-rw-r--r--modules/sd_hijack_optimizations.py10
-rw-r--r--modules/sd_hijack_unet.py30
-rw-r--r--modules/sd_hijack_xlmr.py34
-rw-r--r--modules/sd_models.py200
-rw-r--r--modules/sd_samplers.py176
-rw-r--r--modules/sd_vae.py231
-rw-r--r--modules/sd_vae_approx.py58
-rw-r--r--modules/shared.py193
-rw-r--r--modules/styles.py11
-rw-r--r--modules/textual_inversion/autocrop.py6
-rw-r--r--modules/textual_inversion/dataset.py139
-rw-r--r--modules/textual_inversion/preprocess.py173
-rw-r--r--modules/textual_inversion/textual_inversion.py404
-rw-r--r--modules/textual_inversion/ui.py2
-rw-r--r--modules/txt2img.py13
-rw-r--r--modules/ui.py886
-rw-r--r--modules/ui_components.py25
-rw-r--r--modules/ui_extensions.py94
-rw-r--r--modules/ui_tempdir.py82
-rw-r--r--modules/upscaler.py31
-rw-r--r--modules/xlmr.py137
-rw-r--r--requirements.txt10
-rw-r--r--requirements_versions.txt8
-rw-r--r--script.js9
-rw-r--r--scripts/custom_code.py2
-rw-r--r--scripts/img2imgalt.py7
-rw-r--r--scripts/outpainting_mk_2.py2
-rw-r--r--scripts/poor_mans_outpainting.py4
-rw-r--r--scripts/prompt_matrix.py21
-rw-r--r--scripts/prompts_from_file.py41
-rw-r--r--scripts/sd_upscale.py20
-rw-r--r--scripts/xy_grid.py72
-rw-r--r--style.css143
-rw-r--r--test/advanced_features/__init__.py0
-rw-r--r--test/advanced_features/extras_test.py (renamed from test/extras_test.py)4
-rw-r--r--test/advanced_features/txt2img_test.py47
-rw-r--r--test/basic_features/__init__.py0
-rw-r--r--test/basic_features/img2img_test.py (renamed from test/img2img_test.py)4
-rw-r--r--test/basic_features/txt2img_test.py (renamed from test/txt2img_test.py)12
-rw-r--r--test/basic_features/utils_test.py53
-rw-r--r--test/server_poll.py13
-rw-r--r--test/test_files/empty.ptbin0 -> 431 bytes
-rw-r--r--v2-inference-v.yaml68
-rw-r--r--webui-macos-env.sh19
-rw-r--r--webui-user.sh5
-rw-r--r--webui.bat12
-rw-r--r--webui.py124
-rwxr-xr-xwebui.sh41
131 files changed, 8698 insertions, 8990 deletions
diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml
new file mode 100644
index 00000000..49dc92bd
--- /dev/null
+++ b/.github/workflows/run_tests.yaml
@@ -0,0 +1,31 @@
+name: Run basic features tests on CPU with empty SD model
+
+on:
+ - push
+ - pull_request
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v3
+ - name: Set up Python 3.10
+ uses: actions/setup-python@v4
+ with:
+ python-version: 3.10.6
+ - uses: actions/cache@v3
+ with:
+ path: ~/.cache/pip
+ key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
+ restore-keys: ${{ runner.os }}-pip-
+ - name: Run tests
+ run: python launch.py --tests basic_features --no-half --disable-opt-split-attention --use-cpu all --skip-torch-cuda-test
+ - name: Upload main app stdout-stderr
+ uses: actions/upload-artifact@v3
+ if: always()
+ with:
+ name: stdout-stderr
+ path: |
+ test/stdout.txt
+ test/stderr.txt
diff --git a/.gitignore b/.gitignore
index ee53044c..21fa26a7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
__pycache__
*.ckpt
+*.safetensors
*.pth
/ESRGAN/*
/SwinIR/*
diff --git a/CODEOWNERS b/CODEOWNERS
index a48d8012..7438c9bc 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -1,13 +1,12 @@
* @AUTOMATIC1111
-/localizations/ar_AR.json @xmodar @blackneoo
-/localizations/de_DE.json @LunixWasTaken
-/localizations/es_ES.json @innovaciones
-/localizations/fr_FR.json @tumbly
-/localizations/it_IT.json @EugenioBuffo
-/localizations/ja_JP.json @yuuki76
-/localizations/ko_KR.json @36DB
-/localizations/pt_BR.json @M-art-ucci
-/localizations/ru_RU.json @kabachuha
-/localizations/tr_TR.json @camenduru
-/localizations/zh_CN.json @dtlnor @bgluminous
-/localizations/zh_TW.json @benlisquare
+
+# if you were managing a localization and were removed from this file, this is because
+# the intended way to do localizations now is via extensions. See:
+# https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Developing-extensions
+# Make a repo with your localization and since you are still listed as a collaborator
+# you can add it to the wiki page yourself. This change is because some people complained
+# the git commit log is cluttered with things unrelated to almost everyone and
+# because I believe this is the best overall for the project to handle localizations almost
+# entirely without my oversight.
+
+
diff --git a/README.md b/README.md
index 55c050d5..88250a6b 100644
--- a/README.md
+++ b/README.md
@@ -70,7 +70,7 @@ Check the [custom scripts](https://github.com/AUTOMATIC1111/stable-diffusion-web
- separate prompts using uppercase `AND`
- also supports weights for prompts: `a cat :1.2 AND a dog AND a penguin :2.2`
- No token limit for prompts (original stable diffusion lets you use up to 75 tokens)
-- DeepDanbooru integration, creates danbooru style tags for anime prompts (add --deepdanbooru to commandline args)
+- DeepDanbooru integration, creates danbooru style tags for anime prompts
- [xformers](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Xformers), major speed increase for select cards: (add --xformers to commandline args)
- via extension: [History tab](https://github.com/yfszzx/stable-diffusion-webui-images-browser): view, direct and delete images conveniently within the UI
- Generate forever option
@@ -82,28 +82,9 @@ Check the [custom scripts](https://github.com/AUTOMATIC1111/stable-diffusion-web
- Use VAEs
- Estimated completion time in progress bar
- API
-- Support for dedicated [inpainting model](https://github.com/runwayml/stable-diffusion#inpainting-with-stable-diffusion) by RunwayML.
-- via extension: [Aesthetic Gradients](https://github.com/AUTOMATIC1111/stable-diffusion-webui-aesthetic-gradients), a way to generate images with a specific aesthetic by using clip images embds (implementation of [https://github.com/vicgalle/stable-diffusion-aesthetic-gradients](https://github.com/vicgalle/stable-diffusion-aesthetic-gradients))
-
-## Where are Aesthetic Gradients?!?!
-Aesthetic Gradients are now an extension. You can install it using git:
-
-```commandline
-git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui-aesthetic-gradients extensions/aesthetic-gradients
-```
-
-After running this command, make sure that you have `aesthetic-gradients` dir in webui's `extensions` directory and restart
-the UI. The interface for Aesthetic Gradients should appear exactly the same as it was.
-
-## Where is History/Image browser?!?!
-Image browser is now an extension. You can install it using git:
-
-```commandline
-git clone https://github.com/yfszzx/stable-diffusion-webui-images-browser extensions/images-browser
-```
-
-After running this command, make sure that you have `images-browser` dir in webui's `extensions` directory and restart
-the UI. The interface for Image browser should appear exactly the same as it was.
+- Support for dedicated [inpainting model](https://github.com/runwayml/stable-diffusion#inpainting-with-stable-diffusion) by RunwayML.
+- via extension: [Aesthetic Gradients](https://github.com/AUTOMATIC1111/stable-diffusion-webui-aesthetic-gradients), a way to generate images with a specific aesthetic by using clip images embeds (implementation of [https://github.com/vicgalle/stable-diffusion-aesthetic-gradients](https://github.com/vicgalle/stable-diffusion-aesthetic-gradients))
+- [Stable Diffusion 2.0](https://github.com/Stability-AI/stablediffusion) support - see [wiki](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Features#stable-diffusion-20) for instructions
## Installation and Running
Make sure the required [dependencies](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Dependencies) are met and follow the instructions available for both [NVidia](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-NVidia-GPUs) (recommended) and [AMD](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-AMD-GPUs) GPUs.
@@ -146,6 +127,8 @@ Here's how to add code to this repo: [Contributing](https://github.com/AUTOMATIC
The documentation was moved from this README over to the project's [wiki](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki).
## Credits
+Licenses for borrowed code can be found in `Settings -> Licenses` screen, and also in `html/licenses.html` file.
+
- Stable Diffusion - https://github.com/CompVis/stable-diffusion, https://github.com/CompVis/taming-transformers
- k-diffusion - https://github.com/crowsonkb/k-diffusion.git
- GFPGAN - https://github.com/TencentARC/GFPGAN.git
@@ -154,15 +137,17 @@ The documentation was moved from this README over to the project's [wiki](https:
- SwinIR - https://github.com/JingyunLiang/SwinIR
- Swin2SR - https://github.com/mv-lab/swin2sr
- LDSR - https://github.com/Hafiidz/latent-diffusion
+- MiDaS - https://github.com/isl-org/MiDaS
- Ideas for optimizations - https://github.com/basujindal/stable-diffusion
-- Doggettx - Cross Attention layer optimization - https://github.com/Doggettx/stable-diffusion, original idea for prompt editing.
-- InvokeAI, lstein - Cross Attention layer optimization - https://github.com/invoke-ai/InvokeAI (originally http://github.com/lstein/stable-diffusion)
-- Rinon Gal - Textual Inversion - https://github.com/rinongal/textual_inversion (we're not using his code, but we are using his ideas).
+- Cross Attention layer optimization - Doggettx - https://github.com/Doggettx/stable-diffusion, original idea for prompt editing.
+- Cross Attention layer optimization - InvokeAI, lstein - https://github.com/invoke-ai/InvokeAI (originally http://github.com/lstein/stable-diffusion)
+- Textual Inversion - Rinon Gal - https://github.com/rinongal/textual_inversion (we're not using his code, but we are using his ideas).
- Idea for SD upscale - https://github.com/jquesnelle/txt2imghd
- Noise generation for outpainting mk2 - https://github.com/parlance-zz/g-diffuser-bot
- CLIP interrogator idea and borrowing some code - https://github.com/pharmapsychotic/clip-interrogator
- Idea for Composable Diffusion - https://github.com/energy-based-model/Compositional-Visual-Generation-with-Composable-Diffusion-Models-PyTorch
- xformers - https://github.com/facebookresearch/xformers
- DeepDanbooru - interrogator for anime diffusers https://github.com/KichangKim/DeepDanbooru
+- Security advice - RyotaK
- Initial Gradio script - posted on 4chan by an Anonymous user. Thank you Anonymous user.
- (You)
diff --git a/configs/alt-diffusion-inference.yaml b/configs/alt-diffusion-inference.yaml
new file mode 100644
index 00000000..cfbee72d
--- /dev/null
+++ b/configs/alt-diffusion-inference.yaml
@@ -0,0 +1,72 @@
+model:
+ base_learning_rate: 1.0e-04
+ target: ldm.models.diffusion.ddpm.LatentDiffusion
+ params:
+ linear_start: 0.00085
+ linear_end: 0.0120
+ num_timesteps_cond: 1
+ log_every_t: 200
+ timesteps: 1000
+ first_stage_key: "jpg"
+ cond_stage_key: "txt"
+ image_size: 64
+ channels: 4
+ cond_stage_trainable: false # Note: different from the one we trained before
+ conditioning_key: crossattn
+ monitor: val/loss_simple_ema
+ scale_factor: 0.18215
+ use_ema: False
+
+ scheduler_config: # 10000 warmup steps
+ target: ldm.lr_scheduler.LambdaLinearScheduler
+ params:
+ warm_up_steps: [ 10000 ]
+ cycle_lengths: [ 10000000000000 ] # incredibly large number to prevent corner cases
+ f_start: [ 1.e-6 ]
+ f_max: [ 1. ]
+ f_min: [ 1. ]
+
+ unet_config:
+ target: ldm.modules.diffusionmodules.openaimodel.UNetModel
+ params:
+ image_size: 32 # unused
+ in_channels: 4
+ out_channels: 4
+ model_channels: 320
+ attention_resolutions: [ 4, 2, 1 ]
+ num_res_blocks: 2
+ channel_mult: [ 1, 2, 4, 4 ]
+ num_heads: 8
+ use_spatial_transformer: True
+ transformer_depth: 1
+ context_dim: 768
+ use_checkpoint: True
+ legacy: False
+
+ first_stage_config:
+ target: ldm.models.autoencoder.AutoencoderKL
+ params:
+ embed_dim: 4
+ monitor: val/rec_loss
+ ddconfig:
+ double_z: true
+ z_channels: 4
+ resolution: 256
+ in_channels: 3
+ out_ch: 3
+ ch: 128
+ ch_mult:
+ - 1
+ - 2
+ - 4
+ - 4
+ num_res_blocks: 2
+ attn_resolutions: []
+ dropout: 0.0
+ lossconfig:
+ target: torch.nn.Identity
+
+ cond_stage_config:
+ target: modules.xlmr.BertSeriesModelWithTransformation
+ params:
+ name: "XLMR-Large" \ No newline at end of file
diff --git a/configs/v1-inference.yaml b/configs/v1-inference.yaml
new file mode 100644
index 00000000..d4effe56
--- /dev/null
+++ b/configs/v1-inference.yaml
@@ -0,0 +1,70 @@
+model:
+ base_learning_rate: 1.0e-04
+ target: ldm.models.diffusion.ddpm.LatentDiffusion
+ params:
+ linear_start: 0.00085
+ linear_end: 0.0120
+ num_timesteps_cond: 1
+ log_every_t: 200
+ timesteps: 1000
+ first_stage_key: "jpg"
+ cond_stage_key: "txt"
+ image_size: 64
+ channels: 4
+ cond_stage_trainable: false # Note: different from the one we trained before
+ conditioning_key: crossattn
+ monitor: val/loss_simple_ema
+ scale_factor: 0.18215
+ use_ema: False
+
+ scheduler_config: # 10000 warmup steps
+ target: ldm.lr_scheduler.LambdaLinearScheduler
+ params:
+ warm_up_steps: [ 10000 ]
+ cycle_lengths: [ 10000000000000 ] # incredibly large number to prevent corner cases
+ f_start: [ 1.e-6 ]
+ f_max: [ 1. ]
+ f_min: [ 1. ]
+
+ unet_config:
+ target: ldm.modules.diffusionmodules.openaimodel.UNetModel
+ params:
+ image_size: 32 # unused
+ in_channels: 4
+ out_channels: 4
+ model_channels: 320
+ attention_resolutions: [ 4, 2, 1 ]
+ num_res_blocks: 2
+ channel_mult: [ 1, 2, 4, 4 ]
+ num_heads: 8
+ use_spatial_transformer: True
+ transformer_depth: 1
+ context_dim: 768
+ use_checkpoint: True
+ legacy: False
+
+ first_stage_config:
+ target: ldm.models.autoencoder.AutoencoderKL
+ params:
+ embed_dim: 4
+ monitor: val/rec_loss
+ ddconfig:
+ double_z: true
+ z_channels: 4
+ resolution: 256
+ in_channels: 3
+ out_ch: 3
+ ch: 128
+ ch_mult:
+ - 1
+ - 2
+ - 4
+ - 4
+ num_res_blocks: 2
+ attn_resolutions: []
+ dropout: 0.0
+ lossconfig:
+ target: torch.nn.Identity
+
+ cond_stage_config:
+ target: ldm.modules.encoders.modules.FrozenCLIPEmbedder
diff --git a/modules/ldsr_model_arch.py b/extensions-builtin/LDSR/ldsr_model_arch.py
index 14db5076..0ad49f4e 100644
--- a/modules/ldsr_model_arch.py
+++ b/extensions-builtin/LDSR/ldsr_model_arch.py
@@ -1,3 +1,4 @@
+import os
import gc
import time
import warnings
@@ -8,27 +9,49 @@ import torchvision
from PIL import Image
from einops import rearrange, repeat
from omegaconf import OmegaConf
+import safetensors.torch
from ldm.models.diffusion.ddim import DDIMSampler
from ldm.util import instantiate_from_config, ismap
+from modules import shared, sd_hijack
warnings.filterwarnings("ignore", category=UserWarning)
+cached_ldsr_model: torch.nn.Module = None
+
# Create LDSR Class
class LDSR:
def load_model_from_config(self, half_attention):
- print(f"Loading model from {self.modelPath}")
- pl_sd = torch.load(self.modelPath, map_location="cpu")
- sd = pl_sd["state_dict"]
- config = OmegaConf.load(self.yamlPath)
- model = instantiate_from_config(config.model)
- model.load_state_dict(sd, strict=False)
- model.cuda()
- if half_attention:
- model = model.half()
-
- model.eval()
+ global cached_ldsr_model
+
+ if shared.opts.ldsr_cached and cached_ldsr_model is not None:
+ print("Loading model from cache")
+ model: torch.nn.Module = cached_ldsr_model
+ else:
+ print(f"Loading model from {self.modelPath}")
+ _, extension = os.path.splitext(self.modelPath)
+ if extension.lower() == ".safetensors":
+ pl_sd = safetensors.torch.load_file(self.modelPath, device="cpu")
+ else:
+ pl_sd = torch.load(self.modelPath, map_location="cpu")
+ sd = pl_sd["state_dict"] if "state_dict" in pl_sd else pl_sd
+ config = OmegaConf.load(self.yamlPath)
+ config.model.target = "ldm.models.diffusion.ddpm.LatentDiffusionV1"
+ model: torch.nn.Module = instantiate_from_config(config.model)
+ model.load_state_dict(sd, strict=False)
+ model = model.to(shared.device)
+ if half_attention:
+ model = model.half()
+ if shared.cmd_opts.opt_channelslast:
+ model = model.to(memory_format=torch.channels_last)
+
+ sd_hijack.model_hijack.hijack(model) # apply optimization
+ model.eval()
+
+ if shared.opts.ldsr_cached:
+ cached_ldsr_model = model
+
return {"model": model}
def __init__(self, model_path, yaml_path):
@@ -93,7 +116,8 @@ class LDSR:
down_sample_method = 'Lanczos'
gc.collect()
- torch.cuda.empty_cache()
+ if torch.cuda.is_available:
+ torch.cuda.empty_cache()
im_og = image
width_og, height_og = im_og.size
@@ -101,8 +125,8 @@ class LDSR:
down_sample_rate = target_scale / 4
wd = width_og * down_sample_rate
hd = height_og * down_sample_rate
- width_downsampled_pre = int(wd)
- height_downsampled_pre = int(hd)
+ width_downsampled_pre = int(np.ceil(wd))
+ height_downsampled_pre = int(np.ceil(hd))
if down_sample_rate != 1:
print(
@@ -110,7 +134,12 @@ class LDSR:
im_og = im_og.resize((width_downsampled_pre, height_downsampled_pre), Image.LANCZOS)
else:
print(f"Down sample rate is 1 from {target_scale} / 4 (Not downsampling)")
- logs = self.run(model["model"], im_og, diffusion_steps, eta)
+
+ # pad width and height to multiples of 64, pads with the edge values of image to avoid artifacts
+ pad_w, pad_h = np.max(((2, 2), np.ceil(np.array(im_og.size) / 64).astype(int)), axis=0) * 64 - im_og.size
+ im_padded = Image.fromarray(np.pad(np.array(im_og), ((0, pad_h), (0, pad_w), (0, 0)), mode='edge'))
+
+ logs = self.run(model["model"], im_padded, diffusion_steps, eta)
sample = logs["sample"]
sample = sample.detach().cpu()
@@ -120,9 +149,14 @@ class LDSR:
sample = np.transpose(sample, (0, 2, 3, 1))
a = Image.fromarray(sample[0])
+ # remove padding
+ a = a.crop((0, 0) + tuple(np.array(im_og.size) * 4))
+
del model
gc.collect()
- torch.cuda.empty_cache()
+ if torch.cuda.is_available:
+ torch.cuda.empty_cache()
+
return a
@@ -137,7 +171,7 @@ def get_cond(selected_path):
c = rearrange(c, '1 c h w -> 1 h w c')
c = 2. * c - 1.
- c = c.to(torch.device("cuda"))
+ c = c.to(shared.device)
example["LR_image"] = c
example["image"] = c_up
diff --git a/extensions-builtin/LDSR/preload.py b/extensions-builtin/LDSR/preload.py
new file mode 100644
index 00000000..d746007c
--- /dev/null
+++ b/extensions-builtin/LDSR/preload.py
@@ -0,0 +1,6 @@
+import os
+from modules import paths
+
+
+def preload(parser):
+ parser.add_argument("--ldsr-models-path", type=str, help="Path to directory with LDSR model file(s).", default=os.path.join(paths.models_path, 'LDSR'))
diff --git a/modules/ldsr_model.py b/extensions-builtin/LDSR/scripts/ldsr_model.py
index 8c4db44a..b8cff29b 100644
--- a/modules/ldsr_model.py
+++ b/extensions-builtin/LDSR/scripts/ldsr_model.py
@@ -5,8 +5,9 @@ import traceback
from basicsr.utils.download_util import load_file_from_url
from modules.upscaler import Upscaler, UpscalerData
-from modules.ldsr_model_arch import LDSR
-from modules import shared
+from ldsr_model_arch import LDSR
+from modules import shared, script_callbacks
+import sd_hijack_autoencoder, sd_hijack_ddpm_v1
class UpscalerLDSR(Upscaler):
@@ -24,6 +25,7 @@ class UpscalerLDSR(Upscaler):
yaml_path = os.path.join(self.model_path, "project.yaml")
old_model_path = os.path.join(self.model_path, "model.pth")
new_model_path = os.path.join(self.model_path, "model.ckpt")
+ safetensors_model_path = os.path.join(self.model_path, "model.safetensors")
if os.path.exists(yaml_path):
statinfo = os.stat(yaml_path)
if statinfo.st_size >= 10485760:
@@ -32,8 +34,11 @@ class UpscalerLDSR(Upscaler):
if os.path.exists(old_model_path):
print("Renaming model from model.pth to model.ckpt")
os.rename(old_model_path, new_model_path)
- model = load_file_from_url(url=self.model_url, model_dir=self.model_path,
- file_name="model.ckpt", progress=True)
+ if os.path.exists(safetensors_model_path):
+ model = safetensors_model_path
+ else:
+ model = load_file_from_url(url=self.model_url, model_dir=self.model_path,
+ file_name="model.ckpt", progress=True)
yaml = load_file_from_url(url=self.yaml_url, model_dir=self.model_path,
file_name="project.yaml", progress=True)
@@ -52,3 +57,13 @@ class UpscalerLDSR(Upscaler):
return img
ddim_steps = shared.opts.ldsr_steps
return ldsr.super_resolution(img, ddim_steps, self.scale)
+
+
+def on_ui_settings():
+ import gradio as gr
+
+ shared.opts.add_option("ldsr_steps", shared.OptionInfo(100, "LDSR processing steps. Lower = faster", gr.Slider, {"minimum": 1, "maximum": 200, "step": 1}, section=('upscaling', "Upscaling")))
+ shared.opts.add_option("ldsr_cached", shared.OptionInfo(False, "Cache LDSR model in memory", gr.Checkbox, {"interactive": True}, section=('upscaling', "Upscaling")))
+
+
+script_callbacks.on_ui_settings(on_ui_settings)
diff --git a/extensions-builtin/LDSR/sd_hijack_autoencoder.py b/extensions-builtin/LDSR/sd_hijack_autoencoder.py
new file mode 100644
index 00000000..8e03c7f8
--- /dev/null
+++ b/extensions-builtin/LDSR/sd_hijack_autoencoder.py
@@ -0,0 +1,286 @@
+# The content of this file comes from the ldm/models/autoencoder.py file of the compvis/stable-diffusion repo
+# The VQModel & VQModelInterface were subsequently removed from ldm/models/autoencoder.py when we moved to the stability-ai/stablediffusion repo
+# As the LDSR upscaler relies on VQModel & VQModelInterface, the hijack aims to put them back into the ldm.models.autoencoder
+
+import torch
+import pytorch_lightning as pl
+import torch.nn.functional as F
+from contextlib import contextmanager
+from taming.modules.vqvae.quantize import VectorQuantizer2 as VectorQuantizer
+from ldm.modules.diffusionmodules.model import Encoder, Decoder
+from ldm.util import instantiate_from_config
+
+import ldm.models.autoencoder
+
+class VQModel(pl.LightningModule):
+ def __init__(self,
+ ddconfig,
+ lossconfig,
+ n_embed,
+ embed_dim,
+ ckpt_path=None,
+ ignore_keys=[],
+ image_key="image",
+ colorize_nlabels=None,
+ monitor=None,
+ batch_resize_range=None,
+ scheduler_config=None,
+ lr_g_factor=1.0,
+ remap=None,
+ sane_index_shape=False, # tell vector quantizer to return indices as bhw
+ use_ema=False
+ ):
+ super().__init__()
+ self.embed_dim = embed_dim
+ self.n_embed = n_embed
+ self.image_key = image_key
+ self.encoder = Encoder(**ddconfig)
+ self.decoder = Decoder(**ddconfig)
+ self.loss = instantiate_from_config(lossconfig)
+ self.quantize = VectorQuantizer(n_embed, embed_dim, beta=0.25,
+ remap=remap,
+ sane_index_shape=sane_index_shape)
+ self.quant_conv = torch.nn.Conv2d(ddconfig["z_channels"], embed_dim, 1)
+ self.post_quant_conv = torch.nn.Conv2d(embed_dim, ddconfig["z_channels"], 1)
+ if colorize_nlabels is not None:
+ assert type(colorize_nlabels)==int
+ self.register_buffer("colorize", torch.randn(3, colorize_nlabels, 1, 1))
+ if monitor is not None:
+ self.monitor = monitor
+ self.batch_resize_range = batch_resize_range
+ if self.batch_resize_range is not None:
+ print(f"{self.__class__.__name__}: Using per-batch resizing in range {batch_resize_range}.")
+
+ self.use_ema = use_ema
+ if self.use_ema:
+ self.model_ema = LitEma(self)
+ print(f"Keeping EMAs of {len(list(self.model_ema.buffers()))}.")
+
+ if ckpt_path is not None:
+ self.init_from_ckpt(ckpt_path, ignore_keys=ignore_keys)
+ self.scheduler_config = scheduler_config
+ self.lr_g_factor = lr_g_factor
+
+ @contextmanager
+ def ema_scope(self, context=None):
+ if self.use_ema:
+ self.model_ema.store(self.parameters())
+ self.model_ema.copy_to(self)
+ if context is not None:
+ print(f"{context}: Switched to EMA weights")
+ try:
+ yield None
+ finally:
+ if self.use_ema:
+ self.model_ema.restore(self.parameters())
+ if context is not None:
+ print(f"{context}: Restored training weights")
+
+ def init_from_ckpt(self, path, ignore_keys=list()):
+ sd = torch.load(path, map_location="cpu")["state_dict"]
+ keys = list(sd.keys())
+ for k in keys:
+ for ik in ignore_keys:
+ if k.startswith(ik):
+ print("Deleting key {} from state_dict.".format(k))
+ del sd[k]
+ missing, unexpected = self.load_state_dict(sd, strict=False)
+ print(f"Restored from {path} with {len(missing)} missing and {len(unexpected)} unexpected keys")
+ if len(missing) > 0:
+ print(f"Missing Keys: {missing}")
+ print(f"Unexpected Keys: {unexpected}")
+
+ def on_train_batch_end(self, *args, **kwargs):
+ if self.use_ema:
+ self.model_ema(self)
+
+ def encode(self, x):
+ h = self.encoder(x)
+ h = self.quant_conv(h)
+ quant, emb_loss, info = self.quantize(h)
+ return quant, emb_loss, info
+
+ def encode_to_prequant(self, x):
+ h = self.encoder(x)
+ h = self.quant_conv(h)
+ return h
+
+ def decode(self, quant):
+ quant = self.post_quant_conv(quant)
+ dec = self.decoder(quant)
+ return dec
+
+ def decode_code(self, code_b):
+ quant_b = self.quantize.embed_code(code_b)
+ dec = self.decode(quant_b)
+ return dec
+
+ def forward(self, input, return_pred_indices=False):
+ quant, diff, (_,_,ind) = self.encode(input)
+ dec = self.decode(quant)
+ if return_pred_indices:
+ return dec, diff, ind
+ return dec, diff
+
+ def get_input(self, batch, k):
+ x = batch[k]
+ if len(x.shape) == 3:
+ x = x[..., None]
+ x = x.permute(0, 3, 1, 2).to(memory_format=torch.contiguous_format).float()
+ if self.batch_resize_range is not None:
+ lower_size = self.batch_resize_range[0]
+ upper_size = self.batch_resize_range[1]
+ if self.global_step <= 4:
+ # do the first few batches with max size to avoid later oom
+ new_resize = upper_size
+ else:
+ new_resize = np.random.choice(np.arange(lower_size, upper_size+16, 16))
+ if new_resize != x.shape[2]:
+ x = F.interpolate(x, size=new_resize, mode="bicubic")
+ x = x.detach()
+ return x
+
+ def training_step(self, batch, batch_idx, optimizer_idx):
+ # https://github.com/pytorch/pytorch/issues/37142
+ # try not to fool the heuristics
+ x = self.get_input(batch, self.image_key)
+ xrec, qloss, ind = self(x, return_pred_indices=True)
+
+ if optimizer_idx == 0:
+ # autoencode
+ aeloss, log_dict_ae = self.loss(qloss, x, xrec, optimizer_idx, self.global_step,
+ last_layer=self.get_last_layer(), split="train",
+ predicted_indices=ind)
+
+ self.log_dict(log_dict_ae, prog_bar=False, logger=True, on_step=True, on_epoch=True)
+ return aeloss
+
+ if optimizer_idx == 1:
+ # discriminator
+ discloss, log_dict_disc = self.loss(qloss, x, xrec, optimizer_idx, self.global_step,
+ last_layer=self.get_last_layer(), split="train")
+ self.log_dict(log_dict_disc, prog_bar=False, logger=True, on_step=True, on_epoch=True)
+ return discloss
+
+ def validation_step(self, batch, batch_idx):
+ log_dict = self._validation_step(batch, batch_idx)
+ with self.ema_scope():
+ log_dict_ema = self._validation_step(batch, batch_idx, suffix="_ema")
+ return log_dict
+
+ def _validation_step(self, batch, batch_idx, suffix=""):
+ x = self.get_input(batch, self.image_key)
+ xrec, qloss, ind = self(x, return_pred_indices=True)
+ aeloss, log_dict_ae = self.loss(qloss, x, xrec, 0,
+ self.global_step,
+ last_layer=self.get_last_layer(),
+ split="val"+suffix,
+ predicted_indices=ind
+ )
+
+ discloss, log_dict_disc = self.loss(qloss, x, xrec, 1,
+ self.global_step,
+ last_layer=self.get_last_layer(),
+ split="val"+suffix,
+ predicted_indices=ind
+ )
+ rec_loss = log_dict_ae[f"val{suffix}/rec_loss"]
+ self.log(f"val{suffix}/rec_loss", rec_loss,
+ prog_bar=True, logger=True, on_step=False, on_epoch=True, sync_dist=True)
+ self.log(f"val{suffix}/aeloss", aeloss,
+ prog_bar=True, logger=True, on_step=False, on_epoch=True, sync_dist=True)
+ if version.parse(pl.__version__) >= version.parse('1.4.0'):
+ del log_dict_ae[f"val{suffix}/rec_loss"]
+ self.log_dict(log_dict_ae)
+ self.log_dict(log_dict_disc)
+ return self.log_dict
+
+ def configure_optimizers(self):
+ lr_d = self.learning_rate
+ lr_g = self.lr_g_factor*self.learning_rate
+ print("lr_d", lr_d)
+ print("lr_g", lr_g)
+ opt_ae = torch.optim.Adam(list(self.encoder.parameters())+
+ list(self.decoder.parameters())+
+ list(self.quantize.parameters())+
+ list(self.quant_conv.parameters())+
+ list(self.post_quant_conv.parameters()),
+ lr=lr_g, betas=(0.5, 0.9))
+ opt_disc = torch.optim.Adam(self.loss.discriminator.parameters(),
+ lr=lr_d, betas=(0.5, 0.9))
+
+ if self.scheduler_config is not None:
+ scheduler = instantiate_from_config(self.scheduler_config)
+
+ print("Setting up LambdaLR scheduler...")
+ scheduler = [
+ {
+ 'scheduler': LambdaLR(opt_ae, lr_lambda=scheduler.schedule),
+ 'interval': 'step',
+ 'frequency': 1
+ },
+ {
+ 'scheduler': LambdaLR(opt_disc, lr_lambda=scheduler.schedule),
+ 'interval': 'step',
+ 'frequency': 1
+ },
+ ]
+ return [opt_ae, opt_disc], scheduler
+ return [opt_ae, opt_disc], []
+
+ def get_last_layer(self):
+ return self.decoder.conv_out.weight
+
+ def log_images(self, batch, only_inputs=False, plot_ema=False, **kwargs):
+ log = dict()
+ x = self.get_input(batch, self.image_key)
+ x = x.to(self.device)
+ if only_inputs:
+ log["inputs"] = x
+ return log
+ xrec, _ = self(x)
+ if x.shape[1] > 3:
+ # colorize with random projection
+ assert xrec.shape[1] > 3
+ x = self.to_rgb(x)
+ xrec = self.to_rgb(xrec)
+ log["inputs"] = x
+ log["reconstructions"] = xrec
+ if plot_ema:
+ with self.ema_scope():
+ xrec_ema, _ = self(x)
+ if x.shape[1] > 3: xrec_ema = self.to_rgb(xrec_ema)
+ log["reconstructions_ema"] = xrec_ema
+ return log
+
+ def to_rgb(self, x):
+ assert self.image_key == "segmentation"
+ if not hasattr(self, "colorize"):
+ self.register_buffer("colorize", torch.randn(3, x.shape[1], 1, 1).to(x))
+ x = F.conv2d(x, weight=self.colorize)
+ x = 2.*(x-x.min())/(x.max()-x.min()) - 1.
+ return x
+
+
+class VQModelInterface(VQModel):
+ def __init__(self, embed_dim, *args, **kwargs):
+ super().__init__(embed_dim=embed_dim, *args, **kwargs)
+ self.embed_dim = embed_dim
+
+ def encode(self, x):
+ h = self.encoder(x)
+ h = self.quant_conv(h)
+ return h
+
+ def decode(self, h, force_not_quantize=False):
+ # also go through quantization layer
+ if not force_not_quantize:
+ quant, emb_loss, info = self.quantize(h)
+ else:
+ quant = h
+ quant = self.post_quant_conv(quant)
+ dec = self.decoder(quant)
+ return dec
+
+setattr(ldm.models.autoencoder, "VQModel", VQModel)
+setattr(ldm.models.autoencoder, "VQModelInterface", VQModelInterface)
diff --git a/extensions-builtin/LDSR/sd_hijack_ddpm_v1.py b/extensions-builtin/LDSR/sd_hijack_ddpm_v1.py
new file mode 100644
index 00000000..5c0488e5
--- /dev/null
+++ b/extensions-builtin/LDSR/sd_hijack_ddpm_v1.py
@@ -0,0 +1,1449 @@
+# This script is copied from the compvis/stable-diffusion repo (aka the SD V1 repo)
+# Original filename: ldm/models/diffusion/ddpm.py
+# The purpose to reinstate the old DDPM logic which works with VQ, whereas the V2 one doesn't
+# Some models such as LDSR require VQ to work correctly
+# The classes are suffixed with "V1" and added back to the "ldm.models.diffusion.ddpm" module
+
+import torch
+import torch.nn as nn
+import numpy as np
+import pytorch_lightning as pl
+from torch.optim.lr_scheduler import LambdaLR
+from einops import rearrange, repeat
+from contextlib import contextmanager
+from functools import partial
+from tqdm import tqdm
+from torchvision.utils import make_grid
+from pytorch_lightning.utilities.distributed import rank_zero_only
+
+from ldm.util import log_txt_as_img, exists, default, ismap, isimage, mean_flat, count_params, instantiate_from_config
+from ldm.modules.ema import LitEma
+from ldm.modules.distributions.distributions import normal_kl, DiagonalGaussianDistribution
+from ldm.models.autoencoder import VQModelInterface, IdentityFirstStage, AutoencoderKL
+from ldm.modules.diffusionmodules.util import make_beta_schedule, extract_into_tensor, noise_like
+from ldm.models.diffusion.ddim import DDIMSampler
+
+import ldm.models.diffusion.ddpm
+
+__conditioning_keys__ = {'concat': 'c_concat',
+ 'crossattn': 'c_crossattn',
+ 'adm': 'y'}
+
+
+def disabled_train(self, mode=True):
+ """Overwrite model.train with this function to make sure train/eval mode
+ does not change anymore."""
+ return self
+
+
+def uniform_on_device(r1, r2, shape, device):
+ return (r1 - r2) * torch.rand(*shape, device=device) + r2
+
+
+class DDPMV1(pl.LightningModule):
+ # classic DDPM with Gaussian diffusion, in image space
+ def __init__(self,
+ unet_config,
+ timesteps=1000,
+ beta_schedule="linear",
+ loss_type="l2",
+ ckpt_path=None,
+ ignore_keys=[],
+ load_only_unet=False,
+ monitor="val/loss",
+ use_ema=True,
+ first_stage_key="image",
+ image_size=256,
+ channels=3,
+ log_every_t=100,
+ clip_denoised=True,
+ linear_start=1e-4,
+ linear_end=2e-2,
+ cosine_s=8e-3,
+ given_betas=None,
+ original_elbo_weight=0.,
+ v_posterior=0., # weight for choosing posterior variance as sigma = (1-v) * beta_tilde + v * beta
+ l_simple_weight=1.,
+ conditioning_key=None,
+ parameterization="eps", # all assuming fixed variance schedules
+ scheduler_config=None,
+ use_positional_encodings=False,
+ learn_logvar=False,
+ logvar_init=0.,
+ ):
+ super().__init__()
+ assert parameterization in ["eps", "x0"], 'currently only supporting "eps" and "x0"'
+ self.parameterization = parameterization
+ print(f"{self.__class__.__name__}: Running in {self.parameterization}-prediction mode")
+ self.cond_stage_model = None
+ self.clip_denoised = clip_denoised
+ self.log_every_t = log_every_t
+ self.first_stage_key = first_stage_key
+ self.image_size = image_size # try conv?
+ self.channels = channels
+ self.use_positional_encodings = use_positional_encodings
+ self.model = DiffusionWrapperV1(unet_config, conditioning_key)
+ count_params(self.model, verbose=True)
+ self.use_ema = use_ema
+ if self.use_ema:
+ self.model_ema = LitEma(self.model)
+ print(f"Keeping EMAs of {len(list(self.model_ema.buffers()))}.")
+
+ self.use_scheduler = scheduler_config is not None
+ if self.use_scheduler:
+ self.scheduler_config = scheduler_config
+
+ self.v_posterior = v_posterior
+ self.original_elbo_weight = original_elbo_weight
+ self.l_simple_weight = l_simple_weight
+
+ if monitor is not None:
+ self.monitor = monitor
+ if ckpt_path is not None:
+ self.init_from_ckpt(ckpt_path, ignore_keys=ignore_keys, only_model=load_only_unet)
+
+ self.register_schedule(given_betas=given_betas, beta_schedule=beta_schedule, timesteps=timesteps,
+ linear_start=linear_start, linear_end=linear_end, cosine_s=cosine_s)
+
+ self.loss_type = loss_type
+
+ self.learn_logvar = learn_logvar
+ self.logvar = torch.full(fill_value=logvar_init, size=(self.num_timesteps,))
+ if self.learn_logvar:
+ self.logvar = nn.Parameter(self.logvar, requires_grad=True)
+
+
+ def register_schedule(self, given_betas=None, beta_schedule="linear", timesteps=1000,
+ linear_start=1e-4, linear_end=2e-2, cosine_s=8e-3):
+ if exists(given_betas):
+ betas = given_betas
+ else:
+ betas = make_beta_schedule(beta_schedule, timesteps, linear_start=linear_start, linear_end=linear_end,
+ cosine_s=cosine_s)
+ alphas = 1. - betas
+ alphas_cumprod = np.cumprod(alphas, axis=0)
+ alphas_cumprod_prev = np.append(1., alphas_cumprod[:-1])
+
+ timesteps, = betas.shape
+ self.num_timesteps = int(timesteps)
+ self.linear_start = linear_start
+ self.linear_end = linear_end
+ assert alphas_cumprod.shape[0] == self.num_timesteps, 'alphas have to be defined for each timestep'
+
+ to_torch = partial(torch.tensor, dtype=torch.float32)
+
+ self.register_buffer('betas', to_torch(betas))
+ self.register_buffer('alphas_cumprod', to_torch(alphas_cumprod))
+ self.register_buffer('alphas_cumprod_prev', to_torch(alphas_cumprod_prev))
+
+ # calculations for diffusion q(x_t | x_{t-1}) and others
+ self.register_buffer('sqrt_alphas_cumprod', to_torch(np.sqrt(alphas_cumprod)))
+ self.register_buffer('sqrt_one_minus_alphas_cumprod', to_torch(np.sqrt(1. - alphas_cumprod)))
+ self.register_buffer('log_one_minus_alphas_cumprod', to_torch(np.log(1. - alphas_cumprod)))
+ self.register_buffer('sqrt_recip_alphas_cumprod', to_torch(np.sqrt(1. / alphas_cumprod)))
+ self.register_buffer('sqrt_recipm1_alphas_cumprod', to_torch(np.sqrt(1. / alphas_cumprod - 1)))
+
+ # calculations for posterior q(x_{t-1} | x_t, x_0)
+ posterior_variance = (1 - self.v_posterior) * betas * (1. - alphas_cumprod_prev) / (
+ 1. - alphas_cumprod) + self.v_posterior * betas
+ # above: equal to 1. / (1. / (1. - alpha_cumprod_tm1) + alpha_t / beta_t)
+ self.register_buffer('posterior_variance', to_torch(posterior_variance))
+ # below: log calculation clipped because the posterior variance is 0 at the beginning of the diffusion chain
+ self.register_buffer('posterior_log_variance_clipped', to_torch(np.log(np.maximum(posterior_variance, 1e-20))))
+ self.register_buffer('posterior_mean_coef1', to_torch(
+ betas * np.sqrt(alphas_cumprod_prev) / (1. - alphas_cumprod)))
+ self.register_buffer('posterior_mean_coef2', to_torch(
+ (1. - alphas_cumprod_prev) * np.sqrt(alphas) / (1. - alphas_cumprod)))
+
+ if self.parameterization == "eps":
+ lvlb_weights = self.betas ** 2 / (
+ 2 * self.posterior_variance * to_torch(alphas) * (1 - self.alphas_cumprod))
+ elif self.parameterization == "x0":
+ lvlb_weights = 0.5 * np.sqrt(torch.Tensor(alphas_cumprod)) / (2. * 1 - torch.Tensor(alphas_cumprod))
+ else:
+ raise NotImplementedError("mu not supported")
+ # TODO how to choose this term
+ lvlb_weights[0] = lvlb_weights[1]
+ self.register_buffer('lvlb_weights', lvlb_weights, persistent=False)
+ assert not torch.isnan(self.lvlb_weights).all()
+
+ @contextmanager
+ def ema_scope(self, context=None):
+ if self.use_ema:
+ self.model_ema.store(self.model.parameters())
+ self.model_ema.copy_to(self.model)
+ if context is not None:
+ print(f"{context}: Switched to EMA weights")
+ try:
+ yield None
+ finally:
+ if self.use_ema:
+ self.model_ema.restore(self.model.parameters())
+ if context is not None:
+ print(f"{context}: Restored training weights")
+
+ def init_from_ckpt(self, path, ignore_keys=list(), only_model=False):
+ sd = torch.load(path, map_location="cpu")
+ if "state_dict" in list(sd.keys()):
+ sd = sd["state_dict"]
+ keys = list(sd.keys())
+ for k in keys:
+ for ik in ignore_keys:
+ if k.startswith(ik):
+ print("Deleting key {} from state_dict.".format(k))
+ del sd[k]
+ missing, unexpected = self.load_state_dict(sd, strict=False) if not only_model else self.model.load_state_dict(
+ sd, strict=False)
+ print(f"Restored from {path} with {len(missing)} missing and {len(unexpected)} unexpected keys")
+ if len(missing) > 0:
+ print(f"Missing Keys: {missing}")
+ if len(unexpected) > 0:
+ print(f"Unexpected Keys: {unexpected}")
+
+ def q_mean_variance(self, x_start, t):
+ """
+ Get the distribution q(x_t | x_0).
+ :param x_start: the [N x C x ...] tensor of noiseless inputs.
+ :param t: the number of diffusion steps (minus 1). Here, 0 means one step.
+ :return: A tuple (mean, variance, log_variance), all of x_start's shape.
+ """
+ mean = (extract_into_tensor(self.sqrt_alphas_cumprod, t, x_start.shape) * x_start)
+ variance = extract_into_tensor(1.0 - self.alphas_cumprod, t, x_start.shape)
+ log_variance = extract_into_tensor(self.log_one_minus_alphas_cumprod, t, x_start.shape)
+ return mean, variance, log_variance
+
+ def predict_start_from_noise(self, x_t, t, noise):
+ return (
+ extract_into_tensor(self.sqrt_recip_alphas_cumprod, t, x_t.shape) * x_t -
+ extract_into_tensor(self.sqrt_recipm1_alphas_cumprod, t, x_t.shape) * noise
+ )
+
+ def q_posterior(self, x_start, x_t, t):
+ posterior_mean = (
+ extract_into_tensor(self.posterior_mean_coef1, t, x_t.shape) * x_start +
+ extract_into_tensor(self.posterior_mean_coef2, t, x_t.shape) * x_t
+ )
+ posterior_variance = extract_into_tensor(self.posterior_variance, t, x_t.shape)
+ posterior_log_variance_clipped = extract_into_tensor(self.posterior_log_variance_clipped, t, x_t.shape)
+ return posterior_mean, posterior_variance, posterior_log_variance_clipped
+
+ def p_mean_variance(self, x, t, clip_denoised: bool):
+ model_out = self.model(x, t)
+ if self.parameterization == "eps":
+ x_recon = self.predict_start_from_noise(x, t=t, noise=model_out)
+ elif self.parameterization == "x0":
+ x_recon = model_out
+ if clip_denoised:
+ x_recon.clamp_(-1., 1.)
+
+ model_mean, posterior_variance, posterior_log_variance = self.q_posterior(x_start=x_recon, x_t=x, t=t)
+ return model_mean, posterior_variance, posterior_log_variance
+
+ @torch.no_grad()
+ def p_sample(self, x, t, clip_denoised=True, repeat_noise=False):
+ b, *_, device = *x.shape, x.device
+ model_mean, _, model_log_variance = self.p_mean_variance(x=x, t=t, clip_denoised=clip_denoised)
+ noise = noise_like(x.shape, device, repeat_noise)
+ # no noise when t == 0
+ nonzero_mask = (1 - (t == 0).float()).reshape(b, *((1,) * (len(x.shape) - 1)))
+ return model_mean + nonzero_mask * (0.5 * model_log_variance).exp() * noise
+
+ @torch.no_grad()
+ def p_sample_loop(self, shape, return_intermediates=False):
+ device = self.betas.device
+ b = shape[0]
+ img = torch.randn(shape, device=device)
+ intermediates = [img]
+ for i in tqdm(reversed(range(0, self.num_timesteps)), desc='Sampling t', total=self.num_timesteps):
+ img = self.p_sample(img, torch.full((b,), i, device=device, dtype=torch.long),
+ clip_denoised=self.clip_denoised)
+ if i % self.log_every_t == 0 or i == self.num_timesteps - 1:
+ intermediates.append(img)
+ if return_intermediates:
+ return img, intermediates
+ return img
+
+ @torch.no_grad()
+ def sample(self, batch_size=16, return_intermediates=False):
+ image_size = self.image_size
+ channels = self.channels
+ return self.p_sample_loop((batch_size, channels, image_size, image_size),
+ return_intermediates=return_intermediates)
+
+ def q_sample(self, x_start, t, noise=None):
+ noise = default(noise, lambda: torch.randn_like(x_start))
+ return (extract_into_tensor(self.sqrt_alphas_cumprod, t, x_start.shape) * x_start +
+ extract_into_tensor(self.sqrt_one_minus_alphas_cumprod, t, x_start.shape) * noise)
+
+ def get_loss(self, pred, target, mean=True):
+ if self.loss_type == 'l1':
+ loss = (target - pred).abs()
+ if mean:
+ loss = loss.mean()
+ elif self.loss_type == 'l2':
+ if mean:
+ loss = torch.nn.functional.mse_loss(target, pred)
+ else:
+ loss = torch.nn.functional.mse_loss(target, pred, reduction='none')
+ else:
+ raise NotImplementedError("unknown loss type '{loss_type}'")
+
+ return loss
+
+ def p_losses(self, x_start, t, noise=None):
+ noise = default(noise, lambda: torch.randn_like(x_start))
+ x_noisy = self.q_sample(x_start=x_start, t=t, noise=noise)
+ model_out = self.model(x_noisy, t)
+
+ loss_dict = {}
+ if self.parameterization == "eps":
+ target = noise
+ elif self.parameterization == "x0":
+ target = x_start
+ else:
+ raise NotImplementedError(f"Paramterization {self.parameterization} not yet supported")
+
+ loss = self.get_loss(model_out, target, mean=False).mean(dim=[1, 2, 3])
+
+ log_prefix = 'train' if self.training else 'val'
+
+ loss_dict.update({f'{log_prefix}/loss_simple': loss.mean()})
+ loss_simple = loss.mean() * self.l_simple_weight
+
+ loss_vlb = (self.lvlb_weights[t] * loss).mean()
+ loss_dict.update({f'{log_prefix}/loss_vlb': loss_vlb})
+
+ loss = loss_simple + self.original_elbo_weight * loss_vlb
+
+ loss_dict.update({f'{log_prefix}/loss': loss})
+
+ return loss, loss_dict
+
+ def forward(self, x, *args, **kwargs):
+ # b, c, h, w, device, img_size, = *x.shape, x.device, self.image_size
+ # assert h == img_size and w == img_size, f'height and width of image must be {img_size}'
+ t = torch.randint(0, self.num_timesteps, (x.shape[0],), device=self.device).long()
+ return self.p_losses(x, t, *args, **kwargs)
+
+ def get_input(self, batch, k):
+ x = batch[k]
+ if len(x.shape) == 3:
+ x = x[..., None]
+ x = rearrange(x, 'b h w c -> b c h w')
+ x = x.to(memory_format=torch.contiguous_format).float()
+ return x
+
+ def shared_step(self, batch):
+ x = self.get_input(batch, self.first_stage_key)
+ loss, loss_dict = self(x)
+ return loss, loss_dict
+
+ def training_step(self, batch, batch_idx):
+ loss, loss_dict = self.shared_step(batch)
+
+ self.log_dict(loss_dict, prog_bar=True,
+ logger=True, on_step=True, on_epoch=True)
+
+ self.log("global_step", self.global_step,
+ prog_bar=True, logger=True, on_step=True, on_epoch=False)
+
+ if self.use_scheduler:
+ lr = self.optimizers().param_groups[0]['lr']
+ self.log('lr_abs', lr, prog_bar=True, logger=True, on_step=True, on_epoch=False)
+
+ return loss
+
+ @torch.no_grad()
+ def validation_step(self, batch, batch_idx):
+ _, loss_dict_no_ema = self.shared_step(batch)
+ with self.ema_scope():
+ _, loss_dict_ema = self.shared_step(batch)
+ loss_dict_ema = {key + '_ema': loss_dict_ema[key] for key in loss_dict_ema}
+ self.log_dict(loss_dict_no_ema, prog_bar=False, logger=True, on_step=False, on_epoch=True)
+ self.log_dict(loss_dict_ema, prog_bar=False, logger=True, on_step=False, on_epoch=True)
+
+ def on_train_batch_end(self, *args, **kwargs):
+ if self.use_ema:
+ self.model_ema(self.model)
+
+ def _get_rows_from_list(self, samples):
+ n_imgs_per_row = len(samples)
+ denoise_grid = rearrange(samples, 'n b c h w -> b n c h w')
+ denoise_grid = rearrange(denoise_grid, 'b n c h w -> (b n) c h w')
+ denoise_grid = make_grid(denoise_grid, nrow=n_imgs_per_row)
+ return denoise_grid
+
+ @torch.no_grad()
+ def log_images(self, batch, N=8, n_row=2, sample=True, return_keys=None, **kwargs):
+ log = dict()
+ x = self.get_input(batch, self.first_stage_key)
+ N = min(x.shape[0], N)
+ n_row = min(x.shape[0], n_row)
+ x = x.to(self.device)[:N]
+ log["inputs"] = x
+
+ # get diffusion row
+ diffusion_row = list()
+ x_start = x[:n_row]
+
+ for t in range(self.num_timesteps):
+ if t % self.log_every_t == 0 or t == self.num_timesteps - 1:
+ t = repeat(torch.tensor([t]), '1 -> b', b=n_row)
+ t = t.to(self.device).long()
+ noise = torch.randn_like(x_start)
+ x_noisy = self.q_sample(x_start=x_start, t=t, noise=noise)
+ diffusion_row.append(x_noisy)
+
+ log["diffusion_row"] = self._get_rows_from_list(diffusion_row)
+
+ if sample:
+ # get denoise row
+ with self.ema_scope("Plotting"):
+ samples, denoise_row = self.sample(batch_size=N, return_intermediates=True)
+
+ log["samples"] = samples
+ log["denoise_row"] = self._get_rows_from_list(denoise_row)
+
+ if return_keys:
+ if np.intersect1d(list(log.keys()), return_keys).shape[0] == 0:
+ return log
+ else:
+ return {key: log[key] for key in return_keys}
+ return log
+
+ def configure_optimizers(self):
+ lr = self.learning_rate
+ params = list(self.model.parameters())
+ if self.learn_logvar:
+ params = params + [self.logvar]
+ opt = torch.optim.AdamW(params, lr=lr)
+ return opt
+
+
+class LatentDiffusionV1(DDPMV1):
+ """main class"""
+ def __init__(self,
+ first_stage_config,
+ cond_stage_config,
+ num_timesteps_cond=None,
+ cond_stage_key="image",
+ cond_stage_trainable=False,
+ concat_mode=True,
+ cond_stage_forward=None,
+ conditioning_key=None,
+ scale_factor=1.0,
+ scale_by_std=False,
+ *args, **kwargs):
+ self.num_timesteps_cond = default(num_timesteps_cond, 1)
+ self.scale_by_std = scale_by_std
+ assert self.num_timesteps_cond <= kwargs['timesteps']
+ # for backwards compatibility after implementation of DiffusionWrapper
+ if conditioning_key is None:
+ conditioning_key = 'concat' if concat_mode else 'crossattn'
+ if cond_stage_config == '__is_unconditional__':
+ conditioning_key = None
+ ckpt_path = kwargs.pop("ckpt_path", None)
+ ignore_keys = kwargs.pop("ignore_keys", [])
+ super().__init__(conditioning_key=conditioning_key, *args, **kwargs)
+ self.concat_mode = concat_mode
+ self.cond_stage_trainable = cond_stage_trainable
+ self.cond_stage_key = cond_stage_key
+ try:
+ self.num_downs = len(first_stage_config.params.ddconfig.ch_mult) - 1
+ except:
+ self.num_downs = 0
+ if not scale_by_std:
+ self.scale_factor = scale_factor
+ else:
+ self.register_buffer('scale_factor', torch.tensor(scale_factor))
+ self.instantiate_first_stage(first_stage_config)
+ self.instantiate_cond_stage(cond_stage_config)
+ self.cond_stage_forward = cond_stage_forward
+ self.clip_denoised = False
+ self.bbox_tokenizer = None
+
+ self.restarted_from_ckpt = False
+ if ckpt_path is not None:
+ self.init_from_ckpt(ckpt_path, ignore_keys)
+ self.restarted_from_ckpt = True
+
+ def make_cond_schedule(self, ):
+ self.cond_ids = torch.full(size=(self.num_timesteps,), fill_value=self.num_timesteps - 1, dtype=torch.long)
+ ids = torch.round(torch.linspace(0, self.num_timesteps - 1, self.num_timesteps_cond)).long()
+ self.cond_ids[:self.num_timesteps_cond] = ids
+
+ @rank_zero_only
+ @torch.no_grad()
+ def on_train_batch_start(self, batch, batch_idx, dataloader_idx):
+ # only for very first batch
+ if self.scale_by_std and self.current_epoch == 0 and self.global_step == 0 and batch_idx == 0 and not self.restarted_from_ckpt:
+ assert self.scale_factor == 1., 'rather not use custom rescaling and std-rescaling simultaneously'
+ # set rescale weight to 1./std of encodings
+ print("### USING STD-RESCALING ###")
+ x = super().get_input(batch, self.first_stage_key)
+ x = x.to(self.device)
+ encoder_posterior = self.encode_first_stage(x)
+ z = self.get_first_stage_encoding(encoder_posterior).detach()
+ del self.scale_factor
+ self.register_buffer('scale_factor', 1. / z.flatten().std())
+ print(f"setting self.scale_factor to {self.scale_factor}")
+ print("### USING STD-RESCALING ###")
+
+ def register_schedule(self,
+ given_betas=None, beta_schedule="linear", timesteps=1000,
+ linear_start=1e-4, linear_end=2e-2, cosine_s=8e-3):
+ super().register_schedule(given_betas, beta_schedule, timesteps, linear_start, linear_end, cosine_s)
+
+ self.shorten_cond_schedule = self.num_timesteps_cond > 1
+ if self.shorten_cond_schedule:
+ self.make_cond_schedule()
+
+ def instantiate_first_stage(self, config):
+ model = instantiate_from_config(config)
+ self.first_stage_model = model.eval()
+ self.first_stage_model.train = disabled_train
+ for param in self.first_stage_model.parameters():
+ param.requires_grad = False
+
+ def instantiate_cond_stage(self, config):
+ if not self.cond_stage_trainable:
+ if config == "__is_first_stage__":
+ print("Using first stage also as cond stage.")
+ self.cond_stage_model = self.first_stage_model
+ elif config == "__is_unconditional__":
+ print(f"Training {self.__class__.__name__} as an unconditional model.")
+ self.cond_stage_model = None
+ # self.be_unconditional = True
+ else:
+ model = instantiate_from_config(config)
+ self.cond_stage_model = model.eval()
+ self.cond_stage_model.train = disabled_train
+ for param in self.cond_stage_model.parameters():
+ param.requires_grad = False
+ else:
+ assert config != '__is_first_stage__'
+ assert config != '__is_unconditional__'
+ model = instantiate_from_config(config)
+ self.cond_stage_model = model
+
+ def _get_denoise_row_from_list(self, samples, desc='', force_no_decoder_quantization=False):
+ denoise_row = []
+ for zd in tqdm(samples, desc=desc):
+ denoise_row.append(self.decode_first_stage(zd.to(self.device),
+ force_not_quantize=force_no_decoder_quantization))
+ n_imgs_per_row = len(denoise_row)
+ denoise_row = torch.stack(denoise_row) # n_log_step, n_row, C, H, W
+ denoise_grid = rearrange(denoise_row, 'n b c h w -> b n c h w')
+ denoise_grid = rearrange(denoise_grid, 'b n c h w -> (b n) c h w')
+ denoise_grid = make_grid(denoise_grid, nrow=n_imgs_per_row)
+ return denoise_grid
+
+ def get_first_stage_encoding(self, encoder_posterior):
+ if isinstance(encoder_posterior, DiagonalGaussianDistribution):
+ z = encoder_posterior.sample()
+ elif isinstance(encoder_posterior, torch.Tensor):
+ z = encoder_posterior
+ else:
+ raise NotImplementedError(f"encoder_posterior of type '{type(encoder_posterior)}' not yet implemented")
+ return self.scale_factor * z
+
+ def get_learned_conditioning(self, c):
+ if self.cond_stage_forward is None:
+ if hasattr(self.cond_stage_model, 'encode') and callable(self.cond_stage_model.encode):
+ c = self.cond_stage_model.encode(c)
+ if isinstance(c, DiagonalGaussianDistribution):
+ c = c.mode()
+ else:
+ c = self.cond_stage_model(c)
+ else:
+ assert hasattr(self.cond_stage_model, self.cond_stage_forward)
+ c = getattr(self.cond_stage_model, self.cond_stage_forward)(c)
+ return c
+
+ def meshgrid(self, h, w):
+ y = torch.arange(0, h).view(h, 1, 1).repeat(1, w, 1)
+ x = torch.arange(0, w).view(1, w, 1).repeat(h, 1, 1)
+
+ arr = torch.cat([y, x], dim=-1)
+ return arr
+
+ def delta_border(self, h, w):
+ """
+ :param h: height
+ :param w: width
+ :return: normalized distance to image border,
+ wtith min distance = 0 at border and max dist = 0.5 at image center
+ """
+ lower_right_corner = torch.tensor([h - 1, w - 1]).view(1, 1, 2)
+ arr = self.meshgrid(h, w) / lower_right_corner
+ dist_left_up = torch.min(arr, dim=-1, keepdims=True)[0]
+ dist_right_down = torch.min(1 - arr, dim=-1, keepdims=True)[0]
+ edge_dist = torch.min(torch.cat([dist_left_up, dist_right_down], dim=-1), dim=-1)[0]
+ return edge_dist
+
+ def get_weighting(self, h, w, Ly, Lx, device):
+ weighting = self.delta_border(h, w)
+ weighting = torch.clip(weighting, self.split_input_params["clip_min_weight"],
+ self.split_input_params["clip_max_weight"], )
+ weighting = weighting.view(1, h * w, 1).repeat(1, 1, Ly * Lx).to(device)
+
+ if self.split_input_params["tie_braker"]:
+ L_weighting = self.delta_border(Ly, Lx)
+ L_weighting = torch.clip(L_weighting,
+ self.split_input_params["clip_min_tie_weight"],
+ self.split_input_params["clip_max_tie_weight"])
+
+ L_weighting = L_weighting.view(1, 1, Ly * Lx).to(device)
+ weighting = weighting * L_weighting
+ return weighting
+
+ def get_fold_unfold(self, x, kernel_size, stride, uf=1, df=1): # todo load once not every time, shorten code
+ """
+ :param x: img of size (bs, c, h, w)
+ :return: n img crops of size (n, bs, c, kernel_size[0], kernel_size[1])
+ """
+ bs, nc, h, w = x.shape
+
+ # number of crops in image
+ Ly = (h - kernel_size[0]) // stride[0] + 1
+ Lx = (w - kernel_size[1]) // stride[1] + 1
+
+ if uf == 1 and df == 1:
+ fold_params = dict(kernel_size=kernel_size, dilation=1, padding=0, stride=stride)
+ unfold = torch.nn.Unfold(**fold_params)
+
+ fold = torch.nn.Fold(output_size=x.shape[2:], **fold_params)
+
+ weighting = self.get_weighting(kernel_size[0], kernel_size[1], Ly, Lx, x.device).to(x.dtype)
+ normalization = fold(weighting).view(1, 1, h, w) # normalizes the overlap
+ weighting = weighting.view((1, 1, kernel_size[0], kernel_size[1], Ly * Lx))
+
+ elif uf > 1 and df == 1:
+ fold_params = dict(kernel_size=kernel_size, dilation=1, padding=0, stride=stride)
+ unfold = torch.nn.Unfold(**fold_params)
+
+ fold_params2 = dict(kernel_size=(kernel_size[0] * uf, kernel_size[0] * uf),
+ dilation=1, padding=0,
+ stride=(stride[0] * uf, stride[1] * uf))
+ fold = torch.nn.Fold(output_size=(x.shape[2] * uf, x.shape[3] * uf), **fold_params2)
+
+ weighting = self.get_weighting(kernel_size[0] * uf, kernel_size[1] * uf, Ly, Lx, x.device).to(x.dtype)
+ normalization = fold(weighting).view(1, 1, h * uf, w * uf) # normalizes the overlap
+ weighting = weighting.view((1, 1, kernel_size[0] * uf, kernel_size[1] * uf, Ly * Lx))
+
+ elif df > 1 and uf == 1:
+ fold_params = dict(kernel_size=kernel_size, dilation=1, padding=0, stride=stride)
+ unfold = torch.nn.Unfold(**fold_params)
+
+ fold_params2 = dict(kernel_size=(kernel_size[0] // df, kernel_size[0] // df),
+ dilation=1, padding=0,
+ stride=(stride[0] // df, stride[1] // df))
+ fold = torch.nn.Fold(output_size=(x.shape[2] // df, x.shape[3] // df), **fold_params2)
+
+ weighting = self.get_weighting(kernel_size[0] // df, kernel_size[1] // df, Ly, Lx, x.device).to(x.dtype)
+ normalization = fold(weighting).view(1, 1, h // df, w // df) # normalizes the overlap
+ weighting = weighting.view((1, 1, kernel_size[0] // df, kernel_size[1] // df, Ly * Lx))
+
+ else:
+ raise NotImplementedError
+
+ return fold, unfold, normalization, weighting
+
+ @torch.no_grad()
+ def get_input(self, batch, k, return_first_stage_outputs=False, force_c_encode=False,
+ cond_key=None, return_original_cond=False, bs=None):
+ x = super().get_input(batch, k)
+ if bs is not None:
+ x = x[:bs]
+ x = x.to(self.device)
+ encoder_posterior = self.encode_first_stage(x)
+ z = self.get_first_stage_encoding(encoder_posterior).detach()
+
+ if self.model.conditioning_key is not None:
+ if cond_key is None:
+ cond_key = self.cond_stage_key
+ if cond_key != self.first_stage_key:
+ if cond_key in ['caption', 'coordinates_bbox']:
+ xc = batch[cond_key]
+ elif cond_key == 'class_label':
+ xc = batch
+ else:
+ xc = super().get_input(batch, cond_key).to(self.device)
+ else:
+ xc = x
+ if not self.cond_stage_trainable or force_c_encode:
+ if isinstance(xc, dict) or isinstance(xc, list):
+ # import pudb; pudb.set_trace()
+ c = self.get_learned_conditioning(xc)
+ else:
+ c = self.get_learned_conditioning(xc.to(self.device))
+ else:
+ c = xc
+ if bs is not None:
+ c = c[:bs]
+
+ if self.use_positional_encodings:
+ pos_x, pos_y = self.compute_latent_shifts(batch)
+ ckey = __conditioning_keys__[self.model.conditioning_key]
+ c = {ckey: c, 'pos_x': pos_x, 'pos_y': pos_y}
+
+ else:
+ c = None
+ xc = None
+ if self.use_positional_encodings:
+ pos_x, pos_y = self.compute_latent_shifts(batch)
+ c = {'pos_x': pos_x, 'pos_y': pos_y}
+ out = [z, c]
+ if return_first_stage_outputs:
+ xrec = self.decode_first_stage(z)
+ out.extend([x, xrec])
+ if return_original_cond:
+ out.append(xc)
+ return out
+
+ @torch.no_grad()
+ def decode_first_stage(self, z, predict_cids=False, force_not_quantize=False):
+ if predict_cids:
+ if z.dim() == 4:
+ z = torch.argmax(z.exp(), dim=1).long()
+ z = self.first_stage_model.quantize.get_codebook_entry(z, shape=None)
+ z = rearrange(z, 'b h w c -> b c h w').contiguous()
+
+ z = 1. / self.scale_factor * z
+
+ if hasattr(self, "split_input_params"):
+ if self.split_input_params["patch_distributed_vq"]:
+ ks = self.split_input_params["ks"] # eg. (128, 128)
+ stride = self.split_input_params["stride"] # eg. (64, 64)
+ uf = self.split_input_params["vqf"]
+ bs, nc, h, w = z.shape
+ if ks[0] > h or ks[1] > w:
+ ks = (min(ks[0], h), min(ks[1], w))
+ print("reducing Kernel")
+
+ if stride[0] > h or stride[1] > w:
+ stride = (min(stride[0], h), min(stride[1], w))
+ print("reducing stride")
+
+ fold, unfold, normalization, weighting = self.get_fold_unfold(z, ks, stride, uf=uf)
+
+ z = unfold(z) # (bn, nc * prod(**ks), L)
+ # 1. Reshape to img shape
+ z = z.view((z.shape[0], -1, ks[0], ks[1], z.shape[-1])) # (bn, nc, ks[0], ks[1], L )
+
+ # 2. apply model loop over last dim
+ if isinstance(self.first_stage_model, VQModelInterface):
+ output_list = [self.first_stage_model.decode(z[:, :, :, :, i],
+ force_not_quantize=predict_cids or force_not_quantize)
+ for i in range(z.shape[-1])]
+ else:
+
+ output_list = [self.first_stage_model.decode(z[:, :, :, :, i])
+ for i in range(z.shape[-1])]
+
+ o = torch.stack(output_list, axis=-1) # # (bn, nc, ks[0], ks[1], L)
+ o = o * weighting
+ # Reverse 1. reshape to img shape
+ o = o.view((o.shape[0], -1, o.shape[-1])) # (bn, nc * ks[0] * ks[1], L)
+ # stitch crops together
+ decoded = fold(o)
+ decoded = decoded / normalization # norm is shape (1, 1, h, w)
+ return decoded
+ else:
+ if isinstance(self.first_stage_model, VQModelInterface):
+ return self.first_stage_model.decode(z, force_not_quantize=predict_cids or force_not_quantize)
+ else:
+ return self.first_stage_model.decode(z)
+
+ else:
+ if isinstance(self.first_stage_model, VQModelInterface):
+ return self.first_stage_model.decode(z, force_not_quantize=predict_cids or force_not_quantize)
+ else:
+ return self.first_stage_model.decode(z)
+
+ # same as above but without decorator
+ def differentiable_decode_first_stage(self, z, predict_cids=False, force_not_quantize=False):
+ if predict_cids:
+ if z.dim() == 4:
+ z = torch.argmax(z.exp(), dim=1).long()
+ z = self.first_stage_model.quantize.get_codebook_entry(z, shape=None)
+ z = rearrange(z, 'b h w c -> b c h w').contiguous()
+
+ z = 1. / self.scale_factor * z
+
+ if hasattr(self, "split_input_params"):
+ if self.split_input_params["patch_distributed_vq"]:
+ ks = self.split_input_params["ks"] # eg. (128, 128)
+ stride = self.split_input_params["stride"] # eg. (64, 64)
+ uf = self.split_input_params["vqf"]
+ bs, nc, h, w = z.shape
+ if ks[0] > h or ks[1] > w:
+ ks = (min(ks[0], h), min(ks[1], w))
+ print("reducing Kernel")
+
+ if stride[0] > h or stride[1] > w:
+ stride = (min(stride[0], h), min(stride[1], w))
+ print("reducing stride")
+
+ fold, unfold, normalization, weighting = self.get_fold_unfold(z, ks, stride, uf=uf)
+
+ z = unfold(z) # (bn, nc * prod(**ks), L)
+ # 1. Reshape to img shape
+ z = z.view((z.shape[0], -1, ks[0], ks[1], z.shape[-1])) # (bn, nc, ks[0], ks[1], L )
+
+ # 2. apply model loop over last dim
+ if isinstance(self.first_stage_model, VQModelInterface):
+ output_list = [self.first_stage_model.decode(z[:, :, :, :, i],
+ force_not_quantize=predict_cids or force_not_quantize)
+ for i in range(z.shape[-1])]
+ else:
+
+ output_list = [self.first_stage_model.decode(z[:, :, :, :, i])
+ for i in range(z.shape[-1])]
+
+ o = torch.stack(output_list, axis=-1) # # (bn, nc, ks[0], ks[1], L)
+ o = o * weighting
+ # Reverse 1. reshape to img shape
+ o = o.view((o.shape[0], -1, o.shape[-1])) # (bn, nc * ks[0] * ks[1], L)
+ # stitch crops together
+ decoded = fold(o)
+ decoded = decoded / normalization # norm is shape (1, 1, h, w)
+ return decoded
+ else:
+ if isinstance(self.first_stage_model, VQModelInterface):
+ return self.first_stage_model.decode(z, force_not_quantize=predict_cids or force_not_quantize)
+ else:
+ return self.first_stage_model.decode(z)
+
+ else:
+ if isinstance(self.first_stage_model, VQModelInterface):
+ return self.first_stage_model.decode(z, force_not_quantize=predict_cids or force_not_quantize)
+ else:
+ return self.first_stage_model.decode(z)
+
+ @torch.no_grad()
+ def encode_first_stage(self, x):
+ if hasattr(self, "split_input_params"):
+ if self.split_input_params["patch_distributed_vq"]:
+ ks = self.split_input_params["ks"] # eg. (128, 128)
+ stride = self.split_input_params["stride"] # eg. (64, 64)
+ df = self.split_input_params["vqf"]
+ self.split_input_params['original_image_size'] = x.shape[-2:]
+ bs, nc, h, w = x.shape
+ if ks[0] > h or ks[1] > w:
+ ks = (min(ks[0], h), min(ks[1], w))
+ print("reducing Kernel")
+
+ if stride[0] > h or stride[1] > w:
+ stride = (min(stride[0], h), min(stride[1], w))
+ print("reducing stride")
+
+ fold, unfold, normalization, weighting = self.get_fold_unfold(x, ks, stride, df=df)
+ z = unfold(x) # (bn, nc * prod(**ks), L)
+ # Reshape to img shape
+ z = z.view((z.shape[0], -1, ks[0], ks[1], z.shape[-1])) # (bn, nc, ks[0], ks[1], L )
+
+ output_list = [self.first_stage_model.encode(z[:, :, :, :, i])
+ for i in range(z.shape[-1])]
+
+ o = torch.stack(output_list, axis=-1)
+ o = o * weighting
+
+ # Reverse reshape to img shape
+ o = o.view((o.shape[0], -1, o.shape[-1])) # (bn, nc * ks[0] * ks[1], L)
+ # stitch crops together
+ decoded = fold(o)
+ decoded = decoded / normalization
+ return decoded
+
+ else:
+ return self.first_stage_model.encode(x)
+ else:
+ return self.first_stage_model.encode(x)
+
+ def shared_step(self, batch, **kwargs):
+ x, c = self.get_input(batch, self.first_stage_key)
+ loss = self(x, c)
+ return loss
+
+ def forward(self, x, c, *args, **kwargs):
+ t = torch.randint(0, self.num_timesteps, (x.shape[0],), device=self.device).long()
+ if self.model.conditioning_key is not None:
+ assert c is not None
+ if self.cond_stage_trainable:
+ c = self.get_learned_conditioning(c)
+ if self.shorten_cond_schedule: # TODO: drop this option
+ tc = self.cond_ids[t].to(self.device)
+ c = self.q_sample(x_start=c, t=tc, noise=torch.randn_like(c.float()))
+ return self.p_losses(x, c, t, *args, **kwargs)
+
+ def _rescale_annotations(self, bboxes, crop_coordinates): # TODO: move to dataset
+ def rescale_bbox(bbox):
+ x0 = clamp((bbox[0] - crop_coordinates[0]) / crop_coordinates[2])
+ y0 = clamp((bbox[1] - crop_coordinates[1]) / crop_coordinates[3])
+ w = min(bbox[2] / crop_coordinates[2], 1 - x0)
+ h = min(bbox[3] / crop_coordinates[3], 1 - y0)
+ return x0, y0, w, h
+
+ return [rescale_bbox(b) for b in bboxes]
+
+ def apply_model(self, x_noisy, t, cond, return_ids=False):
+
+ if isinstance(cond, dict):
+ # hybrid case, cond is exptected to be a dict
+ pass
+ else:
+ if not isinstance(cond, list):
+ cond = [cond]
+ key = 'c_concat' if self.model.conditioning_key == 'concat' else 'c_crossattn'
+ cond = {key: cond}
+
+ if hasattr(self, "split_input_params"):
+ assert len(cond) == 1 # todo can only deal with one conditioning atm
+ assert not return_ids
+ ks = self.split_input_params["ks"] # eg. (128, 128)
+ stride = self.split_input_params["stride"] # eg. (64, 64)
+
+ h, w = x_noisy.shape[-2:]
+
+ fold, unfold, normalization, weighting = self.get_fold_unfold(x_noisy, ks, stride)
+
+ z = unfold(x_noisy) # (bn, nc * prod(**ks), L)
+ # Reshape to img shape
+ z = z.view((z.shape[0], -1, ks[0], ks[1], z.shape[-1])) # (bn, nc, ks[0], ks[1], L )
+ z_list = [z[:, :, :, :, i] for i in range(z.shape[-1])]
+
+ if self.cond_stage_key in ["image", "LR_image", "segmentation",
+ 'bbox_img'] and self.model.conditioning_key: # todo check for completeness
+ c_key = next(iter(cond.keys())) # get key
+ c = next(iter(cond.values())) # get value
+ assert (len(c) == 1) # todo extend to list with more than one elem
+ c = c[0] # get element
+
+ c = unfold(c)
+ c = c.view((c.shape[0], -1, ks[0], ks[1], c.shape[-1])) # (bn, nc, ks[0], ks[1], L )
+
+ cond_list = [{c_key: [c[:, :, :, :, i]]} for i in range(c.shape[-1])]
+
+ elif self.cond_stage_key == 'coordinates_bbox':
+ assert 'original_image_size' in self.split_input_params, 'BoudingBoxRescaling is missing original_image_size'
+
+ # assuming padding of unfold is always 0 and its dilation is always 1
+ n_patches_per_row = int((w - ks[0]) / stride[0] + 1)
+ full_img_h, full_img_w = self.split_input_params['original_image_size']
+ # as we are operating on latents, we need the factor from the original image size to the
+ # spatial latent size to properly rescale the crops for regenerating the bbox annotations
+ num_downs = self.first_stage_model.encoder.num_resolutions - 1
+ rescale_latent = 2 ** (num_downs)
+
+ # get top left postions of patches as conforming for the bbbox tokenizer, therefore we
+ # need to rescale the tl patch coordinates to be in between (0,1)
+ tl_patch_coordinates = [(rescale_latent * stride[0] * (patch_nr % n_patches_per_row) / full_img_w,
+ rescale_latent * stride[1] * (patch_nr // n_patches_per_row) / full_img_h)
+ for patch_nr in range(z.shape[-1])]
+
+ # patch_limits are tl_coord, width and height coordinates as (x_tl, y_tl, h, w)
+ patch_limits = [(x_tl, y_tl,
+ rescale_latent * ks[0] / full_img_w,
+ rescale_latent * ks[1] / full_img_h) for x_tl, y_tl in tl_patch_coordinates]
+ # patch_values = [(np.arange(x_tl,min(x_tl+ks, 1.)),np.arange(y_tl,min(y_tl+ks, 1.))) for x_tl, y_tl in tl_patch_coordinates]
+
+ # tokenize crop coordinates for the bounding boxes of the respective patches
+ patch_limits_tknzd = [torch.LongTensor(self.bbox_tokenizer._crop_encoder(bbox))[None].to(self.device)
+ for bbox in patch_limits] # list of length l with tensors of shape (1, 2)
+ print(patch_limits_tknzd[0].shape)
+ # cut tknzd crop position from conditioning
+ assert isinstance(cond, dict), 'cond must be dict to be fed into model'
+ cut_cond = cond['c_crossattn'][0][..., :-2].to(self.device)
+ print(cut_cond.shape)
+
+ adapted_cond = torch.stack([torch.cat([cut_cond, p], dim=1) for p in patch_limits_tknzd])
+ adapted_cond = rearrange(adapted_cond, 'l b n -> (l b) n')
+ print(adapted_cond.shape)
+ adapted_cond = self.get_learned_conditioning(adapted_cond)
+ print(adapted_cond.shape)
+ adapted_cond = rearrange(adapted_cond, '(l b) n d -> l b n d', l=z.shape[-1])
+ print(adapted_cond.shape)
+
+ cond_list = [{'c_crossattn': [e]} for e in adapted_cond]
+
+ else:
+ cond_list = [cond for i in range(z.shape[-1])] # Todo make this more efficient
+
+ # apply model by loop over crops
+ output_list = [self.model(z_list[i], t, **cond_list[i]) for i in range(z.shape[-1])]
+ assert not isinstance(output_list[0],
+ tuple) # todo cant deal with multiple model outputs check this never happens
+
+ o = torch.stack(output_list, axis=-1)
+ o = o * weighting
+ # Reverse reshape to img shape
+ o = o.view((o.shape[0], -1, o.shape[-1])) # (bn, nc * ks[0] * ks[1], L)
+ # stitch crops together
+ x_recon = fold(o) / normalization
+
+ else:
+ x_recon = self.model(x_noisy, t, **cond)
+
+ if isinstance(x_recon, tuple) and not return_ids:
+ return x_recon[0]
+ else:
+ return x_recon
+
+ def _predict_eps_from_xstart(self, x_t, t, pred_xstart):
+ return (extract_into_tensor(self.sqrt_recip_alphas_cumprod, t, x_t.shape) * x_t - pred_xstart) / \
+ extract_into_tensor(self.sqrt_recipm1_alphas_cumprod, t, x_t.shape)
+
+ def _prior_bpd(self, x_start):
+ """
+ Get the prior KL term for the variational lower-bound, measured in
+ bits-per-dim.
+ This term can't be optimized, as it only depends on the encoder.
+ :param x_start: the [N x C x ...] tensor of inputs.
+ :return: a batch of [N] KL values (in bits), one per batch element.
+ """
+ batch_size = x_start.shape[0]
+ t = torch.tensor([self.num_timesteps - 1] * batch_size, device=x_start.device)
+ qt_mean, _, qt_log_variance = self.q_mean_variance(x_start, t)
+ kl_prior = normal_kl(mean1=qt_mean, logvar1=qt_log_variance, mean2=0.0, logvar2=0.0)
+ return mean_flat(kl_prior) / np.log(2.0)
+
+ def p_losses(self, x_start, cond, t, noise=None):
+ noise = default(noise, lambda: torch.randn_like(x_start))
+ x_noisy = self.q_sample(x_start=x_start, t=t, noise=noise)
+ model_output = self.apply_model(x_noisy, t, cond)
+
+ loss_dict = {}
+ prefix = 'train' if self.training else 'val'
+
+ if self.parameterization == "x0":
+ target = x_start
+ elif self.parameterization == "eps":
+ target = noise
+ else:
+ raise NotImplementedError()
+
+ loss_simple = self.get_loss(model_output, target, mean=False).mean([1, 2, 3])
+ loss_dict.update({f'{prefix}/loss_simple': loss_simple.mean()})
+
+ logvar_t = self.logvar[t].to(self.device)
+ loss = loss_simple / torch.exp(logvar_t) + logvar_t
+ # loss = loss_simple / torch.exp(self.logvar) + self.logvar
+ if self.learn_logvar:
+ loss_dict.update({f'{prefix}/loss_gamma': loss.mean()})
+ loss_dict.update({'logvar': self.logvar.data.mean()})
+
+ loss = self.l_simple_weight * loss.mean()
+
+ loss_vlb = self.get_loss(model_output, target, mean=False).mean(dim=(1, 2, 3))
+ loss_vlb = (self.lvlb_weights[t] * loss_vlb).mean()
+ loss_dict.update({f'{prefix}/loss_vlb': loss_vlb})
+ loss += (self.original_elbo_weight * loss_vlb)
+ loss_dict.update({f'{prefix}/loss': loss})
+
+ return loss, loss_dict
+
+ def p_mean_variance(self, x, c, t, clip_denoised: bool, return_codebook_ids=False, quantize_denoised=False,
+ return_x0=False, score_corrector=None, corrector_kwargs=None):
+ t_in = t
+ model_out = self.apply_model(x, t_in, c, return_ids=return_codebook_ids)
+
+ if score_corrector is not None:
+ assert self.parameterization == "eps"
+ model_out = score_corrector.modify_score(self, model_out, x, t, c, **corrector_kwargs)
+
+ if return_codebook_ids:
+ model_out, logits = model_out
+
+ if self.parameterization == "eps":
+ x_recon = self.predict_start_from_noise(x, t=t, noise=model_out)
+ elif self.parameterization == "x0":
+ x_recon = model_out
+ else:
+ raise NotImplementedError()
+
+ if clip_denoised:
+ x_recon.clamp_(-1., 1.)
+ if quantize_denoised:
+ x_recon, _, [_, _, indices] = self.first_stage_model.quantize(x_recon)
+ model_mean, posterior_variance, posterior_log_variance = self.q_posterior(x_start=x_recon, x_t=x, t=t)
+ if return_codebook_ids:
+ return model_mean, posterior_variance, posterior_log_variance, logits
+ elif return_x0:
+ return model_mean, posterior_variance, posterior_log_variance, x_recon
+ else:
+ return model_mean, posterior_variance, posterior_log_variance
+
+ @torch.no_grad()
+ def p_sample(self, x, c, t, clip_denoised=False, repeat_noise=False,
+ return_codebook_ids=False, quantize_denoised=False, return_x0=False,
+ temperature=1., noise_dropout=0., score_corrector=None, corrector_kwargs=None):
+ b, *_, device = *x.shape, x.device
+ outputs = self.p_mean_variance(x=x, c=c, t=t, clip_denoised=clip_denoised,
+ return_codebook_ids=return_codebook_ids,
+ quantize_denoised=quantize_denoised,
+ return_x0=return_x0,
+ score_corrector=score_corrector, corrector_kwargs=corrector_kwargs)
+ if return_codebook_ids:
+ raise DeprecationWarning("Support dropped.")
+ model_mean, _, model_log_variance, logits = outputs
+ elif return_x0:
+ model_mean, _, model_log_variance, x0 = outputs
+ else:
+ model_mean, _, model_log_variance = outputs
+
+ noise = noise_like(x.shape, device, repeat_noise) * temperature
+ if noise_dropout > 0.:
+ noise = torch.nn.functional.dropout(noise, p=noise_dropout)
+ # no noise when t == 0
+ nonzero_mask = (1 - (t == 0).float()).reshape(b, *((1,) * (len(x.shape) - 1)))
+
+ if return_codebook_ids:
+ return model_mean + nonzero_mask * (0.5 * model_log_variance).exp() * noise, logits.argmax(dim=1)
+ if return_x0:
+ return model_mean + nonzero_mask * (0.5 * model_log_variance).exp() * noise, x0
+ else:
+ return model_mean + nonzero_mask * (0.5 * model_log_variance).exp() * noise
+
+ @torch.no_grad()
+ def progressive_denoising(self, cond, shape, verbose=True, callback=None, quantize_denoised=False,
+ img_callback=None, mask=None, x0=None, temperature=1., noise_dropout=0.,
+ score_corrector=None, corrector_kwargs=None, batch_size=None, x_T=None, start_T=None,
+ log_every_t=None):
+ if not log_every_t:
+ log_every_t = self.log_every_t
+ timesteps = self.num_timesteps
+ if batch_size is not None:
+ b = batch_size if batch_size is not None else shape[0]
+ shape = [batch_size] + list(shape)
+ else:
+ b = batch_size = shape[0]
+ if x_T is None:
+ img = torch.randn(shape, device=self.device)
+ else:
+ img = x_T
+ intermediates = []
+ if cond is not None:
+ if isinstance(cond, dict):
+ cond = {key: cond[key][:batch_size] if not isinstance(cond[key], list) else
+ list(map(lambda x: x[:batch_size], cond[key])) for key in cond}
+ else:
+ cond = [c[:batch_size] for c in cond] if isinstance(cond, list) else cond[:batch_size]
+
+ if start_T is not None:
+ timesteps = min(timesteps, start_T)
+ iterator = tqdm(reversed(range(0, timesteps)), desc='Progressive Generation',
+ total=timesteps) if verbose else reversed(
+ range(0, timesteps))
+ if type(temperature) == float:
+ temperature = [temperature] * timesteps
+
+ for i in iterator:
+ ts = torch.full((b,), i, device=self.device, dtype=torch.long)
+ if self.shorten_cond_schedule:
+ assert self.model.conditioning_key != 'hybrid'
+ tc = self.cond_ids[ts].to(cond.device)
+ cond = self.q_sample(x_start=cond, t=tc, noise=torch.randn_like(cond))
+
+ img, x0_partial = self.p_sample(img, cond, ts,
+ clip_denoised=self.clip_denoised,
+ quantize_denoised=quantize_denoised, return_x0=True,
+ temperature=temperature[i], noise_dropout=noise_dropout,
+ score_corrector=score_corrector, corrector_kwargs=corrector_kwargs)
+ if mask is not None:
+ assert x0 is not None
+ img_orig = self.q_sample(x0, ts)
+ img = img_orig * mask + (1. - mask) * img
+
+ if i % log_every_t == 0 or i == timesteps - 1:
+ intermediates.append(x0_partial)
+ if callback: callback(i)
+ if img_callback: img_callback(img, i)
+ return img, intermediates
+
+ @torch.no_grad()
+ def p_sample_loop(self, cond, shape, return_intermediates=False,
+ x_T=None, verbose=True, callback=None, timesteps=None, quantize_denoised=False,
+ mask=None, x0=None, img_callback=None, start_T=None,
+ log_every_t=None):
+
+ if not log_every_t:
+ log_every_t = self.log_every_t
+ device = self.betas.device
+ b = shape[0]
+ if x_T is None:
+ img = torch.randn(shape, device=device)
+ else:
+ img = x_T
+
+ intermediates = [img]
+ if timesteps is None:
+ timesteps = self.num_timesteps
+
+ if start_T is not None:
+ timesteps = min(timesteps, start_T)
+ iterator = tqdm(reversed(range(0, timesteps)), desc='Sampling t', total=timesteps) if verbose else reversed(
+ range(0, timesteps))
+
+ if mask is not None:
+ assert x0 is not None
+ assert x0.shape[2:3] == mask.shape[2:3] # spatial size has to match
+
+ for i in iterator:
+ ts = torch.full((b,), i, device=device, dtype=torch.long)
+ if self.shorten_cond_schedule:
+ assert self.model.conditioning_key != 'hybrid'
+ tc = self.cond_ids[ts].to(cond.device)
+ cond = self.q_sample(x_start=cond, t=tc, noise=torch.randn_like(cond))
+
+ img = self.p_sample(img, cond, ts,
+ clip_denoised=self.clip_denoised,
+ quantize_denoised=quantize_denoised)
+ if mask is not None:
+ img_orig = self.q_sample(x0, ts)
+ img = img_orig * mask + (1. - mask) * img
+
+ if i % log_every_t == 0 or i == timesteps - 1:
+ intermediates.append(img)
+ if callback: callback(i)
+ if img_callback: img_callback(img, i)
+
+ if return_intermediates:
+ return img, intermediates
+ return img
+
+ @torch.no_grad()
+ def sample(self, cond, batch_size=16, return_intermediates=False, x_T=None,
+ verbose=True, timesteps=None, quantize_denoised=False,
+ mask=None, x0=None, shape=None,**kwargs):
+ if shape is None:
+ shape = (batch_size, self.channels, self.image_size, self.image_size)
+ if cond is not None:
+ if isinstance(cond, dict):
+ cond = {key: cond[key][:batch_size] if not isinstance(cond[key], list) else
+ list(map(lambda x: x[:batch_size], cond[key])) for key in cond}
+ else:
+ cond = [c[:batch_size] for c in cond] if isinstance(cond, list) else cond[:batch_size]
+ return self.p_sample_loop(cond,
+ shape,
+ return_intermediates=return_intermediates, x_T=x_T,
+ verbose=verbose, timesteps=timesteps, quantize_denoised=quantize_denoised,
+ mask=mask, x0=x0)
+
+ @torch.no_grad()
+ def sample_log(self,cond,batch_size,ddim, ddim_steps,**kwargs):
+
+ if ddim:
+ ddim_sampler = DDIMSampler(self)
+ shape = (self.channels, self.image_size, self.image_size)
+ samples, intermediates =ddim_sampler.sample(ddim_steps,batch_size,
+ shape,cond,verbose=False,**kwargs)
+
+ else:
+ samples, intermediates = self.sample(cond=cond, batch_size=batch_size,
+ return_intermediates=True,**kwargs)
+
+ return samples, intermediates
+
+
+ @torch.no_grad()
+ def log_images(self, batch, N=8, n_row=4, sample=True, ddim_steps=200, ddim_eta=1., return_keys=None,
+ quantize_denoised=True, inpaint=True, plot_denoise_rows=False, plot_progressive_rows=True,
+ plot_diffusion_rows=True, **kwargs):
+
+ use_ddim = ddim_steps is not None
+
+ log = dict()
+ z, c, x, xrec, xc = self.get_input(batch, self.first_stage_key,
+ return_first_stage_outputs=True,
+ force_c_encode=True,
+ return_original_cond=True,
+ bs=N)
+ N = min(x.shape[0], N)
+ n_row = min(x.shape[0], n_row)
+ log["inputs"] = x
+ log["reconstruction"] = xrec
+ if self.model.conditioning_key is not None:
+ if hasattr(self.cond_stage_model, "decode"):
+ xc = self.cond_stage_model.decode(c)
+ log["conditioning"] = xc
+ elif self.cond_stage_key in ["caption"]:
+ xc = log_txt_as_img((x.shape[2], x.shape[3]), batch["caption"])
+ log["conditioning"] = xc
+ elif self.cond_stage_key == 'class_label':
+ xc = log_txt_as_img((x.shape[2], x.shape[3]), batch["human_label"])
+ log['conditioning'] = xc
+ elif isimage(xc):
+ log["conditioning"] = xc
+ if ismap(xc):
+ log["original_conditioning"] = self.to_rgb(xc)
+
+ if plot_diffusion_rows:
+ # get diffusion row
+ diffusion_row = list()
+ z_start = z[:n_row]
+ for t in range(self.num_timesteps):
+ if t % self.log_every_t == 0 or t == self.num_timesteps - 1:
+ t = repeat(torch.tensor([t]), '1 -> b', b=n_row)
+ t = t.to(self.device).long()
+ noise = torch.randn_like(z_start)
+ z_noisy = self.q_sample(x_start=z_start, t=t, noise=noise)
+ diffusion_row.append(self.decode_first_stage(z_noisy))
+
+ diffusion_row = torch.stack(diffusion_row) # n_log_step, n_row, C, H, W
+ diffusion_grid = rearrange(diffusion_row, 'n b c h w -> b n c h w')
+ diffusion_grid = rearrange(diffusion_grid, 'b n c h w -> (b n) c h w')
+ diffusion_grid = make_grid(diffusion_grid, nrow=diffusion_row.shape[0])
+ log["diffusion_row"] = diffusion_grid
+
+ if sample:
+ # get denoise row
+ with self.ema_scope("Plotting"):
+ samples, z_denoise_row = self.sample_log(cond=c,batch_size=N,ddim=use_ddim,
+ ddim_steps=ddim_steps,eta=ddim_eta)
+ # samples, z_denoise_row = self.sample(cond=c, batch_size=N, return_intermediates=True)
+ x_samples = self.decode_first_stage(samples)
+ log["samples"] = x_samples
+ if plot_denoise_rows:
+ denoise_grid = self._get_denoise_row_from_list(z_denoise_row)
+ log["denoise_row"] = denoise_grid
+
+ if quantize_denoised and not isinstance(self.first_stage_model, AutoencoderKL) and not isinstance(
+ self.first_stage_model, IdentityFirstStage):
+ # also display when quantizing x0 while sampling
+ with self.ema_scope("Plotting Quantized Denoised"):
+ samples, z_denoise_row = self.sample_log(cond=c,batch_size=N,ddim=use_ddim,
+ ddim_steps=ddim_steps,eta=ddim_eta,
+ quantize_denoised=True)
+ # samples, z_denoise_row = self.sample(cond=c, batch_size=N, return_intermediates=True,
+ # quantize_denoised=True)
+ x_samples = self.decode_first_stage(samples.to(self.device))
+ log["samples_x0_quantized"] = x_samples
+
+ if inpaint:
+ # make a simple center square
+ b, h, w = z.shape[0], z.shape[2], z.shape[3]
+ mask = torch.ones(N, h, w).to(self.device)
+ # zeros will be filled in
+ mask[:, h // 4:3 * h // 4, w // 4:3 * w // 4] = 0.
+ mask = mask[:, None, ...]
+ with self.ema_scope("Plotting Inpaint"):
+
+ samples, _ = self.sample_log(cond=c,batch_size=N,ddim=use_ddim, eta=ddim_eta,
+ ddim_steps=ddim_steps, x0=z[:N], mask=mask)
+ x_samples = self.decode_first_stage(samples.to(self.device))
+ log["samples_inpainting"] = x_samples
+ log["mask"] = mask
+
+ # outpaint
+ with self.ema_scope("Plotting Outpaint"):
+ samples, _ = self.sample_log(cond=c, batch_size=N, ddim=use_ddim,eta=ddim_eta,
+ ddim_steps=ddim_steps, x0=z[:N], mask=mask)
+ x_samples = self.decode_first_stage(samples.to(self.device))
+ log["samples_outpainting"] = x_samples
+
+ if plot_progressive_rows:
+ with self.ema_scope("Plotting Progressives"):
+ img, progressives = self.progressive_denoising(c,
+ shape=(self.channels, self.image_size, self.image_size),
+ batch_size=N)
+ prog_row = self._get_denoise_row_from_list(progressives, desc="Progressive Generation")
+ log["progressive_row"] = prog_row
+
+ if return_keys:
+ if np.intersect1d(list(log.keys()), return_keys).shape[0] == 0:
+ return log
+ else:
+ return {key: log[key] for key in return_keys}
+ return log
+
+ def configure_optimizers(self):
+ lr = self.learning_rate
+ params = list(self.model.parameters())
+ if self.cond_stage_trainable:
+ print(f"{self.__class__.__name__}: Also optimizing conditioner params!")
+ params = params + list(self.cond_stage_model.parameters())
+ if self.learn_logvar:
+ print('Diffusion model optimizing logvar')
+ params.append(self.logvar)
+ opt = torch.optim.AdamW(params, lr=lr)
+ if self.use_scheduler:
+ assert 'target' in self.scheduler_config
+ scheduler = instantiate_from_config(self.scheduler_config)
+
+ print("Setting up LambdaLR scheduler...")
+ scheduler = [
+ {
+ 'scheduler': LambdaLR(opt, lr_lambda=scheduler.schedule),
+ 'interval': 'step',
+ 'frequency': 1
+ }]
+ return [opt], scheduler
+ return opt
+
+ @torch.no_grad()
+ def to_rgb(self, x):
+ x = x.float()
+ if not hasattr(self, "colorize"):
+ self.colorize = torch.randn(3, x.shape[1], 1, 1).to(x)
+ x = nn.functional.conv2d(x, weight=self.colorize)
+ x = 2. * (x - x.min()) / (x.max() - x.min()) - 1.
+ return x
+
+
+class DiffusionWrapperV1(pl.LightningModule):
+ def __init__(self, diff_model_config, conditioning_key):
+ super().__init__()
+ self.diffusion_model = instantiate_from_config(diff_model_config)
+ self.conditioning_key = conditioning_key
+ assert self.conditioning_key in [None, 'concat', 'crossattn', 'hybrid', 'adm']
+
+ def forward(self, x, t, c_concat: list = None, c_crossattn: list = None):
+ if self.conditioning_key is None:
+ out = self.diffusion_model(x, t)
+ elif self.conditioning_key == 'concat':
+ xc = torch.cat([x] + c_concat, dim=1)
+ out = self.diffusion_model(xc, t)
+ elif self.conditioning_key == 'crossattn':
+ cc = torch.cat(c_crossattn, 1)
+ out = self.diffusion_model(x, t, context=cc)
+ elif self.conditioning_key == 'hybrid':
+ xc = torch.cat([x] + c_concat, dim=1)
+ cc = torch.cat(c_crossattn, 1)
+ out = self.diffusion_model(xc, t, context=cc)
+ elif self.conditioning_key == 'adm':
+ cc = c_crossattn[0]
+ out = self.diffusion_model(x, t, y=cc)
+ else:
+ raise NotImplementedError()
+
+ return out
+
+
+class Layout2ImgDiffusionV1(LatentDiffusionV1):
+ # TODO: move all layout-specific hacks to this class
+ def __init__(self, cond_stage_key, *args, **kwargs):
+ assert cond_stage_key == 'coordinates_bbox', 'Layout2ImgDiffusion only for cond_stage_key="coordinates_bbox"'
+ super().__init__(cond_stage_key=cond_stage_key, *args, **kwargs)
+
+ def log_images(self, batch, N=8, *args, **kwargs):
+ logs = super().log_images(batch=batch, N=N, *args, **kwargs)
+
+ key = 'train' if self.training else 'validation'
+ dset = self.trainer.datamodule.datasets[key]
+ mapper = dset.conditional_builders[self.cond_stage_key]
+
+ bbox_imgs = []
+ map_fn = lambda catno: dset.get_textual_label(dset.get_category_id(catno))
+ for tknzd_bbox in batch[self.cond_stage_key][:N]:
+ bboximg = mapper.plot(tknzd_bbox.detach().cpu(), map_fn, (256, 256))
+ bbox_imgs.append(bboximg)
+
+ cond_img = torch.stack(bbox_imgs, dim=0)
+ logs['bbox_image'] = cond_img
+ return logs
+
+setattr(ldm.models.diffusion.ddpm, "DDPMV1", DDPMV1)
+setattr(ldm.models.diffusion.ddpm, "LatentDiffusionV1", LatentDiffusionV1)
+setattr(ldm.models.diffusion.ddpm, "DiffusionWrapperV1", DiffusionWrapperV1)
+setattr(ldm.models.diffusion.ddpm, "Layout2ImgDiffusionV1", Layout2ImgDiffusionV1)
diff --git a/extensions-builtin/ScuNET/preload.py b/extensions-builtin/ScuNET/preload.py
new file mode 100644
index 00000000..f12c5b90
--- /dev/null
+++ b/extensions-builtin/ScuNET/preload.py
@@ -0,0 +1,6 @@
+import os
+from modules import paths
+
+
+def preload(parser):
+ parser.add_argument("--scunet-models-path", type=str, help="Path to directory with ScuNET model file(s).", default=os.path.join(paths.models_path, 'ScuNET'))
diff --git a/modules/scunet_model.py b/extensions-builtin/ScuNET/scripts/scunet_model.py
index 59532274..e0fbf3a3 100644
--- a/modules/scunet_model.py
+++ b/extensions-builtin/ScuNET/scripts/scunet_model.py
@@ -9,7 +9,7 @@ from basicsr.utils.download_util import load_file_from_url
import modules.upscaler
from modules import devices, modelloader
-from modules.scunet_model_arch import SCUNet as net
+from scunet_model_arch import SCUNet as net
class UpscalerScuNET(modules.upscaler.Upscaler):
@@ -49,12 +49,12 @@ class UpscalerScuNET(modules.upscaler.Upscaler):
if model is None:
return img
- device = devices.device_scunet
+ device = devices.get_device_for('scunet')
img = np.array(img)
img = img[:, :, ::-1]
img = np.moveaxis(img, 2, 0) / 255
img = torch.from_numpy(img).float()
- img = devices.mps_contiguous_to(img.unsqueeze(0), device)
+ img = img.unsqueeze(0).to(device)
with torch.no_grad():
output = model(img)
@@ -66,7 +66,7 @@ class UpscalerScuNET(modules.upscaler.Upscaler):
return PIL.Image.fromarray(output, 'RGB')
def load_model(self, path: str):
- device = devices.device_scunet
+ device = devices.get_device_for('scunet')
if "http" in path:
filename = load_file_from_url(url=self.model_url, model_dir=self.model_path, file_name="%s.pth" % self.name,
progress=True)
diff --git a/modules/scunet_model_arch.py b/extensions-builtin/ScuNET/scunet_model_arch.py
index 43ca8d36..43ca8d36 100644
--- a/modules/scunet_model_arch.py
+++ b/extensions-builtin/ScuNET/scunet_model_arch.py
diff --git a/extensions-builtin/SwinIR/preload.py b/extensions-builtin/SwinIR/preload.py
new file mode 100644
index 00000000..567e44bc
--- /dev/null
+++ b/extensions-builtin/SwinIR/preload.py
@@ -0,0 +1,6 @@
+import os
+from modules import paths
+
+
+def preload(parser):
+ parser.add_argument("--swinir-models-path", type=str, help="Path to directory with SwinIR model file(s).", default=os.path.join(paths.models_path, 'SwinIR'))
diff --git a/modules/swinir_model.py b/extensions-builtin/SwinIR/scripts/swinir_model.py
index 4253b66d..9a74b253 100644
--- a/modules/swinir_model.py
+++ b/extensions-builtin/SwinIR/scripts/swinir_model.py
@@ -7,15 +7,14 @@ from PIL import Image
from basicsr.utils.download_util import load_file_from_url
from tqdm import tqdm
-from modules import modelloader, devices
+from modules import modelloader, devices, script_callbacks, shared
from modules.shared import cmd_opts, opts
-from modules.swinir_model_arch import SwinIR as net
-from modules.swinir_model_arch_v2 import Swin2SR as net2
+from swinir_model_arch import SwinIR as net
+from swinir_model_arch_v2 import Swin2SR as net2
from modules.upscaler import Upscaler, UpscalerData
-precision_scope = (
- torch.autocast if cmd_opts.precision == "autocast" else contextlib.nullcontext
-)
+
+device_swinir = devices.get_device_for('swinir')
class UpscalerSwinIR(Upscaler):
@@ -42,7 +41,7 @@ class UpscalerSwinIR(Upscaler):
model = self.load_model(model_file)
if model is None:
return img
- model = model.to(devices.device_swinir)
+ model = model.to(device_swinir, dtype=devices.dtype)
img = upscale(img, model)
try:
torch.cuda.empty_cache()
@@ -94,25 +93,27 @@ class UpscalerSwinIR(Upscaler):
model.load_state_dict(pretrained_model[params], strict=True)
else:
model.load_state_dict(pretrained_model, strict=True)
- if not cmd_opts.no_half:
- model = model.half()
return model
def upscale(
img,
model,
- tile=opts.SWIN_tile,
- tile_overlap=opts.SWIN_tile_overlap,
+ tile=None,
+ tile_overlap=None,
window_size=8,
scale=4,
):
+ tile = tile or opts.SWIN_tile
+ tile_overlap = tile_overlap or opts.SWIN_tile_overlap
+
+
img = np.array(img)
img = img[:, :, ::-1]
img = np.moveaxis(img, 2, 0) / 255
img = torch.from_numpy(img).float()
- img = devices.mps_contiguous_to(img.unsqueeze(0), devices.device_swinir)
- with torch.no_grad(), precision_scope("cuda"):
+ img = img.unsqueeze(0).to(device_swinir, dtype=devices.dtype)
+ with torch.no_grad(), devices.autocast():
_, _, h_old, w_old = img.size()
h_pad = (h_old // window_size + 1) * window_size - h_old
w_pad = (w_old // window_size + 1) * window_size - w_old
@@ -139,8 +140,8 @@ def inference(img, model, tile, tile_overlap, window_size, scale):
stride = tile - tile_overlap
h_idx_list = list(range(0, h - tile, stride)) + [h - tile]
w_idx_list = list(range(0, w - tile, stride)) + [w - tile]
- E = torch.zeros(b, c, h * sf, w * sf, dtype=torch.half, device=devices.device_swinir).type_as(img)
- W = torch.zeros_like(E, dtype=torch.half, device=devices.device_swinir)
+ E = torch.zeros(b, c, h * sf, w * sf, dtype=devices.dtype, device=device_swinir).type_as(img)
+ W = torch.zeros_like(E, dtype=devices.dtype, device=device_swinir)
with tqdm(total=len(h_idx_list) * len(w_idx_list), desc="SwinIR tiles") as pbar:
for h_idx in h_idx_list:
@@ -159,3 +160,13 @@ def inference(img, model, tile, tile_overlap, window_size, scale):
output = E.div_(W)
return output
+
+
+def on_ui_settings():
+ import gradio as gr
+
+ shared.opts.add_option("SWIN_tile", shared.OptionInfo(192, "Tile size for all SwinIR.", gr.Slider, {"minimum": 16, "maximum": 512, "step": 16}, section=('upscaling', "Upscaling")))
+ shared.opts.add_option("SWIN_tile_overlap", shared.OptionInfo(8, "Tile overlap, in pixels for SwinIR. Low values = visible seam.", gr.Slider, {"minimum": 0, "maximum": 48, "step": 1}, section=('upscaling', "Upscaling")))
+
+
+script_callbacks.on_ui_settings(on_ui_settings)
diff --git a/modules/swinir_model_arch.py b/extensions-builtin/SwinIR/swinir_model_arch.py
index 863f42db..863f42db 100644
--- a/modules/swinir_model_arch.py
+++ b/extensions-builtin/SwinIR/swinir_model_arch.py
diff --git a/modules/swinir_model_arch_v2.py b/extensions-builtin/SwinIR/swinir_model_arch_v2.py
index 0e28ae6e..0e28ae6e 100644
--- a/modules/swinir_model_arch_v2.py
+++ b/extensions-builtin/SwinIR/swinir_model_arch_v2.py
diff --git a/extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js b/extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js
new file mode 100644
index 00000000..eccfb0f9
--- /dev/null
+++ b/extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js
@@ -0,0 +1,107 @@
+// Stable Diffusion WebUI - Bracket checker
+// Version 1.0
+// By Hingashi no Florin/Bwin4L
+// Counts open and closed brackets (round, square, curly) in the prompt and negative prompt text boxes in the txt2img and img2img tabs.
+// If there's a mismatch, the keyword counter turns red and if you hover on it, a tooltip tells you what's wrong.
+
+function checkBrackets(evt) {
+ textArea = evt.target;
+ tabName = evt.target.parentElement.parentElement.id.split("_")[0];
+ counterElt = document.querySelector('gradio-app').shadowRoot.querySelector('#' + tabName + '_token_counter');
+
+ promptName = evt.target.parentElement.parentElement.id.includes('neg') ? ' negative' : '';
+
+ errorStringParen = '(' + tabName + promptName + ' prompt) - Different number of opening and closing parentheses detected.\n';
+ errorStringSquare = '[' + tabName + promptName + ' prompt] - Different number of opening and closing square brackets detected.\n';
+ errorStringCurly = '{' + tabName + promptName + ' prompt} - Different number of opening and closing curly brackets detected.\n';
+
+ openBracketRegExp = /\(/g;
+ closeBracketRegExp = /\)/g;
+
+ openSquareBracketRegExp = /\[/g;
+ closeSquareBracketRegExp = /\]/g;
+
+ openCurlyBracketRegExp = /\{/g;
+ closeCurlyBracketRegExp = /\}/g;
+
+ totalOpenBracketMatches = 0;
+ totalCloseBracketMatches = 0;
+ totalOpenSquareBracketMatches = 0;
+ totalCloseSquareBracketMatches = 0;
+ totalOpenCurlyBracketMatches = 0;
+ totalCloseCurlyBracketMatches = 0;
+
+ openBracketMatches = textArea.value.match(openBracketRegExp);
+ if(openBracketMatches) {
+ totalOpenBracketMatches = openBracketMatches.length;
+ }
+
+ closeBracketMatches = textArea.value.match(closeBracketRegExp);
+ if(closeBracketMatches) {
+ totalCloseBracketMatches = closeBracketMatches.length;
+ }
+
+ openSquareBracketMatches = textArea.value.match(openSquareBracketRegExp);
+ if(openSquareBracketMatches) {
+ totalOpenSquareBracketMatches = openSquareBracketMatches.length;
+ }
+
+ closeSquareBracketMatches = textArea.value.match(closeSquareBracketRegExp);
+ if(closeSquareBracketMatches) {
+ totalCloseSquareBracketMatches = closeSquareBracketMatches.length;
+ }
+
+ openCurlyBracketMatches = textArea.value.match(openCurlyBracketRegExp);
+ if(openCurlyBracketMatches) {
+ totalOpenCurlyBracketMatches = openCurlyBracketMatches.length;
+ }
+
+ closeCurlyBracketMatches = textArea.value.match(closeCurlyBracketRegExp);
+ if(closeCurlyBracketMatches) {
+ totalCloseCurlyBracketMatches = closeCurlyBracketMatches.length;
+ }
+
+ if(totalOpenBracketMatches != totalCloseBracketMatches) {
+ if(!counterElt.title.includes(errorStringParen)) {
+ counterElt.title += errorStringParen;
+ }
+ } else {
+ counterElt.title = counterElt.title.replace(errorStringParen, '');
+ }
+
+ if(totalOpenSquareBracketMatches != totalCloseSquareBracketMatches) {
+ if(!counterElt.title.includes(errorStringSquare)) {
+ counterElt.title += errorStringSquare;
+ }
+ } else {
+ counterElt.title = counterElt.title.replace(errorStringSquare, '');
+ }
+
+ if(totalOpenCurlyBracketMatches != totalCloseCurlyBracketMatches) {
+ if(!counterElt.title.includes(errorStringCurly)) {
+ counterElt.title += errorStringCurly;
+ }
+ } else {
+ counterElt.title = counterElt.title.replace(errorStringCurly, '');
+ }
+
+ if(counterElt.title != '') {
+ counterElt.style = 'color: #FF5555;';
+ } else {
+ counterElt.style = '';
+ }
+}
+
+var shadowRootLoaded = setInterval(function() {
+ var shadowTextArea = document.querySelector('gradio-app').shadowRoot.querySelectorAll('#txt2img_prompt > label > textarea');
+ if(shadowTextArea.length < 1) {
+ return false;
+ }
+
+ clearInterval(shadowRootLoaded);
+
+ document.querySelector('gradio-app').shadowRoot.querySelector('#txt2img_prompt').onkeyup = checkBrackets;
+ document.querySelector('gradio-app').shadowRoot.querySelector('#txt2img_neg_prompt').onkeyup = checkBrackets;
+ document.querySelector('gradio-app').shadowRoot.querySelector('#img2img_prompt').onkeyup = checkBrackets;
+ document.querySelector('gradio-app').shadowRoot.querySelector('#img2img_neg_prompt').onkeyup = checkBrackets;
+}, 1000);
diff --git a/extensions-builtin/roll-artist/scripts/roll-artist.py b/extensions-builtin/roll-artist/scripts/roll-artist.py
new file mode 100644
index 00000000..c3bc1fd0
--- /dev/null
+++ b/extensions-builtin/roll-artist/scripts/roll-artist.py
@@ -0,0 +1,50 @@
+import random
+
+from modules import script_callbacks, shared
+import gradio as gr
+
+art_symbol = '\U0001f3a8' # 🎨
+global_prompt = None
+related_ids = {"txt2img_prompt", "txt2img_clear_prompt", "img2img_prompt", "img2img_clear_prompt" }
+
+
+def roll_artist(prompt):
+ allowed_cats = set([x for x in shared.artist_db.categories() if len(shared.opts.random_artist_categories)==0 or x in shared.opts.random_artist_categories])
+ artist = random.choice([x for x in shared.artist_db.artists if x.category in allowed_cats])
+
+ return prompt + ", " + artist.name if prompt != '' else artist.name
+
+
+def add_roll_button(prompt):
+ roll = gr.Button(value=art_symbol, elem_id="roll", visible=len(shared.artist_db.artists) > 0)
+
+ roll.click(
+ fn=roll_artist,
+ _js="update_txt2img_tokens",
+ inputs=[
+ prompt,
+ ],
+ outputs=[
+ prompt,
+ ]
+ )
+
+
+def after_component(component, **kwargs):
+ global global_prompt
+
+ elem_id = kwargs.get('elem_id', None)
+ if elem_id not in related_ids:
+ return
+
+ if elem_id == "txt2img_prompt":
+ global_prompt = component
+ elif elem_id == "txt2img_clear_prompt":
+ add_roll_button(global_prompt)
+ elif elem_id == "img2img_prompt":
+ global_prompt = component
+ elif elem_id == "img2img_clear_prompt":
+ add_roll_button(global_prompt)
+
+
+script_callbacks.on_after_component(after_component)
diff --git a/html/footer.html b/html/footer.html
new file mode 100644
index 00000000..a8f2adf7
--- /dev/null
+++ b/html/footer.html
@@ -0,0 +1,9 @@
+<div>
+ <a href="/docs">API</a>
+  • 
+ <a href="https://github.com/AUTOMATIC1111/stable-diffusion-webui">Github</a>
+  • 
+ <a href="https://gradio.app">Gradio</a>
+  • 
+ <a href="/" onclick="javascript:gradioApp().getElementById('settings_restart_gradio').click(); return false">Reload UI</a>
+</div>
diff --git a/html/licenses.html b/html/licenses.html
new file mode 100644
index 00000000..9eeaa072
--- /dev/null
+++ b/html/licenses.html
@@ -0,0 +1,392 @@
+<style>
+ #licenses h2 {font-size: 1.2em; font-weight: bold; margin-bottom: 0.2em;}
+ #licenses small {font-size: 0.95em; opacity: 0.85;}
+ #licenses pre { margin: 1em 0 2em 0;}
+</style>
+
+<h2><a href="https://github.com/sczhou/CodeFormer/blob/master/LICENSE">CodeFormer</a></h2>
+<small>Parts of CodeFormer code had to be copied to be compatible with GFPGAN.</small>
+<pre>
+S-Lab License 1.0
+
+Copyright 2022 S-Lab
+
+Redistribution and use for non-commercial purpose in source and
+binary forms, with or without modification, are permitted provided
+that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+In the event that redistribution and/or use for commercial purpose in
+source or binary forms, with or without modification is required,
+please contact the contributor(s) of the work.
+</pre>
+
+
+<h2><a href="https://github.com/victorca25/iNNfer/blob/main/LICENSE">ESRGAN</a></h2>
+<small>Code for architecture and reading models copied.</small>
+<pre>
+MIT License
+
+Copyright (c) 2021 victorca25
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+</pre>
+
+<h2><a href="https://github.com/xinntao/Real-ESRGAN/blob/master/LICENSE">Real-ESRGAN</a></h2>
+<small>Some code is copied to support ESRGAN models.</small>
+<pre>
+BSD 3-Clause License
+
+Copyright (c) 2021, Xintao Wang
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+</pre>
+
+<h2><a href="https://github.com/invoke-ai/InvokeAI/blob/main/LICENSE">InvokeAI</a></h2>
+<small>Some code for compatibility with OSX is taken from lstein's repository.</small>
+<pre>
+MIT License
+
+Copyright (c) 2022 InvokeAI Team
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+</pre>
+
+<h2><a href="https://github.com/Hafiidz/latent-diffusion/blob/main/LICENSE">LDSR</a></h2>
+<small>Code added by contirubtors, most likely copied from this repository.</small>
+<pre>
+MIT License
+
+Copyright (c) 2022 Machine Vision and Learning Group, LMU Munich
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+</pre>
+
+<h2><a href="https://github.com/pharmapsychotic/clip-interrogator/blob/main/LICENSE">CLIP Interrogator</a></h2>
+<small>Some small amounts of code borrowed and reworked.</small>
+<pre>
+MIT License
+
+Copyright (c) 2022 pharmapsychotic
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+</pre>
+
+<h2><a href="https://github.com/JingyunLiang/SwinIR/blob/main/LICENSE">SwinIR</a></h2>
+<small>Code added by contirubtors, most likely copied from this repository.</small>
+
+<pre>
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [2021] [SwinIR Authors]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+</pre>
+
diff --git a/javascript/contextMenus.js b/javascript/contextMenus.js
index fe67c42e..11bcce1b 100644
--- a/javascript/contextMenus.js
+++ b/javascript/contextMenus.js
@@ -9,7 +9,7 @@ contextMenuInit = function(){
function showContextMenu(event,element,menuEntries){
let posx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
- let posy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
+ let posy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
let oldMenu = gradioApp().querySelector('#context-menu')
if(oldMenu){
@@ -61,15 +61,15 @@ contextMenuInit = function(){
}
- function appendContextMenuOption(targetEmementSelector,entryName,entryFunction){
-
- currentItems = menuSpecs.get(targetEmementSelector)
-
+ function appendContextMenuOption(targetElementSelector,entryName,entryFunction){
+
+ currentItems = menuSpecs.get(targetElementSelector)
+
if(!currentItems){
currentItems = []
- menuSpecs.set(targetEmementSelector,currentItems);
+ menuSpecs.set(targetElementSelector,currentItems);
}
- let newItem = {'id':targetEmementSelector+'_'+uid(),
+ let newItem = {'id':targetElementSelector+'_'+uid(),
'name':entryName,
'func':entryFunction,
'isNew':true}
@@ -97,7 +97,7 @@ contextMenuInit = function(){
if(source.id && source.id.indexOf('check_progress')>-1){
return
}
-
+
let oldMenu = gradioApp().querySelector('#context-menu')
if(oldMenu){
oldMenu.remove()
@@ -117,7 +117,7 @@ contextMenuInit = function(){
})
});
eventListenerApplied=true
-
+
}
return [appendContextMenuOption, removeContextMenuOption, addContextMenuEventListener]
@@ -152,8 +152,8 @@ addContextMenuEventListener = initResponse[2];
generateOnRepeat('#img2img_generate','#img2img_interrupt');
})
- let cancelGenerateForever = function(){
- clearInterval(window.generateOnRepeatInterval)
+ let cancelGenerateForever = function(){
+ clearInterval(window.generateOnRepeatInterval)
}
appendContextMenuOption('#txt2img_interrupt','Cancel generate forever',cancelGenerateForever)
@@ -162,7 +162,7 @@ addContextMenuEventListener = initResponse[2];
appendContextMenuOption('#img2img_generate', 'Cancel generate forever',cancelGenerateForever)
appendContextMenuOption('#roll','Roll three',
- function(){
+ function(){
let rollbutton = get_uiCurrentTabContent().querySelector('#roll');
setTimeout(function(){rollbutton.click()},100)
setTimeout(function(){rollbutton.click()},200)
diff --git a/javascript/dragdrop.js b/javascript/dragdrop.js
index 3ed1cb3c..fe008924 100644
--- a/javascript/dragdrop.js
+++ b/javascript/dragdrop.js
@@ -9,11 +9,19 @@ function dropReplaceImage( imgWrap, files ) {
return;
}
+ const tmpFile = files[0];
+
imgWrap.querySelector('.modify-upload button + button, .touch-none + div button + button')?.click();
const callback = () => {
const fileInput = imgWrap.querySelector('input[type="file"]');
if ( fileInput ) {
- fileInput.files = files;
+ if ( files.length === 0 ) {
+ files = new DataTransfer();
+ files.items.add(tmpFile);
+ fileInput.files = files.files;
+ } else {
+ fileInput.files = files;
+ }
fileInput.dispatchEvent(new Event('change'));
}
};
diff --git a/javascript/edit-attention.js b/javascript/edit-attention.js
index c0d29a74..b947cbec 100644
--- a/javascript/edit-attention.js
+++ b/javascript/edit-attention.js
@@ -1,7 +1,6 @@
addEventListener('keydown', (event) => {
let target = event.originalTarget || event.composedPath()[0];
- if (!target.hasAttribute("placeholder")) return;
- if (!target.placeholder.toLowerCase().includes("prompt")) return;
+ if (!target.matches("#toprow textarea.gr-text-input[placeholder]")) return;
if (! (event.metaKey || event.ctrlKey)) return;
diff --git a/javascript/generationParams.js b/javascript/generationParams.js
new file mode 100644
index 00000000..95f05093
--- /dev/null
+++ b/javascript/generationParams.js
@@ -0,0 +1,33 @@
+// attaches listeners to the txt2img and img2img galleries to update displayed generation param text when the image changes
+
+let txt2img_gallery, img2img_gallery, modal = undefined;
+onUiUpdate(function(){
+ if (!txt2img_gallery) {
+ txt2img_gallery = attachGalleryListeners("txt2img")
+ }
+ if (!img2img_gallery) {
+ img2img_gallery = attachGalleryListeners("img2img")
+ }
+ if (!modal) {
+ modal = gradioApp().getElementById('lightboxModal')
+ modalObserver.observe(modal, { attributes : true, attributeFilter : ['style'] });
+ }
+});
+
+let modalObserver = new MutationObserver(function(mutations) {
+ mutations.forEach(function(mutationRecord) {
+ let selectedTab = gradioApp().querySelector('#tabs div button.bg-white')?.innerText
+ if (mutationRecord.target.style.display === 'none' && selectedTab === 'txt2img' || selectedTab === 'img2img')
+ gradioApp().getElementById(selectedTab+"_generation_info_button").click()
+ });
+});
+
+function attachGalleryListeners(tab_name) {
+ gallery = gradioApp().querySelector('#'+tab_name+'_gallery')
+ gallery?.addEventListener('click', () => gradioApp().getElementById(tab_name+"_generation_info_button").click());
+ gallery?.addEventListener('keydown', (e) => {
+ if (e.keyCode == 37 || e.keyCode == 39) // left or right arrow
+ gradioApp().getElementById(tab_name+"_generation_info_button").click()
+ });
+ return gallery;
+}
diff --git a/javascript/hints.js b/javascript/hints.js
index 623bc25c..63e17e05 100644
--- a/javascript/hints.js
+++ b/javascript/hints.js
@@ -6,6 +6,7 @@ titles = {
"GFPGAN": "Restore low quality faces using GFPGAN neural network",
"Euler a": "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps to higher than 30-40 does not help",
"DDIM": "Denoising Diffusion Implicit Models - best at inpainting",
+ "DPM adaptive": "Ignores step count - uses a number of steps determined by the CFG and resolution",
"Batch count": "How many batches of images to create",
"Batch size": "How many image to create in a single batch",
@@ -17,6 +18,7 @@ titles = {
"\u2199\ufe0f": "Read generation parameters from prompt or last generation if prompt is empty into user interface.",
"\u{1f4c2}": "Open images output directory",
"\u{1f4be}": "Save style",
+ "\U0001F5D1": "Clear prompt",
"\u{1f4cb}": "Apply selected styles to current prompt",
"Inpaint a part of image": "Draw a mask over an image, and the script will regenerate the masked area with content according to prompt",
@@ -62,8 +64,8 @@ titles = {
"Interrogate": "Reconstruct prompt from existing image and put it into the prompt field.",
- "Images filename pattern": "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.",
- "Directory name pattern": "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.",
+ "Images filename pattern": "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [model_name], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.",
+ "Directory name pattern": "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [model_name], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.",
"Max prompt words": "Set the maximum number of words to be used in the [prompt_words] option; ATTENTION: If the words are too long, they may exceed the maximum length of the file path that the system can handle",
"Loopback": "Process an image, use it as an input, repeat.",
@@ -94,6 +96,11 @@ titles = {
"Add difference": "Result = A + (B - C) * M",
"Learning rate": "how fast should the training go. Low values will take longer to train, high values may fail to converge (not generate accurate results) and/or may break the embedding (This has happened if you see Loss: nan in the training info textbox. If this happens, you need to manually restore your embedding from an older not-broken backup).\n\nYou can set a single numeric value, or multiple learning rates using the syntax:\n\n rate_1:max_steps_1, rate_2:max_steps_2, ...\n\nEG: 0.005:100, 1e-3:1000, 1e-5\n\nWill train with rate of 0.005 for first 100 steps, then 1e-3 until 1000 steps, then 1e-5 for all remaining steps.",
+
+ "Clip skip": "Early stopping parameter for CLIP model; 1 is stop at last layer as usual, 2 is stop at penultimate layer, etc.",
+
+ "Approx NN": "Cheap neural network approximation. Very fast compared to VAE, but produces pictures with 4 times smaller horizontal/vertical resoluton and lower quality.",
+ "Approx cheap": "Very cheap approximation. Very fast compared to VAE, but produces pictures with 8 times smaller horizontal/vertical resoluton and extremely low quality."
}
diff --git a/javascript/notification.js b/javascript/notification.js
index f96de313..040a3afa 100644
--- a/javascript/notification.js
+++ b/javascript/notification.js
@@ -15,7 +15,7 @@ onUiUpdate(function(){
}
}
- const galleryPreviews = gradioApp().querySelectorAll('img.h-full.w-full.overflow-hidden');
+ const galleryPreviews = gradioApp().querySelectorAll('div[id^="tab_"][style*="display: block"] img.h-full.w-full.overflow-hidden');
if (galleryPreviews == null) return;
diff --git a/javascript/progressbar.js b/javascript/progressbar.js
index 7a05726e..d6323ed9 100644
--- a/javascript/progressbar.js
+++ b/javascript/progressbar.js
@@ -3,57 +3,75 @@ global_progressbars = {}
galleries = {}
galleryObservers = {}
+// this tracks launches of window.setTimeout for progressbar to prevent starting a new timeout when the previous is still running
+timeoutIds = {}
+
function check_progressbar(id_part, id_progressbar, id_progressbar_span, id_skip, id_interrupt, id_preview, id_gallery){
- var progressbar = gradioApp().getElementById(id_progressbar)
+ // gradio 3.8's enlightened approach allows them to create two nested div elements inside each other with same id
+ // every time you use gr.HTML(elem_id='xxx'), so we handle this here
+ var progressbar = gradioApp().querySelector("#"+id_progressbar+" #"+id_progressbar)
+ var progressbarParent
+ if(progressbar){
+ progressbarParent = gradioApp().querySelector("#"+id_progressbar)
+ } else{
+ progressbar = gradioApp().getElementById(id_progressbar)
+ progressbarParent = null
+ }
+
var skip = id_skip ? gradioApp().getElementById(id_skip) : null
var interrupt = gradioApp().getElementById(id_interrupt)
-
+
if(opts.show_progress_in_title && progressbar && progressbar.offsetParent){
if(progressbar.innerText){
- let newtitle = 'Stable Diffusion - ' + progressbar.innerText
+ let newtitle = '[' + progressbar.innerText.trim() + '] Stable Diffusion';
if(document.title != newtitle){
- document.title = newtitle;
+ document.title = newtitle;
}
}else{
let newtitle = 'Stable Diffusion'
if(document.title != newtitle){
- document.title = newtitle;
+ document.title = newtitle;
}
}
}
-
+
if(progressbar!= null && progressbar != global_progressbars[id_progressbar]){
global_progressbars[id_progressbar] = progressbar
var mutationObserver = new MutationObserver(function(m){
+ if(timeoutIds[id_part]) return;
+
preview = gradioApp().getElementById(id_preview)
gallery = gradioApp().getElementById(id_gallery)
if(preview != null && gallery != null){
preview.style.width = gallery.clientWidth + "px"
preview.style.height = gallery.clientHeight + "px"
+ if(progressbarParent) progressbar.style.width = progressbarParent.clientWidth + "px"
//only watch gallery if there is a generation process going on
check_gallery(id_gallery);
var progressDiv = gradioApp().querySelectorAll('#' + id_progressbar_span).length > 0;
- if(!progressDiv){
+ if(progressDiv){
+ timeoutIds[id_part] = window.setTimeout(function() {
+ timeoutIds[id_part] = null
+ requestMoreProgress(id_part, id_progressbar_span, id_skip, id_interrupt)
+ }, 500)
+ } else{
if (skip) {
skip.style.display = "none"
}
interrupt.style.display = "none"
-
+
//disconnect observer once generation finished, so user can close selected image if they want
if (galleryObservers[id_gallery]) {
galleryObservers[id_gallery].disconnect();
galleries[id_gallery] = null;
- }
+ }
}
-
-
}
- window.setTimeout(function() { requestMoreProgress(id_part, id_progressbar_span, id_skip, id_interrupt) }, 500)
});
mutationObserver.observe( progressbar, { childList:true, subtree:true })
}
@@ -74,14 +92,26 @@ function check_gallery(id_gallery){
if (prevSelectedIndex !== -1 && galleryButtons.length>prevSelectedIndex && !galleryBtnSelected) {
// automatically re-open previously selected index (if exists)
activeElement = gradioApp().activeElement;
+ let scrollX = window.scrollX;
+ let scrollY = window.scrollY;
galleryButtons[prevSelectedIndex].click();
showGalleryImage();
+ // When the gallery button is clicked, it gains focus and scrolls itself into view
+ // We need to scroll back to the previous position
+ setTimeout(function (){
+ window.scrollTo(scrollX, scrollY);
+ }, 50);
+
if(activeElement){
// i fought this for about an hour; i don't know why the focus is lost or why this helps recover it
- // if somenoe has a better solution please by all means
- setTimeout(function() { activeElement.focus() }, 1);
+ // if someone has a better solution please by all means
+ setTimeout(function (){
+ activeElement.focus({
+ preventScroll: true // Refocus the element that was focused before the gallery was opened without scrolling to it
+ })
+ }, 1);
}
}
})
diff --git a/javascript/ui.js b/javascript/ui.js
index 7e116465..34406f3f 100644
--- a/javascript/ui.js
+++ b/javascript/ui.js
@@ -8,8 +8,8 @@ function set_theme(theme){
}
function selected_gallery_index(){
- var buttons = gradioApp().querySelectorAll('[style="display: block;"].tabitem .gallery-item')
- var button = gradioApp().querySelector('[style="display: block;"].tabitem .gallery-item.\\!ring-2')
+ var buttons = gradioApp().querySelectorAll('[style="display: block;"].tabitem div[id$=_gallery] .gallery-item')
+ var button = gradioApp().querySelector('[style="display: block;"].tabitem div[id$=_gallery] .gallery-item.\\!ring-2')
var result = -1
buttons.forEach(function(v, i){ if(v==button) { result = i } })
@@ -19,7 +19,7 @@ function selected_gallery_index(){
function extract_image_from_gallery(gallery){
if(gallery.length == 1){
- return gallery[0]
+ return [gallery[0]]
}
index = selected_gallery_index()
@@ -28,7 +28,7 @@ function extract_image_from_gallery(gallery){
return [null]
}
- return gallery[index];
+ return [gallery[index]];
}
function args_to_array(args){
@@ -100,7 +100,7 @@ function create_submit_args(args){
// As it is currently, txt2img and img2img send back the previous output args (txt2img_gallery, generation_info, html_info) whenever you generate a new image.
// This can lead to uploading a huge gallery of previously generated images, which leads to an unnecessary delay between submitting and beginning to generate.
- // I don't know why gradio is seding outputs along with inputs, but we can prevent sending the image gallery here, which seems to be an issue for some.
+ // I don't know why gradio is sending outputs along with inputs, but we can prevent sending the image gallery here, which seems to be an issue for some.
// If gradio at some point stops sending outputs, this may break something
if(Array.isArray(res[res.length - 3])){
res[res.length - 3] = null
@@ -131,6 +131,15 @@ function ask_for_style_name(_, prompt_text, negative_prompt_text) {
return [name_, prompt_text, negative_prompt_text]
}
+function confirm_clear_prompt(prompt, negative_prompt) {
+ if(confirm("Delete prompt?")) {
+ prompt = ""
+ negative_prompt = ""
+ }
+
+ return [prompt, negative_prompt]
+}
+
opts = {}
@@ -179,6 +188,17 @@ onUiUpdate(function(){
img2img_textarea = gradioApp().querySelector("#img2img_prompt > label > textarea");
img2img_textarea?.addEventListener("input", () => update_token_counter("img2img_token_button"));
}
+
+ show_all_pages = gradioApp().getElementById('settings_show_all_pages')
+ settings_tabs = gradioApp().querySelector('#settings div')
+ if(show_all_pages && settings_tabs){
+ settings_tabs.appendChild(show_all_pages)
+ show_all_pages.onclick = function(){
+ gradioApp().querySelectorAll('#settings > div').forEach(function(elem){
+ elem.style.display = "block";
+ })
+ }
+ }
})
let txt2img_textarea, img2img_textarea = undefined;
@@ -208,4 +228,6 @@ function update_token_counter(button_id) {
function restart_reload(){
document.body.innerHTML='<h1 style="font-family:monospace;margin-top:20%;color:lightgray;text-align:center;">Reloading...</h1>';
setTimeout(function(){location.reload()},2000)
+
+ return []
}
diff --git a/launch.py b/launch.py
index ff2f74ba..af0d418b 100644
--- a/launch.py
+++ b/launch.py
@@ -5,6 +5,8 @@ import sys
import importlib.util
import shlex
import platform
+import argparse
+import json
dir_repos = "repositories"
dir_extensions = "extensions"
@@ -17,6 +19,19 @@ def extract_arg(args, name):
return [x for x in args if x != name], name in args
+def extract_opt(args, name):
+ opt = None
+ is_present = False
+ if name in args:
+ is_present = True
+ idx = args.index(name)
+ del args[idx]
+ if idx < len(args) and args[idx][0] != "-":
+ opt = args[idx]
+ del args[idx]
+ return args, is_present, opt
+
+
def run(command, desc=None, errdesc=None, custom_env=None):
if desc is not None:
print(desc)
@@ -105,56 +120,78 @@ def version_check(commit):
print("version check failed", e)
-def run_extensions_installers():
- if not os.path.isdir(dir_extensions):
+def run_extension_installer(extension_dir):
+ path_installer = os.path.join(extension_dir, "install.py")
+ if not os.path.isfile(path_installer):
return
- for dirname_extension in os.listdir(dir_extensions):
- path_installer = os.path.join(dir_extensions, dirname_extension, "install.py")
- if not os.path.isfile(path_installer):
- continue
+ try:
+ env = os.environ.copy()
+ env['PYTHONPATH'] = os.path.abspath(".")
+
+ print(run(f'"{python}" "{path_installer}"', errdesc=f"Error running install.py for extension {extension_dir}", custom_env=env))
+ except Exception as e:
+ print(e, file=sys.stderr)
+
+
+def list_extensions(settings_file):
+ settings = {}
+
+ try:
+ if os.path.isfile(settings_file):
+ with open(settings_file, "r", encoding="utf8") as file:
+ settings = json.load(file)
+ except Exception as e:
+ print(e, file=sys.stderr)
+
+ disabled_extensions = set(settings.get('disabled_extensions', []))
+
+ return [x for x in os.listdir(dir_extensions) if x not in disabled_extensions]
- try:
- env = os.environ.copy()
- env['PYTHONPATH'] = os.path.abspath(".")
- print(run(f'"{python}" "{path_installer}"', errdesc=f"Error running install.py for extension {dirname_extension}", custom_env=env))
- except Exception as e:
- print(e, file=sys.stderr)
+def run_extensions_installers(settings_file):
+ if not os.path.isdir(dir_extensions):
+ return
+
+ for dirname_extension in list_extensions(settings_file):
+ run_extension_installer(os.path.join(dir_extensions, dirname_extension))
-def prepare_enviroment():
+def prepare_environment():
torch_command = os.environ.get('TORCH_COMMAND', "pip install torch==1.12.1+cu113 torchvision==0.13.1+cu113 --extra-index-url https://download.pytorch.org/whl/cu113")
requirements_file = os.environ.get('REQS_FILE', "requirements_versions.txt")
commandline_args = os.environ.get('COMMANDLINE_ARGS', "")
gfpgan_package = os.environ.get('GFPGAN_PACKAGE', "git+https://github.com/TencentARC/GFPGAN.git@8d2447a2d918f8eba5a4a01463fd48e45126a379")
clip_package = os.environ.get('CLIP_PACKAGE', "git+https://github.com/openai/CLIP.git@d50d76daa670286dd6cacf3bcd80b5e4823fc8e1")
- deepdanbooru_package = os.environ.get('DEEPDANBOORU_PACKAGE', "git+https://github.com/KichangKim/DeepDanbooru.git@d91a2963bf87c6a770d74894667e9ffa9f6de7ff")
+ openclip_package = os.environ.get('OPENCLIP_PACKAGE', "git+https://github.com/mlfoundations/open_clip.git@bb6e834e9c70d9c27d0dc3ecedeebeaeb1ffad6b")
xformers_windows_package = os.environ.get('XFORMERS_WINDOWS_PACKAGE', 'https://github.com/C43H66N12O12S2/stable-diffusion-webui/releases/download/f/xformers-0.0.14.dev0-cp310-cp310-win_amd64.whl')
- stable_diffusion_repo = os.environ.get('STABLE_DIFFUSION_REPO', "https://github.com/CompVis/stable-diffusion.git")
- taming_transformers_repo = os.environ.get('TAMING_REANSFORMERS_REPO', "https://github.com/CompVis/taming-transformers.git")
+ stable_diffusion_repo = os.environ.get('STABLE_DIFFUSION_REPO', "https://github.com/Stability-AI/stablediffusion.git")
+ taming_transformers_repo = os.environ.get('TAMING_TRANSFORMERS_REPO', "https://github.com/CompVis/taming-transformers.git")
k_diffusion_repo = os.environ.get('K_DIFFUSION_REPO', 'https://github.com/crowsonkb/k-diffusion.git')
- codeformer_repo = os.environ.get('CODEFORMET_REPO', 'https://github.com/sczhou/CodeFormer.git')
+ codeformer_repo = os.environ.get('CODEFORMER_REPO', 'https://github.com/sczhou/CodeFormer.git')
blip_repo = os.environ.get('BLIP_REPO', 'https://github.com/salesforce/BLIP.git')
- stable_diffusion_commit_hash = os.environ.get('STABLE_DIFFUSION_COMMIT_HASH', "69ae4b35e0a0f6ee1af8bb9a5d0016ccb27e36dc")
+ stable_diffusion_commit_hash = os.environ.get('STABLE_DIFFUSION_COMMIT_HASH', "47b6b607fdd31875c9279cd2f4f16b92e4ea958e")
taming_transformers_commit_hash = os.environ.get('TAMING_TRANSFORMERS_COMMIT_HASH', "24268930bf1dce879235a7fddd0b2355b84d7ea6")
- k_diffusion_commit_hash = os.environ.get('K_DIFFUSION_COMMIT_HASH', "f4e99857772fc3a126ba886aadf795a332774878")
+ k_diffusion_commit_hash = os.environ.get('K_DIFFUSION_COMMIT_HASH', "5b3af030dd83e0297272d861c19477735d0317ec")
codeformer_commit_hash = os.environ.get('CODEFORMER_COMMIT_HASH', "c5b4593074ba6214284d6acd5f1719b6c5d739af")
blip_commit_hash = os.environ.get('BLIP_COMMIT_HASH', "48211a1594f1321b00f14c9f7a5b4813144b2fb9")
sys.argv += shlex.split(commandline_args)
- test_argv = [x for x in sys.argv if x != '--tests']
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--ui-settings-file", type=str, help="filename to use for ui settings", default='config.json')
+ args, _ = parser.parse_known_args(sys.argv)
+
+ sys.argv, _ = extract_arg(sys.argv, '-f')
sys.argv, skip_torch_cuda_test = extract_arg(sys.argv, '--skip-torch-cuda-test')
sys.argv, reinstall_xformers = extract_arg(sys.argv, '--reinstall-xformers')
sys.argv, update_check = extract_arg(sys.argv, '--update-check')
- sys.argv, run_tests = extract_arg(sys.argv, '--tests')
+ sys.argv, run_tests, test_dir = extract_opt(sys.argv, '--tests')
xformers = '--xformers' in sys.argv
- deepdanbooru = '--deepdanbooru' in sys.argv
ngrok = '--ngrok' in sys.argv
try:
@@ -177,6 +214,9 @@ def prepare_enviroment():
if not is_installed("clip"):
run_pip(f"install {clip_package}", "clip")
+ if not is_installed("open_clip"):
+ run_pip(f"install {openclip_package}", "open_clip")
+
if (not is_installed("xformers") or reinstall_xformers) and xformers:
if platform.system() == "Windows":
if platform.python_version().startswith("3.10"):
@@ -189,15 +229,12 @@ def prepare_enviroment():
elif platform.system() == "Linux":
run_pip("install xformers", "xformers")
- if not is_installed("deepdanbooru") and deepdanbooru:
- run_pip(f"install {deepdanbooru_package}#egg=deepdanbooru[tensorflow] tensorflow==2.10.0 tensorflow-io==0.27.0", "deepdanbooru")
-
if not is_installed("pyngrok") and ngrok:
run_pip("install pyngrok", "ngrok")
os.makedirs(dir_repos, exist_ok=True)
- git_clone(stable_diffusion_repo, repo_dir('stable-diffusion'), "Stable Diffusion", stable_diffusion_commit_hash)
+ git_clone(stable_diffusion_repo, repo_dir('stable-diffusion-stability-ai'), "Stable Diffusion", stable_diffusion_commit_hash)
git_clone(taming_transformers_repo, repo_dir('taming-transformers'), "Taming Transformers", taming_transformers_commit_hash)
git_clone(k_diffusion_repo, repo_dir('k-diffusion'), "K-diffusion", k_diffusion_commit_hash)
git_clone(codeformer_repo, repo_dir('CodeFormer'), "CodeFormer", codeformer_commit_hash)
@@ -208,7 +245,7 @@ def prepare_enviroment():
run_pip(f"install -r {requirements_file}", "requirements for Web UI")
- run_extensions_installers()
+ run_extensions_installers(settings_file=args.ui_settings_file)
if update_check:
version_check(commit)
@@ -218,32 +255,41 @@ def prepare_enviroment():
exit(0)
if run_tests:
- tests(test_argv)
- exit(0)
+ exitcode = tests(test_dir)
+ exit(exitcode)
-def tests(argv):
- if "--api" not in argv:
- argv.append("--api")
+def tests(test_dir):
+ if "--api" not in sys.argv:
+ sys.argv.append("--api")
+ if "--ckpt" not in sys.argv:
+ sys.argv.append("--ckpt")
+ sys.argv.append("./test/test_files/empty.pt")
+ if "--skip-torch-cuda-test" not in sys.argv:
+ sys.argv.append("--skip-torch-cuda-test")
- print(f"Launching Web UI in another process for testing with arguments: {' '.join(argv[1:])}")
+ print(f"Launching Web UI in another process for testing with arguments: {' '.join(sys.argv[1:])}")
with open('test/stdout.txt', "w", encoding="utf8") as stdout, open('test/stderr.txt', "w", encoding="utf8") as stderr:
- proc = subprocess.Popen([sys.executable, *argv], stdout=stdout, stderr=stderr)
+ proc = subprocess.Popen([sys.executable, *sys.argv], stdout=stdout, stderr=stderr)
import test.server_poll
- test.server_poll.run_tests()
+ exitcode = test.server_poll.run_tests(proc, test_dir)
print(f"Stopping Web UI process with id {proc.pid}")
proc.kill()
+ return exitcode
-def start_webui():
- print(f"Launching Web UI with arguments: {' '.join(sys.argv[1:])}")
+def start():
+ print(f"Launching {'API server' if '--nowebui' in sys.argv else 'Web UI'} with arguments: {' '.join(sys.argv[1:])}")
import webui
- webui.webui()
+ if '--nowebui' in sys.argv:
+ webui.api_only()
+ else:
+ webui.webui()
if __name__ == "__main__":
- prepare_enviroment()
- start_webui()
+ prepare_environment()
+ start()
diff --git a/localizations/ar_AR.json b/localizations/ar_AR.json
deleted file mode 100644
index abbbcff4..00000000
--- a/localizations/ar_AR.json
+++ /dev/null
@@ -1,518 +0,0 @@
-{
- "rtl": true,
- "Loading...": "لحظة...",
- "view": "اعرض ",
- "api": "واجهة البرمجة",
- "built with gradio": "مبني باستخدام gradio",
- "Stable Diffusion checkpoint": "أوزان نموذج الإنتشار المسقر",
- "txt2img": "نص إلى صورة",
- "Prompt": "الطلب",
- "Prompt (press Ctrl+Enter or Alt+Enter to generate)": "الطلب (لبدء الإنتاج Ctrl+Enter أو Alt+Enter اضغط)",
- "Negative prompt": "عكس الطلب",
- "Negative prompt (press Ctrl+Enter or Alt+Enter to generate)": "عكس الطلب (لبدء الإنتاج Ctrl+Enter أو Alt+Enter اضغط)",
- "Add a random artist to the prompt.": "أضف فنان عشوائي للطلب",
- "Read generation parameters from prompt or last generation if prompt is empty into user interface.": "اقرأ عوامل الإنتاج من الطلب أو من الإنتاج السابق إذا كان الطلب فارغا",
- "Save style": "احتفظ بالطلب وعكسه كإضافة",
- "Apply selected styles to current prompt": "ألحق الإضافات المحددة إلى الطلب وعكسه",
- "Generate": "أنتج",
- "Skip": "تخطى",
- "Stop processing current image and continue processing.": "لا تكمل خطوات هذة الحزمة وانتقل إلى الحزمة التالية",
- "Interrupt": "توقف",
- "Stop processing images and return any results accumulated so far.": "توقف عن الإنتاج واعرض ما تم إلى الآن",
- "Style 1": "الإضافة 1",
- "Style to apply; styles have components for both positive and negative prompts and apply to both": "الإضافات (styles) عبارة عن كلمات تتكرر كثيرا يتم إلحاقها بالطلب وعكسه عند الرغبة",
- "Style 2": "الإضافة 2",
- "Do not do anything special": "لا يغير شيئا",
- "Sampling Steps": "عدد الخطوات",
- "Sampling method": "أسلوب الخطو",
- "Which algorithm to use to produce the image": "Sampler: اسم نظام تحديد طريقة تغيير المسافات بين الخطوات",
- "Euler a": "Euler a",
- "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps to higher than 30-40 does not help": "Euler Ancestral: طريقة مبدعة يمكن أن تنتج صور مختلفة على حسب عدد الخطوات، لا تتغير بعد 30-40 خطوة",
- "Euler": "Euler",
- "LMS": "LMS",
- "Heun": "Heun",
- "DPM2": "DPM2",
- "DPM2 a": "DPM2 a",
- "DPM fast": "DPM fast",
- "DPM adaptive": "DPM adaptive",
- "LMS Karras": "LMS Karras",
- "DPM2 Karras": "DPM2 Karras",
- "DPM2 a Karras": "DPM2 a Karras",
- "DDIM": "DDIM",
- "Denoising Diffusion Implicit Models - best at inpainting": "Denoising Diffusion Implicit Models: الأفضل في الإنتاج الجزئي",
- "PLMS": "PLMS",
- "Width": "العرض",
- "Height": "الإرتفاع",
- "Restore faces": "تحسين الوجوه",
- "Tiling": "ترصيف",
- "Produce an image that can be tiled.": "أنتج صور يمكن ترصيفها بجانب بعضها كالبلاط",
- "Highres. fix": "إصلاح الدقة العالية",
- "Use a two step process to partially create an image at smaller resolution, upscale, and then improve details in it without changing composition": "أنتج صورة بدقة منخفضة ثم قم برفع الدقة فيما بعد لمنع التشوهات التي تحصل عندما تكون الدقة المطلوبة كبيرة",
- "Firstpass width": "العرض الأولي",
- "Firstpass height": "الإرتفاع الأولي",
- "Denoising strength": "المدى",
- "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.": "Denoising strength: حدد مدى الإبتعاد عن الصورة (عدد الخطوات الفعلي = عدد الخطوات * المدى)",
- "Batch count": "عدد الحزم",
- "How many batches of images to create": "يتم إنتاج الصور على دفعات، كل دفعة فيها حزمة من الصور",
- "Batch size": "حجم الحزمة",
- "How many image to create in a single batch": "Batch size: إنتاج حزمة صور أسرع من إنتاجهم فرادى، حدد عدد الصور في كل حزمة",
- "CFG Scale": "التركيز",
- "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results": "CFG scale: يحدد مقدار التركيز على تلبية الطلب وتجنب عكسه، كلما زاد قل الإبداع",
- "Seed": "البذرة",
- "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result": "Seed: رقم طبيعي عشوائي يسمح بإعادة إنتاج نفس الصورة إذا توافقت قيم العوامل الأخرى",
- "Set seed to -1, which will cause a new random number to be used every time": "استخدم بذرة جديدة في كل مرة (نرمز لهذا الخيار بجعل قيمة البذرة 1-)",
- "Reuse seed from last generation, mostly useful if it was randomed": "أعد استخدام البذرة من الإنتاج السابق",
- "Extra": "مزج",
- "Variation seed": "بذرة الممزوج",
- "Seed of a different picture to be mixed into the generation.": "Variation seed: بذرة صورة أخرى ليتم مزجها مع الصورة الحالية",
- "Variation strength": "أثر الممزوج",
- "How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something).": "Variation seed strength: مقدار أثر الصورة المدمجة على النتيجة النهائية (0: لا أثر، 1: أثر كامل ما عدا عند استخدام أسلوب خطو سلفي Ancestral)",
- "Resize seed from width": "عرض الممزوج",
- "Resize seed from height": "إرتفاع الممزوج",
- "Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution": "Seed resize from: حدد دقة صورة الممزوج (0: نفس دقة الإنتاج)",
- "Open for Clip Aesthetic!": "تضمين تجميلي",
- "▼": "▼",
- "Aesthetic weight": "أثر التضمين",
- "Aesthetic steps": "عدد الخطوات",
- "Aesthetic learning rate": "معدل التعلم",
- "Slerp interpolation": "امزج بطريقة كروية",
- "Aesthetic imgs embedding": "التضمين",
- "None": "بدون",
- "Aesthetic text for imgs": "الطلب (اختياري)",
- "This text is used to rotate the feature space of the imgs embs": "لإعادة توجيه التضمين التجميلي",
- "Slerp angle": "أثر الطلب",
- "Is negative text": "الطلب عكسي",
- "Script": "أدوات خاصة",
- "Prompt matrix": "مصفوفة طلبات",
- "Put variable parts at start of prompt": "الجزء المتغير في بداية الطلب",
- "Prompts from file or textbox": " قائمة طلبات",
- "Iterate seed every line": "غير البذرة مع كل طلب",
- "List of prompt inputs": "قائمة الطلبات",
- "Upload prompt inputs": "اجلب الطلبات من ملف",
- "Drop File Here": "اسقط ملف هنا",
- "-": "-",
- "or": "أو",
- "Click to Upload": "انقر للرفع",
- "X/Y plot": "مصفوفة عوامل",
- "X type": "العامل الأول",
- "Nothing": "لا شيء",
- "Var. seed": "بذرة الممزوج",
- "Var. strength": "أثر الممزوج",
- "Steps": "عدد الخطوات",
- "Prompt S/R": "كلمات بديلة",
- "Prompt order": "ترتيب الكلمات",
- "Sampler": "أسلوب الخطو",
- "Checkpoint name": "ملف الأوزان",
- "Hypernetwork": "الشبكة الفائقة",
- "Hypernet str.": "قوة الشبكة الفائقة",
- "Inpainting conditioning mask strength": "قوة قناع الإنتاج الجزئي",
- "Only applies to inpainting models. Determines how strongly to mask off the original image for inpainting and img2img. 1.0 means fully masked, which is the default behaviour. 0.0 means a fully unmasked conditioning. Lower values will help preserve the overall composition of the image, but will struggle with large changes.": "حدد مدى صرامة قناع الإنتاج، يصبح القناع شفاف إذا قوته 0 (لا يعمل إلا مع ملفات أوزان الإنتاج الجزئي: inpainting)",
- "Sigma Churn": "العشوائية (Schurn)",
- "Sigma min": "أدنى تشويش (Stmin)",
- "Sigma max": "أقصى تشويش (Stmax)",
- "Sigma noise": "التشويش (Snoise)",
- "Eta": "العامل Eta η",
- "Clip skip": "تخطي آخر طبقات CLIP",
- "Denoising": "المدى",
- "Cond. Image Mask Weight": "قوة قناع الإنتاج الجزئي",
- "X values": "قيم العامل الأول",
- "Separate values for X axis using commas.": "افصل القيم بفواصل (,) من اليسار إلى اليمين",
- "Y type": "العامل الثاني",
- "Y values": "قيم العامل الثاني",
- "Separate values for Y axis using commas.": "افصل القيم بفواصل (,) من الأعلى إلى الأسفل",
- "Draw legend": "أضف مفتاح التوضيح",
- "Include Separate Images": "أضف الصور منفصلة",
- "Keep -1 for seeds": "استخدم بذور عشوائية",
- "Save": "احفظ",
- "Write image to a directory (default - log/images) and generation parameters into csv file.": "احفظ الصور مع ملف العوامل بصيغة CSV",
- "Send to img2img": "أرسل لصورة إلى صورة",
- "Send to inpaint": "أرسل للإنتاج الجزئي",
- "Send to extras": "أرسل للمعالجة",
- "Open images output directory": "افتح مجلد الصور المخرجة",
- "Make Zip when Save?": "ضع النتائج في ملف مضغوط عند الحفظ",
- "img2img": "صورة إلى صورة",
- "Interrogate\nCLIP": "استجواب\nCLIP",
- "Drop Image Here": "اسقط صورة هنا",
- "Just resize": "تغيير الحجم فقط",
- "Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.": "غير حجم الصورة بدون مراعات اتزان الأبعاد",
- "Crop and resize": "تغيير الحجم وقص الأطراف",
- "Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out.": "غير حجم الصورة واقتص الأطراف الزائدة",
- "Resize and fill": "تغيير الحجم وتبطين الأطراف",
- "Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors.": "غير حجم الصورة واملأ الأطراف الزائدة بألوان من الصورة",
- "img2img alternative test": "استجواب الصورة (تجريبي)",
- "should be 2 or lower.": "يفترض أن يكون 2 أو أقل",
- "Override `Sampling method` to Euler?(this method is built for it)": "استخدم أسلوب خطو Euler (مستحسن)",
- "Override `prompt` to the same value as `original prompt`?(and `negative prompt`)": "استبدل الطلب وعكسه في الأعلى بالطلب الأصلي وعكسه التاليين",
- "Original prompt": "الطلب الأصلي",
- "Original negative prompt": "عكس الطلب الأصلي",
- "Override `Sampling Steps` to the same value as `Decode steps`?": "استبدل عدد الخطوات بعدد الخطوات الأصلية",
- "Decode steps": "عدد الخطوات الأصلية",
- "Override `Denoising strength` to 1?": "اجعل المدى 1",
- "Decode CFG scale": "التركيز",
- "Randomness": "العشوائية",
- "Sigma adjustment for finding noise for image": "لا تسمح بتثبيت قيمة التباين",
- "Loopback": "اجترار وتكرار",
- "Loops": "عدد المرات",
- "How many times to repeat processing an image and using it as input for the next iteration": "كم مرة يتم أخذ مخرجات الإنتاج كمدخلات وإعادة الإنتاج مرة أخرى",
- "Denoising strength change factor": "معدل تغيير المدى",
- "In loopback mode, on each loop the denoising strength is multiplied by this value. <1 means decreasing variety so your sequence will converge on a fixed picture. >1 means increasing variety so your sequence will become more and more chaotic.": "يتم ضرب المدى بهذا الرقم في كل مرة، إذا استخدمت رقم أصغر من 1 يمكن الرسو على نتيجة، وإذا استخدمت رقم أكبر من 1 تصبح النتيجة عشوائية",
- "Outpainting mk2": "توسيع الصورة (mk2)",
- "Recommended settings: Sampling Steps: 80-100, Sampler: Euler a, Denoising strength: 0.8": "يفضل استخدام: 80-100 خطوة، أسلوب Euler a، المدى 0.8",
- "Pixels to expand": "عدد البيكسلات",
- "Mask blur": "تنعيم القناع",
- "How much to blur the mask before processing, in pixels.": "مقدرا تنعيم القناع قبل استخدامه (يقاس بالبيكسل)",
- "Outpainting direction": "اتجاه توسيع الصورة",
- "left": "يسار",
- "right": "يمين",
- "up": "فوق",
- "down": "تحت",
- "Fall-off exponent (lower=higher detail)": "قوة السقوط (كلما قلت زادت التفاصيل)",
- "Color variation": "تنوع الألوان",
- "Poor man's outpainting": "توسيع الصورة (بدائي)",
- "Masked content": "محتويات القناع",
- "What to put inside the masked area before processing it with Stable Diffusion.": "ما يوضع مكان الفراغ في الصورة الذي نريد إنتاج محتوياته",
- "fill": "ألوان",
- "fill it with colors of the image": "املأ باستخدام ألوان مأخوذة من باقي الصورة",
- "original": "بدون تغيير",
- "keep whatever was there originally": "أبق محتويات ما تحت القناع كما هي",
- "latent noise": "تشويش كامن",
- "fill it with latent space noise": "املأه باستخدام تشويش من الفضاء الكامن",
- "latent nothing": "تصفير كامن",
- "fill it with latent space zeroes": "استبدل مكان القناع في الفضاء الكامن بأصفار",
- "SD upscale": "مضاعفة الدقة بنموذج الإنتشار المستقر",
- "Will upscale the image to twice the dimensions; use width and height sliders to set tile size": "سيتم تكبير حجم الصورة إلى الضعف، استخدم الطول والإرتفاع في الأعلى لتحديد حجم نافذة المكبر",
- "Tile overlap": "تداخل النافذة",
- "For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam.": "المكبر ينظر إلى أجزاء الصورة من خلال نافذة لتكبير المحتوى ثم ينتقل إلى الجزء المجاور، يفضل أن يكون هناك تداخل بين كل رقعة لكي لا يكون هناك اختلاف واضح بينهم",
- "Upscaler": "طريقة التكبير",
- "Lanczos": "Lanczos",
- "LDSR": "LDSR",
- "ScuNET GAN": "ScuNET GAN",
- "ScuNET PSNR": "ScuNET PSNR",
- "ESRGAN_4x": "ESRGAN_4x",
- "SwinIR 4x": "SwinIR 4x",
- "Inpaint": "إنتاج جزئي",
- "Draw mask": "ارسم القناع",
- "Upload mask": "ارفع القناع",
- "Inpaint masked": "أنتج ما بداخل القناع",
- "Inpaint not masked": "أنتج ما حول القناع",
- "Inpaint at full resolution": "إنتاج بالدقة الكاملة",
- "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image": "كبر ما يراد إعادة إنتاجه ثم صغر النتيجة وألصقها في مكانها",
- "Inpaint at full resolution padding, pixels": "عدد بيكسلات التبطين",
- "Batch img2img": "صور إلى صور",
- "Process images in a directory on the same machine where the server is running.": "حدد مسار مجلد صور موجود في جهاز الخادم",
- "Use an empty output directory to save pictures normally instead of writing to the output directory.": "يمكنك أيضا تحديد مجلد حفظ النتائج (غير الإفتراضي)",
- "Input directory": "مجلد المدخلات",
- "Output directory": "مجلد المخرجات",
- "Extras": "معالجة",
- "Single Image": "صورة واحدة",
- "Source": "المصدر",
- "Scale by": "مضاعفة الدقة",
- "Resize": "تغيير الحجم",
- "Upscaler 1": "المكبر الأول",
- "Upscaler 2": "المكبر الثاني",
- "Upscaler 2 visibility": "أثر المكبر الثاني",
- "GFPGAN visibility": "أثر GFPGAN (محسن وجوه)",
- "CodeFormer visibility": "أثر CodeFormer (محسن وجوه)",
- "CodeFormer weight (0 = maximum effect, 1 = minimum effect)": "وزن CodeFormer (يزيد التفاصيل على حساب الجودة)",
- "Upscale Before Restoring Faces": "كبر قبل تحسين الوجوه",
- "Scale to": "دقة محددة",
- "Crop to fit": "قص الأطراف الزائدة إذا لم تتناسب الأبعاد",
- "Batch Process": "حزمة صور",
- "Batch from Directory": "حزمة من مجلد",
- "A directory on the same machine where the server is running.": "مسار مجلد صور موجود في جهاز الخادم",
- "Leave blank to save images to the default path.": "اتركه فارغا لاستخدام المسار الإفتراضي",
- "Show result images": "اعرض الصور الناتجة",
- "PNG Info": "عوامل الصورة",
- "Send to txt2img": "أرسل لنص إلى صورة",
- "Checkpoint Merger": "مزج الأوزان",
- "A merger of the two checkpoints will be generated in your": "سيتم مزج الأوزان التالية وحفظ الأوزان المدجمة مع ",
- "checkpoint": "الأوزان",
- "directory.": " مجلد.",
- "Primary model (A)": "الأوزان الأولى (A)",
- "Secondary model (B)": "الأوزان الثانية (B)",
- "Tertiary model (C)": "الأوزان الثالثة (C)",
- "Custom Name (Optional)": "الاسم الجديد (اختياري)",
- "Multiplier (M) - set to 0 to get model A": "العامل M: مسافة الإبتعاد عن الأوزان الأولى A",
- "Interpolation Method": "طريقة المزج",
- "Weighted sum": "خطية",
- "Result = A * (1 - M) + B * M": "النتيجة = A * (1 - M) + B * M",
- "Add difference": "جمع الفرق",
- "Result = A + (B - C) * M": "النتيجة = A + (B - C) * M",
- "Save as float16": "احفظ بدقة float16",
- "Run": "تشغيل",
- "Train": "تدريب",
- "See": "اقرأ",
- "wiki": " الـwiki ",
- "for detailed explanation.": "لمعرفة المزيد",
- "Create embedding": "إنشاء تضمين",
- "Name": "الاسم",
- "Initialization text": "النص المبدأي",
- "Number of vectors per token": "عدد المتجهات لكل وحدة لغوية",
- "Overwrite Old Embedding": "استبدل التضمين القديم",
- "Create hypernetwork": "إنشاء شبكة فائقة",
- "Modules": "الأجزاء",
- "Enter hypernetwork layer structure": "ترتيب مضاعفات عرض الطبقات",
- "1st and last digit must be 1. ex:'1, 2, 1'": "المضاعفين الأول والأخير يجب أن يكونا 1، مثال: 1, 2, 1",
- "Select activation function of hypernetwork": "دالة التنشيط",
- "linear": "linear",
- "relu": "relu",
- "leakyrelu": "leakyrelu",
- "elu": "elu",
- "swish": "swish",
- "tanh": "tanh",
- "sigmoid": "sigmoid",
- "celu": "celu",
- "gelu": "gelu",
- "glu": "glu",
- "hardshrink": "hardshrink",
- "hardsigmoid": "hardsigmoid",
- "hardtanh": "hardtanh",
- "logsigmoid": "logsigmoid",
- "logsoftmax": "logsoftmax",
- "mish": "mish",
- "prelu": "prelu",
- "rrelu": "rrelu",
- "relu6": "relu6",
- "selu": "selu",
- "silu": "silu",
- "softmax": "softmax",
- "softmax2d": "softmax2d",
- "softmin": "softmin",
- "softplus": "softplus",
- "softshrink": "softshrink",
- "softsign": "softsign",
- "tanhshrink": "tanhshrink",
- "threshold": "threshold",
- "Select Layer weights initialization. relu-like - Kaiming, sigmoid-like - Xavier is recommended": "تهيئة الأوزان (استخدم Kaiming مع relu وأمثالها وXavier مع sigmoid وأمثالها)",
- "Normal": "Normal",
- "KaimingUniform": "KaimingUniform",
- "KaimingNormal": "KaimingNormal",
- "XavierUniform": "XavierUniform",
- "XavierNormal": "XavierNormal",
- "Add layer normalization": "أضف تسوية الطبقات (LayerNorm)",
- "Use dropout": "استخدم الإسقاط (Dropout)",
- "Overwrite Old Hypernetwork": "استبدل الشبكة الفائقة القديمة",
- "Preprocess images": "معالجة مسبقة للصور",
- "Source directory": "مجلد المدخلات",
- "Destination directory": "مجلد المخرجات",
- "Existing Caption txt Action": "اذا كانت الصورة لديها توصيف (طلب)",
- "ignore": "تجاهل",
- "copy": "انسخ",
- "prepend": "أسبق",
- "append": "ألحق",
- "Create flipped copies": "انشئ نسخ معكوسة للصور",
- "Split oversized images": "قسّم الصور الكبيرة",
- "Split image threshold": "حد تقسيم الصور الكبيرة",
- "Split image overlap ratio": "نسبة تداخل اقسام الصور الكبيرة",
- "Auto focal point crop": "اقتصاص تلقائي",
- "Focal point face weight": "تمركز الوجوه",
- "Focal point entropy weight": "تمركز التنوع",
- "Focal point edges weight": "تمركز الحواف",
- "Create debug image": "احفظ نتائج التحليل أيضا",
- "Use BLIP for caption": "استخدم BLIP لتوصيف الصور",
- "Use deepbooru for caption": "استخدم deepbooru لتوصيف الصور",
- "Preprocess": "معالجة مسبقة",
- "Train an embedding or Hypernetwork; you must specify a directory with a set of 1:1 ratio images": "درب التضمين أو الشبكة الفائقة: يجب تحديد مجلد يحتوي صور مربعة فقط ",
- "[wiki]": "[wiki]",
- "Embedding": "التضمين",
- "Embedding Learning rate": "معدل تعلم التضمين",
- "Hypernetwork Learning rate": "معدل تعلم الشبكة الفائقة",
- "Dataset directory": "مجلد مجموعة البيانات",
- "Path to directory with input images": "مسار مجلد الصور المدخلة",
- "Log directory": "مجلد السجل",
- "Path to directory where to write outputs": "مسار مجلد الصور المخرجة",
- "Prompt template file": "ملف صيغ الطلبات",
- "Max steps": "أقصى عدد لخطوات التدريب",
- "Save an image to log directory every N steps, 0 to disable": "احفظ صورة في السجل بعد كل كم خطوة تدريب (إذا 0 لا تحفظ)",
- "Save a copy of embedding to log directory every N steps, 0 to disable": "احفظ التضمين في السجل بعد كل كم خطوة تدريب (إذا 0 لا تحفظ)",
- "Save images with embedding in PNG chunks": "احفظ التضمين بداخل ملف الصورة كعامل يمكن استخراجه من عوامل الصورة (صيغة PNG)",
- "Read parameters (prompt, etc...) from txt2img tab when making previews": "استخدم قيم العوامل الموجودة في تبويب نص إلى صورة لعرض نتائجهم أثناء التدريب",
- "Train Hypernetwork": "درّب الشبكة الفائقة",
- "Train Embedding": "درّب التضمين",
- "Create aesthetic embedding": "تضمين تجميلي",
- "Create an aesthetic embedding out of any number of images": "انشئ تضمين تجميلي يعبر عن مجموعة من الصور",
- "Create images embedding": "انشئ التضمين التجميلي",
- "Image Browser": "معرض الصور",
- "Load": "حمّل",
- "Images directory": "مجلد الصور",
- "First Page": "الصفحة الأولى",
- "Prev Page": "الصفحة السابقة",
- "Page Index": "رقم الصفحة",
- "Next Page": "الصفحة التالية",
- "End Page": "الصفحة الأخيرة",
- "number of images to delete consecutively next": "عدد الصور المتتالية للحذف",
- "Delete": "احذف",
- "Generate Info": "معلومات عامة",
- "File Name": "اسم الملف",
- "Collect": "اجمع",
- "extras": "معالجة",
- "favorites": "المفضلة",
- "custom fold": "مجلد آخر",
- "Input images directory": "مجلد الصور المدخلة",
- "Settings": "إعدادات",
- "Apply settings": "طبق الإعدادت",
- "Saving images/grids": "حفظ الصور وجداولها",
- "Always save all generated images": "احفظ كل الصور المنتجة",
- "File format for images": "صيغة ملفات الصور",
- "Images filename pattern": "نمط تسمية الصور",
- "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.": "استخدم الأوسمة التالية لتحديد كيفية تسمية الصور: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp] أو اتركه فارغا إذا أردت",
- "Add number to filename when saving": "دائما أضف رقم على اسم الملف",
- "Always save all generated image grids": "احفظ جداول الصور دائما",
- "File format for grids": "صيغة ملفات جداول الصور",
- "Add extended info (seed, prompt) to filename when saving grid": "أضف عوامل الإنتاج (مثل الطلب والبذرة) لأسماء جداول الصور",
- "Do not save grids consisting of one picture": "لا تحفظ جدول الصور عند إنتاج صورة واحدة فقط",
- "Prevent empty spots in grid (when set to autodetect)": "في الوضع التلقائي امنع الفراغات في جداول الصور",
- "Grid row count; use -1 for autodetect and 0 for it to be same as batch size": "عدد صفوف جداول الصور (1-: تلقائي، 0: نفس حجم الحزمة)",
- "Save text information about generation parameters as chunks to png files": "احفظ عوامل الإنتاج داخل ملفات الصور (صيغة PNG)",
- "Create a text file next to every image with generation parameters.": "انشئ ملف نصي يحتوي على عوامل الإنتاج بجانب كل صورة",
- "Save a copy of image before doing face restoration.": "احفظ نسخة من الصورة قبل تحسين الوجوه",
- "Quality for saved jpeg images": "جودة حفظ صور JPEG",
- "If PNG image is larger than 4MB or any dimension is larger than 4000, downscale and save copy as JPG": "إذا كان حجم ملف صورة PNG أكبر من 4MB أو أحد أبعاد الصورة أكبر من 4000 بيكسل، صغر الصورة واحفظها بصيغة JPEG",
- "Use original name for output filename during batch process in extras tab": "استخدم الإسم الأصلي للصور عند معالجتهم في حزم تحت تبويب معالجة",
- "When using 'Save' button, only save a single selected image": "احفظ صورة واحدة فقط عند الضغط على حفظ",
- "Do not add watermark to images": "لا تضف علامة مائية على الصور",
- "If this option is enabled, watermark will not be added to created images. Warning: if you do not add watermark, you may be behaving in an unethical manner.": "الصور المنتجة لن تحتوي على علامة مائية عند تفعيل هذا الخيار، تحذير: ربما قد يدل هذا على أنك تتصرف بشكل غير أخلاقي",
- "Paths for saving": "اماكن الحفظ",
- "Output directory for images; if empty, defaults to three directories below": "مسار حفظ الصور المخرجة؛ يمكن أن يترك فارغا",
- "Output directory for txt2img images": "مسار الصور المخرجة من تبويب نص إلى صورة",
- "Output directory for img2img images": "مسار الصور المخرجة من تبويب صورة إلى صورة",
- "Output directory for images from extras tab": "مسار الصور المخرجة من تبويب معالجة",
- "Output directory for grids; if empty, defaults to two directories below": "مسار حفظ جداول الصور المخرجة؛ يمكن أن يترك فارغا",
- "Output directory for txt2img grids": "مسار جداول الصور المخرجة من تبويب نص إلى صورة",
- "Output directory for img2img grids": "مسار جداول الصور المخرجة من تبويب صورة إلى صورة",
- "Directory for saving images using the Save button": "مسار حفظ الصور عند الضغط على زر الحفظ",
- "Saving to a directory": "مجلدات الحفظ",
- "Save images to a subdirectory": "احفظ الصور في مجلد فرعي",
- "Save grids to a subdirectory": "احفظ جداول الصور في مجلد فرعي",
- "When using \"Save\" button, save images to a subdirectory": "احفظ الصور في مجلد فرعي عند الضغط على زر الحفظ",
- "Directory name pattern": "نمط اسم المجلد",
- "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.": "استخدم الأوسمة التالية لتحديد كيفية تسمية المجلدات الفرعية للصور والصور المركبة: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp] أو اتركه فارغا إذا أردت",
- "Max prompt words for [prompt_words] pattern": "أقصى عدد كلمات الطلب عند استخدام وسم [prompt_words]",
- "Upscaling": "تكبير الصور",
- "Tile size for ESRGAN upscalers. 0 = no tiling.": "حجم نافذة المكبر ESRGAN (يمكن أن يكون 0)",
- "Tile overlap, in pixels for ESRGAN upscalers. Low values = visible seam.": "تداخل نافذة المكبر ESRGAN (تتضح الفواصل إذا كان قليل)",
- "Select which Real-ESRGAN models to show in the web UI. (Requires restart)": "حدد ما تريد عرضه كخيار لمكبر من نوع Real-ESRGAN يمكن استخدامه (يتطلب إعادة تشغيل)",
- "Tile size for all SwinIR.": "حجم نافذة المكبر SwinIR",
- "Tile overlap, in pixels for SwinIR. Low values = visible seam.": "تداخل نافذة المكبر SwinIR (تتضح الفواصل إذا كان قليل)",
- "LDSR processing steps. Lower = faster": "عدد خطوات مكبر LDSR (أسرع كلما قلت)",
- "Upscaler for img2img": "طريقة التكبير تحت تبويب صورة إلى صورة",
- "Upscale latent space image when doing hires. fix": "عند اختيار \"إصلاح الدقة العالية\" قم بالتكبير في الفضاء الكامن",
- "Face restoration": "تحسين الوجوه",
- "Face restoration model": "نموذج تحسين الوجوه",
- "Restore low quality faces using GFPGAN neural network": "استخدم نموذج GFPGAN لتحسين الوجوه",
- "CodeFormer weight parameter; 0 = maximum effect; 1 = minimum effect": "وزن CodeFormer (يزيد التفاصيل على حساب الجودة)",
- "Move face restoration model from VRAM into RAM after processing": "احذف محسن الوجوه من ذاكرة كرت الشاشة (VRAM) بعد استخدامه",
- "System": "النظام",
- "VRAM usage polls per second during generation. Set to 0 to disable.": "عدد مرات التحقق من ذاكرة كرت الشاشة المستخدمة (VRAM) في الثانية",
- "Always print all generation info to standard output": "اطبع دائما كل عوامل الإنتاج",
- "Add a second progress bar to the console that shows progress for an entire job.": "أضف شريط تقدم ثاني لعملية الإنتاج الكاملة",
- "Training": "التدريب",
- "Move VAE and CLIP to RAM when training hypernetwork. Saves VRAM.": "قلل استخدام ذاكرة كرت الشاشة (VRAM) عند تدريب الشبكة الفائقة بالتخلص من CLIP وVAE",
- "Filename word regex": "التعبير النمطي (RegEx) لكلمات اسم الملف",
- "This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is.": "استخدم هذا التعبير لاستخراج كلمات من أسماء الملفات ليتم دمجها بالخيار التالي لتستخدم في التدريب، اتركه فارغا لتستخدم اسم الملف كما هو",
- "Filename join string": "النص الفاصل للكلمات المدموجة",
- "This string will be used to join split words into a single line if the option above is enabled.": "سيستخدم بين كل كلمة يتم استخراجها من الخيار السابق",
- "Number of repeats for a single input image per epoch; used only for displaying epoch number": "عدد مرات تكرار الصور في كل دورة (Epoch)، يستخدم للعرض فقط",
- "Save an csv containing the loss to log directory every N steps, 0 to disable": "احفظ خسارة التدريب (Loss) في السجل بعد كل كم خطوة (إذا 0 لا تحفظ)",
- "Stable Diffusion": "نموذج الإنتشار المستقر (Stable Diffusion)",
- "Checkpoints to cache in RAM": "عدد النماذج التي تترك في الذاكرة العشوائية (RAM)",
- "Hypernetwork strength": "قوة الشبكة الفائقة",
- "Apply color correction to img2img results to match original colors.": "صحح ألوان نتائج صورة إلى صورة لتشابه الصورة الأصلية",
- "Save a copy of image before applying color correction to img2img results": "احفظ نسخة من الصور المنتجة من صورة إلى صورة قبل عملية تصحيح الألوان",
- "With img2img, do exactly the amount of steps the slider specifies (normally you'd do less with less denoising).": "استخدم بالضبط عدد الخطوات المحددة بالرغم عن المدى (عدد الخطوات الإفتراضي = عدد الخطوات / المدى)",
- "Enable quantization in K samplers for sharper and cleaner results. This may change existing seeds. Requires restart to apply.": "فعل التجزيء الكمي (Quantization) لأغلب أساليب الخطو (k-diffusion) للحصول على صور أنظف (يتطلب إعادة تشغيل)",
- "Emphasis: use (text) to make model pay more attention to text and [text] to make it pay less attention": "أحط أي كلمة أو عبارة في الطلب أو عكسه بأقواس () للتشديد أو [] للتيسير",
- "Use old emphasis implementation. Can be useful to reproduce old seeds.": "استخدم الطريقة القديمة للتشديد (إذا كانت لديك نتائج قديمة تريد تجربتها)",
- "Make K-diffusion samplers produce same images in a batch as when making a single image": "عدم تأثير تحزيم الصور على البذور عند استخدام أساليب خطو (k-diffusion)",
- "Increase coherency by padding from the last comma within n tokens when using more than 75 tokens": "عند استخدام طلب طويل أكبر من 75 وحدة لغوية، افصل الطلب عند أخر فاصلة قبل كم كلمة",
- "Filter NSFW content": "انتق المحتوى النظيف فقط",
- "Stop At last layers of CLIP model": "قف عند آخر كم طبقة لنموذج CLIP",
- "Allowed categories for random artists selection when using the Roll button": "اختر اهتمامات الفنانين المسموح بإضافتهم للطلب",
- "Interrogate Options": "خيارات الاستجواب",
- "Interrogate: keep models in VRAM": "ابق نموذج الاستجواب في ذاكرة كرت الشاشة (VRAM)",
- "Interrogate: use artists from artists.csv": "استخدم قائمة الفنانين في الاستجواب من ملف artists.csv",
- "Interrogate: include ranks of model tags matches in results (Has no effect on caption-based interrogators).": "أدرج رتب الشعارات عند الاستجواب (لا تعمل مع جميع النماذج)",
- "Interrogate: num_beams for BLIP": "عدد أشعة الاستجواب لنموذج BLIP",
- "Interrogate: minimum description length (excluding artists, etc..)": "أقل عدد كلمات للتوصيف (لا يتضمن الفنانين وغيرهم)",
- "Interrogate: maximum description length": "أكثر عدد كلمات للتوصيف",
- "CLIP: maximum number of lines in text file (0 = No limit)": "أكثر عدد أسطر لملف نصي عند الاستجواب باستخدام CLIP (0 = بدون حد)",
- "Interrogate: deepbooru score threshold": "حد درجة الاستجواب باستخدام deepbooru",
- "Interrogate: deepbooru sort alphabetically": "رتب نتائج توصيف deepbooru أبجديا",
- "use spaces for tags in deepbooru": "افصل شعارات deepbooru بمسافات",
- "escape (\\) brackets in deepbooru (so they are used as literal brackets and not for emphasis)": "تجاهل الأقواس عند استخدام deepbooru (كي لا تعامل كأقواس التشديد)",
- "User interface": "واجهة المستخدم",
- "Show progressbar": "اظهر شريط التقدم",
- "Show image creation progress every N sampling steps. Set 0 to disable.": "اعرض صورة بعد كل كم خطوة (إذا 0 لا تعرض)",
- "Show previews of all images generated in a batch as a grid": "اعرض كل الصور التي تم إنتاجها في حزمة كجدول",
- "Show grid in results for web": "أظهر نتائج جداول الصور",
- "Do not show any images in results for web": "لا تظهر نتائج الصور",
- "Add model hash to generation information": "أضف رمز تهشير (Hash) ملف الأوزان لعوامل الإنتاج",
- "Add model name to generation information": "أضف اسم ملف الأوزان لعوامل الإنتاج",
- "When reading generation parameters from text into UI (from PNG info or pasted text), do not change the selected model/checkpoint.": "لا تغير الأوزان المختارة عند قراءة عوامل الإنتاج من صورة أو من ملف",
- "Send seed when sending prompt or image to other interface": "عند إرسال صورة أو طلب ألحق البذرة أيضا",
- "Font for image grids that have text": "نوع الخط في جداول الصور التي تحتوي على نصوص",
- "Enable full page image viewer": "اسمح بعرض الصور في وضع ملئ الشاشة",
- "Show images zoomed in by default in full page image viewer": "اعرض الصور مقربة عند استخدام وضع ملئ الشاشة",
- "Show generation progress in window title.": "أظهر التقدم في عنوان النافذة",
- "Quicksettings list": "قائمة الإعدادات السريعة",
- "List of setting names, separated by commas, for settings that should go to the quick access bar at the top, rather than the usual setting tab. See modules/shared.py for setting names. Requires restarting to apply.": "قائمة مقسمة بفواصل لأسماء الإعدادات التي يجب أن تظهر في الأعلى لتسهيل الوصول إليها، انظر إلى modules/shared.py لمعرفة الأسماء، يتطلب إعادة تشغيل",
- "Localization (requires restart)": "اللغة (تتطلب إعادة تشغيل)",
- "pt_BR": "البرتغالية",
- "zh_CN": "الصينية",
- "ko_KR": "الكورية",
- "fr_FR": "الفرنسية",
- "ru_RU": "الروسية",
- "ar_AR": "العربية",
- "tr_TR": "التركية",
- "it_IT": "الإيطالية",
- "ja_JP": "اليابانية",
- "de_DE": "الألمانية",
- "zh_TW": "الصينية (تايوان)",
- "es_ES": "الإسبانية",
- "Sampler parameters": "عوامل أساليب الخطو",
- "Hide samplers in user interface (requires restart)": "اخف أساليب الخطو التالية (يتطلب إعادة تشغيل)",
- "eta (noise multiplier) for DDIM": "العامل Eta η لأسلوب الخطو DDIM",
- "eta (noise multiplier) for ancestral samplers": "العامل Eta η لأساليب الخطو السلفية (Ancestral)",
- "img2img DDIM discretize": "طريقة التقطيع (Discretization) لأسلوب الخطو DDIM في وضع صورة إلى صورة",
- "uniform": "خطية",
- "quad": "تربيعية",
- "sigma churn": "العشوائية (Schurn)",
- "sigma tmin": "أدنى تشويش (Stmin)",
- "sigma noise": "التشويش (Snoise)",
- "Eta noise seed delta": "إزاحة بذرة أساليب الخطو التي تستعمل العامل Eta η",
- "If this values is non-zero, it will be added to seed and used to initialize RNG for noises when using samplers with Eta. You can use this to produce even more variation of images, or you can use this to match images of other software if you know what you are doing.": "هذا الرقم سيتم إضافته إلى البذرة عند استخدام أحد أساليب الخطو التي تستعمل العامل Eta η، يفيد هذا الخيار في مشابهة نتائج بعض البرامج الأخرى التي تستعمله",
- "Images Browser": "معرض الصور",
- "Preload images at startup": "حمل الصور عند بدء التشغيل",
- "Number of columns on the page": "عدد الأعمدة في كل صفحة",
- "Number of rows on the page": "عدد الصفوف في كل صفحة",
- "Minimum number of pages per load": "أقل عدد صور يتم تحميلها كل مرة",
- "Request browser notifications": "اطلب تنبيهات المتصفح",
- "Download localization template": "حمل ملف اللغة",
- "Reload custom script bodies (No ui updates, No restart)": "أعد تحميل الأدوات الخاصة (بدون واجهة المستخدم ولا يحتاج إعادة تشغيل)",
- "Restart Gradio and Refresh components (Custom Scripts, ui.py, js and css only)": "أعد تشغيل gradio وتحميل الأدوات الخاصة وواجهة المستخدم",
- "⤡": "⤡",
- "⊞": "⊞",
- "×": "×",
- "❮": "❮",
- "❯": "❯",
- "•": "•",
- "Label": "Label",
- "File": "File",
- "Image": "Image",
- "Check progress": "Check progress",
- "Check progress (first)": "Check progress (first)",
- "Textbox": "Textbox",
- "Image for img2img": "Image for img2img",
- "Image for inpainting with mask": "Image for inpainting with mask",
- "Mask": "Mask",
- "Mask mode": "Mask mode",
- "Masking mode": "Masking mode",
- "Resize mode": "Resize mode",
- "Prev batch": "Prev batch",
- "Next batch": "Next batch",
- "Refresh page": "Refresh page",
- "Date to": "Date to",
- "Number": "Number",
- "set_index": "set_index",
- "Checkbox": "Checkbox"
-}
diff --git a/localizations/de_DE.json b/localizations/de_DE.json
deleted file mode 100644
index 56d54b54..00000000
--- a/localizations/de_DE.json
+++ /dev/null
@@ -1,458 +0,0 @@
-{
- "⤡": "⤡",
- "⊞": "⊞",
- "×": "×",
- "❮": "❮",
- "❯": "❯",
- "view": "API ",
- "api": "anzeigen",
- "•": " • ",
- "built with gradio": "Mit Gradio erstellt",
- "Loading...": "Lädt...",
- "Stable Diffusion checkpoint": "Stable Diffusion Checkpoint",
- "txt2img": "txt2img",
- "img2img": "img2img",
- "Extras": "Extras",
- "PNG Info": "PNG Info",
- "Checkpoint Merger": "Checkpoint Fusion",
- "Train": "Trainieren",
- "Settings": "Einstellungen",
- "Prompt": "Prompt",
- "Negative prompt": "Negative Prompt",
- "Run": "Ausführen",
- "Skip": "Überspringen",
- "Interrupt": "Abbrechen",
- "Generate": "Generieren",
- "Style 1": "Stil 1",
- "Style 2": "Stil 2",
- "Label": "Bezeichnung",
- "File": "Datei",
- "Drop File Here": "Datei hier ablegen",
- "-": "-",
- "o": "oder",
- "Click to Upload": "Hochladen",
- "Image": "Bild",
- "Check progress": "Fortschitt prüfen",
- "Check progress (first)": "Fortschritt prüfen (Initial)",
- "Sampling Steps": "Samplingschritte",
- "Sampling method": "Samplingmethode",
- "Euler a": "Euler a",
- "Euler": "Euler",
- "LMS": "LMS",
- "Heun": "Heun",
- "DPM2": "DPM2",
- "DPM2 a": "DPM2 a",
- "DPM fast": "DPM fast",
- "DPM adaptive": "DPM adaptive",
- "LMS Karras": "LMS Karras",
- "DPM2 Karras": "DPM2 Karras",
- "DPM2 a Karras": "DPM2 a Karras",
- "DDIM": "DDIM",
- "PLMS": "PLMS",
- "Width": "Breite",
- "Height": "Höhe",
- "Restore faces": "Gesichter wiederherstellen",
- "Tiling": "Kacheln",
- "Highres. fix": "Highres. Fix",
- "Firstpass width": "Breite Erstdurchlauf",
- "Firstpass height": "Höhe Erstdurchlauf",
- "Denoising strength": "Denoisingstärke",
- "Batch count": "Batchanzahl",
- "Batch size": "Batchgröße",
- "CFG Scale": "CFG-Skala",
- "Seed": "Seed",
- "Extra": "Extra",
- "Variation seed": "Variationsseed",
- "Variation strength": "Variationsstärke",
- "Resize seed from width": "Seed von Breite ändern",
- "Resize seed from height": "Seed von Höhe ändern",
- "Script": "Skript",
- "None": "Nichts",
- "Prompt matrix": "Promptmatrix",
- "Prompts from file or textbox": "Prompts aus Datei oder Textfeld",
- "X/Y plot": "X/Y Graf",
- "Put variable parts at start of prompt": "Variable teile am start des Prompt setzen",
- "Iterate seed every line": "Iterate seed every line",
- "List of prompt inputs": "List of prompt inputs",
- "Upload prompt inputs": "Upload prompt inputs",
- "X type": "X-Typ",
- "Nothing": "Nichts",
- "Var. seed": "Var. seed",
- "Var. strength": "Var. strength",
- "Steps": "Schritte",
- "Prompt S/R": "Prompt Suchen/Ersetzen",
- "Prompt order": "Promptreihenfolge",
- "Sampler": "Sampler",
- "Checkpoint name": "Checkpointname",
- "Hypernetwork": "Hypernetwork",
- "Hypernet str.": "Hypernet str.",
- "Sigma Churn": "Sigma Churn",
- "Sigma min": "Sigma min",
- "Sigma max": "Sigma max",
- "Sigma noise": "Sigma noise",
- "Eta": "Eta",
- "Clip skip": "Clip skip",
- "Denoising": "Denoising",
- "Cond. Image Mask Weight": "Cond. Image Mask Weight",
- "X values": "X-Werte",
- "Y type": "Y-Typ",
- "Y values": "Y-Werte",
- "Draw legend": "Legende zeichnen",
- "Include Separate Images": "Seperate Bilder hinzufügen",
- "Keep -1 for seeds": "-1 als Seed behalten",
- "Save": "Speichern",
- "Send to img2img": "An img2img senden",
- "Send to inpaint": "An Inpaint senden",
- "Send to extras": "An Extras senden",
- "Make Zip when Save?": "Zip beim Speichern erstellen?",
- "Textbox": "Textfeld",
- "Interrogate\nCLIP": "Interrogate\nCLIP",
- "Interrogate\nDeepBooru": "Interrogate\nDeepBooru",
- "Inpaint": "Inpaint",
- "Batch img2img": "Batch img2img",
- "Image for img2img": "Bild für img2img",
- "Drop Image Here": "Bild hier ablegen",
- "Image for inpainting with mask": "Bild für inpainting mit Maske",
- "Mask": "Maske",
- "Mask blur": "Maskenunschärfe",
- "Mask mode": "Maskenmodus",
- "Draw mask": "Maske zeichnen",
- "Upload mask": "Maske hochladen",
- "Masking mode": "Maskierungsmodus",
- "Inpaint masked": "Maskiertes inpainten",
- "Inpaint not masked": "Nicht maskiertes inpainten",
- "Masked content": "Maskierter Inhalt",
- "fill": "ausfüllen",
- "original": "original",
- "latent noise": "latent noise",
- "latent nothing": "latent nothing",
- "Inpaint at full resolution": "Inpaint mit voller Auflösung",
- "Inpaint at full resolution padding, pixels": "Inpaint bei voller Auflösung Abstand, Pixel",
- "Process images in a directory on the same machine where the server is running.": "Bilder in einem Verzeichnis auf demselben Rechner verarbeiten, auf dem der Server läuft.",
- "Use an empty output directory to save pictures normally instead of writing to the output directory.": "Ein leeres Ausgabeverzeichnis verwenden, um Bilder normal zu speichern, anstatt in das Ausgabeverzeichnis zu schreiben.",
- "Input directory": "Eingabeverzeichnis",
- "Output directory": "Ausgabeverzeichnis",
- "Resize mode": "Größenänderungsmodus",
- "Just resize": "Nur Größe anpassen",
- "Crop and resize": "Zuschneiden und Größe anpassen",
- "Resize and fill": "Größe anpassen und ausfüllen",
- "img2img alternative test": "img2img alternativer Test",
- "Loopback": "Loopback",
- "Outpainting mk2": "Outpainting mk2",
- "Poor man's outpainting": "Poor man's outpainting",
- "SD upscale": "SD-Upscale",
- "should be 2 or lower.": "Sollte 2 oder niedriger sein.",
- "Override `Sampling method` to Euler?(this method is built for it)": "`Samplingmethode` auf Euler setzen? (Diese Methode is dafür ausgelegt)",
- "Override `prompt` to the same value as `original prompt`?(and `negative prompt`)": "`Prompt` auf denselben Wert wie `Originale Prompt` (und `Negative Prompt`) setzen?",
- "Original prompt": "Originale Prompt",
- "Original negative prompt": "Originale negative Prompt",
- "Override `Sampling Steps` to the same value as `Decode steps`?": "`Samplingschritte` auf denselben Wert wie `Dekodierschritte` setzen?",
- "Decode steps": "Dekodierschritte",
- "Override `Denoising strength` to 1?": "`Denoisingstärke auf 1 setzen?",
- "Decode CFG scale": "CFG-Skala dekodieren",
- "Randomness": "Zufälligkeit",
- "Sigma adjustment for finding noise for image": "Sigma-Anpassung für die Suche nach Noise des Bildes",
- "Loops": "Schleifen",
- "Denoising strength change factor": "Denoising strength change factor",
- "Recommended settings: Sampling Steps: 80-100, Sampler: Euler a, Denoising strength: 0.8": "Empfohlene Einstellungen: Samplingschritte: 80-100, Samplermethode: Euler a, Denoisingstärke: 0.8",
- "Pixels to expand": "Pixel zum Erweitern",
- "Outpainting direction": "Outpainting Richtung",
- "left": "Links",
- "right": "Rechts",
- "up": "Hoch",
- "down": "Runter",
- "Fall-off exponent (lower=higher detail)": "Abfallexponent (niedriger=mehr Details)",
- "Color variation": "Farbabweichung",
- "Will upscale the image to twice the dimensions; use width and height sliders to set tile size": "Skaliert das Bild auf die doppelte Größe; Benutze die Schieberegler für Breite und Höhe, um die Kachelgröße einzustellen",
- "Tile overlap": "Kachelüberlappung",
- "Upscaler": "Upscaler",
- "Lanczos": "Lanczos",
- "LDSR": "LDSR",
- "SwinIR 4x": "SwinIR 4x",
- "ScuNET GAN": "ScuNET GAN",
- "ScuNET PSNR": "ScuNET PSNR",
- "ESRGAN_4x": "ESRGAN_4x",
- "Single Image": "Einzelnes Bild",
- "Batch Process": "Batchverarbeitung",
- "Batch from Directory": "Batchverarbeitung aus Verzeichnis",
- "Source": "Quelle",
- "Show result images": "Bildergebnisse zeigen",
- "Scale by": "Skalieren um",
- "Scale to": "Skalieren zu",
- "Resize": "Größe anpassen",
- "Crop to fit": "Zuschneiden damit es passt",
- "Upscaler 2 visibility": "Upscaler 2 Sichtbarkeit",
- "GFPGAN visibility": "GFPGAN Sichtbarkeit",
- "CodeFormer visibility": "CodeFormer Sichtbarkeit",
- "CodeFormer weight (0 = maximum effect, 1 = minimum effect)": "CodeFormer Gewichtung (0 = maximale Wirkung, 1 = minimale Wirkung)",
- "Upscale Before Restoring Faces": "Upscale Before Restoring Faces",
- "Send to txt2img": "An txt2img senden",
- "A merger of the two checkpoints will be generated in your": "Die zusammgeführten Checkpoints werden gespeichert unter",
- "checkpoint": "Checkpoint",
- "directory.": "Verzeichnis.",
- "Primary model (A)": "Primäres Modell (A)",
- "Secondary model (B)": "Sekundäres Modell (B)",
- "Tertiary model (C)": "Tertiäres Modell (C)",
- "Custom Name (Optional)": "Eigener Name (Optional)",
- "Multiplier (M) - set to 0 to get model A": "Multiplikator (M) - auf 0 setzen, um Modell A zu erhalten",
- "Interpolation Method": "Interpolationsmethode",
- "Weighted sum": "Weighted sum",
- "Add difference": "Add difference",
- "Save as float16": "Speichern als float16",
- "See": "Siehe ",
- "wiki": "Wiki ",
- "for detailed explanation.": "für eine ausführliche Erklärung.",
- "Create embedding": "Embedding erstellen",
- "Create hypernetwork": "Hypernetwork erstellen",
- "Preprocess images": "Bilder vorbereiten",
- "Name": "Name",
- "Initialization text": "Initialisierungstext",
- "Number of vectors per token": "Anzahl der Vektoren pro Token",
- "Overwrite Old Embedding": "Alte Embeddings überschreiben",
- "Modules": "Module",
- "Enter hypernetwork layer structure": "Hypernetwork-Ebenenstruktur angeben",
- "Select activation function of hypernetwork": "Aktivierungsfunktion des Hypernetwork auswählen",
- "linear": "linear",
- "relu": "relu",
- "leakyrelu": "leakyrelu",
- "elu": "elu",
- "swish": "swish",
- "tanh": "tanh",
- "sigmoid": "sigmoid",
- "celu": "celu",
- "gelu": "gelu",
- "glu": "glu",
- "hardshrink": "hardshrink",
- "hardsigmoid": "hardsigmoid",
- "hardtanh": "hardtanh",
- "logsigmoid": "logsigmoid",
- "logsoftmax": "logsoftmax",
- "mish": "mish",
- "prelu": "prelu",
- "rrelu": "rrelu",
- "relu6": "relu6",
- "selu": "selu",
- "silu": "silu",
- "softmax": "softmax",
- "softmax2d": "softmax2d",
- "softmin": "softmin",
- "softplus": "softplus",
- "softshrink": "softshrink",
- "softsign": "softsign",
- "tanhshrink": "tanhshrink",
- "threshold": "threshold",
- "Select Layer weights initialization. relu-like - Kaiming, sigmoid-like - Xavier is recommended": "Auswahl der Initialisierung der Ebenengewichte. Empfohlen wird relu-like - Kaiming, sigmoid-like - Xavier",
- "Normal": "Normal",
- "KaimingUniform": "KaimingUniform",
- "KaimingNormal": "KaimingNormal",
- "XavierUniform": "XavierUniform",
- "XavierNormal": "XavierNormal",
- "Add layer normalization": "Ebenennormalisierung hinzufügen",
- "Use dropout": "Dropout benutzen",
- "Overwrite Old Hypernetwork": "Altes Hypernetwork überschreiben",
- "Source directory": "Quellenverzeichnis",
- "Destination directory": "Zielverzeichnis",
- "Existing Caption txt Action": "Vorhandene Beschriftung der txt",
- "ignore": "ignorieren",
- "copy": "kopieren",
- "prepend": "voranstellen",
- "append": "anhängen",
- "Create flipped copies": "Gespiegelte Bilder erstellen",
- "Split oversized images": "Übergroße Bilder aufteilen",
- "Auto focal point crop": "Automatisch auf Fokuspunkt zuschneiden",
- "Use BLIP for caption": "BLIP für Beschriftung nutzen",
- "Use deepbooru for caption": "Deepbooru für Beschriftung nutzen",
- "Split image threshold": "Schwellenwert für die Aufteilung von Bildern",
- "Split image overlap ratio": "Überschneidungsverhältnis der Teilbilder",
- "Focal point face weight": "Fokuspunkt Gesicht Gewicht",
- "Focal point entropy weight": "Fokuspunkt Entropie Gewicht",
- "Focal point edges weight": "Fokuspunkt Kanten Gewicht",
- "Create debug image": "Testbild erstellen",
- "Preprocess": "Vorbereiten",
- "Train an embedding or Hypernetwork; you must specify a directory with a set of 1:1 ratio images": "Trainieren eines Embeddings oder eines Hypernetworks; Sie müssen ein Verzeichnis mit einem Satz von Bildern im Verhältnis 1:1 angeben",
- "[wiki]": "[Wiki]",
- "Embedding": "Embedding",
- "Embedding Learning rate": "Embedding Lernrate",
- "Hypernetwork Learning rate": "Hypernetwork Lernrate",
- "Dataset directory": "Datensatzverzeichnis",
- "Log directory": "Protokollverzeichnis",
- "Prompt template file": "Prompt-Vorlagendatei",
- "Max steps": "Max Schritte",
- "Save an image to log directory every N steps, 0 to disable": "Speichere alle N Schritte ein Bild im Protokollverzeichnis, 0 zum Deaktivieren",
- "Save a copy of embedding to log directory every N steps, 0 to disable": "Speichere alle N Schritte eine Embeddingkopie im Protokollverzeichnis, 0 zum Deaktivieren",
- "Save images with embedding in PNG chunks": "Speichere Bilder mit Embeddings in PNG Chunks",
- "Read parameters (prompt, etc...) from txt2img tab when making previews": "Lese Parameter (Prompt, etc...) aus dem txt2img-Tab beim Erstellen von Vorschaubildern.",
- "Train Hypernetwork": "Hypernetwork Trainieren",
- "Train Embedding": "Embedding Trainieren",
- "Apply settings": "Eintellungen anwenden",
- "Saving images/grids": "Bilder/Raster speichern",
- "Always save all generated images": "Immer alle generierten Bilder speichern",
- "File format for images": "Dateiformat für Bilder",
- "Images filename pattern": "Dateinamensmuster für Bilder",
- "Add number to filename when saving": "Beim speichern, dem Dateinamen Nummer anhängen",
- "Always save all generated image grids": "Immer alle generierten Bildraster speichern",
- "File format for grids": "Dateiformat für Raster",
- "Add extended info (seed, prompt) to filename when saving grid": "Beim Speichern von Rastern zusätzliche Information (Seed, Prompt) hinzufügen",
- "Do not save grids consisting of one picture": "Keine Raster speichern, die nur aus einem Bild bestehen",
- "Prevent empty spots in grid (when set to autodetect)": "Lücken im Raster verhindern (falls auf Auto-Erkennung gesetzt)",
- "Grid row count; use -1 for autodetect and 0 for it to be same as batch size": "Rasterreihenanzahl; -1 für Auto-Erkennung und 0 für die gleiche wie die Batchanzahl",
- "Save text information about generation parameters as chunks to png files": "Generationsparameter als Chunks in PNG-Dateien speichern",
- "Create a text file next to every image with generation parameters.": "Erstelle zu jedem Bild eine Textdatei, die die Generationsparameter enthält",
- "Save a copy of image before doing face restoration.": "Vor der Gesichtswiederhestellung eine Kopie des Bildes speichern",
- "Quality for saved jpeg images": "Qualität der JPEG-Bilder",
- "If PNG image is larger than 4MB or any dimension is larger than 4000, downscale and save copy as JPG": "Wenn ein PNG-Bild größer als 4MB oder die Dimensionen größer als 4000 ist, herunterskalieren und als JPG speichern.",
- "Use original name for output filename during batch process in extras tab": "Orginale Dateinamen als Ausgabenamen bei der Batchverarbeitung im Extras-Tab verwenden",
- "When using 'Save' button, only save a single selected image": "Bei der Benutzung des 'Speichern'-Knopfes, nur das ausgewählte Bild speichern",
- "Do not add watermark to images": "Den Bildern kein Wasserzeichen hinzufügen",
- "Paths for saving": "Pfade zum Speichern",
- "Output directory for images; if empty, defaults to three directories below": "Ausgabeverzeichnis für Bilder; Falls leer, werden die Pfade unterhalb verwendet",
- "Output directory for txt2img images": "Ausgabeverzeichnis für txt2img Bilder",
- "Output directory for img2img images": "Ausgabeverzeichnis für img2img Bilder",
- "Output directory for images from extras tab": "Ausgabeverzeichnis für Extras-Tab Bilder",
- "Output directory for grids; if empty, defaults to two directories below": "Ausgabeverzeichnis für Raster; Falls leer, werden die Pfade unterhalb verwendet",
- "Output directory for txt2img grids": "Ausgabeverzeichnis für txt2img Raster",
- "Output directory for img2img grids": "Ausgabeverzeichnis für img2img Raster",
- "Directory for saving images using the Save button": "Ausgabeverzeichnis für Bilder, die mit dem 'Speichern'-Knopf gespeichert wurden",
- "Saving to a directory": "Speichern in ein Verzeichnis",
- "Save images to a subdirectory": "Bilder in ein Unterverzeichnis speichern",
- "Save grids to a subdirectory": "Raster in ein Unterverzeichnis speichern",
- "When using \"Save\" button, save images to a subdirectory": "Bilder bei der Benutzung des 'Speichern'-Knopfes in ein Unterverzeichnis speichern",
- "Directory name pattern": "Muster für Verzeichnisnamen",
- "Max prompt words for [prompt_words] pattern": "Maximale Wortanzahl für [prompt_words] Muster",
- "Upscaling": "Upscaling",
- "Tile size for ESRGAN upscalers. 0 = no tiling.": "Kachelgröße für ESRGAN-Upscaler. 0 = keine Kacheln.",
- "Tile overlap, in pixels for ESRGAN upscalers. Low values = visible seam.": "Kachelüberlappung in Pixeln für ESRGAN-Upscaler. Niedrige Werte = sichtbare Naht.",
- "Tile size for all SwinIR.": "Kachelgröße für alle SwinIR.",
- "Tile overlap, in pixels for SwinIR. Low values = visible seam.": "Kachelüberlappung in Pixeln für SwinIR. Niedrige Werte = sichtbare Naht.",
- "LDSR processing steps. Lower = faster": "LDSR-Verarbeitungsschritte. Niedriger = schneller",
- "Upscaler for img2img": "Upscaler für img2img",
- "Upscale latent space image when doing hires. fix": "Bild des Latent Space upscalen, wenn Highres. Fix benutzt wird",
- "Face restoration": "Gesichtswiederhestellung",
- "CodeFormer weight parameter; 0 = maximum effect; 1 = minimum effect": "CodeFormer Gewichtung (0 = maximale Wirkung, 1 = minimale Wirkung)",
- "Move face restoration model from VRAM into RAM after processing": "Verschiebe Gesichtswiederhestellung-Modell nach der Verarbeitung vom VRAM in den RAM",
- "System": "System",
- "VRAM usage polls per second during generation. Set to 0 to disable.": "VRAM-Nutzungsabfragen pro Sekunde während der Generierung. Zum Deaktivieren auf 0 setzen.",
- "Always print all generation info to standard output": "Immer alle Generationsinformationen in der Standardausgabe ausgeben",
- "Add a second progress bar to the console that shows progress for an entire job.": "Der Konsole einen zweiten Fortschrittsbalken hinzufügen, der den Fortschritt eines gesamten Auftrags anzeigt.",
- "Training": "Training",
- "Move VAE and CLIP to RAM when training hypernetwork. Saves VRAM.": "VAE und CLIP während des Hypernetwork-Trainings in den RAM verschieben. Spart VRAM.",
- "Filename word regex": "Filename word regex",
- "Filename join string": "Filename join string",
- "Number of repeats for a single input image per epoch; used only for displaying epoch number": "Anzahl der Wiederholungen für ein einzelnes Eingabebild pro Epoche; wird nur für die Anzeige der Epochennummer verwendet",
- "Save an csv containing the loss to log directory every N steps, 0 to disable": "Speichere eine csv-Datei, die den Verlust enthält, im Protokollverzeichnis alle N Schritte, 0 zum Deaktivieren",
- "Stable Diffusion": "Stable Diffusion",
- "Checkpoints to cache in RAM": "Checkpoints zum Zwischenspeichern im RAM",
- "Hypernetwork strength": "Hypernetworkstärke",
- "Inpainting conditioning mask strength": "Inpainting Stärke der Konditionierungsmaske",
- "Apply color correction to img2img results to match original colors.": "Farbkorrektur auf die img2img-Ergebnisse anwenden, damit sie den Originalfarben entsprechen.",
- "Save a copy of image before applying color correction to img2img results": "Vor dem Anwenden der Farbkorrektur eine Kopie des Bildes speichern",
- "With img2img, do exactly the amount of steps the slider specifies (normally you'd do less with less denoising).": "Mit img2img, die exakte Anzahl der Schritte ausführen, die vom Schieberegler angegeben sind (normalerweise weniger bei weniger Denoising).",
- "Enable quantization in K samplers for sharper and cleaner results. This may change existing seeds. Requires restart to apply.": "Aktivieren der Quantisierung in K-Samplern für schärfere und sauberere Ergebnisse. Dies kann bestehende Seeds verändern. Erfordert Neustart.",
- "Emphasis: use (text) to make model pay more attention to text and [text] to make it pay less attention": "Hervorhebung: Verwenden Sie (Text), damit das Modell dem Text mehr Aufmerksamkeit schenkt, und [Text], damit es ihm weniger Aufmerksamkeit schenkt",
- "Use old emphasis implementation. Can be useful to reproduce old seeds.": "Verwenden der alten Implementierung von Hervorhebungen. Kann nützlich sein, um alte Seeds zu reproduzieren.",
- "Make K-diffusion samplers produce same images in a batch as when making a single image": "K-Diffusions-Sampler erzeugen in einem Batch die gleichen Bilder, wie bei der Erstellung eines einzelnen Bildes",
- "Increase coherency by padding from the last comma within n tokens when using more than 75 tokens": "Erhöhung der Kohärenz durch Auffüllen ab dem letzten Komma innerhalb von n Token, wenn mehr als 75 Token verwendet werden",
- "Filter NSFW content": "NSFW-Inhalte filtern",
- "Stop At last layers of CLIP model": "Stoppe bei den letzten Schichten des CLIP-Modells",
- "Interrogate Options": "Interrogate Optionen",
- "Interrogate: keep models in VRAM": "Interrogate: Modelle im VRAM behalten",
- "Interrogate: use artists from artists.csv": "Interrogate: Künstler aus 'artists.csv' nutzen",
- "Interrogate: include ranks of model tags matches in results (Has no effect on caption-based interrogators).": "Interrogate: Die Rangfolge von Modell-Tags in den Ergebnissen einschließen (hat keine Auswirkung auf beschriftungsbasierte Interrogator).",
- "Interrogate: num_beams for BLIP": "Interrogate: num_beams für BLIP",
- "Interrogate: minimum description length (excluding artists, etc..)": "Interrogate: minimale Beschreibungslänge (Künstler, etc.. ausgenommen)",
- "Interrogate: maximum description length": "Interrogate: maximale Beschreibungslänge",
- "CLIP: maximum number of lines in text file (0 = No limit)": "CLIP: maximale Anzahl an Zeilen in Textdatei (0 = Kein Limit)",
- "Interrogate: deepbooru score threshold": "Interrogate: Deepbooru minimale Punkteanzahl",
- "Interrogate: deepbooru sort alphabetically": "Interrogate: Sortiere Deepbooru alphabetisch",
- "use spaces for tags in deepbooru": "Benutze Leerzeichen für Deepbooru-Tags",
- "escape (\\) brackets in deepbooru (so they are used as literal brackets and not for emphasis)": "Escape-Klammern (\\) in Deepbooru (damit sie als normale Klammern und nicht zur Hervorhebung verwendet werden)",
- "User interface": "Benutzeroberfläche",
- "Show progressbar": "Fortschrittsleiste anzeigen",
- "Show image creation progress every N sampling steps. Set 0 to disable.": "Zeige eine Bildvorschau alle N Samplingschritte. Zum Deaktivieren auf 0 setzen.",
- "Show previews of all images generated in a batch as a grid": "Zeige eine Vorschau aller erzeugten Bilder in einem Batch als Raster",
- "Show grid in results for web": "Zeige Raster in der Web-UI Vorschau",
- "Do not show any images in results for web": "Keine Bilder in der Web-UI Vorschau zeigen",
- "Add model hash to generation information": "Hash des Modells zu den Generationsinformationen hinzufügen",
- "Add model name to generation information": "Name des Modells zu den Generationsinformationen hinzufügen",
- "When reading generation parameters from text into UI (from PNG info or pasted text), do not change the selected model/checkpoint.": "Beim Einlesen von Generierungsparametern aus Text in die Benutzeroberfläche (aus PNG-Info oder eingefügtem Text) wird das ausgewählte Modell/Checkpoint nicht geändert.",
- "Send seed when sending prompt or image to other interface": "Den Seed, beim Senden des Bildes/Prompt zu einem anderen Tab, mitsenden",
- "Font for image grids that have text": "Schriftart für Bildraster mit Text",
- "Enable full page image viewer": "Ganzseitenbildbetrachter aktivieren",
- "Show images zoomed in by default in full page image viewer": "Standardmäßig Bilder im Ganzseitenbildbetrachter vergrößert anzeigen",
- "Show generation progress in window title.": "Generationsfortschritt im Fenstertitel anzeigen.",
- "Quicksettings list": "Schnellzugriffsleiste",
- "Localization (requires restart)": "Lokalisierung (Erfordert Neustart)",
- "Sampler parameters": "Samplerparameter",
- "Hide samplers in user interface (requires restart)": "Sampler in der Benutzeroberfläche verstecken (Erfordert Neustart)",
- "eta (noise multiplier) for DDIM": "Eta (noise Multiplikator) für DDIM",
- "eta (noise multiplier) for ancestral samplers": "Eta (noise Multiplikator) für Ancestral Sampler",
- "img2img DDIM discretize": "img2img DDIM diskretisieren",
- "uniform": "uniform",
- "quad": "quad",
- "sigma churn": "sigma churn",
- "sigma tmin": "sigma tmin",
- "sigma noise": "sigma noise",
- "Eta noise seed delta": "Eta noise seed delta",
- "Request browser notifications": "Browserbenachrichtigungen anfordern",
- "Download localization template": "Vorlage für Lokalisierung herunterladen",
- "Reload custom script bodies (No ui updates, No restart)": "Benutzerdefinierte Skripte neu laden (keine Aktualisierung der Benutzeroberfläche, kein Neustart)",
- "Restart Gradio and Refresh components (Custom Scripts, ui.py, js and css only)": "Gradio neu starten und Komponenten aktualisieren (nur Custom Scripts, ui.py, js und css)",
- "Prompt (press Ctrl+Enter or Alt+Enter to generate)": "Prompt (zum Erzeugen Strg+Eingabe oder Alt+Eingabe drücken)",
- "Negative prompt (press Ctrl+Enter or Alt+Enter to generate)": "Negative Prompt (zum Erzeugen Strg+Eingabe oder Alt+Eingabe drücken)",
- "Add a random artist to the prompt.": "Zufälligen Künstler der Prompt hinzufügen.",
- "Read generation parameters from prompt or last generation if prompt is empty into user interface.": "Lesen der Generationsparameter aus der Prompt oder der letzten Generation (wenn Prompt leer ist) in die Benutzeroberfläche.",
- "Save style": "Stil speichern",
- "Apply selected styles to current prompt": "Momentan ausgewählte Stile auf die Prompt anwenden",
- "Stop processing current image and continue processing.": "Verarbeitung des momentanen Bildes abbrechen und Verarbeitung fortsetzen.",
- "Stop processing images and return any results accumulated so far.": "Verarbeitung abbrechen und alle bisherigen Ergebnisse ausgeben.",
- "Style to apply; styles have components for both positive and negative prompts and apply to both": "Stil, der angwendet werden soll. Stile haben sowohl positive als auch negative Promptanteile und werden auf beide angewandt.",
- "Do not do anything special": "Nichts besonderes machen",
- "Which algorithm to use to produce the image": "Der zu benutzende Algorithmus für die Bildgeneration",
- "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps to higher than 30-40 does not help": "Euler Ancestral - sehr kreativ, kann sehr unterschiedliche Bilder in Abhängigkeit von der Schrittanzahl bekommen. Werte höher als 30-40 helfen nicht.",
- "Denoising Diffusion Implicit Models - best at inpainting": "Denoising Diffusion Implicit Modelle - am besten für inpainting",
- "Produce an image that can be tiled.": "Bild erzeugen, dass gekachelt werden kann.",
- "Use a two step process to partially create an image at smaller resolution, upscale, and then improve details in it without changing composition": "Verwendung eines zweistufigen Prozesses, um ein Bild mit geringerer Auflösung zu erstellen, hochzuskalieren und dann die Details zu verbessern, ohne die Komposition zu verändern.",
- "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.": "Bestimmt, wie wenig Bezug der Algorithmus zu dem Inhalt des Bildes haben soll. Bei 0 ändert sich nichts, und bei 1 besitzt das Bild keinen Bezug. Bei Werten unter 1,0 erfolgt die Verarbeitung in weniger Schritten, als der Schieberegler angibt.",
- "How many batches of images to create": "Wie viele Sätze von Bildern erstellt werden sollen",
- "How many image to create in a single batch": "Wie viele Bilder in einem Batch erstellt werden sollen",
- "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results": "Classifier Free Guidance Scale - wie stark das Bild der Prompt entsprechen soll - niedrigere Werte führen zu kreativeren Ergebnissen",
- "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result": "Ein Wert, der die Ausgabe des Zufallszahlengenerators bestimmt: Wenn ein Bild mit denselben Parametern und demselben Seed wie ein anderes Bild erstellt wird, erhält man dasselbe Ergebnis.",
- "Set seed to -1, which will cause a new random number to be used every time": "Seed auf -1 setzen, so dass jedes Mal eine neue Zufallszahl verwendet wird",
- "Reuse seed from last generation, mostly useful if it was randomed": "Wiederverwendung des Seeds der letzten Generation, meist nützlich, wenn er zufällig gewählt wurde",
- "Seed of a different picture to be mixed into the generation.": "Seed eines anderen Bildes, der bei der Erzeugung reingemischt wird.",
- "How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something).": "Wie stark die Veränderung sein soll. Bei 0 gibt es keinen Effekt. Bei 1 erhält man das vollständige Bild mit dem Variationsseed (außer bei Ancestral Samplern, wie Euler A, wo man nur etwas erhält).",
- "Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution": "Versuche ein Bild zu erzeugen, das dem ähnelt, das mit dem Seed bei der angegebenen Auflösung erzeugt worden wäre.",
- "Separate values for X axis using commas.": "Trenne die Werte für die X-Achse durch Kommas.",
- "Separate values for Y axis using commas.": "Trenne die Werte für die Y-Achse durch Kommas.",
- "Write image to a directory (default - log/images) and generation parameters into csv file.": "Bild in ein Verzeichnis (Standard - log/images) und Generationsparameter in eine csv-Datei schreiben.",
- "Open images output directory": "Ausgabeverzeichnis öffnen",
- "How much to blur the mask before processing, in pixels.": "Wie stark die Maske vor der Verarbeitung weichgezeichnet werden soll, in Pixeln.",
- "What to put inside the masked area before processing it with Stable Diffusion.": "Was in den maskierten Bereich vor der Verarbeitung mit Stable Diffusion soll.",
- "fill it with colors of the image": "Füllen mit den Farben des Bildes",
- "keep whatever was there originally": "Originalen Inhalt behalten",
- "fill it with latent space noise": "Füllen mit latent space noise",
- "fill it with latent space zeroes": "Füllen mit latent space Nullen",
- "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image": "Hochskalieren des maskierten Bereichs auf die Zielauflösung, Inpainting, Zurückskalieren und Einfügen in das Originalbild.",
- "Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.": "Die Größe des Bildes auf die gewünschte Auflösung ändern. Wenn Höhe und Breite nicht übereinstimmen, erhält man ein falsches Seitenverhältnis.",
- "Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out.": "Die Größe des Bildes so ändern, dass die gesamte Zielauflösung mit dem Bild ausgefüllt wird. Herausragende Teile werden abgeschnitten.",
- "Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors.": "Die Größe des Bildes so ändern, dass das gesamte Bild enthalten ist. Lücken werden mit Farben des Bildes ausgefüllt.",
- "How many times to repeat processing an image and using it as input for the next iteration": "Wie oft die Verarbeitung eines Bildes wiederholt und als Eingabe für die nächste Iteration verwendet werden soll",
- "In loopback mode, on each loop the denoising strength is multiplied by this value. <1 means decreasing variety so your sequence will converge on a fixed picture. >1 means increasing variety so your sequence will become more and more chaotic.": "Im Loopback-Modus wird die Denoisingstärke in jeder Schleife mit diesem Wert multipliziert. <1 bedeutet abnehmende Vielfalt, so dass die Sequenz zu einem festen Bild konvergiert. >1 bedeutet zunehmende Vielfalt, so dass die Sequenz immer chaotischer wird.",
- "For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam.": "Wie viel Pixel sich beim SD-Upscale zwischen den Kacheln überlappen. Die Kacheln überlappen sich so, dass beim Zusammenfügen zu einem Bild keine deutlich sichtbare Naht entsteht.",
- "A directory on the same machine where the server is running.": "Ein Verzeichnis auf demselben Rechner, auf dem der Server läuft.",
- "Leave blank to save images to the default path.": "Leer lassen, um Bilder im Standardpfad zu speichern.",
- "Result = A * (1 - M) + B * M": "Ergebnis = A * (1 - M) + B * M",
- "Result = A + (B - C) * M": "Ergebnis = A + (B - C) * M",
- "1st and last digit must be 1. ex:'1, 2, 1'": "Erste und letzte Ziffer müssen 1 sein. Bspl:'1, 2, 1'",
- "Path to directory with input images": "Pfad zum Verzeichnis mit den Eingabebildern",
- "Path to directory where to write outputs": "Pfad zum Verzeichnis, wo die Ausgaben gespeichert werden",
- "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.": "Verwende die folgenden Tags, um festzulegen, wie die Dateinamen für Bilder ausgewählt werden: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leer lassen, um Standardwerte zu verwenden.",
- "If this option is enabled, watermark will not be added to created images. Warning: if you do not add watermark, you may be behaving in an unethical manner.": "Wenn diese Option aktiviert ist, wird den erstellten Bildern kein Wasserzeichen hinzugefügt. Achtung: Wenn Sie kein Wasserzeichen hinzufügen, verhalten Sie sich möglicherweise unethisch.",
- "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.": "Verwenden Sie die folgenden Tags, um festzulegen, wie Unterverzeichnisse für Bilder und Raster ausgewählt werden: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leer lassen, um Standardwerte zu verwenden.",
- "Restore low quality faces using GFPGAN neural network": "Wiederherstellung von Gesichtern schlechter Qualität mit dem neuralen Netzwerk GFPGAN",
- "This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is.": "Dieser reguläre Ausdruck wird verwendet, um Wörter aus dem Dateinamen zu extrahieren, die dann mit der unten stehenden Option zu einem Beschriftungstext für das Training zusammengefügt werden. Leer lassen, um den Text des Dateinamens so zu belassen, wie er ist.",
- "This string will be used to join split words into a single line if the option above is enabled.": "Diese Zeichenfolge wird verwendet, um getrennte Wörter in einer einzigen Zeile zu verbinden, wenn die obige Option aktiviert ist.",
- "Only applies to inpainting models. Determines how strongly to mask off the original image for inpainting and img2img. 1.0 means fully masked, which is the default behaviour. 0.0 means a fully unmasked conditioning. Lower values will help preserve the overall composition of the image, but will struggle with large changes.": "Gilt nur für Inpainting-Modelle. Legt fest, wie stark das Originalbild für Inpainting und img2img maskiert werden soll. 1.0 bedeutet vollständig maskiert, was das Standardverhalten ist. 0.0 bedeutet eine vollständig unmaskierte Konditionierung. Niedrigere Werte tragen dazu bei, die Gesamtkomposition des Bildes zu erhalten, sind aber bei großen Änderungen problematisch.",
- "List of setting names, separated by commas, for settings that should go to the quick access bar at the top, rather than the usual setting tab. See modules/shared.py for setting names. Requires restarting to apply.": "Liste von Einstellungsnamen, getrennt durch Kommas, für Einstellungen, die in der Schnellzugriffsleiste oben erscheinen sollen, anstatt in dem üblichen Einstellungs-Tab. Siehe modules/shared.py für Einstellungsnamen. Erfordert einen Neustart zur Anwendung.",
- "If this values is non-zero, it will be added to seed and used to initialize RNG for noises when using samplers with Eta. You can use this to produce even more variation of images, or you can use this to match images of other software if you know what you are doing.": "Wenn dieser Wert ungleich Null ist, wird er zum Seed addiert und zur Initialisierung des RNG für Noise bei der Verwendung von Samplern mit Eta verwendet. Dies kann verwendet werden, um noch mehr Variationen von Bildern zu erzeugen, oder um Bilder von anderer Software zu erzeugen, wenn Sie wissen, was Sie tun."
-} \ No newline at end of file
diff --git a/localizations/es_ES.json b/localizations/es_ES.json
deleted file mode 100644
index d9ca4ef7..00000000
--- a/localizations/es_ES.json
+++ /dev/null
@@ -1,418 +0,0 @@
-{
- "⤡": "⤡",
- "⊞": "⊞",
- "×": "×",
- "❮": "❮",
- "❯": "❯",
- "Loading...": "Cargando...",
- "view": "mostrar",
- "api": "api",
- "•": "•",
- "built with gradio": "Construido con Gradio",
- "Stable Diffusion checkpoint": "Stable Diffusion checkpoint",
- "txt2img": "txt2img",
- "img2img": "img2img",
- "Extras": "Extras",
- "PNG Info": "PNG Info",
- "Checkpoint Merger": "Checkpoint Merger",
- "Train": "Train",
- "Settings": "Ajustes",
- "Prompt": "Prompt",
- "Negative prompt": "Prompt negativo",
- "Run": "Ejecutar",
- "Skip": "Saltar",
- "Interrupt": "Interrumpir",
- "Generate": "Generar",
- "Style 1": "Estilo 1",
- "Style 2": "Estilo 2",
- "Label": "Etiqueta",
- "File": "Archivo",
- "Drop File Here": "Suelta el Archivo Aquí",
- "-": "-",
- "o": "o",
- "Click to Upload": "Click para Cargar",
- "Image": "Imagen",
- "Check progress": "Comprobar progreso",
- "Check progress (first)": "Comprobar progreso (inicial)",
- "Sampling Steps": "Sampling Steps",
- "Sampling method": "Sampling method",
- "Euler a": "Euler a",
- "Euler": "Euler",
- "LMS": "LMS",
- "Heun": "Heun",
- "DPM2": "DPM2",
- "DPM2 a": "DPM2 a",
- "DPM fast": "DPM fast",
- "DPM adaptive": "DPM adaptive",
- "LMS Karras": "LMS Karras",
- "DPM2 Karras": "DPM2 Karras",
- "DPM2 a Karras": "DPM2 a Karras",
- "DDIM": "DDIM",
- "PLMS": "PLMS",
- "Width": "Ancho",
- "Height": "Alto",
- "Restore faces": "Restaurar rostros",
- "Tiling": "Mosaico",
- "Highres. fix": "Highres. fix",
- "Firstpass width": "Ancho original",
- "Firstpass height": "Alto original",
- "Denoising strength": "Denoising strength",
- "Batch count": "Batch count",
- "Batch size": "Batch size",
- "CFG Scale": "CFG Scale",
- "Seed": "Seed",
- "Extra": "Extra",
- "Variation seed": "Variation seed",
- "Variation strength": "Variation strength",
- "Resize seed from width": "Redimensionar seed del ancho",
- "Resize seed from height": "Redimensionar seed del alto",
- "Script": "Script",
- "None": "Ninguno",
- "Prompt matrix": "Prompt matrix",
- "Prompts from file or textbox": "Prompts desde archivo o campo de texto",
- "X/Y plot": "X/Y plot",
- "Put variable parts at start of prompt": "Poner partes variables al inicio del prompt",
- "Show Textbox": "Mostrar Campo de texto",
- "File with inputs": "Archivo con inputs",
- "Prompts": "Prompts",
- "X type": "X type",
- "Nothing": "Nada",
- "Var. seed": "Var. seed",
- "Var. strength": "Var. strength",
- "Steps": "Steps",
- "Prompt S/R": "Prompt S/R",
- "Prompt order": "Prompt order",
- "Sampler": "Sampler",
- "Checkpoint name": "Checkpoint name",
- "Hypernetwork": "Hypernetwork",
- "Hypernet str.": "Hypernet str.",
- "Sigma Churn": "Sigma Churn",
- "Sigma min": "Sigma min",
- "Sigma max": "Sigma max",
- "Sigma noise": "Sigma noise",
- "Eta": "Eta",
- "Clip skip": "Clip skip",
- "Denoising": "Denoising",
- "X values": "X values",
- "Y type": "Y type",
- "Y values": "Y values",
- "Draw legend": "Agregar leyenda",
- "Include Separate Images": "Incluir Imágenes Separadas",
- "Keep -1 for seeds": "Mantener -1 para seeds",
- "Drop Image Here": "Suelta la Imagen Aquí",
- "Save": "Guardar",
- "Send to img2img": "Enviar a img2img",
- "Send to inpaint": "Enviar a inpaint",
- "Send to extras": "Enviar a extras",
- "Make Zip when Save?": "Crear Zip al Guardar?",
- "Textbox": "Campo de texto",
- "Interrogate\nCLIP": "Interrogar\nCLIP",
- "Inpaint": "Inpaint",
- "Batch img2img": "Batch img2img",
- "Image for img2img": "Imagen para img2img",
- "Image for inpainting with mask": "Imagen para inpainting con mask",
- "Mask": "Mask",
- "Mask blur": "Mask blur",
- "Mask mode": "Mask mode",
- "Draw mask": "Dibujar mask",
- "Upload mask": "Cargar mask",
- "Masking mode": "Masking mode",
- "Inpaint masked": "Inpaint masked",
- "Inpaint not masked": "Inpaint not masked",
- "Masked content": "Masked content",
- "fill": "fill",
- "original": "original",
- "latent noise": "latent noise",
- "latent nothing": "latent nothing",
- "Inpaint at full resolution": "Inpaint a resolución completa",
- "Inpaint at full resolution padding, pixels": "Inpaint a resolución completa padding, pixeles",
- "Process images in a directory on the same machine where the server is running.": "Procesa imágenes en un directorio en la misma máquina donde se ejecuta el servidor.",
- "Use an empty output directory to save pictures normally instead of writing to the output directory.": "Usa un directorio de salida vacío para guardar imágenes normalmente en lugar de escribir en el directorio de salida.",
- "Input directory": "Directorio de entrada",
- "Output directory": "Directorio de salida",
- "Resize mode": "Modo de cambio de tamaño",
- "Just resize": "Solo redimensionar",
- "Crop and resize": "Recortar y redimensionar",
- "Resize and fill": "Redimensionar y rellenar",
- "img2img alternative test": "img2img alternative test",
- "Loopback": "Loopback",
- "Outpainting mk2": "Outpainting mk2",
- "Poor man's outpainting": "Poor man's outpainting",
- "SD upscale": "SD upscale",
- "should be 2 or lower.": "debe ser 2 o menos.",
- "Override `Sampling method` to Euler?(this method is built for it)": "Anular `Sampling method` a Euler? (este método está diseñado para ello)",
- "Override `prompt` to the same value as `original prompt`?(and `negative prompt`)": "Anular `prompt` al mismo valor `prompt original`? (y `prompt negativo`)",
- "Original prompt": "Prompt original",
- "Original negative prompt": "Promp negativo original",
- "Override `Sampling Steps` to the same value as `Decode steps`?": "Anular `Sampling Steps` al mismo valor de `Decode steps`?",
- "Decode steps": "Decode steps",
- "Override `Denoising strength` to 1?": "Anular `Denoising strength` a 1?",
- "Decode CFG scale": "Decode CFG scale",
- "Randomness": "Aleatoriedad",
- "Sigma adjustment for finding noise for image": "Ajuste Sigma para encontrar ruido para la imagen.",
- "Loops": "Loops",
- "Denoising strength change factor": "Denoising strength change factor",
- "Recommended settings: Sampling Steps: 80-100, Sampler: Euler a, Denoising strength: 0.8": "Ajustes recomendados: Sampling Steps: 80-100, Sampler: Euler a, Denoising strength: 0.8",
- "Pixels to expand": "Píxeles para expandir",
- "Outpainting direction": "Dirección Outpainting",
- "left": "izquierda",
- "right": "derecha",
- "up": "arriba",
- "down": "abajo",
- "Fall-off exponent (lower=higher detail)": "Fall-off exponent (inferior=mayor detalle)",
- "Color variation": "Variación de color",
- "Will upscale the image to twice the dimensions; use width and height sliders to set tile size": "Mejorará la imagen al doble de las dimensiones; usa los controles deslizantes de ancho y alto para establecer el tamaño del mosaico",
- "Tile overlap": "Solapar mosaicos",
- "Upscaler": "Upscaler",
- "Lanczos": "Lanczos",
- "LDSR": "LDSR",
- "SwinIR 4x": "SwinIR 4x",
- "ScuNET GAN": "ScuNET GAN",
- "ScuNET PSNR": "ScuNET PSNR",
- "ESRGAN_4x": "ESRGAN_4x",
- "Single Image": "Imagen Única",
- "Batch Process": "Batch Process",
- "Batch from Directory": "Batch desde Directorio",
- "Source": "Origen",
- "Show result images": "Mostrar resultados de imágenes",
- "Scale by": "Escalar por",
- "Scale to": "Escalar a",
- "Resize": "Redimensionar",
- "Crop to fit": "Recortar para ajustar",
- "Upscaler 2 visibility": "Upscaler 2 visibilidad",
- "GFPGAN visibility": "GFPGAN visibilidad",
- "CodeFormer visibility": "CodeFormer visibilidad",
- "CodeFormer weight (0 = maximum effect, 1 = minimum effect)": "CodeFormer peso (0 = efecto máximo, 1 = efecto mínimo)",
- "Open output directory": "Abrir directorio de salida",
- "Send to txt2img": "Enviar a txt2img",
- "A merger of the two checkpoints will be generated in your": "Se generará una fusión de los dos checkpoints en su",
- "checkpoint": "checkpoint",
- "directory.": "directorio.",
- "Primary model (A)": "Modelo primario (A)",
- "Secondary model (B)": "Modelo secundario (B)",
- "Tertiary model (C)": "Modelo terciario (C)",
- "Custom Name (Optional)": "Nombre personalizado (Opcional)",
- "Multiplier (M) - set to 0 to get model A": "Multiplier (M) - establecer en 0 para obtener el modelo A",
- "Interpolation Method": "Método de interpolación",
- "Weighted sum": "Weighted sum",
- "Add difference": "Add difference",
- "Save as float16": "Guardar como float16",
- "See": "Ver ",
- "wiki": "wiki ",
- "for detailed explanation.": "para una explicación detallada.",
- "Create embedding": "Crear embedding",
- "Create hypernetwork": "Crear hypernetwork",
- "Preprocess images": "Preprocesar imágenes",
- "Name": "Nombre",
- "Initialization text": "Texto de inicialización",
- "Number of vectors per token": "Número de vectores por token",
- "Overwrite Old Embedding": "Sobrescribir Embedding Anterior",
- "Modules": "Módulos",
- "Enter hypernetwork layer structure": "Ingresa la estructura de capa del hypernetwork",
- "Select activation function of hypernetwork": "Selecciona la función de activación del hypernetwork",
- "linear": "linear",
- "relu": "relu",
- "leakyrelu": "leakyrelu",
- "elu": "elu",
- "swish": "swish",
- "Add layer normalization": "Agregar normalización de capa",
- "Use dropout": "Usar dropout",
- "Overwrite Old Hypernetwork": "Sobrescribir Hypernetwork Anterior",
- "Source directory": "Directorio de origen",
- "Destination directory": "Directorio de salida",
- "Existing Caption txt Action": "Existing Caption txt Action",
- "ignore": "ignorar",
- "copy": "copiar",
- "prepend": "anteponer",
- "append": "añadir",
- "Create flipped copies": "Crear copias volteadas",
- "Split oversized images": "Dividir imágenes grandes",
- "Use BLIP for caption": "Usar BLIP para subtítulo",
- "Use deepbooru for caption": "Usar deepbooru para subtítulo",
- "Split image threshold": "Threshold imagen dividida",
- "Split image overlap ratio": "Overlap ratio imagen dividida",
- "Preprocess": "Preproceso",
- "Train an embedding or Hypernetwork; you must specify a directory with a set of 1:1 ratio images": "Entrenar un embedding o Hypernetwork; debes especificar un directorio con un conjunto de imágenes con una proporción de 1:1 ",
- "[wiki]": "[wiki]",
- "Embedding": "Embedding",
- "Embedding Learning rate": "Embedding Learning rate",
- "Hypernetwork Learning rate": "Hypernetwork Learning rate",
- "Dataset directory": "Directorio dataset",
- "Log directory": "Directorio log",
- "Prompt template file": "Prompt archivos plantilla",
- "Max steps": "Max steps",
- "Save an image to log directory every N steps, 0 to disable": "Guarda una imagen en el directorio log cada N pasos, 0 para deshabilitar",
- "Save a copy of embedding to log directory every N steps, 0 to disable": "Guarda una copia de embedding en el directorio log cada N pasos, 0 para deshabilitar",
- "Save images with embedding in PNG chunks": "Guarda imágenes con embedding en fragmentos PNG",
- "Read parameters (prompt, etc...) from txt2img tab when making previews": "Leer parámetros (prompt, etc...) desde la pestaña txt2img al hacer vistas previas",
- "Train Hypernetwork": "Train Hypernetwork",
- "Train Embedding": "Train Embedding",
- "Apply settings": "Aplicar ajustes",
- "Saving images/grids": "Guardar imágenes/grids",
- "Always save all generated images": "Siempre guardar imágenes generadas",
- "File format for images": "Formato de archivo para imágenes",
- "Images filename pattern": "Patrón nombre archivo imágenes",
- "Add number to filename when saving": "Agregar número al nombre de archivo al guardar",
- "Always save all generated image grids": "Siempre guardar grids de imágenes generadas",
- "File format for grids": "Formato de archivo para grids",
- "Add extended info (seed, prompt) to filename when saving grid": "Agregar información extendida (seed, prompt) al nombre del archivo al guardar grid",
- "Do not save grids consisting of one picture": "No guardar grids que consisten en una imagen",
- "Prevent empty spots in grid (when set to autodetect)": "Evitar espacios vacíos en grids (cuando se establece detección automática)",
- "Grid row count; use -1 for autodetect and 0 for it to be same as batch size": "Recuento de filas de grids; usar -1 para la detección automática y 0 para que sea igual al batch size",
- "Save text information about generation parameters as chunks to png files": "Guardar información de texto sobre parámetros de generación como fragmentos en archivos png",
- "Create a text file next to every image with generation parameters.": "Crear un archivo de texto junto a cada imagen con parámetros de generación.",
- "Save a copy of image before doing face restoration.": "Guardar una copia de la imagen antes de restaurar rostro.",
- "Quality for saved jpeg images": "Calidad para imágenes jpeg guardadas",
- "If PNG image is larger than 4MB or any dimension is larger than 4000, downscale and save copy as JPG": "Si la imagen PNG es más grande de 4 MB o cualquier dimensión es más grande que 4000, reduce la escala y guarda la copia como JPG",
- "Use original name for output filename during batch process in extras tab": "Use el nombre original para el nombre del archivo de salida durante el batch process en la pestaña extras",
- "When using 'Save' button, only save a single selected image": "Al usar el botón 'Guardar', solo guarda una sola imagen seleccionada",
- "Do not add watermark to images": "No agregar watermark a las imágenes",
- "Paths for saving": "Directorios para guardar",
- "Output directory for images; if empty, defaults to three directories below": "Directorio de imágenes; si está vacío, se utilizan los siguientes 3 directorios",
- "Output directory for txt2img images": "Directorio para guardar imágenes de txt2img",
- "Output directory for img2img images": "Directorio para guardar imágenes de img2img",
- "Output directory for images from extras tab": "Directorio para guardar imágenes de extras",
- "Output directory for grids; if empty, defaults to two directories below": "Directorio de grids; si está vacío, se utilizan los siguientes 2 directorios",
- "Output directory for txt2img grids": "Directorio para guardar txt2img grids",
- "Output directory for img2img grids": "Directorio para guardar img2img grids",
- "Directory for saving images using the Save button": "Directorio para guardar imágenes usando el botón Guardar",
- "Saving to a directory": "Guardando a un directorio",
- "Save images to a subdirectory": "Guardar imágenes a un subdirectorio",
- "Save grids to a subdirectory": "Guardar grids a un subdirectorio",
- "When using \"Save\" button, save images to a subdirectory": "Al usar el botón \"Guardar\", guarda las imágenes en un subdirectorio",
- "Directory name pattern": "Patrón nombre directorio",
- "Max prompt words for [prompt_words] pattern": "Máximo de palabras en prompt [prompt_words] para patrón",
- "Upscaling": "Upscaling",
- "Tile size for ESRGAN upscalers. 0 = no tiling.": "Tamaño mosaico para ESRGAN upscalers. 0 = sin mosaico.",
- "Tile overlap, in pixels for ESRGAN upscalers. Low values = visible seam.": "Solapar mosaico, en pixeles para ESRGAN upscalers. Valores bajos = unión visible.",
- "Tile size for all SwinIR.": "Tamaño mosaico para SwinIR.",
- "Tile overlap, in pixels for SwinIR. Low values = visible seam.": "Solapar mosaico, en pixeles para SwinIR. Valores bajos = unión visible.",
- "LDSR processing steps. Lower = faster": "LDSR processing steps. Más bajo = rápido",
- "Upscaler for img2img": "Upscaler para img2img",
- "Upscale latent space image when doing hires. fix": "Upscale latent space al aplicar hires. fix",
- "Face restoration": "Restauración de rostro",
- "CodeFormer weight parameter; 0 = maximum effect; 1 = minimum effect": "CodeFormer parámetro peso; 0 = máximo efecto; 1 = mínimo efecto",
- "Move face restoration model from VRAM into RAM after processing": "Mover modelo de restauración de rostro del VRAM al RAM después de procesar",
- "System": "Sistema",
- "VRAM usage polls per second during generation. Set to 0 to disable.": "Sondeos de uso de VRAM por segundo durante la generación. Establecer en 0 para deshabilitar.",
- "Always print all generation info to standard output": "Imprime siempre toda la información de generación en la salida estándar",
- "Add a second progress bar to the console that shows progress for an entire job.": "Agrega una segunda barra de progreso a la consola que muestra el progreso de un trabajo completo.",
- "Training": "Entrenamiento",
- "Move VAE and CLIP to RAM when training hypernetwork. Saves VRAM.": "Mover VAE y CLIP al RAM al entrenar un hypernetwork. Ahorra VRAM.",
- "Filename word regex": "Filename word regex",
- "Filename join string": "Filename join string",
- "Number of repeats for a single input image per epoch; used only for displaying epoch number": "Número de repeticiones para una sola imagen de entrada por epoch; utilizado solo para mostrar el número epoch",
- "Save an csv containing the loss to log directory every N steps, 0 to disable": "Guarda un csv que contenga la pérdida en el directorio log cada N pasos, 0 para deshabilitar",
- "Stable Diffusion": "Stable Diffusion",
- "Checkpoints to cache in RAM": "Checkpoints al cache en RAM",
- "Hypernetwork strength": "Hypernetwork strength",
- "Apply color correction to img2img results to match original colors.": "Aplica la corrección de color a los resultados de img2img para que coincidan con los colores originales.",
- "Save a copy of image before applying color correction to img2img results": "Guarda una copia de la imagen antes de aplicar la corrección de color a los resultados de img2img",
- "With img2img, do exactly the amount of steps the slider specifies (normally you'd do less with less denoising).": "Con img2img, hace exactamente la cantidad de pasos que especifica el slider (normalmente haría menos con menos eliminación de ruido).",
- "Enable quantization in K samplers for sharper and cleaner results. This may change existing seeds. Requires restart to apply.": "Habilita la cuantificación en K samplers para obtener resultados más nítidos y limpios. Esto puede cambiar los seeds existentes. Requiere reiniciar para aplicar.",
- "Emphasis: use (text) to make model pay more attention to text and [text] to make it pay less attention": "Énfasis: utiliza (texto) para que el modelo preste más atención al texto y [texto] para que preste menos atención",
- "Use old emphasis implementation. Can be useful to reproduce old seeds.": "Utiliza la implementación de énfasis antiguo. Puede ser útil para reproducir seeds anteriores.",
- "Make K-diffusion samplers produce same images in a batch as when making a single image": "Hace que los K-diffusion samplers produzcan las mismas imágenes en un lote que cuando se crea una sola imagen",
- "Increase coherency by padding from the last comma within n tokens when using more than 75 tokens": "Aumenta la coherencia rellenando desde la última coma dentro de n tokens cuando se use más de 75 tokens",
- "Filter NSFW content": "Filtrar contenido NSFW",
- "Stop At last layers of CLIP model": "Detener en las últimas capas del modelo CLIP",
- "Interrogate Options": "Opciones de Interrogar",
- "Interrogate: keep models in VRAM": "Interrogar: mantener modelos en VRAM",
- "Interrogate: use artists from artists.csv": "Interrogar: utilizar artistas de artists.csv",
- "Interrogate: include ranks of model tags matches in results (Has no effect on caption-based interrogators).": "Interrogar: incluir rangos de coincidencias de etiquetas de modelos en los resultados (No tiene efecto en los interrogadores basados en subtítulos).",
- "Interrogate: num_beams for BLIP": "Interrogar: num_beams para BLIP",
- "Interrogate: minimum description length (excluding artists, etc..)": "Interrogar: longitud mínima de la descripción (excluyendo artistas, etc.)",
- "Interrogate: maximum description length": "Interrogar: longitud máxima de la descripción",
- "CLIP: maximum number of lines in text file (0 = No limit)": "CLIP: número máximo de líneas en el archivo de texto (0 = Sin límite)",
- "Interrogate: deepbooru score threshold": "Interrogar: deepbooru score threshold",
- "Interrogate: deepbooru sort alphabetically": "Interrogar: deepbooru ordenar alfabéticamente",
- "use spaces for tags in deepbooru": "usar espacios para etiquetas en deepbooru",
- "escape (\\) brackets in deepbooru (so they are used as literal brackets and not for emphasis)": "corchetes de escape (\\) en deepbooru (por lo que se usan como corchetes literales y no para enfatizar)",
- "User interface": "Interfaz de usuario",
- "Show progressbar": "Mostrar barra de progreso",
- "Show image creation progress every N sampling steps. Set 0 to disable.": "Muestra el progreso de creación de la imagen cada N sampling steps. Establecer 0 para deshabilitar.",
- "Show previews of all images generated in a batch as a grid": "Mostrar vistas previas de todas las imágenes generadas en un batch como un grid",
- "Show grid in results for web": "Mostrar grids en resultados para web",
- "Do not show any images in results for web": "No mostrar ninguna imagen en los resultados para web",
- "Add model hash to generation information": "Agregar hash de modelo a la información de generación",
- "Add model name to generation information": "Agregar nombre de modelo a la información de generación",
- "When reading generation parameters from text into UI (from PNG info or pasted text), do not change the selected model/checkpoint.": "Al leer los parámetros de generación del texto en la interfaz de usuario (desde PNG Info o texto pegado), no cambia el modelo/checkpoint seleccionado.",
- "Font for image grids that have text": "Tipografía para grids de imágenes que tienen texto",
- "Enable full page image viewer": "Habilitar visor de imágenes de página completa",
- "Show images zoomed in by default in full page image viewer": "Mostrar imágenes ampliadas de forma predeterminada en el visor de imágenes de página completa",
- "Show generation progress in window title.": "Muestra el progreso de la generación en el título de la ventana del navegador.",
- "Quicksettings list": "Lista de ajustes rápidos",
- "Localization (requires restart)": "Traducción (requiere reiniciar)",
- "Sampler parameters": "Parámetros sampler",
- "Hide samplers in user interface (requires restart)": "Ocultar samplers en interfaz de usuario (requiere reiniciar)",
- "eta (noise multiplier) for DDIM": "eta (noise multiplier) para DDIM",
- "eta (noise multiplier) for ancestral samplers": "eta (noise multiplier) para ancestral samplers",
- "img2img DDIM discretize": "img2img DDIM discretize",
- "uniform": "uniform",
- "quad": "quad",
- "sigma churn": "sigma churn",
- "sigma tmin": "sigma tmin",
- "sigma noise": "sigma noise",
- "Eta noise seed delta": "Eta noise seed delta",
- "Request browser notifications": "Solicitar notificaciones del navegador",
- "Download localization template": "Descargar plantilla de traducción",
- "Reload custom script bodies (No ui updates, No restart)": "Recargar custom script bodies (Sin actualizar UI, Sin reiniciar)",
- "Restart Gradio and Refresh components (Custom Scripts, ui.py, js and css only)": "Reiniciar Gradio y Refrescar componentes (Custom Scripts, ui.py, js y css)",
- "Prompt (press Ctrl+Enter or Alt+Enter to generate)": "Prompt (presiona Ctrl+Enter o Alt+Enter para generar)",
- "Negative prompt (press Ctrl+Enter or Alt+Enter to generate)": "Prompt negativo (presiona Ctrl+Enter o Alt+Enter para generar)",
- "Add a random artist to the prompt.": "Agregar un artista aleatorio al prompt.",
- "Read generation parameters from prompt or last generation if prompt is empty into user interface.": "Leer los parámetros de generación del prompt o de la última generación si el prompt está vacío en la interfaz de usuario.",
- "Save style": "Guardar estilo",
- "Apply selected styles to current prompt": "Aplicar estilos seleccionados al prompt",
- "Stop processing current image and continue processing.": "Dejar de procesar la imagen actual y continuar procesando.",
- "Stop processing images and return any results accumulated so far.": "Dejar de procesar imágenes y devuelva los resultados acumulados hasta el momento.",
- "Style to apply; styles have components for both positive and negative prompts and apply to both": "Estilo a aplicar; los estilos tienen componentes tanto para prompts positivos como negativos y se aplican a ambos",
- "Do not do anything special": "No hacer nada especial",
- "Which algorithm to use to produce the image": "Qué algoritmo usar para producir la imagen",
- "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps to higher than 30-40 does not help": "Euler Ancestral - muy creativo, cada uno puede obtener una imagen completamente diferente dependiendo del conteo de steps, configurar los steps a más de 30-40 no ayuda",
- "Denoising Diffusion Implicit Models - best at inpainting": "Denoising Diffusion Implicit Models - funcionan mejor para inpainting",
- "Produce an image that can be tiled.": "Produce una imagen que puede usarse como mosaico.",
- "Use a two step process to partially create an image at smaller resolution, upscale, and then improve details in it without changing composition": "Usa un proceso de dos pasos para crear parcialmente una imagen con una resolución más pequeña, mejora la escala y luego mejora los detalles sin cambiar la composición",
- "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.": "Determina qué tan poco respeto debe tener el algoritmo por el contenido de la imagen. En 0, nada cambiará y en 1 obtendrá una imagen no relacionada. Con valores por debajo de 1.0, el procesamiento tomará menos steps de los que especifica el slider de Sampling Steps.",
- "How many batches of images to create": "Cuantos batches de imágenes para crear",
- "How many image to create in a single batch": "Cuantas imágenes para crear en un solo batch",
- "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results": "Classifier Free Guidance Scale - con qué fuerza debe ajustarse la imagen al prompt: los valores más bajos producen resultados más creativos",
- "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result": "Un valor que determina la salida del generador de números aleatorios: si creas una imagen con los mismos parámetros y el seed que otra imagen, obtendrás el mismo resultado",
- "Set seed to -1, which will cause a new random number to be used every time": "Establece el seed a -1, lo que hará que se use un nuevo número aleatorio cada vez",
- "Reuse seed from last generation, mostly useful if it was randomed": "Reutilice el seed de la última generación, muy útil si fue aleatoria",
- "Seed of a different picture to be mixed into the generation.": "Seed de una imagen diferente para ser mezclada en la generación.",
- "How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something).": "Qué fuerte de una variación para producir. En 0, no habrá ningún efecto. En 1, obtendrá la imagen completa con variation seed (excepto para ancestral samplers, donde solo obtendrás algo).",
- "Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution": "Intenta producir una imagen similar a la que se habría producido con el mismo seed a la resolución especificada",
- "Separate values for X axis using commas.": "Separar valores para X usando comas.",
- "Separate values for Y axis using commas.": "Separar valores para Y usando comas.",
- "Write image to a directory (default - log/images) and generation parameters into csv file.": "Escribe la imagen en un directorio (predeterminado: log/images) y los parámetros de generación en el archivo csv.",
- "Open images output directory": "Abrir directorio de imágenes",
- "How much to blur the mask before processing, in pixels.": "Cuánto blur al mask antes de procesar, en píxeles.",
- "What to put inside the masked area before processing it with Stable Diffusion.": "Qué poner dentro del área con mask antes de procesarlo con Stable Diffusion.",
- "fill it with colors of the image": "rellenarlo con los colores de la imagen",
- "keep whatever was there originally": "mantener lo que estaba allí originalmente",
- "fill it with latent space noise": "rellenarlo con latent space noise",
- "fill it with latent space zeroes": "rellenarlo con latent space zeroes",
- "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image": "Upscale la región con mask a la resolución objetivo, vuelve a pintar, reduce la escala hacia atrás y pégala en la imagen original",
- "Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.": "Cambia el tamaño de la imagen a la resolución destino. A menos que la altura y el ancho coincidan, obtendrás una relación de aspecto incorrecta.",
- "Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out.": "Cambia el tamaño de la imagen para que la totalidad de la resolución destino se llene con la imagen. Recorta las partes que sobresalen.",
- "Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors.": "Cambia el tamaño de la imagen para que la totalidad de la imagen esté dentro de la resolución de destino. Rellena el espacio vacío con los colores de la imagen.",
- "How many times to repeat processing an image and using it as input for the next iteration": "Cuántas veces repetir el procesamiento de una imagen y usarla como entrada para la próxima iteración",
- "In loopback mode, on each loop the denoising strength is multiplied by this value. <1 means decreasing variety so your sequence will converge on a fixed picture. >1 means increasing variety so your sequence will become more and more chaotic.": "En modo loopback, en cada bucle, la fuerza de eliminación de ruido se multiplica por este valor. <1 significa variedad decreciente, por lo que su secuencia convergerá en una imagen fija. >1 significa aumentar la variedad, por lo que su secuencia se volverá cada vez más caótica.",
- "For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam.": "Para SD upscale, cuánta superposición en píxeles debe haber entre mosaicos. Los mosaicos se superponen de modo que cuando se fusionan nuevamente en una imagen, no hay una unión claramente visible.",
- "A directory on the same machine where the server is running.": "Un directorio en la misma máquina donde se ejecuta el servidor.",
- "Leave blank to save images to the default path.": "Déjalo en blanco para guardar las imágenes en la ruta predeterminada.",
- "Result = A * (1 - M) + B * M": "Resultado = A * (1 - M) + B * M",
- "Result = A + (B - C) * M": "Resultado = A + (B - C) * M",
- "1st and last digit must be 1. ex:'1, 2, 1'": "Primer y último dígito debe ser 1. ej:'1, 2, 1'",
- "Path to directory with input images": "Ruta al directorio con imágenes de entrada",
- "Path to directory where to write outputs": "Ruta al directorio donde escribir salidas",
- "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.": "Usa las siguientes etiquetas para definir cómo se eligen los nombres de archivo para las imágenes: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; dejar vacío para utilizar predeterminados.",
- "If this option is enabled, watermark will not be added to created images. Warning: if you do not add watermark, you may be behaving in an unethical manner.": "Si esta opción está habilitada, el watermark no se agregará a las imágenes creadas. Advertencia: si no agregas un watermark, es posible que te estés comportando de manera poco ética.",
- "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.": "Usa las siguiente etiquetas para definir cómo los subdirectorios para imágenes y grids son seleccionados: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; dejar vacío para utilizar predeterminados.",
- "Restore low quality faces using GFPGAN neural network": "Restaurar rostros de baja calidad utilizando GFPGAN neural network",
- "This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is.": "Esta expresión regular se usará para extraer palabras del nombre de archivo y se unirán usando la opción a continuación en el texto de la etiqueta que se usa para el entrenamiento. Dejar vacío para mantener el texto del nombre de archivo tal como está.",
- "This string will be used to join split words into a single line if the option above is enabled.": "Esta cadena se usará para unir palabras divididas en una sola línea si la opción anterior está habilitada.",
- "List of setting names, separated by commas, for settings that should go to the quick access bar at the top, rather than the usual setting tab. See modules/shared.py for setting names. Requires restarting to apply.": "Lista de nombres de configuración, separados por comas, para configuraciones que deben ir a la barra de acceso rápido en la parte superior, en lugar de la pestaña de configuración habitual. Ver modules/shared.py para configurar los nombres. Requiere reiniciar para aplicar.",
- "If this values is non-zero, it will be added to seed and used to initialize RNG for noises when using samplers with Eta. You can use this to produce even more variation of images, or you can use this to match images of other software if you know what you are doing.": "Si este valor no es cero, se agregará al seed y se usará para inicializar RNG para ruidos cuando se usan samplers con Eta. Puedes usar esto para producir aún más variaciones de imágenes, o puedes usar esto para hacer coincidir imágenes de otro software si sabes lo que estás haciendo."
-}
diff --git a/localizations/fr_FR.json b/localizations/fr_FR.json
deleted file mode 100644
index b33d0838..00000000
--- a/localizations/fr_FR.json
+++ /dev/null
@@ -1,415 +0,0 @@
-{
- "⤡": "⤡",
- "⊞": "⊞",
- "×": "×",
- "❮": "❮",
- "❯": "❯",
- "Loading...": "Chargement...",
- "view": "vue",
- "api": "api",
- "•": "•",
- "built with gradio": "Construit avec Gradio",
- "Stable Diffusion checkpoint": "checkpoint Stable Diffusion",
- "txt2img": "txt2img",
- "img2img": "img2img",
- "Extras": "Extras",
- "PNG Info": "Infos PNG",
- "History": "Historique",
- "Checkpoint Merger": "Fusion de checkpoints",
- "Train": "Entrainer",
- "Settings": "Paramètres",
- "Prompt": "Requête",
- "Negative prompt": "Requête négative",
- "Run": "Lancer",
- "Skip": "Passer",
- "Interrupt": "Interrrompre",
- "Generate": "Générer",
- "Style 1": "Style 1",
- "Style 2": "Style 2",
- "Label": "Etiquette",
- "File": "Fichier",
- "Drop File Here": "Déposer votre fichier ici",
- "-": "-",
- "or": "ou",
- "Click to Upload": "Cliquer pour uploader",
- "Image": "Image",
- "Check progress": "Voir l'avancement",
- "Check progress (first)": "Voir l'avancement (1er)",
- "Sampling Steps": "Étapes d'échantillonnage",
- "Sampling method": "Méthode d'échantillonnage",
- "Euler a": "Euler a",
- "Euler": "Euler",
- "LMS": "LMS",
- "Heun": "Heun",
- "DPM2": "DPM2",
- "DPM2 a": "DPM2 a",
- "DPM fast": "DPM fast",
- "DPM adaptive": "DPM adaptive",
- "LMS Karras": "LMS Karras",
- "DPM2 Karras": "DPM2 Karras",
- "DPM2 a Karras": "DPM2 a Karras",
- "DDIM": "DDIM",
- "PLMS": "PLMS",
- "Width": "Largeur",
- "Height": "Hauteur",
- "Restore faces": "Restaurer les visages",
- "Tiling": "Mode Tuile",
- "Highres. fix": "Correction haute résolution",
- "Firstpass width": "Largeur première passe",
- "Firstpass height": "Hauteur seconde passe",
- "Denoising strength": "Puissance de réduction du bruit",
- "Batch count": "Nombre de lots",
- "Batch size": "Taille de lots",
- "CFG Scale": "Echelle CFG",
- "Seed": "Valeur aléatoire",
- "Extra": "Extra",
- "Variation seed": "Variation de la valeur aléatoire",
- "Variation strength": "Puissance de variation",
- "Resize seed from width": "Largeur de redimensionnement de la valeur aléatoire",
- "Resize seed from height": "Hauteur de redimensionnement de la valeur aléatoire",
- "Script": "Script",
- "None": "Aucun",
- "Prompt matrix": "Matrice de requète",
- "Prompts from file or textbox": "Requètes depuis un fichier ou une boite de dialogue",
- "X/Y plot": "graphe X/Y",
- "Put variable parts at start of prompt": "Mettre les mots clés variable au début de la requête",
- "Show Textbox": "Afficher le champs texte",
- "File with inputs": "Fichier d'entrée",
- "Prompts": "Requêtes",
- "X type": "Paramètre axe X",
- "Nothing": "Rien",
- "Var. seed": "Valeur aléatoire variable",
- "Var. strength": "Puissance variable",
- "Steps": "Étapes",
- "Prompt S/R": "Cherche et remplace dans la requête",
- "Prompt order": "Ordre de la requête",
- "Sampler": "Echantilloneur",
- "Checkpoint name": "Nom du checkpoint",
- "Hypernetwork": "Hypernetwork",
- "Hypernet str.": "Force de l'Hypernetwork",
- "Sigma Churn": "Sigma Churn",
- "Sigma min": "Sigma min.",
- "Sigma max": "Sigma max.",
- "Sigma noise": "Bruit Sigma",
- "Eta": "Temps estimé",
- "Clip skip": "Passer Clip",
- "Denoising": "Réduction du bruit",
- "X values": "Valeurs X",
- "Y type": "Paramètre axe Y",
- "Y values": "Valeurs Y",
- "Draw legend": "Afficher la légende",
- "Include Separate Images": "Inclure les images séparées",
- "Keep -1 for seeds": "Conserver -1 pour la valeur aléatoire",
- "Drop Image Here": "Déposer l'image ici",
- "Save": "Enregistrer",
- "Send to img2img": "Envoyer vers img2img",
- "Send to inpaint": "Envoyer vers inpaint",
- "Send to extras": "Envoyer vers extras",
- "Make Zip when Save?": "Créer un zip lors de l'enregistrement?",
- "Textbox": "Champ texte",
- "Interrogate\nCLIP": "Interroger\nCLIP",
- "Interrogate\nDeepBooru": "Interroger\nDeepBooru",
- "Inpaint": "Inpaint",
- "Batch img2img": "Lot img2img",
- "Image for img2img": "Image pour img2img",
- "Image for inpainting with mask": "Image pour inpainting avec masque",
- "Mask": "Masque",
- "Mask blur": "Flou masque",
- "Mask mode": "Mode masque",
- "Draw mask": "Dessiner masque",
- "Upload mask": "Uploader masque",
- "Masking mode": "Mode de masquage",
- "Inpaint masked": "Inpaint masqué",
- "Inpaint not masked": "Inpaint non masqué",
- "Masked content": "Contenu masqué",
- "fill": "remplir",
- "original": "original",
- "latent noise": "bruit latent",
- "latent nothing": "latent vide",
- "Inpaint at full resolution": "Inpaint en pleine résolution",
- "Inpaint at full resolution padding, pixels": "Padding de l'inpaint en pleine résolution, en pixels",
- "Process images in a directory on the same machine where the server is running.": "Traite les images dans un dossier sur la même machine où le serveur tourne",
- "Use an empty output directory to save pictures normally instead of writing to the output directory.": "Utiliser un dossier de sortie vide pour enregistrer les images normalement plutôt que d'écrire dans le dossier de sortie",
- "Input directory": "Dossier d'entrée",
- "Output directory": "Dossier de sortie",
- "Resize mode": "Mode redimensionnement",
- "Just resize": "Redimensionner uniquement",
- "Crop and resize": "Recadrer et redimensionner",
- "Resize and fill": "Redimensionner et remplir",
- "img2img alternative test": "Test alternatif img2img",
- "Loopback": "Bouclage",
- "Outpainting mk2": "Outpainting v2",
- "Poor man's outpainting": "Outpainting du pauvre",
- "SD upscale": "Agrandissement SD",
- "should be 2 or lower.": "doit être inférieur ou égal à 2",
- "Override `Sampling method` to Euler?(this method is built for it)": "Forcer `Méthode d'échantillonnage` à Euler ? (cette méthode est dédiée à cela)",
- "Override `prompt` to the same value as `original prompt`?(and `negative prompt`)": "Forcer la `requête` au contenu de la `requête d'origine` ? (de même pour la `requête négative`)",
- "Original prompt": "Requête d'origine",
- "Original negative prompt": "Requête négative d'origine",
- "Override `Sampling Steps` to the same value as `Decode steps`?": "Forcer le valeur d'`Étapes d'échantillonnage` à la même valeur qu'`Étapes de décodage` ?",
- "Decode steps": "Étapes de décodage",
- "Override `Denoising strength` to 1?": "Forcer `Puissance de réduction du bruit` à 1 ?",
- "Decode CFG scale": "Echelle CFG de décodage",
- "Randomness": "Aléatoire",
- "Sigma adjustment for finding noise for image": "Ajustement Sigma lors de la recherche du bruit dans l'image",
- "Loops": "Boucles",
- "Denoising strength change factor": "Facteur de changement de la puissance de réduction du bruit",
- "Recommended settings: Sampling Steps: 80-100, Sampler: Euler a, Denoising strength: 0.8": "Paramètres recommandés : Étapes d'échantillonnage : 80-100, Echantillonneur : Euler a, Puissance de réduction du bruit : 0.8",
- "Pixels to expand": "Pixels à étendre",
- "Outpainting direction": "Direction de l'outpainting",
- "left": "gauche",
- "right": "droite",
- "up": "haut",
- "down": "bas",
- "Fall-off exponent (lower=higher detail)": "Exposant de diminution (plus petit = plus de détails)",
- "Color variation": "Variation de couleur",
- "Will upscale the image to twice the dimensions; use width and height sliders to set tile size": "Agrandira l'image à deux fois sa taille; utilisez les glissières largeur et hauteur afin de choisir la taille de tuile",
- "Tile overlap": "Chevauchement de tuile",
- "Upscaler": "Agrandisseur",
- "Lanczos": "Lanczos",
- "LDSR": "LDSR",
- "BSRGAN 4x": "BSRGAN 4x",
- "ESRGAN_4x": "ESRGAN_4x",
- "R-ESRGAN 4x+ Anime6B": "R-ESRGAN 4x+ Anime6B",
- "ScuNET GAN": "ScuNET GAN",
- "ScuNET PSNR": "ScuNET PSNR",
- "SwinIR 4x": "SwinIR 4x",
- "Single Image": "Image unique",
- "Batch Process": "Traitement par lot",
- "Batch from Directory": "Lot depuis un dossier",
- "Source": "Source",
- "Show result images": "Montrez les images résultantes",
- "Scale by": "Mise à l'échelle de",
- "Scale to": "Mise à l'échelle à",
- "Resize": "Redimensionner",
- "Crop to fit": "Recadrer à la taille",
- "Upscaler 2": "Agrandisseur 2",
- "Upscaler 2 visibility": "Visibilité de l'agrandisseur 2",
- "GFPGAN visibility": "Visibilité GFPGAN",
- "CodeFormer visibility": "Visibilité CodeFormer",
- "CodeFormer weight (0 = maximum effect, 1 = minimum effect)": "Poids CodeFormer (0 = effet maximum, 1 = effet minimum)",
- "Open output directory": "Ouvrir le dossier de sortie",
- "Send to txt2img": "Envoyer vers txt2img",
- "txt2img history": "historique txt2img",
- "img2img history": "historique img2img",
- "extras history": "historique extras",
- "Renew Page": "Rafraichr la page",
- "First Page": "Première page",
- "Prev Page": "Page précendente",
- "Page Index": "Index des pages",
- "Next Page": "Page suivante",
- "End Page": "Page de fin",
- "number of images to delete consecutively next": "nombre d'image à supprimer consécutivement ensuite",
- "Delete": "Supprimer",
- "Generate Info": "Générer les informations",
- "File Name": "Nom de fichier",
- "set_index": "set_index",
- "A merger of the two checkpoints will be generated in your": "Une fusion des deux checkpoints sera générée dans votre",
- "checkpoint": "checkpoint",
- "directory.": "dossier",
- "Primary model (A)": "Modèle primaire (A)",
- "Secondary model (B)": "Modèle secondaire (B)",
- "Tertiary model (C)": "Modèle tertiaire (C)",
- "Custom Name (Optional)": "Nom personnalisé (Optionel)",
- "Multiplier (M) - set to 0 to get model A": "Multiplieur (M) - utiliser 0 pour le modèle A",
- "Interpolation Method": "Méthode d'interpolation",
- "Weighted sum": "Somme pondérée",
- "Add difference": "Ajouter différence",
- "Save as float16": "Enregistrer en tant que float16",
- "See": "Voir",
- "wiki": "wiki",
- "for detailed explanation.": "pour une explication détaillée.",
- "Create embedding": "Créer un embedding",
- "Create hypernetwork": "Créer un hypernetwork",
- "Preprocess images": "Pré-traite les images",
- "Name": "Nom",
- "Initialization text": "Texte d'initialisation",
- "Number of vectors per token": "Nombre de vecteurs par jeton",
- "Modules": "Modules",
- "Source directory": "Dossier source",
- "Destination directory": "Dossier destination",
- "Create flipped copies": "Créer des copies en mirroir",
- "Split oversized images into two": "Couper les images trop grandes en deux",
- "Use BLIP for caption": "Utiliser BLIP pour les descriptions",
- "Use deepbooru for caption": "Utiliser deepbooru pour les descriptions",
- "Preprocess": "Pré-traite",
- "Train an embedding; must specify a directory with a set of 1:1 ratio images": "Entrainer un embedding ; spécifiez un dossier contenant un ensemble d'images avec un ratio de 1:1",
- "Embedding": "Embedding",
- "Learning rate": "Vitesse d'apprentissage",
- "Dataset directory": "Dossier des images d'entrée",
- "Log directory": "Dossier de journalisation",
- "Prompt template file": "Fichier modèle de requêtes",
- "Max steps": "Étapes max.",
- "Save an image to log directory every N steps, 0 to disable": "Enregistrer une image dans le dossier de journalisation toutes les N étapes, 0 pour désactiver",
- "Save a copy of embedding to log directory every N steps, 0 to disable": "Enregistrer une copie de l'embedding dans le dossier de journalisation toutes les N étapes, 0 pour désactiver",
- "Save images with embedding in PNG chunks": "Sauvegarder les images incluant l'embedding dans leur blocs PNG",
- "Read parameters (prompt, etc...) from txt2img tab when making previews": "Lire les paramètres (requête, etc.) depuis l'onglet txt2img lors de la génération des previews",
- "Train Hypernetwork": "Entrainer un Hypernetwork",
- "Train Embedding": "Entrainer un Embedding",
- "Apply settings": "Appliquer les paramètres",
- "Saving images/grids": "Enregistrer les images/grilles",
- "Always save all generated images": "Toujours enregistrer toutes les images",
- "File format for images": "Format de fichier pour les images",
- "Images filename pattern": "Motif pour le nom de fichier des images",
- "Always save all generated image grids": "Toujours enregistrer toutes les grilles d'images générées",
- "File format for grids": "Format de fichier pour les grilles",
- "Add extended info (seed, prompt) to filename when saving grid": "Ajouter les informations étendues (valeur aléatoire, requête) aux noms de fichiers lors de l'enregistrement d'une grille",
- "Do not save grids consisting of one picture": "Ne pas enregistrer les grilles contenant une seule image",
- "Prevent empty spots in grid (when set to autodetect)": "Eviter les vides dans la grille (quand autodétection est choisie)",
- "Grid row count; use -1 for autodetect and 0 for it to be same as batch size": "Nombre de colonnes de la grille; utilisez -1 pour autodétection et 0 pour qu'il soit égal à la taille du lot",
- "Save text information about generation parameters as chunks to png files": "Enregistrer l'information du text des paramètres de génération en tant que blocs dans les fichiers PNG",
- "Create a text file next to every image with generation parameters.": "Créer un fichier texte contenant les paramètres de génération à côté de chaque image",
- "Save a copy of image before doing face restoration.": "Enregistrer une copie de l'image avant de lancer la restauration de visage",
- "Quality for saved jpeg images": "Qualité pour les images jpeg enregistrées",
- "If PNG image is larger than 4MB or any dimension is larger than 4000, downscale and save copy as JPG": "Si l'image PNG est plus grande que 4MB or l'une des ses dimensions supérieure à 4000, réduire sa taille et enregistrer une copie en JPG",
- "Use original name for output filename during batch process in extras tab": "Utiliser un nom de fichier original pour les fichiers de sortie durant le traitement par lot dans l'onglet Extras",
- "When using 'Save' button, only save a single selected image": "A l'utilisation du bouton `Enregistrer`, n'enregistrer que l'image séléctionnée",
- "Do not add watermark to images": "Ne pas ajouter de filigrane aux images",
- "Paths for saving": "Chemins pour l'enregistrement",
- "Output directory for images; if empty, defaults to three directories below": "Dossier de sortie pour les images; si non spécifié, le chemin par défaut sera trois niveau en dessous",
- "Output directory for txt2img images": "Dossier de sortie pour les images txt2img",
- "Output directory for img2img images": "Dossier de sortie pour les images img2img",
- "Output directory for images from extras tab": "Dossier de sortie pour les images de l'onglet Extras",
- "Output directory for grids; if empty, defaults to two directories below": "Dossier de sortie pour les grilles; si non spécifié, le chemin par défaut sera deux niveau en dessous",
- "Output directory for txt2img grids": "Dossier de sortie pour les grilles txt2img",
- "Output directory for img2img grids": "Dossier de sortie pour les grilles img2img",
- "Directory for saving images using the Save button": "Dossier de sauvegarde des images pour le bouton `Enregistrer`",
- "Saving to a directory": "Enregistrer dans un dossier",
- "Save images to a subdirectory": "Enregistrer les images dans un sous dossier",
- "Save grids to a subdirectory": "Enregistrer les grilles dans un sous dossier",
- "When using \"Save\" button, save images to a subdirectory": "Lors de l'utilisation du bouton \"Enregistrer\", sauvegarder les images dans un sous dossier",
- "Directory name pattern": "Motif pour le nom des dossiers",
- "Max prompt words for [prompt_words] pattern": "Maximum de mot pour le motif [prompt_words]",
- "Upscaling": "Agrandissement",
- "Tile size for ESRGAN upscalers. 0 = no tiling.": "Taille des tuile for les agrandisseurs ESRGAN. 0 = mode tuile désactivé.",
- "Tile overlap, in pixels for ESRGAN upscalers. Low values = visible seam.": "Chevauchement des tuiles, en pixel pour l'agrandisseur ESRGAN. Valeur faible = couture visible",
- "Tile size for all SwinIR.": "Taille de la tuile pour tous les agrandisseur SwinIR.",
- "Tile overlap, in pixels for SwinIR. Low values = visible seam.": "Chevauchement de tuile, en pixels pour SwinIR. Valeur faible = couture visible",
- "LDSR processing steps. Lower = faster": "Echantillon du traitement LDSR. Valeur faible = plus rapide",
- "Upscaler for img2img": "Agrandisseur pour img2img",
- "Upscale latent space image when doing hires. fix": "Agrandir l'image de l'espace latent lors de la correction haute résolution",
- "Face restoration": "Restauration de visage",
- "CodeFormer weight parameter; 0 = maximum effect; 1 = minimum effect": "Paramètre de poids pour CodeFormer; 0 = effet maximum ; 1 = effet minimum",
- "Move face restoration model from VRAM into RAM after processing": "Déplacer le modèle de restauration de visage de la VRAM vers la RAM après traitement",
- "System": "Système",
- "VRAM usage polls per second during generation. Set to 0 to disable.": "Fréquence d'interrogation par seconde pendant la génération. Mettez la valeur à 0 pour désactiver.",
- "Always print all generation info to standard output": "Toujours afficher toutes les informations de génération dans la sortie standard",
- "Add a second progress bar to the console that shows progress for an entire job.": "Ajouter un seconde barre de progression dans la console montrant l'avancement pour un tâche complète.",
- "Training": "Entrainement",
- "Unload VAE and CLIP from VRAM when training": "Décharger VAE et CLIP de la VRAM pendant l'entrainement",
- "Filename word regex": "Regex de mot",
- "Filename join string": "Chaine de caractère pour lier les noms de fichier",
- "Number of repeats for a single input image per epoch; used only for displaying epoch number": "Nombre de répétition pour une image unique par époque; utilisé seulement pour afficher le nombre d'époques",
- "Save an csv containing the loss to log directory every N steps, 0 to disable": "Enregistrer un csv contenant la perte dans le dossier de journalisation toutes les N étapes, 0 pour désactiver",
- "Stable Diffusion": "Stable Diffusion",
- "Checkpoints to cache in RAM": "Checkpoint à mettre en cache dans la RAM",
- "Hypernetwork strength": "Force de l'Hypernetwork",
- "Apply color correction to img2img results to match original colors.": "Appliquer une correction de couleur aux résultats img2img afin de conserver les couleurs d'origine",
- "Save a copy of image before applying color correction to img2img results": "Enregistrer une copie de l'image avant d'appliquer les résultats de la correction de couleur img2img",
- "With img2img, do exactly the amount of steps the slider specifies (normally you'd do less with less denoising).": "Avec img2img, executer exactement le nombre d'étapes spécifiées par la glissière (normalement moins d'étapes sont executées quand la réduction du bruit est plus faible).",
- "Enable quantization in K samplers for sharper and cleaner results. This may change existing seeds. Requires restart to apply.": "Activer la quantisation des échantillionneurs K pour des résultats plus nets et plus propres. Cela peut modifier les valeurs aléatoires existantes. Requiert un redémarrage pour être actif.",
- "Emphasis: use (text) to make model pay more attention to text and [text] to make it pay less attention": "Emphase : utilisez (texte) afin de forcer le modèle à porter plus d'attention au texte et [texte] afin qu'il y porte moins attention",
- "Use old emphasis implementation. Can be useful to reproduce old seeds.": "Utilisez l'ancienne méthode d'emphase. Peut être utile afin de reproduire d'anciennes valeurs aléatoires.",
- "Make K-diffusion samplers produce same images in a batch as when making a single image": "Demander aux échantillionneurs K-diffusion de produire les mêmes dans un lot que lors de la génération d'une image unique",
- "Increase coherency by padding from the last comma within n tokens when using more than 75 tokens": "Améliorer la cohérence en remplissant (padding) à partir de la dernière virgule dans les X jetons quand on en utilise plus de 75",
- "Filter NSFW content": "Filtrer le contenu +18 (NSFW)",
- "Stop At last layers of CLIP model": "S'arrêter aux derniers niveaux du modèle CLIP",
- "Interrogate Options": "Options d'intérrogation",
- "Interrogate: keep models in VRAM": "Interroger : conserver les modèles en VRAM",
- "Interrogate: use artists from artists.csv": "Interroger : utiliser les artistes dans artists.csv",
- "Interrogate: include ranks of model tags matches in results (Has no effect on caption-based interrogators).": "Interroger : inclure la correspondance du classement des labels de modèle dans les résultats (N'a pas d'effet sur les interrogateurs basés sur des descriptions) ",
- "Interrogate: num_beams for BLIP": "Interroger : num_beams pour BLIP",
- "Interrogate: minimum description length (excluding artists, etc..)": "Interroger : longueur minimale de la description (excluant les artistes, etc.)",
- "Interrogate: maximum description length": "Interroger : longueur maximale de la description",
- "CLIP: maximum number of lines in text file (0 = No limit)": "CLIP : nombre maximum de lignes dans le fichier texte (0 = pas de limite)",
- "Interrogate: deepbooru score threshold": "Interroger : seuil du score deepbooru",
- "Interrogate: deepbooru sort alphabetically": "Interroger : classement alphabétique deepbooru",
- "use spaces for tags in deepbooru": "Utiliser des espaces pour les étiquettes dans deepbooru",
- "escape (\\) brackets in deepbooru (so they are used as literal brackets and not for emphasis)": "échapper (\\) les crochets dans deepbooru (afin qu'ils puissent être utilisés littéralement et non pour mettre en emphase)",
- "User interface": "Interface utilisateur",
- "Show progressbar": "Afficher la barre de progression",
- "Show image creation progress every N sampling steps. Set 0 to disable.": "Afficher l'état d'avancement de la création d'image toutes les X étapes d'échantillionnage. Utiliser 0 pour désactiver.",
- "Show grid in results for web": "Afficher la grille dans les résultats web",
- "Do not show any images in results for web": "N'afficher aucune image dans les résultats web'",
- "Add model hash to generation information": "Ajouter le hash du modèle dans l'information de génération",
- "Add model name to generation information": "Ajouter le nom du modèle dans l'information de génération",
- "Font for image grids that have text": "Police pour les grilles d'images contenant du texte",
- "Enable full page image viewer": "Activer l'affichage des images en plein écran",
- "Show images zoomed in by default in full page image viewer": "Afficher les images zoomées par défaut lors de l'affichage en plein écran",
- "Show generation progress in window title.": "Afficher l'avancement de la génération dans le titre de la fenêtre.",
- "Quicksettings list": "Liste de réglages rapides",
- "Localization (requires restart)": "Localisation (requiert un redémarrage)",
- "Sampler parameters": "Paramètres de l'échantillionneur",
- "Hide samplers in user interface (requires restart)": "Cacher les échantillonneurs dans l'interface utilisateur (requiert un redémarrage)",
- "eta (noise multiplier) for DDIM": "eta (multiplicateur de bruit) pour DDIM",
- "eta (noise multiplier) for ancestral samplers": "eta (multiplicateur de bruit) poru les échantillionneurs de type 'ancestral'",
- "img2img DDIM discretize": "Discrétisation DDIM pour img2img",
- "uniform": "uniforme",
- "quad": "quad",
- "sigma churn": "sigma churn",
- "sigma tmin": "sigma tmin",
- "sigma noise": "sigma noise",
- "Eta noise seed delta": "Eta noise seed delta",
- "Request browser notifications": "Demander les notifications au navigateur",
- "Download localization template": "Télécharger le modèle de localisation",
- "Reload custom script bodies (No ui updates, No restart)": "Recharger le contenu des scripts personnalisés (Pas de mise à jour de l'interface, Pas de redémarrage)",
- "Restart Gradio and Refresh components (Custom Scripts, ui.py, js and css only)": "Redémarrer Gradio et rafraichir les composants (Scripts personnalisés, ui.py, js et css uniquement)",
- "Prompt (press Ctrl+Enter or Alt+Enter to generate)": "Requête (Ctrl + Entrée ou Alt + Entrée pour générer)",
- "Negative prompt (press Ctrl+Enter or Alt+Enter to generate)": "Requête négative (Ctrl + Entrée ou Alt + Entrée pour générer)",
- "Add a random artist to the prompt.": "Ajouter un artiste aléatoire à la requête",
- "Read generation parameters from prompt or last generation if prompt is empty into user interface.": "Lire les paramètres de génération depuis la requête, ou depuis la dernière génération si la requête est vide dans l'interface utilisateur.",
- "Save style": "Sauvegarder le style",
- "Apply selected styles to current prompt": "Appliquer les styles séléctionnés à la requête actuelle",
- "Stop processing current image and continue processing.": "Arrêter le traitement de l'image actuelle et continuer le traitement.",
- "Stop processing images and return any results accumulated so far.": "Arrêter le traitement des images et retourne les résultats accumulés depuis le début.",
- "Style to apply; styles have components for both positive and negative prompts and apply to both": "Style à appliquer ; les styles sont composés de requêtes positives et négatives et s'appliquent au deux",
- "Do not do anything special": "Ne rien faire de particulier",
- "Which algorithm to use to produce the image": "Quel algorithme utiliser pour produire l'image",
- "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps to higher than 30-40 does not help": "Euler Ancestral - très créatif, peut générer des images complètement différentes en fonction du nombre d'étapes, utiliser plus de 30 à 40 étapes n'améliore pas le résultat",
- "Denoising Diffusion Implicit Models - best at inpainting": "Modèles implicite de réduction du bruit à diffusion - utile pour l'inpainting",
- "Produce an image that can be tiled.": "Produit une image qui peut être bouclée (tuile).",
- "Use a two step process to partially create an image at smaller resolution, upscale, and then improve details in it without changing composition": "Utilise un processus en deux étapes afin de créer partiellement une image dans une résolution plus faible, l'agrandir et améliorer ses détails sans modifier la composition",
- "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.": "Détermine à quel point l'algorithme doit respecter le contenu de l'image. A 0 rien ne changera, à 1 l'image sera entièrement différente. Avec des valeurs inférieures à 1.0 le traitement utilisera moins d'étapes que ce que la glissière Étapes d'échantillionnage spécifie. ",
- "How many batches of images to create": "Combien de lots d'images créer",
- "How many image to create in a single batch": "Combien d'images créer par lot",
- "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results": "Classifier Free Guidance Scale - spécifie à quel point l'image doit se conformer à la requête - des valeurs plus faibles produisent des résultats plus créatifs",
- "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result": "Une valeur qui détermine la sortie du générateur de nombres aléatoires - si vous créez une image avec les mêmes paramètres et valeur aléatoire qu'une autre, le résultat sera identique",
- "Set seed to -1, which will cause a new random number to be used every time": "Passer la valeur aléatoire à -1, cela causera qu'un nombre aléatoire différent sera utilisé à chaque fois",
- "Reuse seed from last generation, mostly useful if it was randomed": "Réutiliser la valeur aléatoire de la dernière génération, généralement utile uniquement si elle était randomisée",
- "Seed of a different picture to be mixed into the generation.": "Valeur aléatoire d'une image différente à mélanger dans la génération",
- "How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something).": "Force de la variation à produire. A 0 il n'y aura pas d'effet. A 1 l'image sera composée uniquement de la valeur aléatoire variable spécifiée (à l'exception des échantillionneurs `ancestral`)",
- "Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution": "Essayer de produire une image similaire à ce qu'elle aurait été avec la même valeur aléatoire, mais dans la résolution spécifiée",
- "Separate values for X axis using commas.": "Séparer les valeurs pour l'axe X par des virgules",
- "Separate values for Y axis using commas.": "Séparer les valeurs pour l'axe Y par des virgules",
- "Write image to a directory (default - log/images) and generation parameters into csv file.": "Ecrire l'image dans un dossier (par défaut - log/images) et les paramètres de génération dans un fichier csv.",
- "Open images output directory": "Ouvrir le dossier de sortie des images",
- "How much to blur the mask before processing, in pixels.": "Quantité de flou à appliquer au masque avant traitement, en pixels",
- "What to put inside the masked area before processing it with Stable Diffusion.": "Avec quoi remplir la zone masquée avant traitement par Stable Diffusion.",
- "fill it with colors of the image": "remplir avec les couleurs de l'image",
- "keep whatever was there originally": "conserver ce qui était présent à l'origine",
- "fill it with latent space noise": "remplir avec le bruit de l'espace latent",
- "fill it with latent space zeroes": "remplir avec des zéros dans l'espace latent",
- "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image": "Agrandir la région masquées à la résolution cible, exécuter l'inpainting, réduire à nouveau puis coller dans l'image originale",
- "Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.": "Redimensionner l'image dans la résolution cible. A moins que la hauteur et la largeur coincident le ratio de l'image sera incorrect.",
- "Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out.": "Redimensionner l'image afin que l'entièreté de la résolution cible soit remplie par l'image. Recadrer les parties qui dépassent.",
- "Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors.": "Redimensionner l'image afin que l'entièreté de l'image soit contenue dans la résolution cible. Remplir l'espace vide avec les couleurs de l'image.",
- "How many times to repeat processing an image and using it as input for the next iteration": "Combien de fois répéter le traitement d'une image et l'utiliser comme entrée pour la prochaine itération",
- "In loopback mode, on each loop the denoising strength is multiplied by this value. <1 means decreasing variety so your sequence will converge on a fixed picture. >1 means increasing variety so your sequence will become more and more chaotic.": "En mode bouclage (Loopback), à chaque tour de la boucle la force du réducteur de bruit est multipliée par cette valeur. <1 signifie réduire la variation donc votre séquence convergera vers une image fixe. >1 signifie augmenter la variation donc votre séquence deviendra de plus en plus chaotique. ",
- "For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam.": "Pour l'agrandissement SD, de combien les tuiles doivent se chevaucher, en pixels. Les tuiles se chevauchent de manière à ce qu'il n'y ait pas de couture visible une fois fusionnées en une image. ",
- "A directory on the same machine where the server is running.": "Un dossier sur la même machine où le serveur tourne.",
- "Leave blank to save images to the default path.": "Laisser vide pour sauvegarder les images dans le chemin par défaut.",
- "Result = A * (1 - M) + B * M": "Résultat = A * (1 - M) + B * M",
- "Result = A + (B - C) * M": "Résultat = A + (B - C) * M",
- "Path to directory with input images": "Chemin vers le dossier contenant les images d'entrée",
- "Path to directory where to write outputs": "Chemin vers le dossier où écrire les sorties",
- "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; leave empty for default.": "Utiliser les étiquettes suivantes pour définir le nom des images : [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp] ; laisser vide pour le nom par défaut.",
- "If this option is enabled, watermark will not be added to created images. Warning: if you do not add watermark, you may be behaving in an unethical manner.": "Si cette option est activée le filigrane ne sera pas ajouté au images crées. Attention : si vous n'ajoutez pas de filigrane vous pourriez vous comporter de manière non éthique.",
- "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; leave empty for default.": "Utiliser les étiquettes suivantes pour définir le nom des sous dossiers pour les images et les grilles : [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp] ; laisser vide pour le nom par défaut.",
- "Restore low quality faces using GFPGAN neural network": "Restaurer les visages de basse qualité en utilisant le réseau neuronal GFPGAN",
- "This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is.": "Cette expression régulière sera utilisée pour extraire les mots depuis le nom de fichier ; ils seront joints en utilisant l'option ci dessous en une étiquette utilisée pour l'entrainement. Laisser vide pour conserver le texte du nom de fichier tel quel.",
- "This string will be used to join split words into a single line if the option above is enabled.": "Cette chaine de caractères sera utilisée pour joindre les mots séparés en une ligne unique si l'option ci dessus est activée.",
- "List of setting names, separated by commas, for settings that should go to the quick access bar at the top, rather than the usual setting tab. See modules/shared.py for setting names. Requires restarting to apply.": "Liste des noms de paramètres, séparés par des virgules, pour les paramètres de la barre d'accès rapide en haut de page, plutôt que dans la page habituelle des paramètres. Voir modules/shared.py pour définir les noms. Requiert un redémarrage pour s'appliquer.",
- "If this values is non-zero, it will be added to seed and used to initialize RNG for noises when using samplers with Eta. You can use this to produce even more variation of images, or you can use this to match images of other software if you know what you are doing.": "Si cette valeur est différente de zéro elle sera ajoutée à la valeur aléatoire et utilisée pour initialiser le générateur de nombres aléatoires du bruit lors de l'utilisation des échantillonneurs supportants Eta. Vous pouvez l'utiliser pour produire encore plus de variation dans les images, ou vous pouvez utiliser ceci pour faire correspondre les images avec d'autres logiciels si vous savez ce que vous faites.",
- "Enable Autocomplete": "Activer l'autocomplétion",
- "/0.0": "/0.0"
-} \ No newline at end of file
diff --git a/localizations/it_IT.json b/localizations/it_IT.json
deleted file mode 100644
index 0a216e22..00000000
--- a/localizations/it_IT.json
+++ /dev/null
@@ -1,1173 +0,0 @@
-{
- "⤡": "⤡",
- "⊞": "⊞",
- "×": "×",
- "❮": "❮",
- "❯": "❯",
- "Loading...": "Caricamento...",
- "view": "mostra ",
- "api": "API",
- "•": " • ",
- "built with gradio": " Sviluppato con Gradio",
- "Stable Diffusion checkpoint": "Stable Diffusion checkpoint",
- "txt2img": "txt2img",
- "img2img": "img2img",
- "Extras": "Extra",
- "PNG Info": "Info PNG",
- "Checkpoint Merger": "Miscelatore di Checkpoint",
- "Train": "Addestramento",
- "Create aesthetic embedding": "Crea incorporamento estetico",
- "Dataset Tag Editor": "Dataset Tag Editor",
- "Deforum": "Deforum",
- "Artists To Study": "Artisti per studiare",
- "Image Browser": "Galleria immagini",
- "Inspiration": "Ispirazione",
- "Settings": "Impostazioni",
- "Extensions": "Estensioni",
- "Prompt": "Prompt",
- "Negative prompt": "Prompt negativo",
- "Run": "Esegui",
- "Skip": "Salta",
- "Interrupt": "Interrompi",
- "Generate": "Genera",
- "Style 1": "Stile 1",
- "Style 2": "Stile 2",
- "Label": "Etichetta",
- "File": "File",
- "Drop File Here": "Trascina il file qui",
- "-": "-",
- "or": "o",
- "Click to Upload": "Clicca per caricare",
- "Image": "Immagine",
- "Check progress": "Controlla i progressi",
- "Check progress (first)": "Controlla i progressi (primo)",
- "Sampling Steps": "Passi di campionamento",
- "Sampling method": "Metodo di campionamento",
- "Euler a": "Euler a",
- "Euler": "Euler",
- "LMS": "LMS",
- "Heun": "Heun",
- "DPM2": "DPM2",
- "DPM2 a": "DPM2 a",
- "DPM fast": "DPM fast",
- "DPM adaptive": "DPM adaptive",
- "LMS Karras": "LMS Karras",
- "DPM2 Karras": "DPM2 Karras",
- "DPM2 a Karras": "DPM2 a Karras",
- "DDIM": "DDIM",
- "PLMS": "PLMS",
- "Width": "Larghezza",
- "Height": "Altezza",
- "Restore faces": "Restaura i volti",
- "Tiling": "Piastrellatura",
- "Highres. fix": "Correzione alta risoluzione",
- "Firstpass width": "Larghezza del primo passaggio",
- "Firstpass height": "Altezza del primo passaggio",
- "Denoising strength": "Forza del Denoising",
- "Batch count": "Lotti di immagini",
- "Batch size": "Immagini per lotto",
- "CFG Scale": "Scala CFG",
- "Seed": "Seme",
- "Extra": "Extra",
- "Variation seed": "Seme della variazione",
- "Variation strength": "Forza della variazione",
- "Resize seed from width": "Ridimensiona il seme dalla larghezza",
- "Resize seed from height": "Ridimensiona il seme dall'altezza",
- "Open for Clip Aesthetic!": "Apri per Gradienti Estetici (CLIP)",
- "▼": "▼",
- "Aesthetic weight": "Estetica - Peso",
- "Aesthetic steps": "Estetica - Passi",
- "Aesthetic learning rate": "Estetica - Tasso di apprendimento",
- "Slerp interpolation": "Interpolazione Slerp",
- "Aesthetic imgs embedding": "Estetica - Incorporamento di immagini",
- "None": "Niente",
- "Aesthetic text for imgs": "Estetica - Testo per le immagini",
- "Slerp angle": "Angolo Slerp",
- "Is negative text": "È un testo negativo",
- "Script": "Script",
- "Random grid": "Generaz. casuale (griglia)",
- "Random": "Generaz. casuale (no griglia)",
- "StylePile": "StylePile",
- "Advanced prompt matrix": "Matrice di prompt avanzata",
- "Advanced Seed Blending": "Miscelazione Semi Avanzata",
- "Alternate Sampler Noise Schedules": "Metodi alternativi di campionamento del rumore",
- "Animator v6": "Animator v6",
- "Asymmetric tiling": "Piastrellatura asimmetrica",
- "Custom code": "Codice personalizzato",
- "Dynamic Prompting v0.2": "Prompt dinamici v0.2",
- "Embedding to Shareable PNG": "Incorporamento convertito in PNG condivisibile",
- "Force symmetry": "Forza la simmetria",
- "Prompts interpolation": "Interpola Prompt",
- "Prompt matrix": "Matrice dei prompt",
- "Prompt morph": "Metamorfosi del prompt",
- "Prompts from file or textbox": "Prompt da file o da casella di testo",
- "To Infinity and Beyond": "Verso l'infinito e oltre",
- "Seed travel": "Interpolazione semi",
- "Shift attention": "Sposta l'attenzione",
- "Text to Vector Graphics": "Da testo a grafica vettoriale",
- "X/Y plot": "Grafico X/Y",
- "X/Y/Z plot": "Grafico X/Y/Z",
- "Create inspiration images": "Crea immagini di ispirazione",
- "step1 min/max": "Passi min(o max)",
- "step2 min/max": "Passi max (o min)",
- "step cnt": "Q.tà di Passi",
- "cfg1 min/max": "CFG min (o max)",
- "cfg2 min/max": "CFG max (o min)",
- "cfg cnt": "Q.tà di CFG",
- "Draw legend": "Disegna legenda",
- "Include Separate Images": "Includi immagini separate",
- "Keep -1 for seeds": "Mantieni sempre il seme a -1",
- "x/y change": "Inverti ordine assi X/Y (Passi/CFG)",
- "Loops": "Cicli",
- "Focus on:": "Focus su:",
- "No focus": "Nessun Focus",
- "Portraits (tick Restore faces above for best results)": "Ritratti (selezionare 'Restaura volti' in alto per ottenere i migliori risultati)",
- "Feminine and extra attractive (tick Restore faces above for best results)": "Femminile ed estremamente attraente (selezionare 'Restaura volti' per ottenere i migliori risultati)",
- "Masculine and extra attractive (tick Restore faces above for best results)": "Maschile ed estremamente attraente (selezionare 'Restaura volti' per ottenere i migliori risultati)",
- "Monsters": "Mostri",
- "Robots": "Robot",
- "Retrofuturistic": "Retrofuturistico",
- "Propaganda": "Propaganda",
- "Landscapes": "Paesaggi",
- "Hints": "Suggerimenti",
- "Image type": "Tipo di immagine",
- "Not set": "Non impostato",
- "Photography": "Fotografia",
- "Digital art": "Arte digitale",
- "3D Rendering": "3D Rendering",
- "Painting": "Dipinto",
- "Sketch": "Schizzo",
- "Classic Comics": "Fumetti classici",
- "Modern Comics": "Fumetti moderni",
- "Manga": "Manga",
- "Vector art": "Arte vettoriale",
- "Visual style": "Stile visivo",
- "Realism": "Realismo",
- "Photorealism": "Fotorealismo",
- "Hyperrealism": "Iperrealismo",
- "Surrealism": "Surrealismo",
- "Modern Art": "Arte moderna",
- "Fauvism": "Fauvismo",
- "Futurism": "Futurismo",
- "Painterly": "Pittorico",
- "Pointillisme": "Puntinismo",
- "Abstract": "Astratto",
- "Pop Art": "Pop Art",
- "Impressionist": "Impressionista",
- "Cubism": "Cubismo",
- "Linocut": "Linoleografia",
- "Fantasy": "Fantasia",
- "Colors": "Colori",
- "Chaotic": "Caotico",
- "Primary colors": "Colori primari",
- "Colorful": "Colorato",
- "Vivid": "Vivido",
- "Muted colors": "Colori tenui",
- "Low contrast": "Basso contrasto",
- "Desaturated": "Desaturato",
- "Grayscale": "Scala di grigi",
- "Black and white": "Bianco e nero",
- "Infrared": "Infrarosso",
- "Complementary": "Colori complementari",
- "Non-complementary": "Colori non complementari",
- "View": "Visuale",
- "Tilt shift": "Tilt shift",
- "Wide-angle": "Angolo ampio",
- "Portrait": "Ritratto",
- "Macro": "Macro",
- "Microscopic": "Microscopico",
- "Isometric": "Isometrico",
- "Panorama": "Panorama",
- "Aerial photograph": "Fotografia aerea",
- "Artist focus (not quite finished, not sure it helps)": "Focus sull'artista (non del tutto finito, non è sicuro che aiuti)",
- "B/W Photograpy": "Fotografia B/N",
- "Portrait photo": "Foto ritratto",
- "Usage: a <corgi|cat> wearing <goggles|a hat>": "Utilizzo: a <corgi|cat> wearing <goggles|a hat>",
- "Seeds": "Semi",
- "Noise Scheduler": "Pianificazione del rumore",
- "Default": "Predefinito",
- "Karras": "Karras",
- "Exponential": "Esponenziale",
- "Variance Preserving": "Conservazione della Varianza",
- "Sigma min": "Sigma min",
- "Sigma max": "Sigma max",
- "Sigma rho (Karras only)": "Sigma rho (Solo Karras)",
- "Beta distribution (VP only)": "Distribuzione Beta (Solo CV)",
- "Beta min (VP only)": "Beta min (Solo CV)",
- "Epsilon (VP only)": "Epsilon (Solo CV)",
- "Running in txt2img mode:": "Running in txt2img mode:",
- "Render these video formats:": "Renderizza in questi formati:",
- "GIF": "GIF",
- "MP4": "MP4",
- "WEBM": "WEBM",
- "Animation Parameters": "Parametri animazione",
- "Total Animation Length (s)": "Durata totale dell'animazione (s)",
- "Framerate": "Frequenza dei fotogrammi",
- "Smoothing_Frames": "Smoothing_Frames",
- "Add_Noise": "Aggiungi rumore",
- "Noise Strength": "Intensità del rumore",
- "Initial Parameters": "Parametri iniziali",
- "Denoising Strength (overrides img2img slider)": "Intensità di riduzione del rumore (sovrascrive il cursore img2img)",
- "Seed_March": "Seed_March",
- "Zoom Factor (scale/s)": "Fattore di ingrandimento (scala/s)",
- "X Pixel Shift (pixels/s)": "Sposta i Pixel sull'asse X (pixel/s)",
- "Y Pixel Shift (pixels/s)": "Sposta i Pixel sull'asse Y (pixel/s)",
- "Rotation (deg/s)": "Rotazione (gradi/s)",
- "Prompt Template, applied to each keyframe below": "Modello di prompt, applicato a ciascun fotogramma chiave qui di seguito",
- "Positive Prompts": "Prompt positivi",
- "Negative Prompts": "Prompt negativi",
- "Props, Stamps": "Props, Stamps",
- "Poper_Folder:": "Cartella Poper:",
- "Supported Keyframes:": "Fotogrammi chiave supportati:",
- "time_s | source | video, images, img2img | path": "time_s | source | video, images, img2img | path",
- "time_s | prompt | positive_prompts | negative_prompts": "time_s | prompt | positive_prompts | negative_prompts",
- "time_s | template | positive_prompts | negative_prompts": "time_s | template | positive_prompts | negative_prompts",
- "time_s | transform | zoom | x_shift | y_shift | rotation": "time_s | transform | zoom | x_shift | y_shift | rotation",
- "time_s | seed | new_seed_int": "time_s | seed | new_seed_int",
- "time_s | noise | added_noise_strength": "time_s | noise | added_noise_strength",
- "time_s | denoise | denoise_value": "time_s | denoise | denoise_value",
- "time_s | set_text | textblock_name | text_prompt | x | y | w | h | fore_color | back_color | font_name": "time_s | set_text | textblock_name | text_prompt | x | y | w | h | fore_color | back_color | font_name",
- "time_s | clear_text | textblock_name": "time_s | clear_text | textblock_name",
- "time_s | prop | prop_name | prop_filename | x pos | y pos | scale | rotation": "time_s | prop | prop_name | prop_filename | x pos | y pos | scale | rotation",
- "time_s | set_stamp | stamp_name | stamp_filename | x pos | y pos | scale | rotation": "time_s | set_stamp | stamp_name | stamp_filename | x pos | y pos | scale | rotation",
- "time_s | clear_stamp | stamp_name": "time_s | clear_stamp | stamp_name",
- "time_s | col_set": "time_s | col_set",
- "time_s | col_clear": "time_s | col_clear",
- "time_s | model | model": "time_s | model | model",
- "img2img_mode": "img2img_mode",
- "Keyframes:": "Fotogrammi chiave:",
- "Tile X": "Piastrella asse X",
- "Tile Y": "Piastrella asse Y",
- "Python code": "Codice Python",
- "Combinatorial generation": "Generazione combinatoria",
- "Combinations": "Combinazioni",
- "Choose a number of terms from a list, in this case we choose two artists": "Scegli un numero di termini da un elenco, in questo caso scegliamo due artisti",
- "{2$$artist1|artist2|artist3}": "{2$$artist1|artist2|artist3}",
- "If $$ is not provided, then 1$$ is assumed.\n\n A range can be provided:": "Se $$ non viene fornito, si presume 1$$.\n\n È possibile fornire un intervallo di valori:",
- "{1-3$$artist1|artist2|artist3}": "{1-3$$artist1|artist2|artist3}",
- "In this case, a random number of artists between 1 and 3 is chosen.": "In questo caso viene scelto un numero casuale di artisti compreso tra 1 e 3.",
- "Wildcards": "Termini jolly",
- "If the groups wont drop down click": "Se i gruppi non vengono visualizzati, clicca",
- "here": "qui",
- "to fix the issue.": "per correggere il problema.",
- "WILDCARD_DIR: scripts/wildcards": "WILDCARD_DIR: scripts/wildcards",
- "You can add more wildcards by creating a text file with one term per line and name is mywildcards.txt. Place it in scripts/wildcards.": "Puoi aggiungere termini jolly creando un file di testo con un termine per riga e nominandolo, per esempio, mywildcards.txt. Inseriscilo in scripts/wildcards.",
- "__<folder>/mywildcards__": "__<folder>/mywildcards__",
- "will then become available.": "diverrà quindi disponibile.",
- "Source embedding to convert": "Incorporamento sorgente da convertire",
- "Embedding token": "Token Incorporamento",
- "Output directory": "Cartella di output",
- "Horizontal symmetry": "Simmetria orizzontale",
- "Vertical symmetry": "Simmetria verticale",
- "Alt. symmetry method (blending)": "Metodo di simmetria alternativo (miscelazione)",
- "Apply every n steps": "Applica ogni n passi",
- "Skip last n steps": "Salta gli ultimi n passi",
- "Interpolation prompt": "Prompt di interpolazione",
- "Number of images": "Numero di immagini",
- "Make a gif": "Crea GIF",
- "Duration of images (ms)": "Durata delle immagini (ms)",
- "Put variable parts at start of prompt": "Inserisce le parti variabili all'inizio del prompt",
- "Keyframe Format:": "Formato dei fotogrammi chiave:",
- "Seed | Prompt or just Prompt": "Seme | Prompt o semplicemente Prompt",
- "Prompt list": "Elenco dei prompt",
- "Number of images between keyframes": "Numero di immagini tra fotogrammi chiave",
- "Save results as video": "Salva i risultati come video",
- "Frames per second": "Fotogrammi al secondo",
- "Iterate seed every line": "Iterare il seme per ogni riga",
- "List of prompt inputs": "Elenco di prompt di input",
- "Upload prompt inputs": "Carica un file contenente i prompt di input",
- "n": "Esegui n volte",
- "Destination seed(s) (Comma separated)": "Seme/i di destinazione (separati da virgola)",
- "Only use Random seeds (Unless comparing paths)": "Usa solo semi casuali (a meno che non si confrontino i percorsi)",
- "Number of random seed(s)": "Numero di semi casuali",
- "Compare paths (Separate travels from 1st seed to each destination)": "Confronta percorsi (transizioni separate dal primo seme a ciascuna destinazione)",
- "Steps": "Passi",
- "Loop back to initial seed": "Ritorna al seme iniziale",
- "Bump seed (If > 0 do a Compare Paths but only one image. No video)": "Modula seme (se > 0 mescola il seme iniziale con quelli di destinazione ma solo un'immagine. Nessun video)",
- "Show generated images in ui": "Mostra le immagini generate nell'interfaccia utente",
- "\"Hug the middle\" during interpolation": "\"Hug the middle\" durante l'interpolazione. Rende l'interpolazione un po' più veloce all'inizio e alla fine. A volte può produrre video più fluidi, il più delle volte no.",
- "Allow the default Euler a Sampling method. (Does not produce good results)": "Consenti Euler_a come metodo di campionamento predefinito. (Non produce buoni risultati)",
- "Illustration": "Illustrazione",
- "Logo": "Logo",
- "Drawing": "Disegno",
- "Artistic": "Artistico",
- "Tattoo": "Tatuaggio",
- "Gothic": "Gotico",
- "Anime": "Anime",
- "Cartoon": "Cartoon",
- "Sticker": "Etichetta",
- "Gold Pendant": "Ciondolo in oro",
- "None - prompt only": "Nessuno - solo prompt",
- "Enable Vectorizing": "Abilita vettorizzazione",
- "Output format": "Formato di output",
- "svg": "svg",
- "pdf": "pdf",
- "White is Opaque": "Il bianco è opaco",
- "Cut white margin from input": "Taglia il margine bianco dall'input",
- "Keep temp images": "Conserva le immagini temporanee",
- "Threshold": "Soglia",
- "Transparent PNG": "PNG trasparente",
- "Noise Tolerance": "Tolleranza al rumore",
- "Quantize": "Quantizzare",
- "X type": "Parametro asse X",
- "Nothing": "Niente",
- "Var. seed": "Seme della variazione",
- "Var. strength": "Forza della variazione",
- "Prompt S/R": "Cerca e Sostituisci nel Prompt",
- "Prompt order": "In ordine di prompt",
- "Sampler": "Campionatore",
- "Checkpoint name": "Nome del checkpoint",
- "Hypernetwork": "Iperrete",
- "Hypernet str.": "Forza della Iperrete",
- "Sigma Churn": "Sigma Churn",
- "Sigma noise": "Sigma noise",
- "Eta": "ETA",
- "Clip skip": "Salta CLIP",
- "Denoising": "Riduzione del rumore",
- "Cond. Image Mask Weight": "Cond. Image Mask Weight",
- "X values": "Valori per X",
- "Y type": "Parametro asse Y",
- "Y values": "Valori per Y",
- "Z type": "Parametro asse Z",
- "Z values": "Valori per Z",
- "Artist or styles name list. '.txt' files with one name per line": "Elenco nomi di artisti o stili. File '.txt' con un nome per riga",
- "Prompt words before artist or style name": "Parole chiave prima del nome dell'artista o dello stile",
- "Prompt words after artist or style name": "Parole chiave dopo il nome dell'artista o dello stile",
- "Negative Prompt": "Prompt negativo",
- "Save": "Salva",
- "Send to img2img": "Invia a img2img",
- "Send to inpaint": "Invia a Inpaint",
- "Send to extras": "Invia a Extra",
- "Make Zip when Save?": "Crea un file ZIP quando si usa 'Salva'",
- "Textbox": "Casella di testo",
- "Interrogate\nCLIP": "Interroga\nCLIP",
- "Interrogate\nDeepBooru": "Interroga\nDeepBooru",
- "Inpaint": "Inpaint",
- "Batch img2img": "img2img in lotti",
- "Image for img2img": "Immagine per img2img",
- "Drop Image Here": "Trascina l'immagine qui",
- "Image for inpainting with mask": "Immagine per inpainting con maschera",
- "Mask": "Maschera",
- "Mask blur": "Sfocatura maschera",
- "Mask mode": "Modalità maschera",
- "Draw mask": "Disegna maschera",
- "Upload mask": "Carica maschera",
- "Masking mode": "Modalità mascheratura",
- "Inpaint masked": "Inpaint mascherato",
- "Inpaint not masked": "Inpaint non mascherato",
- "Masked content": "Contenuto mascherato",
- "fill": "riempi",
- "original": "originale",
- "latent noise": "rumore nello spazio latente",
- "latent nothing": "nulla nello spazio latente",
- "Inpaint at full resolution": "Inpaint alla massima risoluzione",
- "Inpaint at full resolution padding, pixels": "Inpaint con riempimento a piena risoluzione, pixel",
- "Process images in a directory on the same machine where the server is running.": "Elabora le immagini in una cartella sulla stessa macchina su cui è in esecuzione il server.",
- "Use an empty output directory to save pictures normally instead of writing to the output directory.": "Usa una cartella di output vuota per salvare normalmente le immagini invece di scrivere nella cartella di output.",
- "Input directory": "Cartella di Input",
- "Resize mode": "Modalità di ridimensionamento",
- "Just resize": "Ridimensiona solamente",
- "Crop and resize": "Ritaglia e ridimensiona",
- "Resize and fill": "Ridimensiona e riempie",
- "Advanced loopback": "Advanced loopback",
- "External Image Masking": "Immagine esterna per la mascheratura",
- "img2img alternative test": "Test alternativo per img2img",
- "img2tiles": "img2tiles",
- "Interpolate": "Interpola immagini",
- "Loopback": "Rielaborazione ricorsiva",
- "Loopback and Superimpose": "Rielabora ricorsivamente e sovraimponi",
- "Alpha Canvas": "Alpha Canvas",
- "Outpainting mk2": "Outpainting mk2",
- "Poor man's outpainting": "Poor man's outpainting",
- "SD upscale": "Ampliamento SD",
- "txt2mask v0.1.1": "txt2mask v0.1.1",
- "[C] Video to video": "[C] Video to video",
- "Videos": "Filmati",
- "Deforum-webui (use tab extension instead!)": "Deforum-webui (usa piuttosto la scheda Deforum delle estensioni!)",
- "Use first image colors (custom color correction)": "Usa i colori della prima immagine (correzione del colore personalizzata)",
- "Denoising strength change factor (overridden if proportional used)": "Fattore di variazione dell'intensità di riduzione del rumore (sovrascritto se si usa proporzionale)",
- "Zoom level": "Livello di Zoom",
- "Direction X": "Direzione X",
- "Direction Y": "Direzione Y",
- "Denoising strength start": "Intensità di riduzione del rumore - Inizio",
- "Denoising strength end": "Intensità di riduzione del rumore - Fine",
- "Denoising strength proportional change starting value": "Intensità di riduzione del rumore - Valore iniziale della variazione proporzionale",
- "Denoising strength proportional change ending value (0.1 = disabled)": "Intensità di riduzione del rumore - Valore finale della variazione proporzionale (0.1 = disabilitato)",
- "Saturation enhancement per image": "Miglioramento della saturazione per ciascuna immagine",
- "Use sine denoising strength variation": "Utilizzare la variazione sinusoidale dell'intensità di riduzione del rumore",
- "Phase difference": "Differenza di Fase",
- "Denoising strength exponentiation": "Esponenziazione dell'intensità di riduzione del rumore",
- "Use sine zoom variation": "Usa la variazione sinusoidale dello zoom",
- "Zoom exponentiation": "Esponeniazione dello Zoom",
- "Use multiple prompts": "Usa prompt multipli",
- "Same seed per prompt": "Stesso seme per ogni prompt",
- "Same seed for everything": "Stesso seme per tutto",
- "Original init image for everything": "Immagine originale di inizializzazione per tutto",
- "Multiple prompts : 1 line positive, 1 line negative, leave a blank line for no negative": "Prompt multipli: 1 riga positivo, 1 riga negativo, lasciare una riga vuota per nessun negativo",
- "Running in img2img mode:": "Esecuzione in modalità img2img:",
- "Masking preview size": "Dimensione dell'anteprima della mascheratura",
- "Draw new mask on every run": "Disegna una nuova maschera ad ogni esecuzione",
- "Process non-contigious masks separately": "Elaborare le maschere non contigue separatamente",
- "should be 2 or lower.": "dovrebbe essere 2 o inferiore.",
- "Override `Sampling method` to Euler?(this method is built for it)": "Sovrascrivi il 'Metodo di campionamento' con Eulero? (questo metodo è stato creato per questo)",
- "Override `prompt` to the same value as `original prompt`?(and `negative prompt`)": "Sovrascrivi `prompt` con lo stesso valore del `prompt originale`? (e `prompt negativo`)",
- "Original prompt": "Prompt originale",
- "Original negative prompt": "Prompt negativo originale",
- "Override `Sampling Steps` to the same val due as `Decode steps`?": "Sovrascrivere 'Passi di campionamento' allo stesso valore di 'Passi di decodifica'?",
- "Decode steps": "Passi di decodifica",
- "Override `Denoising strength` to 1?": "Sostituisci 'Forza di denoising' a 1?",
- "Decode CFG scale": "Scala CFG di decodifica",
- "Randomness": "Casualità",
- "Sigma adjustment for finding noise for image": "Regolazione Sigma per trovare il rumore per l'immagine",
- "Tile size": "Dimensione piastrella",
- "Tile overlap": "Sovrapposizione piastrella",
- "alternate img2img imgage": "Immagine alternativa per img2img",
- "interpolation values": "Valori di interpolazione",
- "Refinement loops": "Cicli di affinamento",
- "Loopback alpha": "Trasparenza rielaborazione ricorsiva",
- "Border alpha": "Trasparenza del bordo",
- "Blending strides": "Passi di fusione",
- "Reuse Seed": "Riusa il seme",
- "One grid": "Singola griglia",
- "Interpolate VarSeed": "Interpola il seme della variazione",
- "Paste on mask": "Incolla sulla maschera",
- "Inpaint all": "Inpaint tutto",
- "Interpolate in latent": "Interpola nello spazio latente",
- "Denoising strength change factor": "Fattore di variazione dell'intensità di denoising",
- "Superimpose alpha": "Sovrapporre Alpha",
- "Show extra settings": "Mostra impostazioni aggiuntive",
- "Reuse seed": "Riusa il seme",
- "CFG decay factor": "Fattore di decadimento CFG",
- "CFG target": "CFG di destinazione",
- "Show/Hide Canvas": "Mostra/Nascondi Tela",
- "Recommended settings: Sampling Steps: 80-100, Sampler: Euler a, Denoising strength: 0.8": "Impostazioni consigliate: Passi di campionamento: 80-100, Campionatore: Euler a, Intensità denoising: 0.8",
- "Pixels to expand": "Pixel da espandere",
- "Outpainting direction": "Direzione di Outpainting",
- "left": "sinistra",
- "right": "destra",
- "up": "sopra",
- "down": "sotto",
- "Fall-off exponent (lower=higher detail)": "Esponente di decremento (più basso=maggior dettaglio)",
- "Color variation": "Variazione di colore",
- "Will upscale the image to twice the dimensions; use width and height sliders to set tile size": "Aumenterà l'immagine al doppio delle dimensioni; utilizzare i cursori di larghezza e altezza per impostare la dimensione della piastrella",
- "Upscaler": "Ampliamento immagine",
- "Lanczos": "Lanczos",
- "LDSR": "LDSR",
- "ESRGAN_4x": "ESRGAN_4x",
- "ScuNET GAN": "ScuNET GAN",
- "ScuNET PSNR": "ScuNET PSNR",
- "SwinIR 4x": "SwinIR 4x",
- "Mask prompt": "Prompt maschera",
- "Negative mask prompt": "Prompt maschera negativa",
- "Mask precision": "Precisione della maschera",
- "Mask padding": "Estendi i bordi della maschera",
- "Brush mask mode": "Modalità pennello maschera",
- "discard": "Scarta",
- "add": "Aggiungi",
- "subtract": "Sottrai",
- "Show mask in output?": "Mostra maschera in uscita?",
- "If you like my work, please consider showing your support on": "Se ti piace il mio lavoro, per favore considera di mostrare il tuo supporto su ",
- "Patreon": "Patreon",
- "Input file path": "Percorso file di input",
- "CRF (quality, less is better, x264 param)": "CRF (qualità, meno è meglio, x264 param)",
- "FPS": "FPS",
- "Seed step size": "Ampiezza del gradiente del seme",
- "Seed max distance": "Distanza massima del seme",
- "Start time": "Orario di inizio",
- "End time": "Orario di fine",
- "End Prompt Blend Trigger Percent": "Percentuale di innesco del mix col prompt finale",
- "Prompt end": "Prompt finale",
- "Smooth video": "Rendi il filmato fluido",
- "Seconds": "Secondi",
- "Zoom": "Zoom",
- "Rotate": "Ruota",
- "Degrees": "Gradi",
- "Is the Image Tiled?": "L'immagine è piastrellata?",
- "TranslateX": "Traslazione X",
- "Left": "Sinistra",
- "PercentX": "Percentuale X",
- "TranslateY": "Traslazione Y",
- "Up": "Sopra",
- "PercentY": "Percentuale Y",
- "Show generated pictures in ui": "Mostra le immagini generate nell'interfaccia utente",
- "Deforum v0.5-webui-beta": "Deforum v0.5-webui-beta",
- "This script is deprecated. Please use the full Deforum extension instead.": "Questo script è obsoleto. Utilizzare invece l'estensione Deforum completa.",
- "Update instructions:": "Istruzioni per l'aggiornamento:",
- "github.com/deforum-art/deforum-for-automatic1111-webui/blob/automatic1111-webui/README.md": "github.com/deforum-art/deforum-for-automatic1111-webui/blob/automatic1111-webui/README.md",
- "discord.gg/deforum": "discord.gg/deforum",
- "Single Image": "Singola immagine",
- "Batch Process": "Elaborare a lotti",
- "Batch from Directory": "Lotto da cartella",
- "Source": "Sorgente",
- "Show result images": "Mostra le immagini dei risultati",
- "Scale by": "Scala di",
- "Scale to": "Scala a",
- "Resize": "Ridimensiona",
- "Crop to fit": "Ritaglia per adattare",
- "Upscaler 2 visibility": "Visibilità Ampliamento immagine 2",
- "GFPGAN visibility": "Visibilità GFPGAN",
- "CodeFormer visibility": "Visibilità CodeFormer",
- "CodeFormer weight (0 = maximum effect, 1 = minimum effect)": "Peso di CodeFormer (0 = effetto massimo, 1 = effetto minimo)",
- "Upscale Before Restoring Faces": "Amplia prima di restaurare i volti",
- "Send to txt2img": "Invia a txt2img",
- "A merger of the two checkpoints will be generated in your": "I due checkpoint verranno fusi nella cartella dei",
- "checkpoint": "checkpoint",
- "directory.": ".",
- "Primary model (A)": "Modello Primario (A)",
- "Secondary model (B)": "Modello Secondario (B)",
- "Tertiary model (C)": "Modello Terziario (C)",
- "Custom Name (Optional)": "Nome personalizzato (facoltativo)",
- "Multiplier (M) - set to 0 to get model A": "Moltiplicatore (M): impostare a 0 per ottenere il modello A",
- "Interpolation Method": "Metodo di interpolazione",
- "Weighted sum": "Somma pesata",
- "Add difference": "Aggiungi differenza",
- "Save as float16": "Salva come float16",
- "See": "Consulta la ",
- "wiki": "wiki",
- "for detailed explanation.": " per una spiegazione dettagliata.",
- "Create embedding": "Crea Incorporamento",
- "Create hypernetwork": "Crea Iperrete",
- "Preprocess images": "Preprocessa le immagini",
- "Name": "Nome",
- "Initialization text": "Testo di inizializzazione",
- "Number of vectors per token": "Numero di vettori per token",
- "Overwrite Old Embedding": "Sovrascrivi il vecchio incorporamento",
- "Modules": "Moduli",
- "Enter hypernetwork layer structure": "Immettere la struttura del livello della Iperrete",
- "Select activation function of hypernetwork": "Selezionare la funzione di attivazione della Iperrete",
- "linear": "linear",
- "relu": "relu",
- "leakyrelu": "leakyrelu",
- "elu": "elu",
- "swish": "swish",
- "tanh": "tanh",
- "sigmoid": "sigmoid",
- "celu": "celu",
- "gelu": "gelu",
- "glu": "glu",
- "hardshrink": "hardshrink",
- "hardsigmoid": "hardsigmoid",
- "hardtanh": "hardtanh",
- "logsigmoid": "logsigmoid",
- "logsoftmax": "logsoftmax",
- "mish": "mish",
- "prelu": "prelu",
- "rrelu": "rrelu",
- "relu6": "relu6",
- "selu": "selu",
- "silu": "silu",
- "softmax": "softmax",
- "softmax2d": "softmax2d",
- "softmin": "softmin",
- "softplus": "softplus",
- "softshrink": "softshrink",
- "softsign": "softsign",
- "tanhshrink": "tanhshrink",
- "threshold": "threshold",
- "Select Layer weights initialization. relu-like - Kaiming, sigmoid-like - Xavier is recommended": "Seleziona inizializzazione dei pesi dei livelli. relu-like - Kaiming, Si consiglia sigmoid-like - Xavier",
- "Normal": "Normal",
- "KaimingUniform": "KaimingUniform",
- "KaimingNormal": "KaimingNormal",
- "XavierUniform": "XavierUniform",
- "XavierNormal": "XavierNormal",
- "Add layer normalization": "Aggiunge la normalizzazione del livello",
- "Use dropout": "Usa Dropout",
- "Overwrite Old Hypernetwork": "Sovrascrive la vecchia Iperrete",
- "Source directory": "Cartella sorgente",
- "Destination directory": "Cartella di destinazione",
- "Existing Caption txt Action": "Azione sul testo della didascalia esistente",
- "ignore": "ignora",
- "copy": "copia",
- "prepend": "anteporre",
- "append": "appendere",
- "Create flipped copies": "Crea copie specchiate",
- "Split oversized images": "Dividi immagini di grandi dimensioni",
- "Auto focal point crop": "Ritaglio automatico al punto focale",
- "Use BLIP for caption": "Usa BLIP per la didascalia",
- "Use deepbooru for caption": "Usa deepbooru per la didascalia",
- "Split image threshold": "Soglia di divisione dell'immagine",
- "Split image overlap ratio": "Rapporto di sovrapposizione dell'immagine",
- "Focal point face weight": "Peso della faccia del punto focale",
- "Focal point entropy weight": "Peso dell'entropia del punto focale",
- "Focal point edges weight": "Peso dei bordi del punto focale",
- "Create debug image": "Crea immagine di debug",
- "Preprocess": "Preprocessa",
- "Train an embedding or Hypernetwork; you must specify a directory with a set of 1:1 ratio images": "Addestra un Incorporamento o Iperrete; è necessario specificare una directory con un set di immagini con rapporto 1:1",
- "[wiki]": "[wiki]",
- "Embedding": "Incorporamento",
- "Embedding Learning rate": "Tasso di apprendimento Incorporamento",
- "Hypernetwork Learning rate": "Tasso di apprendimento Iperrete",
- "Dataset directory": "Cartella del Dataset",
- "Log directory": "Cartella del registro",
- "Prompt template file": "File modello prompt",
- "Max steps": "Passi massimi",
- "Save an image to log directory every N steps, 0 to disable": "Salva un'immagine nella cartella del registro ogni N passaggi, 0 per disabilitare",
- "Save a copy of embedding to log directory every N steps, 0 to disable": "Salva una copia dell'incorporamento nella cartella del registro ogni N passaggi, 0 per disabilitare",
- "Save images with embedding in PNG chunks": "Salva le immagini con l'incorporamento in blocchi PNG",
- "Read parameters (prompt, etc...) from txt2img tab when making previews": "Legge i parametri (prompt, ecc...) dalla scheda txt2img durante la creazione delle anteprime",
- "Train Hypernetwork": "Addestra Iperrete",
- "Train Embedding": "Addestra Incorporamento",
- "Create an aesthetic embedding out of any number of images": "Crea un'incorporamento estetico da qualsiasi numero di immagini",
- "Create images embedding": "Crea incorporamento di immagini",
- "-1": "-1",
- "This extension works well with text captions in comma-separated style (such as the tags generated by DeepBooru interrogator).": "Questa estensione funziona bene con i sottotitoli di testo in stile separato da virgole (come i tag generati dall'interrogatore DeepBooru).",
- "Save all changes": "Salva tutte le modifiche",
- "Backup original text file (original file will be renamed like filename.000, .001, .002, ...)": "Backup del file di testo originale (il file originale verrà rinominato come nomefile.000, .001, .002, ...)",
- "Note:": "Note:",
- "New text file will be created if you are using filename as captions.": "Verrà creato un nuovo file di testo se si utilizza il nome del file come didascalia.",
- "Results": "Risultati",
- "Load": "Carica",
- "Dataset Images": "Immagini del Dataset",
- "Filter and Edit Tags": "Filtra e modifica i tag",
- "Edit Caption of Selected Image": "Modifica la didascalia dell'immagine selezionata",
- "Search tags / Filter images by tags": "Cerca tag / Filtra le immagini per tag",
- "Search Tags": "Cerca tag",
- "Clear all filters": "Rimuovi tutti i filtri",
- "Sort by": "Ordina per",
- "Alphabetical Order": "Ordine alfabetico",
- "Frequency": "Frequenza",
- "Sort Order": "Ordinamento",
- "Ascending": "Ascendente",
- "Descending": "Discendente",
- "Filter Images by Tags": "Filtra le immagini per tag",
- "Edit tags in filtered images": "Modifica i tag nelle immagini filtrate",
- "Selected Tags": "Tag selezionati",
- "Edit Tags": "Modificare i tag",
- "Apply changes to filtered images": "Applica le modifiche alle immagini filtrate",
- "Append additional tags to the beginning": "Aggiungi tag addizionali all'inizio",
- "1. The selected tags are displayed in comma separated style.": "1. I tag selezionati vengono visualizzati in uno stile separato da virgole.",
- "2. When changes are applied, all tags in each displayed images are replaced.": "2. Quando vengono applicate le modifiche, tutti i tag in ciascuna immagine visualizzata vengono sostituiti.",
- "3. If you change some tags into blank, they will be erased.": "3. Se modifichi alcuni tag con uno spazio vuoto, verranno cancellati.",
- "4. If you add some tags to the end, they will be appended to the end/beginning of the text file.": "4. Se aggiungi dei tag alla fine, questi verranno aggiunti alla fine/inizio del file di testo.",
- "5. Changes are not applied to the text files until the \"Save all changes\" button is pressed.": "5. Le modifiche non vengono applicate ai file di testo finché non viene premuto il pulsante \"Salva tutte le modifiche\"..",
- "ex A.": "esempio A.",
- "Original Text = \"A, A, B, C\" Selected Tags = \"B, A\" Edit Tags = \"X, Y\"": "Testo originale = \"A, A, B, C\" Tag selezionati = \"B, A\" Modifica tag = \"X, Y\"",
- "Result = \"Y, Y, X, C\" (B->X, A->Y)": "Risultato = \"Y, Y, X, C\" (B->X, A->Y)",
- "ex B.": "esempio B.",
- "Original Text = \"A, B, C\" Selected Tags = \"(nothing)\" Edit Tags = \"X, Y\"": "Testo originale = \"A, B, C\" Tag selezionati = \"(nothing)\" Modifica tag = \"X, Y\"",
- "Result = \"A, B, C, X, Y\" (add X and Y to the end (default))": "Risultato = \"A, B, C, X, Y\" (aggiunge X e Y alla fine (predefinito))",
- "Result = \"X, Y, A, B, C\" (add X and Y to the beginning (\"Append additional tags to the beginning\" checked))": "Risultato = \"X, Y, A, B, C\" (aggiunge X e Y all'inizio (\"Aggiungi tag addizionali all'inizio\" selezionato))",
- "ex C.": "esempio C.",
- "Original Text = \"A, B, C, D, E\" Selected Tags = \"A, B, D\" Edit Tags = \", X, \"": "Testo originale = \"A, B, C, D, E\" Tag selezionati = \"A, B, D\" Modifica tag = \", X, \"",
- "Result = \"X, C, E\" (A->\"\", B->X, D->\"\")": "Risultato = \"X, C, E\" (A->\"\", B->X, D->\"\")",
- "Caption of Selected Image": "Didascalia dell'immagine selezionata",
- "Copy caption": "Copia didascalia",
- "Edit Caption": "Modifica didascalia",
- "Apply changes to selected image": "Applica le modifiche all'immagine selezionata",
- "Changes are not applied to the text files until the \"Save all changes\" button is pressed.": "Le modifiche non vengono applicate ai file di testo finché non viene premuto il pulsante \"Salva tutte le modifiche\".",
- "Info and links": "Info e link",
- "Made by deforum.github.io, port for AUTOMATIC1111's webui maintained by kabachuha": "Realizzato da deforum.github.io, port per l'interfaccia web di AUTOMATIC1111 manutenuto da kabachuha",
- "Original Deforum Github repo github.com/deforum/stable-diffusion": "Repository Github originale di Deforum github.com/deforum/stable-diffusion",
- "This fork for auto1111's webui github.com/deforum-art/deforum-for-automatic1111-webui": "Questo fork è per l'interfaccia web di AUTOMATIC1111 github.com/deforum-art/deforum-for-automatic1111-webui",
- "Join the official Deforum Discord discord.gg/deforum to share your creations and suggestions": "Unisciti al canale Discord ufficiale di Deforum discord.gg/deforum per condividere le tue creazioni e suggerimenti",
- "User guide for v0.5 docs.google.com/document/d/1pEobUknMFMkn8F5TMsv8qRzamXX_75BShMMXV8IFslI/edit": "Manuale d'uso per la versione 0.5 docs.google.com/document/d/1pEobUknMFMkn8F5TMsv8qRzamXX_75BShMMXV8IFslI/edit",
- "Math keyframing explanation docs.google.com/document/d/1pfW1PwbDIuW0cv-dnuyYj1UzPqe23BlSLTJsqazffXM/edit?usp=sharing": "Spiegazione della matematica dei fotogrammi chiave docs.google.com/document/d/1pfW1PwbDIuW0cv-dnuyYj1UzPqe23BlSLTJsqazffXM/edit?usp=sharing",
- "Keyframes": "Fotogrammi chiave",
- "Prompts": "Prompt",
- "Init": "Inizializzare",
- "Video output": "Uscita video",
- "Run settings": "Esegui le impostazioni",
- "Import settings from file": "Importa impostazioni da file",
- "Override settings": "Sostituisci le impostazioni",
- "Custom settings file": "File delle impostazioni personalizzate",
- "Sampling settings": "Impostazioni di campionamento",
- "override_these_with_webui": "Sovrascrivi con Web UI",
- "W": "L",
- "H": "A",
- "seed": "Seme",
- "sampler": "Campionatore",
- "Enable extras": "Abilita 'Extra'",
- "subseed": "Sub seme",
- "subseed_strength": "Intensità subseme",
- "steps": "Passi",
- "ddim_eta": "ETA DDIM",
- "n_batch": "Numero lotto",
- "make_grid": "Crea griglia",
- "grid_rows": "Righe griglia",
- "save_settings": "Salva impostazioni",
- "save_samples": "Salva i campioni",
- "display_samples": "Mostra i campioni",
- "save_sample_per_step": "Salva campioni per passo",
- "show_sample_per_step": "Mostra campioni per passo",
- "Batch settings": "Impostazioni lotto",
- "batch_name": "Nome del lotto",
- "filename_format": "Formato nome del file",
- "seed_behavior": "Comportamento seme",
- "iter": "Iterativo",
- "fixed": "Fisso",
- "random": "Casuale",
- "schedule": "Pianificato",
- "Animation settings": "Impostazioni animazione",
- "animation_mode": "Modalità animazione",
- "2D": "2D",
- "3D": "3D",
- "Video Input": "Ingresso video",
- "max_frames": "Fotogrammi max",
- "border": "Bordo",
- "replicate": "Replica",
- "wrap": "Impacchetta",
- "Motion parameters:": "Parametri di movimento:",
- "2D and 3D settings": "Impostazioni 2D e 3D",
- "angle": "Angolo",
- "zoom": "Zoom",
- "translation_x": "Traslazione X",
- "translation_y": "Traslazione Y",
- "3D settings": "Impostazioni 3D",
- "translation_z": "Traslazione Z",
- "rotation_3d_x": "Rotazione 3D X",
- "rotation_3d_y": "Rotazione 3D Y",
- "rotation_3d_z": "Rotazione 3D Z",
- "Prespective flip — Low VRAM pseudo-3D mode:": "Inversione prospettica: modalità pseudo-3D a bassa VRAM:",
- "flip_2d_perspective": "Inverti prospettiva 2D",
- "perspective_flip_theta": "Inverti prospettiva theta",
- "perspective_flip_phi": "Inverti prospettiva phi",
- "perspective_flip_gamma": "Inverti prospettiva gamma",
- "perspective_flip_fv": "Inverti prospettiva fv",
- "Generation settings:": "Impostazioni di generazione:",
- "noise_schedule": "Pianificazione del rumore",
- "strength_schedule": "Intensità della pianificazione",
- "contrast_schedule": "Contrasto della pianificazione",
- "cfg_scale_schedule": "Pianificazione della scala CFG",
- "3D Fov settings:": "Impostazioni del campo visivo 3D:",
- "fov_schedule": "Pianificazione del campo visivo",
- "near_schedule": "Pianificazione da vicino",
- "far_schedule": "Pianificazione da lontano",
- "To enable seed schedule select seed behavior — 'schedule'": "Per abilitare la pianificazione del seme, seleziona il comportamento del seme — 'pianifica'",
- "seed_schedule": "Pianificazione del seme",
- "Coherence:": "Coerenza:",
- "color_coherence": "Coerenza del colore",
- "Match Frame 0 HSV": "Uguaglia HSV del fotogramma 0",
- "Match Frame 0 LAB": "Uguaglia LAB del fotogramma 0",
- "Match Frame 0 RGB": "Uguaglia RGB del fotogramma 0",
- "diffusion_cadence": "Cadenza di diffusione",
- "3D Depth Warping:": "Deformazione della profondità 3D:",
- "use_depth_warping": "Usa la deformazione della profondità",
- "midas_weight": "Peso MIDAS",
- "near_plane": "Piano vicino",
- "far_plane": "Piano lontano",
- "fov": "Campo visivo",
- "padding_mode": "Modalità di riempimento",
- "reflection": "Rifletti",
- "zeros": "Zeri",
- "sampling_mode": "Modalità di campionamento",
- "bicubic": "bicubic",
- "bilinear": "bilinear",
- "nearest": "nearest",
- "save_depth_maps": "Salva le mappe di profondità",
- "`animation_mode: None` batches on list of *prompts*. (Batch mode disabled atm, only animation_prompts are working)": "`modalità animazione: Nessuno` si inserisce nell'elenco di *prompt*. (Modalità batch disabilitata atm, funzionano solo i prompt di animazione)",
- "*Important change from vanilla Deforum!*": "*Importante cambiamento rispetto alla versione originale di Deforum!*",
- "This script uses the built-in webui weighting settings.": "Questo script utilizza le impostazioni di pesatura webui integrate.",
- "So if you want to use math functions as prompt weights,": "Quindi, se vuoi usare le funzioni matematiche come pesi dei prompt,",
- "keep the values above zero in both parts": "mantenere i valori sopra lo zero in entrambe le parti",
- "Negative prompt part can be specified with --neg": "La parte negativa del prompt può essere specificata con --neg",
- "batch_prompts (disabled atm)": "Prompt in lotti (al momento è disabilitato)",
- "animation_prompts": "Prompt animazione",
- "Init settings": "Impostazioni iniziali",
- "use_init": "Usa le impostazioni iniziali",
- "from_img2img_instead_of_link": "from_img2img_instead_of_link",
- "strength_0_no_init": "strength_0_no_init",
- "strength": "Intensità",
- "init_image": "Immagine di inizializzazione",
- "use_mask": "Usa maschera",
- "use_alpha_as_mask": "Usa alpha come maschera",
- "invert_mask": "Inverti la maschera",
- "overlay_mask": "Sovrapponi la maschera",
- "mask_file": "File della maschera",
- "mask_brightness_adjust": "Regola la luminosità della maschera",
- "mask_overlay_blur": "Sfocatura della sovrapposizione della maschera",
- "Video Input:": "Ingresso video:",
- "video_init_path": "Percorso del video di inizializzazione",
- "extract_nth_frame": "Estrai ogni ennesimo fotogramma",
- "overwrite_extracted_frames": "Sovrascrivi i fotogrammi estratti",
- "use_mask_video": "Usa maschera video",
- "video_mask_path": "Percorso della maschera video",
- "Interpolation (turned off atm)": "Interpolazione (attualmente spento)",
- "interpolate_key_frames": "Interpola fotogrammi chiave",
- "interpolate_x_frames": "Interpola x fotogrammi",
- "Resume animation:": "Riprendi l'animazione:",
- "resume_from_timestring": "Riprendi da stringa temporale",
- "resume_timestring": "Stringa temporale",
- "Video output settings": "Impostazioni uscita video",
- "skip_video_for_run_all": "Salta il video per eseguire tutto",
- "fps": "FPS",
- "output_format": "Formato di uscita",
- "PIL gif": "PIL gif",
- "FFMPEG mp4": "FFMPEG mp4",
- "ffmpeg_location": "Percorso ffmpeg",
- "add_soundtrack": "Aggiungi colonna sonora",
- "soundtrack_path": "Percorso colonna sonora",
- "use_manual_settings": "Usa impostazioni manuali",
- "render_steps": "Passi di renderizzazione",
- "max_video_frames": "Numero max fotogrammi video",
- "path_name_modifier": "Modificatore del nome del percorso",
- "x0_pred": "x0_pred",
- "x": "x",
- "image_path": "Percorso immagine",
- "mp4_path": "Percorso MP4",
- "Click here after the generation to show the video": "Clicca qui dopo la generazione per mostrare il video",
- "Save Settings": "Salva le impostazioni",
- "Load Settings": "Carica le impostazioni",
- "Path relative to the webui folder." : "Percorso relativo alla cartella webui.",
- "Save Video Settings": "Salva impostazioni video",
- "Load Video Settings": "Carica impostazioni video",
- "dog": "cane",
- "house": "casa",
- "portrait": "ritratto",
- "spaceship": "nave spaziale",
- "anime": "anime",
- "cartoon": "cartoon",
- "digipa-high-impact": "digipa-high-impact",
- "digipa-med-impact": "digipa-med-impact",
- "digipa-low-impact": "digipa-low-impact",
- "fareast": "estremo oriente",
- "fineart": "fineart",
- "scribbles": "scarabocchi",
- "special": "special",
- "ukioe": "ukioe",
- "weird": "strano",
- "black-white": "bianco e nero",
- "nudity": "nudità",
- "c": "c",
- "Get Images": "Ottieni immagini",
- "dog-anime": "dog-anime",
- "dog-cartoon": "dog-cartoon",
- "dog-digipa-high-impact": "dog-digipa-high-impact",
- "dog-digipa-med-impact": "dog-digipa-med-impact",
- "dog-digipa-low-impact": "dog-digipa-low-impact",
- "dog-fareast": "dog-fareast",
- "dog-fineart": "dog-fineart",
- "dog-scribbles": "dog-scribbles",
- "dog-special": "dog-special",
- "dog-ukioe": "dog-ukioe",
- "dog-weird": "dog-weird",
- "dog-black-white": "dog-black-white",
- "dog-nudity": "dog-nudity",
- "dog-c": "dog-c",
- "dog-n": "dog-n",
- "house-anime": "house-anime",
- "house-cartoon": "house-cartoon",
- "house-digipa-high-impact": "house-digipa-high-impact",
- "house-digipa-med-impact": "house-digipa-med-impact",
- "house-digipa-low-impact": "house-digipa-low-impact",
- "house-fareast": "house-fareast",
- "house-fineart": "house-fineart",
- "house-scribbles": "house-scribbles",
- "house-special": "house-special",
- "house-ukioe": "house-ukioe",
- "house-weird": "house-weird",
- "house-black-white": "house-black-white",
- "house-nudity": "house-nudity",
- "house-c": "house-c",
- "house-n": "house-n",
- "portrait-anime": "portrait-anime",
- "portrait-cartoon": "portrait-cartoon",
- "portrait-digipa-high-impact": "portrait-digipa-high-impact",
- "portrait-digipa-med-impact": "portrait-digipa-med-impact",
- "portrait-digipa-low-impact": "portrait-digipa-low-impact",
- "portrait-fareast": "portrait-fareast",
- "portrait-fineart": "portrait-fineart",
- "portrait-scribbles": "portrait-scribbles",
- "portrait-special": "portrait-special",
- "portrait-ukioe": "portrait-ukioe",
- "portrait-weird": "portrait-weird",
- "portrait-black-white": "portrait-black-white",
- "portrait-nudity": "portrait-nudity",
- "portrait-c": "portrait-c",
- "portrait-n": "portrait-n",
- "spaceship-anime": "spaceship-anime",
- "spaceship-cartoon": "spaceship-cartoon",
- "spaceship-digipa-high-impact": "spaceship-digipa-high-impact",
- "spaceship-digipa-med-impact": "spaceship-digipa-med-impact",
- "spaceship-digipa-low-impact": "spaceship-digipa-low-impact",
- "spaceship-fareast": "spaceship-fareast",
- "spaceship-fineart": "spaceship-fineart",
- "spaceship-scribbles": "spaceship-scribbles",
- "spaceship-special": "spaceship-special",
- "spaceship-ukioe": "spaceship-ukioe",
- "spaceship-weird": "spaceship-weird",
- "spaceship-black-white": "spaceship-black-white",
- "spaceship-nudity": "spaceship-nudity",
- "spaceship-c": "spaceship-c",
- "spaceship-n": "spaceship-n",
- "artists to study extension by camenduru |": "Estensione 'Artisti per studiare' a cura di camenduru |",
- "github": "Github",
- "|": "|",
- "twitter": "Twitter",
- "youtube": "Youtube",
- "hi-res images": "Immagini in alta risoluzione",
- "All images generated with CompVis/stable-diffusion-v1-4 +": "Tutte le immagini sono state generate con CompVis/stable-diffusion-v1-4 +",
- "artists.csv": "artists.csv",
- "| License: Attribution 4.0 International (CC BY 4.0)": "| Licenza: Attribution 4.0 International (CC BY 4.0)",
- "Favorites": "Preferiti",
- "Others": "Altre immagini",
- "Images directory": "Cartella immagini",
- "Dropdown": "Elenco cartelle",
- "First Page": "Prima pagina",
- "Prev Page": "Pagina precedente",
- "Page Index": "Indice pagina",
- "Next Page": "Pagina successiva",
- "End Page": "Ultima pagina",
- "delete next": "Cancella successivo",
- "Delete": "Elimina",
- "sort by": "Ordina per",
- "path name": "Nome percorso",
- "date": "Data",
- "keyword": "Parola chiave",
- "Generate Info": "Genera Info",
- "File Name": "Nome del file",
- "Move to favorites": "Aggiungi ai preferiti",
- "Renew page": "Aggiorna la pagina",
- "Number": "Numero",
- "set_index": "Imposta indice",
- "load_switch": "load_switch",
- "turn_page_switch": "turn_page_switch",
- "Checkbox": "Casella di controllo",
- "Checkbox Group": "Seleziona immagini per",
- "artists": "Artisti",
- "flavors": "Stili",
- "mediums": "Tecniche",
- "movements": "Movimenti artistici",
- "All": "Tutto",
- "Exclude abandoned": "Escludi scartati",
- "Abandoned": "Scartati",
- "Key word": "Parola chiave",
- "Get inspiration": "Ispirami",
- "to txt2img": "Invia a txt2img",
- "to img2img": "Invia a img2img",
- "Collect": "Salva nei preferiti",
- "Don't show again": "Scarta",
- "Move out": "Rimuovi",
- "set button": "Pulsante imposta",
- "Apply settings": "Applica le impostazioni",
- "Saving images/grids": "Salva immagini/griglie",
- "Always save all generated images": "Salva sempre tutte le immagini generate",
- "File format for images": "Formato del file delle immagini",
- "Images filename pattern": "Modello del nome dei file immagine",
- "Add number to filename when saving": "Aggiungi un numero al nome del file al salvataggio",
- "Always save all generated image grids": "Salva sempre tutte le griglie di immagini generate",
- "File format for grids": "Formato del file per le griglie",
- "Add extended info (seed, prompt) to filename when saving grid": "Aggiungi informazioni estese (seme, prompt) al nome del file durante il salvataggio della griglia",
- "Do not save grids consisting of one picture": "Non salvare le griglie composte da una sola immagine",
- "Prevent empty spots in grid (when set to autodetect)": "Previeni spazi vuoti nella griglia (se impostato su rilevamento automatico)",
- "Grid row count; use -1 for autodetect and 0 for it to be same as batch size": "Numero di righe della griglia; utilizzare -1 per il rilevamento automatico e 0 per essere uguale alla dimensione del lotto",
- "Save text information about generation parameters as chunks to png files": "Salva le informazioni di testo dei parametri di generazione come blocchi nel file png",
- "Create a text file next to every image with generation parameters.": "Crea un file di testo assieme a ogni immagine con i parametri di generazione.",
- "Save a copy of image before doing face restoration.": "Salva una copia dell'immagine prima di eseguire il restauro dei volti.",
- "Quality for saved jpeg images": "Qualità delle immagini salvate in formato JPEG",
- "If PNG image is larger than 4MB or any dimension is larger than 4000, downscale and save copy as JPG": "Se l'immagine PNG è più grande di 4 MB o qualsiasi dimensione è maggiore di 4000, ridimensiona e salva la copia come JPG",
- "Use original name for output filename during batch process in extras tab": "Usa il nome originale per il nome del file di output durante l'elaborazione a lotti nella scheda 'Extra'",
- "When using 'Save' button, only save a single selected image": "Usando il pulsante 'Salva', verrà salvata solo la singola immagine selezionata",
- "Do not add watermark to images": "Non aggiungere la filigrana alle immagini",
- "Paths for saving": "Percorsi di salvataggio",
- "Output directory for images; if empty, defaults to three directories below": "Cartella di output per le immagini; se vuoto, per impostazione predefinita verranno usate le cartelle seguenti",
- "Output directory for txt2img images": "Cartella di output per le immagini txt2img",
- "Output directory for img2img images": "Cartella di output per le immagini img2img",
- "Output directory for images from extras tab": "Cartella di output per le immagini dalla scheda 'Extra'",
- "Output directory for grids; if empty, defaults to two directories below": "Cartella di output per le griglie; se vuoto, per impostazione predefinita veranno usate cartelle seguenti",
- "Output directory for txt2img grids": "Cartella di output per le griglie txt2img",
- "Output directory for img2img grids": "Cartella di output per le griglie img2img",
- "Directory for saving images using the Save button": "Cartella dove salvare le immagini usando il pulsante 'Salva'",
- "Saving to a directory": "Salva in una cartella",
- "Save images to a subdirectory": "Salva le immagini in una sotto cartella",
- "Save grids to a subdirectory": "Salva le griglie in una sotto cartella",
- "When using \"Save\" button, save images to a subdirectory": "Usando il pulsante \"Salva\", le immagini verranno salvate in una sotto cartella",
- "Directory name pattern": "Modello del nome della cartella",
- "Max prompt words for [prompt_words] pattern": "Numero massimo di parole del prompt per il modello [prompt_words]",
- "Upscaling": "Ampliamento",
- "Tile size for ESRGAN upscalers. 0 = no tiling.": "Dimensione piastrella per ampliamento ESRGAN. 0 = nessuna piastrellatura.",
- "Tile overlap, in pixels for ESRGAN upscalers. Low values = visible seam.": "Sovrapposizione delle piastrelle, in pixel per gli ampliamenti ESRGAN. Valori bassi = cucitura visibile.",
- "Tile size for all SwinIR.": "Dimensione piastrella per tutti gli SwinIR.",
- "Tile overlap, in pixels for SwinIR. Low values = visible seam.": "Sovrapposizione delle piastrelle, in pixel per SwinIR. Valori bassi = cucitura visibile.",
- "LDSR processing steps. Lower = faster": "Fasi di elaborazione LDSR. Più basso = più veloce",
- "Upscaler for img2img": "Metodo di ampliamento per img2img",
- "Upscale latent space image when doing hires. fix": "Amplia l'immagine nello spazio latente durante la correzione in alta risoluzione",
- "Face restoration": "Restauro del viso",
- "CodeFormer weight parameter; 0 = maximum effect; 1 = minimum effect": "Peso di CodeFormer; 0 = effetto massimo; 1 = effetto minimo",
- "Move face restoration model from VRAM into RAM after processing": "Sposta il modello di restauro facciale dalla VRAM alla RAM dopo l'elaborazione",
- "System": "Sistema",
- "VRAM usage polls per second during generation. Set to 0 to disable.": "Verifiche al secondo sull'utilizzo della VRAM durante la generazione. Impostare a 0 per disabilitare.",
- "Always print all generation info to standard output": "Stampa sempre tutte le informazioni di generazione sul output standard",
- "Add a second progress bar to the console that shows progress for an entire job.": "Aggiungi una seconda barra di avanzamento alla console che mostra l'avanzamento complessivo del lavoro.",
- "Training": "Addestramento",
- "Move VAE and CLIP to RAM when training hypernetwork. Saves VRAM.": "Sposta VAE e CLIP nella RAM durante l'addestramento di Iperreti. Risparmia VRAM.",
- "Filename word regex": "Filename word regex",
- "Filename join string": "Filename join string",
- "Number of repeats for a single input image per epoch; used only for displaying epoch number": "Numero di ripetizioni per una singola immagine di input per epoca; utilizzato solo per visualizzare il numero di epoca",
- "Save an csv containing the loss to log directory every N steps, 0 to disable": "Salva un file CSV contenente la perdita nella cartella di registrazione ogni N passaggi, 0 per disabilitare",
- "Stable Diffusion": "Stable Diffusion",
- "Checkpoints to cache in RAM": "Checkpoint da memorizzare nella RAM",
- "Hypernetwork strength": "Forza della Iperrete",
- "Inpainting conditioning mask strength": "Forza della maschera di condizionamento del Inpainting",
- "Apply color correction to img2img results to match original colors.": "Applica la correzione del colore ai risultati di img2img in modo che corrispondano ai colori originali.",
- "Save a copy of image before applying color correction to img2img results": "Salva una copia dell'immagine prima di applicare la correzione del colore ai risultati di img2img",
- "With img2img, do exactly the amount of steps the slider specifies (normally you'd do less with less denoising).": "Con img2img, esegue esattamente la quantità di passi specificata dalla barra di scorrimento (normalmente se ne effettuano di meno con meno riduzione del rumore).",
- "Enable quantization in K samplers for sharper and cleaner results. This may change existing seeds. Requires restart to apply.": "Abilita la quantizzazione nei campionatori K per risultati più nitidi e puliti. Questo può cambiare i semi esistenti. Richiede il riavvio per applicare la modifica.",
- "Emphasis: use (text) to make model pay more attention to text and [text] to make it pay less attention": "Enfasi: utilizzare (testo) per fare in modo che il modello presti maggiore attenzione al testo e [testo] per fargli prestare meno attenzione",
- "Use old emphasis implementation. Can be useful to reproduce old seeds.": "Usa la vecchia implementazione dell'enfasi. Può essere utile per riprodurre vecchi semi.",
- "Make K-diffusion samplers produce same images in a batch as when making a single image": "Fa sì che i campionatori di diffusione K producano le stesse immagini in un lotto come quando si genera una singola immagine",
- "Increase coherency by padding from the last comma within n tokens when using more than 75 tokens": "Aumenta la coerenza disattivando dall'ultima virgola all'indietro di n token quando si utilizzano più di 75 token",
- "Filter NSFW content": "Filtra i contenuti NSFW",
- "Stop At last layers of CLIP model": "Fermati agli ultimi livelli del modello CLIP",
- "Interrogate Options": "Opzioni di interrogazione",
- "Interrogate: keep models in VRAM": "Interroga: mantieni i modelli nella VRAM",
- "Interrogate: use artists from artists.csv": "Interroga: utilizza artisti dal file artisti.csv",
- "Interrogate: include ranks of model tags matches in results (Has no effect on caption-based interrogators).": "Interroga: include la classifica delle corrispondenze dei tag del modello nei risultati (non ha effetto sulle interrogazioni basate su didascalie).",
- "Interrogate: num_beams for BLIP": "Interroga: num_beams per BLIP",
- "Interrogate: minimum description length (excluding artists, etc..)": "Interroga: lunghezza minima della descrizione (esclusi artisti, ecc..)",
- "Interrogate: maximum description length": "Interroga: lunghezza massima della descrizione",
- "CLIP: maximum number of lines in text file (0 = No limit)": "CLIP: numero massimo di righe nel file di testo (0 = Nessun limite)",
- "Interrogate: deepbooru score threshold": "Interroga: soglia del punteggio deepbooru",
- "Interrogate: deepbooru sort alphabetically": "Interroga: deepbooru ordinato alfabeticamente",
- "use spaces for tags in deepbooru": "usa gli spazi per i tag in deepbooru",
- "escape (\\) brackets in deepbooru (so they are used as literal brackets and not for emphasis)": "Effettua l'escape (\\) delle parentesi in deepbooru (così vengono usate come parentesi letterali e non per enfatizzare)",
- "User interface": "Interfaccia Utente",
- "Show progressbar": "Mostra la barra di avanzamento",
- "Show image creation progress every N sampling steps. Set 0 to disable.": "Mostra l'avanzamento della generazione dell'immagine ogni N passaggi di campionamento. Impostare a 0 per disabilitare.",
- "Show previews of all images generated in a batch as a grid": "Mostra le anteprime di tutte le immagini generate in un lotto come una griglia",
- "Show grid in results for web": "Mostra la griglia nei risultati per il web",
- "Do not show any images in results for web": "Non mostrare alcuna immagine nei risultati per il web",
- "Add model hash to generation information": "Aggiungi l'hash del modello alle informazioni sulla generazione",
- "Add model name to generation information": "Aggiungi il nome del modello alle informazioni sulla generazione",
- "When reading generation parameters from text into UI (from PNG info or pasted text), do not change the selected model/checkpoint.": "Durante la lettura dei parametri di generazione dal testo nell'interfaccia utente (da informazioni PNG o testo incollato), non modificare il modello/checkpoint selezionato.",
- "Send seed when sending prompt or image to other interface": "Invia il seme quando si invia un prompt o un'immagine a un'altra interfaccia",
- "Font for image grids that have text": "Font per griglie di immagini con testo",
- "Enable full page image viewer": "Abilita la visualizzazione delle immagini a pagina intera",
- "Show images zoomed in by default in full page image viewer": "Mostra le immagini ingrandite per impostazione predefinita nella visualizzazione a pagina intera",
- "Show generation progress in window title.": "Mostra l'avanzamento della generazione nel titolo della finestra.",
- "Quicksettings list": "Elenco delle impostazioni rapide",
- "Localization (requires restart)": "Localizzazione (richiede il riavvio)",
- "ar_AR": "ar_AR",
- "de_DE": "de_DE",
- "es_ES": "es_ES",
- "fr_FR": "fr_FR",
- "it_IT": "it_IT",
- "ja_JP": "ja_JP",
- "ko_KR": "ko_KR",
- "pt_BR": "pt_BR",
- "ru_RU": "ru_RU",
- "tr_TR": "tr_TR",
- "zh_CN": "zh_CN",
- "zh_TW": "zh_TW",
- "Sampler parameters": "Parametri del campionatore",
- "Hide samplers in user interface (requires restart)": "Nascondi campionatori nell'interfaccia utente (richiede il riavvio)",
- "eta (noise multiplier) for DDIM": "ETA (moltiplicatore di rumore) per DDIM",
- "eta (noise multiplier) for ancestral samplers": "ETA (moltiplicatore di rumore) per campionatori ancestrali",
- "img2img DDIM discretize": "discretizzazione DDIM per img2img",
- "uniform": "uniforme",
- "quad": "quad",
- "sigma churn": "sigma churn",
- "sigma tmin": "sigma tmin",
- "sigma noise": "sigma noise",
- "Eta noise seed delta": "ETA del delta del seme del rumore",
- "Aesthetic Image Scorer": "Punteggio delle immagini estetiche",
- "Save score as EXIF or PNG Info Chunk": "Salva il punteggio come info EXIF o PNG",
- "Save score as tag (Windows Only)": "Salva punteggio come etichetta (solo Windows)",
- "Force CPU (Requires Custom Script Reload)": "Forza CPU (richiede il ricaricamento dello script personalizzato)",
- "Number of columns on image gallery": "Numero di colonne nella galleria di immagini",
- "Images Browser": "Galleria immagini",
- "Preload images at startup": "Precarica le immagini all'avvio",
- "Number of columns on the page": "Numero di colonne nella pagina",
- "Number of rows on the page": "Numero di righe nella pagina",
- "Minimum number of pages per load": "Numero minimo di pagine da caricare",
- "Maximum number of samples, used to determine which folders to skip when continue running the create script": "Numero massimo di campioni, utilizzato per determinare quali cartelle ignorare quando si continua a eseguire lo script di creazione",
- "Use same seed for all images": "Usa lo stesso seme per tutte le immagini",
- "Request browser notifications": "Richiedi le notifiche del browser",
- "Download localization template": "Scarica il modello per la localizzazione",
- "Reload custom script bodies (No ui updates, No restart)": "Ricarica gli script personalizzati (nessun aggiornamento dell'interfaccia utente, nessun riavvio)",
- "Restart Gradio and Refresh components (Custom Scripts, ui.py, js and css only)": "Riavvia Gradio e aggiorna i componenti (solo script personalizzati, ui.py, js e css)",
- "Installed": "Installato",
- "Install from URL": "Installa da URL",
- "Apply and restart UI": "Applica e riavvia l'interfaccia utente",
- "Check for updates": "Controlla aggiornamenti",
- "Extension": "Estensione",
- "URL": "URL",
- "Update": "Aggiorna",
- "aesthetic-gradients": "Gradienti Estetici (CLIP)",
- "https://github.com/AUTOMATIC1111/stable-diffusion-webui-aesthetic-gradients": "https://github.com/AUTOMATIC1111/stable-diffusion-webui-aesthetic-gradients",
- "unknown": "sconosciuto",
- "aesthetic-image-scorer": "Punteggio delle immagini estetiche",
- "https://github.com/tsngo/stable-diffusion-webui-aesthetic-image-scorer": "https://github.com/tsngo/stable-diffusion-webui-aesthetic-image-scorer",
- "dataset-tag-editor": "Dataset Tag Editor",
- "https://github.com/toshiaki1729/stable-diffusion-webui-dataset-tag-editor.git": "https://github.com/toshiaki1729/stable-diffusion-webui-dataset-tag-editor.git",
- "deforum": "Deforum",
- "https://github.com/deforum-art/deforum-for-automatic1111-webui/": "https://github.com/deforum-art/deforum-for-automatic1111-webui/",
- "stable-diffusion-webui-artists-to-study": "Artisti per studiare",
- "https://github.com/camenduru/stable-diffusion-webui-artists-to-study": "https://github.com/camenduru/stable-diffusion-webui-artists-to-study",
- "stable-diffusion-webui-images-browser": "Galleria immagini",
- "https://github.com/yfszzx/stable-diffusion-webui-images-browser": "https://github.com/yfszzx/stable-diffusion-webui-images-browser",
- "stable-diffusion-webui-inspiration": "Ispirazione",
- "https://github.com/yfszzx/stable-diffusion-webui-inspiration": "https://github.com/yfszzx/stable-diffusion-webui-inspiration",
- "tag-autocomplete": "Autocompletamento etichette",
- "https://github.com/DominikDoom/a1111-sd-webui-tagcomplete.git": "https://github.com/DominikDoom/a1111-sd-webui-tagcomplete.git",
- "wildcards": "Termini Jolly",
- "https://github.com/AUTOMATIC1111/stable-diffusion-webui-wildcards.git": "https://github.com/AUTOMATIC1111/stable-diffusion-webui-wildcards.git",
- "URL for extension's git repository": "URL del repository GIT dell'estensione",
- "Local directory name": "Nome cartella locale",
- "Install": "Installa",
- "Prompt (press Ctrl+Enter or Alt+Enter to generate)": "Prompt (premi Ctrl+Invio o Alt+Invio per generare)",
- "Negative prompt (press Ctrl+Enter or Alt+Enter to generate)": "Prompt negativo (premere Ctrl+Invio o Alt+Invio per generare)",
- "Add a random artist to the prompt.": "Aggiungi un artista casuale al prompt.",
- "Read generation parameters from prompt or last generation if prompt is empty into user interface.": "Leggere i parametri di generazione dal prompt o dall'ultima generazione se il prompt è vuoto ed inserirli nell'interfaccia utente.",
- "Save style": "Salva stile",
- "Apply selected styles to current prompt": "Applica gli stili selezionati al prompt corrente",
- "Stop processing current image and continue processing.": "Interrompe l'elaborazione dell'immagine corrente e continua l'elaborazione.",
- "Stop processing images and return any results accumulated so far.": "Interrompe l'elaborazione delle immagini e restituisce tutti i risultati accumulati finora.",
- "Style to apply; styles have components for both positive and negative prompts and apply to both": "Stile da applicare; gli stili hanno componenti sia per i prompt positivi che per quelli negativi e si applicano a entrambi",
- "Do not do anything special": "Non fa nulla di speciale",
- "Which algorithm to use to produce the image": "Quale algoritmo utilizzare per produrre l'immagine",
- "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps to higher than 30-40 does not help": "Euler Ancestral - molto creativo, si può ottenere un'immagine completamente diversa a seconda del numero di passi, impostare i passi su un valore superiore a 30-40 non aiuta",
- "Denoising Diffusion Implicit Models - best at inpainting": "Denoising Diffusion Implicit Models - il migliore per inpainting",
- "Produce an image that can be tiled.": "Produce un'immagine che può essere piastrellata.",
- "Use a two step process to partially create an image at smaller resolution, upscale, and then improve details in it without changing composition": "Utilizza un processo in due fasi per creare parzialmente un'immagine con una risoluzione inferiore, aumentare la scala e quindi migliorarne i dettagli senza modificare la composizione",
- "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.": "Determina quanto poco l'algoritmo dovrebbe rispettare dovrebbe il contenuto dell'immagine. A 0, non cambierà nulla e a 1 otterrai un'immagine non correlata. Con valori inferiori a 1.0 l'elaborazione richiederà meno passaggi di quelli specificati dalla barra di scorrimento dei passi di campionamento.",
- "How many batches of images to create": "Quanti lotti di immagini generare",
- "How many image to create in a single batch": "Quante immagini generare in un singolo lotto",
- "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results": "Classifier Free Guidance Scale - quanto fortemente l'immagine deve conformarsi al prompt: valori più bassi producono risultati più creativi",
- "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result": "Un valore che determina l'output del generatore di numeri casuali: se create un'immagine con gli stessi parametri e seme di un'altra immagine, otterrete lo stesso risultato",
- "Set seed to -1, which will cause a new random number to be used every time": "Imposta il seme su -1, che farà sì che ogni volta venga utilizzato un nuovo numero casuale",
- "Reuse seed from last generation, mostly useful if it was randomed": "Riusa il seme dell'ultima generazione, utile soprattutto se casuale",
- "Seed of a different picture to be mixed into the generation.": "Seme di un'immagine diversa da miscelare nella generazione.",
- "How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something).": "Quanto è forte la variazione da produrre. A 0, non ci sarà alcun effetto. A 1, otterrai l'intera immagine con il seme della variazione (tranne per i campionatori ancestrali, dove otterrai solo una leggera variazione).",
- "Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution": "Prova a produrre un'immagine simile a quella che sarebbe stata prodotta con lo stesso seme alla risoluzione specificata",
- "This text is used to rotate the feature space of the imgs embs": "Questo testo viene utilizzato per ruotare lo spazio delle funzioni delle immagini incorporate",
- "How many times to repeat processing an image and using it as input for the next iteration": "Quante volte ripetere l'elaborazione di un'immagine e utilizzarla come input per l'iterazione successiva",
- "Hello, StylePile here.\nUntil some weird bug gets fixed you will see this even if the script itself is not active. Meanwhile, some hints to take your artwork to new heights:\nUse the 'Focus on' dropdown to select complex presets. Toggle selections below (with or without Focus) to affect your results. Mix and match to get some interesting results. \nAnd some general Stable Diffusion tips that will take your designs to next level:\nYou can add parenthesis to make parts of the prompt stronger. So (((cute))) kitten will make it extra cute (try it out). This is alsow important if a style is affecting your original prompt too much. Make that prompt stronger by adding parenthesis around it, like this: ((promt)).\nYou can type promts like [A|B] to sequentially use terms one after another on each step. So, like [cat|dog] will produce a hybrid catdog. And [A:B:0.4] to switch to other terms after the first one has been active for a certain percentage of steps. So [cat:dog:0.4] will build a cat 40% of the time and then start turning it into a dog. This needs more steps to work properly.": "Salve, qui è StylePile.\nFinché qualche strano bug non verrà risolto, vedrai questo testo anche se lo script non è attivo. Nel frattempo, alcuni suggerimenti per portare la tua grafica a nuovi livelli:\nUtilizza il menu a discesa 'Focus on' per selezionare valori predefiniti complessi. Attiva o disattiva le selezioni seguenti (con o senza Focus) per influire sui risultati. Mescola e abbina per ottenere risultati interessanti. \nE alcuni suggerimenti generali su Stable Diffusion che porteranno i tuoi risultati a un livello superiore:\nPuoi aggiungere parentesi per aumentare l'influenza di certe parti del prompt. Quindi '(((cute))) kitten' lo renderà molto carino (fai delle prove). Questo è importante quando uno stile influisce troppo sul prompt originale. Rendi più forte quel prompt aggiungendo delle parentesi intorno ad esso, così: ((promt)).\nPuoi digitare prompt nel formato [A|B] per usare in sequenza i termini uno dopo l'altro in ogni passaggio. Quindi, come [cat|dog] produrrà un 'canegatto' ibrido. E [A:B:0.4] per passare ad altri termini dopo che il primo è stato attivo per una certa percentuale di passaggi. Quindi [cat:dog:0.4] genererà un gatto il 40% dei passaggi e poi inizierà a trasformarlo in un cane. Sono richiesti più passaggi perchè funzioni correttamente.",
- "Enter one prompt per line. Blank lines will be ignored.": "Immettere un prompt per riga. Le righe vuote verranno ignorate.",
- "Separate values for X axis using commas.": "Separare i valori per l'asse X usando le virgole.",
- "Separate values for Y axis using commas.": "Separare i valori per l'asse Y usando le virgole.",
- "Separate a list of words with commas, and the script will make a variation of prompt with those words for their every possible order": "Separa un elenco di parole con virgole e lo script eseguirà una variazione di prompt con quelle parole per ogni loro possibile ordine",
- "Write image to a directory (default - log/images) and generation parameters into csv file.": "Salva l'immagine/i in una cartella (predefinita - log/images) ed i parametri di generazione in un file CSV.",
- "Open images output directory": "Apri la cartella di output delle immagini",
- "How much to blur the mask before processing, in pixels.": "Quanto sfocare la maschera prima dell'elaborazione, in pixel.",
- "What to put inside the masked area before processing it with Stable Diffusion.": "Cosa mettere all'interno dell'area mascherata prima di elaborarla con Stable Diffusion.",
- "fill it with colors of the image": "riempi con i colori dell'immagine",
- "keep whatever was there originally": "conserva tutto ciò che c'era in origine",
- "fill it with latent space noise": "riempi di rumore spaziale latente",
- "fill it with latent space zeroes": "riempi con zeri di spazio latente",
- "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image": "Ingrandisce la regione mascherata per raggiungere la risoluzione, esegue la pittura, riduce la scala e incolla nell'immagine originale",
- "Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.": "Ridimensiona l'immagine alla risoluzione di destinazione. A meno che altezza e larghezza non corrispondano, otterrai proporzioni errate.",
- "Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out.": "Ridimensionare l'immagine in modo che l'intera risoluzione di destinazione sia riempita con l'immagine. Ritaglia le parti che sporgono.",
- "Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors.": "Ridimensiona l'immagine in modo che l'intera immagine rientri nella risoluzione di destinazione. Riempi lo spazio vuoto con i colori dell'immagine.",
- "For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam.": "Per l'upscaling SD, quanta sovrapposizione in pixel dovrebbe esserci tra le piastrelle. Le piastrelle si sovrappongono in modo che quando vengono unite nuovamente in un'immagine, non ci siano giunture chiaramente visibili.",
- "Process an image, use it as an input, repeat.": "Elabora un'immagine, usala come input, ripeti.",
- "In loopback mode, on each loop the denoising strength is multiplied by this value. <1 means decreasing variety so your sequence will converge on a fixed picture. >1 means increasing variety so your sequence will become more and more chaotic.": "In modalità rielaborazione ricorsiva, su ogni ciclo la forza di denoising viene moltiplicata per questo valore. <1 significa varietà decrescente in modo che la sequenza converga su un'immagine fissa. >1 significa aumentare la varietà in modo che la tua sequenza diventi sempre più caotica.",
- "A directory on the same machine where the server is running.": "Una cartella sulla stessa macchina su cui è in esecuzione il server.",
- "Leave blank to save images to the default path.": "Lascia vuoto per salvare le immagini nel percorso predefinito.",
- "Result = A * (1 - M) + B * M": "Risultato = A * (1 - M) + B * M",
- "Result = A + (B - C) * M": "Risultato = A + (B - C) * M",
- "1st and last digit must be 1. ex:'1, 2, 1'": "La prima e l'ultima cifra devono essere 1. Es.:'1, 2, 1'",
- "Path to directory with input images": "Percorso della cartella con immagini di input",
- "Path to directory where to write outputs": "Percorso della cartella in cui scrivere i risultati",
- "C:\\directory\\of\\datasets": "C:\\cartella\\del\\dataset",
- "Input images directory": "Cartella di input delle immagini",
- "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; leave empty for default.": "Usa i seguenti tag per definire come vengono scelti i nomi dei file per le immagini: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed ], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; lasciare vuoto per usare l'impostazione predefinita.",
- "If this option is enabled, watermark will not be added to created images. Warning: if you do not add watermark, you may be behaving in an unethical manner.": "Se questa opzione è abilitata, la filigrana non verrà aggiunta alle immagini create. Attenzione: se non aggiungi la filigrana, potresti comportarti in modo non etico.",
- "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; leave empty for default.": "Utilizzare i seguenti tag per definire come vengono scelte le sottodirectory per le immagini e le griglie: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; lasciare vuoto per usare l'impostazione predefinita.",
- "Restore low quality faces using GFPGAN neural network": "Ripristina volti di bassa qualità utilizzando la rete neurale GFPGAN",
- "This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is.": "Questa espressione regolare verrà utilizzata per estrarre le parole dal nome del file e verranno unite utilizzando l'opzione seguente nel testo dell'etichetta utilizzato per l'addestramento. Lascia vuoto per mantenere il testo del nome del file così com'è.",
- "This string will be used to join split words into a single line if the option above is enabled.": "Questa stringa verrà utilizzata per unire le parole divise in un'unica riga se l'opzione sopra è abilitata.",
- "Only applies to inpainting models. Determines how strongly to mask off the original image for inpainting and img2img. 1.0 means fully masked, which is the default behaviour. 0.0 means a fully unmasked conditioning. Lower values will help preserve the overall composition of the image, but will struggle with large changes.": "Si applica solo ai modelli di pittura. Determina con quale forza mascherare l'immagine originale per inpainting e img2img. 1.0 significa completamente mascherato, che è il comportamento predefinito. 0.0 significa un condizionamento completamente non mascherato. Valori più bassi aiuteranno a preservare la composizione generale dell'immagine, ma avranno difficoltà con grandi cambiamenti.",
- "List of setting names, separated by commas, for settings that should go to the quick access bar at the top, rather than the usual setting tab. See modules/shared.py for setting names. Requires restarting to apply.": "Elenco dei nomi delle impostazioni, separati da virgole, per le impostazioni che dovrebbero essere visualizzate nella barra di accesso rapido in alto, anziché nella normale scheda delle impostazioni. Vedi modules/shared.py per impostare i nomi. Richiede il riavvio per applicare.",
- "If this values is non-zero, it will be added to seed and used to initialize RNG for noises when using samplers with Eta. You can use this to produce even more variation of images, or you can use this to match images of other software if you know what you are doing.": "Se questo valore è diverso da zero, verrà aggiunto al seed e utilizzato per inizializzare il generatore di numeri casuali per il rumore quando si utilizzano campionatori con ETA. Puoi usarlo per produrre ancora più variazioni di immagini, oppure puoi usarlo per abbinare le immagini di altri software se sai cosa stai facendo.",
- "Leave empty for auto": "Lasciare vuoto per automatico"
-}
diff --git a/localizations/ja_JP.json b/localizations/ja_JP.json
deleted file mode 100644
index a6cc2477..00000000
--- a/localizations/ja_JP.json
+++ /dev/null
@@ -1,482 +0,0 @@
-{
- "⤡": "⤡",
- "⊞": "⊞",
- "×": "×",
- "❮": "❮",
- "❯": "❯",
- "Loading...": "読み込み中...",
- "view": "view",
- "api": "api",
- "•": "•",
- "gradioで作ろう": "gradioで作ろう",
- "Stable Diffusion checkpoint": "Stable Diffusion checkpoint",
- "Stop At last layers of CLIP model": "最後から何層目でCLIPを止めるか",
- "txt2img": "txt2img",
- "img2img": "img2img",
- "Extras": "その他",
- "PNG Info": "PNG内の情報を表示",
- "Image Browser": "画像閲覧",
- "Checkpoint Merger": "Checkpointの統合",
- "Train": "学習",
- "Create aesthetic embedding": "aesthetic embeddingを作る",
- "Settings": "設定",
- "Prompt": "プロンプト",
- "Negative prompt": "ネガティブ プロンプト",
- "Run": "実行",
- "Skip": "スキップ",
- "Interrupt": "中断",
- "Generate": "生成!",
- "Style 1": "スタイル 1",
- "Style 2": "スタイル 2",
- "Label": "ラベル",
- "File": "ファイル",
- "ここにファイルをドロップ": "ここにファイルをドロップ",
- "-": "-",
- "または": "または",
- "クリックしてアップロード": "クリックしてアップロード",
- "Image": "画像",
- "Check progress": "Check progress",
- "Check progress (first)": "Check progress (first)",
- "Sampling Steps": "サンプリング回数",
- "Sampling method": "サンプリングアルゴリズム",
- "Euler a": "Euler a",
- "Euler": "Euler",
- "LMS": "LMS",
- "Heun": "Heun",
- "DPM2": "DPM2",
- "DPM2 a": "DPM2 a",
- "DPM fast": "DPM fast",
- "DPM adaptive": "DPM adaptive",
- "LMS Karras": "LMS Karras",
- "DPM2 Karras": "DPM2 Karras",
- "DPM2 a Karras": "DPM2 a Karras",
- "DDIM": "DDIM",
- "PLMS": "PLMS",
- "Width": "幅",
- "Height": "高さ",
- "Restore faces": "顔修復",
- "Tiling": "テクスチャ生成モード",
- "Highres. fix": "高解像度 fix(マウスオーバーで詳細)",
- "Firstpass width": "Firstpass width",
- "Firstpass height": "Firstpass height",
- "Denoising strength": "ノイズ除去強度",
- "Batch count": "バッチ生成回数",
- "Batch size": "バッチあたり生成枚数",
- "CFG Scale": "CFG Scale",
- "Seed": "シード値",
- "Extra": "その他",
- "Variation seed": "Variation シード値",
- "Variation strength": "Variation 強度",
- "Resize seed from width": "Resize seed from width",
- "Resize seed from height": "Resize seed from height",
- "Open for Clip Aesthetic!": "Open for Clip Aesthetic!",
- "▼": "▼",
- "Aesthetic weight": "Aesthetic weight",
- "Aesthetic steps": "Aesthetic steps",
- "Aesthetic learning rate": "Aesthetic learning rate",
- "Slerp interpolation": "Slerp interpolation",
- "Aesthetic imgs embedding": "Aesthetic imgs embedding",
- "None": "なし",
- "Aesthetic text for imgs": "Aesthetic text for imgs",
- "Slerp angle": "Slerp angle",
- "Is negative text": "Is negative text",
- "Script": "スクリプト",
- "Prompt matrix": "Prompt matrix",
- "Prompts from file or textbox": "Prompts from file or textbox",
- "Save steps of the sampling process to files": "Save steps of the sampling process to files",
- "X/Y plot": "X/Y plot",
- "Put variable parts at start of prompt": "Put variable parts at start of prompt",
- "Show Textbox": "Show Textbox",
- "File with inputs": "File with inputs",
- "Prompts": "プロンプト",
- "Save images to path": "Save images to path",
- "X type": "X軸の種類",
- "Nothing": "なし",
- "Var. seed": "Var. seed",
- "Var. strength": "Var. 強度",
- "Steps": "ステップ数",
- "Prompt S/R": "Prompt S/R",
- "Prompt order": "Prompt order",
- "Sampler": "サンプラー",
- "Checkpoint name": "Checkpoint名",
- "Hypernetwork": "Hypernetwork",
- "Hypernet str.": "Hypernetの強度",
- "Sigma Churn": "Sigma Churn",
- "Sigma min": "Sigma min",
- "Sigma max": "Sigma max",
- "Sigma noise": "Sigma noise",
- "Eta": "Eta",
- "Clip skip": "Clip skip",
- "Denoising": "Denoising",
- "X values": "Xの値",
- "Y type": "Y軸の種類",
- "Y values": "Yの値",
- "Draw legend": "凡例を描画",
- "Include Separate Images": "Include Separate Images",
- "Keep -1 for seeds": "シード値を-1で固定",
- "ここに画像をドロップ": "ここに画像をドロップ",
- "Save": "保存",
- "Send to img2img": "img2imgに送る",
- "Send to inpaint": "描き直しに送る",
- "Send to extras": "その他タブに送る",
- "Make Zip when Save?": "保存するときZipも同時に作る",
- "Textbox": "Textbox",
- "Interrogate\nCLIP": "Interrogate\nCLIP",
- "Interrogate\nDeepBooru": "Interrogate\nDeepBooru",
- "Inpaint": "描き直し(Inpaint)",
- "Batch img2img": "Batch img2img",
- "Image for img2img": "Image for img2img",
- "Image for inpainting with mask": "Image for inpainting with mask",
- "Mask": "マスク",
- "Mask blur": "マスクぼかし",
- "Mask mode": "マスクモード",
- "Draw mask": "マスクをかける",
- "Upload mask": "マスクをアップロードする",
- "Masking mode": "マスキング方法",
- "Inpaint masked": "マスクされた場所を描き直す",
- "Inpaint not masked": "マスクされていない場所を描き直す",
- "Masked content": "マスクされたコンテンツ",
- "fill": "埋める",
- "original": "オリジナル",
- "latent noise": "潜在空間でのノイズ",
- "latent nothing": "潜在空間での無",
- "Inpaint at full resolution": "フル解像度で描き直す",
- "Inpaint at full resolution padding, pixels": "フル解像度で描き直す際のパディング数。px単位。",
- "Process images in a directory on the same machine where the server is running.": "サーバーが稼働しているマシンと同じフォルダにある画像を処理します",
- "Use an empty output directory to save pictures normally instead of writing to the output directory.": "\"出力フォルダ\"を空にすると、通常の画像と同様に保存されます。",
- "Input directory": "入力フォルダ",
- "Output directory": "出力フォルダ",
- "Resize mode": "リサイズモード",
- "Just resize": "リサイズのみ",
- "Crop and resize": "切り取ってからリサイズ",
- "Resize and fill": "リサイズして埋める",
- "img2img alternative test": "img2img alternative test",
- "Loopback": "ループバック",
- "Outpainting mk2": "Outpainting mk2",
- "Poor man's outpainting": "Poor man's outpainting",
- "SD upscale": "SD アップスケール",
- "[C] Video to video": "[C] Video to video",
- "should be 2 or lower.": "2以下にすること",
- "Override `Sampling method` to Euler?(this method is built for it)": "サンプリングアルゴリズムをEulerに上書きする(そうすることを前提に設計されています)",
- "Override `prompt` to the same value as `original prompt`?(and `negative prompt`)": "プロンプトをオリジナルプロンプトと同じ値に上書きする(ネガティブプロンプトも同様)",
- "Original prompt": "オリジナルのプロンプト",
- "Original negative prompt": "オリジナルのネガティブプロンプト",
- "Override `Sampling Steps` to the same value as `Decode steps`?": "サンプリング数をデコードステップ数と同じ値に上書きする",
- "Decode steps": "デコードステップ数",
- "Override `Denoising strength` to 1?": "ノイズ除去強度を1に上書きする",
- "Decode CFG scale": "Decode CFG scale",
- "Randomness": "ランダム性",
- "Sigma adjustment for finding noise for image": "Sigma adjustment for finding noise for image",
- "Loops": "ループ数",
- "Denoising strength change factor": "Denoising strength change factor",
- "Recommended settings: Sampling Steps: 80-100, Sampler: Euler a, Denoising strength: 0.8": "推奨設定: サンプリング回数: 80-100, サンプリングアルゴリズム: Euler a, ノイズ除去強度: 0.8",
- "Pixels to expand": "Pixels to expand",
- "Outpainting direction": "Outpainting direction",
- "left": "左",
- "right": "右",
- "up": "上",
- "down": "下",
- "Fall-off exponent (lower=higher detail)": "Fall-off exponent (lower=higher detail)",
- "Color variation": "Color variation",
- "Will upscale the image to twice the dimensions; use width and height sliders to set tile size": "画像を2倍の大きさにアップスケールします。幅と高さのスライダーでタイルの大きさを設定します。",
- "Tile overlap": "Tile overlap",
- "Upscaler": "アップスケーラー",
- "Lanczos": "Lanczos",
- "LDSR": "LDSR",
- "ESRGAN_4x": "ESRGAN_4x",
- "R-ESRGAN General 4xV3": "R-ESRGAN General 4xV3",
- "R-ESRGAN General WDN 4xV3": "R-ESRGAN General WDN 4xV3",
- "R-ESRGAN AnimeVideo": "R-ESRGAN AnimeVideo",
- "R-ESRGAN 4x+": "R-ESRGAN 4x+",
- "R-ESRGAN 4x+ Anime6B": "R-ESRGAN 4x+ Anime6B",
- "R-ESRGAN 2x+": "R-ESRGAN 2x+",
- "ScuNET GAN": "ScuNET GAN",
- "ScuNET PSNR": "ScuNET PSNR",
- "SwinIR 4x": "SwinIR 4x",
- "Input file path": "Input file path",
- "CRF (quality, less is better, x264 param)": "CRF (quality, less is better, x264 param)",
- "FPS": "FPS",
- "Seed step size": "Seed step size",
- "Seed max distance": "Seed max distance",
- "Start time": "Start time",
- "End time": "End time",
- "Single Image": "単一画像",
- "Batch Process": "バッチ処理",
- "Batch from Directory": "フォルダからバッチ処理",
- "Source": "入力",
- "Show result images": "出力画像を表示",
- "Scale by": "倍率指定",
- "Scale to": "解像度指定",
- "Resize": "倍率",
- "Crop to fit": "合うように切り抜き",
- "Upscaler 2 visibility": "Upscaler 2 visibility",
- "GFPGAN visibility": "GFPGAN visibility",
- "CodeFormer visibility": "CodeFormer visibility",
- "CodeFormer weight (0 = maximum effect, 1 = minimum effect)": "CodeFormerの重み (注:0で最大、1で最小)",
- "Open output directory": "出力フォルダを開く",
- "Send to txt2img": "txt2imgに送る",
- "extras": "その他タブ",
- "favorites": "お気に入り",
- "Load": "読み込み",
- "Images directory": "フォルダ",
- "Prev batch": "前の batch",
- "Next batch": "次の batch",
- "First Page": "最初のぺージへ",
- "Prev Page": "前ページへ",
- "Page Index": "ページ番号",
- "Next Page": "次ページへ",
- "End Page": "最後のページへ",
- "number of images to delete consecutively next": "次の削除で一度に削除する画像数",
- "Delete": "削除",
- "Generate Info": "生成情報",
- "File Name": "ファイル名",
- "Collect": "保存(お気に入り)",
- "Refresh page": "ページを更新",
- "Date to": "Date to",
- "Number": "Number",
- "set_index": "set_index",
- "Checkbox": "Checkbox",
- "A merger of the two checkpoints will be generated in your": "統合されたチェックポイントはあなたの",
- "checkpoint": "checkpoint",
- "directory.": "フォルダに保存されます.",
- "Primary model (A)": "1つめのmodel (A)",
- "Secondary model (B)": "2つめのmodel (B)",
- "Tertiary model (C)": "3つめのmodel (C)",
- "Custom Name (Optional)": "Custom Name (任意)",
- "Multiplier (M) - set to 0 to get model A": "Multiplier (M) 0にすると完全にmodel Aとなります (ツールチップ参照)",
- "Interpolation Method": "混合(Interpolation)方式",
- "Weighted sum": "加重平均",
- "Add difference": "差を加える",
- "Save as float16": "float16で保存",
- "See": "詳細な説明については",
- "wiki": "wiki",
- "for detailed explanation.": "を見てください。",
- "Create embedding": "Embeddingを作る",
- "Create hypernetwork": "Hypernetworkを作る",
- "Preprocess images": "画像の前処理",
- "Name": "名称",
- "Initialization text": "Initialization text",
- "Number of vectors per token": "Number of vectors per token",
- "Overwrite Old Embedding": "古いEmbeddingを上書き",
- "Modules": "モジュール",
- "Enter hypernetwork layer structure": "Hypernetworkのレイヤー構造を入力",
- "Select activation function of hypernetwork": "Hypernetworkの活性化関数",
- "linear": "linear",
- "relu": "relu",
- "leakyrelu": "leakyrelu",
- "elu": "elu",
- "swish": "swish",
- "Add layer normalization": "Add layer normalization",
- "Use dropout": "Use dropout",
- "Overwrite Old Hypernetwork": "古いHypernetworkを上書きする",
- "Source directory": "入力フォルダ",
- "Destination directory": "出力フォルダ",
- "Existing Caption txt Action": "既存のキャプションの取り扱い",
- "ignore": "無視する",
- "copy": "コピーする",
- "prepend": "先頭に加える",
- "append": "末尾に加える",
- "Create flipped copies": "反転画像を生成する",
- "Split oversized images": "大きすぎる画像を分割する",
- "Use BLIP for caption": "BLIPで説明をつける",
- "Use deepbooru for caption": "deepbooruで説明をつける",
- "Split image threshold": "分割する大きさの閾値",
- "Split image overlap ratio": "Split image overlap ratio",
- "Preprocess": "前処理開始",
- "Train an embedding or Hypernetwork; you must specify a directory with a set of 1:1 ratio images": "EmbeddingまたはHypernetworkを学習します。1:1の比率の画像セットを含むフォルダを指定する必要があります。",
- "[wiki]": "[wiki]",
- "Embedding": "Embedding",
- "Embedding Learning rate": "Embeddingの学習率(Learning rate)",
- "Hypernetwork Learning rate": "Hypernetworkの学習率(Learning rate)",
- "Dataset directory": "データセットフォルダ",
- "Log directory": "ログフォルダ",
- "Prompt template file": "プロンプトのテンプレートファイル",
- "Max steps": "最大ステップ数",
- "Save an image to log directory every N steps, 0 to disable": "指定したステップ数ごとに画像を生成し、ログに保存する。0で無効化。",
- "Save a copy of embedding to log directory every N steps, 0 to disable": "指定したステップ数ごとにEmbeddingのコピーをログに保存する。0で無効化。",
- "Save images with embedding in PNG chunks": "保存する画像にembeddingを埋め込む",
- "Read parameters (prompt, etc...) from txt2img tab when making previews": "プレビューの作成にtxt2imgタブから読み込んだパラメータ(プロンプトなど)を使う",
- "Train Hypernetwork": "Hypernetworkの学習を開始",
- "Train Embedding": "Embeddingの学習を開始",
- "Create an aesthetic embedding out of any number of images": "Create an aesthetic embedding out of any number of images",
- "Create images embedding": "Create images embedding",
- "Apply settings": "設定を適用",
- "Saving images/grids": "画像/グリッドの保存",
- "Always save all generated images": "生成された画像をすべて保存する",
- "File format for images": "画像ファイルの保存形式",
- "Images filename pattern": "ファイル名のパターン",
- "Always save all generated image grids": "グリッド画像を常に保存する",
- "File format for grids": "グリッド画像の保存形式",
- "Add extended info (seed, prompt) to filename when saving grid": "保存するグリッド画像のファイル名に追加情報(シード値、プロンプト)を加える",
- "Do not save grids consisting of one picture": "1画像からなるグリッド画像は保存しない",
- "Prevent empty spots in grid (when set to autodetect)": "(自動設定のとき)グリッドに空隙が生じるのを防ぐ",
- "Grid row count; use -1 for autodetect and 0 for it to be same as batch size": "グリッドの列数; -1で自動設定、0でバッチ生成回数と同じにする",
- "Save text information about generation parameters as chunks to png files": "生成に関するパラメーターをPNG画像に含める",
- "Create a text file next to every image with generation parameters.": "保存する画像とともに生成パラメータをテキストファイルで保存する",
- "Save a copy of image before doing face restoration.": "顔修復を行う前にコピーを保存しておく。",
- "Quality for saved jpeg images": "JPG保存時の画質",
- "If PNG image is larger than 4MB or any dimension is larger than 4000, downscale and save copy as JPG": "PNG画像が4MBを超えるか、どちらか1辺の長さが4000を超えたなら、ダウンスケールしてコピーを別にJPGで保存する",
- "Use original name for output filename during batch process in extras tab": "その他タブでバッチ処理をする際、元のファイル名を出力ファイル名に使う",
- "When using 'Save' button, only save a single selected image": "\"保存\"ボタンを使うとき、単一の選択された画像のみを保存する",
- "Do not add watermark to images": "電子透かしを画像に追加しない",
- "Paths for saving": "保存する場所",
- "Output directory for images; if empty, defaults to three directories below": "画像の保存先フォルダ(下項目のデフォルト値になります)",
- "Output directory for txt2img images": "txt2imgで作った画像の保存先フォルダ",
- "Output directory for img2img images": "img2imgで作った画像の保存先フォルダ",
- "Output directory for images from extras tab": "その他タブで作った画像の保存先フォルダ",
- "Output directory for grids; if empty, defaults to two directories below": "画像の保存先フォルダ(下項目のデフォルト値になります)",
- "Output directory for txt2img grids": "txt2imgで作ったグリッドの保存先フォルダ",
- "Output directory for img2img grids": "img2imgで作ったグリッドの保存先フォルダ",
- "Directory for saving images using the Save button": "保存ボタンを押したときの画像の保存先フォルダ",
- "Saving to a directory": "フォルダについて",
- "Save images to a subdirectory": "画像をサブフォルダに保存する",
- "Save grids to a subdirectory": "グリッドをサブフォルダに保存する",
- "When using \"Save\" button, save images to a subdirectory": "保存ボタンを押した時、画像をサブフォルダに保存する",
- "Directory name pattern": "フォルダ名のパターン",
- "Max prompt words for [prompt_words] pattern": "Max prompt words for [prompt_words] pattern",
- "Upscaling": "アップスケール",
- "Tile size for ESRGAN upscalers. 0 = no tiling.": "ESRGANのタイルサイズ。0とするとタイルしない。",
- "Tile overlap, in pixels for ESRGAN upscalers. Low values = visible seam.": "ESRGANのタイルの重複部分のピクセル数。少なくするとつなぎ目が見えやすくなる。",
- "Tile size for all SwinIR.": "SwinIRのタイルサイズ",
- "Tile overlap, in pixels for SwinIR. Low values = visible seam.": "SwinIRのタイルの重複部分のピクセル数。少なくするとつなぎ目が見えやすくなる。",
- "LDSR processing steps. Lower = faster": "LDSR processing steps. Lower = faster",
- "Upscaler for img2img": "img2imgで使うアップスケーラー",
- "Upscale latent space image when doing hires. fix": "高解像度 fix時に潜在空間(latent space)の画像をアップスケールする",
- "Face restoration": "顔修復",
- "CodeFormer weight parameter; 0 = maximum effect; 1 = minimum effect": "CodeFormerの重みパラメーター;0が最大で1が最小",
- "Move face restoration model from VRAM into RAM after processing": "処理終了後、顔修復モデルをVRAMからRAMへと移動する",
- "System": "システム設定",
- "VRAM usage polls per second during generation. Set to 0 to disable.": "生成中のVRAM使用率の取得間隔。0にすると取得しない。",
- "Always print all generation info to standard output": "常にすべての生成に関する情報を標準出力(stdout)に出力する",
- "Add a second progress bar to the console that shows progress for an entire job.": "ジョブ全体の進捗をコンソールに表示する2つ目のプログレスバーを追加する",
- "Training": "学習",
- "Move VAE and CLIP to RAM when training hypernetwork. Saves VRAM.": "hypernetworkの学習をするとき、VAEとCLIPをRAMへ退避する。VRAMが節約できます。",
- "Filename word regex": "ファイル名の正規表現(学習用)",
- "Filename join string": "ファイル名の結合子",
- "Number of repeats for a single input image per epoch; used only for displaying epoch number": "Number of repeats for a single input image per epoch; used only for displaying epoch number",
- "Save an csv containing the loss to log directory every N steps, 0 to disable": "Save an csv containing the loss to log directory every N steps, 0 to disable",
- "Stable Diffusion": "Stable Diffusion",
- "Checkpoints to cache in RAM": "RAMにキャッシュするCheckpoint数",
- "Hypernetwork strength": "Hypernetwork strength",
- "Apply color correction to img2img results to match original colors.": "元画像に合わせてimg2imgの結果を色補正する",
- "Save a copy of image before applying color correction to img2img results": "色補正をする前の画像も保存する",
- "With img2img, do exactly the amount of steps the slider specifies (normally you'd do less with less denoising).": "img2imgでスライダーで指定されたステップ数を正確に実行する(通常は、ノイズ除去を少なくするためにより少ないステップ数で実行します)。",
- "Enable quantization in K samplers for sharper and cleaner results. This may change existing seeds. Requires restart to apply.": "より良い結果を得るために、Kサンプラーで量子化を有効にします。これにより既存のシードが変更される可能性があります。適用するには再起動が必要です。",
- "Emphasis: use (text) to make model pay more attention to text and [text] to make it pay less attention": "強調: (text)とするとモデルはtextをより強く扱い、[text]とするとモデルはtextをより弱く扱います。",
- "Use old emphasis implementation. Can be useful to reproduce old seeds.": "古い強調の実装を使う。古い生成物を再現するのに使えます。",
- "Make K-diffusion samplers produce same images in a batch as when making a single image": "K-diffusionサンプラーによるバッチ生成時に、単一画像生成時と同じ画像を生成する",
- "Increase coherency by padding from the last comma within n tokens when using more than 75 tokens": "75トークン以上を使用する場合、nトークン内の最後のカンマからパディングして一貫性を高める",
- "Filter NSFW content": "NSFW(≒R-18)なコンテンツを検閲する",
- "Interrogate Options": "Interrogate 設定",
- "Interrogate: keep models in VRAM": "Interrogate: モデルをVRAMに保持する",
- "Interrogate: use artists from artists.csv": "Interrogate: artists.csvにある芸術家などの名称を利用する",
- "Interrogate: include ranks of model tags matches in results (Has no effect on caption-based interrogators).": "Interrogate: include ranks of model tags matches in results (Has no effect on caption-based interrogators).",
- "Interrogate: num_beams for BLIP": "Interrogate: num_beams for BLIP",
- "Interrogate: minimum description length (excluding artists, etc..)": "Interrogate: minimum description length (excluding artists, etc..)",
- "Interrogate: maximum description length": "Interrogate: maximum description length",
- "CLIP: maximum number of lines in text file (0 = No limit)": "CLIP: maximum number of lines in text file (0 = No limit)",
- "Interrogate: deepbooru score threshold": "Interrogate: deepbooruで拾う単語のスコア閾値",
- "Interrogate: deepbooru sort alphabetically": "Interrogate: deepbooruで単語をアルファベット順に並べる",
- "use spaces for tags in deepbooru": "deepbooruのタグでスペースを使う",
- "escape (\\) brackets in deepbooru (so they are used as literal brackets and not for emphasis)": "deepbooruで括弧をエスケープする(\\) (強調を示す()ではなく、文字通りの()であることをモデルに示すため)",
- "User interface": "UI設定",
- "Show progressbar": "プログレスバーを表示",
- "Show image creation progress every N sampling steps. Set 0 to disable.": "指定したステップ数ごとに画像の生成過程を表示する。0で無効化。",
- "Show previews of all images generated in a batch as a grid": "Show previews of all images generated in a batch as a grid",
- "Show grid in results for web": "WebUI上でグリッド表示",
- "Do not show any images in results for web": "WebUI上で一切画像を表示しない",
- "Add model hash to generation information": "モデルのハッシュ値を生成情報に追加",
- "Add model name to generation information": "モデルの名称を生成情報に追加",
- "When reading generation parameters from text into UI (from PNG info or pasted text), do not change the selected model/checkpoint.": "テキストからUIに生成パラメータを読み込む場合(PNG情報または貼り付けられたテキストから)、選択されたモデル/チェックポイントは変更しない。",
- "Font for image grids that have text": "画像グリッド内のテキストフォント",
- "Enable full page image viewer": "フルページの画像ビューワーを有効化",
- "Show images zoomed in by default in full page image viewer": "フルページ画像ビューアでデフォルトで画像を拡大して表示する",
- "Show generation progress in window title.": "ウィンドウのタイトルで生成の進捗を表示",
- "Quicksettings list": "クイック設定",
- "Localization (requires restart)": "言語 (プログラムの再起動が必要)",
- "ja_JP": "ja_JP",
- "ru_RU": "ru_RU",
- "Sampler parameters": "サンプラー parameters",
- "Hide samplers in user interface (requires restart)": "使わないサンプリングアルゴリズムを隠す (再起動が必要)",
- "eta (noise multiplier) for DDIM": "DDIMで用いるeta (noise multiplier)",
- "eta (noise multiplier) for ancestral samplers": "ancestral サンプラーで用いるeta (noise multiplier)",
- "img2img DDIM discretize": "img2img DDIM discretize",
- "uniform": "uniform",
- "quad": "quad",
- "sigma churn": "sigma churn",
- "sigma tmin": "sigma tmin",
- "sigma noise": "sigma noise",
- "Eta noise seed delta": "Eta noise seed delta",
- "Images Browser": "画像閲覧",
- "Preload images at startup": "起動時に画像を読み込んでおく",
- "Number of pictures displayed on each page": "各ページに表示される画像の枚数",
- "Minimum number of pages per load": "Minimum number of pages per load",
- "Number of grids in each row": "Number of grids in each row",
- "Request browser notifications": "ブラウザ通知の許可を要求する",
- "Download localization template": "ローカライゼーション用のテンプレートをダウンロードする",
- "Reload custom script bodies (No ui updates, No restart)": "カスタムスクリプトを再読み込み (UIは変更されず、再起動もしません。)",
- "Restart Gradio and Refresh components (Custom Scripts, ui.py, js and css only)": "Gradioを再起動してコンポーネントをリフレッシュする (Custom Scripts, ui.py, js, cssのみ影響を受ける)",
- "Audio": "音声",
- "Prompt (press Ctrl+Enter or Alt+Enter to generate)": "プロンプト (Ctrl+Enter か Alt+Enter を押して生成)",
- "Negative prompt (press Ctrl+Enter or Alt+Enter to generate)": "ネガティブ プロンプト (Ctrl+Enter か Alt+Enter を押して生成)",
- "Add a random artist to the prompt.": "芸術家などの名称をプロンプトに追加",
- "Read generation parameters from prompt or last generation if prompt is empty into user interface.": "プロンプトから生成パラメータを読み込むか、プロンプトが空の場合は最後の生成パラメータをユーザーインターフェースに読み込む。",
- "Save style": "スタイルを保存する",
- "Apply selected styles to current prompt": "現在のプロンプトに選択したスタイルを適用する",
- "Stop processing current image and continue processing.": "現在の処理を中断し、その後の処理は続ける",
- "Stop processing images and return any results accumulated so far.": "処理を中断し、それまでに出来た結果を表示する",
- "Style to apply; styles have components for both positive and negative prompts and apply to both": "適用するスタイル。スタイルは、ポジティブプロンプトとネガティブプロンプトの両方のコンポーネントを持ち、両方に適用される。",
- "Do not do anything special": "特別なことをなにもしない",
- "Which algorithm to use to produce the image": "どのアルゴリズムを使って生成するか",
- "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps to higher than 30-40 does not help": "Euler Ancestral - 非常に独創的で、ステップ数によって全く異なる画像が得られる、ステップ数を30~40より高く設定しても効果がない。",
- "Denoising Diffusion Implicit Models - best at inpainting": "Denoising Diffusion Implicit Models - 描き直しには最適",
- "Produce an image that can be tiled.": "タイルとして扱える画像を生成する",
- "Use a two step process to partially create an image at smaller resolution, upscale, and then improve details in it without changing composition": "2ステップで、まず部分的に小さい解像度で画像を作成し、その後アップスケールすることで、構図を変えずにディテールが改善されます。",
- "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.": "アルゴリズムが画像の内容をどの程度参考にするかを決定します。0 にすると何も変わりませんし、 1 にすると全く無関係な画像になります。1.0未満の値ではスライダーで指定したサンプリングステップ数よりも少ないステップ数で処理が行われます。",
- "How many batches of images to create": "バッチ処理を何回行うか",
- "How many image to create in a single batch": "1回のバッチ処理で何枚の画像を生成するか",
- "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results": "Classifier Free Guidance Scale - 生成する画像がどの程度プロンプトに沿ったものになるか。 - 低い値の方がよりクリエイティブな結果を生み出します。",
- "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result": "乱数発生器の出力を決定する値。同じパラメータとシードで画像を作成すれば、同じ結果が得られます。",
- "Set seed to -1, which will cause a new random number to be used every time": "シード値を-1に設定。つまり、毎回ランダムに生成します。",
- "Reuse seed from last generation, mostly useful if it was randomed": "前回生成時のシード値を読み出す。(ランダム生成時に便利)",
- "Seed of a different picture to be mixed into the generation.": "生成時に混合されることになる画像のシード値",
- "How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something).": "Variationの強度。0の場合、何の効果もありません。1では、バリエーションシードで完全な画像を得ることができます(Ancestalなアルゴリズム以外では、何か(?)を得るだけです)。",
- "Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution": "同じシードで指定された解像度の似た画像を生成することを試みる。",
- "This text is used to rotate the feature space of the imgs embs": "This text is used to rotate the feature space of the imgs embs",
- "Separate values for X axis using commas.": "X軸に用いる値をカンマ(,)で区切って入力してください。",
- "Separate values for Y axis using commas.": "Y軸に用いる値をカンマ(,)で区切って入力してください。",
- "Write image to a directory (default - log/images) and generation parameters into csv file.": "画像はフォルダ(デフォルト:log/images)に、生成パラメータはcsvファイルに書き出します。",
- "Open images output directory": "画像の出力フォルダを開く",
- "How much to blur the mask before processing, in pixels.": "処理前にどれだけマスクをぼかすか。px単位。",
- "What to put inside the masked area before processing it with Stable Diffusion.": "Stable Diffusionにわたす前にマスクされたエリアに何を書き込むか",
- "fill it with colors of the image": "元画像の色で埋める",
- "keep whatever was there originally": "もともとあったものをそのままにする",
- "fill it with latent space noise": "潜在空間(latent space)におけるノイズで埋める",
- "fill it with latent space zeroes": "潜在空間(latent space)における0で埋める",
- "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image": "マスクされた領域をターゲット解像度にアップスケールし、インペイントを行い、元の解像度にダウンスケールして元の画像に貼り付けます。",
- "Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.": "画像をターゲット解像度にリサイズします。高さと幅が一致しない場合、アスペクト比が正しくなくなります。",
- "Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out.": "対象の解像度に画像をフィットさせます。はみ出た部分は切り取られます。",
- "Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors.": "画像をリサイズして、ターゲット解像度の中に収まるようにします。空白部分は画像の色で埋めます。",
- "How many times to repeat processing an image and using it as input for the next iteration": "何回画像処理を繰り返し、次の反復処理の入力として使用するか",
- "In loopback mode, on each loop the denoising strength is multiplied by this value. <1 means decreasing variety so your sequence will converge on a fixed picture. >1 means increasing variety so your sequence will become more and more chaotic.": "ループバックモードにおいて、各ループでのノイズ除去の強度はこの値によって乗算されます。1より小さければ変化が小さくなっていって、生成される画像は1つの画像に収束します。1より大きいとどんどん変化が大きくなるので、生成される画像はよりカオスになります。",
- "For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam.": "SDアップスケールで、どれだけタイル間の重なりを確保するか(px単位)。タイルの一部を重複させることで、1枚の画像にした時明らかな継ぎ目がなくなります。",
- "A directory on the same machine where the server is running.": "サーバーが稼働しているのと同じマシンのあるフォルダ",
- "Leave blank to save images to the default path.": "空欄でデフォルトの場所へ画像を保存",
- "Input images directory": "Input images directory",
- "Result = A * (1 - M) + B * M": "出力されるモデル = A * (1 - M) + B * M",
- "Result = A + (B - C) * M": "出力されるモデル = A + (B - C) * M",
- "1st and last digit must be 1. ex:'1, 2, 1'": "最初と最後の数字は1でなければなりません。 例:'1, 2, 1'",
- "Path to directory with input images": "入力ファイルのあるフォルダの場所",
- "Path to directory where to write outputs": "出力を書き込むフォルダの場所",
- "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; leave empty for default.": "以下のタグを用いてファイル名パターンを決められます: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; 空白でデフォルト設定。",
- "If this option is enabled, watermark will not be added to created images. Warning: if you do not add watermark, you may be behaving in an unethical manner.": "このオプションを有効にすると、作成された画像にウォーターマークが追加されなくなります。警告:ウォーターマークを追加しない場合、非倫理的な行動とみなされる場合があります。",
- "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; leave empty for default.": "以下のタグを用いてサブフォルダのフォルダ名パターンを決められます: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; 空白でデフォルト設定",
- "Restore low quality faces using GFPGAN neural network": "GFPGANを用いて低クオリティーな顔画像を修復",
- "This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is.": "この正規表現を使ってファイル名から単語を抽出し、以下のオプションで結合して学習用のラベルテキストにします。ファイル名のテキストをそのまま使用する場合は、空白にしてください。",
- "This string will be used to join split words into a single line if the option above is enabled.": "この文字列は、上記のオプションが有効な場合に、分割された単語を1行に結合するために使用されます。",
- "List of setting names, separated by commas, for settings that should go to the quick access bar at the top, rather than the usual setting tab. See modules/shared.py for setting names. Requires restarting to apply.": "上部のクイックアクセスバーに置く設定の設定名をカンマで区切って入力。設定名については modules/shared.py を参照してください。適用するには再起動が必要です。",
- "If this values is non-zero, it will be added to seed and used to initialize RNG for noises when using samplers with Eta. You can use this to produce even more variation of images, or you can use this to match images of other software if you know what you are doing.": "この値が0以外の場合、シードに追加され、Etaでサンプラーを使用する際のノイズ用の乱数生成器を初期化するのに使用されます。これを利用して、さらにバリエーション豊かな画像を作成したり、他のソフトの画像に合わせたりすることができます。",
- "NAIConvert": "NAIから変換",
- "History": "履歴",
- "Enable Autocomplete": "自動補完を有効化"
-} \ No newline at end of file
diff --git a/localizations/ko_KR.json b/localizations/ko_KR.json
deleted file mode 100644
index d152e575..00000000
--- a/localizations/ko_KR.json
+++ /dev/null
@@ -1,577 +0,0 @@
-{
- "×": "×",
- "•": "•",
- "⊞": "⊞",
- "❮": "❮",
- "❯": "❯",
- "⤡": "⤡",
- " images during ": "개의 이미지를 불러왔고, 생성 기간은 ",
- " images in this directory. Loaded ": "개의 이미지가 이 경로에 존재합니다. ",
- " pages": "페이지로 나뉘어 표시합니다.",
- ", divided into ": "입니다. ",
- ". Use Installed tab to restart.": "에 성공적으로 설치하였습니다. 설치된 확장기능 탭에서 UI를 재시작해주세요.",
- "1st and last digit must be 1. ex:'1, 2, 1'": "1st and last digit must be 1. ex:'1, 2, 1'",
- "[wiki]": " [위키] 참조",
- "A directory on the same machine where the server is running.": "WebUI 서버가 돌아가고 있는 디바이스에 존재하는 디렉토리를 선택해 주세요.",
- "A merger of the two checkpoints will be generated in your": "체크포인트들이 병합된 결과물이 당신의",
- "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result": "난수 생성기의 결과물을 지정하는 값 - 동일한 설정값과 동일한 시드를 적용 시, 완전히 똑같은 결과물을 얻게 됩니다.",
- "Action": "작업",
- "Add a random artist to the prompt.": "프롬프트에 랜덤한 작가 추가",
- "Add a second progress bar to the console that shows progress for an entire job.": "콘솔에 전체 작업의 진행도를 보여주는 2번째 프로그레스 바 추가하기",
- "Add difference": "차이점 추가",
- "Add extended info (seed, prompt) to filename when saving grid": "그리드 저장 시 파일명에 추가 정보(시드, 프롬프트) 기입",
- "Add layer normalization": "레이어 정규화(normalization) 추가",
- "Add model hash to generation information": "생성 정보에 모델 해시 추가",
- "Add model name to generation information": "생성 정보에 모델 이름 추가",
- "Add number to filename when saving": "이미지를 저장할 때 파일명에 숫자 추가하기",
- "Aesthetic Gradients": "스타일 그라디언트",
- "Aesthetic Image Scorer": "스타일 이미지 스코어러",
- "Aesthetic imgs embedding": "스타일 이미지 임베딩",
- "Aesthetic learning rate": "스타일 학습 수",
- "Aesthetic steps": "스타일 스텝 수",
- "Aesthetic text for imgs": "스타일 텍스트",
- "Aesthetic weight": "스타일 가중치",
- "Allowed categories for random artists selection when using the Roll button": "랜덤 버튼을 눌러 무작위 작가를 선택할 때 허용된 카테고리",
- "Always print all generation info to standard output": "기본 아웃풋에 모든 생성 정보 항상 출력하기",
- "Always save all generated image grids": "생성된 이미지 그리드 항상 저장하기",
- "Always save all generated images": "생성된 이미지 항상 저장하기",
- "api": "",
- "append": "뒤에 삽입",
- "Append commas": "쉼표 삽입",
- "Apply and restart UI": "적용 후 UI 재시작",
- "Apply color correction to img2img results to match original colors.": "이미지→이미지 결과물이 기존 색상과 일치하도록 색상 보정 적용하기",
- "Apply selected styles to current prompt": "현재 프롬프트에 선택된 스타일 적용",
- "Apply settings": "설정 적용하기",
- "Artists to study": "연구할만한 작가들",
- "Auto focal point crop": "초점 기준 크롭(자동 감지)",
- "Autocomplete options": "자동완성 설정",
- "Available": "지원되는 확장기능 목록",
- "Batch count": "배치 수",
- "Batch from Directory": "저장 경로로부터 여러장 처리",
- "Batch img2img": "이미지→이미지 배치",
- "Batch Process": "이미지 여러장 처리",
- "Batch size": "배치 크기",
- "behind": "최신 아님",
- "BSRGAN 4x": "BSRGAN 4x",
- "built with gradio": "gradio로 제작되었습니다",
- "Calculates aesthetic score for generated images using CLIP+MLP Aesthetic Score Predictor based on Chad Scorer": "Chad 스코어러를 기반으로 한 CLIP+MLP 스타일 점수 예측기를 이용해 생성된 이미지의 스타일 점수를 계산합니다.",
- "Cancel generate forever": "반복 생성 취소",
- "cfg cnt": "CFG 변화 횟수",
- "cfg count": "CFG 변화 횟수",
- "CFG Scale": "CFG 스케일",
- "cfg1 min/max": "CFG1 최소/최대",
- "cfg2 min/max": "CFG2 최소/최대",
- "Check for updates": "업데이트 확인",
- "Check progress": "진행도 체크",
- "Check progress (first)": "진행도 체크 (처음)",
- "checkpoint": " 체크포인트 ",
- "Checkpoint Merger": "체크포인트 병합",
- "Checkpoint name": "체크포인트 이름",
- "Checkpoints to cache in RAM": "RAM에 캐싱할 체크포인트 수",
- "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results": "Classifier Free Guidance Scale - 이미지가 주어진 프롬프트를 얼마나 따를지를 정해주는 수치 - 낮은 값일수록 더 창의적인 결과물이 나옴",
- "Click to Upload": "클릭해서 업로드하기",
- "Clip skip": "클립 건너뛰기",
- "CLIP: maximum number of lines in text file (0 = No limit)": "CLIP : 텍스트 파일 최대 라인 수 (0 = 제한 없음)",
- "CodeFormer visibility": "CodeFormer 가시성",
- "CodeFormer weight (0 = maximum effect, 1 = minimum effect)": "CodeFormer 가중치 (0 = 최대 효과, 1 = 최소 효과)",
- "CodeFormer weight parameter; 0 = maximum effect; 1 = minimum effect": "CodeFormer 가중치 설정값 (0 = 최대 효과, 1 = 최소 효과)",
- "Collect": "즐겨찾기",
- "Color variation": "색깔 다양성",
- "Combinations": "조합",
- "Combinatorial batches": "조합 배치 수",
- "Combinatorial generation": "조합 생성",
- "copy": "복사",
- "Create a grid where images will have different parameters. Use inputs below to specify which parameters will be shared by columns and rows": "서로 다른 설정값으로 생성된 이미지의 그리드를 만듭니다. 아래의 설정으로 가로/세로에 어떤 설정값을 적용할지 선택하세요.",
- "Create a text file next to every image with generation parameters.": "생성된 이미지마다 생성 설정값을 담은 텍스트 파일 생성하기",
- "Create aesthetic images embedding": "스타일 이미지 임베딩 생성하기",
- "Create an embedding from one or few pictures and use it to apply their style to generated images.": "하나 혹은 그 이상의 이미지들로부터 임베딩을 생성해, 그 이미지들의 스타일을 다른 이미지 생성 시 적용할 수 있게 해줍니다.",
- "Create debug image": "디버그 이미지 생성",
- "Create embedding": "임베딩 생성",
- "Create flipped copies": "좌우로 뒤집은 복사본 생성",
- "Create hypernetwork": "하이퍼네트워크 생성",
- "Create images embedding": "이미지 임베딩 생성하기",
- "Crop and resize": "잘라낸 후 리사이징",
- "Crop to fit": "잘라내서 맞추기",
- "custom fold": "커스텀 경로",
- "Custom Name (Optional)": "병합 모델 이름 (선택사항)",
- "Dataset directory": "데이터셋 경로",
- "Dataset Tag Editor": "데이터셋 태그 편집기",
- "date": "생성 일자",
- "DDIM": "DDIM",
- "Decode CFG scale": "디코딩 CFG 스케일",
- "Decode steps": "디코딩 스텝 수",
- "Delete": "삭제",
- "delete next": "선택한 이미지부터 시작해서 삭제할 이미지 갯수",
- "Denoising": "디노이징",
- "Denoising Diffusion Implicit Models - best at inpainting": "Denoising Diffusion Implicit Models - 인페이팅에 뛰어남",
- "Denoising strength": "디노이즈 강도",
- "Denoising strength change factor": "디노이즈 강도 변경 배수",
- "Description": "설명",
- "Destination directory": "결과물 저장 경로",
- "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.": "알고리즘이 얼마나 원본 이미지를 반영할지를 결정하는 수치입니다. 0일 경우 아무것도 바뀌지 않고, 1일 경우 원본 이미지와 전혀 관련없는 결과물을 얻게 됩니다. 1.0 아래의 값일 경우, 설정된 샘플링 스텝 수보다 적은 스텝 수를 거치게 됩니다.",
- "Directory for saving images using the Save button": "저장 버튼을 이용해 저장하는 이미지들의 저장 경로",
- "Directory name pattern": "디렉토리명 패턴",
- "directory.": "저장 경로에 저장됩니다.",
- "Do not add watermark to images": "이미지에 워터마크 추가하지 않기",
- "Do not do anything special": "아무것도 하지 않기",
- "Do not save grids consisting of one picture": "이미지가 1개뿐인 그리드는 저장하지 않기",
- "Do not show any images in results for web": "웹에서 결과창에 아무 이미지도 보여주지 않기",
- "down": "아래쪽",
- "Download": "다운로드",
- "Download localization template": "현지화 템플릿 다운로드",
- "DPM adaptive": "DPM adaptive",
- "DPM fast": "DPM fast",
- "DPM2": "DPM2",
- "DPM2 a": "DPM2 a",
- "DPM2 a Karras": "DPM2 a Karras",
- "DPM2 Karras": "DPM2 Karras",
- "Draw legend": "범례 그리기",
- "Draw mask": "마스크 직접 그리기",
- "Drop File Here": "파일을 끌어 놓으세요",
- "Drop Image Here": "이미지를 끌어 놓으세요",
- "Dropdown": "드롭다운",
- "Dynamic Prompts": "다이나믹 프롬프트",
- "Embedding": "임베딩",
- "Embedding Learning rate": "임베딩 학습률",
- "Emphasis: use (text) to make model pay more attention to text and [text] to make it pay less attention": "강조 : (텍스트)를 이용해 모델의 텍스트에 대한 가중치를 더 강하게 주고 [텍스트]를 이용해 더 약하게 줍니다.",
- "Enable Autocomplete": "태그 자동완성 사용",
- "Enable full page image viewer": "전체 페이지 이미지 뷰어 활성화",
- "Enable quantization in K samplers for sharper and cleaner results. This may change existing seeds. Requires restart to apply.": "더 예리하고 깔끔한 결과물을 위해 K 샘플러들에 양자화를 적용합니다. 존재하는 시드가 변경될 수 있습니다. 재시작이 필요합니다.",
- "End Page": "마지막 페이지",
- "Enter hypernetwork layer structure": "하이퍼네트워크 레이어 구조 입력",
- "Error": "오류",
- "escape (\\) brackets in deepbooru (so they are used as literal brackets and not for emphasis)": "deepbooru에서 괄호를 역슬래시(\\)로 이스케이프 처리하기(가중치 강조가 아니라 실제 괄호로 사용되게 하기 위해)",
- "ESRGAN_4x": "ESRGAN_4x",
- "Eta": "Eta",
- "eta (noise multiplier) for ancestral samplers": "ancestral 샘플러를 위한 eta(노이즈 배수)값",
- "eta (noise multiplier) for DDIM": "DDIM을 위한 eta(노이즈 배수)값",
- "Eta noise seed delta": "Eta 노이즈 시드 변화",
- "Euler": "Euler",
- "Euler a": "Euler a",
- "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps to higher than 30-40 does not help": "Euler Ancestral - 매우 창의적, 스텝 수에 따라 완전히 다른 결과물이 나올 수 있음. 30~40보다 높은 스텝 수는 효과가 미미함",
- "Existing Caption txt Action": "이미 존재하는 캡션 텍스트 처리",
- "Extension": "확장기능",
- "Extension index URL": "확장기능 목록 URL",
- "Extensions": "확장기능",
- "Extra": "고급",
- "Extras": "부가기능",
- "extras": "부가기능",
- "extras history": "부가기능 기록",
- "Face restoration": "얼굴 보정",
- "Face restoration model": "얼굴 보정 모델",
- "Fall-off exponent (lower=higher detail)": "감쇠 지수 (낮을수록 디테일이 올라감)",
- "Favorites": "즐겨찾기",
- "File": "파일",
- "File format for grids": "그리드 이미지 파일 형식",
- "File format for images": "이미지 파일 형식",
- "File Name": "파일 이름",
- "File with inputs": "설정값 파일",
- "Filename join string": "파일명 병합 문자열",
- "Filename word regex": "파일명 정규표현식",
- "fill": "채우기",
- "fill it with colors of the image": "이미지의 색상으로 채우기",
- "fill it with latent space noise": "잠재 공간 노이즈로 채우기",
- "fill it with latent space zeroes": "잠재 공간의 0값으로 채우기",
- "Filter NSFW content": "성인 컨텐츠 필터링하기",
- "First Page": "처음 페이지",
- "Firstpass height": "초기 세로길이",
- "Firstpass width": "초기 가로길이",
- "Fixed seed": "시드 고정",
- "Focal point edges weight": "경계면 가중치",
- "Focal point entropy weight": "엔트로피 가중치",
- "Focal point face weight": "얼굴 가중치",
- "Font for image grids that have text": "텍스트가 존재하는 그리드 이미지의 폰트",
- "for detailed explanation.": "를 참조하십시오.",
- "For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam.": "SD 업스케일링에서 타일 간 몇 픽셀을 겹치게 할지 결정하는 설정값입니다. 타일들이 다시 한 이미지로 합쳐질 때, 눈에 띄는 이음매가 없도록 서로 겹치게 됩니다.",
- "Generate": "생성",
- "Generate forever": "반복 생성",
- "Generate Info": "생성 정보",
- "GFPGAN visibility": "GFPGAN 가시성",
- "Grid row count; use -1 for autodetect and 0 for it to be same as batch size": "그리드 세로줄 수 : -1로 설정 시 자동 감지/0으로 설정 시 배치 크기와 동일",
- "Height": "세로",
- "Heun": "Heun",
- "hide": "api 숨기기",
- "Hide samplers in user interface (requires restart)": "사용자 인터페이스에서 숨길 샘플러 선택(재시작 필요)",
- "Highres. fix": "고해상도 보정",
- "History": "기록",
- "how fast should the training go. Low values will take longer to train, high values may fail to converge (not generate accurate results) and/or may break the embedding (This has happened if you see Loss: nan in the training info textbox. If this happens, you need to manually restore your embedding from an older not-broken backup).\n\nYou can set a single numeric value, or multiple learning rates using the syntax:\n\n rate_1:max_steps_1, rate_2:max_steps_2, ...\n\nEG: 0.005:100, 1e-3:1000, 1e-5\n\nWill train with rate of 0.005 for first 100 steps, then 1e-3 until 1000 steps, then 1e-5 for all remaining steps.": "훈련이 얼마나 빨리 이루어질지 정하는 값입니다. 값이 낮을수록 훈련 시간이 길어지고, 높은 값일수록 정확한 결과를 내는 데 실패하고 임베딩을 망가뜨릴 수 있습니다(임베딩이 망가진 경우에는 훈련 정보 텍스트박스에 손실(Loss) : nan 이라고 출력되게 됩니다. 이 경우에는 망가지지 않은 이전 백업본을 불러와야 합니다).\n\n학습률은 하나의 값으로 설정할 수도 있고, 다음 문법을 사용해 여러 값을 사용할 수도 있습니다 :\n\n학습률_1:최대 스텝수_1, 학습률_2:최대 스텝수_2, ...\n\n예 : 0.005:100, 1e-3:1000, 1e-5\n\n예의 설정값은 첫 100스텝동안 0.005의 학습률로, 그 이후 1000스텝까지는 1e-3으로, 남은 스텝은 1e-5로 훈련하게 됩니다.",
- "How many batches of images to create": "생성할 이미지 배치 수",
- "How many image to create in a single batch": "한 배치당 이미지 수",
- "How many times to improve the generated image iteratively; higher values take longer; very low values can produce bad results": "생성된 이미지를 향상할 횟수; 매우 낮은 값은 만족스럽지 못한 결과물을 출력할 수 있음",
- "How many times to repeat processing an image and using it as input for the next iteration": "이미지를 생성 후 원본으로 몇 번 반복해서 사용할지 결정하는 값",
- "How much to blur the mask before processing, in pixels.": "이미지 생성 전 마스크를 얼마나 블러처리할지 결정하는 값. 픽셀 단위",
- "How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something).": "바리에이션을 얼마나 줄지 정하는 수치 - 0일 경우 아무것도 바뀌지 않고, 1일 경우 바리에이션 시드로부터 생성된 이미지를 얻게 됩니다. (Ancestral 샘플러 제외 - 이 경우에는 좀 다른 무언가를 얻게 됩니다)",
- "Hypernet str.": "하이퍼네트워크 강도",
- "Hypernetwork": "하이퍼네트워크",
- "Hypernetwork Learning rate": "하이퍼네트워크 학습률",
- "Hypernetwork strength": "하이퍼네트워크 강도",
- "If PNG image is larger than 4MB or any dimension is larger than 4000, downscale and save copy as JPG": "PNG 이미지가 4MB보다 크거나 가로 또는 세로길이가 4000보다 클 경우, 다운스케일 후 JPG로 복사본 저장하기",
- "If this option is enabled, watermark will not be added to created images. Warning: if you do not add watermark, you may be behaving in an unethical manner.": "이 옵션이 활성화되면 생성된 이미지에 워터마크가 추가되지 않습니다. 경고 : 워터마크를 추가하지 않는다면, 비윤리적인 행동을 하는 중일지도 모릅니다.",
- "If this values is non-zero, it will be added to seed and used to initialize RNG for noises when using samplers with Eta. You can use this to produce even more variation of images, or you can use this to match images of other software if you know what you are doing.": "이 값이 0이 아니라면, 시드에 해당 값이 더해지고, Eta가 있는 샘플러를 사용할 때 노이즈의 RNG 조정을 위해 해당 값이 사용됩니다. 이 설정으로 더 다양한 이미지를 생성하거나, 잘 알고 계시다면 특정 소프트웨어의 결과값을 재현할 수도 있습니다.",
- "ignore": "무시",
- "Image": "이미지",
- "Image Browser": "이미지 브라우저",
- "Image browser": "이미지 브라우저",
- "Image for img2img": "Image for img2img",
- "Image for inpainting with mask": "마스크로 인페인팅할 이미지",
- "Image not found (may have been already moved)": "이미지를 찾을 수 없습니다 (이미 옮겨졌을 수 있음)",
- "Images Browser": "이미지 브라우저",
- "Images directory": "이미지 경로",
- "Images filename pattern": "이미지 파일명 패턴",
- "img2img": "이미지→이미지",
- "img2img alternative test": "이미지→이미지 대체버전 테스트",
- "img2img DDIM discretize": "이미지→이미지 DDIM 이산화",
- "img2img history": "이미지→이미지 기록",
- "Implements an expressive template language for random or combinatorial prompt generation along with features to support deep wildcard directory structures.": "무작위/조합 프롬프트 생성을 위한 문법과 복잡한 와일드카드 구조를 지원합니다.",
- "In loopback mode, on each loop the denoising strength is multiplied by this value. <1 means decreasing variety so your sequence will converge on a fixed picture. >1 means increasing variety so your sequence will become more and more chaotic.": "루프백 모드에서는 매 루프마다 디노이즈 강도에 이 값이 곱해집니다. 1보다 작을 경우 다양성이 낮아져 결과 이미지들이 고정된 형태로 모일 겁니다. 1보다 클 경우 다양성이 높아져 결과 이미지들이 갈수록 혼란스러워지겠죠.",
- "Include Separate Images": "분리된 이미지 포함하기",
- "Increase coherency by padding from the last comma within n tokens when using more than 75 tokens": "75개보다 많은 토큰을 사용시 마지막 쉼표로부터 N개의 토큰 이내에 패딩을 추가해 통일성 증가시키기",
- "Initialization text": "초기화 텍스트",
- "Inpaint": "인페인트",
- "Inpaint at full resolution": "전체 해상도로 인페인트하기",
- "Inpaint at full resolution padding, pixels": "전체 해상도로 인페인트시 패딩값(픽셀 단위)",
- "Inpaint masked": "마스크만 처리",
- "Inpaint not masked": "마스크 이외만 처리",
- "Inpainting conditioning mask strength": "인페인팅 조절 마스크 강도",
- "Input directory": "인풋 이미지 경로",
- "Input images directory": "이미지 경로 입력",
- "Inspiration": "\"영감\"",
- "Install": "설치",
- "Install from URL": "URL로부터 확장기능 설치",
- "Installed": "설치된 확장기능",
- "Installed into ": "확장기능을 ",
- "Interpolation Method": "보간 방법",
- "Interrogate\nCLIP": "CLIP\n분석",
- "Interrogate\nDeepBooru": "DeepBooru\n분석",
- "Interrogate Options": "분석 설정",
- "Interrogate: deepbooru score threshold": "분석 : deepbooru 점수 임계값",
- "Interrogate: deepbooru sort alphabetically": "분석 : deepbooru 알파벳 순서로 정렬하기",
- "Interrogate: include ranks of model tags matches in results (Has no effect on caption-based interrogators).": "분석 : 결과물에 모델 태그의 랭크 포함하기 (캡션 바탕의 분석기에는 효과 없음)",
- "Interrogate: keep models in VRAM": "분석 : VRAM에 모델 유지하기",
- "Interrogate: maximum description length": "분석 : 설명 최대 길이",
- "Interrogate: minimum description length (excluding artists, etc..)": "분석 : 설명 최소 길이(작가 등등..제외)",
- "Interrogate: num_beams for BLIP": "분석 : BLIP의 num_beams값",
- "Interrogate: use artists from artists.csv": "분석 : artists.csv의 작가들 사용하기",
- "Interrupt": "중단",
- "Is negative text": "네거티브 텍스트일시 체크",
- "Iterate seed every line": "줄마다 시드 반복하기",
- "Just resize": "리사이징",
- "Keep -1 for seeds": "시드값 -1로 유지",
- "keep whatever was there originally": "이미지 원본 유지",
- "keyword": "프롬프트",
- "Label": "라벨",
- "Lanczos": "Lanczos",
- "Last prompt:": "마지막 프롬프트 : ",
- "Last saved hypernetwork:": "마지막으로 저장된 하이퍼네트워크 : ",
- "Last saved image:": "마지막으로 저장된 이미지 : ",
- "latent noise": "잠재 노이즈",
- "latent nothing": "잠재 공백",
- "latest": "최신 버전",
- "LDSR": "LDSR",
- "LDSR processing steps. Lower = faster": "LDSR 스텝 수. 낮은 값 = 빠른 속도",
- "leakyrelu": "leakyrelu",
- "Leave blank to save images to the default path.": "기존 저장 경로에 이미지들을 저장하려면 비워두세요.",
- "Leave empty for auto": "자동 설정하려면 비워두십시오",
- "left": "왼쪽",
- "Lets you edit captions in training datasets.": "훈련에 사용되는 데이터셋의 캡션을 수정할 수 있게 해줍니다.",
- "linear": "linear",
- "List of prompt inputs": "프롬프트 입력 리스트",
- "List of setting names, separated by commas, for settings that should go to the quick access bar at the top, rather than the usual setting tab. See modules/shared.py for setting names. Requires restarting to apply.": "설정 탭이 아니라 상단의 빠른 설정 바에 위치시킬 설정 이름을 쉼표로 분리해서 입력하십시오. 설정 이름은 modules/shared.py에서 찾을 수 있습니다. 재시작이 필요합니다.",
- "LMS": "LMS",
- "LMS Karras": "LMS Karras",
- "Load": "불러오기",
- "Load from:": "URL로부터 불러오기",
- "Loading...": "로딩 중...",
- "Local directory name": "로컬 경로 이름",
- "Localization (requires restart)": "현지화 (재시작 필요)",
- "Log directory": "로그 경로",
- "Loopback": "루프백",
- "Loops": "루프 수",
- "Loss:": "손실(Loss) : ",
- "Magic prompt": "매직 프롬프트",
- "Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution": "동일한 시드 값으로 생성되었을 이미지를 주어진 해상도로 최대한 유사하게 재현합니다.",
- "Make K-diffusion samplers produce same images in a batch as when making a single image": "K-diffusion 샘플러들이 단일 이미지를 생성하는 것처럼 배치에서도 동일한 이미지를 생성하게 하기",
- "Make Zip when Save?": "저장 시 Zip 생성하기",
- "Mask": "마스크",
- "Mask blur": "마스크 블러",
- "Mask mode": "마스크 모드",
- "Masked content": "마스크된 부분",
- "Masking mode": "마스킹 모드",
- "Max prompt words for [prompt_words] pattern": "[prompt_words] 패턴의 최대 프롬프트 단어 수",
- "Max steps": "최대 스텝 수",
- "Minimum number of pages per load": "한번 불러올 때마다 불러올 최소 페이지 수",
- "Modules": "모듈",
- "Move face restoration model from VRAM into RAM after processing": "처리가 완료되면 얼굴 보정 모델을 VRAM에서 RAM으로 옮기기",
- "Move to favorites": "즐겨찾기로 옮기기",
- "Move VAE and CLIP to RAM when training hypernetwork. Saves VRAM.": "하이퍼네트워크 훈련 진행 시 VAE와 CLIP을 RAM으로 옮기기. VRAM이 절약됩니다.",
- "Moved to favorites": "즐겨찾기로 옮겨짐",
- "Multiplier (M) - set to 0 to get model A": "배율 (M) - 0으로 적용하면 모델 A를 얻게 됩니다",
- "Name": "이름",
- "Negative prompt": "네거티브 프롬프트",
- "Negative prompt (press Ctrl+Enter or Alt+Enter to generate)": "네거티브 프롬프트(Prompt) 입력(Ctrl+Enter나 Alt+Enter로 생성 시작)",
- "Next batch": "다음 묶음",
- "Next Page": "다음 페이지",
- "None": "없음",
- "Nothing": "없음",
- "Nothing found in the image.": "Nothing found in the image.",
- "Number of columns on the page": "각 페이지마다 표시할 가로줄 수",
- "Number of grids in each row": "각 세로줄마다 표시될 그리드 수",
- "number of images to delete consecutively next": "연속적으로 삭제할 이미지 수",
- "Number of pictures displayed on each page": "각 페이지에 표시될 이미지 수",
- "Number of repeats for a single input image per epoch; used only for displaying epoch number": "세대(Epoch)당 단일 인풋 이미지의 반복 횟수 - 세대(Epoch) 숫자를 표시하는 데에만 사용됩니다. ",
- "Number of rows on the page": "각 페이지마다 표시할 세로줄 수",
- "Number of vectors per token": "토큰별 벡터 수",
- "Only applies to inpainting models. Determines how strongly to mask off the original image for inpainting and img2img. 1.0 means fully masked, which is the default behaviour. 0.0 means a fully unmasked conditioning. Lower values will help preserve the overall composition of the image, but will struggle with large changes.": "인페인팅 모델에만 적용됩니다. 인페인팅과 이미지→이미지에서 원본 이미지를 얼마나 마스킹 처리할지 결정하는 값입니다. 1.0은 완전히 마스킹함(기본 설정)을 의미하고, 0.0은 완전히 언마스킹된 이미지를 의미합니다. 낮은 값일수록 이미지의 전체적인 구성을 유지하는 데에 도움되겠지만, 변화량이 많을수록 불안정해집니다.",
- "Open for Clip Aesthetic!": "클립 스타일 기능을 활성화하려면 클릭!",
- "Open images output directory": "이미지 저장 경로 열기",
- "Open output directory": "저장 경로 열기",
- "or": "또는",
- "original": "원본 유지",
- "Original negative prompt": "기존 네거티브 프롬프트",
- "Original prompt": "기존 프롬프트",
- "Others": "기타",
- "Outpainting direction": "아웃페인팅 방향",
- "Outpainting mk2": "아웃페인팅 마크 2",
- "Output directory": "이미지 저장 경로",
- "Output directory for grids; if empty, defaults to two directories below": "그리드 이미지 저장 경로 - 비워둘 시 하단의 2가지 기본 경로로 설정됨",
- "Output directory for images from extras tab": "부가기능 탭 저장 경로",
- "Output directory for images; if empty, defaults to three directories below": "이미지 저장 경로 - 비워둘 시 하단의 3가지 기본 경로로 설정됨",
- "Output directory for img2img grids": "이미지→이미지 그리드 저장 경로",
- "Output directory for img2img images": "이미지→이미지 저장 경로",
- "Output directory for txt2img grids": "텍스트→이미지 그리드 저장 경로",
- "Output directory for txt2img images": "텍스트→이미지 저장 경로",
- "Override `Denoising strength` to 1?": "디노이즈 강도를 1로 적용할까요?",
- "Override `prompt` to the same value as `original prompt`?(and `negative prompt`)": "프롬프트 값을 기존 프롬프트와 동일하게 적용할까요?(네거티브 프롬프트 포함)",
- "Override `Sampling method` to Euler?(this method is built for it)": "샘플링 방법을 Euler로 적용할까요?(이 기능은 해당 샘플러를 위해 만들어져 있습니다)",
- "Override `Sampling Steps` to the same value as `Decode steps`?": "샘플링 스텝 수를 디코딩 스텝 수와 동일하게 적용할까요?",
- "Overwrite Old Embedding": "기존 임베딩 덮어쓰기",
- "Overwrite Old Hypernetwork": "기존 하이퍼네트워크 덮어쓰기",
- "Page Index": "페이지 인덱스",
- "parameters": "설정값",
- "path name": "경로 이름",
- "Path to directory where to write outputs": "결과물을 출력할 경로",
- "Path to directory with input images": "인풋 이미지가 있는 경로",
- "Paths for saving": "저장 경로",
- "Pixels to expand": "확장할 픽셀 수",
- "PLMS": "PLMS",
- "PNG Info": "PNG 정보",
- "Poor man's outpainting": "가난뱅이의 아웃페인팅",
- "Preload images at startup": "WebUI 가동 시 이미지 프리로드하기",
- "Preparing dataset from": "준비된 데이터셋 경로 : ",
- "prepend": "앞에 삽입",
- "Preprocess": "전처리",
- "Preprocess images": "이미지 전처리",
- "Prev batch": "이전 묶음",
- "Prev Page": "이전 페이지",
- "Prevent empty spots in grid (when set to autodetect)": "(자동 감지 사용시)그리드에 빈칸이 생기는 것 방지하기",
- "Primary model (A)": "주 모델 (A)",
- "Process an image, use it as an input, repeat.": "이미지를 생성하고, 생성한 이미지를 다시 원본으로 사용하는 과정을 반복합니다.",
- "Process images in a directory on the same machine where the server is running.": "WebUI 서버가 돌아가고 있는 디바이스에 존재하는 디렉토리의 이미지들을 처리합니다.",
- "Produce an image that can be tiled.": "타일링 가능한 이미지를 생성합니다.",
- "Prompt": "프롬프트",
- "Prompt (press Ctrl+Enter or Alt+Enter to generate)": "프롬프트(Prompt) 입력(Ctrl+Enter나 Alt+Enter로 생성 시작)",
- "Prompt matrix": "프롬프트 매트릭스",
- "Prompt order": "프롬프트 순서",
- "Prompt S/R": "프롬프트 스타일 변경",
- "Prompt template file": "프롬프트 템플릿 파일 경로",
- "Prompts": "프롬프트",
- "Prompts from file or textbox": "파일이나 텍스트박스로부터 프롬프트 불러오기",
- "Provides an interface to browse created images in the web browser.": "생성된 이미지를 브라우저 내에서 볼 수 있는 인터페이스를 추가합니다.",
- "Put variable parts at start of prompt": "변경되는 프롬프트를 앞에 위치시키기",
- "quad": "quad",
- "Quality for saved jpeg images": "저장된 jpeg 이미지들의 품질",
- "Quicksettings list": "빠른 설정 리스트",
- "R-ESRGAN 4x+ Anime6B": "R-ESRGAN 4x+ Anime6B",
- "Random": "랜덤",
- "Random grid": "랜덤 그리드",
- "Randomly display the pictures of the artist's or artistic genres typical style, more pictures of this artist or genre is displayed after selecting. So you don't have to worry about how hard it is to choose the right style of art when you create.": "특정 작가 또는 스타일의 이미지들 중 하나를 무작위로 보여줍니다. 선택 후 선택한 작가 또는 스타일의 이미지들이 더 나타나게 됩니다. 고르기 어려워도 걱정하실 필요 없어요!",
- "Randomness": "랜덤성",
- "Read generation parameters from prompt or last generation if prompt is empty into user interface.": "클립보드에 복사된 정보로부터 설정값 읽어오기/프롬프트창이 비어있을경우 제일 최근 설정값 불러오기",
- "Read parameters (prompt, etc...) from txt2img tab when making previews": "프리뷰 이미지 생성 시 텍스트→이미지 탭에서 설정값(프롬프트 등) 읽어오기",
- "Recommended settings: Sampling Steps: 80-100, Sampler: Euler a, Denoising strength: 0.8": "추천 설정값 - 샘플링 스텝 수 : 80-100 , 샘플러 : Euler a, 디노이즈 강도 : 0.8",
- "Reload custom script bodies (No ui updates, No restart)": "커스텀 스크립트 리로드하기(UI 업데이트 없음, 재시작 없음)",
- "Reloading...": "재시작 중...",
- "relu": "relu",
- "Renew Page": "Renew Page",
- "Request browser notifications": "브라우저 알림 권한 요청",
- "Resize": "리사이징 배수",
- "Resize and fill": "리사이징 후 채우기",
- "Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.": "설정된 해상도로 이미지 리사이징을 진행합니다. 원본과 가로/세로 길이가 일치하지 않을 경우, 부정확한 화면비의 이미지를 얻게 됩니다.",
- "Resize mode": "리사이징 모드",
- "Resize seed from height": "시드 리사이징 가로길이",
- "Resize seed from width": "시드 리사이징 세로길이",
- "Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors.": "이미지 전체가 설정된 해상도 내부에 들어가게 리사이징을 진행합니다. 빈 공간은 이미지의 색상으로 채웁니다.",
- "Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out.": "설정된 해상도 전체가 이미지로 가득차게 리사이징을 진행합니다. 튀어나오는 부분은 잘라냅니다.",
- "Restart Gradio and Refresh components (Custom Scripts, ui.py, js and css only)": "Gradio를 재시작하고 컴포넌트 새로고침하기 (커스텀 스크립트, ui.py, js, css만 해당됨)",
- "Restore faces": "얼굴 보정",
- "Restore low quality faces using GFPGAN neural network": "GFPGAN 신경망을 이용해 저품질의 얼굴을 보정합니다.",
- "Result = A * (1 - M) + B * M": "결과물 = A * (1 - M) + B * M",
- "Result = A + (B - C) * M": "결과물 = A + (B - C) * M",
- "Reuse seed from last generation, mostly useful if it was randomed": "이전 생성에서 사용된 시드를 불러옵니다. 랜덤하게 생성했을 시 도움됨",
- "right": "오른쪽",
- "Run": "가동",
- "Sample extension. Allows you to use __name__ syntax in your prompt to get a random line from a file named name.txt in the wildcards directory. Also see Dynamic Prompts for similar functionality.": "샘플 확장기능입니다. __이름__형식의 문법을 사용해 와일드카드 경로 내의 이름.txt파일로부터 무작위 프롬프트를 적용할 수 있게 해줍니다. 유사한 확장기능으로 다이나믹 프롬프트가 있습니다.",
- "Sampler": "샘플러",
- "Sampler parameters": "샘플러 설정값",
- "Sampling method": "샘플링 방법",
- "Sampling Steps": "샘플링 스텝 수",
- "Save": "저장",
- "Save a copy of embedding to log directory every N steps, 0 to disable": "N스텝마다 로그 경로에 임베딩을 저장합니다, 비활성화하려면 0으로 설정하십시오.",
- "Save a copy of image before applying color correction to img2img results": "이미지→이미지 결과물에 색상 보정을 진행하기 전 이미지의 복사본을 저장하기",
- "Save a copy of image before doing face restoration.": "얼굴 보정을 진행하기 전 이미지의 복사본을 저장하기",
- "Save an csv containing the loss to log directory every N steps, 0 to disable": "N스텝마다 로그 경로에 손실(Loss)을 포함하는 csv 파일을 저장합니다, 비활성화하려면 0으로 설정하십시오.",
- "Save an image to log directory every N steps, 0 to disable": "N스텝마다 로그 경로에 이미지를 저장합니다, 비활성화하려면 0으로 설정하십시오.",
- "Save as float16": "float16으로 저장",
- "Save grids to a subdirectory": "그리드 이미지를 하위 디렉토리에 저장하기",
- "Save images to a subdirectory": "이미지를 하위 디렉토리에 저장하기",
- "Save images with embedding in PNG chunks": "PNG 청크로 이미지에 임베딩을 포함시켜 저장",
- "Save style": "스타일 저장",
- "Save text information about generation parameters as chunks to png files": "이미지 생성 설정값을 PNG 청크에 텍스트로 저장",
- "Saving images/grids": "이미지/그리드 저장",
- "Saving to a directory": "디렉토리에 저장",
- "Scale by": "스케일링 배수 지정",
- "Scale to": "스케일링 사이즈 지정",
- "Script": "스크립트",
- "ScuNET GAN": "ScuNET GAN",
- "ScuNET PSNR": "ScuNET PSNR",
- "SD upscale": "SD 업스케일링",
- "Secondary model (B)": "2차 모델 (B)",
- "See": "자세한 설명은",
- "Seed": "시드",
- "Seed of a different picture to be mixed into the generation.": "결과물에 섞일 다른 그림의 시드",
- "Select activation function of hypernetwork": "하이퍼네트워크 활성화 함수 선택",
- "Select Layer weights initialization. relu-like - Kaiming, sigmoid-like - Xavier is recommended": "레이어 가중치 초기화 방식 선택 - relu류 : Kaiming 추천, sigmoid류 : Xavier 추천",
- "Select which Real-ESRGAN models to show in the web UI. (Requires restart)": "WebUI에 표시할 Real-ESRGAN 모델을 선택하십시오. (재시작 필요)",
- "Send seed when sending prompt or image to other interface": "다른 화면으로 프롬프트나 이미지를 보낼 때 시드도 함께 보내기",
- "Send to extras": "부가기능으로 전송",
- "Send to img2img": "이미지→이미지로 전송",
- "Send to inpaint": "인페인트로 전송",
- "Send to txt2img": "텍스트→이미지로 전송",
- "Separate prompts into parts using vertical pipe character (|) and the script will create a picture for every combination of them (except for the first part, which will be present in all combinations)": "(|)를 이용해 프롬프트를 분리할 시 첫 프롬프트를 제외하고 모든 프롬프트의 조합마다 이미지를 생성합니다. 첫 프롬프트는 모든 조합에 포함되게 됩니다.",
- "Separate values for X axis using commas.": "쉼표로 X축에 적용할 값 분리",
- "Separate values for Y axis using commas.": "쉼표로 Y축에 적용할 값 분리",
- "Set seed to -1, which will cause a new random number to be used every time": "시드를 -1로 적용 - 매번 랜덤한 시드가 적용되게 됩니다.",
- "set_index": "set_index",
- "Settings": "설정",
- "should be 2 or lower.": "이 2 이하여야 합니다.",
- "Show generation progress in window title.": "창 타이틀에 생성 진행도 보여주기",
- "Show grid in results for web": "웹에서 결과창에 그리드 보여주기",
- "Show image creation progress every N sampling steps. Set 0 to disable.": "N번째 샘플링 스텝마다 이미지 생성 과정 보이기 - 비활성화하려면 0으로 설정",
- "Show images zoomed in by default in full page image viewer": "전체 페이지 이미지 뷰어에서 기본값으로 이미지 확대해서 보여주기",
- "Show previews of all images generated in a batch as a grid": "배치에서 생성된 모든 이미지의 미리보기를 그리드 형식으로 보여주기",
- "Show progressbar": "프로그레스 바 보이기",
- "Show result images": "이미지 결과 보이기",
- "Show Textbox": "텍스트박스 보이기",
- "Shows a gallery of generated pictures by artists separated into categories.": "생성된 이미지들을 작가별로 분류해 보여줍니다. 원본 - https://artiststostudy.pages.dev",
- "Sigma adjustment for finding noise for image": "이미지 노이즈를 찾기 위해 시그마 조정",
- "Sigma Churn": "시그마 섞기",
- "sigma churn": "시그마 섞기",
- "Sigma max": "시그마 최댓값",
- "Sigma min": "시그마 최솟값",
- "Sigma noise": "시그마 노이즈",
- "sigma noise": "시그마 노이즈",
- "sigma tmin": "시그마 tmin",
- "Single Image": "단일 이미지",
- "Skip": "건너뛰기",
- "Slerp angle": "구면 선형 보간 각도",
- "Slerp interpolation": "구면 선형 보간",
- "sort by": "정렬 기준",
- "Source": "원본",
- "Source directory": "원본 경로",
- "Split image overlap ratio": "이미지 분할 겹침 비율",
- "Split image threshold": "이미지 분할 임계값",
- "Split oversized images": "사이즈가 큰 이미지 분할하기",
- "Stable Diffusion": "Stable Diffusion",
- "Stable Diffusion checkpoint": "Stable Diffusion 체크포인트",
- "step cnt": "스텝 변화 횟수",
- "step count": "스텝 변화 횟수",
- "step1 min/max": "스텝1 최소/최대",
- "step2 min/max": "스텝2 최소/최대",
- "Step:": "Step:",
- "Steps": "스텝 수",
- "Stop At last layers of CLIP model": "CLIP 모델의 n번째 레이어에서 멈추기",
- "Stop processing current image and continue processing.": "현재 진행중인 이미지 생성을 중단하고 작업을 계속하기",
- "Stop processing images and return any results accumulated so far.": "이미지 생성을 중단하고 지금까지 진행된 결과물 출력",
- "Style 1": "스타일 1",
- "Style 2": "스타일 2",
- "Style to apply; styles have components for both positive and negative prompts and apply to both": "적용할 스타일 - 스타일은 긍정/부정 프롬프트 모두에 대한 설정값을 가지고 있고 양쪽 모두에 적용 가능합니다.",
- "SwinIR 4x": "SwinIR 4x",
- "Sys VRAM:": "시스템 VRAM : ",
- "System": "시스템",
- "Tertiary model (C)": "3차 모델 (C)",
- "Textbox": "텍스트박스",
- "The official port of Deforum, an extensive script for 2D and 3D animations, supporting keyframable sequences, dynamic math parameters (even inside the prompts), dynamic masking, depth estimation and warping.": "Deforum의 공식 포팅 버전입니다. 2D와 3D 애니메이션, 키프레임 시퀀스, 수학적 매개변수, 다이나믹 마스킹 등을 지원합니다.",
- "This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is.": "이 정규표현식은 파일명으로부터 단어를 추출하는 데 사용됩니다. 추출된 단어들은 하단의 설정을 이용해 라벨 텍스트로 변환되어 훈련에 사용됩니다. 파일명 텍스트를 유지하려면 비워두십시오.",
- "This string will be used to join split words into a single line if the option above is enabled.": "이 문자열은 상단 설정이 활성화되어있을 때 분리된 단어들을 한 줄로 합치는 데 사용됩니다.",
- "This text is used to rotate the feature space of the imgs embs": "이 텍스트는 이미지 임베딩의 특징 공간을 회전하는 데 사용됩니다.",
- "Tile overlap": "타일 겹침",
- "Tile overlap, in pixels for ESRGAN upscalers. Low values = visible seam.": "ESRGAN 업스케일러들의 타일 중첩 수치, 픽셀 단위. 낮은 값 = 눈에 띄는 이음매.",
- "Tile overlap, in pixels for SwinIR. Low values = visible seam.": "SwinIR의 타일 중첩 수치, 픽셀 단위. 낮은 값 = 눈에 띄는 이음매.",
- "Tile size for all SwinIR.": "SwinIR의 타일 사이즈.",
- "Tile size for ESRGAN upscalers. 0 = no tiling.": "ESRGAN 업스케일러들의 타일 사이즈. 0 = 타일링 없음.",
- "Tiling": "타일링",
- "Time taken:": "소요 시간 : ",
- "Torch active/reserved:": "활성화/예약된 Torch 양 : ",
- "Torch active: Peak amount of VRAM used by Torch during generation, excluding cached data.\nTorch reserved: Peak amount of VRAM allocated by Torch, including all active and cached data.\nSys VRAM: Peak amount of VRAM allocation across all applications / total GPU VRAM (peak utilization%).": "활성화된 Torch : 생성 도중 캐시된 데이터를 포함해 사용된 VRAM의 최대량\n예약된 Torch : 활성화되고 캐시된 모든 데이터를 포함해 Torch에게 할당된 VRAM의 최대량\n시스템 VRAM : 모든 어플리케이션에 할당된 VRAM 최대량 / 총 GPU VRAM (최고 이용도%)",
- "Train": "훈련",
- "Train an embedding or Hypernetwork; you must specify a directory with a set of 1:1 ratio images": "임베딩이나 하이퍼네트워크를 훈련시킵니다. 1:1 비율의 이미지가 있는 경로를 지정해야 합니다.",
- "Train Embedding": "임베딩 훈련",
- "Train Hypernetwork": "하이퍼네트워크 훈련",
- "Training": "훈련",
- "txt2img": "텍스트→이미지",
- "txt2img history": "텍스트→이미지 기록",
- "uniform": "uniform",
- "unknown": "알수 없음",
- "up": "위쪽",
- "Update": "업데이트",
- "Upload mask": "마스크 업로드하기",
- "Upload prompt inputs": "입력할 프롬프트를 업로드하십시오",
- "Upscale Before Restoring Faces": "얼굴 보정을 진행하기 전에 업스케일링 먼저 진행하기",
- "Upscale latent space image when doing hires. fix": "고해상도 보정 사용시 잠재 공간 이미지 업스케일하기",
- "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image": "마스크된 부분을 설정된 해상도로 업스케일하고, 인페인팅을 진행한 뒤, 다시 다운스케일 후 원본 이미지에 붙여넣습니다.",
- "Upscaler": "업스케일러",
- "Upscaler 1": "업스케일러 1",
- "Upscaler 2": "업스케일러 2",
- "Upscaler 2 visibility": "업스케일러 2 가시성",
- "Upscaler for img2img": "이미지→이미지 업스케일러",
- "Upscaling": "업스케일링",
- "URL for extension's git repository": "확장기능의 git 레포 URL",
- "Use a two step process to partially create an image at smaller resolution, upscale, and then improve details in it without changing composition": "저해상도 이미지를 1차적으로 생성 후 업스케일을 진행하여, 이미지의 전체적인 구성을 바꾸지 않고 세부적인 디테일을 향상시킵니다.",
- "Use an empty output directory to save pictures normally instead of writing to the output directory.": "저장 경로를 비워두면 기본 저장 폴더에 이미지들이 저장됩니다.",
- "Use BLIP for caption": "캡션에 BLIP 사용",
- "Use checkbox to enable the extension; it will be enabled or disabled when you click apply button": "체크박스를 이용해 적용할 확장기능을 선택하세요. 변경사항은 적용 후 UI 재시작 버튼을 눌러야 적용됩니다.",
- "Use checkbox to mark the extension for update; it will be updated when you click apply button": "체크박스를 이용해 업데이트할 확장기능을 선택하세요. 업데이트는 적용 후 UI 재시작 버튼을 눌러야 적용됩니다.",
- "Use deepbooru for caption": "캡션에 deepbooru 사용",
- "Use dropout": "드롭아웃 사용",
- "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.": "다음 태그들을 사용해 이미지 파일명 형식을 결정하세요 : [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]. 비워두면 기본값으로 설정됩니다.",
- "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.": "다음 태그들을 사용해 이미지와 그리드의 하위 디렉토리명의 형식을 결정하세요 : [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]. 비워두면 기본값으로 설정됩니다.",
- "Use old emphasis implementation. Can be useful to reproduce old seeds.": "옛 방식의 강조 구현을 사용합니다. 옛 시드를 재현하는 데 효과적일 수 있습니다.",
- "Use original name for output filename during batch process in extras tab": "부가기능 탭에서 이미지를 여러장 처리 시 결과물 파일명에 기존 파일명 사용하기",
- "Use same seed for each image": "각 이미지에 동일한 시드 사용",
- "use spaces for tags in deepbooru": "deepbooru에서 태그에 공백 사용",
- "User interface": "사용자 인터페이스",
- "Var. seed": "바리에이션 시드",
- "Var. strength": "바리에이션 강도",
- "Variation seed": "바리에이션 시드",
- "Variation strength": "바리에이션 강도",
- "view": "api 보이기",
- "VRAM usage polls per second during generation. Set to 0 to disable.": "생성 도중 초당 VRAM 사용량 폴링 수. 비활성화하려면 0으로 설정하십시오.",
- "Weighted sum": "가중 합",
- "What to put inside the masked area before processing it with Stable Diffusion.": "Stable Diffusion으로 이미지를 생성하기 전 마스크된 부분에 무엇을 채울지 결정하는 설정값",
- "When reading generation parameters from text into UI (from PNG info or pasted text), do not change the selected model/checkpoint.": "PNG 정보나 붙여넣은 텍스트로부터 생성 설정값을 읽어올 때, 선택된 모델/체크포인트는 변경하지 않기.",
- "When using \"Save\" button, save images to a subdirectory": "저장 버튼 사용시, 이미지를 하위 디렉토리에 저장하기",
- "When using 'Save' button, only save a single selected image": "저장 버튼 사용시, 선택된 이미지 1개만 저장하기",
- "Which algorithm to use to produce the image": "이미지를 생성할 때 사용할 알고리즘",
- "Width": "가로",
- "wiki": " 위키",
- "Wildcards": "와일드카드",
- "Will upscale the image to twice the dimensions; use width and height sliders to set tile size": "이미지를 설정된 사이즈의 2배로 업스케일합니다. 상단의 가로와 세로 슬라이더를 이용해 타일 사이즈를 지정하세요.",
- "With img2img, do exactly the amount of steps the slider specifies (normally you'd do less with less denoising).": "이미지→이미지 진행 시, 슬라이더로 설정한 스텝 수를 정확히 실행하기 (일반적으로 디노이즈 강도가 낮을수록 실제 설정된 스텝 수보다 적게 진행됨)",
- "Write image to a directory (default - log/images) and generation parameters into csv file.": "이미지를 경로에 저장하고, 설정값들을 csv 파일로 저장합니다. (기본 경로 - log/images)",
- "X type": "X축",
- "X values": "X 설정값",
- "x/y change": "X/Y축 변경",
- "X/Y plot": "X/Y 플롯",
- "Y type": "Y축",
- "Y values": "Y 설정값"
-} \ No newline at end of file
diff --git a/localizations/pt_BR.json b/localizations/pt_BR.json
deleted file mode 100644
index 56281105..00000000
--- a/localizations/pt_BR.json
+++ /dev/null
@@ -1,468 +0,0 @@
-{
- "⤡": "⤡",
- "⊞": "⊞",
- "×": "×",
- "❮": "❮",
- "❯": "❯",
- "Loading...": "Carregando...",
- "view": "ver",
- "api": "api",
- "•": "•",
- "built with gradio": "criado com gradio",
- "Stable Diffusion checkpoint": "Stable Diffusion checkpoint",
- "txt2img": "txt2img",
- "img2img": "img2img",
- "Extras": "Extras",
- "PNG Info": "Informações de PNG",
- "Checkpoint Merger": "Fusão de Checkpoint",
- "Train": "Treinar",
- "Settings": "Configurações",
- "Prompt": "Prompt",
- "Negative prompt": "Prompt negativo",
- "Run": "Executar",
- "Skip": "Pular",
- "Interrupt": "Interromper",
- "Generate": "Gerar",
- "Style 1": "Estilo 1",
- "Style 2": "Estilo 2",
- "Label": "Rótulo",
- "File": "Arquivo",
- "Drop File Here": "Solte Aqui o Arquivo",
- "-": "-",
- "or": "ou",
- "Click to Upload": "Clique para Carregar um Arquivo",
- "Image": "Imagem",
- "Check progress": "Checar progresso",
- "Check progress (first)": "Checar progresso (primeiro)",
- "Sampling Steps": "Passos de Amostragem",
- "Sampling method": "Método de amostragem",
- "Euler a": "Euler a",
- "Euler": "Euler",
- "LMS": "LMS",
- "Heun": "Heun",
- "DPM2": "DPM2",
- "DPM2 a": "DPM2 a",
- "DPM fast": "DPM fast",
- "DPM adaptive": "DPM adaptive",
- "LMS Karras": "LMS Karras",
- "DPM2 Karras": "DPM2 Karras",
- "DPM2 a Karras": "DPM2 a Karras",
- "DDIM": "DDIM",
- "PLMS": "PLMS",
- "Width": "Largura",
- "Height": "Altura",
- "Restore faces": "Restaurar rostos",
- "Tiling": "Ladrilhar",
- "Highres. fix": "Ajuste de alta resolução",
- "Firstpass width": "Primeira Passagem da largura",
- "Firstpass height": "Primeira Passagem da altura",
- "Denoising strength": "Denoising strength",
- "Batch count": "Quantidade por lote",
- "Batch size": "Quantidade de lotes",
- "CFG Scale": "Escala CFG",
- "Seed": "Seed",
- "Extra": "Extra",
- "Variation seed": "Variação de seed",
- "Variation strength": "Força da variação",
- "Resize seed from width": "Redimensionar a seed a partir da largura",
- "Resize seed from height": "Redimensionar a seed a partir da altura",
- "Script": "Script",
- "None": "Nenhum",
- "Prompt matrix": "Matriz de prompt",
- "Prompts from file or textbox": "Prompts a partir de arquivo ou caixa de texto",
- "X/Y plot": "X/Y plot",
- "Put variable parts at start of prompt": "Coloca partes variáveis no começo do prompt",
- "Iterate seed every line": "Iterar seed a cada linha",
- "List of prompt inputs": "Lista de entrada de texto para prompt",
- "Upload prompt inputs": "Carregar entrada de texto para prompt",
- "X type": "Tipo do X",
- "Nothing": "Nenhum",
- "Var. seed": "Var. seed",
- "Var. strength": "Var. da força",
- "Steps": "Passos",
- "Prompt S/R": "Prompt S/R",
- "Prompt order": "Ordem de Prompt",
- "Sampler": "Sampler",
- "Checkpoint name": "Nome do Checkpoint",
- "Hypernetwork": "Hypernetwork",
- "Hypernet str.": "Força da Hypernet",
- "Sigma Churn": "Sigma Churn",
- "Sigma min": "Sigma min",
- "Sigma max": "Sigma max",
- "Sigma noise": "Sigma noise",
- "Eta": "Tempo estimado",
- "Clip skip": "Pular Clip",
- "Denoising": "Denoising",
- "X values": "Valores de X",
- "Y type": "Tipo de Y",
- "Y values": "Valores de Y",
- "Draw legend": "Desenhar a legenda",
- "Include Separate Images": "Incluir Imagens Separadas",
- "Keep -1 for seeds": "Manter em -1 para seeds",
- "Drop Image Here": "Solte a imagem aqui",
- "Save": "Salvar",
- "Send to img2img": "Mandar para img2img",
- "Send to inpaint": "Mandar para inpaint",
- "Send to extras": "Mandar para extras",
- "Make Zip when Save?": "Criar um Zip quando salvar?",
- "Textbox": "Caixa de texto",
- "Interrogate\nCLIP": "Interrogatório\nCLIP",
- "Inpaint": "Inpaint",
- "Batch img2img": "Lote img2img",
- "Image for img2img": "Imagem para img2img",
- "Image for inpainting with mask": "Imagem para inpainting com máscara",
- "Mask": "Máscara",
- "Mask blur": "Desfoque da máscara",
- "Mask mode": "Modo de máscara",
- "Draw mask": "Desenhar máscara",
- "Upload mask": "Carregar máscara",
- "Masking mode": "Modo de máscara",
- "Inpaint masked": "Inpaint o que está dentro da máscara",
- "Inpaint not masked": "Inpaint o que está fora da máscara",
- "Masked content": "Conteúdo mascarado",
- "fill": "preencher",
- "original": "original",
- "latent noise": "latent noise",
- "latent nothing": "latent nothing",
- "Inpaint at full resolution": "Inpaint em resolução total",
- "Inpaint at full resolution padding, pixels": "Inpaint de preenchimento em resolução total, pixels",
- "Process images in a directory on the same machine where the server is running.": "Processar imagens no diretório da mesma maquina onde o servidor está rodando.",
- "Use an empty output directory to save pictures normally instead of writing to the output directory.": "Usar um diretório vazio para salvar imagens, ao invés de salvá-las no diretório output.",
- "Input directory": "Diretório de entrada",
- "Output directory": "Diretório de saída",
- "Resize mode": "Modo de redimensionamento",
- "Just resize": "Apenas redimensionar",
- "Crop and resize": "Cortar e redimensionar",
- "Resize and fill": "Redimensionar e preencher",
- "img2img alternative test": "Teste alternativo de img2img",
- "Loopback": "Loopback",
- "Outpainting mk2": "Outpainting mk2",
- "Poor man's outpainting": "Poor man`s outpainting",
- "SD upscale": "Ampliamento SD",
- "should be 2 or lower.": "deve ser 2 ou menos.",
- "Override `Sampling method` to Euler?(this method is built for it)": "Substituir `Método de amostragem` por Euler? (este método foi feito para isso)",
- "Override `prompt` to the same value as `original prompt`?(and `negative prompt`)": "Substituir `prompt` para o mesmo valor que o `prompt original`? (também para o `prompt negativo`)",
- "Original prompt": "Prompt original",
- "Original negative prompt": "Prompt negativo original",
- "Override `Sampling Steps` to the same value as `Decode steps`?": "Substituir `Passos de Amostragem` para o mesmo valor que `Decodificar Passos`?",
- "Decode steps": "Decode steps",
- "Override `Denoising strength` to 1?": "Substituir `Quantidade do Denoise` para 1?",
- "Decode CFG scale": "Decodificar escala CFG",
- "Randomness": "Aleatoriedade",
- "Sigma adjustment for finding noise for image": "Ajuste Sigma para encontrar ruído para imagem",
- "Loops": "Loops",
- "Denoising strength change factor": "Fator de mudança na quantidade do Denoise",
- "Recommended settings: Sampling Steps: 80-100, Sampler: Euler a, Denoising strength: 0.8": "Configurações recomendadas: Passos de amostragem: 80-100: Euler a, força do Denoise: 0.8",
- "Pixels to expand": "Pixels para expandir",
- "Outpainting direction": "Direção do outpainting",
- "left": "esquerda",
- "right": "direita",
- "up": "cima",
- "down": "baixo",
- "Fall-off exponent (lower=higher detail)": "Expoente de queda (menor=mais detalhes)",
- "Color variation": "Variação de cor",
- "Will upscale the image to twice the dimensions; use width and height sliders to set tile size": "Amplia a imagem em dobro; ajusta a largura e altura para definir o tamanho do ladrilho",
- "Tile overlap": "Sobreposição de ladrilho",
- "Upscaler": "Ampliador",
- "Lanczos": "Lanczos",
- "LDSR": "LDSR",
- "4x_foolhardy_Remacri": "4x_foolhardy_Remacri",
- "Put ESRGAN models here": "Coloque modelos ESRGAN aqui",
- "R-ESRGAN General 4xV3": "R-ESRGAN General 4xV3",
- "R-ESRGAN AnimeVideo": "R-ESRGAN AnimeVideo",
- "R-ESRGAN 4x+": "R-ESRGAN 4x+",
- "R-ESRGAN 4x+ Anime6B": "R-ESRGAN 4x+ Anime6B",
- "R-ESRGAN 2x+": "R-ESRGAN 2x+",
- "ScuNET": "ScuNET",
- "ScuNET PSNR": "ScuNET PSNR",
- "put_swinir_models_here": "put_swinir_models_here",
- "Single Image": "Uma imagem",
- "Batch Process": "Processo em lote",
- "Batch from Directory": "Lote apartir de diretório",
- "Source": "Origem",
- "Show result images": "Mostrar imagens resultantes",
- "Scale by": "Aumentar proporcionalmente em",
- "Scale to": "Aumentar proporcionalmente para",
- "Resize": "Redimensionar",
- "Crop to fit": "Cortar para caber",
- "Upscaler 2 visibility": "Visibilidade da ferramenta de ampliação 2",
- "GFPGAN visibility": "Visibilidade GFPGAN",
- "CodeFormer visibility": "Visibilidade CodeFormer",
- "CodeFormer weight (0 = maximum effect, 1 = minimum effect)": "Peso do CodeFormer (0 = efeito máximo, 1 = efeito mínimo)",
- "Open output directory": "Abrir diretório de saída",
- "Send to txt2img": "Mandar para txt2img",
- "A merger of the two checkpoints will be generated in your": "Uma fusão dos dois checkpoints será gerada em seu",
- "checkpoint": "checkpoint",
- "directory.": "diretório.",
- "Primary model (A)": "Modelo primário (A)",
- "Secondary model (B)": "Modelo secundário (B)",
- "Tertiary model (C)": "Modelo terciário (C)",
- "Custom Name (Optional)": "Nome personalizado (Opcional)",
- "Multiplier (M) - set to 0 to get model A": "Multiplicador (M) - definir em 0 para obter o modelo A",
- "Interpolation Method": "Método de Interpolação",
- "Weighted sum": "Soma de pesos",
- "Add difference": "Acrescentar diferença",
- "Save as float16": "Salvar como float16",
- "See": "Ver",
- "wiki": "wiki",
- "for detailed explanation.": "para explicação detalhada.",
- "Create embedding": "Criar incorporação",
- "Create hypernetwork": "Criar hypernetwork",
- "Preprocess images": "Pré-processar imagens",
- "Name": "Nome",
- "Initialization text": "Texto de inicialização",
- "Number of vectors per token": "Número de vetores por token",
- "Overwrite Old Embedding": "Substituir Incorporação anterior",
- "Modules": "Módulos",
- "Enter hypernetwork layer structure": "Entrar na estrutura de camadas da hypernetwork",
- "Select activation function of hypernetwork": "Selecionar a função de ativação de hypernetwork",
- "relu": "relu",
- "leakyrelu": "leakyrelu",
- "elu": "elu",
- "swish": "swish",
- "tanh": "tanh",
- "sigmoid": "sigmoid",
- "celu": "celu",
- "gelu": "gelu",
- "glu": "glu",
- "hardshrink": "hardshrink",
- "hardsigmoid": "hardsigmoid",
- "hardswish": "hardswish",
- "hardtanh": "hardtanh",
- "logsigmoid": "logsigmoid",
- "logsoftmax": "logsoftmax",
- "mish": "mish",
- "multiheadattention": "multiheadattention",
- "prelu": "prelu",
- "rrelu": "rrelu",
- "relu6": "relu6",
- "selu": "selu",
- "silu": "silu",
- "softmax": "softmax",
- "softmax2d": "softmax2d",
- "softmin": "softmin",
- "softplus": "softplus",
- "softshrink": "softshrink",
- "softsign": "softsign",
- "tanhshrink": "tanhshrink",
- "threshold": "threshold",
- "Select Layer weights initialization. relu-like - Kaiming, sigmoid-like - Xavier is recommended": "Selecionar a inicialização de pesos de camada. relu-like - Kaiming, sigmoid-like - Xavier é recomendado",
- "Normal": "Normal",
- "KaimingUniform": "KaimingUniform",
- "KaimingNormal": "KaimingNormal",
- "XavierUniform": "XavierUniform",
- "XavierNormal": "XavierNormal",
- "Add layer normalization": "Adicionar normalização de camada",
- "Use dropout": "Usar dropout",
- "Overwrite Old Hypernetwork": "Sobrescrever Hypernetwork Anterior",
- "Source directory": "Diretório de origem",
- "Destination directory": "Diretório de destino",
- "Existing Caption txt Action": "Ação de Título txt Já Existente",
- "ignore": "ignorar",
- "copy": "copiar",
- "prepend": "adicionar ao início",
- "append": "adicionar ao final",
- "Create flipped copies": "Criar cópias espelhadas",
- "Split oversized images into two": "Dividir imagens maiores em duas",
- "Auto focal point crop": "Ajuste de corte em ponto focal automático",
- "Use BLIP for caption": "Usar BLIP para o título",
- "Use deepbooru for caption": "Usar deepbooru para o título",
- "Split image threshold": "Limite de divisão de imagem",
- "Split image overlap ratio": "Proporção de sobreposição da divisão de imagem",
- "Focal point face weight": "Peso de ponto focal para rosto",
- "Focal point entropy weight": "Peso de ponto focal para entropia",
- "Focal point edges weight": "Peso de ponto focal para bordas",
- "Create debug image": "Criar imagem de depuração",
- "Preprocess": "Pré-processar",
- "Train an embedding; must specify a directory with a set of 1:1 ratio images": "Treinar um embedding; precisa especificar um diretório com imagens de proporção 1:1",
- "[wiki]": "[wiki]",
- "Embedding": "Embedding",
- "Embedding Learning rate": "Taxa de aprendizagem da incorporação",
- "Hypernetwork Learning rate": "Taxa de aprendizagem de Hypernetwork",
- "Dataset directory": "Diretório de Dataset",
- "Log directory": "Diretório de Log",
- "Prompt template file": "Arquivo padrão de Prompt",
- "Max steps": "Passos máximos",
- "Save an image to log directory every N steps, 0 to disable": "Salvar uma imagem no diretório de log a cada N passos. 0 para desativar",
- "Save a copy of embedding to log directory every N steps, 0 to disable": "Salva uma cópia da incorporação no diretório de log a cada N passos. 0 para desativar",
- "Save images with embedding in PNG chunks": "Salva imagens com incorporação em segmentos de PNG",
- "Read parameters (prompt, etc...) from txt2img tab when making previews": "Ler parâmetros (prompt, etc...) para a aba txt2img durante os previews",
- "Train Hypernetwork": "Treinar Hypernetwork",
- "Train Embedding": "Treinar Incorporação",
- "Apply settings": "Aplicar configurações",
- "Saving images/grids": "Salvar imagens/grades",
- "Always save all generated images": "Sempre salvar todas as imagens geradas",
- "File format for images": "Tipo de formato das imagens salvas",
- "Images filename pattern": "Padrão de nomeação para imagens salvas",
- "Add number to filename when saving": "Adicionar número para o nome do arquivo quando salvar",
- "Always save all generated image grids": "Sempre salvar todas as grades de imagens",
- "File format for grids": "Tipo de formato das grades de imagens salvas",
- "Add extended info (seed, prompt) to filename when saving grid": "Adicionar informações extras (seed, prompt) para os arquivos quando gerar uma grade",
- "Do not save grids consisting of one picture": "Não salvar grades de apenas uma imagem",
- "Prevent empty spots in grid (when set to autodetect)": "Previnir espaços vazios na grade (quando marcado para autodetectar)",
- "Grid row count; use -1 for autodetect and 0 for it to be same as batch size": "Contagem de linhas da grade; -1 para autodetectar e 0 para ser igual ao valor do tamanho das levas",
- "Save text information about generation parameters as chunks to png files": "Salvar informações de parâmetros de geração como segmentos png",
- "Create a text file next to every image with generation parameters.": "Criar um arquivo de texto com informações de geração junto a cada imagem gerada.",
- "Save a copy of image before doing face restoration.": "Salva uma cópia de cada imagem antes do refinamento facial.",
- "Quality for saved jpeg images": "Qualidade das imagens jpeg",
- "If PNG image is larger than 4MB or any dimension is larger than 4000, downscale and save copy as JPG": "Se a imagem PNG for maior que 4MB ou qualquer dimensão maior que 4000, diminuir e salvar uma cópia em JPG",
- "Use original name for output filename during batch process in extras tab": "Usar o nome original para os arquivos de output durante o processo de levas da aba Extras",
- "When using 'Save' button, only save a single selected image": "Quando usar o botão `Salvar`, somente salvar as imagens selecionadas.",
- "Do not add watermark to images": "Não adicionar marca dágua nas imagens",
- "Paths for saving": "Caminhos para salvar",
- "Output directory for images; if empty, defaults to three directories below": "Diretório de saída para imagens; se deixado em branco, as imagens vao para os seguintes diretórios",
- "Output directory for txt2img images": "Diretório de Saída para imagens txt2img",
- "Output directory for img2img images": "Diretório de Saída para imagens img2img",
- "Output directory for images from extras tab": "Diretório de Saída para a aba Extras",
- "Output directory for grids; if empty, defaults to two directories below": "Diretório de Saída para grades; se vazio, vão para os diretórios seguintes",
- "Output directory for txt2img grids": "Diretório de Saída para grades de imagens txt2img",
- "Output directory for img2img grids": "Diretório de Saída para grades de imagens img2img",
- "Directory for saving images using the Save button": "Diretório para imagens salvas utilizando o botão de salvar",
- "Saving to a directory": "Salvando para um diretório",
- "Save images to a subdirectory": "Salvar imagens para um subdiretório",
- "Save grids to a subdirectory": "Salvar grades de imagens para um subdiretório",
- "When using \"Save\" button, save images to a subdirectory": "Quando usar o botão \"Salvar\", salvar imagens para um subdiretório",
- "Directory name pattern": "Padrão de nome de diretório",
- "Max prompt words for [prompt_words] pattern": "Número máximo de palavras do padrão de prompt [prompt_words]",
- "Upscaling": "Ampliando",
- "Tile size for ESRGAN upscalers. 0 = no tiling.": "Tamanho do ladrilho para ampliação ESRGAN. 0 = sem ladrilho.",
- "Tile overlap, in pixels for ESRGAN upscalers. Low values = visible seam.": "Sobreposição de azulejo, em pixels, para amplicação ESRGAN. Valores baixos = linhas de fusão mais aparente.",
- "Tile size for all SwinIR.": "Tamanho do ladrilho para todo SwinIR.",
- "Tile overlap, in pixels for SwinIR. Low values = visible seam.": "Sobreposição de azulejo, em pixels, para SwinIR. Valores baixos = junção mais aparente.",
- "LDSR processing steps. Lower = faster": "Steps de processamento LDSR. Menos = rápido",
- "Upscaler for img2img": "Ampliação para img2img",
- "Upscale latent space image when doing hires. fix": "Ampliar a imagem do espaço latente quando usando o ajuste de alta definição - hires. fix",
- "Face restoration": "Refinamento de rosto",
- "CodeFormer weight parameter; 0 = maximum effect; 1 = minimum effect": "Parâmento de peso do CodeFormer; 0 = efeito máximo; 1 = efeito mínimo",
- "Move face restoration model from VRAM into RAM after processing": "Mover o processo de refinamento de rosto da VRAM da placa de vídeo para a RAM do computador depois do processamento.",
- "System": "Sistema",
- "VRAM usage polls per second during generation. Set to 0 to disable.": "Levantamento de uso de VRAM por segundo durante gerações. Deixar em 0 para desativar.",
- "Always print all generation info to standard output": "Sempre mostrar as informações de todas as gerações no padrão de output",
- "Add a second progress bar to the console that shows progress for an entire job.": "Adicionar uma segunda barra de processamento no console que mostra a progressão de todo o trabalho.",
- "Training": "Treinamento",
- "Move VAE and CLIP to RAM when training hypernetwork. Saves VRAM.": "Mover VAE e CLIP para a RAM quando treinando hypernetwork. Preserva VRAM.",
- "Filename word regex": "Palavra de nome de arquivo regex",
- "Filename join string": "Nome de arquivo join string",
- "Number of repeats for a single input image per epoch; used only for displaying epoch number": "Número de repetições para entrada única de imagens por época; serve apenas para mostrar o número de época",
- "Save an csv containing the loss to log directory every N steps, 0 to disable": "Salvar um csv com as perdas para o diretório de log a cada N steps, 0 para desativar",
- "Stable Diffusion": "Stable Diffusion",
- "Checkpoints to cache in RAM": "Checkpoints para manter no cache da RAM",
- "Hypernetwork strength": "Força da Hypernetwork",
- "Apply color correction to img2img results to match original colors.": "Aplicar correção de cor nas imagens geradas em img2img, usando a imagem original como base.",
- "Save a copy of image before applying color correction to img2img results": "Salvar uma cópia das imagens geradas em img2img antes de aplicar a correção de cor",
- "With img2img, do exactly the amount of steps the slider specifies (normally you'd do less with less denoising).": "Durante gerações img2img, fazer examente o número de steps definidos na barra (normalmente você faz menos steps com denoising menor).",
- "Enable quantization in K samplers for sharper and cleaner results. This may change existing seeds. Requires restart to apply.": "Ativar quantização em K samples para resultados mais nítidos e visíveis. Pode alterar seeds ja existentes. Precisa reiniciar para funcionar.",
- "Emphasis: use (text) to make model pay more attention to text and [text] to make it pay less attention": "Ênfase: usar parênteses ao redor de palavras (texto de exemplo) para fazer o modelo dar mais atenção para aquela palavra ou frase, e chaves [texto de exemplo] para tirar atenção",
- "Use old emphasis implementation. Can be useful to reproduce old seeds.": "Usar método anterior de implementação de ênfase. Útil para reproduzir seeds antigas.",
- "Make K-diffusion samplers produce same images in a batch as when making a single image": "Faz as amostragens K-diffusion produzirem imagens iguais em lotes quando criando uma única imagem",
- "Increase coherency by padding from the last comma within n tokens when using more than 75 tokens": "Aumenta a coerência por preenchimento apartir da ultima vírgula dentro de n tokens quando usando mais de 75 tokens",
- "Filter NSFW content": "Filtra conteúdos inadequados(geralmente +18)",
- "Stop At last layers of CLIP model": "Para na última camada do modelo CLIP",
- "Interrogate Options": "Opções de Interrogatório",
- "Interrogate: keep models in VRAM": "Interrogar: manter modelos na VRAM",
- "Interrogate: use artists from artists.csv": "Interrogar: usa artistas e estilos do documento artists.csv",
- "Interrogate: include ranks of model tags matches in results (Has no effect on caption-based interrogators).": "Interrogar: incluir classificação de tags de modelo combinando nos resultados (Não tem efeito na interrogação feita por legenda).",
- "Interrogate: num_beams for BLIP": "Interrogar: num_beams para BLIP",
- "Interrogate: minimum description length (excluding artists, etc..)": "Interrogar: tamanho mínimo da descrição (tirando artistas, etc..)",
- "Interrogate: maximum description length": "Interrogar: tamanho máximo da descrição",
- "CLIP: maximum number of lines in text file (0 = No limit)": "CLIP: número máximo de linhas no arquivo de texto(0 = Sem limites)",
- "Interrogate: deepbooru score threshold": "Interrogatório: limite de score deepbooru",
- "Interrogate: deepbooru sort alphabetically": "Interrogar: organizar deepbooru por ordem alfabética",
- "use spaces for tags in deepbooru": "usar espaços para tags em deepbooru",
- "escape (\\) brackets in deepbooru (so they are used as literal brackets and not for emphasis)": "espaço (\\) colchetes em deepbooru (são usados como colchetes ao invés de dar ênfase)",
- "User interface": "Interface de usuário",
- "Show progressbar": "Mostrar barra de progresso",
- "Show image creation progress every N sampling steps. Set 0 to disable.": "Mostrar a criação de imagens a cada N sampling steps. Em 1 já dá para ver o processo de geração. Marcar como 0 para desativar.",
- "Show previews of all images generated in a batch as a grid": "Mostrar previsualização de todas as imagens geradas em leva numa grade",
- "Show grid in results for web": "Mostrar grade em resultados para web",
- "Do not show any images in results for web": "Não mostrar nenhuma imagem em resultados para web",
- "Add model hash to generation information": "Adicionar hash do modelo para informação de geração",
- "Add model name to generation information": "Adicionar nome do modelo para informação de geração",
- "When reading generation parameters from text into UI (from PNG info or pasted text), do not change the selected model/checkpoint.": "Quando ler parâmetros de texto para a interface (de informações de PNG ou texto copiado), não alterar o modelo/intervalo selecionado.",
- "Font for image grids that have text": "Fonte para grade de imagens que têm texto",
- "Enable full page image viewer": "Ativar visualizador de página inteira",
- "Show images zoomed in by default in full page image viewer": "Mostrar imagens com zoom por definição no visualizador de página inteira",
- "Show generation progress in window title.": "Mostrar barra de progresso no nome da janela.",
- "Quicksettings list": "Lista de configurações rapidas",
- "Localization (requires restart)": "Localização (precisa reiniciar)",
- "ar_AR": "ar_AR",
- "es_ES": "es_ES",
- "fr-FR": "fr-FR",
- "ja_JP": "ja_JP",
- "ko_KR": "ko_KR",
- "ru_RU": "ru_RU",
- "tr_TR": "tr_TR",
- "zh_CN": "zh_CN",
- "Sampler parameters": "Parâmetros de Amostragem",
- "Hide samplers in user interface (requires restart)": "Esconder amostragens na interface de usuário (precisa reiniciar)",
- "eta (noise multiplier) for DDIM": "tempo estimado (multiplicador de ruído) para DDIM",
- "eta (noise multiplier) for ancestral samplers": "tempo estimado (multiplicador de ruído) para amostragens ancestrais",
- "img2img DDIM discretize": "Discretização de img2img DDIM",
- "uniform": "uniforme",
- "quad": "quad",
- "sigma churn": "sigma churn",
- "sigma tmin": "sigma tmin",
- "sigma noise": "sigma noise",
- "Eta noise seed delta": "tempo estimado para ruído seed delta",
- "Request browser notifications": "Solicitar notificações do navegador",
- "Download localization template": "Baixar arquivo modelo de localização",
- "Reload custom script bodies (No ui updates, No restart)": "Recarregar scripts personalizados (Sem atualizar a interface, Sem reiniciar)",
- "Restart Gradio and Refresh components (Custom Scripts, ui.py, js and css only)": "Reiniciar Gradio e atualizar componentes (Scripts personalizados, ui.py, js e css)",
- "Prompt (press Ctrl+Enter or Alt+Enter to generate)": "Prompt (apertar Ctrl+Enter ou Alt+Enter para gerar)",
- "Negative prompt (press Ctrl+Enter or Alt+Enter to generate)": "Prompt Negativo (apertar Ctrl+Enter ou Alt+Enter para gerar)",
- "Add a random artist to the prompt.": "Adicionar um artista aleatório para o prompt.",
- "Read generation parameters from prompt or last generation if prompt is empty into user interface.": "Lê os parâmetros de geração do prompt ou da última geraçao, caso o prompt esteja vazio.",
- "Save style": "Salva um estilo de prompt.",
- "Apply selected styles to current prompt": "Aplica o estilo para o prompt atual.",
- "Stop processing current image and continue processing.": "Pula a imagem sendo gerada e vai para a próxima.",
- "Stop processing images and return any results accumulated so far.": "Interrompe o processo e mostra o que foi gerado até então.",
- "Style to apply; styles have components for both positive and negative prompts and apply to both": "Estilo para aplicar; também serve para o prompt negativo e vai preencher se usado.",
- "Do not do anything special": "Não faça nada de especial",
- "Which algorithm to use to produce the image": "O tipo de algoritmo para gerar imagens.",
- "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps to higher than 30-40 does not help": "Euler Ancestral - cria mais variações para as imagens em diferentes passos. Mais que 40 passos cancela o efeito.",
- "Denoising Diffusion Implicit Models - Funciona melhor para inpainting.": "Denoising Diffusion Implicit Models - Funciona melhor para inpainting.",
- "Produce an image that can be tiled.": "Produz uma imagem que pode ser ladrilhada.",
- "Use a two step process to partially create an image at smaller resolution, upscale, and then improve details in it without changing composition": "Cria um processo em duas etapas, com uma imagem em baixa qualidade primeiro, aumenta a imagem e refina os detalhes sem alterar a composição da imagem",
- "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.": "Quanto o algoritmo deve manter da imagem original. Em 0, nada muda. Em 1 o algoritmo ignora a imagem original. Valores menores que 1.0 demoram mais.",
- "How many batches of images to create": "Quantos lotes de imagens criar",
- "How many image to create in a single batch": "Quantas imagens criar em um único lote",
- "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results": "Classifier Free Guidance Scale - Quanto maior o valor, mais segue o prompt e quanto menor, menor segue.",
- "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result": "Codigo de geração de uma imagem - criando uma imagem com os mesmos parâmetros e seed trazem o mesmo resultado.",
- "Set seed to -1, which will cause a new random number to be used every time": "Define seed como -1, deixando o valor que vai aparecer como aleatório.",
- "Reuse seed from last generation, mostly useful if it was randomed": "Reutilizar a seed da última geração, útil principalmente se ela foi aleatória",
- "Seed of a different picture to be mixed into the generation.": "Seed de uma imagem diferente é misturada na geração.",
- "How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something).": "Qual a variação a ser gerada. Em 0, não tem efeito. Em 1, gera uma imagem completa com a variação de seed, (exceto com amostragens a).",
- "Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution": "Tenta gerar uma imagem similar ao que teria sido feito com a mesma seed em dimensões especifica.",
- "Separate values for X axis using commas.": "Separa os valores para o eixo X usando vírgulas.",
- "Separate values for Y axis using commas.": "Separa os valores para o eixo Y usando vírgulas.",
- "Write image to a directory (default - log/images) and generation parameters into csv file.": "Salva a imagem no diretório padrão ou escolhido e cria um arquivo csv com os parâmetros da geração.",
- "Open images output directory": "Abre o diretório de saída de imagens.",
- "How much to blur the mask before processing, in pixels.": "Transição do contorno da máscara, em pixels.",
- "What to put inside the masked area before processing it with Stable Diffusion.": "O que vai dentro da máscara antes de processar.",
- "fill it with colors of the image": "Preenche usando as cores da imagem.",
- "keep whatever was there originally": "manter usando o que estava lá originalmente",
- "fill it with latent space noise": "Preenche com ruídos do espaço latente.",
- "fill it with latent space zeroes": "Preenche com zeros do espaço latente.",
- "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image": "Faz ampliação na região com máscara para atingir a resolução desejada, faz inpainting, faz downscale para voltar à resolução original e cola na imagem original",
- "Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.": "Redimensiona a imagem para a resolução desejada. A menos que a altura e a largura sejam iguais, você obterá uma proporção incorreta.",
- "Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out.": "Redimensiona a imagem para que toda a resolução desejada seja preenchida com a imagem. Corta as partes que ficaram pra fora.",
- "Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors.": "Redimensiona a imagem para que toda a imagem esteja dentro da resolução desejada. Preenche o espaço vazio com as cores da imagem.",
- "How many times to repeat processing an image and using it as input for the next iteration": "Número de vezes que vai repetir o processamento da imagem e usar como entrada para a próxima iteração",
- "In loopback mode, on each loop the denoising strength is multiplied by this value. <1 means decreasing variety so your sequence will converge on a fixed picture. >1 means increasing variety so your sequence will become more and more chaotic.": "No modo de loopback, em cada loop a força do denoise é multiplicado por este valor. <1 significa diminuir a variedade para que sua sequência converta em uma imagem fixa. >1 significa aumentar a variedade para que sua sequência se torne cada vez mais caótica.",
- "For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam.": "Para ampliação SD, quantidade de sobreposição em pixels que deve haver entre os ladrilhos. Os ladrilhos se sobrepõem para que, quando forem mesclados de volta em uma imagem, não haja linhas de junção claramente visíveis.",
- "A directory on the same machine where the server is running.": "Um diretório na mesma máquina onde o servidor está rodando.",
- "Leave blank to save images to the default path.": "Deixar em branco para salvar imagens no caminho padrão.",
- "Result = A * (1 - M) + B * M": "Resultado = A * (1 - M) + B * M",
- "Result = A + (B - C) * M": "Resultado = A + (B - C) * M",
- "1st and last digit must be 1. ex:'1, 2, 1'": "Primeiro e último dígito precisam ser 1. ex:`1, 2, 1`",
- "Path to directory with input images": "Caminho para o diretório com imagens de entrada",
- "Path to directory where to write outputs": "Caminho para o diretório para gravar as saídas",
- "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.": "Usa essas tags para definir como os nomes dos arquivos sao escolhidos: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; deixe em branco para manter o padrão.",
- "If this option is enabled, watermark will not be added to created images. Warning: if you do not add watermark, you may be behaving in an unethical manner.": "Se esta opção estiver marcada, as imagens não vão ter marca d`água. Aviso: se você não quer a marca d`água, você pode estar se envolvendo em comportamentos antiéticos",
- "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.": "Usa essas tags para definir como os nomes dos subdiretorios e grades são escolhidos: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; deixe em branco para manter o padrão.",
- "Restore low quality faces using GFPGAN neural network": "Restaurar rostos de baixa qualidade usando a rede neural GFPGAN",
- "This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is.": "Esta expressão regular vai retirar palavras do nome do arquivo e serão juntadas via regex usando a opção abaixo em etiquetas usadas em treinamento. Não mexer para manter os nomes como estão.",
- "This string will be used to join split words into a single line if the option above is enabled.": "Esta string será usada para unir palavras divididas em uma única linha se a opção acima estiver habilitada.",
- "List of setting names, separated by commas, for settings that should go to the quick access bar at the top, rather than the usual setting tab. See modules/shared.py for setting names. Requires restarting to apply.": "Lista de nomes de configurações, separados por vírgulas, para configurações que devem ir para a barra de acesso rápido na parte superior, em vez da guia de configuração usual. Veja modules/shared.py para nomes de configuração. Necessita reinicialização para aplicar.",
- "If this values is non-zero, it will be added to seed and used to initialize RNG for noises when using samplers with Eta. You can use this to produce even more variation of images, or you can use this to match images of other software if you know what you are doing.": "Se este valor for diferente de zero, ele será adicionado à seed e usado para inicializar o RNG para ruídos ao usar amostragens com Tempo Estimado. Você pode usar isso para produzir ainda mais variações de imagens ou pode usar isso para combinar imagens de outro software se souber o que está fazendo."
-}
diff --git a/localizations/ru_RU.json b/localizations/ru_RU.json
deleted file mode 100644
index 664d36ea..00000000
--- a/localizations/ru_RU.json
+++ /dev/null
@@ -1,475 +0,0 @@
-{
- "⤡": "⤡",
- "⊞": "⊞",
- "×": "×",
- "❮": "❮",
- "❯": "❯",
- "Loading...": "Загрузка...",
- "view": "просмотр",
- "api": "api",
- "•": "•",
- "built with gradio": "На основе Gradio",
- "Stable Diffusion checkpoint": "Веса Stable Diffusion",
- "txt2img": "текст-в-рисунок",
- "img2img": "рисунок-в-рисунок",
- "Extras": "Дополнения",
- "PNG Info": "Информация о PNG",
- "Image Browser": "Просмотр изображений",
- "History": "Журнал",
- "Checkpoint Merger": "Слияние весов",
- "Train": "Обучение",
- "Create aesthetic embedding": "Создать эмбеддинг эстетики",
- "Settings": "Настройки",
- "Prompt": "Запрос",
- "Negative prompt": "Исключающий запрос",
- "Run": "Запустить",
- "Skip": "Пропустить",
- "Interrupt": "Прервать",
- "Generate": "Создать",
- "Style 1": "Стиль 1",
- "Style 2": "Стиль 2",
- "Label": "Метка",
- "File": "Файл",
- "Drop File Here": "Перетащите файл сюда",
- "-": "-",
- "or": "или",
- "Click to Upload": "Нажмите, чтобы загрузить",
- "Image": "Рисунок",
- "Check progress": "Узнать состояние",
- "Check progress (first)": "Узнать состояние первого",
- "Sampling Steps": "Шагов семплера",
- "Sampling method": "Метод семплирования",
- "Euler a": "Euler a",
- "Euler": "Euler",
- "LMS": "LMS",
- "Heun": "Heun",
- "DPM2": "DPM2",
- "DPM2 a": "DPM2 a",
- "DPM fast": "DPM fast",
- "DPM adaptive": "DPM adaptive",
- "LMS Karras": "LMS Karras",
- "DPM2 Karras": "DPM2 Karras",
- "DPM2 a Karras": "DPM2 a Karras",
- "DDIM": "DDIM",
- "PLMS": "PLMS",
- "Width": "Ширина",
- "Height": "Высота",
- "Restore faces": "Восстановить лица",
- "Tiling": "Замощение",
- "Highres. fix": "HD-режим",
- "Firstpass width": "Ширина первого прохода",
- "Firstpass height": "Высота первого прохода",
- "Denoising strength": "Сила шумоподавления",
- "Batch count": "Рисунков подряд",
- "Batch size": "Рисунков параллельно",
- "CFG Scale": "Близость к запросу",
- "Seed": "Семя",
- "Extra": "Дополнения",
- "Variation seed": "Вариация семени",
- "Variation strength": "Вариация шумоподавления",
- "Resize seed from width": "Поправка в семя от ширины",
- "Resize seed from height": "Поправка в семя от высоты",
- "Open for Clip Aesthetic!": "Clip-эстетика!",
- "▼": "▼",
- "Aesthetic weight": "Вес эстетики",
- "Aesthetic steps": "Шагов эстетики",
- "Aesthetic learning rate": "Скорость обучения эстетики",
- "Slerp interpolation": "Slerp-интерполяция",
- "Aesthetic imgs embedding": "Рисунки - эмбеддинги эстетики",
- "None": "Ничего",
- "Aesthetic text for imgs": "Имя эстетики рисунков",
- "Slerp angle": "Угол slerp",
- "Is negative text": "Это текст для исключения",
- "Script": "Скрипт",
- "Prompt matrix": "Матрица запросов",
- "Prompts from file or textbox": "Запросы из файла или текста",
- "X/Y plot": "X/Y-график",
- "Put variable parts at start of prompt": "Переменное начало запроса",
- "Show Textbox": "Показать текстовый ввод",
- "File with inputs": "Файл входа",
- "Prompts": "Запросы",
- "X type": "Ось X",
- "Nothing": "Ничего",
- "Var. seed": "Вариация семени",
- "Var. strength": "Вариация силы",
- "Steps": "Число шагов",
- "Prompt S/R": "Вариация запроса",
- "Prompt order": "Порядок запросов",
- "Sampler": "Семплер",
- "Checkpoint name": "Имя файла весов",
- "Hypernetwork": "Гиперсеть",
- "Hypernet str.": "Строка гиперсети",
- "Sigma Churn": "Возмущение сигмы",
- "Sigma min": "Мин. сигма",
- "Sigma max": "Макс. сигма",
- "Sigma noise": "Сигма-шум",
- "Eta": "Расчётное время",
- "Clip skip": "Пропустить Clip",
- "Denoising": "Шумоподавление",
- "X values": "Значения X",
- "Y type": "Тип Y",
- "Y values": "Значения Y",
- "Draw legend": "Легенда графика",
- "Include Separate Images": "Включить отдельные рисунки",
- "Keep -1 for seeds": "-1 для семени",
- "Drop Image Here": "Перетащите рисунок сюда",
- "Save": "Сохранить",
- "Send to img2img": "В рисунок-в-рисунок",
- "Send to inpaint": "В режим врисовывания",
- "Send to extras": "В дополнения",
- "Make Zip when Save?": "Создать zip при сохранении?",
- "Textbox": "Текст",
- "Interrogate\nCLIP": "Распознавание\nCLIP",
- "Interrogate\nDeepBooru": "Распознавание\nDeepBooru",
- "Inpaint": "врисовать",
- "Batch img2img": "рисунок-в-рисунок (набор)",
- "Image for img2img": "рисунок-в-рисунок (вход)",
- "Image for inpainting with mask": "врисовать (вход с трафаретом)",
- "Mask": "Трафарет",
- "Mask blur": "Размытие трафарета",
- "Mask mode": "Режим трафарета",
- "Draw mask": "Нарисовать трафарет",
- "Upload mask": "Загрузить трафарет",
- "Masking mode": "Режим трафарета",
- "Inpaint masked": "Внутри трафарета",
- "Inpaint not masked": "Вне трафарета",
- "Masked content": "Под трафаретом",
- "fill": "залить",
- "original": "сохранить",
- "latent noise": "латентный шум",
- "latent nothing": "латентная пустота",
- "Inpaint at full resolution": "Врисовать при полном разрешении",
- "Inpaint at full resolution padding, pixels": "Врисовать с достройкой до полного разрешения, в пикселях",
- "Process images in a directory on the same machine where the server is running.": "Обрабатывать рисунки на том же компьютере, где сервер",
- "Use an empty output directory to save pictures normally instead of writing to the output directory.": "Использовать пустую папку вместо того, чтобы выводить в output",
- "Disabled when launched with --hide-ui-dir-config.": "Выключено при запуске с --hide-ui-dir-config",
- "Input directory": "Папка входа",
- "Output directory": "Папка выхода",
- "Resize mode": "Масштабирование",
- "Just resize": "Только сжать",
- "Crop and resize": "Сжать и обрезать",
- "Resize and fill": "Сжать и залить",
- "img2img alternative test": "рисунок-в-рисунок (альтернатива)",
- "Loopback": "Прокручивание",
- "Outpainting mk2": "Обрисовыватель mk2",
- "Poor man's outpainting": "Хоть какой-то обрисовыватель",
- "SD upscale": "SD-апскейл",
- "should be 2 or lower.": "должно быть меньше равно 2",
- "Override `Sampling method` to Euler?(this method is built for it)": "Сменить метод семплирования на метод Эйлера?(скрипт строился с его учётом)",
- "Override `prompt` to the same value as `original prompt`?(and `negative prompt`)": "Сменить `запрос` на `изначальный запрос`?(и `запрос-исключение`)",
- "Original prompt": "Изначальный запрос",
- "Original negative prompt": "Изначальный запрос-исключение",
- "Override `Sampling Steps` to the same value as `Decode steps`?": "Сменить число шагов на число шагов декодирования?",
- "Decode steps": "Шагов декодирования",
- "Override `Denoising strength` to 1?": "Сменить силу шумоподавления на 1?",
- "Decode CFG scale": "Близость к запросу декодирования",
- "Randomness": "Случайность",
- "Sigma adjustment for finding noise for image": "Поправка к сигме подбора шума для рисунка",
- "Loops": "Циклов",
- "Denoising strength change factor": "Множитель силы шумоподавления",
- "Recommended settings: Sampling Steps: 80-100, Sampler: Euler a, Denoising strength: 0.8": "Рекоммендуемые настройки: Число шагов:80-100,Метод:Euler a,Шумоподавление:0.8",
- "Pixels to expand": "Пикселов расширить",
- "Outpainting direction": "Направление обрисовывания",
- "left": "влево",
- "right": "вправо",
- "up": "вверх",
- "down": "вниз",
- "Fall-off exponent (lower=higher detail)": "Степень затухания (меньше=больше деталей)",
- "Color variation": "Вариация цвета",
- "Will upscale the image to twice the dimensions; use width and height sliders to set tile size": "Расширит рисунок дважды; ползунки ширины и высоты устанавливают размеры плиток",
- "Tile overlap": "Перекрытие плиток",
- "Upscaler": "Апскейлер",
- "Lanczos": "Lanczos",
- "LDSR": "LDSR",
- "BSRGAN 4x": "BSRGAN 4x",
- "ESRGAN_4x": "ESRGAN_4x",
- "R-ESRGAN 4x+ Anime6B": "R-ESRGAN 4x+ Anime6B",
- "ScuNET GAN": "ScuNET GAN",
- "ScuNET PSNR": "ScuNET PSNR",
- "SwinIR_4x": "SwinIR 4x",
- "Single Image": "Один рисунок",
- "Batch Process": "Набор рисунков",
- "Batch from Directory": "Рисунки из папки",
- "Source": "Вход",
- "Show result images": "Показать результаты",
- "Scale by": "Увеличить в",
- "Scale to": "Увеличить до",
- "Resize": "Масштабировать",
- "Crop to fit": "Обрезать до рамки",
- "Upscaler 2": "Апскейлер 2",
- "Upscaler 2 visibility": "Видимость Апскейлера 2",
- "GFPGAN visibility": "Видимость GFPGAN",
- "CodeFormer visibility": "Видимость CodeFormer",
- "CodeFormer weight (0 = maximum effect, 1 = minimum effect)": "Вес CodeFormer (0 = максимальное действие, 1 = минимальное)",
- "Open output directory": "Открыть папку выхода",
- "Send to txt2img": "В текст-в-рисунок",
- "txt2img history": "журнал текста-в-рисунок",
- "img2img history": "журнал рисунка-в-рисунок",
- "extras history": "журнал дополнений",
- "Renew Page": "Обновить страницу",
- "extras": "дополнения",
- "favorites": "избранное",
- "Load": "Загрузить",
- "Images directory": "Папка с рисунками",
- "Prev batch": "Пред. набор",
- "Next batch": "След. набор",
- "First Page": "Первая страница",
- "Prev Page": "Пред. страница",
- "Page Index": "Список страниц",
- "Next Page": "След. страница",
- "End Page": "Конец страницы",
- "number of images to delete consecutively next": "сколько рисунков удалить подряд",
- "Delete": "Удалить",
- "Generate Info": "Сведения о генерации",
- "File Name": "Имя файла",
- "Collect": "Накопить",
- "Refresh page": "Обновить страницу",
- "Date to": "Дата",
- "Number": "Число",
- "set_index": "индекс",
- "Checkbox": "Галочка",
- "A merger of the two checkpoints will be generated in your": "Слияние весов будет создано, где хранятся",
- "checkpoint": "ckpt",
- "directory.": "веса",
- "Primary model (A)": "Первичная модель (A)",
- "Secondary model (B)": "Вторичная модель (B)",
- "Tertiary model (C)": "Третичная модель (C)",
- "Custom Name (Optional)": "Произвольное имя (необязательно)",
- "Multiplier (M) - set to 0 to get model A": "Множитель (M) - 0 даст модель A",
- "Interpolation Method": "Метод интерполяции",
- "Weighted sum": "Взвешенная сумма",
- "Add difference": "Сумма разностей",
- "Save as float16": "Сохранить как float16",
- "See": "См.",
- "wiki": "вики",
- "for detailed explanation.": "для подробных объяснений.",
- "Create embedding": "Создать эмбеддинг",
- "Create aesthetic images embedding": "Создать эмбеддинг эстетики по рисункам",
- "Create hypernetwork": "Создать гиперсеть",
- "Preprocess images": "Предобработать рисунки",
- "Name": "Имя",
- "Initialization text": "Соответствующий текст",
- "Number of vectors per token": "Векторов на токен",
- "Overwrite Old Embedding": "Перезаписать эмбеддинг",
- "Source directory": "Исходная папка",
- "Modules": "Модули",
- "Enter hypernetwork layer structure": "Структура слоёв гиперсети",
- "Add layer normalization": "Добавить нормализацию слоёв",
- "Overwrite Old Hypernetwork": "Перезаписать гиперсеть",
- "Select activation function of hypernetwork": "Функция активации гиперсети",
- "linear": "линейная",
- "relu": "relu",
- "leakyrelu": "leakyrelu",
- "Destination directory": "Папка назначения",
- "Existing Caption txt Action": "Что делать с предыдущим текстом",
- "ignore": "игнорировать",
- "copy": "копировать",
- "prepend": "в начало",
- "append": "в конец",
- "Create flipped copies": "Создать отражённые копии",
- "Split oversized images into two": "Поделить слишком большие рисунки пополам",
- "Split oversized images": "Поделить слишком большие рисунки",
- "Use BLIP for caption": "Использовать BLIP для названий",
- "Use deepbooru for caption": "Использовать deepbooru для тегов",
- "Split image threshold": "Порог разделения рисунков",
- "Split image overlap ratio": "Пропорции разделения рисунков",
- "Preprocess": "Предобработка",
- "Train an embedding; must specify a directory with a set of 1:1 ratio images": "Обучить эмбеддинг; укажите папку рисунков с пропорциями 1:1",
- "Train an embedding or Hypernetwork; you must specify a directory with a set of 1:1 ratio images": "Обучить эмбеддинг или гиперсеть; укажите папку рисунков с пропорциями 1:1",
- "[wiki]": "[вики]",
- "Embedding": "Эмбеддинг",
- "Embedding Learning rate": "Скорость обучения эмбеддинга",
- "Hypernetwork Learning rate": "Скорость обучения гиперсети",
- "Learning rate": "Скорость обучения",
- "Dataset directory": "Папка датасета",
- "Log directory": "Папка журнала",
- "Prompt template file": "Файл шаблона запроса",
- "Max steps": "Макс. шагов",
- "Save an image to log directory every N steps, 0 to disable": "Сохранять рисунок каждые N шагов, 0 чтобы отключить",
- "Save a copy of embedding to log directory every N steps, 0 to disable": "Сохранять эмбеддинг каждые N шагов, 0 чтобы отключить",
- "Save images with embedding in PNG chunks": "Сохранить рисунок с эмбеддингом в виде PNG-фрагментов",
- "Read parameters (prompt, etc...) from txt2img tab when making previews": "Считать параметры (запрос и т.д.) из вкладки текст-в-рисунок для предпросмотра",
- "Train Hypernetwork": "Обучить гиперсеть",
- "Train Embedding": "Обучить эмбеддинг",
- "Create an aesthetic embedding out of any number of images": "Создать эмбеддинг эстетики по любому числу рисунков",
- "Create images embedding": "Создать эмбеддинг рисунков",
- "Apply settings": "Применить настройки",
- "Saving images/grids": "Сохранение рисунков/таблиц",
- "Always save all generated images": "Всегда сохранять созданные рисунки",
- "File format for images": "Формат файла рисунков",
- "Images filename pattern": "Формат имени файлов рисунков",
- "Always save all generated image grids": "Всегда сохранять созданные таблицы",
- "File format for grids": "Формат файла таблиц",
- "Add extended info (seed, prompt) to filename when saving grid": "Вставлять доп. сведения (семя, запрос) в имя файла таблиц",
- "Do not save grids consisting of one picture": "Не сохранять таблицы из одного рисунка",
- "Prevent empty spots in grid (when set to autodetect)": "Не допускать пустоты в таблицах (автообнаружение)",
- "Grid row count; use -1 for autodetect and 0 for it to be same as batch size": "Число строк таблицы; -1, чтобы автоматически, 0 — размер набора",
- "Save text information about generation parameters as chunks to png files": "Встроить сведения о генерации в файлы png",
- "Create a text file next to every image with generation parameters.": "Создать текстовый файл для каждого рисунка с параметрами генерации",
- "Save a copy of image before doing face restoration.": "Сохранить копию перед восстановлением лиц",
- "Quality for saved jpeg images": "Качество jpeg-рисунков",
- "If PNG image is larger than 4MB or any dimension is larger than 4000, downscale and save copy as JPG": "Если размер PNG больше 4МБ или рисунок шире 4000 пикселей, пересжать в JPEG",
- "Use original name for output filename during batch process in extras tab": "Использовать исходное имя выходного файла для обработки набора во вкладке дополнений",
- "When using 'Save' button, only save a single selected image": "Сохранять только один рисунок при нажатии кнопки Сохранить",
- "Do not add watermark to images": "Не добавлять водяной знак",
- "Paths for saving": "Папки сохранений",
- "Output directory for images; if empty, defaults to three directories below": "Папка выхода рисунков; если пусто, использует те, что ниже",
- "Output directory for txt2img images": "Папка выхода текста-в-рисунок",
- "Output directory for img2img images": "Папка выхода рисунка-в-рисунок",
- "Output directory for images from extras tab": "Папка выхода для дополнений",
- "Output directory for grids; if empty, defaults to two directories below": "Папка выхода таблиц; если пусто, использует папки выше",
- "Output directory for txt2img grids": "Папка выхода текста-в-рисунок",
- "Output directory for img2img grids": "Папка выхода рисунка-в-рисунок",
- "Directory for saving images using the Save button": "Папка выхода для кнопки Сохранить",
- "Saving to a directory": "Сохранить в папку",
- "Save images to a subdirectory": "Сохранить рисунки в подпапку",
- "Save grids to a subdirectory": "Сохранить таблицы в подпапку",
- "When using \"Save\" button, save images to a subdirectory": "При нажатии кнопки Сохранить, сложить рисунки в подпапку",
- "Directory name pattern": "Шаблон имени папки",
- "Max prompt words for [prompt_words] pattern": "Макс. число слов для шаблона [prompt_words]",
- "Upscaling": "Апскейл",
- "Tile size for ESRGAN upscalers. 0 = no tiling.": "Размер плитки для ESRGAN. 0 = нет замощения",
- "Tile overlap, in pixels for ESRGAN upscalers. Low values = visible seam.": "Наложение плиток ESRGAN, в пикселях. Меньше = выделеннее шов",
- "Tile size for all SwinIR.": "Размер плиток SwinIR",
- "Tile overlap, in pixels for SwinIR. Low values = visible seam.": "Наложение плиток SwinIR, в пикселях. Меньше = выделеннее шов",
- "LDSR processing steps. Lower = faster": "Число шагов LDSR. Меньше = быстрее",
- "Upscaler for img2img": "Апскейлер рисунка-в-рисунок",
- "Upscale latent space image when doing hires. fix": "Апскейлить образ латентного пространства для HD-режима",
- "Face restoration": "Восстановление лиц",
- "CodeFormer weight parameter; 0 = maximum effect; 1 = minimum effect": "Вес CodeFormer; 0 = максимальное действие; 1 = минимальное",
- "Move face restoration model from VRAM into RAM after processing": "Переместить модель восстановления лиц из ВОЗУ в ОЗУ после обработки",
- "System": "Система",
- "VRAM usage polls per second during generation. Set to 0 to disable.": "Сколько раз в секунду следить за потреблением ВОЗУ. 0, чтобы отключить",
- "Always print all generation info to standard output": "Выводить все сведения о генерации в стандартный вывод",
- "Add a second progress bar to the console that shows progress for an entire job.": "Вторая шкала прогресса для всей задачи",
- "Training": "Обучение",
- "Unload VAE and CLIP from VRAM when training": "Убрать VAE и CLIP из ВОЗУ на время обучения",
- "Move VAE and CLIP to RAM when training hypernetwork. Saves VRAM.": "Переместить VAE и CLIP в ОЗУ на время обучения гиперсети. Сохраняет ВОЗУ",
- "Filename word regex": "Regex имени файла",
- "Filename join string": "Дополнить к имени файла",
- "Number of repeats for a single input image per epoch; used only for displaying epoch number": "Число повторов для каждого рисунка за эпоху; используется только, чтобы отобразить число эпохи",
- "Save an csv containing the loss to log directory every N steps, 0 to disable": "Сохранять csv с параметром loss в папку журнала каждые N шагов, 0 - отключить",
- "Stable Diffusion": "Stable Diffusion",
- "Checkpoints to cache in RAM": "Удерживать веса в ОЗУ",
- "Hypernetwork strength": "Сила гиперсети",
- "Apply color correction to img2img results to match original colors.": "Цветокоррекция вывода рисунка-в-рисунок, сохраняющая исходные цвета",
- "Save a copy of image before applying color correction to img2img results": "Сохранить копию рисунка перед цветокоррекцией",
- "With img2img, do exactly the amount of steps the slider specifies (normally you'd do less with less denoising).": "В режиме рисунок-в-рисунок сделать ровно указанное ползунком число шагов (обычно шумоподавление их уменьшает)",
- "Enable quantization in K samplers for sharper and cleaner results. This may change existing seeds. Requires restart to apply.": "Включить квантование К-семплерах для более резких и чистых результатов. Может потребовать поменять семя. Требует перезапуска.",
- "Emphasis: use (text) to make model pay more attention to text and [text] to make it pay less attention": "Скобки: (понятие) - больше внимания к тексту, [понятие] - меньше внимания к тексту",
- "Use old emphasis implementation. Can be useful to reproduce old seeds.": "Включить старую обработку скобок. Может потребоваться, чтобы воспроизвести старые семена.",
- "Make K-diffusion samplers produce same images in a batch as when making a single image": "Заставить семплеры K-diffusion производить тот же самый рисунок в наборе, как и в единичной генерации",
- "Increase coherency by padding from the last comma within n tokens when using more than 75 tokens": "Увеличить связность, достраивая запрос от последней запятой до n токенов, когда используется свыше 75 токенов",
- "Filter NSFW content": "Фильтровать небезопасный контент",
- "Stop At last layers of CLIP model": "Остановиться на последних слоях модели CLIP",
- "Interrogate Options": "Опции распознавания",
- "Interrogate: keep models in VRAM": "Распознавание: хранить модели в ВОЗУ",
- "Interrogate: use artists from artists.csv": "Распознавание: использовать художников из artists.csv",
- "Interrogate: include ranks of model tags matches in results (Has no effect on caption-based interrogators).": "Распознавание: включить ранжирование совпавших тегов в результате (не работает для распознавателей-создателей заголовков)",
- "Interrogate: num_beams for BLIP": "Распознавание: num_beams для BLIP",
- "Interrogate: minimum description length (excluding artists, etc..)": "Распознавание: минимальная длина описания (исключая художников и т.п.)",
- "Interrogate: maximum description length": "Распознавание: максимальная длина описания",
- "CLIP: maximum number of lines in text file (0 = No limit)": "CLIP: максимальное число строк в текстовом файле (0 = без ограничений)",
- "Interrogate: deepbooru score threshold": "Распознавание: ограничение счёта deepbooru",
- "Interrogate: deepbooru sort alphabetically": "Распознавание: сортировать deepbooru по алфавиту",
- "use spaces for tags in deepbooru": "Пробелы для тегов deepbooru",
- "escape (\\) brackets in deepbooru (so they are used as literal brackets and not for emphasis)": "Использовать скобки в deepbooru как обычные скобки, а не для усиления",
- "User interface": "Пользовательский интерфейс",
- "Show progressbar": "Шкала прогресса",
- "Show image creation progress every N sampling steps. Set 0 to disable.": "Показывать процесс созданния рисунка каждые N шагов. 0 - отключить",
- "Show grid in results for web": "Показать таблицу в выводе браузера",
- "Do not show any images in results for web": "Не показывать выходные рисунки в браузере",
- "Add model hash to generation information": "Добавить хеш весов к параметрам генерации",
- "Add model name to generation information": "Добавить имя весов к параметрам генерации",
- "When reading generation parameters from text into UI (from PNG info or pasted text), do not change the selected model/checkpoint.": "При считывании параметров генерации из текста в интерфейс, не менять выбранную модель/веса.",
- "Font for image grids that have text": "Шрифт для таблиц, содержащих текст",
- "Enable full page image viewer": "Включить полноэкранный просмотр картинок",
- "Show images zoomed in by default in full page image viewer": "По умолчанию увеличивать картинки в полноэкранном просмотре",
- "Show generation progress in window title.": "Отображать прогресс в имени вкладки",
- "Quicksettings list": "Список быстрых настроек",
- "Localization (requires restart)": "Перевод (требует перезапуск)",
- "Sampler parameters": "Параметры семплера",
- "Hide samplers in user interface (requires restart)": "Убрать семплеры из интерфейса (требует перезапуск)",
- "eta (noise multiplier) for DDIM": "eta (множитель шума) DDIM",
- "eta (noise multiplier) for ancestral samplers": "eta (множитель шума) для ancestral-семплеров",
- "img2img DDIM discretize": "дискретизация DDIM для рисунка-в-рисунок",
- "uniform": "однородная",
- "quad": "квадратичная",
- "sigma churn": "сигма-вариация",
- "sigma tmin": "сигма-tmin",
- "sigma noise": "сигма-шум",
- "Eta noise seed delta": "Eta (дельта шума семени)",
- "Images Browser": "Просмотр изображений",
- "Preload images at startup": "Предзагружать рисунки во время запуска",
- "Number of pictures displayed on each page": "Число рисунков на каждой странице",
- "Minimum number of pages per load": "Мин. число загружаемых страниц",
- "Number of grids in each row": "Число таблиц в каждой строке",
- "Request browser notifications": "Запросить уведомления браузера",
- "Download localization template": "Загрузить щаблон перевода",
- "Reload custom script bodies (No ui updates, No restart)": "Перезагрузить пользовательские скрипты (не требует обновления интерфейса и перезапуска)",
- "Restart Gradio and Refresh components (Custom Scripts, ui.py, js and css only)": "Перезагрузить Gradio и обновить компоненты (только пользовательские скрипты, ui.py, js и css)",
- "Prompt (press Ctrl+Enter or Alt+Enter to generate)": "Запрос (нажмите Ctrl+Enter или Alt+Enter для генерации)",
- "Negative prompt (press Ctrl+Enter or Alt+Enter to generate)": "Запрос-исключение (нажмите Ctrl+Enter или Alt+Enter для генерации)",
- "Add a random artist to the prompt.": "Добавить случайного художника к запросу",
- "Read generation parameters from prompt or last generation if prompt is empty into user interface.": "Считать параметры генерации из запроса или из предыдущей генерации в пользовательский интерфейс, если пусто",
- "Save style": "Сохранить стиль",
- "Apply selected styles to current prompt": "Применить выбранные стили к текущему промпту",
- "Stop processing current image and continue processing.": "Прекратить обрабатывать текущий рисунок, но продолжить работу",
- "Stop processing images and return any results accumulated so far.": "Прекратить обрабатку рисунков и вернуть всё, что успели сделать.",
- "Style to apply; styles have components for both positive and negative prompts and apply to both": "Стиль к применению; стили содержат как запрос, так и исключение, и применяют их оба",
- "Do not do anything special": "Не делать ничего особенного",
- "Which algorithm to use to produce the image": "Какой алгоритм использовать для того, чтобы произвести рисунок",
- "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps to higher than 30-40 does not help": "Euler Ancestral - очень творческий, в зависимости от числа шагов может привести совершенно к различным результатам, выше 30-40 лучше не ставить",
- "Denoising Diffusion Implicit Models - best at inpainting": "Denoising Diffusion Implicit модели - лучше всего для обрисовки",
- "Produce an image that can be tiled.": "Сделать из рисунка непрерывную обёртку",
- "Use a two step process to partially create an image at smaller resolution, upscale, and then improve details in it without changing composition": "Применить двушаговый процесс, чтобы создать рисунок на меньшем разрешении, апскейлнуть, а затем улучшить детали без смены композиции",
- "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.": "Определяет, насколько сильно алгоритм будет опираться на содержание изображения. 0 - не меняет ничего, 1 - совсем не связанный выход. Меньше 1.0 процесс использует меньше шагов, чем указано их ползунком.",
- "How many batches of images to create": "Сколько создать наборов из картинок",
- "How many image to create in a single batch": "Сколько картинок создать в каждом наборе",
- "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results": "Classifier Free Guidance Scale: насколько сильно изображение должно соответсвтовать запросу — меньшие значения приведут к более свободным итогам",
- "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result": "Значение, которое определяет выход генератора случайных чисел — если вы создадите рисунок с теми же параметрами и семенем, как у другого изображения, вы получите тот же результат",
- "Set seed to -1, which will cause a new random number to be used every time": "Установить семя в -1, что вызовет каждый раз случайное число",
- "Reuse seed from last generation, mostly useful if it was randomed": "Использовать семя предыдущей генерации, обычно полезно, если оно было случайным",
- "Seed of a different picture to be mixed into the generation.": "Семя с другого рисунка, подмешенного в генерацию.",
- "How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something).": "Насколько сильную вариацию произвести. При 0м значении действия не будет. Для 1 вы получите полноценный рисунок с семенем вариации (кроме ancestral-семплеров, где вы просто что-то получите).",
- "Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution": "Попытаться воспроизвести изображение, похожее на то, чтобы получилось с тем же семенем на выбранном разрешении",
- "This text is used to rotate the feature space of the imgs embs": "Этот текст используется, чтобы произвести вращение пространства признаков из эмбеддинга рисунков",
- "Separate values for X axis using commas.": "Отдельные значения оси X через запятую.",
- "Separate values for Y axis using commas.": "Отдельные значения оси Y через запятую.",
- "Write image to a directory (default - log/images) and generation parameters into csv file.": "Записать изображение в папку (по-умолчанию - log/images), а параметры генерации - в csv файл",
- "Open images output directory": "Открыть папку сохранения изображений",
- "How much to blur the mask before processing, in pixels.": "Насколько пикселей размыть трафарет перед обработкой",
- "What to put inside the masked area before processing it with Stable Diffusion.": "Что поместить в область под трафаретом перед обработкой Stable Diffusion",
- "fill it with colors of the image": "залить цветами изображения",
- "keep whatever was there originally": "сохранить то, что было до этого",
- "fill it with latent space noise": "залить латентным шумом",
- "fill it with latent space zeroes": "залить латентными нулями",
- "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image": "апскейл до нужного разрешения, врисовка, сжатие до начального размера и вставка в исходный рисунок",
- "Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.": "Масшабировать изображение до нужного разрешения. Если только высота и ширина не совпадают, вы получите неверное соотношение сторон.",
- "Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out.": "Масштабировать изображение так, чтобы им заполнялось всё выбранное выходное разрешение. Обрезать выступающие части",
- "Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors.": "Масштабировать изображение так, всё изображение помещалось в выбранное выходное разрешение. Заполнить пустое место цветами изображения.",
- "How many times to repeat processing an image and using it as input for the next iteration": "Сколько раз повторить обработку изображения и использовать её как вход для следующией итерации",
- "In loopback mode, on each loop the denoising strength is multiplied by this value. <1 means decreasing variety so your sequence will converge on a fixed picture. >1 means increasing variety so your sequence will become more and more chaotic.": "В режиме прокрутки, для каждого цикла сила шумоподавления умножается на это значение. <1 уменьшает вариации так, чтобы последовательность сошлась на какой-то одной картинке. >1 увеличивает вариации, так что ваша последовательность станет всё более и более сумбурной.",
- "For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam.": "Для SD-апскейла, как много перекрытия в пикселях должно быть между плитками. Плитки перекрываются таким образом, чтобы они могли сойтись обратно в единое изображение, без видимого шва.",
- "A directory on the same machine where the server is running.": "Папка на той же машине, где запущен сервер",
- "Leave blank to save images to the default path.": "Оставьте пустым, чтобы сохранить рисунки в папку по-умолчанию",
- "Result = A * (1 - M) + B * M": "Выход = A * (1 - M) + B * M",
- "Result = A + (B - C) * M": "Выход = A + (B - C) * M",
- "1st and last digit must be 1. ex:'1, 2, 1'": "1я и последняя цифры должны быть 1. напр.'1, 2, 1'",
- "how fast should the training go. Low values will take longer to train, high values may fail to converge (not generate accurate results) and/or may break the embedding (This has happened if you see Loss: nan in the training info textbox. If this happens, you need to manually restore your embedding from an older not-broken backup).\n\nYou can set a single numeric value, or multiple learning rates using the syntax:\n\n rate_1:max_steps_1, rate_2:max_steps_2, ...\n\nEG: 0.005:100, 1e-3:1000, 1e-5\n\nWill train with rate of 0.005 for first 100 steps, then 1e-3 until 1000 steps, then 1e-5 for all remaining steps.": "как быстро будет происходить обучение. Меньшие значения увеличат время обучения, но высокие могут нарушить сходимость модели (не будет создавать должные результаты) и/или сломать эмбеддинг. (Это случилось, если вы видете Loss: nan в текстовом окне вывода обучения. В этом случае вам придётся восстанавливать эмбеддинг вручную из старой, не повреждённой резервной копии).\n\nВы также можете указать единичное значение или последовательность из нескольких, используя следующий синтаксис:\n\n rate_1:max_steps_1, rate_2:max_steps_2, ...\n\nEG: 0.005:100, 1e-3:1000, 1e-5\n\nБудет обучаться со скоростью 0.005 первые 100 шагов, затем 1e-3 до 1000 шагов, после 1e-5 для всех оставшихся шагов.",
- "Path to directory with input images": "Путь к папке со входными изображениями",
- "Path to directory where to write outputs": "Путь к папке, в которую записывать результаты",
- "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; leave empty for default.": "Используйте следующие теги, чтобы определить, как подбираются названия файлов для изображений: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; если пусто, используется значение по-умолчанию",
- "If this option is enabled, watermark will not be added to created images. Warning: if you do not add watermark, you may be behaving in an unethical manner.": "Когда эта опция включена, на созданные изображения не будет добавляться водяной знак. Предупреждение: не добавляя водяной знак, вы, вероятно, ведёте себя аморально.",
- "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; leave empty for default.": "Используйте следующие теги, чтобы определить, как подбираются названия подпапок для рисунков и табоиц: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; если пусто, используется значение по-умолчанию",
- "Restore low quality faces using GFPGAN neural network": "Восстановить низкокачественные лица, используя нейросеть GFPGAN",
- "This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is.": "Это регулярное выражение будет использовано, чтобы извлечь слова из имени файла, и они будут соединены с текстом в метке ниже как вход во время обучения. Оставьте пустым, чтобы сохранить имя файла как есть",
- "This string will be used to join split words into a single line if the option above is enabled.": "Эта строка будет использована, чтобы объединить разделённые слова в одну строку, если включена опция выше.",
- "List of setting names, separated by commas, for settings that should go to the quick access bar at the top, rather than the usual setting tab. See modules/shared.py for setting names. Requires restarting to apply.": "Список имён настроек, разделённый запятыми, предназначенных для быстрого доступа через панель наверху, а не через привычную вкладку настроек. Для применения требует перезапуска.",
- "If this values is non-zero, it will be added to seed and used to initialize RNG for noises when using samplers with Eta. You can use this to produce even more variation of images, or you can use this to match images of other software if you know what you are doing.": "Если это значение не нулевое, оно будет добавлено к семени и использовано для инициалицации ГСЧ шума семплеров с параметром Eta. Вы можете использовать это, чтобы произвести ещё больше вариаций рисунков, либо же для того, чтобы подойти близко к результатам других программ, если знаете, что делаете.",
- "Enable Autocomplete": "Включить автодополнение",
- "Allowed categories for random artists selection when using the Roll button": "Разрешённые категории художников для случайного выбора при использовании кнопки + три",
- "Roll three": "+ три",
- "Generate forever": "Непрерывная генерация",
- "Cancel generate forever": "Отключить непрерывную генерацию"
-}
diff --git a/localizations/tr_TR.json b/localizations/tr_TR.json
deleted file mode 100644
index 74cdf056..00000000
--- a/localizations/tr_TR.json
+++ /dev/null
@@ -1,423 +0,0 @@
-{
- "⤡": "⤡",
- "⊞": "⊞",
- "×": "×",
- "❮": "❮",
- "❯": "❯",
- "Loading...": "Yükleniyor...",
- "view": "arayüz",
- "api": "",
- "•": "-",
- "built with gradio": "gradio ile inşa edildi",
- "Stable Diffusion checkpoint": "Kararlı Difüzyon kontrol noktası",
- "txt2img": "txt2img",
- "img2img": "img2img",
- "Extras": "Ekstralar",
- "PNG Info": "PNG Bilgisi",
- "Checkpoint Merger": "Checkpoint Birleştir",
- "Train": "Eğitim",
- "Settings": "Ayarlar",
- "Prompt": "İstem",
- "Negative prompt": "Negatif istem",
- "Run": "Koşmak",
- "Skip": "Atla",
- "Interrupt": "Durdur",
- "Generate": "Oluştur",
- "Style 1": "Stil 1",
- "Style 2": "Stil 2",
- "Label": "Etiket",
- "File": "Dosya",
- "Drop File Here": "Dosyayı Buraya Bırakın",
- "-": "-",
- "or": "veya",
- "Click to Upload": "Yüklemek için Tıklayınız",
- "Image": "Resim",
- "Check progress": "İlerlemeyi kontrol edin",
- "Check progress (first)": "Önce ilerlemeyi kontrol edin",
- "Sampling Steps": "Örnekleme Adımları",
- "Sampling method": "Örnekleme yöntemi",
- "Euler a": "Euler a",
- "Euler": "Euler",
- "LMS": "LMS",
- "Heun": "Heun",
- "DPM2": "DPM2",
- "DPM2 a": "DPM2 a",
- "DPM fast": "DPM hızlı",
- "DPM adaptive": "DPM uyarlanabilir",
- "LMS Karras": "LMS Karras",
- "DPM2 Karras": "DPM2 Karras",
- "DPM2 a Karras": "DPM2 a Karras",
- "DDIM": "DDIM",
- "PLMS": "PLMS",
- "Width": "Genişlik",
- "Height": "Yükseklik",
- "Restore faces": "Yüzleri düzeltme",
- "Tiling": "Döşeme Oluştur",
- "Highres. fix": "Highres. düzeltme",
- "Firstpass width": "İlk geçiş genişliği",
- "Firstpass height": "İlk geçiş yüksekliği",
- "Denoising strength": "Gürültü arındırma gücü",
- "Batch count": "Grup sayısı",
- "Batch size": "Grup büyüklüğü",
- "CFG Scale": "CFG Ölçeği",
- "Seed": "Tohum",
- "Extra": "Ekstra",
- "Variation seed": "Varyasyon tohumu",
- "Variation strength": "Varyasyon gücü",
- "Resize seed from width": "Tohumu genişlik ile yeniden boyutlandırma",
- "Resize seed from height": "Tohumu yükseklik ile yeniden boyutlandırma",
- "Script": "Scriptler",
- "None": "Hiçbiri",
- "Prompt matrix": "İstem matrisi",
- "Prompts from file or textbox": "Dosyadan veya metin kutusundan istemler",
- "X/Y plot": "X/Y grafiği",
- "Put variable parts at start of prompt": "Değişken parçaları komut isteminin başına koyun",
- "Show Textbox": "Metin Kutusunu Göster",
- "File with inputs": "Girdileri içeren dosya",
- "Prompts": "İpuçları",
- "X type": "X tipi",
- "Nothing": "Hiçbir şey",
- "Var. seed": "Var. tohum",
- "Var. strength": "Var. güç",
- "Steps": "Adımlar",
- "Prompt S/R": "İstem S/R",
- "Prompt order": "İstem sırası",
- "Sampler": "Örnekleyici",
- "Checkpoint name": "Kontrol noktası adı",
- "Hypernetwork": "Hipernetwork",
- "Hypernet str.": "Hypernet str.",
- "Sigma Churn": "Sigma Churn",
- "Sigma min": "Sigma dakika",
- "Sigma max": "Sigma maksimum",
- "Sigma noise": "Sigma gürültüsü",
- "Eta": "Eta",
- "Clip skip": "Klip atlama",
- "Denoising": "Denoising",
- "X values": "X değerleri",
- "Y type": "Y tipi",
- "Y values": "Y değerleri",
- "Draw legend": "Gösterge çizin",
- "Include Separate Images": "Ayrı Görseller Ekleyin",
- "Keep -1 for seeds": "Tohumlar için -1'i saklayın",
- "Drop Image Here": "Resmi Buraya Bırakın",
- "Save": "Kaydet",
- "Send to img2img": "img2img'ye gönder",
- "Send to inpaint": "Inpaint'e gönder",
- "Send to extras": "Ekstralara gönder",
- "Make Zip when Save?": "Kaydederken Zip Yap?",
- "Textbox": "Metin Kutusu",
- "Interrogate\nCLIP": "Sorgula\nCLIP",
- "Inpaint": "Inpaint",
- "Batch img2img": "Toplu img2img",
- "Image for img2img": "img2img için resim",
- "Image for inpainting with mask": "Maske ile inpainting için görüntü",
- "Mask": "Maske",
- "Mask blur": "Maske bulanıklığı",
- "Mask mode": "Maske modu",
- "Draw mask": "Maske çizin",
- "Upload mask": "Maske yükle",
- "Masking mode": "Maskeleme modu",
- "Inpaint masked": "Maskeli inpaint",
- "Inpaint not masked": "Boya maskelenmemiş",
- "Masked content": "Maskelenmiş içerik",
- "fill": "doldurun",
- "original": "orijinal",
- "latent noise": "gizli gürültü",
- "latent nothing": "gizli hiçbir şey",
- "Inpaint at full resolution": "Tam çözünürlükte inpaint",
- "Inpaint at full resolution padding, pixels": "Tam çözünürlükte inpaint dolgu, piksel",
- "Process images in a directory on the same machine where the server is running.": "Görüntüleri sunucunun çalıştığı makinedeki bir dizinde işleyin.",
- "Use an empty output directory to save pictures normally instead of writing to the output directory.": "Resimleri çıktı dizinine yazmak yerine normal şekilde kaydetmek için boş bir çıktı dizini kullanın.",
- "Input directory": "Girdi dizini",
- "Output directory": "Çıktı dizini",
- "Resize mode": "Yeniden boyutlandırma modu",
- "Just resize": "Sadece yeniden boyutlandır",
- "Crop and resize": "Kırpma ve yeniden boyutlandırma",
- "Resize and fill": "Yeniden boyutlandırın ve doldurun",
- "img2img alternative test": "img2img alternatif test",
- "Loopback": "Geri Döngü",
- "Outpainting mk2": "Outpainting mk2",
- "Poor man's outpainting": "Zavallı adamın dış boyaması",
- "SD upscale": "SD lüks",
- "should be 2 or lower.": "2 veya daha düşük olmalıdır.",
- "Override `Sampling method` to Euler?(this method is built for it)": "Euler için `Örnekleme yöntemini` geçersiz kılın (bu yöntem bunun için oluşturulmuştur)",
- "Override `prompt` to the same value as `original prompt`?(and `negative prompt`)": "Prompt` değerini `orijinal prompt` ile aynı değere geçersiz kılma (ve `negatif prompt`)",
- "Original prompt": "Orijinal bilgi istemi",
- "Original negative prompt": "Orijinal negatif istem",
- "Override `Sampling Steps` to the same value as `Decode steps`?": "Örnekleme Adımlarını `Kod çözme adımları` ile aynı değere mi geçersiz kılıyorsunuz?",
- "Decode steps": "Kod çözme adımları",
- "Override `Denoising strength` to 1?": "`Denoising strength` değerini 1 olarak geçersiz kıl?",
- "Decode CFG scale": "CFG ölçeğinin kodunu çöz",
- "Randomness": "Rastgelelik",
- "Sigma adjustment for finding noise for image": "Görüntü için gürültü bulmaya yönelik Sigma ayarı",
- "Loops": "Döngüler",
- "Denoising strength change factor": "Denoising gücü değişim faktörü",
- "Recommended settings: Sampling Steps: 80-100, Sampler: Euler a, Denoising strength: 0.8": "Önerilen ayarlar: Örnekleme Adımları: 80-100, Örnekleyici: Euler a, Denoising gücü: 0.8",
- "Pixels to expand": "Genişletilecek pikseller",
- "Outpainting direction": "Dış boyama yönü",
- "left": "sol",
- "right": "doğru",
- "up": "yukarı",
- "down": "aşağı",
- "Fall-off exponent (lower=higher detail)": "Düşme üssü (düşük=daha yüksek detay)",
- "Color variation": "Renk çeşitliliği",
- "Will upscale the image to twice the dimensions; use width and height sliders to set tile size": "Görüntüyü boyutlarının iki katına yükseltir; döşeme boyutunu ayarlamak için genişlik ve yükseklik kaydırıcılarını kullanın",
- "Tile overlap": "Karo örtüşmesi",
- "Upscaler": "Upscaler",
- "Lanczos": "Lanczos",
- "LDSR": "LDSR",
- "SwinIR 4x": "SwinIR 4x",
- "ScuNET GAN": "ScuNET GAN",
- "ScuNET PSNR": "ScuNET PSNR",
- "ESRGAN_4x": "ESRGAN_4x",
- "Single Image": "Tek Resim",
- "Batch Process": "Toplu İşlem",
- "Batch from Directory": "Dizinden Toplu İş",
- "Source": "Kaynak",
- "Show result images": "Sonuç resimlerini göster",
- "Scale by": "Ölçek tarafından",
- "Scale to": "Ölçeklendir",
- "Resize": "Yeniden Boyutlandır",
- "Crop to fit": "Sığdırmak için kırpın",
- "Upscaler 2 visibility": "Upscaler 2 görünürlüğü",
- "GFPGAN visibility": "GFPGAN görünürlüğü",
- "CodeFormer visibility": "CodeFormer görünürlüğü",
- "CodeFormer weight (0 = maximum effect, 1 = minimum effect)": "CodeFormer ağırlığı (0 = maksimum etki, 1 = minimum etki)",
- "Open output directory": "Çıktı dizinini aç",
- "Send to txt2img": "txt2img'ye gönder",
- "A merger of the two checkpoints will be generated in your": "İki kontrol noktasının bir birleşimi sizin kontrol noktanızda oluşturulacaktır.",
- "checkpoint": "kontrol noktası",
- "directory.": "dizin.",
- "Primary model (A)": "Birincil model (A)",
- "Secondary model (B)": "İkincil model (B)",
- "Tertiary model (C)": "Üçüncü model (C)",
- "Custom Name (Optional)": "Özel Ad (İsteğe Bağlı)",
- "Multiplier (M) - set to 0 to get model A": "Çarpan (M) - A modelini elde etmek için 0'a ayarlayın",
- "Interpolation Method": "İnterpolasyon Yöntemi",
- "Weighted sum": "Ağırlıklı toplam",
- "Add difference": "Farklılık ekleyin",
- "Save as float16": "float16 olarak kaydet",
- "See": "Bkz. ",
- "wiki": "wiki",
- "for detailed explanation.": " ayrıntılı açıklama için.",
- "Create embedding": "Yerleştirme oluşturma",
- "Create hypernetwork": "Hipernet oluşturun",
- "Preprocess images": "Görüntüleri ön işleme",
- "Name": "İsim",
- "Initialization text": "Başlatma metni",
- "Number of vectors per token": "Belirteç başına vektör sayısı",
- "Overwrite Old Embedding": "Eski Yerleştirmenin Üzerine Yaz",
- "Modules": "Modüller",
- "Enter hypernetwork layer structure": "Hipernetwork katman yapısına girin",
- "Select activation function of hypernetwork": "Hipernetwork'ün aktivasyon fonksiyonunu seçin",
- "linear": "doğrusal",
- "relu": "relu",
- "leakyrelu": "leakyrelu",
- "elu": "elu",
- "swish": "swish",
- "Add layer normalization": "Katman normalizasyonu ekleyin",
- "Use dropout": "Bırakmayı kullanın",
- "Overwrite Old Hypernetwork": "Eski Hipernetwork'ün Üzerine Yazma",
- "Source directory": "Kaynak dizini",
- "Destination directory": "Hedef dizini",
- "Existing Caption txt Action": "Mevcut Başlık txt Eylem",
- "ignore": "görmezden gel",
- "copy": "kopya",
- "prepend": "prepend",
- "append": "ekle",
- "Create flipped copies": "Ters çevrilmiş kopyalar oluşturun",
- "Split oversized images": "Büyük boyutlu görüntüleri bölme",
- "Use BLIP for caption": "Başlık için BLIP kullanın",
- "Use deepbooru for caption": "Başlık için deepbooru kullanın",
- "Split image threshold": "Bölünmüş görüntü eşiği",
- "Split image overlap ratio": "Bölünmüş görüntü örtüşme oranı",
- "Preprocess": "Ön işlem",
- "Train an embedding or Hypernetwork; you must specify a directory with a set of 1:1 ratio images": "Bir gömme veya Hipernetwork eğitin; 1:1 oranlı görüntülerin bulunduğu bir dizin belirtmelisiniz",
- "[wiki]": "[wiki]",
- "Embedding": "Yerleştirme",
- "Embedding Learning rate": "Gömme Öğrenme oranı",
- "Hypernetwork Learning rate": "Hypernetwork Öğrenme oranı",
- "Dataset directory": "Veri seti dizini",
- "Log directory": "Günlük dizini",
- "Prompt template file": "Komut istemi şablon dosyası",
- "Max steps": "Maksimum adım",
- "Save an image to log directory every N steps, 0 to disable": "Her N adımda bir görüntüyü günlük dizinine kaydet, 0 devre dışı bırakmak için",
- "Save a copy of embedding to log directory every N steps, 0 to disable": "Katıştırmanın bir kopyasını her N adımda bir günlük dizinine kaydedin, devre dışı bırakmak için 0",
- "Save images with embedding in PNG chunks": "Görüntüleri PNG parçalarına yerleştirerek kaydedin",
- "Read parameters (prompt, etc...) from txt2img tab when making previews": "Önizleme yaparken txt2img sekmesinden parametreleri (istem, vb...) okuma",
- "Train Hypernetwork": "Tren Hipernetwork",
- "Train Embedding": "Tren Gömme",
- "Apply settings": "Ayarları uygula",
- "Saving images/grids": "Görüntüleri/gridleri kaydetme",
- "Always save all generated images": "Oluşturulan tüm görüntüleri her zaman kaydedin",
- "File format for images": "Görüntüler için dosya formatı",
- "Images filename pattern": "Görüntü dosya adı deseni",
- "Add number to filename when saving": "Kaydederken dosya adına numara ekle",
- "Always save all generated image grids": "Oluşturulan tüm görüntü ızgaralarını her zaman kaydedin",
- "File format for grids": "Izgaralar için dosya formatı",
- "Add extended info (seed, prompt) to filename when saving grid": "Izgarayı kaydederken dosya adına genişletilmiş bilgi (tohum, istem) ekleyin",
- "Do not save grids consisting of one picture": "Tek resimden oluşan ızgaraları kaydetmeyin",
- "Prevent empty spots in grid (when set to autodetect)": "Izgaradaki boş noktaları önleme (otomatik algılamaya ayarlandığında)",
- "Grid row count; use -1 for autodetect and 0 for it to be same as batch size": "Izgara satır sayısı; otomatik algılama için -1, yığın boyutuyla aynı olması için 0 kullanın",
- "Save text information about generation parameters as chunks to png files": "Üretim parametreleri hakkındaki metin bilgilerini png dosyalarına parçalar halinde kaydedin",
- "Create a text file next to every image with generation parameters.": "Oluşturma parametreleri ile her görüntünün yanında bir metin dosyası oluşturun.",
- "Save a copy of image before doing face restoration.": "Yüz restorasyonu yapmadan önce görüntünün bir kopyasını kaydedin.",
- "Quality for saved jpeg images": "Kaydedilen jpeg görüntüleri için kalite",
- "If PNG image is larger than 4MB or any dimension is larger than 4000, downscale and save copy as JPG": "PNG görüntüsü 4MB'den büyükse veya herhangi bir boyut 4000'den büyükse, ölçeği küçültün ve kopyayı JPG olarak kaydedin",
- "Use original name for output filename during batch process in extras tab": "Ekstralar sekmesinde toplu işlem sırasında çıktı dosya adı için orijinal adı kullan",
- "When using 'Save' button, only save a single selected image": "'Kaydet' düğmesini kullanırken, yalnızca seçilen tek bir resmi kaydedin",
- "Do not add watermark to images": "Görüntülere filigran eklemeyin",
- "Paths for saving": "Tasarruf için yollar",
- "Output directory for images; if empty, defaults to three directories below": "Görüntüler için çıktı dizini; boşsa, varsayılan olarak aşağıdaki üç dizine gider",
- "Output directory for txt2img images": "txt2img görüntüleri için çıktı dizini",
- "Output directory for img2img images": "img2img görüntüleri için çıktı dizini",
- "Output directory for images from extras tab": "Ekstralar sekmesindeki görüntüler için çıktı dizini",
- "Output directory for grids; if empty, defaults to two directories below": "Izgaralar için çıktı dizini; boşsa, varsayılan olarak aşağıdaki iki dizine gider",
- "Output directory for txt2img grids": "txt2img ızgaraları için çıktı dizini",
- "Output directory for img2img grids": "img2img ızgaraları için çıktı dizini",
- "Directory for saving images using the Save button": "Kaydet düğmesini kullanarak görüntüleri kaydetmek için dizin",
- "Saving to a directory": "Bir dizine kaydetme",
- "Save images to a subdirectory": "Görüntüleri bir alt dizine kaydetme",
- "Save grids to a subdirectory": "Izgaraları bir alt dizine kaydetme",
- "When using \"Save\" button, save images to a subdirectory": "\"Kaydet\" düğmesini kullanırken, görüntüleri bir alt dizine kaydedin",
- "Directory name pattern": "Dizin adı kalıbı",
- "Max prompt words for [prompt_words] pattern": "prompt_words] kalıbı için maksimum istem sözcükleri",
- "Upscaling": "Yükseltme",
- "Tile size for ESRGAN upscalers. 0 = no tiling.": "ESRGAN yükselticileri için döşeme boyutu. 0 = döşeme yok.",
- "Tile overlap, in pixels for ESRGAN upscalers. Low values = visible seam.": "ESRGAN yükselticileri için piksel cinsinden döşeme örtüşmesi. Düşük değerler = görünür bağlantı hattı.",
- "Tile size for all SwinIR.": "Tüm SwinIR için döşeme boyutu.",
- "Tile overlap, in pixels for SwinIR. Low values = visible seam.": "SwinIR için piksel cinsinden döşeme örtüşmesi. Düşük değerler = görünür dikiş.",
- "LDSR processing steps. Lower = faster": "LDSR işleme adımları. Düşük = daha hızlı",
- "Upscaler for img2img": "img2img için üst ölçekleyici",
- "Upscale latent space image when doing hires. fix": "İşe alım yaparken gizli alan görüntüsünü yükselt. düzelt",
- "Face restoration": "Yüz restorasyonu",
- "CodeFormer weight parameter; 0 = maximum effect; 1 = minimum effect": "CodeFormer ağırlık parametresi; 0 = maksimum etki; 1 = minimum etki",
- "Move face restoration model from VRAM into RAM after processing": "İşlemden sonra yüz restorasyon modelini VRAM'den RAM'e taşıma",
- "System": "Sistem",
- "VRAM usage polls per second during generation. Set to 0 to disable.": "Üretim sırasında saniye başına VRAM kullanım yoklamaları. Devre dışı bırakmak için 0 olarak ayarlayın.",
- "Always print all generation info to standard output": "Tüm üretim bilgilerini her zaman standart çıktıya yazdır",
- "Add a second progress bar to the console that shows progress for an entire job.": "Konsola tüm iş için ilerlemeyi gösteren ikinci bir ilerleme çubuğu ekleyin.",
- "Training": "Eğitim",
- "Move VAE and CLIP to RAM when training hypernetwork. Saves VRAM.": "Hiperneti eğitirken VAE ve CLIP'i RAM'e taşıyın. VRAM'den tasarruf sağlar.",
- "Filename word regex": "Dosya adı kelime regex",
- "Filename join string": "Dosya adı birleştirme dizesi",
- "Number of repeats for a single input image per epoch; used only for displaying epoch number": "Epok başına tek bir girdi görüntüsü için tekrar sayısı; yalnızca epok numarasını görüntülemek için kullanılır",
- "Save an csv containing the loss to log directory every N steps, 0 to disable": "Her N adımda bir günlük dizinine kaybı içeren bir csv kaydedin, devre dışı bırakmak için 0",
- "Stable Diffusion": "Kararlı Difüzyon",
- "Checkpoints to cache in RAM": "RAM'de önbelleğe alınacak kontrol noktaları",
- "Hypernetwork strength": "Hipernetwork gücü",
- "Apply color correction to img2img results to match original colors.": "Orijinal renklerle eşleştirmek için img2img sonuçlarına renk düzeltmesi uygulayın.",
- "Save a copy of image before applying color correction to img2img results": "img2img sonuçlarına renk düzeltmesi uygulamadan önce görüntünün bir kopyasını kaydedin",
- "With img2img, do exactly the amount of steps the slider specifies (normally you'd do less with less denoising).": "img2img ile, kaydırıcının belirttiği adım miktarını tam olarak yapın (normalde daha az denoising ile daha az yaparsınız).",
- "Enable quantization in K samplers for sharper and cleaner results. This may change existing seeds. Requires restart to apply.": "Daha keskin ve temiz sonuçlar için K örnekleyicilerinde nicelemeyi etkinleştirin. Bu, mevcut tohumları değiştirebilir. Uygulamak için yeniden başlatma gerektirir.",
- "Emphasis: use (text) to make model pay more attention to text and [text] to make it pay less attention": "Vurgu: modelin metne daha fazla dikkat etmesini sağlamak için (metin) ve daha az dikkat etmesini sağlamak için [metin] kullanın",
- "Use old emphasis implementation. Can be useful to reproduce old seeds.": "Eski vurgu uygulamasını kullanın. Eski tohumları yeniden üretmek faydalı olabilir.",
- "Make K-diffusion samplers produce same images in a batch as when making a single image": "K-difüzyon örnekleyicilerinin tek bir görüntü oluştururken olduğu gibi toplu halde aynı görüntüleri üretmesini sağlayın",
- "Increase coherency by padding from the last comma within n tokens when using more than 75 tokens": "75'ten fazla belirteç kullanıldığında n belirteç içindeki son virgülden itibaren dolgu yaparak tutarlılığı artırın",
- "Filter NSFW content": "NSFW içeriği filtreleme",
- "Stop At last layers of CLIP model": "Durdur CLIP modelinin son katmanlarında",
- "Interrogate Options": "Sorgulama Seçenekleri",
- "Interrogate: keep models in VRAM": "Sorgula: modelleri VRAM'de tut",
- "Interrogate: use artists from artists.csv": "Sorgula: artists.csv dosyasındaki sanatçıları kullan",
- "Interrogate: include ranks of model tags matches in results (Has no effect on caption-based interrogators).": "Interrogate: sonuçlara eşleşen model etiketlerinin sıralarını dahil et (Başlık tabanlı sorgulayıcılar üzerinde etkisi yoktur).",
- "Interrogate: num_beams for BLIP": "Sorgula: BLIP için num_beams",
- "Interrogate: minimum description length (excluding artists, etc..)": "Sorgula: minimum açıklama uzunluğu (sanatçılar vb. hariç)",
- "Interrogate: maximum description length": "Sorgula: maksimum açıklama uzunluğu",
- "CLIP: maximum number of lines in text file (0 = No limit)": "CLIP: metin dosyasındaki maksimum satır sayısı (0 = Sınır yok)",
- "Interrogate: deepbooru score threshold": "Sorgula: deepbooru puan eşiği",
- "Interrogate: deepbooru sort alphabetically": "Sorgula: deepbooru alfabetik olarak sırala",
- "use spaces for tags in deepbooru": "deepbooru'da etiketler için boşluk kullanın",
- "escape (\\) brackets in deepbooru (so they are used as literal brackets and not for emphasis)": "deepbooru'da kaçış (\\) parantezleri (böylece vurgu için değil, gerçek parantez olarak kullanılırlar)",
- "User interface": "Kullanıcı arayüzü",
- "Show progressbar": "İlerleme çubuğunu göster",
- "Show image creation progress every N sampling steps. Set 0 to disable.": "Her N örnekleme adımında görüntü oluşturma ilerlemesini gösterir. Devre dışı bırakmak için 0 olarak ayarlayın.",
- "Show previews of all images generated in a batch as a grid": "Bir toplu işte oluşturulan tüm görüntülerin önizlemelerini ızgara olarak göster",
- "Show grid in results for web": "Web için sonuçlarda ızgarayı göster",
- "Do not show any images in results for web": "Web için sonuçlarda herhangi bir resim gösterme",
- "Add model hash to generation information": "Üretim bilgilerine model karması ekleyin",
- "Add model name to generation information": "Üretim bilgilerine model adı ekleme",
- "When reading generation parameters from text into UI (from PNG info or pasted text), do not change the selected model/checkpoint.": "Üretim parametrelerini metinden kullanıcı arayüzüne okurken (PNG bilgisinden veya yapıştırılan metinden), seçilen modeli/denetim noktasını değiştirmeyin.",
- "Font for image grids that have text": "Metin içeren görüntü ızgaraları için yazı tipi",
- "Enable full page image viewer": "Tam sayfa resim görüntüleyiciyi etkinleştir",
- "Show images zoomed in by default in full page image viewer": "Tam sayfa resim görüntüleyicide resimleri varsayılan olarak yakınlaştırılmış olarak gösterme",
- "Show generation progress in window title.": "Pencere başlığında üretim ilerlemesini göster.",
- "Quicksettings list": "Hızlı ayarlar listesi",
- "Localization (requires restart)": "Yerelleştirme (yeniden başlatma gerektirir)",
- "ko_KR": "ko_KR",
- "ru_RU": "ru_RU",
- "es_ES": "es_ES",
- "ja_JP": "ja_JP",
- "ar_AR": "ar_AR",
- "Sampler parameters": "Örnekleyici parametreleri",
- "Hide samplers in user interface (requires restart)": "Kullanıcı arayüzünde örnekleyicileri gizle (yeniden başlatma gerektirir)",
- "eta (noise multiplier) for DDIM": "DDIM için eta (gürültü çarpanı)",
- "eta (noise multiplier) for ancestral samplers": "eta örnekleyiciler için eta (gürültü çarpanı)",
- "img2img DDIM discretize": "img2img DDIM discretize",
- "uniform": "üniforma",
- "quad": "dörtlü",
- "sigma churn": "sigma churn",
- "sigma tmin": "sigma tmin",
- "sigma noise": "sigma gürültüsü",
- "Eta noise seed delta": "Eta gürültü tohum deltası",
- "Request browser notifications": "Tarayıcı bildirimleri isteyin",
- "Download localization template": "Dil şablonunu indirin",
- "Reload custom script bodies (No ui updates, No restart)": "Kişisel komut dosyası gövdelerini yeniden yükle (Kullanıcı arayüzü güncellemesi yok, yeniden başlatma yok)",
- "Restart Gradio and Refresh components (Custom Scripts, ui.py, js and css only)": "Gradio'yu yeniden başlatın ve bileşenleri yenileyin (yalnızca Özel Komut Dosyaları, ui.py, js ve css)",
- "Prompt (press Ctrl+Enter or Alt+Enter to generate)": "İstem (oluşturmak için Ctrl+Enter veya Alt+Enter tuşlarına basın)",
- "Negative prompt (press Ctrl+Enter or Alt+Enter to generate)": "Negatif istem (oluşturmak için Ctrl+Enter veya Alt+Enter tuşlarına basın)",
- "Add a random artist to the prompt.": "Komut istemine rastgele bir sanatçı ekleyin.",
- "Read generation parameters from prompt or last generation if prompt is empty into user interface.": "Kullanıcı arayüzüne istemden veya istem boşsa son üretimden üretim parametrelerini okuyun.",
- "Save style": "Stil kaydet",
- "Apply selected styles to current prompt": "Seçilen stilleri geçerli komut istemine uygulama",
- "Stop processing current image and continue processing.": "Geçerli görüntüyü işlemeyi durdurun ve işlemeye devam edin.",
- "Stop processing images and return any results accumulated so far.": "Görüntüleri işlemeyi durdurun ve o ana kadar biriken tüm sonuçları döndürün.",
- "Style to apply; styles have components for both positive and negative prompts and apply to both": "Uygulanacak stil; stillerin hem pozitif hem de negatif istemler için bileşenleri vardır ve her ikisine de uygulanır",
- "Do not do anything special": "Özel bir şey yapmayın",
- "Which algorithm to use to produce the image": "Görüntüyü üretmek için hangi algoritmanın kullanılacağı",
- "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps to higher than 30-40 does not help": "Euler Ancestral - çok yaratıcı, adım sayısına bağlı olarak her biri tamamen farklı bir resim elde edebilir, adımları 30-40'tan daha yükseğe ayarlamak yardımcı olmaz",
- "Denoising Diffusion Implicit Models - best at inpainting": "Denoising Difüzyon Örtük Modelleri - en iyi inpainting",
- "Produce an image that can be tiled.": "Döşenebilen bir görüntü üretin.",
- "Use a two step process to partially create an image at smaller resolution, upscale, and then improve details in it without changing composition": "Bir görüntüyü kısmen daha düşük çözünürlükte oluşturmak, büyütmek ve ardından kompozisyonu değiştirmeden ayrıntıları iyileştirmek için iki adımlı bir işlem kullanın",
- "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.": "Algoritmanın resmin içeriğine ne kadar az saygı göstermesi gerektiğini belirler. 0'da hiçbir şey değişmez ve 1'de ilgisiz bir görüntü elde edersiniz. 1,0'ın altındaki değerlerde işleme, Örnekleme Adımları kaydırıcısının belirttiğinden daha az adım atacaktır.",
- "How many batches of images to create": "Kaç görüntü grubu oluşturulacağı",
- "How many image to create in a single batch": "Tek bir partide kaç görüntü oluşturulacağı",
- "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results": "Sınıflandırıcı Serbest Rehberlik Ölçeği - görüntünün istemle ne kadar uyumlu olması gerektiği - düşük değerler daha yaratıcı sonuçlar üretir",
- "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result": "Rastgele sayı üretecinin çıktısını belirleyen bir değer - başka bir resimle aynı parametrelere ve tohuma sahip bir resim oluşturursanız, aynı sonucu alırsınız",
- "Set seed to -1, which will cause a new random number to be used every time": "Tohum değerini -1 olarak ayarlayın, bu her seferinde yeni bir rastgele sayı kullanılmasına neden olacaktır",
- "Reuse seed from last generation, mostly useful if it was randomed": "Son nesilden tohumu yeniden kullanın, çoğunlukla rastgele ise kullanışlıdır",
- "Seed of a different picture to be mixed into the generation.": "Nesle karıştırılacak farklı bir resmin tohumu.",
- "How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something).": "Ne kadar güçlü bir varyasyon üretileceği. 0'da hiçbir etki olmayacaktır. 1'de, varyasyon tohumu ile tam bir resim elde edersiniz (sadece bir şey alacağınız atasal örnekleyiciler hariç).",
- "Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution": "Belirtilen çözünürlükte aynı tohumla üretilecek olana benzer bir resim üretme girişiminde bulunun",
- "Separate values for X axis using commas.": "X ekseni için değerleri virgül kullanarak ayırın.",
- "Separate values for Y axis using commas.": "Y ekseni için değerleri virgül kullanarak ayırın.",
- "Write image to a directory (default - log/images) and generation parameters into csv file.": "Görüntüyü bir dizine (varsayılan - log/images) ve üretim parametrelerini csv dosyasına yazın.",
- "Open images output directory": "Görüntü çıktı dizinini açın",
- "How much to blur the mask before processing, in pixels.": "İşlemeden önce maskenin piksel cinsinden ne kadar bulanıklaştırılacağı.",
- "What to put inside the masked area before processing it with Stable Diffusion.": "Kararlı Difüzyon ile işlemeden önce maskelenmiş alanın içine ne konulacağı.",
- "fill it with colors of the image": "Görüntünün renkleriyle doldurun",
- "keep whatever was there originally": "başlangıçta orada ne varsa saklayın",
- "fill it with latent space noise": "gizli alan gürültüsü ile doldurun",
- "fill it with latent space zeroes": "gizli uzay sıfırları ile doldurun",
- "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image": "Maskelenmiş bölgeyi hedef çözünürlüğe yükseltme, inpainting yapma, ölçeği küçültme ve orijinal görüntüye yapıştırma",
- "Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.": "Görüntüyü hedef çözünürlüğe göre yeniden boyutlandırın. Yükseklik ve genişlik eşleşmediği sürece, yanlış en boy oranı elde edersiniz.",
- "Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out.": "Görüntüyü, hedef çözünürlüğün tamamı görüntüyle dolacak şekilde yeniden boyutlandırın. Dışarıda kalan kısımları kırpın.",
- "Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors.": "Görüntünün tamamı hedef çözünürlüğün içinde olacak şekilde görüntüyü yeniden boyutlandırın. Boş alanı görüntünün renkleriyle doldurun.",
- "How many times to repeat processing an image and using it as input for the next iteration": "Bir görüntüyü işlemeyi kaç kez tekrarlamak ve bir sonraki yineleme için girdi olarak kullanmak",
- "In loopback mode, on each loop the denoising strength is multiplied by this value. <1 means decreasing variety so your sequence will converge on a fixed picture. >1 means increasing variety so your sequence will become more and more chaotic.": "Geri döngü modunda, her döngüde denoising gücü bu değerle çarpılır. <1 çeşitliliğin azalması anlamına gelir, böylece diziniz sabit bir resme yakınsayacaktır. >1'den büyük olması çeşitliliğin artması anlamına gelir, böylece sekansınız gittikçe daha kaotik hale gelecektir.",
- "For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam.": "SD yükseltme için karolar arasında piksel olarak ne kadar örtüşme olmalıdır. Döşemeler, tekrar tek bir resimde birleştirildiklerinde açıkça görülebilen bir dikiş olmayacak şekilde üst üste biner.",
- "A directory on the same machine where the server is running.": "Sunucunun çalıştığı makinedeki bir dizin.",
- "Leave blank to save images to the default path.": "Görüntüleri varsayılan yola kaydetmek için boş bırakın.",
- "Result = A * (1 - M) + B * M": "Sonuç = A * (1 - M) + B * M",
- "Result = A + (B - C) * M": "Sonuç = A + (B - C) * M",
- "1st and last digit must be 1. ex:'1, 2, 1'": "1. ve son rakam 1 olmalıdır. örn:'1, 2, 1'",
- "Path to directory with input images": "Girdi resimlerinin bulunduğu dizinin yolu",
- "Path to directory where to write outputs": "Çıktıların yazılacağı dizinin yolu",
- "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.": "Görüntülerin dosya adlarının nasıl seçileceğini tanımlamak için aşağıdaki etiketleri kullanın: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; varsayılan için boş bırakın.",
- "If this option is enabled, watermark will not be added to created images. Warning: if you do not add watermark, you may be behaving in an unethical manner.": "Bu seçenek etkinleştirilirse, oluşturulan görüntülere filigran eklenmeyecektir. Uyarı: filigran eklemezseniz, etik olmayan bir şekilde davranıyor olabilirsiniz.",
- "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.": "Görüntüler ve ızgaralar için alt dizinlerin nasıl seçileceğini tanımlamak için aşağıdaki etiketleri kullanın: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; varsayılan için boş bırakın.",
- "Restore low quality faces using GFPGAN neural network": "GFPGAN sinir ağını kullanarak düşük kaliteli yüzleri geri yükleme",
- "This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is.": "Bu düzenli ifade, dosya adından sözcükleri ayıklamak için kullanılır ve bunlar aşağıdaki seçenek kullanılarak eğitim için kullanılan etiket metnine birleştirilir. Dosya adı metnini olduğu gibi tutmak için boş bırakın.",
- "This string will be used to join split words into a single line if the option above is enabled.": "Bu dize, yukarıdaki seçenek etkinleştirilirse bölünmüş kelimeleri tek bir satırda birleştirmek için kullanılacaktır.",
- "List of setting names, separated by commas, for settings that should go to the quick access bar at the top, rather than the usual setting tab. See modules/shared.py for setting names. Requires restarting to apply.": "Normal ayar sekmesi yerine üstteki hızlı erişim çubuğuna gitmesi gereken ayarlar için virgülle ayrılmış ayar adlarının listesi. Ayar adları için modules/shared.py dosyasına bakın. Uygulanması için yeniden başlatma gerekir.",
- "If this values is non-zero, it will be added to seed and used to initialize RNG for noises when using samplers with Eta. You can use this to produce even more variation of images, or you can use this to match images of other software if you know what you are doing.": "Bu değer sıfır değilse, tohuma eklenecek ve Eta ile örnekleyiciler kullanılırken gürültüler için RNG'yi başlatmak için kullanılacaktır. Bunu daha fazla görüntü çeşitliliği üretmek için kullanabilir veya ne yaptığınızı biliyorsanız diğer yazılımların görüntülerini eşleştirmek için kullanabilirsiniz.."
-}
diff --git a/localizations/zh_CN.json b/localizations/zh_CN.json
deleted file mode 100644
index e453f5e3..00000000
--- a/localizations/zh_CN.json
+++ /dev/null
@@ -1,488 +0,0 @@
-{
- "⤡": "⤡",
- "⊞": "⊞",
- "×": "×",
- "❮": "❮",
- "❯": "❯",
- "Loading...": "载入中...",
- "view": "查看",
- "api": "api",
- "•": "•",
- "built with gradio": "基于 Gradio 构建",
- "Stable Diffusion checkpoint": "Stable Diffusion 模型(ckpt)",
- "txt2img": "文生图",
- "img2img": "图生图",
- "Extras": "后处理",
- "PNG Info": "PNG 信息",
- "Checkpoint Merger": "模型(ckpt)合并工具",
- "Train": "训练",
- "Create aesthetic embedding": "生成美术风格 embedding",
- "Image Browser": "图库浏览器",
- "History": "历史记录",
- "Settings": "设置",
- "Prompt": "提示词",
- "Negative prompt": "反向提示词",
- "Run": "运行",
- "Skip": "跳过",
- "Interrupt": "中止",
- "Generate": "生成",
- "Style 1": "模版风格 1",
- "Style 2": "模版风格 2",
- "Label": "标签",
- "File": "文件",
- "Drop File Here": "拖拽文件到此",
- "-": "-",
- "or": "或",
- "Click to Upload": "点击上传",
- "Image": "图像",
- "Check progress": "查看进度",
- "Check progress (first)": "(首次)查看进度",
- "Sampling Steps": "采样迭代步数",
- "Sampling method": "采样方法",
- "Euler a": "Euler a",
- "Euler": "Euler",
- "LMS": "LMS",
- "Heun": "Heun",
- "DPM2": "DPM2",
- "DPM2 a": "DPM2 a",
- "DPM fast": "DPM fast",
- "DPM adaptive": "DPM adaptive",
- "LMS Karras": "LMS Karras",
- "DPM2 Karras": "DPM2 Karras",
- "DPM2 a Karras": "DPM2 a Karras",
- "DDIM": "DDIM",
- "PLMS": "PLMS",
- "Width": "宽度",
- "Height": "高度",
- "Restore faces": "面部修复",
- "Tiling": "可平铺(Tiling)",
- "Highres. fix": "高分辨率修复",
- "Firstpass width": "第一遍的宽度",
- "Firstpass height": "第一遍的高度",
- "Denoising strength": "去噪强度",
- "Batch count": "批次",
- "Batch size": "批量",
- "CFG Scale": "提示词相关性(CFG Scale)",
- "Seed": "随机种子",
- "Extra": "额外参数",
- "Variation seed": "差异随机种子",
- "Variation strength": "差异强度",
- "Resize seed from width": "自宽度缩放随机种子",
- "Resize seed from height": "自高度缩放随机种子",
- "Open for Clip Aesthetic!": "打开美术风格 Clip!",
- "▼": "▼",
- "Aesthetic weight": "美术风格权重",
- "Aesthetic steps": "美术风格迭代步数",
- "Aesthetic learning rate": "美术风格学习率",
- "Slerp interpolation": "Slerp 插值",
- "Aesthetic imgs embedding": "美术风格图集 embedding",
- "None": "无",
- "Aesthetic text for imgs": "该图集的美术风格描述",
- "Slerp angle": "Slerp 角度",
- "Is negative text": "是反向提示词",
- "Script": "脚本",
- "Embedding to Shareable PNG": "将 Embedding 转换为可分享的 PNG",
- "Prompt matrix": "提示词矩阵",
- "Prompts from file or textbox": "从文本框或文件载入提示词",
- "X/Y plot": "X/Y 图表",
- "Source embedding to convert": "用于转换的源 Embedding",
- "Embedding token": "Embedding 的 token (关键词)",
- "Put variable parts at start of prompt": "把变量部分放在提示词文本的开头",
- "Show Textbox": "显示文本框",
- "File with inputs": "含输入内容的文件",
- "Prompts": "提示词",
- "X type": "X轴类型",
- "Nothing": "无",
- "Var. seed": "差异随机种子",
- "Var. strength": "差异强度",
- "Steps": "迭代步数",
- "Prompt S/R": "提示词替换",
- "Prompt order": "提示词顺序",
- "Sampler": "采样器",
- "Checkpoint name": "模型(ckpt)名",
- "Hypernetwork": "Hypernetwork",
- "Hypernet str.": "Hypernetwork 强度",
- "Sigma Churn": "Sigma Churn",
- "Sigma min": "最小 Sigma",
- "Sigma max": "最大 Sigma",
- "Sigma noise": "Sigma noise",
- "Eta": "Eta",
- "Clip skip": "Clip 跳过",
- "Denoising": "去噪",
- "X values": "X轴数值",
- "Y type": "Y轴类型",
- "Y values": "Y轴数值",
- "Draw legend": "在图表中包括轴标题",
- "Include Separate Images": "包括独立的图像",
- "Keep -1 for seeds": "保持随机种子为-1",
- "Drop Image Here": "拖拽图像到此",
- "Save": "保存",
- "Send to img2img": ">> 图生图",
- "Send to inpaint": ">> 内补绘制",
- "Send to extras": ">> 后处理",
- "Make Zip when Save?": "保存时生成zip压缩文件?",
- "Textbox": "文本框",
- "Interrogate\nCLIP": "CLIP\n反推提示词",
- "Interrogate\nDeepBooru": "DeepBooru\n反推提示词",
- "Inpaint": "内补绘制",
- "Batch img2img": "批量图生图",
- "Image for img2img": "图生图的图像",
- "Image for inpainting with mask": "用于内补绘制蒙版内容的图像",
- "Mask": "蒙版",
- "Mask blur": "蒙版模糊",
- "Mask mode": "蒙版模式",
- "Draw mask": "绘制蒙版",
- "Upload mask": "上传蒙版",
- "Masking mode": "蒙版模式",
- "Inpaint masked": "内补绘制蒙版内容",
- "Inpaint not masked": "内补绘制非蒙版内容",
- "Masked content": "蒙版蒙住的内容",
- "fill": "填充",
- "original": "原图",
- "latent noise": "潜空间噪声",
- "latent nothing": "潜空间数值零",
- "Inpaint at full resolution": "以完整分辨率进行内补绘制",
- "Inpaint at full resolution padding, pixels": "以完整分辨率进行内补绘制 - 填补像素",
- "Process images in a directory on the same machine where the server is running.": "在服务器主机上的目录中处理图像",
- "Use an empty output directory to save pictures normally instead of writing to the output directory.": "指定一个空的文件夹为输出目录而非默认的 output 文件夹为输出目录",
- "Disabled when launched with --hide-ui-dir-config.": "启动 --hide-ui-dir-config 时禁用",
- "Input directory": "输入目录",
- "Output directory": "输出目录",
- "Resize mode": "缩放模式",
- "Just resize": "只缩放",
- "Crop and resize": "缩放并剪裁",
- "Resize and fill": "缩放并填充",
- "img2img alternative test": "图生图的另一种测试",
- "Loopback": "回送",
- "Outpainting mk2": "外补绘制第二版",
- "Poor man's outpainting": "效果稍差的外补绘制",
- "SD upscale": "使用 SD 放大(SD upscale)",
- "should be 2 or lower.": "必须小于等于2",
- "Override `Sampling method` to Euler?(this method is built for it)": "覆写 `采样方法` 为 Euler?(这个方法就是为这样做设计的)",
- "Override `prompt` to the same value as `original prompt`?(and `negative prompt`)": "覆写 `提示词` 为 `初始提示词`?(包括`反向提示词`)",
- "Original prompt": "初始提示词",
- "Original negative prompt": "初始反向提示词",
- "Override `Sampling Steps` to the same value as `Decode steps`?": "覆写 `采样迭代步数` 为 `解码迭代步数`?",
- "Decode steps": "解码迭代步数",
- "Override `Denoising strength` to 1?": "覆写 `去噪强度` 为 1?",
- "Decode CFG scale": "解码提示词相关性(CFG scale)",
- "Randomness": "随机度",
- "Sigma adjustment for finding noise for image": "为寻找图中噪点的 Sigma 调整",
- "Loops": "迭代次数",
- "Denoising strength change factor": "去噪强度的调整系数",
- "Recommended settings: Sampling Steps: 80-100, Sampler: Euler a, Denoising strength: 0.8": "推荐设置:采样迭代步数:80-100,采样器:Euler a,去噪强度:0.8",
- "Pixels to expand": "拓展的像素数",
- "Outpainting direction": "外补绘制的方向",
- "left": "左",
- "right": "右",
- "up": "上",
- "down": "下",
- "Fall-off exponent (lower=higher detail)": "衰减指数(越低细节越好)",
- "Color variation": "色彩变化",
- "Will upscale the image to twice the dimensions; use width and height sliders to set tile size": "将图像放大到两倍尺寸; 使用宽度和高度滑块设置图块尺寸(tile size)",
- "Tile overlap": "图块重叠的像素(Tile overlap)",
- "Upscaler": "放大算法",
- "Lanczos": "Lanczos",
- "LDSR": "LDSR",
- "BSRGAN 4x": "BSRGAN 4x",
- "ESRGAN_4x": "ESRGAN_4x",
- "R-ESRGAN 4x+ Anime6B": "R-ESRGAN 4x+ Anime6B",
- "ScuNET GAN": "ScuNET GAN",
- "ScuNET PSNR": "ScuNET PSNR",
- "SwinIR_4x": "SwinIR 4x",
- "Single Image": "单个图像",
- "Batch Process": "批量处理",
- "Batch from Directory": "从目录进行批量处理",
- "Source": "来源",
- "Show result images": "显示输出图像",
- "Scale by": "等比缩放",
- "Scale to": "指定尺寸缩放",
- "Resize": "缩放",
- "Crop to fit": "裁剪以适应",
- "Upscaler 2": "放大算法 2",
- "Upscaler 2 visibility": "放大算法 2 可见度",
- "GFPGAN visibility": "GFPGAN 可见度",
- "CodeFormer visibility": "CodeFormer 可见度",
- "CodeFormer weight (0 = maximum effect, 1 = minimum effect)": "CodeFormer 权重 (0 = 最大效果, 1 = 最小效果)",
- "Open output directory": "打开输出目录",
- "Send to txt2img": ">> 文生图",
- "A merger of the two checkpoints will be generated in your": "合并后的模型(ckpt)会生成在你的",
- "checkpoint": "模型(ckpt)",
- "directory.": "目录",
- "Primary model (A)": "主要模型 (A)",
- "Secondary model (B)": "第二模型 (B)",
- "Tertiary model (C)": "第三模型 (C)",
- "Custom Name (Optional)": "自定义名称 (可选)",
- "Multiplier (M) - set to 0 to get model A": "倍率 (M) - 设为 0 等价于模型 A",
- "Interpolation Method": "插值方法",
- "Weighted sum": "加权和",
- "Add difference": "添加差分",
- "Save as float16": "以 float16 储存",
- "See": "查看",
- "wiki": "wiki",
- "for detailed explanation.": "以了解详细说明",
- "Create embedding": "生成 embedding",
- "Create aesthetic images embedding": "生成美术风格图集 embedding",
- "Create hypernetwork": "生成 hypernetwork",
- "Preprocess images": "图像预处理",
- "Name": "名称",
- "Initialization text": "初始化文字",
- "Number of vectors per token": "每个 token 的向量数",
- "Overwrite Old Embedding": "覆写旧的 Embedding",
- "Modules": "模块",
- "Enter hypernetwork layer structure": "输入 hypernetwork 层结构",
- "Select activation function of hypernetwork": "选择 hypernetwork 的激活函数",
- "linear": "linear",
- "relu": "relu",
- "leakyrelu": "leakyrelu",
- "elu": "elu",
- "swish": "swish",
- "Add layer normalization": "添加层标准化",
- "Use dropout": "采用 dropout 防止过拟合",
- "Overwrite Old Hypernetwork": "覆写旧的 Hypernetwork",
- "Source directory": "源目录",
- "Destination directory": "目标目录",
- "Existing Caption txt Action": "对已有的 txt 说明文字的行为",
- "ignore": "无视",
- "copy": "复制",
- "prepend": "放前面",
- "append": "放后面",
- "Create flipped copies": "生成镜像副本",
- "Split oversized images into two": "将过大的图像分为两份",
- "Split oversized images": "分割过大的图像",
- "Use BLIP for caption": "使用 BLIP 生成说明文字(自然语言描述)",
- "Use deepbooru for caption": "使用 deepbooru 生成说明文字(tags)",
- "Split image threshold": "图像分割阈值",
- "Split image overlap ratio": "分割图像重叠的比率",
- "Preprocess": "预处理",
- "Train an embedding; must specify a directory with a set of 1:1 ratio images": "训练 embedding; 必须指定一组具有 1:1 比例图像的目录",
- "Train an embedding or Hypernetwork; you must specify a directory with a set of 1:1 ratio images": "训练 embedding 或者 hypernetwork; 必须指定一组具有 1:1 比例图像的目录",
- "[wiki]": "[wiki]",
- "Embedding": "Embedding",
- "Embedding Learning rate": "Embedding 学习率",
- "Hypernetwork Learning rate": "Hypernetwork 学习率",
- "Learning rate": "学习率",
- "Dataset directory": "数据集目录",
- "Log directory": "日志目录",
- "Prompt template file": "提示词模版文件",
- "Max steps": "最大迭代步数",
- "Save an image to log directory every N steps, 0 to disable": "每 N 步保存一个图像到日志目录,0 表示禁用",
- "Save a copy of embedding to log directory every N steps, 0 to disable": "每 N 步将 embedding 的副本保存到日志目录,0 表示禁用",
- "Save images with embedding in PNG chunks": "保存图像并在 PNG 文件中嵌入 embedding 文件",
- "Read parameters (prompt, etc...) from txt2img tab when making previews": "进行预览时从文生图选项卡中读取参数(提示词等)",
- "Train Hypernetwork": "训练 Hypernetwork",
- "Train Embedding": "训练 Embedding",
- "Create an aesthetic embedding out of any number of images": "从任意数量的图像中创建美术风格 embedding",
- "Create images embedding": "生成图集 embedding",
- "txt2img history": "文生图历史记录",
- "img2img history": "图生图历史记录",
- "extras history": "后处理历史记录",
- "Renew Page": "刷新页面",
- "extras": "后处理",
- "favorites": "收藏夹",
- "custom fold": "自定义文件夹",
- "Load": "载入",
- "Images directory": "图像目录",
- "Prev batch": "上一批",
- "Next batch": "下一批",
- "First Page": "首页",
- "Prev Page": "上一页",
- "Page Index": "页数",
- "Next Page": "下一页",
- "End Page": "尾页",
- "number of images to delete consecutively next": "接下来要连续删除的图像数",
- "Delete": "删除",
- "Generate Info": "生成信息",
- "File Name": "文件名",
- "Collect": "收藏",
- "Refresh page": "刷新页面",
- "Date to": "日期至",
- "Number": "数量",
- "set_index": "设置索引",
- "Checkbox": "勾选框",
- "Apply settings": "保存设置",
- "Saving images/grids": "保存图像/概览图",
- "Always save all generated images": "始终保存所有生成的图像",
- "File format for images": "图像的文件格式",
- "Images filename pattern": "图像文件名格式",
- "Always save all generated image grids": "始终保存所有生成的概览图",
- "File format for grids": "概览图的文件格式",
- "Add extended info (seed, prompt) to filename when saving grid": "保存概览时将扩展信息(随机种子、提示词)添加到文件名",
- "Do not save grids consisting of one picture": "只有一张图片时不要保存概览图",
- "Prevent empty spots in grid (when set to autodetect)": "(在自动检测时)防止概览图中出现空位",
- "Grid row count; use -1 for autodetect and 0 for it to be same as batch size": "概览行数; 使用 -1 进行自动检测,使用 0 使其与批量大小相同",
- "Save text information about generation parameters as chunks to png files": "将有关生成参数的文本信息作为块保存到 png 文件中",
- "Create a text file next to every image with generation parameters.": "保存图像时在每个图像旁边创建一个文本文件储存生成参数",
- "Save a copy of image before doing face restoration.": "在进行面部修复之前保存图像副本",
- "Quality for saved jpeg images": "保存的 jpeg 图像的质量",
- "If PNG image is larger than 4MB or any dimension is larger than 4000, downscale and save copy as JPG": "如果 PNG 图像大于 4MB 或宽高大于 4000,则缩小并保存副本为 JPG",
- "Use original name for output filename during batch process in extras tab": "在后处理选项卡中的批量处理过程中使用原始名称作为输出文件名",
- "When using 'Save' button, only save a single selected image": "使用“保存”按钮时,只保存一个选定的图像",
- "Do not add watermark to images": "不要给图像加水印",
- "Paths for saving": "保存路径",
- "Output directory for images; if empty, defaults to three directories below": "图像的输出目录; 如果为空,则默认为以下三个目录",
- "Output directory for txt2img images": "文生图的输出目录",
- "Output directory for img2img images": "图生图的输出目录",
- "Output directory for images from extras tab": "后处理的输出目录",
- "Output directory for grids; if empty, defaults to two directories below": "概览图的输出目录; 如果为空,则默认为以下两个目录",
- "Output directory for txt2img grids": "文生图概览的输出目录",
- "Output directory for img2img grids": "图生图概览的输出目录",
- "Directory for saving images using the Save button": "使用“保存”按钮保存图像的目录",
- "Saving to a directory": "保存到目录",
- "Save images to a subdirectory": "将图像保存到子目录",
- "Save grids to a subdirectory": "将概览图保存到子目录",
- "When using \"Save\" button, save images to a subdirectory": "使用“保存”按钮时,将图像保存到子目录",
- "Directory name pattern": "目录名称格式",
- "Max prompt words for [prompt_words] pattern": "[prompt_words] 格式的最大提示词数量",
- "Upscaling": "放大",
- "Tile size for ESRGAN upscalers. 0 = no tiling.": "ESRGAN 的图块尺寸(Tile size)。0 = 不分块(no tiling)",
- "Tile overlap, in pixels for ESRGAN upscalers. Low values = visible seam.": "ESRGAN 的图块重叠(Tile overlap)像素。低值 = 可见接缝",
- "Tile size for all SwinIR.": "适用所有 SwinIR 系算法的图块尺寸(Tile size)",
- "Tile overlap, in pixels for SwinIR. Low values = visible seam.": "SwinIR 的图块重叠(Tile overlap)像素。低值 = 可见接缝",
- "LDSR processing steps. Lower = faster": "LDSR 处理迭代步数。更低 = 更快",
- "Upscaler for img2img": "图生图的放大算法",
- "Upscale latent space image when doing hires. fix": "做高分辨率修复时也放大潜空间图像",
- "Face restoration": "面部修复",
- "CodeFormer weight parameter; 0 = maximum effect; 1 = minimum effect": "CodeFormer 权重参数; 0 = 最大效果; 1 = 最小效果",
- "Move face restoration model from VRAM into RAM after processing": "面部修复处理完成后将面部修复模型从显存(VRAM)移至内存(RAM)",
- "System": "系统",
- "VRAM usage polls per second during generation. Set to 0 to disable.": "生成图像时每秒轮询显存(VRAM)使用情况的次数。设置为 0 以禁用",
- "Always print all generation info to standard output": "始终将所有生成信息输出到 standard output (一般为控制台)",
- "Add a second progress bar to the console that shows progress for an entire job.": "向控制台添加第二个进度条,显示整个作业的进度",
- "Training": "训练",
- "Unload VAE and CLIP from VRAM when training": "训练时从显存(VRAM)中取消 VAE 和 CLIP 的加载",
- "Move VAE and CLIP to RAM when training hypernetwork. Saves VRAM.": "训练时将 VAE 和 CLIP 从显存(VRAM)移放到内存(RAM),节省显存(VRAM)",
- "Filename word regex": "文件名用词的正则表达式",
- "Filename join string": "文件名连接用字符串",
- "Number of repeats for a single input image per epoch; used only for displaying epoch number": "每个 epoch 中单个输入图像的重复次数; 仅用于显示 epoch 数",
- "Save an csv containing the loss to log directory every N steps, 0 to disable": "每 N 步保存一个包含 loss 的 csv 到日志目录,0 表示禁用",
- "Stable Diffusion": "Stable Diffusion",
- "Checkpoints to cache in RAM": "缓存在内存(RAM)中的模型(ckpt)",
- "Hypernetwork strength": "Hypernetwork 强度",
- "Apply color correction to img2img results to match original colors.": "对图生图结果应用颜色校正以匹配原始颜色",
- "Save a copy of image before applying color correction to img2img results": "在对图生图结果应用颜色校正之前保存图像副本",
- "With img2img, do exactly the amount of steps the slider specifies (normally you'd do less with less denoising).": "在进行图生图的时候,确切地执行滑块指定的迭代步数(正常情况下更弱的去噪需要更少的迭代步数)",
- "Enable quantization in K samplers for sharper and cleaner results. This may change existing seeds. Requires restart to apply.": "在 K 采样器中启用量化以获得更清晰、更清晰的结果。这可能会改变现有的随机种子。需要重新启动才能应用",
- "Emphasis: use (text) to make model pay more attention to text and [text] to make it pay less attention": "强调符:使用 (文字) 使模型更关注该文本,使用 [文字] 使其减少关注",
- "Use old emphasis implementation. Can be useful to reproduce old seeds.": "使用旧的强调符实现。可用于复现旧随机种子",
- "Make K-diffusion samplers produce same images in a batch as when making a single image": "使 K-diffusion 采样器批量生成与生成单个图像时产出相同的图像",
- "Increase coherency by padding from the last comma within n tokens when using more than 75 tokens": "当使用超过 75 个 token 时,通过从 n 个 token 中的最后一个逗号填补来提高一致性",
- "Filter NSFW content": "过滤成人内容",
- "Stop At last layers of CLIP model": "在 CLIP 模型的最后哪一层停下",
- "Interrogate Options": "反推提示词选项",
- "Interrogate: keep models in VRAM": "反推: 将模型保存在显存(VRAM)中",
- "Interrogate: use artists from artists.csv": "反推: 使用 artists.csv 中的艺术家",
- "Interrogate: include ranks of model tags matches in results (Has no effect on caption-based interrogators).": "反推: 在生成结果中包含与模型标签(tags)相匹配的等级(对基于生成自然语言描述的反推没有影响)",
- "Interrogate: num_beams for BLIP": "反推: BLIP 的 num_beams",
- "Interrogate: minimum description length (excluding artists, etc..)": "反推: 最小描述长度(不包括艺术家, 等…)",
- "Interrogate: maximum description length": "反推: 最大描述长度",
- "CLIP: maximum number of lines in text file (0 = No limit)": "CLIP: 文本文件中的最大行数(0 = 无限制)",
- "Interrogate: deepbooru score threshold": "反推: deepbooru 分数阈值",
- "Interrogate: deepbooru sort alphabetically": "反推: deepbooru 按字母顺序排序",
- "use spaces for tags in deepbooru": "在 deepbooru 中为标签使用空格",
- "escape (\\) brackets in deepbooru (so they are used as literal brackets and not for emphasis)": "在 deepbooru 中使用转义 (\\) 括号(因此它们用作文字括号而不是强调符号)",
- "User interface": "用户界面",
- "Show progressbar": "显示进度条",
- "Show image creation progress every N sampling steps. Set 0 to disable.": "每 N 个采样迭代步数显示图像生成进度。设置 0 禁用",
- "Show previews of all images generated in a batch as a grid": "以网格的形式预览所有批量生成出来的图像",
- "Show grid in results for web": "在网页的结果中显示概览图",
- "Do not show any images in results for web": "不在网页的结果中显示任何图像",
- "Add model hash to generation information": "将模型的哈希值添加到生成信息",
- "Add model name to generation information": "将模型名称添加到生成信息",
- "When reading generation parameters from text into UI (from PNG info or pasted text), do not change the selected model/checkpoint.": "当从文本读取生成参数到 UI(从 PNG 信息或粘贴文本)时,不要更改选定的模型(ckpt)",
- "Font for image grids that have text": "有文字的概览图使用的字体",
- "Enable full page image viewer": "启用整页图像查看器",
- "Show images zoomed in by default in full page image viewer": "在整页图像查看器中默认放大显示图像",
- "Show generation progress in window title.": "在窗口标题中显示生成进度",
- "Quicksettings list": "快速设置列表",
- "Localization (requires restart)": "本地化(需要重新启动)",
- "Sampler parameters": "采样器参数",
- "Hide samplers in user interface (requires restart)": "在用户界面中隐藏采样器(需要重新启动)",
- "eta (noise multiplier) for DDIM": "DDIM 的 eta (噪声乘数) ",
- "eta (noise multiplier) for ancestral samplers": "ancestral 采样器的 eta (噪声乘数)",
- "img2img DDIM discretize": "图生图 DDIM 离散化",
- "uniform": "均勻",
- "quad": "二阶",
- "sigma churn": "sigma churn",
- "sigma tmin": "最小(tmin) sigma",
- "sigma noise": "sigma 噪声",
- "Eta noise seed delta": "Eta 噪声种子偏移(noise seed delta)",
- "Images Browser": "图库浏览器",
- "Preload images at startup": "在启动时预载图像",
- "Number of columns on the page": "每页列数",
- "Number of rows on the page": "每页行数",
- "Number of pictures displayed on each page": "每页显示的图像数量",
- "Minimum number of pages per load": "每次加载的最小页数",
- "Number of grids in each row": "每行显示多少格",
- "Wildcards": "通配符",
- "Use same seed for all images": "为所有图像使用同一个随机种子",
- "Request browser notifications": "请求浏览器通知",
- "Download localization template": "下载本地化模板",
- "Reload custom script bodies (No ui updates, No restart)": "重新加载自定义脚本主体(无 ui 更新,无重启)",
- "Restart Gradio and Refresh components (Custom Scripts, ui.py, js and css only)": "重启 Gradio 及刷新组件(仅限自定义脚本、ui.py、js 和 css)",
- "Prompt (press Ctrl+Enter or Alt+Enter to generate)": "提示词(按 Ctrl+Enter 或 Alt+Enter 生成)",
- "Negative prompt (press Ctrl+Enter or Alt+Enter to generate)": "反向提示词(按 Ctrl+Enter 或 Alt+Enter 生成)",
- "Add a random artist to the prompt.": "随机添加一个艺术家到提示词中",
- "Read generation parameters from prompt or last generation if prompt is empty into user interface.": "从提示词中读取生成参数,如果提示词为空,则读取上一次的生成参数到用户界面",
- "Save style": "储存为模版风格",
- "Apply selected styles to current prompt": "将所选样式应用于当前提示",
- "Stop processing current image and continue processing.": "停止处理当前图像并继续处理下一个",
- "Stop processing images and return any results accumulated so far.": "停止处理图像并返回迄今为止累积的任何结果",
- "Style to apply; styles have components for both positive and negative prompts and apply to both": "要应用的模版风格; 模版风格包含正向和反向提示词,并应用于两者",
- "Do not do anything special": "什么都不做",
- "Which algorithm to use to produce the image": "使用哪种算法生成图像",
- "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps to higher than 30-40 does not help": "Euler Ancestral - 非常有创意,可以根据迭代步数获得完全不同的图像,将迭代步数设置为高于 30-40 不会有正面作用",
- "Denoising Diffusion Implicit Models - best at inpainting": "Denoising Diffusion Implicit models - 最擅长内补绘制",
- "Produce an image that can be tiled.": "生成可用于平铺(tiled)的图像",
- "Use a two step process to partially create an image at smaller resolution, upscale, and then improve details in it without changing composition": "使用两步处理的时候以较小的分辨率生成初步图像、接着放大图像,然后在不更改构图的情况下改进其中的细节",
- "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.": "决定算法对图像内容的影响程度。设置 0 时,什么都不会改变,而在 1 时,你将获得不相关的图像。值低于 1.0 时,处理的迭代步数将少于“采样迭代步数”滑块指定的步数",
- "How many batches of images to create": "创建多少批次的图像",
- "How many image to create in a single batch": "每批创建多少图像",
- "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results": "Classifier Free Guidance Scale - 图像应在多大程度上服从提示词 - 较低的值会产生更有创意的结果",
- "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result": "一个固定随机数生成器输出的值 - 以相同参数和随机种子生成的图像会得到相同的结果",
- "Set seed to -1, which will cause a new random number to be used every time": "将随机种子设置为-1,则每次都会使用一个新的随机数",
- "Reuse seed from last generation, mostly useful if it was randomed": "重用上一次使用的随机种子,如果想要固定结果就会很有用",
- "Seed of a different picture to be mixed into the generation.": "将要参与生成的另一张图的随机种子",
- "How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something).": "想要产生多强烈的变化。设为 0 时,将没有效果。设为 1 时,你将获得完全产自差异随机种子的图像(ancestral 采样器除外,你只是单纯地生成了一些东西)",
- "Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution": "尝试生成与在指定分辨率下使用相同随机种子生成的图像相似的图片",
- "This text is used to rotate the feature space of the imgs embs": "此文本用于旋转图集 embeddings 的特征空间",
- "Separate values for X axis using commas.": "使用逗号分隔 X 轴的值",
- "Separate values for Y axis using commas.": "使用逗号分隔 Y 轴的值",
- "Write image to a directory (default - log/images) and generation parameters into csv file.": "将图像写入目录(默认 - log/images)并将生成参数写入 csv 文件",
- "Open images output directory": "打开图像输出目录",
- "How much to blur the mask before processing, in pixels.": "处理前要对蒙版进行多强的模糊,以像素为单位",
- "What to put inside the masked area before processing it with Stable Diffusion.": "在使用 Stable Diffusion 处理蒙版区域之前要在蒙版区域内放置什么",
- "fill it with colors of the image": "用图像的颜色填充它",
- "keep whatever was there originally": "保留原来的东西",
- "fill it with latent space noise": "用潜空间的噪声填充它",
- "fill it with latent space zeroes": "用潜空间的零填充它",
- "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image": "将蒙版区域放大到目标分辨率,做内补绘制,缩小后粘贴到原始图像中",
- "Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.": "将图像大小调整为目标分辨率。除非高度和宽度匹配,否则你将获得不正确的纵横比",
- "Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out.": "调整图像大小,使整个目标分辨率都被图像填充。裁剪多出来的部分",
- "Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors.": "调整图像大小,使整个图像在目标分辨率内。用图像的颜色填充空白区域",
- "How many times to repeat processing an image and using it as input for the next iteration": "重复处理图像并用作下次迭代输入的次数",
- "In loopback mode, on each loop the denoising strength is multiplied by this value. <1 means decreasing variety so your sequence will converge on a fixed picture. >1 means increasing variety so your sequence will become more and more chaotic.": "在回送模式下,在每个循环中,去噪强度都会乘以该值。<1 表示减少多样性,因此你的这一组图将集中在固定的图像上。>1 意味着增加多样性,因此你的这一组图将变得越来越混乱",
- "For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam.": "使用 SD 放大(SD upscale)时,图块(Tiles)之间应该有多少像素重叠。图块(Tiles)之间需要重叠才可以让它们在合并回一张图像时,没有清晰可见的接缝",
- "A directory on the same machine where the server is running.": "与服务器主机上的目录",
- "Leave blank to save images to the default path.": "留空以将图像保存到默认路径",
- "Result = A * (1 - M) + B * M": "结果 = A * (1 - M) + B * M",
- "Result = A + (B - C) * M": "结果 = A + (B - C) * M",
- "1st and last digit must be 1. ex:'1, 2, 1'": "第一个和最后一个数字必须是 1。例:'1, 2, 1'",
- "how fast should the training go. Low values will take longer to train, high values may fail to converge (not generate accurate results) and/or may break the embedding (This has happened if you see Loss: nan in the training info textbox. If this happens, you need to manually restore your embedding from an older not-broken backup).\n\nYou can set a single numeric value, or multiple learning rates using the syntax:\n\n rate_1:max_steps_1, rate_2:max_steps_2, ...\n\nEG: 0.005:100, 1e-3:1000, 1e-5\n\nWill train with rate of 0.005 for first 100 steps, then 1e-3 until 1000 steps, then 1e-5 for all remaining steps.": "训练应该多快。低值将需要更长的时间来训练,高值可能无法收敛(无法产生准确的结果)以及/也许可能会破坏 embedding(如果你在训练信息文本框中看到 Loss: nan 就会发生这种情况。如果发生这种情况,你需要从较旧的未损坏的备份手动恢复 embedding)\n\n你可以使用以下语法设置单个数值或多个学习率:\n\n 率1:步限1, 率2:步限2, ...\n\n如: 0.005:100, 1e-3:1000, 1e-5\n\n即前 100 步将以 0.005 的速率训练,接着直到 1000 步为止以 1e-3 训练,然后剩余所有步以 1e-5 训练",
- "Path to directory with input images": "带有输入图像的路径",
- "Path to directory where to write outputs": "进行输出的路径",
- "Input images directory": "输入图像目录",
- "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; leave empty for default.": "使用以下标签定义如何选择图像的文件名: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; 默认请留空",
- "If this option is enabled, watermark will not be added to created images. Warning: if you do not add watermark, you may be behaving in an unethical manner.": "如果启用此选项,水印将不会添加到生成出来的图像中。警告:如果你不添加水印,你的行为可能是不符合专业操守的",
- "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; leave empty for default.": "使用以下标签定义如何选择图像和概览图的子目录: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; 默认请留空",
- "Restore low quality faces using GFPGAN neural network": "使用 GFPGAN 神经网络修复低质量面部",
- "This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is.": "此正则表达式将用于从文件名中提取单词,并将使用以下选项将它们接合到用于训练的标签文本中。留空以保持文件名文本不变",
- "This string will be used to join split words into a single line if the option above is enabled.": "如果启用了上述选项,则此处的字符会用于将拆分的单词接合为同一行",
- "List of setting names, separated by commas, for settings that should go to the quick access bar at the top, rather than the usual setting tab. See modules/shared.py for setting names. Requires restarting to apply.": "设置名称列表,以逗号分隔,设置应转到顶部的快速访问栏,而不是通常的设置选项卡。有关设置名称,请参见 modules/shared.py。需要重新启动才能应用",
- "If this values is non-zero, it will be added to seed and used to initialize RNG for noises when using samplers with Eta. You can use this to produce even more variation of images, or you can use this to match images of other software if you know what you are doing.": "如果这个值不为零,它将被添加到随机种子中,并在使用带有 Eta 的采样器时用于初始化随机噪声。你可以使用它来产生更多的图像变化,或者你可以使用它来模仿其他软件生成的图像,如果你知道你在做什么",
- "Enable Autocomplete": "开启Tag补全",
- "Allowed categories for random artists selection when using the Roll button": "使用抽选艺术家按钮时将会随机的艺术家类别",
- "Roll three": "抽三位出來",
- "Generate forever": "不停地生成",
- "Cancel generate forever": "取消不停地生成"
-}
diff --git a/localizations/zh_TW.json b/localizations/zh_TW.json
deleted file mode 100644
index 724df1ac..00000000
--- a/localizations/zh_TW.json
+++ /dev/null
@@ -1,488 +0,0 @@
-{
- "⤡": "⤡",
- "⊞": "⊞",
- "×": "×",
- "❮": "❮",
- "❯": "❯",
- "Loading...": "載入中…",
- "view": "檢視",
- "api": "api",
- "•": "•",
- "built with gradio": "基於 Gradio 構建",
- "Stable Diffusion checkpoint": "Stable Diffusion 模型權重存檔點",
- "txt2img": "文生圖",
- "img2img": "圖生圖",
- "Extras": "後處理",
- "PNG Info": "PNG 資訊",
- "Checkpoint Merger": "模型權重存檔點合併工具",
- "Train": "訓練",
- "Create aesthetic embedding": "生成美術風格 embedding",
- "Image Browser": "圖庫瀏覽器",
- "History": "歷史記錄",
- "Settings": "設定",
- "Prompt": "提示詞",
- "Negative prompt": "反向提示詞",
- "Run": "執行",
- "Skip": "跳過",
- "Interrupt": "中止",
- "Generate": "生成",
- "Style 1": "模版風格 1",
- "Style 2": "模版風格 2",
- "Label": "標籤",
- "File": "檔案",
- "Drop File Here": "拖曳檔案到此",
- "-": "-",
- "or": "或",
- "Click to Upload": "點擊上傳",
- "Image": "圖像",
- "Check progress": "檢視進度",
- "Check progress (first)": "(首次)檢視進度",
- "Sampling Steps": "採樣疊代步數",
- "Sampling method": "採樣方法",
- "Euler a": "Euler a",
- "Euler": "Euler",
- "LMS": "LMS",
- "Heun": "Heun",
- "DPM2": "DPM2",
- "DPM2 a": "DPM2 a",
- "DPM fast": "DPM fast",
- "DPM adaptive": "DPM adaptive",
- "LMS Karras": "LMS Karras",
- "DPM2 Karras": "DPM2 Karras",
- "DPM2 a Karras": "DPM2 a Karras",
- "DDIM": "DDIM",
- "PLMS": "PLMS",
- "Width": "寬度",
- "Height": "高度",
- "Restore faces": "面部修復",
- "Tiling": "可平鋪",
- "Highres. fix": "高解析度修復",
- "Firstpass width": "第一遍的寬度",
- "Firstpass height": "第一遍的高度",
- "Denoising strength": "去噪強度",
- "Batch count": "批次",
- "Batch size": "批量",
- "CFG Scale": "提示詞相關性(CFG)",
- "Seed": "隨機種子",
- "Extra": "額外參數",
- "Variation seed": "差異隨機種子",
- "Variation strength": "差異強度",
- "Resize seed from width": "自寬度縮放隨機種子",
- "Resize seed from height": "自高度縮放隨機種子",
- "Open for Clip Aesthetic!": "打開美術風格 Clip!",
- "▼": "▼",
- "Aesthetic weight": "美術風格權重",
- "Aesthetic steps": "美術風格疊代步數",
- "Aesthetic learning rate": "美術風格學習率",
- "Slerp interpolation": "Slerp 插值",
- "Aesthetic imgs embedding": "美術風格圖集 embedding",
- "None": "無",
- "Aesthetic text for imgs": "該圖集的美術風格描述",
- "Slerp angle": "Slerp 角度",
- "Is negative text": "是反向提示詞",
- "Script": "指令碼",
- "Embedding to Shareable PNG": "將 Embedding 轉換為可分享的 PNG",
- "Prompt matrix": "提示詞矩陣",
- "Prompts from file or textbox": "從文字方塊或檔案載入提示詞",
- "X/Y plot": "X/Y 圖表",
- "Source embedding to convert": "用於轉換的源 Embedding",
- "Embedding token": "Embedding 的關鍵詞",
- "Put variable parts at start of prompt": "把變量部分放在提示詞文本的開頭",
- "Show Textbox": "顯示文字方塊",
- "File with inputs": "含輸入內容的檔案",
- "Prompts": "提示詞",
- "X type": "X軸類型",
- "Nothing": "無",
- "Var. seed": "差異隨機種子",
- "Var. strength": "差異強度",
- "Steps": "疊代步數",
- "Prompt S/R": "提示詞替換",
- "Prompt order": "提示詞順序",
- "Sampler": "採樣器",
- "Checkpoint name": "模型權重存檔點的名稱",
- "Hypernetwork": "Hypernetwork",
- "Hypernet str.": "Hypernetwork 強度",
- "Sigma Churn": "Sigma Churn",
- "Sigma min": "最小 Sigma",
- "Sigma max": "最大 Sigma",
- "Sigma noise": "Sigma noise",
- "Eta": "Eta",
- "Clip skip": "Clip 跳過",
- "Denoising": "去噪",
- "X values": "X軸數值",
- "Y type": "Y軸類型",
- "Y values": "Y軸數值",
- "Draw legend": "在圖表中包括軸標題",
- "Include Separate Images": "包括獨立的圖像",
- "Keep -1 for seeds": "保持隨機種子為-1",
- "Drop Image Here": "拖曳圖像到此",
- "Save": "儲存",
- "Send to img2img": ">> 圖生圖",
- "Send to inpaint": ">> 內補繪製",
- "Send to extras": ">> 後處理",
- "Make Zip when Save?": "儲存時生成ZIP壓縮檔案?",
- "Textbox": "文字方塊",
- "Interrogate\nCLIP": "CLIP\n反推提示詞",
- "Interrogate\nDeepBooru": "DeepBooru\n反推提示詞",
- "Inpaint": "內補繪製",
- "Batch img2img": "批量圖生圖",
- "Image for img2img": "圖生圖的圖像",
- "Image for inpainting with mask": "用於內補繪製蒙版內容的圖像",
- "Mask": "蒙版",
- "Mask blur": "蒙版模糊",
- "Mask mode": "蒙版模式",
- "Draw mask": "繪製蒙版",
- "Upload mask": "上傳蒙版",
- "Masking mode": "蒙版模式",
- "Inpaint masked": "內補繪製蒙版內容",
- "Inpaint not masked": "內補繪製非蒙版內容",
- "Masked content": "蒙版蒙住的內容",
- "fill": "填充",
- "original": "原圖",
- "latent noise": "潛空間噪聲",
- "latent nothing": "潛空間數值零",
- "Inpaint at full resolution": "以完整解析度進行內補繪製",
- "Inpaint at full resolution padding, pixels": "以完整解析度進行內補繪製 — 填補畫素",
- "Process images in a directory on the same machine where the server is running.": "在伺服器主機上的目錄中處理圖像",
- "Use an empty output directory to save pictures normally instead of writing to the output directory.": "指定一個空的資料夾為輸出目錄而非預設的 output 資料夾為輸出目錄",
- "Disabled when launched with --hide-ui-dir-config.": "啟動 --hide-ui-dir-config 時禁用",
- "Input directory": "輸入目錄",
- "Output directory": "輸出目錄",
- "Resize mode": "縮放模式",
- "Just resize": "只縮放",
- "Crop and resize": "縮放並剪裁",
- "Resize and fill": "縮放並填充",
- "img2img alternative test": "圖生圖的另一種測試",
- "Loopback": "回送",
- "Outpainting mk2": "外補繪製第二版",
- "Poor man's outpainting": "效果稍差的外補繪製",
- "SD upscale": "使用 SD 放大",
- "should be 2 or lower.": "必須小於等於2",
- "Override `Sampling method` to Euler?(this method is built for it)": "覆寫「採樣方法」為 Euler?(這個方法就是為這樣做設計的)",
- "Override `prompt` to the same value as `original prompt`?(and `negative prompt`)": "覆寫「提示詞」為「初始提示詞」?(包括「反向提示詞」)",
- "Original prompt": "初始提示詞",
- "Original negative prompt": "初始反向提示詞",
- "Override `Sampling Steps` to the same value as `Decode steps`?": "覆寫「採樣疊代步數」為「解碼疊代步數」?",
- "Decode steps": "解碼疊代步數",
- "Override `Denoising strength` to 1?": "覆寫「去噪強度」為1?",
- "Decode CFG scale": "解碼提示詞相關性(CFG)",
- "Randomness": "隨機度",
- "Sigma adjustment for finding noise for image": "為尋找圖中噪點的 Sigma 調整",
- "Loops": "疊代次數",
- "Denoising strength change factor": "去噪強度的調整係數",
- "Recommended settings: Sampling Steps: 80-100, Sampler: Euler a, Denoising strength: 0.8": "推薦設定:採樣疊代步數:80-100,採樣器:Euler a,去噪強度:0.8",
- "Pixels to expand": "拓展的畫素數",
- "Outpainting direction": "外補繪製的方向",
- "left": "左",
- "right": "右",
- "up": "上",
- "down": "下",
- "Fall-off exponent (lower=higher detail)": "衰減指數(越低細節越好)",
- "Color variation": "色彩變化",
- "Will upscale the image to twice the dimensions; use width and height sliders to set tile size": "將圖像放大到兩倍尺寸; 使用寬度和高度滑塊設定圖塊尺寸",
- "Tile overlap": "圖塊重疊的畫素",
- "Upscaler": "放大演算法",
- "Lanczos": "Lanczos",
- "LDSR": "LDSR",
- "BSRGAN 4x": "BSRGAN 4x",
- "ESRGAN_4x": "ESRGAN_4x",
- "R-ESRGAN 4x+ Anime6B": "R-ESRGAN 4x+ Anime6B",
- "ScuNET GAN": "ScuNET GAN",
- "ScuNET PSNR": "ScuNET PSNR",
- "SwinIR_4x": "SwinIR 4x",
- "Single Image": "單個圖像",
- "Batch Process": "批量處理",
- "Batch from Directory": "從目錄進行批量處理",
- "Source": "來源",
- "Show result images": "顯示輸出圖像",
- "Scale by": "等比縮放",
- "Scale to": "指定尺寸縮放",
- "Resize": "縮放",
- "Crop to fit": "裁剪以適應",
- "Upscaler 2": "放大演算法 2",
- "Upscaler 2 visibility": "放大演算法 2 可見度",
- "GFPGAN visibility": "GFPGAN 可見度",
- "CodeFormer visibility": "CodeFormer 可見度",
- "CodeFormer weight (0 = maximum effect, 1 = minimum effect)": "CodeFormer 權重 (0 = 最大效果, 1 = 最小效果)",
- "Open output directory": "打開輸出目錄",
- "Send to txt2img": ">> 文生圖",
- "A merger of the two checkpoints will be generated in your": "合併後的模型權重存檔點會生成在你的",
- "checkpoint": "模型權重存檔點",
- "directory.": "目錄",
- "Primary model (A)": "主要模型 (A)",
- "Secondary model (B)": "第二模型 (B)",
- "Tertiary model (C)": "第三模型 (C)",
- "Custom Name (Optional)": "自訂名稱 (可選)",
- "Multiplier (M) - set to 0 to get model A": "倍率 (M) - 設為 0 等價於模型 A",
- "Interpolation Method": "插值方法",
- "Weighted sum": "加權和",
- "Add difference": "加入差分",
- "Save as float16": "以 float16 儲存",
- "See": "檢視",
- "wiki": "wiki",
- "for detailed explanation.": "以了解詳細說明",
- "Create embedding": "生成 embedding",
- "Create aesthetic images embedding": "生成美術風格圖集 embedding",
- "Create hypernetwork": "生成 hypernetwork",
- "Preprocess images": "圖像預處理",
- "Name": "名稱",
- "Initialization text": "初始化文字",
- "Number of vectors per token": "每個 token 的向量數",
- "Overwrite Old Embedding": "覆寫舊的 Embedding",
- "Modules": "模組",
- "Enter hypernetwork layer structure": "輸入 hypernetwork 層結構",
- "Select activation function of hypernetwork": "選擇 hypernetwork 的激活函數",
- "linear": "linear",
- "relu": "relu",
- "leakyrelu": "leakyrelu",
- "elu": "elu",
- "swish": "swish",
- "Add layer normalization": "加入層標準化",
- "Use dropout": "採用 dropout 防止過擬合",
- "Overwrite Old Hypernetwork": "覆寫舊的 Hypernetwork",
- "Source directory": "來源目錄",
- "Destination directory": "目標目錄",
- "Existing Caption txt Action": "對已有的TXT說明文字的行為",
- "ignore": "無視",
- "copy": "複製",
- "prepend": "放前面",
- "append": "放後面",
- "Create flipped copies": "生成鏡像副本",
- "Split oversized images into two": "將過大的圖像分為兩份",
- "Split oversized images": "分割過大的圖像",
- "Use BLIP for caption": "使用 BLIP 生成說明文字(自然語言描述)",
- "Use deepbooru for caption": "使用 deepbooru 生成說明文字(標籤)",
- "Split image threshold": "圖像分割閾值",
- "Split image overlap ratio": "分割圖像重疊的比率",
- "Preprocess": "預處理",
- "Train an embedding; must specify a directory with a set of 1:1 ratio images": "訓練 embedding; 必須指定一組具有 1:1 比例圖像的目錄",
- "Train an embedding or Hypernetwork; you must specify a directory with a set of 1:1 ratio images": "訓練 embedding 或者 hypernetwork; 必須指定一組具有 1:1 比例圖像的目錄",
- "[wiki]": "[wiki]",
- "Embedding": "Embedding",
- "Embedding Learning rate": "Embedding 學習率",
- "Hypernetwork Learning rate": "Hypernetwork 學習率",
- "Learning rate": "學習率",
- "Dataset directory": "資料集目錄",
- "Log directory": "日誌目錄",
- "Prompt template file": "提示詞模版檔案",
- "Max steps": "最大疊代步數",
- "Save an image to log directory every N steps, 0 to disable": "每 N 步儲存一個圖像到日誌目錄,0 表示禁用",
- "Save a copy of embedding to log directory every N steps, 0 to disable": "每 N 步將 embedding 的副本儲存到日誌目錄,0 表示禁用",
- "Save images with embedding in PNG chunks": "儲存圖像並在 PNG 檔案中嵌入 embedding 檔案",
- "Read parameters (prompt, etc...) from txt2img tab when making previews": "進行預覽時從文生圖頁籤中讀取參數(提示詞等)",
- "Train Hypernetwork": "訓練 Hypernetwork",
- "Train Embedding": "訓練 Embedding",
- "Create an aesthetic embedding out of any number of images": "從任意數量的圖像中建立美術風格 embedding",
- "Create images embedding": "生成圖集 embedding",
- "txt2img history": "文生圖歷史記錄",
- "img2img history": "圖生圖歷史記錄",
- "extras history": "後處理歷史記錄",
- "Renew Page": "刷新頁面",
- "extras": "後處理",
- "favorites": "收藏夾",
- "custom fold": "自訂資料夾",
- "Load": "載入",
- "Images directory": "圖像目錄",
- "Prev batch": "上一批",
- "Next batch": "下一批",
- "First Page": "首頁",
- "Prev Page": "上一頁",
- "Page Index": "頁數",
- "Next Page": "下一頁",
- "End Page": "尾頁",
- "number of images to delete consecutively next": "接下來要連續刪除的圖像數",
- "Delete": "刪除",
- "Generate Info": "生成資訊",
- "File Name": "檔案名",
- "Collect": "收藏",
- "Refresh page": "刷新頁面",
- "Date to": "日期至",
- "Number": "數量",
- "set_index": "設定索引",
- "Checkbox": "核取方塊",
- "Apply settings": "儲存設定",
- "Saving images/grids": "儲存圖像/概覽圖",
- "Always save all generated images": "始終儲存所有生成的圖像",
- "File format for images": "圖像的檔案格式",
- "Images filename pattern": "圖像檔案名格式",
- "Always save all generated image grids": "始終儲存所有生成的概覽圖",
- "File format for grids": "概覽圖的檔案格式",
- "Add extended info (seed, prompt) to filename when saving grid": "儲存概覽時將擴展資訊(隨機種子,提示詞)加入到檔案名",
- "Do not save grids consisting of one picture": "只有一張圖片時不要儲存概覽圖",
- "Prevent empty spots in grid (when set to autodetect)": "(在自動檢測時)防止概覽圖中出現空位",
- "Grid row count; use -1 for autodetect and 0 for it to be same as batch size": "概覽行數; 使用 -1 進行自動檢測,使用 0 使其與批量大小相同",
- "Save text information about generation parameters as chunks to png files": "將有關生成參數的文本資訊作為塊儲存到PNG檔案中",
- "Create a text file next to every image with generation parameters.": "儲存圖像時在每個圖像旁邊建立一個文本檔案儲存生成參數",
- "Save a copy of image before doing face restoration.": "在進行面部修復之前儲存圖像副本",
- "Quality for saved jpeg images": "儲存的JPEG圖像的品質",
- "If PNG image is larger than 4MB or any dimension is larger than 4000, downscale and save copy as JPG": "如果 PNG 圖像大於 4MB 或寬高大於 4000,則縮小並儲存副本為 JPG",
- "Use original name for output filename during batch process in extras tab": "在後處理頁籤中的批量處理過程中使用原始名稱作為輸出檔案名",
- "When using 'Save' button, only save a single selected image": "使用「儲存」按鈕時,只儲存一個選定的圖像",
- "Do not add watermark to images": "不要給圖像加浮水印",
- "Paths for saving": "儲存路徑",
- "Output directory for images; if empty, defaults to three directories below": "圖像的輸出目錄; 如果為空,則預設為以下三個目錄",
- "Output directory for txt2img images": "文生圖的輸出目錄",
- "Output directory for img2img images": "圖生圖的輸出目錄",
- "Output directory for images from extras tab": "後處理的輸出目錄",
- "Output directory for grids; if empty, defaults to two directories below": "概覽圖的輸出目錄; 如果為空,則預設為以下兩個目錄",
- "Output directory for txt2img grids": "文生圖概覽的輸出目錄",
- "Output directory for img2img grids": "圖生圖概覽的輸出目錄",
- "Directory for saving images using the Save button": "使用「儲存」按鈕儲存圖像的目錄",
- "Saving to a directory": "儲存到目錄",
- "Save images to a subdirectory": "將圖像儲存到子目錄",
- "Save grids to a subdirectory": "將概覽圖儲存到子目錄",
- "When using \"Save\" button, save images to a subdirectory": "使用「儲存」按鈕時,將圖像儲存到子目錄",
- "Directory name pattern": "目錄名稱格式",
- "Max prompt words for [prompt_words] pattern": "[prompt_words] 格式的最大提示詞數量",
- "Upscaling": "放大",
- "Tile size for ESRGAN upscalers. 0 = no tiling.": "ESRGAN 的圖塊尺寸。0 = 不分塊",
- "Tile overlap, in pixels for ESRGAN upscalers. Low values = visible seam.": "ESRGAN 的圖塊重疊畫素。低值 = 可見接縫",
- "Tile size for all SwinIR.": "適用所有 SwinIR 系演算法的圖塊尺寸",
- "Tile overlap, in pixels for SwinIR. Low values = visible seam.": "SwinIR 的圖塊重疊畫素。低值 = 可見接縫",
- "LDSR processing steps. Lower = faster": "LDSR 處理疊代步數。更低 = 更快",
- "Upscaler for img2img": "圖生圖的放大演算法",
- "Upscale latent space image when doing hires. fix": "做高解析度修復時也放大潛空間圖像",
- "Face restoration": "面部修復",
- "CodeFormer weight parameter; 0 = maximum effect; 1 = minimum effect": "CodeFormer 權重參數; 0 = 最大效果; 1 = 最小效果",
- "Move face restoration model from VRAM into RAM after processing": "面部修復處理完成後將面部修復模型從顯存(VRAM)移至內存(RAM)",
- "System": "系統",
- "VRAM usage polls per second during generation. Set to 0 to disable.": "生成圖像時每秒輪詢顯存(VRAM)使用情況的次數。設定為 0 以禁用",
- "Always print all generation info to standard output": "始終將所有生成資訊輸出到 standard output (一般為控制台)",
- "Add a second progress bar to the console that shows progress for an entire job.": "向控制台加入第二個進度列,顯示整個作業的進度",
- "Training": "訓練",
- "Unload VAE and CLIP from VRAM when training": "訓練時從顯存(VRAM)中取消 VAE 和 CLIP 的載入",
- "Move VAE and CLIP to RAM when training hypernetwork. Saves VRAM.": "訓練時將 VAE 和 CLIP 從顯存(VRAM)移放到內存(RAM),節省顯存(VRAM)",
- "Filename word regex": "檔案名用詞的正則表達式",
- "Filename join string": "檔案名連接用字串",
- "Number of repeats for a single input image per epoch; used only for displaying epoch number": "每個 epoch 中單個輸入圖像的重複次數; 僅用於顯示 epoch 數",
- "Save an csv containing the loss to log directory every N steps, 0 to disable": "每 N 步儲存一個包含 loss 的CSV到日誌目錄,0 表示禁用",
- "Stable Diffusion": "Stable Diffusion",
- "Checkpoints to cache in RAM": "快取在內存(RAM)中的模型權重存檔點",
- "Hypernetwork strength": "Hypernetwork 強度",
- "Apply color correction to img2img results to match original colors.": "對圖生圖結果套用顏色校正以匹配原始顏色",
- "Save a copy of image before applying color correction to img2img results": "在對圖生圖結果套用顏色校正之前儲存圖像副本",
- "With img2img, do exactly the amount of steps the slider specifies (normally you'd do less with less denoising).": "在進行圖生圖的時候,確切地執行滑塊指定的疊代步數(正常情況下更弱的去噪需要更少的疊代步數)",
- "Enable quantization in K samplers for sharper and cleaner results. This may change existing seeds. Requires restart to apply.": "在 K 採樣器中啟用量化以獲得更清晰,更清晰的結果。這可能會改變現有的隨機種子。需要重新啟動才能套用",
- "Emphasis: use (text) to make model pay more attention to text and [text] to make it pay less attention": "強調符:使用 (文字) 使模型更關注該文本,使用 [文字] 使其減少關注",
- "Use old emphasis implementation. Can be useful to reproduce old seeds.": "使用舊的強調符實作。可用於復現舊隨機種子",
- "Make K-diffusion samplers produce same images in a batch as when making a single image": "使 K-diffusion 採樣器批量生成與生成單個圖像時產出相同的圖像",
- "Increase coherency by padding from the last comma within n tokens when using more than 75 tokens": "當使用超過 75 個 token 時,通過從 n 個 token 中的最後一個逗號填補來提高一致性",
- "Filter NSFW content": "過濾成人內容",
- "Stop At last layers of CLIP model": "在 CLIP 模型的最後哪一層停下",
- "Interrogate Options": "反推提示詞選項",
- "Interrogate: keep models in VRAM": "反推: 將模型儲存在顯存(VRAM)中",
- "Interrogate: use artists from artists.csv": "反推: 使用 artists.csv 中的藝術家",
- "Interrogate: include ranks of model tags matches in results (Has no effect on caption-based interrogators).": "反推: 在生成結果中包含與模型標籤相匹配的等級(對基於生成自然語言描述的反推沒有影響)",
- "Interrogate: num_beams for BLIP": "反推: BLIP 的 num_beams",
- "Interrogate: minimum description length (excluding artists, etc..)": "反推: 最小描述長度(不包括藝術家, 等…)",
- "Interrogate: maximum description length": "反推: 最大描述長度",
- "CLIP: maximum number of lines in text file (0 = No limit)": "CLIP: 文本檔案中的最大行數(0 = 無限制)",
- "Interrogate: deepbooru score threshold": "反推: deepbooru 分數閾值",
- "Interrogate: deepbooru sort alphabetically": "反推: deepbooru 按字母順序排序",
- "use spaces for tags in deepbooru": "在 deepbooru 中為標籤使用空格",
- "escape (\\) brackets in deepbooru (so they are used as literal brackets and not for emphasis)": "在 deepbooru 中使用轉義 (\\) 括號(因此它們用作文字括號而不是強調符號)",
- "User interface": "使用者介面",
- "Show progressbar": "顯示進度列",
- "Show image creation progress every N sampling steps. Set 0 to disable.": "每 N 個採樣疊代步數顯示圖像生成進度。設定 0 禁用",
- "Show previews of all images generated in a batch as a grid": "以網格的形式預覽所有批量生成出來的圖像",
- "Show grid in results for web": "在網頁的結果中顯示概覽圖",
- "Do not show any images in results for web": "不在網頁的結果中顯示任何圖像",
- "Add model hash to generation information": "將模型的雜湊值加入到生成資訊",
- "Add model name to generation information": "將模型名稱加入到生成資訊",
- "When reading generation parameters from text into UI (from PNG info or pasted text), do not change the selected model/checkpoint.": "當從文本讀取生成參數到 UI(從 PNG 資訊或粘貼文本)時,不要更改選定的模型權重存檔點",
- "Font for image grids that have text": "有文字的概覽圖使用的字體",
- "Enable full page image viewer": "啟用整頁圖像檢視器",
- "Show images zoomed in by default in full page image viewer": "在整頁圖像檢視器中預設放大顯示圖像",
- "Show generation progress in window title.": "在視窗標題中顯示生成進度",
- "Quicksettings list": "快速設定列表",
- "Localization (requires restart)": "本地化(需要重新啟動)",
- "Sampler parameters": "採樣器參數",
- "Hide samplers in user interface (requires restart)": "在使用者介面中隱藏採樣器(需要重新啟動)",
- "eta (noise multiplier) for DDIM": "DDIM 的 eta (噪聲乘數)",
- "eta (noise multiplier) for ancestral samplers": "ancestral 採樣器的 eta (噪聲乘數)",
- "img2img DDIM discretize": "圖生圖 DDIM 離散化",
- "uniform": "均勻",
- "quad": "二階",
- "sigma churn": "sigma churn",
- "sigma tmin": "最小(tmin) sigma",
- "sigma noise": "sigma 噪聲",
- "Eta noise seed delta": "Eta 噪聲種子偏移(noise seed delta)",
- "Images Browser": "圖庫瀏覽器",
- "Preload images at startup": "在啟動時預載圖像",
- "Number of columns on the page": "每頁列數",
- "Number of rows on the page": "每頁行數",
- "Number of pictures displayed on each page": "每頁顯示的圖像數量",
- "Minimum number of pages per load": "每次載入的最小頁數",
- "Number of grids in each row": "每行顯示多少格",
- "Wildcards": "萬用字元",
- "Use same seed for all images": "為所有圖像使用同一個隨機種子",
- "Request browser notifications": "請求瀏覽器通知",
- "Download localization template": "下載本地化模板",
- "Reload custom script bodies (No ui updates, No restart)": "重新載入自訂指令碼主體(無UI更新,無重啟)",
- "Restart Gradio and Refresh components (Custom Scripts, ui.py, js and css only)": "重啟 Gradio 及刷新組件(僅限自訂指令碼,ui.py,JS 和 CSS)",
- "Prompt (press Ctrl+Enter or Alt+Enter to generate)": "提示詞(按 Ctrl+Enter 或 Alt+Enter 生成)",
- "Negative prompt (press Ctrl+Enter or Alt+Enter to generate)": "反向提示詞(按 Ctrl+Enter 或 Alt+Enter 生成)",
- "Add a random artist to the prompt.": "隨機加入一個藝術家到提示詞中",
- "Read generation parameters from prompt or last generation if prompt is empty into user interface.": "從提示詞中讀取生成參數,如果提示詞為空,則讀取上一次的生成參數到使用者介面",
- "Save style": "存儲為模板風格",
- "Apply selected styles to current prompt": "將所選樣式套用於當前提示",
- "Stop processing current image and continue processing.": "停止處理當前圖像並繼續處理下一個",
- "Stop processing images and return any results accumulated so far.": "停止處理圖像並返回迄今為止累積的任何結果",
- "Style to apply; styles have components for both positive and negative prompts and apply to both": "要套用的模版風格; 模版風格包含正向和反向提示詞,並套用於兩者",
- "Do not do anything special": "什麼都不做",
- "Which algorithm to use to produce the image": "使用哪種演算法生成圖像",
- "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps to higher than 30-40 does not help": "Euler Ancestral - 非常有創意,可以根據疊代步數獲得完全不同的圖像,將疊代步數設定為高於 30-40 不會有正面作用",
- "Denoising Diffusion Implicit Models - best at inpainting": "Denoising Diffusion Implicit models - 最擅長內補繪製",
- "Produce an image that can be tiled.": "生成可用於平舖的圖像",
- "Use a two step process to partially create an image at smaller resolution, upscale, and then improve details in it without changing composition": "使用兩步處理的時候以較小的解析度生成初步圖像,接著放大圖像,然後在不更改構圖的情況下改進其中的細節",
- "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.": "決定演算法對圖像內容的影響程度。設定 0 時,什麼都不會改變,而在 1 時,你將獲得不相關的圖像。值低於 1.0 時,處理的疊代步數將少於「採樣疊代步數」滑塊指定的步數",
- "How many batches of images to create": "建立多少批次的圖像",
- "How many image to create in a single batch": "每批建立多少圖像",
- "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results": "Classifier Free Guidance Scale - 圖像應在多大程度上服從提示詞 - 較低的值會產生更有創意的結果",
- "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result": "一個固定隨機數生成器輸出的值 — 以相同參數和隨機種子生成的圖像會得到相同的結果",
- "Set seed to -1, which will cause a new random number to be used every time": "將隨機種子設定為-1,則每次都會使用一個新的隨機數",
- "Reuse seed from last generation, mostly useful if it was randomed": "重用上一次使用的隨機種子,如果想要固定結果就會很有用",
- "Seed of a different picture to be mixed into the generation.": "將要參與生成的另一張圖的隨機種子",
- "How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something).": "想要產生多強烈的變化。設為 0 時,將沒有效果。設為 1 時,你將獲得完全產自差異隨機種子的圖像(ancestral 採樣器除外,你只是單純地生成了一些東西)",
- "Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution": "嘗試生成與在指定解析度下使用相同隨機種子生成的圖像相似的圖片",
- "This text is used to rotate the feature space of the imgs embs": "此文本用於旋轉圖集 embeddings 的特徵空間",
- "Separate values for X axis using commas.": "使用逗號分隔 X 軸的值",
- "Separate values for Y axis using commas.": "使用逗號分隔 Y 軸的值",
- "Write image to a directory (default - log/images) and generation parameters into csv file.": "將圖像寫入目錄(預設 — log/images)並將生成參數寫入CSV檔案",
- "Open images output directory": "打開圖像輸出目錄",
- "How much to blur the mask before processing, in pixels.": "處理前要對蒙版進行多強的模糊,以畫素為單位",
- "What to put inside the masked area before processing it with Stable Diffusion.": "在使用 Stable Diffusion 處理蒙版區域之前要在蒙版區域內放置什麼",
- "fill it with colors of the image": "用圖像的顏色填充它",
- "keep whatever was there originally": "保留原來的内容",
- "fill it with latent space noise": "用潛空間的噪聲填充它",
- "fill it with latent space zeroes": "用潛空間的零填充它",
- "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image": "將蒙版區域放大到目標解析度,做內補繪製,縮小後粘貼到原始圖像中",
- "Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.": "將圖像大小調整為目標解析度。除非高度和寬度匹配,否則你將獲得不正確的縱橫比",
- "Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out.": "調整圖像大小,使整個目標解析度都被圖像填充。裁剪多出來的部分",
- "Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors.": "調整圖像大小,使整個圖像在目標解析度內。用圖像的顏色填充空白區域",
- "How many times to repeat processing an image and using it as input for the next iteration": "重複處理圖像並用作下次疊代輸入的次數",
- "In loopback mode, on each loop the denoising strength is multiplied by this value. <1 means decreasing variety so your sequence will converge on a fixed picture. >1 means increasing variety so your sequence will become more and more chaotic.": "在回送模式下,在每個循環中,去噪強度都會乘以該值。<1 表示減少多樣性,因此你的這一組圖將集中在固定的圖像上。>1 意味著增加多樣性,因此你的這一組圖將變得越來越混亂",
- "For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam.": "使用 SD 放大時,圖塊之間應該有多少畫素重疊。圖塊之間需要重疊才可以讓它們在合併回一張圖像時,沒有清晰可見的接縫",
- "A directory on the same machine where the server is running.": "與伺服器主機上的目錄",
- "Leave blank to save images to the default path.": "留空以將圖像儲存到預設路徑",
- "Result = A * (1 - M) + B * M": "結果 = A * (1 - M) + B * M",
- "Result = A + (B - C) * M": "結果 = A + (B - C) * M",
- "1st and last digit must be 1. ex:'1, 2, 1'": "第一個和最後一個數字必須是 1。例:'1, 2, 1'",
- "how fast should the training go. Low values will take longer to train, high values may fail to converge (not generate accurate results) and/or may break the embedding (This has happened if you see Loss: nan in the training info textbox. If this happens, you need to manually restore your embedding from an older not-broken backup).\n\nYou can set a single numeric value, or multiple learning rates using the syntax:\n\n rate_1:max_steps_1, rate_2:max_steps_2, ...\n\nEG: 0.005:100, 1e-3:1000, 1e-5\n\nWill train with rate of 0.005 for first 100 steps, then 1e-3 until 1000 steps, then 1e-5 for all remaining steps.": "訓練應該多快。低值將需要更長的時間來訓練,高值可能無法收斂(無法產生準確的結果)以及/也許可能會破壞 embedding(如果你在訓練資訊文字方塊中看到 Loss: nan 就會發生這種情況。如果發生這種情況,你需要從較舊的未損壞的備份手動恢復 embedding)\n\n你可以使用以下語法設定單個數值或多個學習率:\n\n 率1:步限1, 率2:步限2, …\n\n如: 0.005:100, 1e-3:1000, 1e-5\n\n即前 100 步將以 0.005 的速率訓練,接著直到 1000 步為止以 1e-3 訓練,然後剩餘所有步以 1e-5 訓練",
- "Path to directory with input images": "帶有輸入圖像的路徑",
- "Path to directory where to write outputs": "進行輸出的路徑",
- "Input images directory": "輸入圖像目錄",
- "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; leave empty for default.": "使用以下標籤定義如何選擇圖像的檔案名: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; 預設請留空",
- "If this option is enabled, watermark will not be added to created images. Warning: if you do not add watermark, you may be behaving in an unethical manner.": "如果啟用此選項,浮水印將不會加入到生成出來的圖像中。警告:如果你不加入浮水印,你的行為可能是不符合道德操守的",
- "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; leave empty for default.": "使用以下標籤定義如何選擇圖像和概覽圖的子目錄: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [prompt_words], [date], [datetime], [job_timestamp]; 預設請留空",
- "Restore low quality faces using GFPGAN neural network": "使用 GFPGAN 神經網路修復低品質面部",
- "This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is.": "此正則表達式將用於從檔案名中提取單詞,並將使用以下選項將它們接合到用於訓練的標籤文本中。留空以保持檔案名文本不變",
- "This string will be used to join split words into a single line if the option above is enabled.": "如果啟用了上述選項,則此處的字元會用於將拆分的單詞接合為同一行",
- "List of setting names, separated by commas, for settings that should go to the quick access bar at the top, rather than the usual setting tab. See modules/shared.py for setting names. Requires restarting to apply.": "設定名稱列表,以逗號分隔,設定應轉到頂部的快速存取列,而不是通常的設定頁籤。有關設定名稱,請參見 modules/shared.py。需要重新啟動才能套用",
- "If this values is non-zero, it will be added to seed and used to initialize RNG for noises when using samplers with Eta. You can use this to produce even more variation of images, or you can use this to match images of other software if you know what you are doing.": "如果這個值不為零,它將被加入到隨機種子中,並在使用帶有 Eta 的採樣器時用於初始化隨機噪聲。你可以使用它來產生更多的圖像變化,或者你可以使用它來模仿其他軟體生成的圖像,如果你知道你在做什麼",
- "Enable Autocomplete": "開啟Tag補全",
- "Allowed categories for random artists selection when using the Roll button": "使用抽選藝術家按鈕時將會隨機的藝術家類別",
- "Roll three": "抽三位出來",
- "Generate forever": "不停地生成",
- "Cancel generate forever": "取消不停地生成"
-}
diff --git a/models/VAE-approx/model.pt b/models/VAE-approx/model.pt
new file mode 100644
index 00000000..8bda9d6e
--- /dev/null
+++ b/models/VAE-approx/model.pt
Binary files differ
diff --git a/models/VAE/Put VAE here.txt b/models/VAE/Put VAE here.txt
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/models/VAE/Put VAE here.txt
diff --git a/modules/api/api.py b/modules/api/api.py
index bb87d795..48a70a44 100644
--- a/modules/api/api.py
+++ b/modules/api/api.py
@@ -1,16 +1,28 @@
import base64
import io
import time
+import datetime
import uvicorn
-from gradio.processing_utils import decode_base64_to_file, decode_base64_to_image
-from fastapi import APIRouter, Depends, HTTPException
+from threading import Lock
+from io import BytesIO
+from gradio.processing_utils import decode_base64_to_file
+from fastapi import APIRouter, Depends, FastAPI, HTTPException, Request, Response
+from fastapi.security import HTTPBasic, HTTPBasicCredentials
+from secrets import compare_digest
+
import modules.shared as shared
-from modules import devices
+from modules import sd_samplers, deepbooru, sd_hijack
from modules.api.models import *
from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img, process_images
-from modules.sd_samplers import all_samplers
from modules.extras import run_extras, run_pnginfo
-
+from modules.textual_inversion.textual_inversion import create_embedding, train_embedding
+from modules.textual_inversion.preprocess import preprocess
+from modules.hypernetworks.hypernetwork import create_hypernetwork, train_hypernetwork
+from PIL import PngImagePlugin,Image
+from modules.sd_models import checkpoints_list, find_checkpoint_config
+from modules.realesrgan_model import get_realesrgan_models
+from modules import devices
+from typing import List
def upscaler_to_index(name: str):
try:
@@ -19,8 +31,12 @@ def upscaler_to_index(name: str):
raise HTTPException(status_code=400, detail=f"Invalid upscaler, needs to be on of these: {' , '.join([x.name for x in sd_upscalers])}")
-sampler_to_index = lambda name: next(filter(lambda row: name.lower() == row[1].name.lower(), enumerate(all_samplers)), None)
+def validate_sampler_name(name):
+ config = sd_samplers.all_samplers_map.get(name, None)
+ if config is None:
+ raise HTTPException(status_code=404, detail="Sampler not found")
+ return name
def setUpscalers(req: dict):
reqDict = vars(req)
@@ -30,60 +46,126 @@ def setUpscalers(req: dict):
reqDict.pop('upscaler_2')
return reqDict
+def decode_base64_to_image(encoding):
+ if encoding.startswith("data:image/"):
+ encoding = encoding.split(";")[1].split(",")[1]
+ return Image.open(BytesIO(base64.b64decode(encoding)))
def encode_pil_to_base64(image):
- buffer = io.BytesIO()
- image.save(buffer, format="png")
- return base64.b64encode(buffer.getvalue())
+ with io.BytesIO() as output_bytes:
+
+ # Copy any text-only metadata
+ use_metadata = False
+ metadata = PngImagePlugin.PngInfo()
+ for key, value in image.info.items():
+ if isinstance(key, str) and isinstance(value, str):
+ metadata.add_text(key, value)
+ use_metadata = True
+
+ image.save(
+ output_bytes, "PNG", pnginfo=(metadata if use_metadata else None)
+ )
+ bytes_data = output_bytes.getvalue()
+ return base64.b64encode(bytes_data)
+
+def api_middleware(app: FastAPI):
+ @app.middleware("http")
+ async def log_and_time(req: Request, call_next):
+ ts = time.time()
+ res: Response = await call_next(req)
+ duration = str(round(time.time() - ts, 4))
+ res.headers["X-Process-Time"] = duration
+ endpoint = req.scope.get('path', 'err')
+ if shared.cmd_opts.api_log and endpoint.startswith('/sdapi'):
+ print('API {t} {code} {prot}/{ver} {method} {endpoint} {cli} {duration}'.format(
+ t = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"),
+ code = res.status_code,
+ ver = req.scope.get('http_version', '0.0'),
+ cli = req.scope.get('client', ('0:0.0.0', 0))[0],
+ prot = req.scope.get('scheme', 'err'),
+ method = req.scope.get('method', 'err'),
+ endpoint = endpoint,
+ duration = duration,
+ ))
+ return res
class Api:
- def __init__(self, app, queue_lock):
+ def __init__(self, app: FastAPI, queue_lock: Lock):
+ if shared.cmd_opts.api_auth:
+ self.credentials = dict()
+ for auth in shared.cmd_opts.api_auth.split(","):
+ user, password = auth.split(":")
+ self.credentials[user] = password
+
self.router = APIRouter()
self.app = app
self.queue_lock = queue_lock
- self.app.add_api_route("/sdapi/v1/txt2img", self.text2imgapi, methods=["POST"], response_model=TextToImageResponse)
- self.app.add_api_route("/sdapi/v1/img2img", self.img2imgapi, methods=["POST"], response_model=ImageToImageResponse)
- self.app.add_api_route("/sdapi/v1/extra-single-image", self.extras_single_image_api, methods=["POST"], response_model=ExtrasSingleImageResponse)
- self.app.add_api_route("/sdapi/v1/extra-batch-images", self.extras_batch_images_api, methods=["POST"], response_model=ExtrasBatchImagesResponse)
- self.app.add_api_route("/sdapi/v1/png-info", self.pnginfoapi, methods=["POST"], response_model=PNGInfoResponse)
- self.app.add_api_route("/sdapi/v1/progress", self.progressapi, methods=["GET"], response_model=ProgressResponse)
- self.app.add_api_route("/sdapi/v1/interrupt", self.interruptapi, methods=["POST"])
+ api_middleware(self.app)
+ self.add_api_route("/sdapi/v1/txt2img", self.text2imgapi, methods=["POST"], response_model=TextToImageResponse)
+ self.add_api_route("/sdapi/v1/img2img", self.img2imgapi, methods=["POST"], response_model=ImageToImageResponse)
+ self.add_api_route("/sdapi/v1/extra-single-image", self.extras_single_image_api, methods=["POST"], response_model=ExtrasSingleImageResponse)
+ self.add_api_route("/sdapi/v1/extra-batch-images", self.extras_batch_images_api, methods=["POST"], response_model=ExtrasBatchImagesResponse)
+ self.add_api_route("/sdapi/v1/png-info", self.pnginfoapi, methods=["POST"], response_model=PNGInfoResponse)
+ self.add_api_route("/sdapi/v1/progress", self.progressapi, methods=["GET"], response_model=ProgressResponse)
+ self.add_api_route("/sdapi/v1/interrogate", self.interrogateapi, methods=["POST"])
+ self.add_api_route("/sdapi/v1/interrupt", self.interruptapi, methods=["POST"])
+ self.add_api_route("/sdapi/v1/skip", self.skip, methods=["POST"])
+ self.add_api_route("/sdapi/v1/options", self.get_config, methods=["GET"], response_model=OptionsModel)
+ self.add_api_route("/sdapi/v1/options", self.set_config, methods=["POST"])
+ self.add_api_route("/sdapi/v1/cmd-flags", self.get_cmd_flags, methods=["GET"], response_model=FlagsModel)
+ self.add_api_route("/sdapi/v1/samplers", self.get_samplers, methods=["GET"], response_model=List[SamplerItem])
+ self.add_api_route("/sdapi/v1/upscalers", self.get_upscalers, methods=["GET"], response_model=List[UpscalerItem])
+ self.add_api_route("/sdapi/v1/sd-models", self.get_sd_models, methods=["GET"], response_model=List[SDModelItem])
+ self.add_api_route("/sdapi/v1/hypernetworks", self.get_hypernetworks, methods=["GET"], response_model=List[HypernetworkItem])
+ self.add_api_route("/sdapi/v1/face-restorers", self.get_face_restorers, methods=["GET"], response_model=List[FaceRestorerItem])
+ self.add_api_route("/sdapi/v1/realesrgan-models", self.get_realesrgan_models, methods=["GET"], response_model=List[RealesrganItem])
+ self.add_api_route("/sdapi/v1/prompt-styles", self.get_prompt_styles, methods=["GET"], response_model=List[PromptStyleItem])
+ self.add_api_route("/sdapi/v1/artist-categories", self.get_artists_categories, methods=["GET"], response_model=List[str])
+ self.add_api_route("/sdapi/v1/artists", self.get_artists, methods=["GET"], response_model=List[ArtistItem])
+ self.add_api_route("/sdapi/v1/embeddings", self.get_embeddings, methods=["GET"], response_model=EmbeddingsResponse)
+ self.add_api_route("/sdapi/v1/refresh-checkpoints", self.refresh_checkpoints, methods=["POST"])
+ self.add_api_route("/sdapi/v1/create/embedding", self.create_embedding, methods=["POST"], response_model=CreateResponse)
+ self.add_api_route("/sdapi/v1/create/hypernetwork", self.create_hypernetwork, methods=["POST"], response_model=CreateResponse)
+ self.add_api_route("/sdapi/v1/preprocess", self.preprocess, methods=["POST"], response_model=PreprocessResponse)
+ self.add_api_route("/sdapi/v1/train/embedding", self.train_embedding, methods=["POST"], response_model=TrainResponse)
+ self.add_api_route("/sdapi/v1/train/hypernetwork", self.train_hypernetwork, methods=["POST"], response_model=TrainResponse)
+
+ def add_api_route(self, path: str, endpoint, **kwargs):
+ if shared.cmd_opts.api_auth:
+ return self.app.add_api_route(path, endpoint, dependencies=[Depends(self.auth)], **kwargs)
+ return self.app.add_api_route(path, endpoint, **kwargs)
+
+ def auth(self, credentials: HTTPBasicCredentials = Depends(HTTPBasic())):
+ if credentials.username in self.credentials:
+ if compare_digest(credentials.password, self.credentials[credentials.username]):
+ return True
+
+ raise HTTPException(status_code=401, detail="Incorrect username or password", headers={"WWW-Authenticate": "Basic"})
def text2imgapi(self, txt2imgreq: StableDiffusionTxt2ImgProcessingAPI):
- sampler_index = sampler_to_index(txt2imgreq.sampler_index)
-
- if sampler_index is None:
- raise HTTPException(status_code=404, detail="Sampler not found")
-
populate = txt2imgreq.copy(update={ # Override __init__ params
- "sd_model": shared.sd_model,
- "sampler_index": sampler_index[0],
+ "sampler_name": validate_sampler_name(txt2imgreq.sampler_name or txt2imgreq.sampler_index),
"do_not_save_samples": True,
"do_not_save_grid": True
}
)
- p = StableDiffusionProcessingTxt2Img(**vars(populate))
- # Override object param
-
- shared.state.begin()
+ if populate.sampler_name:
+ populate.sampler_index = None # prevent a warning later on
with self.queue_lock:
+ p = StableDiffusionProcessingTxt2Img(sd_model=shared.sd_model, **vars(populate))
+
+ shared.state.begin()
processed = process_images(p)
+ shared.state.end()
- shared.state.end()
b64images = list(map(encode_pil_to_base64, processed.images))
return TextToImageResponse(images=b64images, parameters=vars(txt2imgreq), info=processed.js())
def img2imgapi(self, img2imgreq: StableDiffusionImg2ImgProcessingAPI):
- sampler_index = sampler_to_index(img2imgreq.sampler_index)
-
- if sampler_index is None:
- raise HTTPException(status_code=404, detail="Sampler not found")
-
-
init_images = img2imgreq.init_images
if init_images is None:
raise HTTPException(status_code=404, detail="Init image not found")
@@ -92,34 +174,30 @@ class Api:
if mask:
mask = decode_base64_to_image(mask)
-
populate = img2imgreq.copy(update={ # Override __init__ params
- "sd_model": shared.sd_model,
- "sampler_index": sampler_index[0],
+ "sampler_name": validate_sampler_name(img2imgreq.sampler_name or img2imgreq.sampler_index),
"do_not_save_samples": True,
"do_not_save_grid": True,
"mask": mask
}
)
- p = StableDiffusionProcessingImg2Img(**vars(populate))
+ if populate.sampler_name:
+ populate.sampler_index = None # prevent a warning later on
- imgs = []
- for img in init_images:
- img = decode_base64_to_image(img)
- imgs = [img] * p.batch_size
-
- p.init_images = imgs
-
- shared.state.begin()
+ args = vars(populate)
+ args.pop('include_init_images', None) # this is meant to be done by "exclude": True in model, but it's for a reason that I cannot determine.
with self.queue_lock:
- processed = process_images(p)
+ p = StableDiffusionProcessingImg2Img(sd_model=shared.sd_model, **args)
+ p.init_images = [decode_base64_to_image(x) for x in init_images]
- shared.state.end()
+ shared.state.begin()
+ processed = process_images(p)
+ shared.state.end()
b64images = list(map(encode_pil_to_base64, processed.images))
- if (not img2imgreq.include_init_images):
+ if not img2imgreq.include_init_images:
img2imgreq.init_images = None
img2imgreq.mask = None
@@ -131,7 +209,7 @@ class Api:
reqDict['image'] = decode_base64_to_image(reqDict['image'])
with self.queue_lock:
- result = run_extras(extras_mode=0, image_folder="", input_dir="", output_dir="", **reqDict)
+ result = run_extras(extras_mode=0, image_folder="", input_dir="", output_dir="", save_output=False, **reqDict)
return ExtrasSingleImageResponse(image=encode_pil_to_base64(result[0][0]), html_info=result[1])
@@ -147,7 +225,7 @@ class Api:
reqDict.pop('imageList')
with self.queue_lock:
- result = run_extras(extras_mode=1, image="", input_dir="", output_dir="", **reqDict)
+ result = run_extras(extras_mode=1, image="", input_dir="", output_dir="", save_output=False, **reqDict)
return ExtrasBatchImagesResponse(images=list(map(encode_pil_to_base64, result[0])), html_info=result[1])
@@ -179,17 +257,206 @@ class Api:
progress = min(progress, 1)
+ shared.state.set_current_image()
+
current_image = None
if shared.state.current_image and not req.skip_current_image:
current_image = encode_pil_to_base64(shared.state.current_image)
return ProgressResponse(progress=progress, eta_relative=eta_relative, state=shared.state.dict(), current_image=current_image)
+ def interrogateapi(self, interrogatereq: InterrogateRequest):
+ image_b64 = interrogatereq.image
+ if image_b64 is None:
+ raise HTTPException(status_code=404, detail="Image not found")
+
+ img = decode_base64_to_image(image_b64)
+ img = img.convert('RGB')
+
+ # Override object param
+ with self.queue_lock:
+ if interrogatereq.model == "clip":
+ processed = shared.interrogator.interrogate(img)
+ elif interrogatereq.model == "deepdanbooru":
+ processed = deepbooru.model.tag(img)
+ else:
+ raise HTTPException(status_code=404, detail="Model not found")
+
+ return InterrogateResponse(caption=processed)
+
def interruptapi(self):
shared.state.interrupt()
return {}
+ def skip(self):
+ shared.state.skip()
+
+ def get_config(self):
+ options = {}
+ for key in shared.opts.data.keys():
+ metadata = shared.opts.data_labels.get(key)
+ if(metadata is not None):
+ options.update({key: shared.opts.data.get(key, shared.opts.data_labels.get(key).default)})
+ else:
+ options.update({key: shared.opts.data.get(key, None)})
+
+ return options
+
+ def set_config(self, req: Dict[str, Any]):
+ for k, v in req.items():
+ shared.opts.set(k, v)
+
+ shared.opts.save(shared.config_filename)
+ return
+
+ def get_cmd_flags(self):
+ return vars(shared.cmd_opts)
+
+ def get_samplers(self):
+ return [{"name": sampler[0], "aliases":sampler[2], "options":sampler[3]} for sampler in sd_samplers.all_samplers]
+
+ def get_upscalers(self):
+ upscalers = []
+
+ for upscaler in shared.sd_upscalers:
+ u = upscaler.scaler
+ upscalers.append({"name":u.name, "model_name":u.model_name, "model_path":u.model_path, "model_url":u.model_url})
+
+ return upscalers
+
+ def get_sd_models(self):
+ return [{"title":x.title, "model_name":x.model_name, "hash":x.hash, "filename": x.filename, "config": find_checkpoint_config(x)} for x in checkpoints_list.values()]
+
+ def get_hypernetworks(self):
+ return [{"name": name, "path": shared.hypernetworks[name]} for name in shared.hypernetworks]
+
+ def get_face_restorers(self):
+ return [{"name":x.name(), "cmd_dir": getattr(x, "cmd_dir", None)} for x in shared.face_restorers]
+
+ def get_realesrgan_models(self):
+ return [{"name":x.name,"path":x.data_path, "scale":x.scale} for x in get_realesrgan_models(None)]
+
+ def get_prompt_styles(self):
+ styleList = []
+ for k in shared.prompt_styles.styles:
+ style = shared.prompt_styles.styles[k]
+ styleList.append({"name":style[0], "prompt": style[1], "negative_prompt": style[2]})
+
+ return styleList
+
+ def get_artists_categories(self):
+ return shared.artist_db.cats
+
+ def get_artists(self):
+ return [{"name":x[0], "score":x[1], "category":x[2]} for x in shared.artist_db.artists]
+
+ def get_embeddings(self):
+ db = sd_hijack.model_hijack.embedding_db
+
+ def convert_embedding(embedding):
+ return {
+ "step": embedding.step,
+ "sd_checkpoint": embedding.sd_checkpoint,
+ "sd_checkpoint_name": embedding.sd_checkpoint_name,
+ "shape": embedding.shape,
+ "vectors": embedding.vectors,
+ }
+
+ def convert_embeddings(embeddings):
+ return {embedding.name: convert_embedding(embedding) for embedding in embeddings.values()}
+
+ return {
+ "loaded": convert_embeddings(db.word_embeddings),
+ "skipped": convert_embeddings(db.skipped_embeddings),
+ }
+
+ def refresh_checkpoints(self):
+ shared.refresh_checkpoints()
+
+ def create_embedding(self, args: dict):
+ try:
+ shared.state.begin()
+ filename = create_embedding(**args) # create empty embedding
+ sd_hijack.model_hijack.embedding_db.load_textual_inversion_embeddings() # reload embeddings so new one can be immediately used
+ shared.state.end()
+ return CreateResponse(info = "create embedding filename: {filename}".format(filename = filename))
+ except AssertionError as e:
+ shared.state.end()
+ return TrainResponse(info = "create embedding error: {error}".format(error = e))
+
+ def create_hypernetwork(self, args: dict):
+ try:
+ shared.state.begin()
+ filename = create_hypernetwork(**args) # create empty embedding
+ shared.state.end()
+ return CreateResponse(info = "create hypernetwork filename: {filename}".format(filename = filename))
+ except AssertionError as e:
+ shared.state.end()
+ return TrainResponse(info = "create hypernetwork error: {error}".format(error = e))
+
+ def preprocess(self, args: dict):
+ try:
+ shared.state.begin()
+ preprocess(**args) # quick operation unless blip/booru interrogation is enabled
+ shared.state.end()
+ return PreprocessResponse(info = 'preprocess complete')
+ except KeyError as e:
+ shared.state.end()
+ return PreprocessResponse(info = "preprocess error: invalid token: {error}".format(error = e))
+ except AssertionError as e:
+ shared.state.end()
+ return PreprocessResponse(info = "preprocess error: {error}".format(error = e))
+ except FileNotFoundError as e:
+ shared.state.end()
+ return PreprocessResponse(info = 'preprocess error: {error}'.format(error = e))
+
+ def train_embedding(self, args: dict):
+ try:
+ shared.state.begin()
+ apply_optimizations = shared.opts.training_xattention_optimizations
+ error = None
+ filename = ''
+ if not apply_optimizations:
+ sd_hijack.undo_optimizations()
+ try:
+ embedding, filename = train_embedding(**args) # can take a long time to complete
+ except Exception as e:
+ error = e
+ finally:
+ if not apply_optimizations:
+ sd_hijack.apply_optimizations()
+ shared.state.end()
+ return TrainResponse(info = "train embedding complete: filename: {filename} error: {error}".format(filename = filename, error = error))
+ except AssertionError as msg:
+ shared.state.end()
+ return TrainResponse(info = "train embedding error: {msg}".format(msg = msg))
+
+ def train_hypernetwork(self, args: dict):
+ try:
+ shared.state.begin()
+ initial_hypernetwork = shared.loaded_hypernetwork
+ apply_optimizations = shared.opts.training_xattention_optimizations
+ error = None
+ filename = ''
+ if not apply_optimizations:
+ sd_hijack.undo_optimizations()
+ try:
+ hypernetwork, filename = train_hypernetwork(*args)
+ except Exception as e:
+ error = e
+ finally:
+ shared.loaded_hypernetwork = initial_hypernetwork
+ shared.sd_model.cond_stage_model.to(devices.device)
+ shared.sd_model.first_stage_model.to(devices.device)
+ if not apply_optimizations:
+ sd_hijack.apply_optimizations()
+ shared.state.end()
+ return TrainResponse(info = "train embedding complete: filename: {filename} error: {error}".format(filename = filename, error = error))
+ except AssertionError as msg:
+ shared.state.end()
+ return TrainResponse(info = "train embedding error: {error}".format(error = error))
+
def launch(self, server_name, port):
self.app.include_router(self.router)
uvicorn.run(self.app, host=server_name, port=port)
diff --git a/modules/api/models.py b/modules/api/models.py
index 9ee42a17..4a632c68 100644
--- a/modules/api/models.py
+++ b/modules/api/models.py
@@ -1,11 +1,11 @@
import inspect
-from click import prompt
from pydantic import BaseModel, Field, create_model
from typing import Any, Optional
from typing_extensions import Literal
from inflection import underscore
from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img
-from modules.shared import sd_upscalers
+from modules.shared import sd_upscalers, opts, parser
+from typing import Dict, List
API_NOT_ALLOWED = [
"self",
@@ -65,6 +65,7 @@ class PydanticModelGenerator:
self._model_name = model_name
self._class_data = merge_class_params(class_instance)
+
self._model_def = [
ModelDef(
field=underscore(k),
@@ -109,12 +110,12 @@ StableDiffusionImg2ImgProcessingAPI = PydanticModelGenerator(
).generate_model()
class TextToImageResponse(BaseModel):
- images: list[str] = Field(default=None, title="Image", description="The generated image in base64 format.")
+ images: List[str] = Field(default=None, title="Image", description="The generated image in base64 format.")
parameters: dict
info: str
class ImageToImageResponse(BaseModel):
- images: list[str] = Field(default=None, title="Image", description="The generated image in base64 format.")
+ images: List[str] = Field(default=None, title="Image", description="The generated image in base64 format.")
parameters: dict
info: str
@@ -127,10 +128,11 @@ class ExtrasBaseRequest(BaseModel):
upscaling_resize: float = Field(default=2, title="Upscaling Factor", ge=1, le=4, description="By how much to upscale the image, only used when resize_mode=0.")
upscaling_resize_w: int = Field(default=512, title="Target Width", ge=1, description="Target width for the upscaler to hit. Only used when resize_mode=1.")
upscaling_resize_h: int = Field(default=512, title="Target Height", ge=1, description="Target height for the upscaler to hit. Only used when resize_mode=1.")
- upscaling_crop: bool = Field(default=True, title="Crop to fit", description="Should the upscaler crop the image to fit in the choosen size?")
+ upscaling_crop: bool = Field(default=True, title="Crop to fit", description="Should the upscaler crop the image to fit in the chosen size?")
upscaler_1: str = Field(default="None", title="Main upscaler", description=f"The name of the main upscaler to use, it has to be one of this list: {' , '.join([x.name for x in sd_upscalers])}")
upscaler_2: str = Field(default="None", title="Secondary upscaler", description=f"The name of the secondary upscaler to use, it has to be one of this list: {' , '.join([x.name for x in sd_upscalers])}")
extras_upscaler_2_visibility: float = Field(default=0, title="Secondary upscaler visibility", ge=0, le=1, allow_inf_nan=False, description="Sets the visibility of secondary upscaler, values should be between 0 and 1.")
+ upscale_first: bool = Field(default=False, title="Upscale first", description="Should the upscaler run before restoring faces?")
class ExtraBaseResponse(BaseModel):
html_info: str = Field(title="HTML info", description="A series of HTML tags containing the process info.")
@@ -146,10 +148,10 @@ class FileData(BaseModel):
name: str = Field(title="File name")
class ExtrasBatchImagesRequest(ExtrasBaseRequest):
- imageList: list[FileData] = Field(title="Images", description="List of images to work on. Must be Base64 strings")
+ imageList: List[FileData] = Field(title="Images", description="List of images to work on. Must be Base64 strings")
class ExtrasBatchImagesResponse(ExtraBaseResponse):
- images: list[str] = Field(title="Images", description="The generated images in base64 format.")
+ images: List[str] = Field(title="Images", description="The generated images in base64 format.")
class PNGInfoRequest(BaseModel):
image: str = Field(title="Image", description="The base64 encoded PNG image")
@@ -165,3 +167,95 @@ class ProgressResponse(BaseModel):
eta_relative: float = Field(title="ETA in secs")
state: dict = Field(title="State", description="The current state snapshot")
current_image: str = Field(default=None, title="Current image", description="The current image in base64 format. opts.show_progress_every_n_steps is required for this to work.")
+
+class InterrogateRequest(BaseModel):
+ image: str = Field(default="", title="Image", description="Image to work on, must be a Base64 string containing the image's data.")
+ model: str = Field(default="clip", title="Model", description="The interrogate model used.")
+
+class InterrogateResponse(BaseModel):
+ caption: str = Field(default=None, title="Caption", description="The generated caption for the image.")
+
+class TrainResponse(BaseModel):
+ info: str = Field(title="Train info", description="Response string from train embedding or hypernetwork task.")
+
+class CreateResponse(BaseModel):
+ info: str = Field(title="Create info", description="Response string from create embedding or hypernetwork task.")
+
+class PreprocessResponse(BaseModel):
+ info: str = Field(title="Preprocess info", description="Response string from preprocessing task.")
+
+fields = {}
+for key, metadata in opts.data_labels.items():
+ value = opts.data.get(key)
+ optType = opts.typemap.get(type(metadata.default), type(value))
+
+ if (metadata is not None):
+ fields.update({key: (Optional[optType], Field(
+ default=metadata.default ,description=metadata.label))})
+ else:
+ fields.update({key: (Optional[optType], Field())})
+
+OptionsModel = create_model("Options", **fields)
+
+flags = {}
+_options = vars(parser)['_option_string_actions']
+for key in _options:
+ if(_options[key].dest != 'help'):
+ flag = _options[key]
+ _type = str
+ if _options[key].default is not None: _type = type(_options[key].default)
+ flags.update({flag.dest: (_type,Field(default=flag.default, description=flag.help))})
+
+FlagsModel = create_model("Flags", **flags)
+
+class SamplerItem(BaseModel):
+ name: str = Field(title="Name")
+ aliases: List[str] = Field(title="Aliases")
+ options: Dict[str, str] = Field(title="Options")
+
+class UpscalerItem(BaseModel):
+ name: str = Field(title="Name")
+ model_name: Optional[str] = Field(title="Model Name")
+ model_path: Optional[str] = Field(title="Path")
+ model_url: Optional[str] = Field(title="URL")
+
+class SDModelItem(BaseModel):
+ title: str = Field(title="Title")
+ model_name: str = Field(title="Model Name")
+ hash: str = Field(title="Hash")
+ filename: str = Field(title="Filename")
+ config: str = Field(title="Config file")
+
+class HypernetworkItem(BaseModel):
+ name: str = Field(title="Name")
+ path: Optional[str] = Field(title="Path")
+
+class FaceRestorerItem(BaseModel):
+ name: str = Field(title="Name")
+ cmd_dir: Optional[str] = Field(title="Path")
+
+class RealesrganItem(BaseModel):
+ name: str = Field(title="Name")
+ path: Optional[str] = Field(title="Path")
+ scale: Optional[int] = Field(title="Scale")
+
+class PromptStyleItem(BaseModel):
+ name: str = Field(title="Name")
+ prompt: Optional[str] = Field(title="Prompt")
+ negative_prompt: Optional[str] = Field(title="Negative Prompt")
+
+class ArtistItem(BaseModel):
+ name: str = Field(title="Name")
+ score: float = Field(title="Score")
+ category: str = Field(title="Category")
+
+class EmbeddingItem(BaseModel):
+ step: Optional[int] = Field(title="Step", description="The number of steps that were used to train this embedding, if available")
+ sd_checkpoint: Optional[str] = Field(title="SD Checkpoint", description="The hash of the checkpoint this embedding was trained on, if available")
+ sd_checkpoint_name: Optional[str] = Field(title="SD Checkpoint Name", description="The name of the checkpoint this embedding was trained on, if available. Note that this is the name that was used by the trainer; for a stable identifier, use `sd_checkpoint` instead")
+ shape: int = Field(title="Shape", description="The length of each individual vector in the embedding")
+ vectors: int = Field(title="Vectors", description="The number of vectors in the embedding")
+
+class EmbeddingsResponse(BaseModel):
+ loaded: Dict[str, EmbeddingItem] = Field(title="Loaded", description="Embeddings loaded for the current model")
+ skipped: Dict[str, EmbeddingItem] = Field(title="Skipped", description="Embeddings skipped for the current model (likely due to architecture incompatibility)") \ No newline at end of file
diff --git a/modules/call_queue.py b/modules/call_queue.py
new file mode 100644
index 00000000..4cd49533
--- /dev/null
+++ b/modules/call_queue.py
@@ -0,0 +1,98 @@
+import html
+import sys
+import threading
+import traceback
+import time
+
+from modules import shared
+
+queue_lock = threading.Lock()
+
+
+def wrap_queued_call(func):
+ def f(*args, **kwargs):
+ with queue_lock:
+ res = func(*args, **kwargs)
+
+ return res
+
+ return f
+
+
+def wrap_gradio_gpu_call(func, extra_outputs=None):
+ def f(*args, **kwargs):
+
+ shared.state.begin()
+
+ with queue_lock:
+ res = func(*args, **kwargs)
+
+ shared.state.end()
+
+ return res
+
+ return wrap_gradio_call(f, extra_outputs=extra_outputs, add_stats=True)
+
+
+def wrap_gradio_call(func, extra_outputs=None, add_stats=False):
+ def f(*args, extra_outputs_array=extra_outputs, **kwargs):
+ run_memmon = shared.opts.memmon_poll_rate > 0 and not shared.mem_mon.disabled and add_stats
+ if run_memmon:
+ shared.mem_mon.monitor()
+ t = time.perf_counter()
+
+ try:
+ res = list(func(*args, **kwargs))
+ except Exception as e:
+ # When printing out our debug argument list, do not print out more than a MB of text
+ max_debug_str_len = 131072 # (1024*1024)/8
+
+ print("Error completing request", file=sys.stderr)
+ argStr = f"Arguments: {str(args)} {str(kwargs)}"
+ print(argStr[:max_debug_str_len], file=sys.stderr)
+ if len(argStr) > max_debug_str_len:
+ print(f"(Argument list truncated at {max_debug_str_len}/{len(argStr)} characters)", file=sys.stderr)
+
+ print(traceback.format_exc(), file=sys.stderr)
+
+ shared.state.job = ""
+ shared.state.job_count = 0
+
+ if extra_outputs_array is None:
+ extra_outputs_array = [None, '']
+
+ res = extra_outputs_array + [f"<div class='error'>{html.escape(type(e).__name__+': '+str(e))}</div>"]
+
+ shared.state.skipped = False
+ shared.state.interrupted = False
+ shared.state.job_count = 0
+
+ if not add_stats:
+ return tuple(res)
+
+ elapsed = time.perf_counter() - t
+ elapsed_m = int(elapsed // 60)
+ elapsed_s = elapsed % 60
+ elapsed_text = f"{elapsed_s:.2f}s"
+ if elapsed_m > 0:
+ elapsed_text = f"{elapsed_m}m "+elapsed_text
+
+ if run_memmon:
+ mem_stats = {k: -(v//-(1024*1024)) for k, v in shared.mem_mon.stop().items()}
+ active_peak = mem_stats['active_peak']
+ reserved_peak = mem_stats['reserved_peak']
+ sys_peak = mem_stats['system_peak']
+ sys_total = mem_stats['total']
+ sys_pct = round(sys_peak/max(sys_total, 1) * 100, 2)
+
+ vram_html = f"<p class='vram'>Torch active/reserved: {active_peak}/{reserved_peak} MiB, <wbr>Sys VRAM: {sys_peak}/{sys_total} MiB ({sys_pct}%)</p>"
+ else:
+ vram_html = ''
+
+ # last item is always HTML
+ res[-1] += f"<div class='performance'><p class='time'>Time taken: <wbr>{elapsed_text}</p>{vram_html}</div>"
+
+ return tuple(res)
+
+ return f
+
diff --git a/modules/codeformer/vqgan_arch.py b/modules/codeformer/vqgan_arch.py
index c06c590c..e7293683 100644
--- a/modules/codeformer/vqgan_arch.py
+++ b/modules/codeformer/vqgan_arch.py
@@ -382,7 +382,7 @@ class VQAutoEncoder(nn.Module):
self.load_state_dict(torch.load(model_path, map_location='cpu')['params'])
logger.info(f'vqgan is loaded from: {model_path} [params]')
else:
- raise ValueError(f'Wrong params!')
+ raise ValueError('Wrong params!')
def forward(self, x):
@@ -431,7 +431,7 @@ class VQGANDiscriminator(nn.Module):
elif 'params' in chkpt:
self.load_state_dict(torch.load(model_path, map_location='cpu')['params'])
else:
- raise ValueError(f'Wrong params!')
+ raise ValueError('Wrong params!')
def forward(self, x):
return self.main(x) \ No newline at end of file
diff --git a/modules/codeformer_model.py b/modules/codeformer_model.py
index e6d9fa4f..ab40d842 100644
--- a/modules/codeformer_model.py
+++ b/modules/codeformer_model.py
@@ -36,6 +36,7 @@ def setup_model(dirname):
from basicsr.utils.download_util import load_file_from_url
from basicsr.utils import imwrite, img2tensor, tensor2img
from facelib.utils.face_restoration_helper import FaceRestoreHelper
+ from facelib.detection.retinaface import retinaface
from modules.shared import cmd_opts
net_class = CodeFormer
@@ -65,6 +66,8 @@ def setup_model(dirname):
net.load_state_dict(checkpoint)
net.eval()
+ if hasattr(retinaface, 'device'):
+ retinaface.device = devices.device_codeformer
face_helper = FaceRestoreHelper(1, face_size=512, crop_ratio=(1, 1), det_model='retinaface_resnet50', save_ext='png', use_parse=True, device=devices.device_codeformer)
self.net = net
diff --git a/modules/deepbooru.py b/modules/deepbooru.py
index 8bbc90a4..122fce7f 100644
--- a/modules/deepbooru.py
+++ b/modules/deepbooru.py
@@ -1,173 +1,99 @@
-import os.path
-from concurrent.futures import ProcessPoolExecutor
-import multiprocessing
-import time
+import os
import re
+import torch
+from PIL import Image
+import numpy as np
+
+from modules import modelloader, paths, deepbooru_model, devices, images, shared
+
re_special = re.compile(r'([\\()])')
-def get_deepbooru_tags(pil_image):
- """
- This method is for running only one image at a time for simple use. Used to the img2img interrogate.
- """
- from modules import shared # prevents circular reference
-
- try:
- create_deepbooru_process(shared.opts.interrogate_deepbooru_score_threshold, create_deepbooru_opts())
- return get_tags_from_process(pil_image)
- finally:
- release_process()
-
-
-OPT_INCLUDE_RANKS = "include_ranks"
-def create_deepbooru_opts():
- from modules import shared
-
- return {
- "use_spaces": shared.opts.deepbooru_use_spaces,
- "use_escape": shared.opts.deepbooru_escape,
- "alpha_sort": shared.opts.deepbooru_sort_alpha,
- OPT_INCLUDE_RANKS: shared.opts.interrogate_return_ranks,
- }
-
-
-def deepbooru_process(queue, deepbooru_process_return, threshold, deepbooru_opts):
- model, tags = get_deepbooru_tags_model()
- while True: # while process is running, keep monitoring queue for new image
- pil_image = queue.get()
- if pil_image == "QUIT":
- break
- else:
- deepbooru_process_return["value"] = get_deepbooru_tags_from_model(model, tags, pil_image, threshold, deepbooru_opts)
-
-
-def create_deepbooru_process(threshold, deepbooru_opts):
- """
- Creates deepbooru process. A queue is created to send images into the process. This enables multiple images
- to be processed in a row without reloading the model or creating a new process. To return the data, a shared
- dictionary is created to hold the tags created. To wait for tags to be returned, a value of -1 is assigned
- to the dictionary and the method adding the image to the queue should wait for this value to be updated with
- the tags.
- """
- from modules import shared # prevents circular reference
- context = multiprocessing.get_context("spawn")
- shared.deepbooru_process_manager = context.Manager()
- shared.deepbooru_process_queue = shared.deepbooru_process_manager.Queue()
- shared.deepbooru_process_return = shared.deepbooru_process_manager.dict()
- shared.deepbooru_process_return["value"] = -1
- shared.deepbooru_process = context.Process(target=deepbooru_process, args=(shared.deepbooru_process_queue, shared.deepbooru_process_return, threshold, deepbooru_opts))
- shared.deepbooru_process.start()
-
-
-def get_tags_from_process(image):
- from modules import shared
-
- shared.deepbooru_process_return["value"] = -1
- shared.deepbooru_process_queue.put(image)
- while shared.deepbooru_process_return["value"] == -1:
- time.sleep(0.2)
- caption = shared.deepbooru_process_return["value"]
- shared.deepbooru_process_return["value"] = -1
-
- return caption
-
-
-def release_process():
- """
- Stops the deepbooru process to return used memory
- """
- from modules import shared # prevents circular reference
- shared.deepbooru_process_queue.put("QUIT")
- shared.deepbooru_process.join()
- shared.deepbooru_process_queue = None
- shared.deepbooru_process = None
- shared.deepbooru_process_return = None
- shared.deepbooru_process_manager = None
-
-def get_deepbooru_tags_model():
- import deepdanbooru as dd
- import tensorflow as tf
- import numpy as np
- this_folder = os.path.dirname(__file__)
- model_path = os.path.abspath(os.path.join(this_folder, '..', 'models', 'deepbooru'))
- if not os.path.exists(os.path.join(model_path, 'project.json')):
- # there is no point importing these every time
- import zipfile
- from basicsr.utils.download_util import load_file_from_url
- load_file_from_url(
- r"https://github.com/KichangKim/DeepDanbooru/releases/download/v3-20211112-sgd-e28/deepdanbooru-v3-20211112-sgd-e28.zip",
- model_path)
- with zipfile.ZipFile(os.path.join(model_path, "deepdanbooru-v3-20211112-sgd-e28.zip"), "r") as zip_ref:
- zip_ref.extractall(model_path)
- os.remove(os.path.join(model_path, "deepdanbooru-v3-20211112-sgd-e28.zip"))
-
- tags = dd.project.load_tags_from_project(model_path)
- model = dd.project.load_model_from_project(
- model_path, compile_model=False
- )
- return model, tags
-
-
-def get_deepbooru_tags_from_model(model, tags, pil_image, threshold, deepbooru_opts):
- import deepdanbooru as dd
- import tensorflow as tf
- import numpy as np
-
- alpha_sort = deepbooru_opts['alpha_sort']
- use_spaces = deepbooru_opts['use_spaces']
- use_escape = deepbooru_opts['use_escape']
- include_ranks = deepbooru_opts['include_ranks']
-
- width = model.input_shape[2]
- height = model.input_shape[1]
- image = np.array(pil_image)
- image = tf.image.resize(
- image,
- size=(height, width),
- method=tf.image.ResizeMethod.AREA,
- preserve_aspect_ratio=True,
- )
- image = image.numpy() # EagerTensor to np.array
- image = dd.image.transform_and_pad_image(image, width, height)
- image = image / 255.0
- image_shape = image.shape
- image = image.reshape((1, image_shape[0], image_shape[1], image_shape[2]))
-
- y = model.predict(image)[0]
-
- result_dict = {}
-
- for i, tag in enumerate(tags):
- result_dict[tag] = y[i]
-
- unsorted_tags_in_theshold = []
- result_tags_print = []
- for tag in tags:
- if result_dict[tag] >= threshold:
+
+class DeepDanbooru:
+ def __init__(self):
+ self.model = None
+
+ def load(self):
+ if self.model is not None:
+ return
+
+ files = modelloader.load_models(
+ model_path=os.path.join(paths.models_path, "torch_deepdanbooru"),
+ model_url='https://github.com/AUTOMATIC1111/TorchDeepDanbooru/releases/download/v1/model-resnet_custom_v3.pt',
+ ext_filter=[".pt"],
+ download_name='model-resnet_custom_v3.pt',
+ )
+
+ self.model = deepbooru_model.DeepDanbooruModel()
+ self.model.load_state_dict(torch.load(files[0], map_location="cpu"))
+
+ self.model.eval()
+ self.model.to(devices.cpu, devices.dtype)
+
+ def start(self):
+ self.load()
+ self.model.to(devices.device)
+
+ def stop(self):
+ if not shared.opts.interrogate_keep_models_in_memory:
+ self.model.to(devices.cpu)
+ devices.torch_gc()
+
+ def tag(self, pil_image):
+ self.start()
+ res = self.tag_multi(pil_image)
+ self.stop()
+
+ return res
+
+ def tag_multi(self, pil_image, force_disable_ranks=False):
+ threshold = shared.opts.interrogate_deepbooru_score_threshold
+ use_spaces = shared.opts.deepbooru_use_spaces
+ use_escape = shared.opts.deepbooru_escape
+ alpha_sort = shared.opts.deepbooru_sort_alpha
+ include_ranks = shared.opts.interrogate_return_ranks and not force_disable_ranks
+
+ pic = images.resize_image(2, pil_image.convert("RGB"), 512, 512)
+ a = np.expand_dims(np.array(pic, dtype=np.float32), 0) / 255
+
+ with torch.no_grad(), devices.autocast():
+ x = torch.from_numpy(a).to(devices.device)
+ y = self.model(x)[0].detach().cpu().numpy()
+
+ probability_dict = {}
+
+ for tag, probability in zip(self.model.tags, y):
+ if probability < threshold:
+ continue
+
if tag.startswith("rating:"):
continue
- unsorted_tags_in_theshold.append((result_dict[tag], tag))
- result_tags_print.append(f'{result_dict[tag]} {tag}')
-
- # sort tags
- result_tags_out = []
- sort_ndx = 0
- if alpha_sort:
- sort_ndx = 1
-
- # sort by reverse by likelihood and normal for alpha, and format tag text as requested
- unsorted_tags_in_theshold.sort(key=lambda y: y[sort_ndx], reverse=(not alpha_sort))
- for weight, tag in unsorted_tags_in_theshold:
- tag_outformat = tag
- if use_spaces:
- tag_outformat = tag_outformat.replace('_', ' ')
- if use_escape:
- tag_outformat = re.sub(re_special, r'\\\1', tag_outformat)
- if include_ranks:
- tag_outformat = f"({tag_outformat}:{weight:.3f})"
-
- result_tags_out.append(tag_outformat)
-
- print('\n'.join(sorted(result_tags_print, reverse=True)))
-
- return ', '.join(result_tags_out)
+
+ probability_dict[tag] = probability
+
+ if alpha_sort:
+ tags = sorted(probability_dict)
+ else:
+ tags = [tag for tag, _ in sorted(probability_dict.items(), key=lambda x: -x[1])]
+
+ res = []
+
+ filtertags = set([x.strip().replace(' ', '_') for x in shared.opts.deepbooru_filter_tags.split(",")])
+
+ for tag in [x for x in tags if x not in filtertags]:
+ probability = probability_dict[tag]
+ tag_outformat = tag
+ if use_spaces:
+ tag_outformat = tag_outformat.replace('_', ' ')
+ if use_escape:
+ tag_outformat = re.sub(re_special, r'\\\1', tag_outformat)
+ if include_ranks:
+ tag_outformat = f"({tag_outformat}:{probability:.3f})"
+
+ res.append(tag_outformat)
+
+ return ", ".join(res)
+
+
+model = DeepDanbooru()
diff --git a/modules/deepbooru_model.py b/modules/deepbooru_model.py
new file mode 100644
index 00000000..edd40c81
--- /dev/null
+++ b/modules/deepbooru_model.py
@@ -0,0 +1,676 @@
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+# see https://github.com/AUTOMATIC1111/TorchDeepDanbooru for more
+
+
+class DeepDanbooruModel(nn.Module):
+ def __init__(self):
+ super(DeepDanbooruModel, self).__init__()
+
+ self.tags = []
+
+ self.n_Conv_0 = nn.Conv2d(kernel_size=(7, 7), in_channels=3, out_channels=64, stride=(2, 2))
+ self.n_MaxPool_0 = nn.MaxPool2d(kernel_size=(3, 3), stride=(2, 2))
+ self.n_Conv_1 = nn.Conv2d(kernel_size=(1, 1), in_channels=64, out_channels=256)
+ self.n_Conv_2 = nn.Conv2d(kernel_size=(1, 1), in_channels=64, out_channels=64)
+ self.n_Conv_3 = nn.Conv2d(kernel_size=(3, 3), in_channels=64, out_channels=64)
+ self.n_Conv_4 = nn.Conv2d(kernel_size=(1, 1), in_channels=64, out_channels=256)
+ self.n_Conv_5 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=64)
+ self.n_Conv_6 = nn.Conv2d(kernel_size=(3, 3), in_channels=64, out_channels=64)
+ self.n_Conv_7 = nn.Conv2d(kernel_size=(1, 1), in_channels=64, out_channels=256)
+ self.n_Conv_8 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=64)
+ self.n_Conv_9 = nn.Conv2d(kernel_size=(3, 3), in_channels=64, out_channels=64)
+ self.n_Conv_10 = nn.Conv2d(kernel_size=(1, 1), in_channels=64, out_channels=256)
+ self.n_Conv_11 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=512, stride=(2, 2))
+ self.n_Conv_12 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=128)
+ self.n_Conv_13 = nn.Conv2d(kernel_size=(3, 3), in_channels=128, out_channels=128, stride=(2, 2))
+ self.n_Conv_14 = nn.Conv2d(kernel_size=(1, 1), in_channels=128, out_channels=512)
+ self.n_Conv_15 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=128)
+ self.n_Conv_16 = nn.Conv2d(kernel_size=(3, 3), in_channels=128, out_channels=128)
+ self.n_Conv_17 = nn.Conv2d(kernel_size=(1, 1), in_channels=128, out_channels=512)
+ self.n_Conv_18 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=128)
+ self.n_Conv_19 = nn.Conv2d(kernel_size=(3, 3), in_channels=128, out_channels=128)
+ self.n_Conv_20 = nn.Conv2d(kernel_size=(1, 1), in_channels=128, out_channels=512)
+ self.n_Conv_21 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=128)
+ self.n_Conv_22 = nn.Conv2d(kernel_size=(3, 3), in_channels=128, out_channels=128)
+ self.n_Conv_23 = nn.Conv2d(kernel_size=(1, 1), in_channels=128, out_channels=512)
+ self.n_Conv_24 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=128)
+ self.n_Conv_25 = nn.Conv2d(kernel_size=(3, 3), in_channels=128, out_channels=128)
+ self.n_Conv_26 = nn.Conv2d(kernel_size=(1, 1), in_channels=128, out_channels=512)
+ self.n_Conv_27 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=128)
+ self.n_Conv_28 = nn.Conv2d(kernel_size=(3, 3), in_channels=128, out_channels=128)
+ self.n_Conv_29 = nn.Conv2d(kernel_size=(1, 1), in_channels=128, out_channels=512)
+ self.n_Conv_30 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=128)
+ self.n_Conv_31 = nn.Conv2d(kernel_size=(3, 3), in_channels=128, out_channels=128)
+ self.n_Conv_32 = nn.Conv2d(kernel_size=(1, 1), in_channels=128, out_channels=512)
+ self.n_Conv_33 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=128)
+ self.n_Conv_34 = nn.Conv2d(kernel_size=(3, 3), in_channels=128, out_channels=128)
+ self.n_Conv_35 = nn.Conv2d(kernel_size=(1, 1), in_channels=128, out_channels=512)
+ self.n_Conv_36 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=1024, stride=(2, 2))
+ self.n_Conv_37 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=256)
+ self.n_Conv_38 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256, stride=(2, 2))
+ self.n_Conv_39 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_40 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_41 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_42 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_43 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_44 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_45 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_46 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_47 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_48 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_49 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_50 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_51 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_52 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_53 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_54 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_55 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_56 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_57 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_58 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_59 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_60 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_61 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_62 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_63 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_64 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_65 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_66 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_67 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_68 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_69 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_70 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_71 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_72 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_73 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_74 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_75 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_76 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_77 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_78 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_79 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_80 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_81 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_82 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_83 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_84 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_85 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_86 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_87 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_88 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_89 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_90 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_91 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_92 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_93 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_94 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_95 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_96 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_97 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_98 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256, stride=(2, 2))
+ self.n_Conv_99 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_100 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=1024, stride=(2, 2))
+ self.n_Conv_101 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_102 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_103 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_104 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_105 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_106 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_107 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_108 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_109 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_110 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_111 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_112 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_113 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_114 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_115 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_116 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_117 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_118 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_119 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_120 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_121 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_122 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_123 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_124 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_125 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_126 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_127 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_128 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_129 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_130 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_131 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_132 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_133 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_134 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_135 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_136 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_137 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_138 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_139 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_140 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_141 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_142 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_143 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_144 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_145 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_146 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_147 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_148 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_149 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_150 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_151 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_152 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_153 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_154 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_155 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=256)
+ self.n_Conv_156 = nn.Conv2d(kernel_size=(3, 3), in_channels=256, out_channels=256)
+ self.n_Conv_157 = nn.Conv2d(kernel_size=(1, 1), in_channels=256, out_channels=1024)
+ self.n_Conv_158 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=2048, stride=(2, 2))
+ self.n_Conv_159 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=512)
+ self.n_Conv_160 = nn.Conv2d(kernel_size=(3, 3), in_channels=512, out_channels=512, stride=(2, 2))
+ self.n_Conv_161 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=2048)
+ self.n_Conv_162 = nn.Conv2d(kernel_size=(1, 1), in_channels=2048, out_channels=512)
+ self.n_Conv_163 = nn.Conv2d(kernel_size=(3, 3), in_channels=512, out_channels=512)
+ self.n_Conv_164 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=2048)
+ self.n_Conv_165 = nn.Conv2d(kernel_size=(1, 1), in_channels=2048, out_channels=512)
+ self.n_Conv_166 = nn.Conv2d(kernel_size=(3, 3), in_channels=512, out_channels=512)
+ self.n_Conv_167 = nn.Conv2d(kernel_size=(1, 1), in_channels=512, out_channels=2048)
+ self.n_Conv_168 = nn.Conv2d(kernel_size=(1, 1), in_channels=2048, out_channels=4096, stride=(2, 2))
+ self.n_Conv_169 = nn.Conv2d(kernel_size=(1, 1), in_channels=2048, out_channels=1024)
+ self.n_Conv_170 = nn.Conv2d(kernel_size=(3, 3), in_channels=1024, out_channels=1024, stride=(2, 2))
+ self.n_Conv_171 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=4096)
+ self.n_Conv_172 = nn.Conv2d(kernel_size=(1, 1), in_channels=4096, out_channels=1024)
+ self.n_Conv_173 = nn.Conv2d(kernel_size=(3, 3), in_channels=1024, out_channels=1024)
+ self.n_Conv_174 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=4096)
+ self.n_Conv_175 = nn.Conv2d(kernel_size=(1, 1), in_channels=4096, out_channels=1024)
+ self.n_Conv_176 = nn.Conv2d(kernel_size=(3, 3), in_channels=1024, out_channels=1024)
+ self.n_Conv_177 = nn.Conv2d(kernel_size=(1, 1), in_channels=1024, out_channels=4096)
+ self.n_Conv_178 = nn.Conv2d(kernel_size=(1, 1), in_channels=4096, out_channels=9176, bias=False)
+
+ def forward(self, *inputs):
+ t_358, = inputs
+ t_359 = t_358.permute(*[0, 3, 1, 2])
+ t_359_padded = F.pad(t_359, [2, 3, 2, 3], value=0)
+ t_360 = self.n_Conv_0(t_359_padded)
+ t_361 = F.relu(t_360)
+ t_361 = F.pad(t_361, [0, 1, 0, 1], value=float('-inf'))
+ t_362 = self.n_MaxPool_0(t_361)
+ t_363 = self.n_Conv_1(t_362)
+ t_364 = self.n_Conv_2(t_362)
+ t_365 = F.relu(t_364)
+ t_365_padded = F.pad(t_365, [1, 1, 1, 1], value=0)
+ t_366 = self.n_Conv_3(t_365_padded)
+ t_367 = F.relu(t_366)
+ t_368 = self.n_Conv_4(t_367)
+ t_369 = torch.add(t_368, t_363)
+ t_370 = F.relu(t_369)
+ t_371 = self.n_Conv_5(t_370)
+ t_372 = F.relu(t_371)
+ t_372_padded = F.pad(t_372, [1, 1, 1, 1], value=0)
+ t_373 = self.n_Conv_6(t_372_padded)
+ t_374 = F.relu(t_373)
+ t_375 = self.n_Conv_7(t_374)
+ t_376 = torch.add(t_375, t_370)
+ t_377 = F.relu(t_376)
+ t_378 = self.n_Conv_8(t_377)
+ t_379 = F.relu(t_378)
+ t_379_padded = F.pad(t_379, [1, 1, 1, 1], value=0)
+ t_380 = self.n_Conv_9(t_379_padded)
+ t_381 = F.relu(t_380)
+ t_382 = self.n_Conv_10(t_381)
+ t_383 = torch.add(t_382, t_377)
+ t_384 = F.relu(t_383)
+ t_385 = self.n_Conv_11(t_384)
+ t_386 = self.n_Conv_12(t_384)
+ t_387 = F.relu(t_386)
+ t_387_padded = F.pad(t_387, [0, 1, 0, 1], value=0)
+ t_388 = self.n_Conv_13(t_387_padded)
+ t_389 = F.relu(t_388)
+ t_390 = self.n_Conv_14(t_389)
+ t_391 = torch.add(t_390, t_385)
+ t_392 = F.relu(t_391)
+ t_393 = self.n_Conv_15(t_392)
+ t_394 = F.relu(t_393)
+ t_394_padded = F.pad(t_394, [1, 1, 1, 1], value=0)
+ t_395 = self.n_Conv_16(t_394_padded)
+ t_396 = F.relu(t_395)
+ t_397 = self.n_Conv_17(t_396)
+ t_398 = torch.add(t_397, t_392)
+ t_399 = F.relu(t_398)
+ t_400 = self.n_Conv_18(t_399)
+ t_401 = F.relu(t_400)
+ t_401_padded = F.pad(t_401, [1, 1, 1, 1], value=0)
+ t_402 = self.n_Conv_19(t_401_padded)
+ t_403 = F.relu(t_402)
+ t_404 = self.n_Conv_20(t_403)
+ t_405 = torch.add(t_404, t_399)
+ t_406 = F.relu(t_405)
+ t_407 = self.n_Conv_21(t_406)
+ t_408 = F.relu(t_407)
+ t_408_padded = F.pad(t_408, [1, 1, 1, 1], value=0)
+ t_409 = self.n_Conv_22(t_408_padded)
+ t_410 = F.relu(t_409)
+ t_411 = self.n_Conv_23(t_410)
+ t_412 = torch.add(t_411, t_406)
+ t_413 = F.relu(t_412)
+ t_414 = self.n_Conv_24(t_413)
+ t_415 = F.relu(t_414)
+ t_415_padded = F.pad(t_415, [1, 1, 1, 1], value=0)
+ t_416 = self.n_Conv_25(t_415_padded)
+ t_417 = F.relu(t_416)
+ t_418 = self.n_Conv_26(t_417)
+ t_419 = torch.add(t_418, t_413)
+ t_420 = F.relu(t_419)
+ t_421 = self.n_Conv_27(t_420)
+ t_422 = F.relu(t_421)
+ t_422_padded = F.pad(t_422, [1, 1, 1, 1], value=0)
+ t_423 = self.n_Conv_28(t_422_padded)
+ t_424 = F.relu(t_423)
+ t_425 = self.n_Conv_29(t_424)
+ t_426 = torch.add(t_425, t_420)
+ t_427 = F.relu(t_426)
+ t_428 = self.n_Conv_30(t_427)
+ t_429 = F.relu(t_428)
+ t_429_padded = F.pad(t_429, [1, 1, 1, 1], value=0)
+ t_430 = self.n_Conv_31(t_429_padded)
+ t_431 = F.relu(t_430)
+ t_432 = self.n_Conv_32(t_431)
+ t_433 = torch.add(t_432, t_427)
+ t_434 = F.relu(t_433)
+ t_435 = self.n_Conv_33(t_434)
+ t_436 = F.relu(t_435)
+ t_436_padded = F.pad(t_436, [1, 1, 1, 1], value=0)
+ t_437 = self.n_Conv_34(t_436_padded)
+ t_438 = F.relu(t_437)
+ t_439 = self.n_Conv_35(t_438)
+ t_440 = torch.add(t_439, t_434)
+ t_441 = F.relu(t_440)
+ t_442 = self.n_Conv_36(t_441)
+ t_443 = self.n_Conv_37(t_441)
+ t_444 = F.relu(t_443)
+ t_444_padded = F.pad(t_444, [0, 1, 0, 1], value=0)
+ t_445 = self.n_Conv_38(t_444_padded)
+ t_446 = F.relu(t_445)
+ t_447 = self.n_Conv_39(t_446)
+ t_448 = torch.add(t_447, t_442)
+ t_449 = F.relu(t_448)
+ t_450 = self.n_Conv_40(t_449)
+ t_451 = F.relu(t_450)
+ t_451_padded = F.pad(t_451, [1, 1, 1, 1], value=0)
+ t_452 = self.n_Conv_41(t_451_padded)
+ t_453 = F.relu(t_452)
+ t_454 = self.n_Conv_42(t_453)
+ t_455 = torch.add(t_454, t_449)
+ t_456 = F.relu(t_455)
+ t_457 = self.n_Conv_43(t_456)
+ t_458 = F.relu(t_457)
+ t_458_padded = F.pad(t_458, [1, 1, 1, 1], value=0)
+ t_459 = self.n_Conv_44(t_458_padded)
+ t_460 = F.relu(t_459)
+ t_461 = self.n_Conv_45(t_460)
+ t_462 = torch.add(t_461, t_456)
+ t_463 = F.relu(t_462)
+ t_464 = self.n_Conv_46(t_463)
+ t_465 = F.relu(t_464)
+ t_465_padded = F.pad(t_465, [1, 1, 1, 1], value=0)
+ t_466 = self.n_Conv_47(t_465_padded)
+ t_467 = F.relu(t_466)
+ t_468 = self.n_Conv_48(t_467)
+ t_469 = torch.add(t_468, t_463)
+ t_470 = F.relu(t_469)
+ t_471 = self.n_Conv_49(t_470)
+ t_472 = F.relu(t_471)
+ t_472_padded = F.pad(t_472, [1, 1, 1, 1], value=0)
+ t_473 = self.n_Conv_50(t_472_padded)
+ t_474 = F.relu(t_473)
+ t_475 = self.n_Conv_51(t_474)
+ t_476 = torch.add(t_475, t_470)
+ t_477 = F.relu(t_476)
+ t_478 = self.n_Conv_52(t_477)
+ t_479 = F.relu(t_478)
+ t_479_padded = F.pad(t_479, [1, 1, 1, 1], value=0)
+ t_480 = self.n_Conv_53(t_479_padded)
+ t_481 = F.relu(t_480)
+ t_482 = self.n_Conv_54(t_481)
+ t_483 = torch.add(t_482, t_477)
+ t_484 = F.relu(t_483)
+ t_485 = self.n_Conv_55(t_484)
+ t_486 = F.relu(t_485)
+ t_486_padded = F.pad(t_486, [1, 1, 1, 1], value=0)
+ t_487 = self.n_Conv_56(t_486_padded)
+ t_488 = F.relu(t_487)
+ t_489 = self.n_Conv_57(t_488)
+ t_490 = torch.add(t_489, t_484)
+ t_491 = F.relu(t_490)
+ t_492 = self.n_Conv_58(t_491)
+ t_493 = F.relu(t_492)
+ t_493_padded = F.pad(t_493, [1, 1, 1, 1], value=0)
+ t_494 = self.n_Conv_59(t_493_padded)
+ t_495 = F.relu(t_494)
+ t_496 = self.n_Conv_60(t_495)
+ t_497 = torch.add(t_496, t_491)
+ t_498 = F.relu(t_497)
+ t_499 = self.n_Conv_61(t_498)
+ t_500 = F.relu(t_499)
+ t_500_padded = F.pad(t_500, [1, 1, 1, 1], value=0)
+ t_501 = self.n_Conv_62(t_500_padded)
+ t_502 = F.relu(t_501)
+ t_503 = self.n_Conv_63(t_502)
+ t_504 = torch.add(t_503, t_498)
+ t_505 = F.relu(t_504)
+ t_506 = self.n_Conv_64(t_505)
+ t_507 = F.relu(t_506)
+ t_507_padded = F.pad(t_507, [1, 1, 1, 1], value=0)
+ t_508 = self.n_Conv_65(t_507_padded)
+ t_509 = F.relu(t_508)
+ t_510 = self.n_Conv_66(t_509)
+ t_511 = torch.add(t_510, t_505)
+ t_512 = F.relu(t_511)
+ t_513 = self.n_Conv_67(t_512)
+ t_514 = F.relu(t_513)
+ t_514_padded = F.pad(t_514, [1, 1, 1, 1], value=0)
+ t_515 = self.n_Conv_68(t_514_padded)
+ t_516 = F.relu(t_515)
+ t_517 = self.n_Conv_69(t_516)
+ t_518 = torch.add(t_517, t_512)
+ t_519 = F.relu(t_518)
+ t_520 = self.n_Conv_70(t_519)
+ t_521 = F.relu(t_520)
+ t_521_padded = F.pad(t_521, [1, 1, 1, 1], value=0)
+ t_522 = self.n_Conv_71(t_521_padded)
+ t_523 = F.relu(t_522)
+ t_524 = self.n_Conv_72(t_523)
+ t_525 = torch.add(t_524, t_519)
+ t_526 = F.relu(t_525)
+ t_527 = self.n_Conv_73(t_526)
+ t_528 = F.relu(t_527)
+ t_528_padded = F.pad(t_528, [1, 1, 1, 1], value=0)
+ t_529 = self.n_Conv_74(t_528_padded)
+ t_530 = F.relu(t_529)
+ t_531 = self.n_Conv_75(t_530)
+ t_532 = torch.add(t_531, t_526)
+ t_533 = F.relu(t_532)
+ t_534 = self.n_Conv_76(t_533)
+ t_535 = F.relu(t_534)
+ t_535_padded = F.pad(t_535, [1, 1, 1, 1], value=0)
+ t_536 = self.n_Conv_77(t_535_padded)
+ t_537 = F.relu(t_536)
+ t_538 = self.n_Conv_78(t_537)
+ t_539 = torch.add(t_538, t_533)
+ t_540 = F.relu(t_539)
+ t_541 = self.n_Conv_79(t_540)
+ t_542 = F.relu(t_541)
+ t_542_padded = F.pad(t_542, [1, 1, 1, 1], value=0)
+ t_543 = self.n_Conv_80(t_542_padded)
+ t_544 = F.relu(t_543)
+ t_545 = self.n_Conv_81(t_544)
+ t_546 = torch.add(t_545, t_540)
+ t_547 = F.relu(t_546)
+ t_548 = self.n_Conv_82(t_547)
+ t_549 = F.relu(t_548)
+ t_549_padded = F.pad(t_549, [1, 1, 1, 1], value=0)
+ t_550 = self.n_Conv_83(t_549_padded)
+ t_551 = F.relu(t_550)
+ t_552 = self.n_Conv_84(t_551)
+ t_553 = torch.add(t_552, t_547)
+ t_554 = F.relu(t_553)
+ t_555 = self.n_Conv_85(t_554)
+ t_556 = F.relu(t_555)
+ t_556_padded = F.pad(t_556, [1, 1, 1, 1], value=0)
+ t_557 = self.n_Conv_86(t_556_padded)
+ t_558 = F.relu(t_557)
+ t_559 = self.n_Conv_87(t_558)
+ t_560 = torch.add(t_559, t_554)
+ t_561 = F.relu(t_560)
+ t_562 = self.n_Conv_88(t_561)
+ t_563 = F.relu(t_562)
+ t_563_padded = F.pad(t_563, [1, 1, 1, 1], value=0)
+ t_564 = self.n_Conv_89(t_563_padded)
+ t_565 = F.relu(t_564)
+ t_566 = self.n_Conv_90(t_565)
+ t_567 = torch.add(t_566, t_561)
+ t_568 = F.relu(t_567)
+ t_569 = self.n_Conv_91(t_568)
+ t_570 = F.relu(t_569)
+ t_570_padded = F.pad(t_570, [1, 1, 1, 1], value=0)
+ t_571 = self.n_Conv_92(t_570_padded)
+ t_572 = F.relu(t_571)
+ t_573 = self.n_Conv_93(t_572)
+ t_574 = torch.add(t_573, t_568)
+ t_575 = F.relu(t_574)
+ t_576 = self.n_Conv_94(t_575)
+ t_577 = F.relu(t_576)
+ t_577_padded = F.pad(t_577, [1, 1, 1, 1], value=0)
+ t_578 = self.n_Conv_95(t_577_padded)
+ t_579 = F.relu(t_578)
+ t_580 = self.n_Conv_96(t_579)
+ t_581 = torch.add(t_580, t_575)
+ t_582 = F.relu(t_581)
+ t_583 = self.n_Conv_97(t_582)
+ t_584 = F.relu(t_583)
+ t_584_padded = F.pad(t_584, [0, 1, 0, 1], value=0)
+ t_585 = self.n_Conv_98(t_584_padded)
+ t_586 = F.relu(t_585)
+ t_587 = self.n_Conv_99(t_586)
+ t_588 = self.n_Conv_100(t_582)
+ t_589 = torch.add(t_587, t_588)
+ t_590 = F.relu(t_589)
+ t_591 = self.n_Conv_101(t_590)
+ t_592 = F.relu(t_591)
+ t_592_padded = F.pad(t_592, [1, 1, 1, 1], value=0)
+ t_593 = self.n_Conv_102(t_592_padded)
+ t_594 = F.relu(t_593)
+ t_595 = self.n_Conv_103(t_594)
+ t_596 = torch.add(t_595, t_590)
+ t_597 = F.relu(t_596)
+ t_598 = self.n_Conv_104(t_597)
+ t_599 = F.relu(t_598)
+ t_599_padded = F.pad(t_599, [1, 1, 1, 1], value=0)
+ t_600 = self.n_Conv_105(t_599_padded)
+ t_601 = F.relu(t_600)
+ t_602 = self.n_Conv_106(t_601)
+ t_603 = torch.add(t_602, t_597)
+ t_604 = F.relu(t_603)
+ t_605 = self.n_Conv_107(t_604)
+ t_606 = F.relu(t_605)
+ t_606_padded = F.pad(t_606, [1, 1, 1, 1], value=0)
+ t_607 = self.n_Conv_108(t_606_padded)
+ t_608 = F.relu(t_607)
+ t_609 = self.n_Conv_109(t_608)
+ t_610 = torch.add(t_609, t_604)
+ t_611 = F.relu(t_610)
+ t_612 = self.n_Conv_110(t_611)
+ t_613 = F.relu(t_612)
+ t_613_padded = F.pad(t_613, [1, 1, 1, 1], value=0)
+ t_614 = self.n_Conv_111(t_613_padded)
+ t_615 = F.relu(t_614)
+ t_616 = self.n_Conv_112(t_615)
+ t_617 = torch.add(t_616, t_611)
+ t_618 = F.relu(t_617)
+ t_619 = self.n_Conv_113(t_618)
+ t_620 = F.relu(t_619)
+ t_620_padded = F.pad(t_620, [1, 1, 1, 1], value=0)
+ t_621 = self.n_Conv_114(t_620_padded)
+ t_622 = F.relu(t_621)
+ t_623 = self.n_Conv_115(t_622)
+ t_624 = torch.add(t_623, t_618)
+ t_625 = F.relu(t_624)
+ t_626 = self.n_Conv_116(t_625)
+ t_627 = F.relu(t_626)
+ t_627_padded = F.pad(t_627, [1, 1, 1, 1], value=0)
+ t_628 = self.n_Conv_117(t_627_padded)
+ t_629 = F.relu(t_628)
+ t_630 = self.n_Conv_118(t_629)
+ t_631 = torch.add(t_630, t_625)
+ t_632 = F.relu(t_631)
+ t_633 = self.n_Conv_119(t_632)
+ t_634 = F.relu(t_633)
+ t_634_padded = F.pad(t_634, [1, 1, 1, 1], value=0)
+ t_635 = self.n_Conv_120(t_634_padded)
+ t_636 = F.relu(t_635)
+ t_637 = self.n_Conv_121(t_636)
+ t_638 = torch.add(t_637, t_632)
+ t_639 = F.relu(t_638)
+ t_640 = self.n_Conv_122(t_639)
+ t_641 = F.relu(t_640)
+ t_641_padded = F.pad(t_641, [1, 1, 1, 1], value=0)
+ t_642 = self.n_Conv_123(t_641_padded)
+ t_643 = F.relu(t_642)
+ t_644 = self.n_Conv_124(t_643)
+ t_645 = torch.add(t_644, t_639)
+ t_646 = F.relu(t_645)
+ t_647 = self.n_Conv_125(t_646)
+ t_648 = F.relu(t_647)
+ t_648_padded = F.pad(t_648, [1, 1, 1, 1], value=0)
+ t_649 = self.n_Conv_126(t_648_padded)
+ t_650 = F.relu(t_649)
+ t_651 = self.n_Conv_127(t_650)
+ t_652 = torch.add(t_651, t_646)
+ t_653 = F.relu(t_652)
+ t_654 = self.n_Conv_128(t_653)
+ t_655 = F.relu(t_654)
+ t_655_padded = F.pad(t_655, [1, 1, 1, 1], value=0)
+ t_656 = self.n_Conv_129(t_655_padded)
+ t_657 = F.relu(t_656)
+ t_658 = self.n_Conv_130(t_657)
+ t_659 = torch.add(t_658, t_653)
+ t_660 = F.relu(t_659)
+ t_661 = self.n_Conv_131(t_660)
+ t_662 = F.relu(t_661)
+ t_662_padded = F.pad(t_662, [1, 1, 1, 1], value=0)
+ t_663 = self.n_Conv_132(t_662_padded)
+ t_664 = F.relu(t_663)
+ t_665 = self.n_Conv_133(t_664)
+ t_666 = torch.add(t_665, t_660)
+ t_667 = F.relu(t_666)
+ t_668 = self.n_Conv_134(t_667)
+ t_669 = F.relu(t_668)
+ t_669_padded = F.pad(t_669, [1, 1, 1, 1], value=0)
+ t_670 = self.n_Conv_135(t_669_padded)
+ t_671 = F.relu(t_670)
+ t_672 = self.n_Conv_136(t_671)
+ t_673 = torch.add(t_672, t_667)
+ t_674 = F.relu(t_673)
+ t_675 = self.n_Conv_137(t_674)
+ t_676 = F.relu(t_675)
+ t_676_padded = F.pad(t_676, [1, 1, 1, 1], value=0)
+ t_677 = self.n_Conv_138(t_676_padded)
+ t_678 = F.relu(t_677)
+ t_679 = self.n_Conv_139(t_678)
+ t_680 = torch.add(t_679, t_674)
+ t_681 = F.relu(t_680)
+ t_682 = self.n_Conv_140(t_681)
+ t_683 = F.relu(t_682)
+ t_683_padded = F.pad(t_683, [1, 1, 1, 1], value=0)
+ t_684 = self.n_Conv_141(t_683_padded)
+ t_685 = F.relu(t_684)
+ t_686 = self.n_Conv_142(t_685)
+ t_687 = torch.add(t_686, t_681)
+ t_688 = F.relu(t_687)
+ t_689 = self.n_Conv_143(t_688)
+ t_690 = F.relu(t_689)
+ t_690_padded = F.pad(t_690, [1, 1, 1, 1], value=0)
+ t_691 = self.n_Conv_144(t_690_padded)
+ t_692 = F.relu(t_691)
+ t_693 = self.n_Conv_145(t_692)
+ t_694 = torch.add(t_693, t_688)
+ t_695 = F.relu(t_694)
+ t_696 = self.n_Conv_146(t_695)
+ t_697 = F.relu(t_696)
+ t_697_padded = F.pad(t_697, [1, 1, 1, 1], value=0)
+ t_698 = self.n_Conv_147(t_697_padded)
+ t_699 = F.relu(t_698)
+ t_700 = self.n_Conv_148(t_699)
+ t_701 = torch.add(t_700, t_695)
+ t_702 = F.relu(t_701)
+ t_703 = self.n_Conv_149(t_702)
+ t_704 = F.relu(t_703)
+ t_704_padded = F.pad(t_704, [1, 1, 1, 1], value=0)
+ t_705 = self.n_Conv_150(t_704_padded)
+ t_706 = F.relu(t_705)
+ t_707 = self.n_Conv_151(t_706)
+ t_708 = torch.add(t_707, t_702)
+ t_709 = F.relu(t_708)
+ t_710 = self.n_Conv_152(t_709)
+ t_711 = F.relu(t_710)
+ t_711_padded = F.pad(t_711, [1, 1, 1, 1], value=0)
+ t_712 = self.n_Conv_153(t_711_padded)
+ t_713 = F.relu(t_712)
+ t_714 = self.n_Conv_154(t_713)
+ t_715 = torch.add(t_714, t_709)
+ t_716 = F.relu(t_715)
+ t_717 = self.n_Conv_155(t_716)
+ t_718 = F.relu(t_717)
+ t_718_padded = F.pad(t_718, [1, 1, 1, 1], value=0)
+ t_719 = self.n_Conv_156(t_718_padded)
+ t_720 = F.relu(t_719)
+ t_721 = self.n_Conv_157(t_720)
+ t_722 = torch.add(t_721, t_716)
+ t_723 = F.relu(t_722)
+ t_724 = self.n_Conv_158(t_723)
+ t_725 = self.n_Conv_159(t_723)
+ t_726 = F.relu(t_725)
+ t_726_padded = F.pad(t_726, [0, 1, 0, 1], value=0)
+ t_727 = self.n_Conv_160(t_726_padded)
+ t_728 = F.relu(t_727)
+ t_729 = self.n_Conv_161(t_728)
+ t_730 = torch.add(t_729, t_724)
+ t_731 = F.relu(t_730)
+ t_732 = self.n_Conv_162(t_731)
+ t_733 = F.relu(t_732)
+ t_733_padded = F.pad(t_733, [1, 1, 1, 1], value=0)
+ t_734 = self.n_Conv_163(t_733_padded)
+ t_735 = F.relu(t_734)
+ t_736 = self.n_Conv_164(t_735)
+ t_737 = torch.add(t_736, t_731)
+ t_738 = F.relu(t_737)
+ t_739 = self.n_Conv_165(t_738)
+ t_740 = F.relu(t_739)
+ t_740_padded = F.pad(t_740, [1, 1, 1, 1], value=0)
+ t_741 = self.n_Conv_166(t_740_padded)
+ t_742 = F.relu(t_741)
+ t_743 = self.n_Conv_167(t_742)
+ t_744 = torch.add(t_743, t_738)
+ t_745 = F.relu(t_744)
+ t_746 = self.n_Conv_168(t_745)
+ t_747 = self.n_Conv_169(t_745)
+ t_748 = F.relu(t_747)
+ t_748_padded = F.pad(t_748, [0, 1, 0, 1], value=0)
+ t_749 = self.n_Conv_170(t_748_padded)
+ t_750 = F.relu(t_749)
+ t_751 = self.n_Conv_171(t_750)
+ t_752 = torch.add(t_751, t_746)
+ t_753 = F.relu(t_752)
+ t_754 = self.n_Conv_172(t_753)
+ t_755 = F.relu(t_754)
+ t_755_padded = F.pad(t_755, [1, 1, 1, 1], value=0)
+ t_756 = self.n_Conv_173(t_755_padded)
+ t_757 = F.relu(t_756)
+ t_758 = self.n_Conv_174(t_757)
+ t_759 = torch.add(t_758, t_753)
+ t_760 = F.relu(t_759)
+ t_761 = self.n_Conv_175(t_760)
+ t_762 = F.relu(t_761)
+ t_762_padded = F.pad(t_762, [1, 1, 1, 1], value=0)
+ t_763 = self.n_Conv_176(t_762_padded)
+ t_764 = F.relu(t_763)
+ t_765 = self.n_Conv_177(t_764)
+ t_766 = torch.add(t_765, t_760)
+ t_767 = F.relu(t_766)
+ t_768 = self.n_Conv_178(t_767)
+ t_769 = F.avg_pool2d(t_768, kernel_size=t_768.shape[-2:])
+ t_770 = torch.squeeze(t_769, 3)
+ t_770 = torch.squeeze(t_770, 2)
+ t_771 = torch.sigmoid(t_770)
+ return t_771
+
+ def load_state_dict(self, state_dict, **kwargs):
+ self.tags = state_dict.get('tags', [])
+
+ super(DeepDanbooruModel, self).load_state_dict({k: v for k, v in state_dict.items() if k != 'tags'})
+
diff --git a/modules/devices.py b/modules/devices.py
index 7511e1dc..800510b7 100644
--- a/modules/devices.py
+++ b/modules/devices.py
@@ -2,72 +2,95 @@ import sys, os, shlex
import contextlib
import torch
from modules import errors
+from packaging import version
-# has_mps is only available in nightly pytorch (for now), `getattr` for compatibility
-has_mps = getattr(torch, 'has_mps', False)
-cpu = torch.device("cpu")
+# has_mps is only available in nightly pytorch (for now) and macOS 12.3+.
+# check `getattr` and try it for compatibility
+def has_mps() -> bool:
+ if not getattr(torch, 'has_mps', False):
+ return False
+ try:
+ torch.zeros(1).to(torch.device("mps"))
+ return True
+ except Exception:
+ return False
+
def extract_device_id(args, name):
for x in range(len(args)):
- if name in args[x]: return args[x+1]
+ if name in args[x]:
+ return args[x + 1]
+
return None
-def get_optimal_device():
- if torch.cuda.is_available():
- from modules import shared
- device_id = shared.cmd_opts.device_id
+def get_cuda_device_string():
+ from modules import shared
+
+ if shared.cmd_opts.device_id is not None:
+ return f"cuda:{shared.cmd_opts.device_id}"
- if device_id is not None:
- cuda_device = f"cuda:{device_id}"
- return torch.device(cuda_device)
- else:
- return torch.device("cuda")
+ return "cuda"
- if has_mps:
+
+def get_optimal_device():
+ if torch.cuda.is_available():
+ return torch.device(get_cuda_device_string())
+
+ if has_mps():
return torch.device("mps")
return cpu
+def get_device_for(task):
+ from modules import shared
+
+ if task in shared.cmd_opts.use_cpu:
+ return cpu
+
+ return get_optimal_device()
+
+
def torch_gc():
if torch.cuda.is_available():
- torch.cuda.empty_cache()
- torch.cuda.ipc_collect()
+ with torch.cuda.device(get_cuda_device_string()):
+ torch.cuda.empty_cache()
+ torch.cuda.ipc_collect()
def enable_tf32():
if torch.cuda.is_available():
+
+ # enabling benchmark option seems to enable a range of cards to do fp16 when they otherwise can't
+ # see https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/4407
+ if any([torch.cuda.get_device_capability(devid) == (7, 5) for devid in range(0, torch.cuda.device_count())]):
+ torch.backends.cudnn.benchmark = True
+
torch.backends.cuda.matmul.allow_tf32 = True
torch.backends.cudnn.allow_tf32 = True
+
errors.run(enable_tf32, "Enabling TF32")
-device = device_interrogate = device_gfpgan = device_swinir = device_esrgan = device_scunet = device_codeformer = None
+cpu = torch.device("cpu")
+device = device_interrogate = device_gfpgan = device_esrgan = device_codeformer = None
dtype = torch.float16
dtype_vae = torch.float16
-def randn(seed, shape):
- # Pytorch currently doesn't handle setting randomness correctly when the metal backend is used.
- if device.type == 'mps':
- generator = torch.Generator(device=cpu)
- generator.manual_seed(seed)
- noise = torch.randn(shape, generator=generator, device=cpu).to(device)
- return noise
+def randn(seed, shape):
torch.manual_seed(seed)
+ if device.type == 'mps':
+ return torch.randn(shape, device=cpu).to(device)
return torch.randn(shape, device=device)
def randn_without_seed(shape):
- # Pytorch currently doesn't handle setting randomness correctly when the metal backend is used.
if device.type == 'mps':
- generator = torch.Generator(device=cpu)
- noise = torch.randn(shape, generator=generator, device=cpu).to(device)
- return noise
-
+ return torch.randn(shape, device=cpu).to(device)
return torch.randn(shape, device=device)
@@ -82,6 +105,36 @@ def autocast(disable=False):
return torch.autocast("cuda")
+
# MPS workaround for https://github.com/pytorch/pytorch/issues/79383
-def mps_contiguous(input_tensor, device): return input_tensor.contiguous() if device.type == 'mps' else input_tensor
-def mps_contiguous_to(input_tensor, device): return mps_contiguous(input_tensor, device).to(device)
+orig_tensor_to = torch.Tensor.to
+def tensor_to_fix(self, *args, **kwargs):
+ if self.device.type != 'mps' and \
+ ((len(args) > 0 and isinstance(args[0], torch.device) and args[0].type == 'mps') or \
+ (isinstance(kwargs.get('device'), torch.device) and kwargs['device'].type == 'mps')):
+ self = self.contiguous()
+ return orig_tensor_to(self, *args, **kwargs)
+
+
+# MPS workaround for https://github.com/pytorch/pytorch/issues/80800
+orig_layer_norm = torch.nn.functional.layer_norm
+def layer_norm_fix(*args, **kwargs):
+ if len(args) > 0 and isinstance(args[0], torch.Tensor) and args[0].device.type == 'mps':
+ args = list(args)
+ args[0] = args[0].contiguous()
+ return orig_layer_norm(*args, **kwargs)
+
+
+# MPS workaround for https://github.com/pytorch/pytorch/issues/90532
+orig_tensor_numpy = torch.Tensor.numpy
+def numpy_fix(self, *args, **kwargs):
+ if self.requires_grad:
+ self = self.detach()
+ return orig_tensor_numpy(self, *args, **kwargs)
+
+
+# PyTorch 1.13 doesn't need these fixes but unfortunately is slower and has regressions that prevent training from working
+if has_mps() and version.parse(torch.__version__) < version.parse("1.13"):
+ torch.Tensor.to = tensor_to_fix
+ torch.nn.functional.layer_norm = layer_norm_fix
+ torch.Tensor.numpy = numpy_fix
diff --git a/modules/errors.py b/modules/errors.py
index 372dc51a..a668c014 100644
--- a/modules/errors.py
+++ b/modules/errors.py
@@ -2,9 +2,30 @@ import sys
import traceback
+def print_error_explanation(message):
+ lines = message.strip().split("\n")
+ max_len = max([len(x) for x in lines])
+
+ print('=' * max_len, file=sys.stderr)
+ for line in lines:
+ print(line, file=sys.stderr)
+ print('=' * max_len, file=sys.stderr)
+
+
+def display(e: Exception, task):
+ print(f"{task or 'error'}: {type(e).__name__}", file=sys.stderr)
+ print(traceback.format_exc(), file=sys.stderr)
+
+ message = str(e)
+ if "copying a param with shape torch.Size([640, 1024]) from checkpoint, the shape in current model is torch.Size([640, 768])" in message:
+ print_error_explanation("""
+The most likely cause of this is you are trying to load Stable Diffusion 2.0 model without specifying its connfig file.
+See https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Features#stable-diffusion-20 for how to solve this.
+ """)
+
+
def run(code, task):
try:
code()
except Exception as e:
- print(f"{task}: {type(e).__name__}", file=sys.stderr)
- print(traceback.format_exc(), file=sys.stderr)
+ display(task, e)
diff --git a/modules/esrgan_model.py b/modules/esrgan_model.py
index a13cf6ac..9a9c38f1 100644
--- a/modules/esrgan_model.py
+++ b/modules/esrgan_model.py
@@ -50,6 +50,7 @@ def mod2normal(state_dict):
def resrgan2normal(state_dict, nb=23):
# this code is copied from https://github.com/victorca25/iNNfer
if "conv_first.weight" in state_dict and "body.0.rdb1.conv1.weight" in state_dict:
+ re8x = 0
crt_net = {}
items = []
for k, v in state_dict.items():
@@ -75,10 +76,18 @@ def resrgan2normal(state_dict, nb=23):
crt_net['model.3.bias'] = state_dict['conv_up1.bias']
crt_net['model.6.weight'] = state_dict['conv_up2.weight']
crt_net['model.6.bias'] = state_dict['conv_up2.bias']
- crt_net['model.8.weight'] = state_dict['conv_hr.weight']
- crt_net['model.8.bias'] = state_dict['conv_hr.bias']
- crt_net['model.10.weight'] = state_dict['conv_last.weight']
- crt_net['model.10.bias'] = state_dict['conv_last.bias']
+
+ if 'conv_up3.weight' in state_dict:
+ # modification supporting: https://github.com/ai-forever/Real-ESRGAN/blob/main/RealESRGAN/rrdbnet_arch.py
+ re8x = 3
+ crt_net['model.9.weight'] = state_dict['conv_up3.weight']
+ crt_net['model.9.bias'] = state_dict['conv_up3.bias']
+
+ crt_net[f'model.{8+re8x}.weight'] = state_dict['conv_hr.weight']
+ crt_net[f'model.{8+re8x}.bias'] = state_dict['conv_hr.bias']
+ crt_net[f'model.{10+re8x}.weight'] = state_dict['conv_last.weight']
+ crt_net[f'model.{10+re8x}.bias'] = state_dict['conv_last.bias']
+
state_dict = crt_net
return state_dict
@@ -190,7 +199,7 @@ def upscale_without_tiling(model, img):
img = img[:, :, ::-1]
img = np.ascontiguousarray(np.transpose(img, (2, 0, 1))) / 255
img = torch.from_numpy(img).float()
- img = devices.mps_contiguous_to(img.unsqueeze(0), devices.device_esrgan)
+ img = img.unsqueeze(0).to(devices.device_esrgan)
with torch.no_grad():
output = model(img)
output = output.squeeze().float().cpu().clamp_(0, 1).numpy()
diff --git a/modules/extensions.py b/modules/extensions.py
index 897af96e..b522125c 100644
--- a/modules/extensions.py
+++ b/modules/extensions.py
@@ -6,9 +6,9 @@ import git
from modules import paths, shared
-
extensions = []
extensions_dir = os.path.join(paths.script_path, "extensions")
+extensions_builtin_dir = os.path.join(paths.script_path, "extensions-builtin")
def active():
@@ -16,12 +16,13 @@ def active():
class Extension:
- def __init__(self, name, path, enabled=True):
+ def __init__(self, name, path, enabled=True, is_builtin=False):
self.name = name
self.path = path
self.enabled = enabled
self.status = ''
self.can_update = False
+ self.is_builtin = is_builtin
repo = None
try:
@@ -34,8 +35,11 @@ class Extension:
if repo is None or repo.bare:
self.remote = None
else:
- self.remote = next(repo.remote().urls, None)
- self.status = 'unknown'
+ try:
+ self.remote = next(repo.remote().urls, None)
+ self.status = 'unknown'
+ except Exception:
+ self.remote = None
def list_files(self, subdir, extension):
from modules import scripts
@@ -63,9 +67,12 @@ class Extension:
self.can_update = False
self.status = "latest"
- def pull(self):
+ def fetch_and_reset_hard(self):
repo = git.Repo(self.path)
- repo.remotes.origin.pull()
+ # Fix: `error: Your local changes to the following files would be overwritten by merge`,
+ # because WSL2 Docker set 755 file permissions instead of 644, this results to the error.
+ repo.git.fetch('--all')
+ repo.git.reset('--hard', 'origin')
def list_extensions():
@@ -74,10 +81,19 @@ def list_extensions():
if not os.path.isdir(extensions_dir):
return
- for dirname in sorted(os.listdir(extensions_dir)):
- path = os.path.join(extensions_dir, dirname)
- if not os.path.isdir(path):
- continue
+ paths = []
+ for dirname in [extensions_dir, extensions_builtin_dir]:
+ if not os.path.isdir(dirname):
+ return
+
+ for extension_dirname in sorted(os.listdir(dirname)):
+ path = os.path.join(dirname, extension_dirname)
+ if not os.path.isdir(path):
+ continue
- extension = Extension(name=dirname, path=path, enabled=dirname not in shared.opts.disabled_extensions)
+ paths.append((extension_dirname, path, dirname == extensions_builtin_dir))
+
+ for dirname, path, is_builtin in paths:
+ extension = Extension(name=dirname, path=path, enabled=dirname not in shared.opts.disabled_extensions, is_builtin=is_builtin)
extensions.append(extension)
+
diff --git a/modules/extras.py b/modules/extras.py
index 8e2ab35c..d665440a 100644
--- a/modules/extras.py
+++ b/modules/extras.py
@@ -1,6 +1,8 @@
from __future__ import annotations
import math
import os
+import sys
+import traceback
import numpy as np
from PIL import Image
@@ -12,7 +14,7 @@ from typing import Callable, List, OrderedDict, Tuple
from functools import partial
from dataclasses import dataclass
-from modules import processing, shared, images, devices, sd_models
+from modules import processing, shared, images, devices, sd_models, sd_samplers
from modules.shared import opts
import modules.gfpgan_model
from modules.ui import plaintext_to_html
@@ -20,7 +22,7 @@ import modules.codeformer_model
import piexif
import piexif.helper
import gradio as gr
-
+import safetensors.torch
class LruCache(OrderedDict):
@dataclass(frozen=True)
@@ -53,14 +55,17 @@ class LruCache(OrderedDict):
cached_images: LruCache = LruCache(max_size=5)
-def run_extras(extras_mode, resize_mode, image, image_folder, input_dir, output_dir, show_extras_results, gfpgan_visibility, codeformer_visibility, codeformer_weight, upscaling_resize, upscaling_resize_w, upscaling_resize_h, upscaling_crop, extras_upscaler_1, extras_upscaler_2, extras_upscaler_2_visibility, upscale_first: bool):
+def run_extras(extras_mode, resize_mode, image, image_folder, input_dir, output_dir, show_extras_results, gfpgan_visibility, codeformer_visibility, codeformer_weight, upscaling_resize, upscaling_resize_w, upscaling_resize_h, upscaling_crop, extras_upscaler_1, extras_upscaler_2, extras_upscaler_2_visibility, upscale_first: bool, save_output: bool = True):
devices.torch_gc()
+ shared.state.begin()
+ shared.state.job = 'extras'
+
imageArr = []
# Also keep track of original file names
imageNameArr = []
outputs = []
-
+
if extras_mode == 1:
#convert file to pillow image
for img in image_folder:
@@ -92,6 +97,7 @@ def run_extras(extras_mode, resize_mode, image, image_folder, input_dir, output_
# Extra operation definitions
def run_gfpgan(image: Image.Image, info: str) -> Tuple[Image.Image, str]:
+ shared.state.job = 'extras-gfpgan'
restored_img = modules.gfpgan_model.gfpgan_fix_faces(np.array(image, dtype=np.uint8))
res = Image.fromarray(restored_img)
@@ -102,6 +108,7 @@ def run_extras(extras_mode, resize_mode, image, image_folder, input_dir, output_
return (res, info)
def run_codeformer(image: Image.Image, info: str) -> Tuple[Image.Image, str]:
+ shared.state.job = 'extras-codeformer'
restored_img = modules.codeformer_model.codeformer.restore(np.array(image, dtype=np.uint8), w=codeformer_weight)
res = Image.fromarray(restored_img)
@@ -112,6 +119,7 @@ def run_extras(extras_mode, resize_mode, image, image_folder, input_dir, output_
return (res, info)
def upscale(image, scaler_index, resize, mode, resize_w, resize_h, crop):
+ shared.state.job = 'extras-upscale'
upscaler = shared.sd_upscalers[scaler_index]
res = upscaler.scaler.upscale(image, resize, upscaler.data_path)
if mode == 1 and crop:
@@ -136,12 +144,13 @@ def run_extras(extras_mode, resize_mode, image, image_folder, input_dir, output_
def run_upscalers_blend(params: List[UpscaleParams], image: Image.Image, info: str) -> Tuple[Image.Image, str]:
blended_result: Image.Image = None
+ image_hash: str = hash(np.array(image.getdata()).tobytes())
for upscaler in params:
upscale_args = (upscaler.upscaler_idx, upscaling_resize, resize_mode,
upscaling_resize_w, upscaling_resize_h, upscaling_crop)
- cache_key = LruCache.Key(image_hash=hash(np.array(image.getdata()).tobytes()),
+ cache_key = LruCache.Key(image_hash=image_hash,
info_hash=hash(info),
- args_hash=hash((upscale_args, upscale_first)))
+ args_hash=hash(upscale_args))
cached_entry = cached_images.get(cache_key)
if cached_entry is None:
res = upscale(image, *upscale_args)
@@ -177,6 +186,9 @@ def run_extras(extras_mode, resize_mode, image, image_folder, input_dir, output_
for image, image_name in zip(imageArr, imageNameArr):
if image is None:
return outputs, "Please select an input image.", ''
+
+ shared.state.textinfo = f'Processing image {image_name}'
+
existing_pnginfo = image.info or {}
image = image.convert("RGB")
@@ -185,18 +197,25 @@ def run_extras(extras_mode, resize_mode, image, image_folder, input_dir, output_
for op in extras_ops:
image, info = op(image, info)
- if opts.use_original_name_batch and image_name != None:
+ if opts.use_original_name_batch and image_name is not None:
basename = os.path.splitext(os.path.basename(image_name))[0]
else:
basename = ''
- images.save_image(image, path=outpath, basename=basename, seed=None, prompt=None, extension=opts.samples_format, info=info, short_filename=True,
- no_prompt=True, grid=False, pnginfo_section_name="extras", existing_info=existing_pnginfo, forced_filename=None)
-
- if opts.enable_pnginfo:
+ if opts.enable_pnginfo: # append info before save
image.info = existing_pnginfo
image.info["extras"] = info
+ if save_output:
+ # Add upscaler name as a suffix.
+ suffix = f"-{shared.sd_upscalers[extras_upscaler_1].name}" if shared.opts.use_upscaler_name_as_suffix else ""
+ # Add second upscaler if applicable.
+ if suffix and extras_upscaler_2 and extras_upscaler_2_visibility:
+ suffix += f"-{shared.sd_upscalers[extras_upscaler_2].name}"
+
+ images.save_image(image, path=outpath, basename=basename, seed=None, prompt=None, extension=opts.samples_format, info=info, short_filename=True,
+ no_prompt=True, grid=False, pnginfo_section_name="extras", existing_info=existing_pnginfo, forced_filename=None, suffix=suffix)
+
if extras_mode != 2 or show_extras_results :
outputs.append(image)
@@ -212,25 +231,8 @@ def run_pnginfo(image):
if image is None:
return '', '', ''
- items = image.info
- geninfo = ''
-
- if "exif" in image.info:
- exif = piexif.load(image.info["exif"])
- exif_comment = (exif or {}).get("Exif", {}).get(piexif.ExifIFD.UserComment, b'')
- try:
- exif_comment = piexif.helper.UserComment.load(exif_comment)
- except ValueError:
- exif_comment = exif_comment.decode('utf8', errors="ignore")
-
- items['exif comment'] = exif_comment
- geninfo = exif_comment
-
- for field in ['jfif', 'jfif_version', 'jfif_unit', 'jfif_density', 'dpi', 'exif',
- 'loop', 'background', 'timestamp', 'duration']:
- items.pop(field, None)
-
- geninfo = items.get('parameters', geninfo)
+ geninfo, items = images.read_info_from_image(image)
+ items = {**{'parameters': geninfo}, **items}
info = ''
for key, text in items.items():
@@ -248,7 +250,10 @@ def run_pnginfo(image):
return '', geninfo, info
-def run_modelmerger(primary_model_name, secondary_model_name, teritary_model_name, interp_method, multiplier, save_as_half, custom_name):
+def run_modelmerger(primary_model_name, secondary_model_name, tertiary_model_name, interp_method, multiplier, save_as_half, custom_name, checkpoint_format):
+ shared.state.begin()
+ shared.state.job = 'model-merge'
+
def weighted_sum(theta0, theta1, alpha):
return ((1 - alpha) * theta0) + (alpha * theta1)
@@ -260,23 +265,8 @@ def run_modelmerger(primary_model_name, secondary_model_name, teritary_model_nam
primary_model_info = sd_models.checkpoints_list[primary_model_name]
secondary_model_info = sd_models.checkpoints_list[secondary_model_name]
- teritary_model_info = sd_models.checkpoints_list.get(teritary_model_name, None)
-
- print(f"Loading {primary_model_info.filename}...")
- primary_model = torch.load(primary_model_info.filename, map_location='cpu')
- theta_0 = sd_models.get_state_dict_from_checkpoint(primary_model)
-
- print(f"Loading {secondary_model_info.filename}...")
- secondary_model = torch.load(secondary_model_info.filename, map_location='cpu')
- theta_1 = sd_models.get_state_dict_from_checkpoint(secondary_model)
-
- if teritary_model_info is not None:
- print(f"Loading {teritary_model_info.filename}...")
- teritary_model = torch.load(teritary_model_info.filename, map_location='cpu')
- theta_2 = sd_models.get_state_dict_from_checkpoint(teritary_model)
- else:
- teritary_model = None
- theta_2 = None
+ tertiary_model_info = sd_models.checkpoints_list.get(tertiary_model_name, None)
+ result_is_inpainting_model = False
theta_funcs = {
"Weighted sum": (None, weighted_sum),
@@ -284,9 +274,19 @@ def run_modelmerger(primary_model_name, secondary_model_name, teritary_model_nam
}
theta_func1, theta_func2 = theta_funcs[interp_method]
- print(f"Merging...")
+ if theta_func1 and not tertiary_model_info:
+ shared.state.textinfo = "Failed: Interpolation method requires a tertiary model."
+ shared.state.end()
+ return ["Failed: Interpolation method requires a tertiary model."] + [gr.Dropdown.update(choices=sd_models.checkpoint_tiles()) for _ in range(4)]
+
+ shared.state.textinfo = f"Loading {secondary_model_info.filename}..."
+ print(f"Loading {secondary_model_info.filename}...")
+ theta_1 = sd_models.read_state_dict(secondary_model_info.filename, map_location='cpu')
if theta_func1:
+ print(f"Loading {tertiary_model_info.filename}...")
+ theta_2 = sd_models.read_state_dict(tertiary_model_info.filename, map_location='cpu')
+
for key in tqdm.tqdm(theta_1.keys()):
if 'model' in key:
if key in theta_2:
@@ -294,12 +294,33 @@ def run_modelmerger(primary_model_name, secondary_model_name, teritary_model_nam
theta_1[key] = theta_func1(theta_1[key], t2)
else:
theta_1[key] = torch.zeros_like(theta_1[key])
- del theta_2, teritary_model
+ del theta_2
+
+ shared.state.textinfo = f"Loading {primary_model_info.filename}..."
+ print(f"Loading {primary_model_info.filename}...")
+ theta_0 = sd_models.read_state_dict(primary_model_info.filename, map_location='cpu')
+
+ print("Merging...")
for key in tqdm.tqdm(theta_0.keys()):
if 'model' in key and key in theta_1:
+ a = theta_0[key]
+ b = theta_1[key]
- theta_0[key] = theta_func2(theta_0[key], theta_1[key], multiplier)
+ shared.state.textinfo = f'Merging layer {key}'
+ # this enables merging an inpainting model (A) with another one (B);
+ # where normal model would have 4 channels, for latenst space, inpainting model would
+ # have another 4 channels for unmasked picture's latent space, plus one channel for mask, for a total of 9
+ if a.shape != b.shape and a.shape[0:1] + a.shape[2:] == b.shape[0:1] + b.shape[2:]:
+ if a.shape[1] == 4 and b.shape[1] == 9:
+ raise RuntimeError("When merging inpainting model with a normal one, A must be the inpainting model.")
+
+ assert a.shape[1] == 9 and b.shape[1] == 4, f"Bad dimensions for merged layer {key}: A={a.shape}, B={b.shape}"
+
+ theta_0[key][:, 0:4, :, :] = theta_func2(a[:, 0:4, :, :], b, multiplier)
+ result_is_inpainting_model = True
+ else:
+ theta_0[key] = theta_func2(a, b, multiplier)
if save_as_half:
theta_0[key] = theta_0[key].half()
@@ -310,17 +331,35 @@ def run_modelmerger(primary_model_name, secondary_model_name, teritary_model_nam
theta_0[key] = theta_1[key]
if save_as_half:
theta_0[key] = theta_0[key].half()
+ del theta_1
ckpt_dir = shared.cmd_opts.ckpt_dir or sd_models.model_path
- filename = primary_model_info.model_name + '_' + str(round(1-multiplier, 2)) + '-' + secondary_model_info.model_name + '_' + str(round(multiplier, 2)) + '-' + interp_method.replace(" ", "_") + '-merged.ckpt'
- filename = filename if custom_name == '' else (custom_name + '.ckpt')
+ filename = \
+ primary_model_info.model_name + '_' + str(round(1-multiplier, 2)) + '-' + \
+ secondary_model_info.model_name + '_' + str(round(multiplier, 2)) + '-' + \
+ interp_method.replace(" ", "_") + \
+ '-merged.' + \
+ ("inpainting." if result_is_inpainting_model else "") + \
+ checkpoint_format
+
+ filename = filename if custom_name == '' else (custom_name + '.' + checkpoint_format)
+
output_modelname = os.path.join(ckpt_dir, filename)
+ shared.state.textinfo = f"Saving to {output_modelname}..."
print(f"Saving to {output_modelname}...")
- torch.save(primary_model, output_modelname)
+
+ _, extension = os.path.splitext(output_modelname)
+ if extension.lower() == ".safetensors":
+ safetensors.torch.save_file(theta_0, output_modelname, metadata={"format": "pt"})
+ else:
+ torch.save(theta_0, output_modelname)
sd_models.list_models()
- print(f"Checkpoint saved.")
+ print("Checkpoint saved.")
+ shared.state.textinfo = "Checkpoint saved to " + output_modelname
+ shared.state.end()
+
return ["Checkpoint saved to " + output_modelname] + [gr.Dropdown.update(choices=sd_models.checkpoint_tiles()) for _ in range(4)]
diff --git a/modules/generation_parameters_copypaste.py b/modules/generation_parameters_copypaste.py
index 985ec95e..4baf4d9a 100644
--- a/modules/generation_parameters_copypaste.py
+++ b/modules/generation_parameters_copypaste.py
@@ -1,10 +1,13 @@
import base64
import io
+import math
import os
import re
+from pathlib import Path
+
import gradio as gr
from modules.shared import script_path
-from modules import shared
+from modules import shared, ui_tempdir
import tempfile
from PIL import Image
@@ -12,6 +15,7 @@ re_param_code = r'\s*([\w ]+):\s*("(?:\\|\"|[^\"])+"|[^,]*)(?:,|$)'
re_param = re.compile(re_param_code)
re_params = re.compile(r"^(?:" + re_param_code + "){3,}$")
re_imagesize = re.compile(r"^(\d+)x(\d+)$")
+re_hypernet_hash = re.compile("\(([0-9a-f]+)\)$")
type_of_gr_update = type(gr.update())
paste_fields = {}
bind_list = []
@@ -33,11 +37,13 @@ def quote(text):
def image_from_url_text(filedata):
- if type(filedata) == dict and filedata["is_file"]:
+ if type(filedata) == list and len(filedata) > 0 and type(filedata[0]) == dict and filedata[0].get("is_file", False):
+ filedata = filedata[0]
+
+ if type(filedata) == dict and filedata.get("is_file", False):
filename = filedata["name"]
- tempdir = os.path.normpath(tempfile.gettempdir())
- normfn = os.path.normpath(filename)
- assert normfn.startswith(tempdir), 'trying to open image file not in temporary directory'
+ is_in_right_dir = ui_tempdir.check_tmp_file(shared.demo, filename)
+ assert is_in_right_dir, 'trying to open image file outside of allowed directories'
return Image.open(filename)
@@ -73,7 +79,10 @@ def integrate_settings_paste_fields(component_dict):
'sd_hypernetwork': 'Hypernet',
'sd_hypernetwork_strength': 'Hypernet strength',
'CLIP_stop_at_last_layers': 'Clip skip',
+ 'inpainting_mask_weight': 'Conditional mask weight',
'sd_model_checkpoint': 'Model hash',
+ 'eta_noise_seed_delta': 'ENSD',
+ 'initial_noise_multiplier': 'Noise multiplier',
}
settings_paste_fields = [
(component_dict[k], lambda d, k=k, v=v: ui.apply_setting(k, d.get(v, None)))
@@ -88,7 +97,7 @@ def integrate_settings_paste_fields(component_dict):
def create_buttons(tabs_list):
buttons = {}
for tab in tabs_list:
- buttons[tab] = gr.Button(f"Send to {tab}")
+ buttons[tab] = gr.Button(f"Send to {tab}", elem_id=f"{tab}_tab")
return buttons
@@ -97,36 +106,57 @@ def bind_buttons(buttons, send_image, send_generate_info):
bind_list.append([buttons, send_image, send_generate_info])
+def send_image_and_dimensions(x):
+ if isinstance(x, Image.Image):
+ img = x
+ else:
+ img = image_from_url_text(x)
+
+ if shared.opts.send_size and isinstance(img, Image.Image):
+ w = img.width
+ h = img.height
+ else:
+ w = gr.update()
+ h = gr.update()
+
+ return img, w, h
+
+
def run_bind():
- for buttons, send_image, send_generate_info in bind_list:
+ for buttons, source_image_component, send_generate_info in bind_list:
for tab in buttons:
button = buttons[tab]
- if send_image and paste_fields[tab]["init_img"]:
- if type(send_image) == gr.Gallery:
- button.click(
- fn=lambda x: image_from_url_text(x),
- _js="extract_image_from_gallery",
- inputs=[send_image],
- outputs=[paste_fields[tab]["init_img"]],
- )
+ destination_image_component = paste_fields[tab]["init_img"]
+ fields = paste_fields[tab]["fields"]
+
+ destination_width_component = next(iter([field for field, name in fields if name == "Size-1"] if fields else []), None)
+ destination_height_component = next(iter([field for field, name in fields if name == "Size-2"] if fields else []), None)
+
+ if source_image_component and destination_image_component:
+ if isinstance(source_image_component, gr.Gallery):
+ func = send_image_and_dimensions if destination_width_component else image_from_url_text
+ jsfunc = "extract_image_from_gallery"
else:
- button.click(
- fn=lambda x: x,
- inputs=[send_image],
- outputs=[paste_fields[tab]["init_img"]],
- )
+ func = send_image_and_dimensions if destination_width_component else lambda x: x
+ jsfunc = None
- if send_generate_info and paste_fields[tab]["fields"] is not None:
- if send_generate_info in paste_fields:
- paste_field_names = ['Prompt', 'Negative prompt', 'Steps', 'Face restoration', 'Size-1', 'Size-2'] + (["Seed"] if shared.opts.send_seed else [])
+ button.click(
+ fn=func,
+ _js=jsfunc,
+ inputs=[source_image_component],
+ outputs=[destination_image_component, destination_width_component, destination_height_component] if destination_width_component else [destination_image_component],
+ )
+ if send_generate_info and fields is not None:
+ if send_generate_info in paste_fields:
+ paste_field_names = ['Prompt', 'Negative prompt', 'Steps', 'Face restoration'] + (["Seed"] if shared.opts.send_seed else [])
button.click(
fn=lambda *x: x,
inputs=[field for field, name in paste_fields[send_generate_info]["fields"] if name in paste_field_names],
- outputs=[field for field, name in paste_fields[tab]["fields"] if name in paste_field_names],
+ outputs=[field for field, name in fields if name in paste_field_names],
)
else:
- connect_paste(button, paste_fields[tab]["fields"], send_generate_info)
+ connect_paste(button, fields, send_generate_info)
button.click(
fn=None,
@@ -136,6 +166,59 @@ def run_bind():
)
+def find_hypernetwork_key(hypernet_name, hypernet_hash=None):
+ """Determines the config parameter name to use for the hypernet based on the parameters in the infotext.
+
+ Example: an infotext provides "Hypernet: ke-ta" and "Hypernet hash: 1234abcd". For the "Hypernet" config
+ parameter this means there should be an entry that looks like "ke-ta-10000(1234abcd)" to set it to.
+
+ If the infotext has no hash, then a hypernet with the same name will be selected instead.
+ """
+ hypernet_name = hypernet_name.lower()
+ if hypernet_hash is not None:
+ # Try to match the hash in the name
+ for hypernet_key in shared.hypernetworks.keys():
+ result = re_hypernet_hash.search(hypernet_key)
+ if result is not None and result[1] == hypernet_hash:
+ return hypernet_key
+ else:
+ # Fall back to a hypernet with the same name
+ for hypernet_key in shared.hypernetworks.keys():
+ if hypernet_key.lower().startswith(hypernet_name):
+ return hypernet_key
+
+ return None
+
+
+def restore_old_hires_fix_params(res):
+ """for infotexts that specify old First pass size parameter, convert it into
+ width, height, and hr scale"""
+
+ firstpass_width = res.get('First pass size-1', None)
+ firstpass_height = res.get('First pass size-2', None)
+
+ if firstpass_width is None or firstpass_height is None:
+ return
+
+ firstpass_width, firstpass_height = int(firstpass_width), int(firstpass_height)
+ width = int(res.get("Size-1", 512))
+ height = int(res.get("Size-2", 512))
+
+ if firstpass_width == 0 or firstpass_height == 0:
+ # old algorithm for auto-calculating first pass size
+ desired_pixel_count = 512 * 512
+ actual_pixel_count = width * height
+ scale = math.sqrt(desired_pixel_count / actual_pixel_count)
+ firstpass_width = math.ceil(scale * width / 64) * 64
+ firstpass_height = math.ceil(scale * height / 64) * 64
+
+ hr_scale = width / firstpass_width if firstpass_width > 0 else height / firstpass_height
+
+ res['Size-1'] = firstpass_width
+ res['Size-2'] = firstpass_height
+ res['Hires upscale'] = hr_scale
+
+
def parse_generation_parameters(x: str):
"""parses generation parameters string, the one you see in text field under the picture in UI:
```
@@ -181,6 +264,20 @@ Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 965400086, Size: 512x512, Model
else:
res[k] = v
+ # Missing CLIP skip means it was set to 1 (the default)
+ if "Clip skip" not in res:
+ res["Clip skip"] = "1"
+
+ if "Hypernet strength" not in res:
+ res["Hypernet strength"] = "1"
+
+ if "Hypernet" in res:
+ hypernet_name = res["Hypernet"]
+ hypernet_hash = res.get("Hypernet hash", None)
+ res["Hypernet"] = find_hypernetwork_key(hypernet_name, hypernet_hash)
+
+ restore_old_hires_fix_params(res)
+
return res
diff --git a/modules/gfpgan_model.py b/modules/gfpgan_model.py
index a9452dce..1e2dbc32 100644
--- a/modules/gfpgan_model.py
+++ b/modules/gfpgan_model.py
@@ -36,7 +36,9 @@ def gfpgann():
else:
print("Unable to load gfpgan model!")
return None
- model = gfpgan_constructor(model_path=model_file, upscale=1, arch='clean', channel_multiplier=2, bg_upsampler=None)
+ if hasattr(facexlib.detection.retinaface, 'device'):
+ facexlib.detection.retinaface.device = devices.device_gfpgan
+ model = gfpgan_constructor(model_path=model_file, upscale=1, arch='clean', channel_multiplier=2, bg_upsampler=None, device=devices.device_gfpgan)
loaded_gfpgan_model = model
return model
diff --git a/modules/hypernetworks/hypernetwork.py b/modules/hypernetworks/hypernetwork.py
index a11e01d6..450fecac 100644
--- a/modules/hypernetworks/hypernetwork.py
+++ b/modules/hypernetworks/hypernetwork.py
@@ -12,7 +12,7 @@ import torch
import tqdm
from einops import rearrange, repeat
from ldm.util import default
-from modules import devices, processing, sd_models, shared
+from modules import devices, processing, sd_models, shared, sd_samplers
from modules.textual_inversion import textual_inversion
from modules.textual_inversion.learn_schedule import LearnRateScheduler
from torch import einsum
@@ -22,6 +22,8 @@ from collections import defaultdict, deque
from statistics import stdev, mean
+optimizer_dict = {optim_name : cls_obj for optim_name, cls_obj in inspect.getmembers(torch.optim, inspect.isclass) if optim_name != "Optimizer"}
+
class HypernetworkModule(torch.nn.Module):
multiplier = 1.0
activation_dict = {
@@ -35,7 +37,8 @@ class HypernetworkModule(torch.nn.Module):
}
activation_dict.update({cls_name.lower(): cls_obj for cls_name, cls_obj in inspect.getmembers(torch.nn.modules.activation) if inspect.isclass(cls_obj) and cls_obj.__module__ == 'torch.nn.modules.activation'})
- def __init__(self, dim, state_dict=None, layer_structure=None, activation_func=None, weight_init='Normal', add_layer_norm=False, use_dropout=False):
+ def __init__(self, dim, state_dict=None, layer_structure=None, activation_func=None, weight_init='Normal',
+ add_layer_norm=False, use_dropout=False, activate_output=False, last_layer_dropout=False):
super().__init__()
assert layer_structure is not None, "layer_structure must not be None"
@@ -48,8 +51,8 @@ class HypernetworkModule(torch.nn.Module):
# Add a fully-connected layer
linears.append(torch.nn.Linear(int(dim * layer_structure[i]), int(dim * layer_structure[i+1])))
- # Add an activation func
- if activation_func == "linear" or activation_func is None:
+ # Add an activation func except last layer
+ if activation_func == "linear" or activation_func is None or (i >= len(layer_structure) - 2 and not activate_output):
pass
elif activation_func in self.activation_dict:
linears.append(self.activation_dict[activation_func]())
@@ -60,8 +63,8 @@ class HypernetworkModule(torch.nn.Module):
if add_layer_norm:
linears.append(torch.nn.LayerNorm(int(dim * layer_structure[i+1])))
- # Add dropout expect last layer
- if use_dropout and i < len(layer_structure) - 3:
+ # Add dropout except last layer
+ if use_dropout and (i < len(layer_structure) - 3 or last_layer_dropout and i < len(layer_structure) - 2):
linears.append(torch.nn.Dropout(p=0.3))
self.linear = torch.nn.Sequential(*linears)
@@ -75,7 +78,7 @@ class HypernetworkModule(torch.nn.Module):
w, b = layer.weight.data, layer.bias.data
if weight_init == "Normal" or type(layer) == torch.nn.LayerNorm:
normal_(w, mean=0.0, std=0.01)
- normal_(b, mean=0.0, std=0.005)
+ normal_(b, mean=0.0, std=0)
elif weight_init == 'XavierUniform':
xavier_uniform_(w)
zeros_(b)
@@ -127,7 +130,7 @@ class Hypernetwork:
filename = None
name = None
- def __init__(self, name=None, enable_sizes=None, layer_structure=None, activation_func=None, weight_init=None, add_layer_norm=False, use_dropout=False):
+ def __init__(self, name=None, enable_sizes=None, layer_structure=None, activation_func=None, weight_init=None, add_layer_norm=False, use_dropout=False, activate_output=False, **kwargs):
self.filename = None
self.name = name
self.layers = {}
@@ -139,25 +142,44 @@ class Hypernetwork:
self.weight_init = weight_init
self.add_layer_norm = add_layer_norm
self.use_dropout = use_dropout
+ self.activate_output = activate_output
+ self.last_layer_dropout = kwargs['last_layer_dropout'] if 'last_layer_dropout' in kwargs else True
+ self.optimizer_name = None
+ self.optimizer_state_dict = None
for size in enable_sizes or []:
self.layers[size] = (
- HypernetworkModule(size, None, self.layer_structure, self.activation_func, self.weight_init, self.add_layer_norm, self.use_dropout),
- HypernetworkModule(size, None, self.layer_structure, self.activation_func, self.weight_init, self.add_layer_norm, self.use_dropout),
+ HypernetworkModule(size, None, self.layer_structure, self.activation_func, self.weight_init,
+ self.add_layer_norm, self.use_dropout, self.activate_output, last_layer_dropout=self.last_layer_dropout),
+ HypernetworkModule(size, None, self.layer_structure, self.activation_func, self.weight_init,
+ self.add_layer_norm, self.use_dropout, self.activate_output, last_layer_dropout=self.last_layer_dropout),
)
+ self.eval_mode()
def weights(self):
res = []
+ for k, layers in self.layers.items():
+ for layer in layers:
+ res += layer.parameters()
+ return res
+ def train_mode(self):
for k, layers in self.layers.items():
for layer in layers:
layer.train()
- res += layer.trainables()
+ for param in layer.parameters():
+ param.requires_grad = True
- return res
+ def eval_mode(self):
+ for k, layers in self.layers.items():
+ for layer in layers:
+ layer.eval()
+ for param in layer.parameters():
+ param.requires_grad = False
def save(self, filename):
state_dict = {}
+ optimizer_saved_dict = {}
for k, v in self.layers.items():
state_dict[k] = (v[0].state_dict(), v[1].state_dict())
@@ -171,8 +193,17 @@ class Hypernetwork:
state_dict['use_dropout'] = self.use_dropout
state_dict['sd_checkpoint'] = self.sd_checkpoint
state_dict['sd_checkpoint_name'] = self.sd_checkpoint_name
+ state_dict['activate_output'] = self.activate_output
+ state_dict['last_layer_dropout'] = self.last_layer_dropout
+
+ if self.optimizer_name is not None:
+ optimizer_saved_dict['optimizer_name'] = self.optimizer_name
torch.save(state_dict, filename)
+ if shared.opts.save_optimizer_state and self.optimizer_state_dict:
+ optimizer_saved_dict['hash'] = sd_models.model_hash(filename)
+ optimizer_saved_dict['optimizer_state_dict'] = self.optimizer_state_dict
+ torch.save(optimizer_saved_dict, filename + '.optim')
def load(self, filename):
self.filename = filename
@@ -191,12 +222,29 @@ class Hypernetwork:
print(f"Layer norm is set to {self.add_layer_norm}")
self.use_dropout = state_dict.get('use_dropout', False)
print(f"Dropout usage is set to {self.use_dropout}" )
+ self.activate_output = state_dict.get('activate_output', True)
+ print(f"Activate last layer is set to {self.activate_output}")
+ self.last_layer_dropout = state_dict.get('last_layer_dropout', False)
+
+ optimizer_saved_dict = torch.load(self.filename + '.optim', map_location = 'cpu') if os.path.exists(self.filename + '.optim') else {}
+ self.optimizer_name = optimizer_saved_dict.get('optimizer_name', 'AdamW')
+ print(f"Optimizer name is {self.optimizer_name}")
+ if sd_models.model_hash(filename) == optimizer_saved_dict.get('hash', None):
+ self.optimizer_state_dict = optimizer_saved_dict.get('optimizer_state_dict', None)
+ else:
+ self.optimizer_state_dict = None
+ if self.optimizer_state_dict:
+ print("Loaded existing optimizer from checkpoint")
+ else:
+ print("No saved optimizer exists in checkpoint")
for size, sd in state_dict.items():
if type(size) == int:
self.layers[size] = (
- HypernetworkModule(size, sd[0], self.layer_structure, self.activation_func, self.weight_init, self.add_layer_norm, self.use_dropout),
- HypernetworkModule(size, sd[1], self.layer_structure, self.activation_func, self.weight_init, self.add_layer_norm, self.use_dropout),
+ HypernetworkModule(size, sd[0], self.layer_structure, self.activation_func, self.weight_init,
+ self.add_layer_norm, self.use_dropout, self.activate_output, last_layer_dropout=self.last_layer_dropout),
+ HypernetworkModule(size, sd[1], self.layer_structure, self.activation_func, self.weight_init,
+ self.add_layer_norm, self.use_dropout, self.activate_output, last_layer_dropout=self.last_layer_dropout),
)
self.name = state_dict.get('name', self.name)
@@ -207,11 +255,11 @@ class Hypernetwork:
def list_hypernetworks(path):
res = {}
- for filename in glob.iglob(os.path.join(path, '**/*.pt'), recursive=True):
+ for filename in sorted(glob.iglob(os.path.join(path, '**/*.pt'), recursive=True)):
name = os.path.splitext(os.path.basename(filename))[0]
# Prevent a hypothetical "None.pt" from being listed.
if name != "None":
- res[name] = filename
+ res[name + f"({sd_models.model_hash(filename)})"] = filename
return res
@@ -229,7 +277,7 @@ def load_hypernetwork(filename):
print(traceback.format_exc(), file=sys.stderr)
else:
if shared.loaded_hypernetwork is not None:
- print(f"Unloading hypernetwork")
+ print("Unloading hypernetwork")
shared.loaded_hypernetwork = None
@@ -330,22 +378,50 @@ def report_statistics(loss_info:dict):
print(e)
+def create_hypernetwork(name, enable_sizes, overwrite_old, layer_structure=None, activation_func=None, weight_init=None, add_layer_norm=False, use_dropout=False):
+ # Remove illegal characters from name.
+ name = "".join( x for x in name if (x.isalnum() or x in "._- "))
+
+ fn = os.path.join(shared.cmd_opts.hypernetwork_dir, f"{name}.pt")
+ if not overwrite_old:
+ assert not os.path.exists(fn), f"file {fn} already exists"
+
+ if type(layer_structure) == str:
+ layer_structure = [float(x.strip()) for x in layer_structure.split(",")]
-def train_hypernetwork(hypernetwork_name, learn_rate, batch_size, data_root, log_directory, training_width, training_height, steps, create_image_every, save_hypernetwork_every, template_file, preview_from_txt2img, preview_prompt, preview_negative_prompt, preview_steps, preview_sampler_index, preview_cfg_scale, preview_seed, preview_width, preview_height):
+ hypernet = modules.hypernetworks.hypernetwork.Hypernetwork(
+ name=name,
+ enable_sizes=[int(x) for x in enable_sizes],
+ layer_structure=layer_structure,
+ activation_func=activation_func,
+ weight_init=weight_init,
+ add_layer_norm=add_layer_norm,
+ use_dropout=use_dropout,
+ )
+ hypernet.save(fn)
+
+ shared.reload_hypernetworks()
+
+ return fn
+
+
+def train_hypernetwork(hypernetwork_name, learn_rate, batch_size, gradient_step, data_root, log_directory, training_width, training_height, steps, shuffle_tags, tag_drop_out, latent_sampling_method, create_image_every, save_hypernetwork_every, template_file, preview_from_txt2img, preview_prompt, preview_negative_prompt, preview_steps, preview_sampler_index, preview_cfg_scale, preview_seed, preview_width, preview_height):
# images allows training previews to have infotext. Importing it at the top causes a circular import problem.
from modules import images
save_hypernetwork_every = save_hypernetwork_every or 0
create_image_every = create_image_every or 0
- textual_inversion.validate_train_inputs(hypernetwork_name, learn_rate, batch_size, data_root, template_file, steps, save_hypernetwork_every, create_image_every, log_directory, name="hypernetwork")
+ textual_inversion.validate_train_inputs(hypernetwork_name, learn_rate, batch_size, gradient_step, data_root, template_file, steps, save_hypernetwork_every, create_image_every, log_directory, name="hypernetwork")
path = shared.hypernetworks.get(hypernetwork_name, None)
shared.loaded_hypernetwork = Hypernetwork()
shared.loaded_hypernetwork.load(path)
+ shared.state.job = "train-hypernetwork"
shared.state.textinfo = "Initializing hypernetwork training..."
shared.state.job_count = steps
+ hypernetwork_name = hypernetwork_name.rsplit('(', 1)[0]
filename = os.path.join(shared.cmd_opts.hypernetwork_dir, f'{hypernetwork_name}.pt')
log_directory = os.path.join(log_directory, datetime.datetime.now().strftime("%Y-%m-%d"), hypernetwork_name)
@@ -366,34 +442,65 @@ def train_hypernetwork(hypernetwork_name, learn_rate, batch_size, data_root, log
hypernetwork = shared.loaded_hypernetwork
checkpoint = sd_models.select_checkpoint()
- ititial_step = hypernetwork.step or 0
- if ititial_step >= steps:
- shared.state.textinfo = f"Model has already been trained beyond specified max steps"
+ initial_step = hypernetwork.step or 0
+ if initial_step >= steps:
+ shared.state.textinfo = "Model has already been trained beyond specified max steps"
return hypernetwork, filename
- scheduler = LearnRateScheduler(learn_rate, steps, ititial_step)
-
+ scheduler = LearnRateScheduler(learn_rate, steps, initial_step)
+
# dataset loading may take a while, so input validations and early returns should be done before this
shared.state.textinfo = f"Preparing dataset from {html.escape(data_root)}..."
- with torch.autocast("cuda"):
- ds = modules.textual_inversion.dataset.PersonalizedBase(data_root=data_root, width=training_width, height=training_height, repeats=shared.opts.training_image_repeats_per_epoch, placeholder_token=hypernetwork_name, model=shared.sd_model, device=devices.device, template_file=template_file, include_cond=True, batch_size=batch_size)
+
+ pin_memory = shared.opts.pin_memory
+
+ ds = modules.textual_inversion.dataset.PersonalizedBase(data_root=data_root, width=training_width, height=training_height, repeats=shared.opts.training_image_repeats_per_epoch, placeholder_token=hypernetwork_name, model=shared.sd_model, cond_model=shared.sd_model.cond_stage_model, device=devices.device, template_file=template_file, include_cond=True, batch_size=batch_size, gradient_step=gradient_step, shuffle_tags=shuffle_tags, tag_drop_out=tag_drop_out, latent_sampling_method=latent_sampling_method)
+
+ latent_sampling_method = ds.latent_sampling_method
+
+ dl = modules.textual_inversion.dataset.PersonalizedDataLoader(ds, latent_sampling_method=latent_sampling_method, batch_size=ds.batch_size, pin_memory=pin_memory)
+
+ old_parallel_processing_allowed = shared.parallel_processing_allowed
if unload:
+ shared.parallel_processing_allowed = False
shared.sd_model.cond_stage_model.to(devices.cpu)
shared.sd_model.first_stage_model.to(devices.cpu)
-
- size = len(ds.indexes)
- loss_dict = defaultdict(lambda : deque(maxlen = 1024))
- losses = torch.zeros((size,))
- previous_mean_losses = [0]
- previous_mean_loss = 0
- print("Mean loss of {} elements".format(size))
weights = hypernetwork.weights()
- for weight in weights:
- weight.requires_grad = True
- # if optimizer == "AdamW": or else Adam / AdamW / SGD, etc...
- optimizer = torch.optim.AdamW(weights, lr=scheduler.learn_rate)
+ hypernetwork.train_mode()
+
+ # Here we use optimizer from saved HN, or we can specify as UI option.
+ if hypernetwork.optimizer_name in optimizer_dict:
+ optimizer = optimizer_dict[hypernetwork.optimizer_name](params=weights, lr=scheduler.learn_rate)
+ optimizer_name = hypernetwork.optimizer_name
+ else:
+ print(f"Optimizer type {hypernetwork.optimizer_name} is not defined!")
+ optimizer = torch.optim.AdamW(params=weights, lr=scheduler.learn_rate)
+ optimizer_name = 'AdamW'
+
+ if hypernetwork.optimizer_state_dict: # This line must be changed if Optimizer type can be different from saved optimizer.
+ try:
+ optimizer.load_state_dict(hypernetwork.optimizer_state_dict)
+ except RuntimeError as e:
+ print("Cannot resume from saved optimizer!")
+ print(e)
+
+ scaler = torch.cuda.amp.GradScaler()
+
+ batch_size = ds.batch_size
+ gradient_step = ds.gradient_step
+ # n steps = batch_size * gradient_step * n image processed
+ steps_per_epoch = len(ds) // batch_size // gradient_step
+ max_steps_per_epoch = len(ds) // batch_size - (len(ds) // batch_size) % gradient_step
+ loss_step = 0
+ _loss_step = 0 #internal
+ # size = len(ds.indexes)
+ # loss_dict = defaultdict(lambda : deque(maxlen = 1024))
+ # losses = torch.zeros((size,))
+ # previous_mean_losses = [0]
+ # previous_mean_loss = 0
+ # print("Mean loss of {} elements".format(size))
steps_without_grad = 0
@@ -401,125 +508,147 @@ def train_hypernetwork(hypernetwork_name, learn_rate, batch_size, data_root, log
last_saved_image = "<none>"
forced_filename = "<none>"
- pbar = tqdm.tqdm(enumerate(ds), total=steps - ititial_step)
- for i, entries in pbar:
- hypernetwork.step = i + ititial_step
- if len(loss_dict) > 0:
- previous_mean_losses = [i[-1] for i in loss_dict.values()]
- previous_mean_loss = mean(previous_mean_losses)
-
- scheduler.apply(optimizer, hypernetwork.step)
- if scheduler.finished:
- break
-
- if shared.state.interrupted:
- break
-
- with torch.autocast("cuda"):
- c = stack_conds([entry.cond for entry in entries]).to(devices.device)
- # c = torch.vstack([entry.cond for entry in entries]).to(devices.device)
- x = torch.stack([entry.latent for entry in entries]).to(devices.device)
- loss = shared.sd_model(x, c)[0]
- del x
- del c
-
- losses[hypernetwork.step % losses.shape[0]] = loss.item()
- for entry in entries:
- loss_dict[entry.filename].append(loss.item())
+ pbar = tqdm.tqdm(total=steps - initial_step)
+ try:
+ for i in range((steps-initial_step) * gradient_step):
+ if scheduler.finished:
+ break
+ if shared.state.interrupted:
+ break
+ for j, batch in enumerate(dl):
+ # works as a drop_last=True for gradient accumulation
+ if j == max_steps_per_epoch:
+ break
+ scheduler.apply(optimizer, hypernetwork.step)
+ if scheduler.finished:
+ break
+ if shared.state.interrupted:
+ break
+
+ with devices.autocast():
+ x = batch.latent_sample.to(devices.device, non_blocking=pin_memory)
+ if tag_drop_out != 0 or shuffle_tags:
+ shared.sd_model.cond_stage_model.to(devices.device)
+ c = shared.sd_model.cond_stage_model(batch.cond_text).to(devices.device, non_blocking=pin_memory)
+ shared.sd_model.cond_stage_model.to(devices.cpu)
+ else:
+ c = stack_conds(batch.cond).to(devices.device, non_blocking=pin_memory)
+ loss = shared.sd_model(x, c)[0] / gradient_step
+ del x
+ del c
+
+ _loss_step += loss.item()
+ scaler.scale(loss).backward()
+ # go back until we reach gradient accumulation steps
+ if (j + 1) % gradient_step != 0:
+ continue
+ # print(f"grad:{weights[0].grad.detach().cpu().abs().mean().item():.7f}")
+ # scaler.unscale_(optimizer)
+ # print(f"grad:{weights[0].grad.detach().cpu().abs().mean().item():.15f}")
+ # torch.nn.utils.clip_grad_norm_(weights, max_norm=1.0)
+ # print(f"grad:{weights[0].grad.detach().cpu().abs().mean().item():.15f}")
+ scaler.step(optimizer)
+ scaler.update()
+ hypernetwork.step += 1
+ pbar.update()
+ optimizer.zero_grad(set_to_none=True)
+ loss_step = _loss_step
+ _loss_step = 0
+
+ steps_done = hypernetwork.step + 1
- optimizer.zero_grad()
- weights[0].grad = None
- loss.backward()
-
- if weights[0].grad is None:
- steps_without_grad += 1
- else:
- steps_without_grad = 0
- assert steps_without_grad < 10, 'no gradient found for the trained weight after backward() for 10 steps in a row; this is a bug; training cannot continue'
-
- optimizer.step()
-
- steps_done = hypernetwork.step + 1
-
- if torch.isnan(losses[hypernetwork.step % losses.shape[0]]):
- raise RuntimeError("Loss diverged.")
-
- if len(previous_mean_losses) > 1:
- std = stdev(previous_mean_losses)
- else:
- std = 0
- dataset_loss_info = f"dataset loss:{mean(previous_mean_losses):.3f}" + u"\u00B1" + f"({std / (len(previous_mean_losses) ** 0.5):.3f})"
- pbar.set_description(dataset_loss_info)
-
- if hypernetwork_dir is not None and steps_done % save_hypernetwork_every == 0:
- # Before saving, change name to match current checkpoint.
- hypernetwork_name_every = f'{hypernetwork_name}-{steps_done}'
- last_saved_file = os.path.join(hypernetwork_dir, f'{hypernetwork_name_every}.pt')
- save_hypernetwork(hypernetwork, checkpoint, hypernetwork_name, last_saved_file)
-
- textual_inversion.write_loss(log_directory, "hypernetwork_loss.csv", hypernetwork.step, len(ds), {
- "loss": f"{previous_mean_loss:.7f}",
- "learn_rate": scheduler.learn_rate
- })
-
- if images_dir is not None and steps_done % create_image_every == 0:
- forced_filename = f'{hypernetwork_name}-{steps_done}'
- last_saved_image = os.path.join(images_dir, forced_filename)
-
- optimizer.zero_grad()
- shared.sd_model.cond_stage_model.to(devices.device)
- shared.sd_model.first_stage_model.to(devices.device)
-
- p = processing.StableDiffusionProcessingTxt2Img(
- sd_model=shared.sd_model,
- do_not_save_grid=True,
- do_not_save_samples=True,
- )
-
- if preview_from_txt2img:
- p.prompt = preview_prompt
- p.negative_prompt = preview_negative_prompt
- p.steps = preview_steps
- p.sampler_index = preview_sampler_index
- p.cfg_scale = preview_cfg_scale
- p.seed = preview_seed
- p.width = preview_width
- p.height = preview_height
- else:
- p.prompt = entries[0].cond_text
- p.steps = 20
-
- preview_text = p.prompt
+ epoch_num = hypernetwork.step // steps_per_epoch
+ epoch_step = hypernetwork.step % steps_per_epoch
+
+ pbar.set_description(f"[Epoch {epoch_num}: {epoch_step+1}/{steps_per_epoch}]loss: {loss_step:.7f}")
+ if hypernetwork_dir is not None and steps_done % save_hypernetwork_every == 0:
+ # Before saving, change name to match current checkpoint.
+ hypernetwork_name_every = f'{hypernetwork_name}-{steps_done}'
+ last_saved_file = os.path.join(hypernetwork_dir, f'{hypernetwork_name_every}.pt')
+ hypernetwork.optimizer_name = optimizer_name
+ if shared.opts.save_optimizer_state:
+ hypernetwork.optimizer_state_dict = optimizer.state_dict()
+ save_hypernetwork(hypernetwork, checkpoint, hypernetwork_name, last_saved_file)
+ hypernetwork.optimizer_state_dict = None # dereference it after saving, to save memory.
+
+ textual_inversion.write_loss(log_directory, "hypernetwork_loss.csv", hypernetwork.step, steps_per_epoch, {
+ "loss": f"{loss_step:.7f}",
+ "learn_rate": scheduler.learn_rate
+ })
+
+ if images_dir is not None and steps_done % create_image_every == 0:
+ forced_filename = f'{hypernetwork_name}-{steps_done}'
+ last_saved_image = os.path.join(images_dir, forced_filename)
+ hypernetwork.eval_mode()
+ shared.sd_model.cond_stage_model.to(devices.device)
+ shared.sd_model.first_stage_model.to(devices.device)
+
+ p = processing.StableDiffusionProcessingTxt2Img(
+ sd_model=shared.sd_model,
+ do_not_save_grid=True,
+ do_not_save_samples=True,
+ )
+
+ if preview_from_txt2img:
+ p.prompt = preview_prompt
+ p.negative_prompt = preview_negative_prompt
+ p.steps = preview_steps
+ p.sampler_name = sd_samplers.samplers[preview_sampler_index].name
+ p.cfg_scale = preview_cfg_scale
+ p.seed = preview_seed
+ p.width = preview_width
+ p.height = preview_height
+ else:
+ p.prompt = batch.cond_text[0]
+ p.steps = 20
+ p.width = training_width
+ p.height = training_height
- processed = processing.process_images(p)
- image = processed.images[0] if len(processed.images)>0 else None
+ preview_text = p.prompt
- if unload:
- shared.sd_model.cond_stage_model.to(devices.cpu)
- shared.sd_model.first_stage_model.to(devices.cpu)
+ processed = processing.process_images(p)
+ image = processed.images[0] if len(processed.images) > 0 else None
- if image is not None:
- shared.state.current_image = image
- last_saved_image, last_text_info = images.save_image(image, images_dir, "", p.seed, p.prompt, shared.opts.samples_format, processed.infotexts[0], p=p, forced_filename=forced_filename, save_to_dirs=False)
- last_saved_image += f", prompt: {preview_text}"
+ if unload:
+ shared.sd_model.cond_stage_model.to(devices.cpu)
+ shared.sd_model.first_stage_model.to(devices.cpu)
+ hypernetwork.train_mode()
+ if image is not None:
+ shared.state.current_image = image
+ last_saved_image, last_text_info = images.save_image(image, images_dir, "", p.seed, p.prompt, shared.opts.samples_format, processed.infotexts[0], p=p, forced_filename=forced_filename, save_to_dirs=False)
+ last_saved_image += f", prompt: {preview_text}"
- shared.state.job_no = hypernetwork.step
+ shared.state.job_no = hypernetwork.step
- shared.state.textinfo = f"""
+ shared.state.textinfo = f"""
<p>
-Loss: {previous_mean_loss:.7f}<br/>
-Step: {hypernetwork.step}<br/>
-Last prompt: {html.escape(entries[0].cond_text)}<br/>
+Loss: {loss_step:.7f}<br/>
+Step: {steps_done}<br/>
+Last prompt: {html.escape(batch.cond_text[0])}<br/>
Last saved hypernetwork: {html.escape(last_saved_file)}<br/>
Last saved image: {html.escape(last_saved_image)}<br/>
</p>
"""
-
- report_statistics(loss_dict)
+ except Exception:
+ print(traceback.format_exc(), file=sys.stderr)
+ finally:
+ pbar.leave = False
+ pbar.close()
+ hypernetwork.eval_mode()
+ #report_statistics(loss_dict)
filename = os.path.join(shared.cmd_opts.hypernetwork_dir, f'{hypernetwork_name}.pt')
+ hypernetwork.optimizer_name = optimizer_name
+ if shared.opts.save_optimizer_state:
+ hypernetwork.optimizer_state_dict = optimizer.state_dict()
save_hypernetwork(hypernetwork, checkpoint, hypernetwork_name, filename)
+ del optimizer
+ hypernetwork.optimizer_state_dict = None # dereference it after saving, to save memory.
+ shared.sd_model.cond_stage_model.to(devices.device)
+ shared.sd_model.first_stage_model.to(devices.device)
+ shared.parallel_processing_allowed = old_parallel_processing_allowed
+
return hypernetwork, filename
def save_hypernetwork(hypernetwork, checkpoint, hypernetwork_name, filename):
diff --git a/modules/hypernetworks/ui.py b/modules/hypernetworks/ui.py
index aad09ffc..e7f9e593 100644
--- a/modules/hypernetworks/ui.py
+++ b/modules/hypernetworks/ui.py
@@ -3,39 +3,16 @@ import os
import re
import gradio as gr
-import modules.textual_inversion.preprocess
-import modules.textual_inversion.textual_inversion
+import modules.hypernetworks.hypernetwork
from modules import devices, sd_hijack, shared
-from modules.hypernetworks import hypernetwork
not_available = ["hardswish", "multiheadattention"]
-keys = ["linear"] + list(x for x in hypernetwork.HypernetworkModule.activation_dict.keys() if x not in not_available)
+keys = list(x for x in modules.hypernetworks.hypernetwork.HypernetworkModule.activation_dict.keys() if x not in not_available)
def create_hypernetwork(name, enable_sizes, overwrite_old, layer_structure=None, activation_func=None, weight_init=None, add_layer_norm=False, use_dropout=False):
- # Remove illegal characters from name.
- name = "".join( x for x in name if (x.isalnum() or x in "._- "))
+ filename = modules.hypernetworks.hypernetwork.create_hypernetwork(name, enable_sizes, overwrite_old, layer_structure, activation_func, weight_init, add_layer_norm, use_dropout)
- fn = os.path.join(shared.cmd_opts.hypernetwork_dir, f"{name}.pt")
- if not overwrite_old:
- assert not os.path.exists(fn), f"file {fn} already exists"
-
- if type(layer_structure) == str:
- layer_structure = [float(x.strip()) for x in layer_structure.split(",")]
-
- hypernet = modules.hypernetworks.hypernetwork.Hypernetwork(
- name=name,
- enable_sizes=[int(x) for x in enable_sizes],
- layer_structure=layer_structure,
- activation_func=activation_func,
- weight_init=weight_init,
- add_layer_norm=add_layer_norm,
- use_dropout=use_dropout,
- )
- hypernet.save(fn)
-
- shared.reload_hypernetworks()
-
- return gr.Dropdown.update(choices=sorted([x for x in shared.hypernetworks.keys()])), f"Created: {fn}", ""
+ return gr.Dropdown.update(choices=sorted([x for x in shared.hypernetworks.keys()])), f"Created: {filename}", ""
def train_hypernetwork(*args):
diff --git a/modules/images.py b/modules/images.py
index ae705cbd..c3a5fc8b 100644
--- a/modules/images.py
+++ b/modules/images.py
@@ -15,6 +15,7 @@ import piexif.helper
from PIL import Image, ImageFont, ImageDraw, PngImagePlugin
from fonts.ttf import Roboto
import string
+import json
from modules import sd_samplers, shared, script_callbacks
from modules.shared import opts, cmd_opts
@@ -38,11 +39,14 @@ def image_grid(imgs, batch_size=1, rows=None):
cols = math.ceil(len(imgs) / rows)
+ params = script_callbacks.ImageGridLoopParams(imgs, cols, rows)
+ script_callbacks.image_grid_callback(params)
+
w, h = imgs[0].size
- grid = Image.new('RGB', size=(cols * w, rows * h), color='black')
+ grid = Image.new('RGB', size=(params.cols * w, params.rows * h), color='black')
- for i, img in enumerate(imgs):
- grid.paste(img, box=(i % cols * w, i // cols * h))
+ for i, img in enumerate(params.imgs):
+ grid.paste(img, box=(i % params.cols * w, i // params.cols * h))
return grid
@@ -135,8 +139,19 @@ def draw_grid_annotations(im, width, height, hor_texts, ver_texts):
lines.append(word)
return lines
- def draw_texts(drawing, draw_x, draw_y, lines):
+ def get_font(fontsize):
+ try:
+ return ImageFont.truetype(opts.font or Roboto, fontsize)
+ except Exception:
+ return ImageFont.truetype(Roboto, fontsize)
+
+ def draw_texts(drawing, draw_x, draw_y, lines, initial_fnt, initial_fontsize):
for i, line in enumerate(lines):
+ fnt = initial_fnt
+ fontsize = initial_fontsize
+ while drawing.multiline_textsize(line.text, font=fnt)[0] > line.allowed_width and fontsize > 0:
+ fontsize -= 1
+ fnt = get_font(fontsize)
drawing.multiline_text((draw_x, draw_y + line.size[1] / 2), line.text, font=fnt, fill=color_active if line.is_active else color_inactive, anchor="mm", align="center")
if not line.is_active:
@@ -147,10 +162,7 @@ def draw_grid_annotations(im, width, height, hor_texts, ver_texts):
fontsize = (width + height) // 25
line_spacing = fontsize // 2
- try:
- fnt = ImageFont.truetype(opts.font or Roboto, fontsize)
- except Exception:
- fnt = ImageFont.truetype(Roboto, fontsize)
+ fnt = get_font(fontsize)
color_active = (0, 0, 0)
color_inactive = (153, 153, 153)
@@ -177,6 +189,7 @@ def draw_grid_annotations(im, width, height, hor_texts, ver_texts):
for line in texts:
bbox = calc_d.multiline_textbbox((0, 0), line.text, font=fnt)
line.size = (bbox[2] - bbox[0], bbox[3] - bbox[1])
+ line.allowed_width = allowed_width
hor_text_heights = [sum([line.size[1] + line_spacing for line in lines]) - line_spacing for lines in hor_texts]
ver_text_heights = [sum([line.size[1] + line_spacing for line in lines]) - line_spacing * len(lines) for lines in
@@ -193,13 +206,13 @@ def draw_grid_annotations(im, width, height, hor_texts, ver_texts):
x = pad_left + width * col + width / 2
y = pad_top / 2 - hor_text_heights[col] / 2
- draw_texts(d, x, y, hor_texts[col])
+ draw_texts(d, x, y, hor_texts[col], fnt, fontsize)
for row in range(rows):
x = pad_left / 2
y = pad_top + height * row + height / 2 - ver_text_heights[row] / 2
- draw_texts(d, x, y, ver_texts[row])
+ draw_texts(d, x, y, ver_texts[row], fnt, fontsize)
return result
@@ -217,16 +230,32 @@ def draw_prompt_matrix(im, width, height, all_prompts):
return draw_grid_annotations(im, width, height, hor_texts, ver_texts)
-def resize_image(resize_mode, im, width, height):
+def resize_image(resize_mode, im, width, height, upscaler_name=None):
+ """
+ Resizes an image with the specified resize_mode, width, and height.
+
+ Args:
+ resize_mode: The mode to use when resizing the image.
+ 0: Resize the image to the specified width and height.
+ 1: Resize the image to fill the specified width and height, maintaining the aspect ratio, and then center the image within the dimensions, cropping the excess.
+ 2: Resize the image to fit within the specified width and height, maintaining the aspect ratio, and then center the image within the dimensions, filling empty with data from image.
+ im: The image to resize.
+ width: The width to resize the image to.
+ height: The height to resize the image to.
+ upscaler_name: The name of the upscaler to use. If not provided, defaults to opts.upscaler_for_img2img.
+ """
+
+ upscaler_name = upscaler_name or opts.upscaler_for_img2img
+
def resize(im, w, h):
- if opts.upscaler_for_img2img is None or opts.upscaler_for_img2img == "None" or im.mode == 'L':
+ if upscaler_name is None or upscaler_name == "None" or im.mode == 'L':
return im.resize((w, h), resample=LANCZOS)
scale = max(w / im.width, h / im.height)
if scale > 1.0:
- upscalers = [x for x in shared.sd_upscalers if x.name == opts.upscaler_for_img2img]
- assert len(upscalers) > 0, f"could not find upscaler named {opts.upscaler_for_img2img}"
+ upscalers = [x for x in shared.sd_upscalers if x.name == upscaler_name]
+ assert len(upscalers) > 0, f"could not find upscaler named {upscaler_name}"
upscaler = upscalers[0]
im = upscaler.scaler.upscale(im, scale, upscaler.data_path)
@@ -303,8 +332,9 @@ class FilenameGenerator:
'width': lambda self: self.image.width,
'height': lambda self: self.image.height,
'styles': lambda self: self.p and sanitize_filename_part(", ".join([style for style in self.p.styles if not style == "None"]) or "None", replace_spaces=False),
- 'sampler': lambda self: self.p and sanitize_filename_part(sd_samplers.samplers[self.p.sampler_index].name, replace_spaces=False),
+ 'sampler': lambda self: self.p and sanitize_filename_part(self.p.sampler_name, replace_spaces=False),
'model_hash': lambda self: getattr(self.p, "sd_model_hash", shared.sd_model.sd_model_hash),
+ 'model_name': lambda self: sanitize_filename_part(shared.sd_model.sd_checkpoint_info.model_name, replace_spaces=False),
'date': lambda self: datetime.datetime.now().strftime('%Y-%m-%d'),
'datetime': lambda self, *args: self.datetime(*args), # accepts formats: [datetime], [datetime<Format>], [datetime<Format><Time Zone>]
'job_timestamp': lambda self: getattr(self.p, "job_timestamp", shared.state.job_timestamp),
@@ -427,7 +457,7 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i
The directory to save the image. Note, the option `save_to_dirs` will make the image to be saved into a sub directory.
basename (`str`):
The base filename which will be applied to `filename pattern`.
- seed, prompt, short_filename,
+ seed, prompt, short_filename,
extension (`str`):
Image file extension, default is `png`.
pngsectionname (`str`):
@@ -499,30 +529,44 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i
image = params.image
fullfn = params.filename
info = params.pnginfo.get(pnginfo_section_name, None)
- fullfn_without_extension, extension = os.path.splitext(params.filename)
- def exif_bytes():
- return piexif.dump({
- "Exif": {
- piexif.ExifIFD.UserComment: piexif.helper.UserComment.dump(info or "", encoding="unicode")
- },
- })
+ def _atomically_save_image(image_to_save, filename_without_extension, extension):
+ # save image with .tmp extension to avoid race condition when another process detects new image in the directory
+ temp_file_path = filename_without_extension + ".tmp"
+ image_format = Image.registered_extensions()[extension]
- if extension.lower() == '.png':
- pnginfo_data = PngImagePlugin.PngInfo()
- if opts.enable_pnginfo:
- for k, v in params.pnginfo.items():
- pnginfo_data.add_text(k, str(v))
+ if extension.lower() == '.png':
+ pnginfo_data = PngImagePlugin.PngInfo()
+ if opts.enable_pnginfo:
+ for k, v in params.pnginfo.items():
+ pnginfo_data.add_text(k, str(v))
- image.save(fullfn, quality=opts.jpeg_quality, pnginfo=pnginfo_data)
+ image_to_save.save(temp_file_path, format=image_format, quality=opts.jpeg_quality, pnginfo=pnginfo_data)
- elif extension.lower() in (".jpg", ".jpeg", ".webp"):
- image.save(fullfn, quality=opts.jpeg_quality)
+ elif extension.lower() in (".jpg", ".jpeg", ".webp"):
+ if image_to_save.mode == 'RGBA':
+ image_to_save = image_to_save.convert("RGB")
- if opts.enable_pnginfo and info is not None:
- piexif.insert(exif_bytes(), fullfn)
- else:
- image.save(fullfn, quality=opts.jpeg_quality)
+ image_to_save.save(temp_file_path, format=image_format, quality=opts.jpeg_quality)
+
+ if opts.enable_pnginfo and info is not None:
+ exif_bytes = piexif.dump({
+ "Exif": {
+ piexif.ExifIFD.UserComment: piexif.helper.UserComment.dump(info or "", encoding="unicode")
+ },
+ })
+
+ piexif.insert(exif_bytes, temp_file_path)
+ else:
+ image_to_save.save(temp_file_path, format=image_format, quality=opts.jpeg_quality)
+
+ # atomically rename the file with correct extension
+ os.replace(temp_file_path, filename_without_extension + extension)
+
+ fullfn_without_extension, extension = os.path.splitext(params.filename)
+ _atomically_save_image(image, fullfn_without_extension, extension)
+
+ image.already_saved_as = fullfn
target_side_length = 4000
oversize = image.width > target_side_length or image.height > target_side_length
@@ -534,9 +578,7 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i
elif oversize:
image = image.resize((image.width * target_side_length // image.height, target_side_length), LANCZOS)
- image.save(fullfn_without_extension + ".jpg", quality=opts.jpeg_quality)
- if opts.enable_pnginfo and info is not None:
- piexif.insert(exif_bytes(), fullfn_without_extension + ".jpg")
+ _atomically_save_image(image, fullfn_without_extension, ".jpg")
if opts.save_txt and info is not None:
txt_fullfn = f"{fullfn_without_extension}.txt"
@@ -550,10 +592,45 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i
return fullfn, txt_fullfn
+def read_info_from_image(image):
+ items = image.info or {}
+
+ geninfo = items.pop('parameters', None)
+
+ if "exif" in items:
+ exif = piexif.load(items["exif"])
+ exif_comment = (exif or {}).get("Exif", {}).get(piexif.ExifIFD.UserComment, b'')
+ try:
+ exif_comment = piexif.helper.UserComment.load(exif_comment)
+ except ValueError:
+ exif_comment = exif_comment.decode('utf8', errors="ignore")
+
+ items['exif comment'] = exif_comment
+ geninfo = exif_comment
+
+ for field in ['jfif', 'jfif_version', 'jfif_unit', 'jfif_density', 'dpi', 'exif',
+ 'loop', 'background', 'timestamp', 'duration']:
+ items.pop(field, None)
+
+ if items.get("Software", None) == "NovelAI":
+ try:
+ json_info = json.loads(items["Comment"])
+ sampler = sd_samplers.samplers_map.get(json_info["sampler"], "Euler a")
+
+ geninfo = f"""{items["Description"]}
+Negative prompt: {json_info["uc"]}
+Steps: {json_info["steps"]}, Sampler: {sampler}, CFG scale: {json_info["scale"]}, Seed: {json_info["seed"]}, Size: {image.width}x{image.height}, Clip skip: 2, ENSD: 31337"""
+ except Exception:
+ print("Error parsing NovelAI image generation parameters:", file=sys.stderr)
+ print(traceback.format_exc(), file=sys.stderr)
+
+ return geninfo, items
+
+
def image_data(data):
try:
image = Image.open(io.BytesIO(data))
- textinfo = image.text["parameters"]
+ textinfo, _ = read_info_from_image(image)
return textinfo, None
except Exception:
pass
@@ -567,3 +644,14 @@ def image_data(data):
pass
return '', None
+
+
+def flatten(img, bgcolor):
+ """replaces transparency with bgcolor (example: "#ffffff"), returning an RGB mode image with no transparency"""
+
+ if img.mode == "RGBA":
+ background = Image.new('RGBA', img.size, bgcolor)
+ background.paste(img, mask=img)
+ img = background
+
+ return img.convert('RGB')
diff --git a/modules/img2img.py b/modules/img2img.py
index 35c5df9b..ca58b5d8 100644
--- a/modules/img2img.py
+++ b/modules/img2img.py
@@ -4,9 +4,9 @@ import sys
import traceback
import numpy as np
-from PIL import Image, ImageOps, ImageChops
+from PIL import Image, ImageOps, ImageFilter, ImageEnhance, ImageChops
-from modules import devices
+from modules import devices, sd_samplers
from modules.processing import Processed, StableDiffusionProcessingImg2Img, process_images
from modules.shared import opts, state
import modules.shared as shared
@@ -40,7 +40,7 @@ def process_batch(p, input_dir, output_dir, args):
img = Image.open(image)
# Use the EXIF orientation of photos taken by smartphones.
- img = ImageOps.exif_transpose(img)
+ img = ImageOps.exif_transpose(img)
p.init_images = [img] * p.batch_size
proc = modules.scripts.scripts_img2img.run(p, *args)
@@ -59,18 +59,31 @@ def process_batch(p, input_dir, output_dir, args):
processed_image.save(os.path.join(output_dir, filename))
-def img2img(mode: int, prompt: str, negative_prompt: str, prompt_style: str, prompt_style2: str, init_img, init_img_with_mask, init_img_inpaint, init_mask_inpaint, mask_mode, steps: int, sampler_index: int, mask_blur: int, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, *args):
+def img2img(mode: int, prompt: str, negative_prompt: str, prompt_style: str, prompt_style2: str, init_img, init_img_with_mask, init_img_with_mask_orig, init_img_inpaint, init_mask_inpaint, mask_mode, steps: int, sampler_index: int, mask_blur: int, mask_alpha: float, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, *args):
is_inpaint = mode == 1
is_batch = mode == 2
if is_inpaint:
# Drawn mask
if mask_mode == 0:
- image = init_img_with_mask['image']
- mask = init_img_with_mask['mask']
- alpha_mask = ImageOps.invert(image.split()[-1]).convert('L').point(lambda x: 255 if x > 0 else 0, mode='1')
- mask = ImageChops.lighter(alpha_mask, mask.convert('L')).convert('L')
- image = image.convert('RGB')
+ is_mask_sketch = isinstance(init_img_with_mask, dict)
+ is_mask_paint = not is_mask_sketch
+ if is_mask_sketch:
+ # Sketch: mask iff. not transparent
+ image, mask = init_img_with_mask["image"], init_img_with_mask["mask"]
+ alpha_mask = ImageOps.invert(image.split()[-1]).convert('L').point(lambda x: 255 if x > 0 else 0, mode='1')
+ mask = ImageChops.lighter(alpha_mask, mask.convert('L')).convert('L')
+ else:
+ # Color-sketch: mask iff. painted over
+ image = init_img_with_mask
+ orig = init_img_with_mask_orig or init_img_with_mask
+ pred = np.any(np.array(image) != np.array(orig), axis=-1)
+ mask = Image.fromarray(pred.astype(np.uint8) * 255, "L")
+ mask = ImageEnhance.Brightness(mask).enhance(1 - mask_alpha / 100)
+ blur = ImageFilter.GaussianBlur(mask_blur)
+ image = Image.composite(image.filter(blur), orig, mask.filter(blur))
+
+ image = image.convert("RGB")
# Uploaded mask
else:
image = init_img_inpaint
@@ -81,7 +94,8 @@ def img2img(mode: int, prompt: str, negative_prompt: str, prompt_style: str, pro
mask = None
# Use the EXIF orientation of photos taken by smartphones.
- image = ImageOps.exif_transpose(image)
+ if image is not None:
+ image = ImageOps.exif_transpose(image)
assert 0. <= denoising_strength <= 1., 'can only work with strength in [0.0, 1.0]'
@@ -98,7 +112,7 @@ def img2img(mode: int, prompt: str, negative_prompt: str, prompt_style: str, pro
seed_resize_from_h=seed_resize_from_h,
seed_resize_from_w=seed_resize_from_w,
seed_enable_extras=seed_enable_extras,
- sampler_index=sampler_index,
+ sampler_name=sd_samplers.samplers_for_img2img[sampler_index].name,
batch_size=batch_size,
n_iter=n_iter,
steps=steps,
@@ -137,6 +151,8 @@ def img2img(mode: int, prompt: str, negative_prompt: str, prompt_style: str, pro
if processed is None:
processed = process_images(p)
+ p.close()
+
shared.total_tqdm.clear()
generation_info_js = processed.js()
@@ -146,4 +162,4 @@ def img2img(mode: int, prompt: str, negative_prompt: str, prompt_style: str, pro
if opts.do_not_show_images:
processed.images = []
- return processed.images, generation_info_js, plaintext_to_html(processed.info)
+ return processed.images, generation_info_js, plaintext_to_html(processed.info), plaintext_to_html(processed.comments)
diff --git a/modules/import_hook.py b/modules/import_hook.py
new file mode 100644
index 00000000..28c67dfa
--- /dev/null
+++ b/modules/import_hook.py
@@ -0,0 +1,5 @@
+import sys
+
+# this will break any attempt to import xformers which will prevent stability diffusion repo from trying to use it
+if "--xformers" not in "".join(sys.argv):
+ sys.modules["xformers"] = None
diff --git a/modules/interrogate.py b/modules/interrogate.py
index 9769aa34..738d8ff7 100644
--- a/modules/interrogate.py
+++ b/modules/interrogate.py
@@ -1,4 +1,3 @@
-import contextlib
import os
import sys
import traceback
@@ -11,10 +10,9 @@ from torchvision import transforms
from torchvision.transforms.functional import InterpolationMode
import modules.shared as shared
-from modules import devices, paths, lowvram
+from modules import devices, paths, lowvram, modelloader
blip_image_eval_size = 384
-blip_model_url = 'https://storage.googleapis.com/sfr-vision-language-research/BLIP/models/model_base_caption_capfilt_large.pth'
clip_model_name = 'ViT-L/14'
Category = namedtuple("Category", ["name", "topn", "items"])
@@ -47,7 +45,14 @@ class InterrogateModels:
def load_blip_model(self):
import models.blip
- blip_model = models.blip.blip_decoder(pretrained=blip_model_url, image_size=blip_image_eval_size, vit='base', med_config=os.path.join(paths.paths["BLIP"], "configs", "med_config.json"))
+ files = modelloader.load_models(
+ model_path=os.path.join(paths.models_path, "BLIP"),
+ model_url='https://storage.googleapis.com/sfr-vision-language-research/BLIP/models/model_base_caption_capfilt_large.pth',
+ ext_filter=[".pth"],
+ download_name='model_base_caption_capfilt_large.pth',
+ )
+
+ blip_model = models.blip.blip_decoder(pretrained=files[0], image_size=blip_image_eval_size, vit='base', med_config=os.path.join(paths.paths["BLIP"], "configs", "med_config.json"))
blip_model.eval()
return blip_model
@@ -130,8 +135,9 @@ class InterrogateModels:
return caption[0]
def interrogate(self, pil_image):
- res = None
-
+ res = ""
+ shared.state.begin()
+ shared.state.job = 'interrogate'
try:
if shared.cmd_opts.lowvram or shared.cmd_opts.medvram:
@@ -148,8 +154,7 @@ class InterrogateModels:
clip_image = self.clip_preprocess(pil_image).unsqueeze(0).type(self.dtype).to(devices.device_interrogate)
- precision_scope = torch.autocast if shared.cmd_opts.precision == "autocast" else contextlib.nullcontext
- with torch.no_grad(), precision_scope("cuda"):
+ with torch.no_grad(), devices.autocast():
image_features = self.clip_model.encode_image(clip_image).type(self.dtype)
image_features /= image_features.norm(dim=-1, keepdim=True)
@@ -168,10 +173,11 @@ class InterrogateModels:
res += ", " + match
except Exception:
- print(f"Error interrogating", file=sys.stderr)
+ print("Error interrogating", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
res += "<error>"
self.unload()
+ shared.state.end()
return res
diff --git a/modules/localization.py b/modules/localization.py
index b1810cda..f6a6f2fb 100644
--- a/modules/localization.py
+++ b/modules/localization.py
@@ -3,6 +3,7 @@ import os
import sys
import traceback
+
localizations = {}
@@ -16,6 +17,11 @@ def list_localizations(dirname):
localizations[fn] = os.path.join(dirname, file)
+ from modules import scripts
+ for file in scripts.list_scripts("localizations", ".json"):
+ fn, ext = os.path.splitext(file.filename)
+ localizations[fn] = file.path
+
def localization_js(current_localization_name):
fn = localizations.get(current_localization_name, None)
diff --git a/modules/lowvram.py b/modules/lowvram.py
index a4652cb1..042a0254 100644
--- a/modules/lowvram.py
+++ b/modules/lowvram.py
@@ -51,20 +51,30 @@ def setup_for_low_vram(sd_model, use_medvram):
send_me_to_gpu(first_stage_model, None)
return first_stage_model_decode(z)
- # remove three big modules, cond, first_stage, and unet from the model and then
+ # for SD1, cond_stage_model is CLIP and its NN is in the tranformer frield, but for SD2, it's open clip, and it's in model field
+ if hasattr(sd_model.cond_stage_model, 'model'):
+ sd_model.cond_stage_model.transformer = sd_model.cond_stage_model.model
+
+ # remove four big modules, cond, first_stage, depth (if applicable), and unet from the model and then
# send the model to GPU. Then put modules back. the modules will be in CPU.
- stored = sd_model.cond_stage_model.transformer, sd_model.first_stage_model, sd_model.model
- sd_model.cond_stage_model.transformer, sd_model.first_stage_model, sd_model.model = None, None, None
+ stored = sd_model.cond_stage_model.transformer, sd_model.first_stage_model, getattr(sd_model, 'depth_model', None), sd_model.model
+ sd_model.cond_stage_model.transformer, sd_model.first_stage_model, sd_model.depth_model, sd_model.model = None, None, None, None
sd_model.to(devices.device)
- sd_model.cond_stage_model.transformer, sd_model.first_stage_model, sd_model.model = stored
+ sd_model.cond_stage_model.transformer, sd_model.first_stage_model, sd_model.depth_model, sd_model.model = stored
- # register hooks for those the first two models
+ # register hooks for those the first three models
sd_model.cond_stage_model.transformer.register_forward_pre_hook(send_me_to_gpu)
sd_model.first_stage_model.register_forward_pre_hook(send_me_to_gpu)
sd_model.first_stage_model.encode = first_stage_model_encode_wrap
sd_model.first_stage_model.decode = first_stage_model_decode_wrap
+ if sd_model.depth_model:
+ sd_model.depth_model.register_forward_pre_hook(send_me_to_gpu)
parents[sd_model.cond_stage_model.transformer] = sd_model.cond_stage_model
+ if hasattr(sd_model.cond_stage_model, 'model'):
+ sd_model.cond_stage_model.model = sd_model.cond_stage_model.transformer
+ del sd_model.cond_stage_model.transformer
+
if use_medvram:
sd_model.model.register_forward_pre_hook(send_me_to_gpu)
else:
diff --git a/modules/masking.py b/modules/masking.py
index fd8d9241..a5c4d2da 100644
--- a/modules/masking.py
+++ b/modules/masking.py
@@ -49,7 +49,7 @@ def expand_crop_region(crop_region, processing_width, processing_height, image_w
ratio_processing = processing_width / processing_height
if ratio_crop_region > ratio_processing:
- desired_height = (x2 - x1) * ratio_processing
+ desired_height = (x2 - x1) / ratio_processing
desired_height_diff = int(desired_height - (y2-y1))
y1 -= desired_height_diff//2
y2 += desired_height_diff - desired_height_diff//2
diff --git a/modules/memmon.py b/modules/memmon.py
index 9fb9b687..a7060f58 100644
--- a/modules/memmon.py
+++ b/modules/memmon.py
@@ -71,10 +71,13 @@ class MemUsageMonitor(threading.Thread):
def read(self):
if not self.disabled:
free, total = torch.cuda.mem_get_info()
+ self.data["free"] = free
self.data["total"] = total
torch_stats = torch.cuda.memory_stats(self.device)
+ self.data["active"] = torch_stats["active.all.current"]
self.data["active_peak"] = torch_stats["active_bytes.all.peak"]
+ self.data["reserved"] = torch_stats["reserved_bytes.all.current"]
self.data["reserved_peak"] = torch_stats["reserved_bytes.all.peak"]
self.data["system_peak"] = total - self.data["min_free"]
diff --git a/modules/modelloader.py b/modules/modelloader.py
index b0f2f33d..6a1a7ac8 100644
--- a/modules/modelloader.py
+++ b/modules/modelloader.py
@@ -82,9 +82,13 @@ def cleanup_models():
src_path = models_path
dest_path = os.path.join(models_path, "Stable-diffusion")
move_files(src_path, dest_path, ".ckpt")
+ move_files(src_path, dest_path, ".safetensors")
src_path = os.path.join(root_path, "ESRGAN")
dest_path = os.path.join(models_path, "ESRGAN")
move_files(src_path, dest_path)
+ src_path = os.path.join(models_path, "BSRGAN")
+ dest_path = os.path.join(models_path, "ESRGAN")
+ move_files(src_path, dest_path, ".pth")
src_path = os.path.join(root_path, "gfpgan")
dest_path = os.path.join(models_path, "GFPGAN")
move_files(src_path, dest_path)
@@ -119,11 +123,27 @@ def move_files(src_path: str, dest_path: str, ext_filter: str = None):
pass
+builtin_upscaler_classes = []
+forbidden_upscaler_classes = set()
+
+
+def list_builtin_upscalers():
+ load_upscalers()
+
+ builtin_upscaler_classes.clear()
+ builtin_upscaler_classes.extend(Upscaler.__subclasses__())
+
+
+def forbid_loaded_nonbuiltin_upscalers():
+ for cls in Upscaler.__subclasses__():
+ if cls not in builtin_upscaler_classes:
+ forbidden_upscaler_classes.add(cls)
+
+
def load_upscalers():
- sd = shared.script_path
# We can only do this 'magic' method to dynamically load upscalers if they are referenced,
# so we'll try to import any _model.py files before looking in __subclasses__
- modules_dir = os.path.join(sd, "modules")
+ modules_dir = os.path.join(shared.script_path, "modules")
for file in os.listdir(modules_dir):
if "_model.py" in file:
model_name = file.replace("_model.py", "")
@@ -132,22 +152,16 @@ def load_upscalers():
importlib.import_module(full_model)
except:
pass
+
datas = []
- c_o = vars(shared.cmd_opts)
+ commandline_options = vars(shared.cmd_opts)
for cls in Upscaler.__subclasses__():
+ if cls in forbidden_upscaler_classes:
+ continue
+
name = cls.__name__
- module_name = cls.__module__
- module = importlib.import_module(module_name)
- class_ = getattr(module, name)
cmd_name = f"{name.lower().replace('upscaler', '')}_models_path"
- opt_string = None
- try:
- if cmd_name in c_o:
- opt_string = c_o[cmd_name]
- except:
- pass
- scaler = class_(opt_string)
- for child in scaler.scalers:
- datas.append(child)
+ scaler = cls(commandline_options.get(cmd_name, None))
+ datas += scaler.scalers
shared.sd_upscalers = datas
diff --git a/modules/ngrok.py b/modules/ngrok.py
index 5c5f349a..3df2c06b 100644
--- a/modules/ngrok.py
+++ b/modules/ngrok.py
@@ -1,14 +1,23 @@
from pyngrok import ngrok, conf, exception
-
def connect(token, port, region):
- if token == None:
+ account = None
+ if token is None:
token = 'None'
+ else:
+ if ':' in token:
+ # token = authtoken:username:password
+ account = token.split(':')[1] + ':' + token.split(':')[-1]
+ token = token.split(':')[0]
+
config = conf.PyngrokConfig(
auth_token=token, region=region
)
try:
- public_url = ngrok.connect(port, pyngrok_config=config).public_url
+ if account is None:
+ public_url = ngrok.connect(port, pyngrok_config=config, bind_tls=True).public_url
+ else:
+ public_url = ngrok.connect(port, pyngrok_config=config, bind_tls=True, auth=account).public_url
except exception.PyngrokNgrokError:
print(f'Invalid ngrok authtoken, ngrok connection aborted.\n'
f'Your token: {token}, get the right one on https://dashboard.ngrok.com/get-started/your-authtoken')
diff --git a/modules/paths.py b/modules/paths.py
index 1e7a2fbc..4dd03a35 100644
--- a/modules/paths.py
+++ b/modules/paths.py
@@ -9,7 +9,7 @@ sys.path.insert(0, script_path)
# search for directory of stable diffusion in following places
sd_path = None
-possible_sd_paths = [os.path.join(script_path, 'repositories/stable-diffusion'), '.', os.path.dirname(script_path)]
+possible_sd_paths = [os.path.join(script_path, 'repositories/stable-diffusion-stability-ai'), '.', os.path.dirname(script_path)]
for possible_sd_path in possible_sd_paths:
if os.path.exists(os.path.join(possible_sd_path, 'ldm/models/diffusion/ddpm.py')):
sd_path = os.path.abspath(possible_sd_path)
diff --git a/modules/processing.py b/modules/processing.py
index 57d3a523..c03e77e7 100644
--- a/modules/processing.py
+++ b/modules/processing.py
@@ -2,6 +2,7 @@ import json
import math
import os
import sys
+import warnings
import torch
import numpy as np
@@ -12,15 +13,21 @@ from skimage import exposure
from typing import Any, Dict, List, Optional
import modules.sd_hijack
-from modules import devices, prompt_parser, masking, sd_samplers, lowvram, generation_parameters_copypaste
+from modules import devices, prompt_parser, masking, sd_samplers, lowvram, generation_parameters_copypaste, script_callbacks
from modules.sd_hijack import model_hijack
from modules.shared import opts, cmd_opts, state
import modules.shared as shared
import modules.face_restoration
import modules.images as images
import modules.styles
+import modules.sd_models as sd_models
+import modules.sd_vae as sd_vae
import logging
+from ldm.data.util import AddMiDaS
+from ldm.models.diffusion.ddpm import LatentDepth2ImageDiffusion
+from einops import repeat, rearrange
+from blendmodes.blend import blendLayers, BlendType
# some of those options should not be changed at all because they would break the model, so I removed them from options.
opt_C = 4
@@ -33,17 +40,19 @@ def setup_color_correction(image):
return correction_target
-def apply_color_correction(correction, image):
+def apply_color_correction(correction, original_image):
logging.info("Applying color correction.")
image = Image.fromarray(cv2.cvtColor(exposure.match_histograms(
cv2.cvtColor(
- np.asarray(image),
+ np.asarray(original_image),
cv2.COLOR_RGB2LAB
),
correction,
channel_axis=2
), cv2.COLOR_LAB2RGB).astype("uint8"))
-
+
+ image = blendLayers(image, original_image, BlendType.LUMINOSITY)
+
return image
@@ -66,19 +75,15 @@ def apply_overlay(image, paste_loc, index, overlays):
return image
-def get_correct_sampler(p):
- if isinstance(p, modules.processing.StableDiffusionProcessingTxt2Img):
- return sd_samplers.samplers
- elif isinstance(p, modules.processing.StableDiffusionProcessingImg2Img):
- return sd_samplers.samplers_for_img2img
- elif isinstance(p, modules.api.processing.StableDiffusionProcessingAPI):
- return sd_samplers.samplers
class StableDiffusionProcessing():
"""
The first set of paramaters: sd_models -> do_not_reload_embeddings represent the minimum required to create a StableDiffusionProcessing
"""
- def __init__(self, sd_model=None, outpath_samples=None, outpath_grids=None, prompt: str = "", styles: List[str] = None, seed: int = -1, subseed: int = -1, subseed_strength: float = 0, seed_resize_from_h: int = -1, seed_resize_from_w: int = -1, seed_enable_extras: bool = True, sampler_index: int = 0, batch_size: int = 1, n_iter: int = 1, steps: int = 50, cfg_scale: float = 7.0, width: int = 512, height: int = 512, restore_faces: bool = False, tiling: bool = False, do_not_save_samples: bool = False, do_not_save_grid: bool = False, extra_generation_params: Dict[Any, Any] = None, overlay_images: Any = None, negative_prompt: str = None, eta: float = None, do_not_reload_embeddings: bool = False, denoising_strength: float = 0, ddim_discretize: str = None, s_churn: float = 0.0, s_tmax: float = None, s_tmin: float = 0.0, s_noise: float = 1.0, override_settings: Dict[str, Any] = None):
+ def __init__(self, sd_model=None, outpath_samples=None, outpath_grids=None, prompt: str = "", styles: List[str] = None, seed: int = -1, subseed: int = -1, subseed_strength: float = 0, seed_resize_from_h: int = -1, seed_resize_from_w: int = -1, seed_enable_extras: bool = True, sampler_name: str = None, batch_size: int = 1, n_iter: int = 1, steps: int = 50, cfg_scale: float = 7.0, width: int = 512, height: int = 512, restore_faces: bool = False, tiling: bool = False, do_not_save_samples: bool = False, do_not_save_grid: bool = False, extra_generation_params: Dict[Any, Any] = None, overlay_images: Any = None, negative_prompt: str = None, eta: float = None, do_not_reload_embeddings: bool = False, denoising_strength: float = 0, ddim_discretize: str = None, s_churn: float = 0.0, s_tmax: float = None, s_tmin: float = 0.0, s_noise: float = 1.0, override_settings: Dict[str, Any] = None, override_settings_restore_afterwards: bool = True, sampler_index: int = None):
+ if sampler_index is not None:
+ print("sampler_index argument for StableDiffusionProcessing does not do anything; use sampler_name", file=sys.stderr)
+
self.sd_model = sd_model
self.outpath_samples: str = outpath_samples
self.outpath_grids: str = outpath_grids
@@ -91,7 +96,7 @@ class StableDiffusionProcessing():
self.subseed_strength: float = subseed_strength
self.seed_resize_from_h: int = seed_resize_from_h
self.seed_resize_from_w: int = seed_resize_from_w
- self.sampler_index: int = sampler_index
+ self.sampler_name: str = sampler_name
self.batch_size: int = batch_size
self.n_iter: int = n_iter
self.steps: int = steps
@@ -116,6 +121,8 @@ class StableDiffusionProcessing():
self.s_tmax = s_tmax or float('inf') # not representable as a standard ui option
self.s_noise = s_noise or opts.s_noise
self.override_settings = {k: v for k, v in (override_settings or {}).items() if k not in shared.restricted_opts}
+ self.override_settings_restore_afterwards = override_settings_restore_afterwards
+ self.is_using_inpainting_conditioning = False
if not seed_enable_extras:
self.subseed = -1
@@ -126,41 +133,54 @@ class StableDiffusionProcessing():
self.scripts = None
self.script_args = None
self.all_prompts = None
+ self.all_negative_prompts = None
self.all_seeds = None
self.all_subseeds = None
+ self.iteration = 0
def txt2img_image_conditioning(self, x, width=None, height=None):
if self.sampler.conditioning_key not in {'hybrid', 'concat'}:
# Dummy zero conditioning if we're not using inpainting model.
# Still takes up a bit of memory, but no encoder call.
# Pretty sure we can just make this a 1x1 image since its not going to be used besides its batch size.
- return torch.zeros(
- x.shape[0], 5, 1, 1,
- dtype=x.dtype,
- device=x.device
- )
+ return x.new_zeros(x.shape[0], 5, 1, 1)
+
+ self.is_using_inpainting_conditioning = True
height = height or self.height
width = width or self.width
# The "masked-image" in this case will just be all zeros since the entire image is masked.
image_conditioning = torch.zeros(x.shape[0], 3, height, width, device=x.device)
- image_conditioning = self.sd_model.get_first_stage_encoding(self.sd_model.encode_first_stage(image_conditioning))
+ image_conditioning = self.sd_model.get_first_stage_encoding(self.sd_model.encode_first_stage(image_conditioning))
# Add the fake full 1s mask to the first dimension.
image_conditioning = torch.nn.functional.pad(image_conditioning, (0, 0, 0, 0, 1, 0), value=1.0)
- image_conditioning = image_conditioning.to(x.dtype)
+ image_conditioning = image_conditioning.to(x.dtype)
return image_conditioning
- def img2img_image_conditioning(self, source_image, latent_image, image_mask = None):
- if self.sampler.conditioning_key not in {'hybrid', 'concat'}:
- # Dummy zero conditioning if we're not using inpainting model.
- return torch.zeros(
- latent_image.shape[0], 5, 1, 1,
- dtype=latent_image.dtype,
- device=latent_image.device
- )
+ def depth2img_image_conditioning(self, source_image):
+ # Use the AddMiDaS helper to Format our source image to suit the MiDaS model
+ transformer = AddMiDaS(model_type="dpt_hybrid")
+ transformed = transformer({"jpg": rearrange(source_image[0], "c h w -> h w c")})
+ midas_in = torch.from_numpy(transformed["midas_in"][None, ...]).to(device=shared.device)
+ midas_in = repeat(midas_in, "1 ... -> n ...", n=self.batch_size)
+
+ conditioning_image = self.sd_model.get_first_stage_encoding(self.sd_model.encode_first_stage(source_image))
+ conditioning = torch.nn.functional.interpolate(
+ self.sd_model.depth_model(midas_in),
+ size=conditioning_image.shape[2:],
+ mode="bicubic",
+ align_corners=False,
+ )
+
+ (depth_min, depth_max) = torch.aminmax(conditioning)
+ conditioning = 2. * (conditioning - depth_min) / (depth_max - depth_min) - 1.
+ return conditioning
+
+ def inpainting_image_conditioning(self, source_image, latent_image, image_mask = None):
+ self.is_using_inpainting_conditioning = True
# Handle the different mask inputs
if image_mask is not None:
@@ -174,17 +194,17 @@ class StableDiffusionProcessing():
# Inpainting model uses a discretized mask as input, so we round to either 1.0 or 0.0
conditioning_mask = torch.round(conditioning_mask)
else:
- conditioning_mask = torch.ones(1, 1, *source_image.shape[-2:])
+ conditioning_mask = source_image.new_ones(1, 1, *source_image.shape[-2:])
# Create another latent image, this time with a masked version of the original input.
# Smoothly interpolate between the masked and unmasked latent conditioning image using a parameter.
- conditioning_mask = conditioning_mask.to(source_image.device)
+ conditioning_mask = conditioning_mask.to(source_image.device).to(source_image.dtype)
conditioning_image = torch.lerp(
source_image,
source_image * (1.0 - conditioning_mask),
getattr(self, "inpainting_mask_weight", shared.opts.inpainting_mask_weight)
)
-
+
# Encode the new masked image using first stage of network.
conditioning_image = self.sd_model.get_first_stage_encoding(self.sd_model.encode_first_stage(conditioning_image))
@@ -196,15 +216,31 @@ class StableDiffusionProcessing():
return image_conditioning
+ def img2img_image_conditioning(self, source_image, latent_image, image_mask=None):
+ # HACK: Using introspection as the Depth2Image model doesn't appear to uniquely
+ # identify itself with a field common to all models. The conditioning_key is also hybrid.
+ if isinstance(self.sd_model, LatentDepth2ImageDiffusion):
+ return self.depth2img_image_conditioning(source_image)
+
+ if self.sampler.conditioning_key in {'hybrid', 'concat'}:
+ return self.inpainting_image_conditioning(source_image, latent_image, image_mask=image_mask)
+
+ # Dummy zero conditioning if we're not using inpainting or depth model.
+ return latent_image.new_zeros(latent_image.shape[0], 5, 1, 1)
+
def init(self, all_prompts, all_seeds, all_subseeds):
pass
- def sample(self, conditioning, unconditional_conditioning, seeds, subseeds, subseed_strength):
+ def sample(self, conditioning, unconditional_conditioning, seeds, subseeds, subseed_strength, prompts):
raise NotImplementedError()
+ def close(self):
+ self.sd_model = None
+ self.sampler = None
+
class Processed:
- def __init__(self, p: StableDiffusionProcessing, images_list, seed=-1, info="", subseed=None, all_prompts=None, all_seeds=None, all_subseeds=None, index_of_first_image=0, infotexts=None):
+ def __init__(self, p: StableDiffusionProcessing, images_list, seed=-1, info="", subseed=None, all_prompts=None, all_negative_prompts=None, all_seeds=None, all_subseeds=None, index_of_first_image=0, infotexts=None, comments=""):
self.images = images_list
self.prompt = p.prompt
self.negative_prompt = p.negative_prompt
@@ -212,10 +248,10 @@ class Processed:
self.subseed = subseed
self.subseed_strength = p.subseed_strength
self.info = info
+ self.comments = comments
self.width = p.width
self.height = p.height
- self.sampler_index = p.sampler_index
- self.sampler = sd_samplers.samplers[p.sampler_index].name
+ self.sampler_name = p.sampler_name
self.cfg_scale = p.cfg_scale
self.steps = p.steps
self.batch_size = p.batch_size
@@ -242,17 +278,20 @@ class Processed:
self.negative_prompt = self.negative_prompt if type(self.negative_prompt) != list else self.negative_prompt[0]
self.seed = int(self.seed if type(self.seed) != list else self.seed[0]) if self.seed is not None else -1
self.subseed = int(self.subseed if type(self.subseed) != list else self.subseed[0]) if self.subseed is not None else -1
+ self.is_using_inpainting_conditioning = p.is_using_inpainting_conditioning
- self.all_prompts = all_prompts or [self.prompt]
- self.all_seeds = all_seeds or [self.seed]
- self.all_subseeds = all_subseeds or [self.subseed]
+ self.all_prompts = all_prompts or p.all_prompts or [self.prompt]
+ self.all_negative_prompts = all_negative_prompts or p.all_negative_prompts or [self.negative_prompt]
+ self.all_seeds = all_seeds or p.all_seeds or [self.seed]
+ self.all_subseeds = all_subseeds or p.all_subseeds or [self.subseed]
self.infotexts = infotexts or [info]
def js(self):
obj = {
- "prompt": self.prompt,
+ "prompt": self.all_prompts[0],
"all_prompts": self.all_prompts,
- "negative_prompt": self.negative_prompt,
+ "negative_prompt": self.all_negative_prompts[0],
+ "all_negative_prompts": self.all_negative_prompts,
"seed": self.seed,
"all_seeds": self.all_seeds,
"subseed": self.subseed,
@@ -260,8 +299,7 @@ class Processed:
"subseed_strength": self.subseed_strength,
"width": self.width,
"height": self.height,
- "sampler_index": self.sampler_index,
- "sampler": self.sampler,
+ "sampler_name": self.sampler_name,
"cfg_scale": self.cfg_scale,
"steps": self.steps,
"batch_size": self.batch_size,
@@ -277,11 +315,12 @@ class Processed:
"styles": self.styles,
"job_timestamp": self.job_timestamp,
"clip_skip": self.clip_skip,
+ "is_using_inpainting_conditioning": self.is_using_inpainting_conditioning,
}
return json.dumps(obj)
- def infotext(self, p: StableDiffusionProcessing, index):
+ def infotext(self, p: StableDiffusionProcessing, index):
return create_infotext(p, self.all_prompts, self.all_seeds, self.all_subseeds, comments=[], position_in_batch=index % self.batch_size, iteration=index // self.batch_size)
@@ -301,13 +340,14 @@ def slerp(val, low, high):
def create_random_tensors(shape, seeds, subseeds=None, subseed_strength=0.0, seed_resize_from_h=0, seed_resize_from_w=0, p=None):
+ eta_noise_seed_delta = opts.eta_noise_seed_delta or 0
xs = []
# if we have multiple seeds, this means we are working with batch size>1; this then
# enables the generation of additional tensors with noise that the sampler will use during its processing.
# Using those pre-generated tensors instead of simple torch.randn allows a batch with seeds [100, 101] to
# produce the same images as with two batches [100], [101].
- if p is not None and p.sampler is not None and (len(seeds) > 1 and opts.enable_batch_seeds or opts.eta_noise_seed_delta > 0):
+ if p is not None and p.sampler is not None and (len(seeds) > 1 and opts.enable_batch_seeds or eta_noise_seed_delta > 0):
sampler_noises = [[] for _ in range(p.sampler.number_of_needed_noises(p))]
else:
sampler_noises = None
@@ -347,8 +387,8 @@ def create_random_tensors(shape, seeds, subseeds=None, subseed_strength=0.0, see
if sampler_noises is not None:
cnt = p.sampler.number_of_needed_noises(p)
- if opts.eta_noise_seed_delta > 0:
- torch.manual_seed(seed + opts.eta_noise_seed_delta)
+ if eta_noise_seed_delta > 0:
+ torch.manual_seed(seed + eta_noise_seed_delta)
for j in range(cnt):
sampler_noises[j].append(devices.randn_without_seed(tuple(noise_shape)))
@@ -388,7 +428,7 @@ def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments, iteration
generation_params = {
"Steps": p.steps,
- "Sampler": get_correct_sampler(p)[p.sampler_index].name,
+ "Sampler": p.sampler_name,
"CFG scale": p.cfg_scale,
"Seed": all_seeds[index],
"Face restoration": (opts.face_restoration_model if p.restore_faces else None),
@@ -396,6 +436,7 @@ def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments, iteration
"Model hash": getattr(p, 'sd_model_hash', None if not opts.add_model_hash_to_info or not shared.sd_model.sd_model_hash else shared.sd_model.sd_model_hash),
"Model": (None if not opts.add_model_name_to_info or not shared.sd_model.sd_checkpoint_info.model_name else shared.sd_model.sd_checkpoint_info.model_name.replace(',', '').replace(':', '')),
"Hypernet": (None if shared.loaded_hypernetwork is None else shared.loaded_hypernetwork.name),
+ "Hypernet hash": (None if shared.loaded_hypernetwork is None else sd_models.model_hash(shared.loaded_hypernetwork.filename)),
"Hypernet strength": (None if shared.loaded_hypernetwork is None or shared.opts.sd_hypernetwork_strength >= 1 else shared.opts.sd_hypernetwork_strength),
"Batch size": (None if p.batch_size < 2 else p.batch_size),
"Batch pos": (None if p.batch_size < 2 else position_in_batch),
@@ -403,6 +444,7 @@ def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments, iteration
"Variation seed strength": (None if p.subseed_strength == 0 else p.subseed_strength),
"Seed resize from": (None if p.seed_resize_from_w == 0 or p.seed_resize_from_h == 0 else f"{p.seed_resize_from_w}x{p.seed_resize_from_h}"),
"Denoising strength": getattr(p, 'denoising_strength', None),
+ "Conditional mask weight": getattr(p, "inpainting_mask_weight", shared.opts.inpainting_mask_weight) if p.is_using_inpainting_conditioning else None,
"Eta": (None if p.sampler is None or p.sampler.eta == p.sampler.default_eta else p.sampler.eta),
"Clip skip": None if clip_skip <= 1 else clip_skip,
"ENSD": None if opts.eta_noise_seed_delta == 0 else opts.eta_noise_seed_delta,
@@ -412,7 +454,7 @@ def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments, iteration
generation_params_text = ", ".join([k if k == v else f'{k}: {generation_parameters_copypaste.quote(v)}' for k, v in generation_params.items() if v is not None])
- negative_prompt_text = "\nNegative prompt: " + p.negative_prompt if p.negative_prompt else ""
+ negative_prompt_text = "\nNegative prompt: " + p.all_negative_prompts[index] if p.all_negative_prompts[index] else ""
return f"{all_prompts[index]}{negative_prompt_text}\n{generation_params_text}".strip()
@@ -422,13 +464,21 @@ def process_images(p: StableDiffusionProcessing) -> Processed:
try:
for k, v in p.override_settings.items():
- opts.data[k] = v # we don't call onchange for simplicity which makes changing model, hypernet impossible
+ setattr(opts, k, v)
+ if k == 'sd_hypernetwork': shared.reload_hypernetworks() # make onchange call for changing hypernet
+ if k == 'sd_model_checkpoint': sd_models.reload_model_weights() # make onchange call for changing SD model
+ if k == 'sd_vae': sd_vae.reload_vae_weights() # make onchange call for changing VAE
res = process_images_inner(p)
finally:
- for k, v in stored_opts.items():
- opts.data[k] = v
+ # restore opts to original state
+ if p.override_settings_restore_afterwards:
+ for k, v in stored_opts.items():
+ setattr(opts, k, v)
+ if k == 'sd_hypernetwork': shared.reload_hypernetworks()
+ if k == 'sd_model_checkpoint': sd_models.reload_model_weights()
+ if k == 'sd_vae': sd_vae.reload_vae_weights()
return res
@@ -441,10 +491,6 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
else:
assert p.prompt is not None
- with open(os.path.join(shared.script_path, "params.txt"), "w", encoding="utf8") as file:
- processed = Processed(p, [], p.seed, "")
- file.write(processed.infotext(p, 0))
-
devices.torch_gc()
seed = get_fixed_seed(p.seed)
@@ -455,12 +501,15 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
comments = {}
- shared.prompt_styles.apply_styles(p)
-
if type(p.prompt) == list:
- p.all_prompts = p.prompt
+ p.all_prompts = [shared.prompt_styles.apply_styles_to_prompt(x, p.styles) for x in p.prompt]
+ else:
+ p.all_prompts = p.batch_size * p.n_iter * [shared.prompt_styles.apply_styles_to_prompt(p.prompt, p.styles)]
+
+ if type(p.negative_prompt) == list:
+ p.all_negative_prompts = [shared.prompt_styles.apply_negative_styles_to_prompt(x, p.styles) for x in p.negative_prompt]
else:
- p.all_prompts = p.batch_size * p.n_iter * [p.prompt]
+ p.all_negative_prompts = p.batch_size * p.n_iter * [shared.prompt_styles.apply_negative_styles_to_prompt(p.negative_prompt, p.styles)]
if type(seed) == list:
p.all_seeds = seed
@@ -475,6 +524,10 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
def infotext(iteration=0, position_in_batch=0):
return create_infotext(p, p.all_prompts, p.all_seeds, p.all_subseeds, comments, iteration, position_in_batch)
+ with open(os.path.join(shared.script_path, "params.txt"), "w", encoding="utf8") as file:
+ processed = Processed(p, [], p.seed, "")
+ file.write(processed.infotext(p, 0))
+
if os.path.exists(cmd_opts.embeddings_dir) and not p.do_not_reload_embeddings:
model_hijack.embedding_db.load_textual_inversion_embeddings()
@@ -492,21 +545,27 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
state.job_count = p.n_iter
for n in range(p.n_iter):
+ p.iteration = n
+
if state.skipped:
state.skipped = False
-
+
if state.interrupted:
break
prompts = p.all_prompts[n * p.batch_size:(n + 1) * p.batch_size]
+ negative_prompts = p.all_negative_prompts[n * p.batch_size:(n + 1) * p.batch_size]
seeds = p.all_seeds[n * p.batch_size:(n + 1) * p.batch_size]
subseeds = p.all_subseeds[n * p.batch_size:(n + 1) * p.batch_size]
if len(prompts) == 0:
break
+ if p.scripts is not None:
+ p.scripts.process_batch(p, batch_number=n, prompts=prompts, seeds=seeds, subseeds=subseeds)
+
with devices.autocast():
- uc = prompt_parser.get_learned_conditioning(shared.sd_model, len(prompts) * [p.negative_prompt], p.steps)
+ uc = prompt_parser.get_learned_conditioning(shared.sd_model, negative_prompts, p.steps)
c = prompt_parser.get_multicond_learned_conditioning(shared.sd_model, prompts, p.steps)
if len(model_hijack.comments) > 0:
@@ -517,10 +576,10 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
shared.state.job = f"Batch {n+1} out of {p.n_iter}"
with devices.autocast():
- samples_ddim = p.sample(conditioning=c, unconditional_conditioning=uc, seeds=seeds, subseeds=subseeds, subseed_strength=p.subseed_strength)
+ samples_ddim = p.sample(conditioning=c, unconditional_conditioning=uc, seeds=seeds, subseeds=subseeds, subseed_strength=p.subseed_strength, prompts=prompts)
- samples_ddim = samples_ddim.to(devices.dtype_vae)
- x_samples_ddim = decode_first_stage(p.sd_model, samples_ddim)
+ x_samples_ddim = [decode_first_stage(p.sd_model, samples_ddim[i:i+1].to(dtype=devices.dtype_vae))[0].cpu() for i in range(samples_ddim.size(0))]
+ x_samples_ddim = torch.stack(x_samples_ddim).float()
x_samples_ddim = torch.clamp((x_samples_ddim + 1.0) / 2.0, min=0.0, max=1.0)
del samples_ddim
@@ -530,9 +589,8 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
devices.torch_gc()
- if opts.filter_nsfw:
- import modules.safety as safety
- x_samples_ddim = modules.safety.censor_batch(x_samples_ddim)
+ if p.scripts is not None:
+ p.scripts.postprocess_batch(p, x_samples_ddim, batch_number=n)
for i, x_sample in enumerate(x_samples_ddim):
x_sample = 255. * np.moveaxis(x_sample.cpu().numpy(), 0, 2)
@@ -566,7 +624,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
image.info["parameters"] = text
output_images.append(image)
- del x_samples_ddim
+ del x_samples_ddim
devices.torch_gc()
@@ -592,28 +650,29 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
devices.torch_gc()
- res = Processed(p, output_images, p.all_seeds[0], infotext() + "".join(["\n\n" + x for x in comments]), subseed=p.all_subseeds[0], all_prompts=p.all_prompts, all_seeds=p.all_seeds, all_subseeds=p.all_subseeds, index_of_first_image=index_of_first_image, infotexts=infotexts)
+ res = Processed(p, output_images, p.all_seeds[0], infotext(), comments="".join(["\n\n" + x for x in comments]), subseed=p.all_subseeds[0], index_of_first_image=index_of_first_image, infotexts=infotexts)
if p.scripts is not None:
p.scripts.postprocess(p, res)
- p.sd_model = None
- p.sampler = None
-
return res
class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
sampler = None
- def __init__(self, enable_hr: bool=False, denoising_strength: float=0.75, firstphase_width: int=0, firstphase_height: int=0, **kwargs):
+ def __init__(self, enable_hr: bool = False, denoising_strength: float = 0.75, firstphase_width: int = 0, firstphase_height: int = 0, hr_scale: float = 2.0, hr_upscaler: str = None, **kwargs):
super().__init__(**kwargs)
self.enable_hr = enable_hr
self.denoising_strength = denoising_strength
- self.firstphase_width = firstphase_width
- self.firstphase_height = firstphase_height
- self.truncate_x = 0
- self.truncate_y = 0
+ self.hr_scale = hr_scale
+ self.hr_upscaler = hr_upscaler
+
+ if firstphase_width != 0 or firstphase_height != 0:
+ print("firstphase_width/firstphase_height no longer supported; use hr_scale", file=sys.stderr)
+ self.hr_scale = self.width / firstphase_width
+ self.width = firstphase_width
+ self.height = firstphase_height
def init(self, all_prompts, all_seeds, all_subseeds):
if self.enable_hr:
@@ -622,48 +681,50 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
else:
state.job_count = state.job_count * 2
- self.extra_generation_params["First pass size"] = f"{self.firstphase_width}x{self.firstphase_height}"
+ self.extra_generation_params["Hires upscale"] = self.hr_scale
+ if self.hr_upscaler is not None:
+ self.extra_generation_params["Hires upscaler"] = self.hr_upscaler
- if self.firstphase_width == 0 or self.firstphase_height == 0:
- desired_pixel_count = 512 * 512
- actual_pixel_count = self.width * self.height
- scale = math.sqrt(desired_pixel_count / actual_pixel_count)
- self.firstphase_width = math.ceil(scale * self.width / 64) * 64
- self.firstphase_height = math.ceil(scale * self.height / 64) * 64
- firstphase_width_truncated = int(scale * self.width)
- firstphase_height_truncated = int(scale * self.height)
+ def sample(self, conditioning, unconditional_conditioning, seeds, subseeds, subseed_strength, prompts):
+ self.sampler = sd_samplers.create_sampler(self.sampler_name, self.sd_model)
- else:
+ latent_scale_mode = shared.latent_upscale_modes.get(self.hr_upscaler, None) if self.hr_upscaler is not None else shared.latent_upscale_modes.get(shared.latent_upscale_default_mode, "nearest")
+ if self.enable_hr and latent_scale_mode is None:
+ assert len([x for x in shared.sd_upscalers if x.name == self.hr_upscaler]) > 0, f"could not find upscaler named {self.hr_upscaler}"
+
+ x = create_random_tensors([opt_C, self.height // opt_f, self.width // opt_f], seeds=seeds, subseeds=subseeds, subseed_strength=self.subseed_strength, seed_resize_from_h=self.seed_resize_from_h, seed_resize_from_w=self.seed_resize_from_w, p=self)
+ samples = self.sampler.sample(self, x, conditioning, unconditional_conditioning, image_conditioning=self.txt2img_image_conditioning(x))
- width_ratio = self.width / self.firstphase_width
- height_ratio = self.height / self.firstphase_height
+ if not self.enable_hr:
+ return samples
- if width_ratio > height_ratio:
- firstphase_width_truncated = self.firstphase_width
- firstphase_height_truncated = self.firstphase_width * self.height / self.width
- else:
- firstphase_width_truncated = self.firstphase_height * self.width / self.height
- firstphase_height_truncated = self.firstphase_height
+ target_width = int(self.width * self.hr_scale)
+ target_height = int(self.height * self.hr_scale)
- self.truncate_x = int(self.firstphase_width - firstphase_width_truncated) // opt_f
- self.truncate_y = int(self.firstphase_height - firstphase_height_truncated) // opt_f
+ def save_intermediate(image, index):
+ """saves image before applying hires fix, if enabled in options; takes as an argument either an image or batch with latent space images"""
- def sample(self, conditioning, unconditional_conditioning, seeds, subseeds, subseed_strength):
- self.sampler = sd_samplers.create_sampler_with_index(sd_samplers.samplers, self.sampler_index, self.sd_model)
+ if not opts.save or self.do_not_save_samples or not opts.save_images_before_highres_fix:
+ return
- if not self.enable_hr:
- x = create_random_tensors([opt_C, self.height // opt_f, self.width // opt_f], seeds=seeds, subseeds=subseeds, subseed_strength=self.subseed_strength, seed_resize_from_h=self.seed_resize_from_h, seed_resize_from_w=self.seed_resize_from_w, p=self)
- samples = self.sampler.sample(self, x, conditioning, unconditional_conditioning, image_conditioning=self.txt2img_image_conditioning(x))
- return samples
+ if not isinstance(image, Image.Image):
+ image = sd_samplers.sample_to_image(image, index, approximation=0)
- x = create_random_tensors([opt_C, self.firstphase_height // opt_f, self.firstphase_width // opt_f], seeds=seeds, subseeds=subseeds, subseed_strength=self.subseed_strength, seed_resize_from_h=self.seed_resize_from_h, seed_resize_from_w=self.seed_resize_from_w, p=self)
- samples = self.sampler.sample(self, x, conditioning, unconditional_conditioning, image_conditioning=self.txt2img_image_conditioning(x, self.firstphase_width, self.firstphase_height))
+ info = create_infotext(self, self.all_prompts, self.all_seeds, self.all_subseeds, [], iteration=self.iteration, position_in_batch=index)
+ images.save_image(image, self.outpath_samples, "", seeds[index], prompts[index], opts.samples_format, info=info, suffix="-before-highres-fix")
- samples = samples[:, :, self.truncate_y//2:samples.shape[2]-self.truncate_y//2, self.truncate_x//2:samples.shape[3]-self.truncate_x//2]
+ if latent_scale_mode is not None:
+ for i in range(samples.shape[0]):
+ save_intermediate(samples, i)
- if opts.use_scale_latent_for_hires_fix:
- samples = torch.nn.functional.interpolate(samples, size=(self.height // opt_f, self.width // opt_f), mode="bilinear")
+ samples = torch.nn.functional.interpolate(samples, size=(target_height // opt_f, target_width // opt_f), mode=latent_scale_mode["mode"], antialias=latent_scale_mode["antialias"])
+ # Avoid making the inpainting conditioning unless necessary as
+ # this does need some extra compute to decode / encode the image again.
+ if getattr(self, "inpainting_mask_weight", shared.opts.inpainting_mask_weight) < 1.0:
+ image_conditioning = self.img2img_image_conditioning(decode_first_stage(self.sd_model, samples), samples)
+ else:
+ image_conditioning = self.txt2img_image_conditioning(samples)
else:
decoded_samples = decode_first_stage(self.sd_model, samples)
lowres_samples = torch.clamp((decoded_samples + 1.0) / 2.0, min=0.0, max=1.0)
@@ -673,7 +734,10 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
x_sample = 255. * np.moveaxis(x_sample.cpu().numpy(), 0, 2)
x_sample = x_sample.astype(np.uint8)
image = Image.fromarray(x_sample)
- image = images.resize_image(0, image, self.width, self.height)
+
+ save_intermediate(image, i)
+
+ image = images.resize_image(0, image, target_width, target_height, upscaler_name=self.hr_upscaler)
image = np.array(image).astype(np.float32) / 255.0
image = np.moveaxis(image, 2, 0)
batch_images.append(image)
@@ -684,13 +748,13 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
samples = self.sd_model.get_first_stage_encoding(self.sd_model.encode_first_stage(decoded_samples))
- shared.state.nextjob()
+ image_conditioning = self.img2img_image_conditioning(decoded_samples, samples)
- self.sampler = sd_samplers.create_sampler_with_index(sd_samplers.samplers, self.sampler_index, self.sd_model)
+ shared.state.nextjob()
- noise = create_random_tensors(samples.shape[1:], seeds=seeds, subseeds=subseeds, subseed_strength=subseed_strength, seed_resize_from_h=self.seed_resize_from_h, seed_resize_from_w=self.seed_resize_from_w, p=self)
+ self.sampler = sd_samplers.create_sampler(self.sampler_name, self.sd_model)
- image_conditioning = self.txt2img_image_conditioning(x)
+ noise = create_random_tensors(samples.shape[1:], seeds=seeds, subseeds=subseeds, subseed_strength=subseed_strength, p=self)
# GC now before running the next img2img to prevent running out of memory
x = None
@@ -704,7 +768,7 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
sampler = None
- def __init__(self, init_images: list=None, resize_mode: int=0, denoising_strength: float=0.75, mask: Any=None, mask_blur: int=4, inpainting_fill: int=0, inpaint_full_res: bool=True, inpaint_full_res_padding: int=0, inpainting_mask_invert: int=0, **kwargs):
+ def __init__(self, init_images: list = None, resize_mode: int = 0, denoising_strength: float = 0.75, mask: Any = None, mask_blur: int = 4, inpainting_fill: int = 0, inpaint_full_res: bool = True, inpaint_full_res_padding: int = 0, inpainting_mask_invert: int = 0, initial_noise_multiplier: float = None, **kwargs):
super().__init__(**kwargs)
self.init_images = init_images
@@ -712,7 +776,6 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
self.denoising_strength: float = denoising_strength
self.init_latent = None
self.image_mask = mask
- #self.image_unblurred_mask = None
self.latent_mask = None
self.mask_for_overlay = None
self.mask_blur = mask_blur
@@ -720,66 +783,68 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
self.inpaint_full_res = inpaint_full_res
self.inpaint_full_res_padding = inpaint_full_res_padding
self.inpainting_mask_invert = inpainting_mask_invert
+ self.initial_noise_multiplier = opts.initial_noise_multiplier if initial_noise_multiplier is None else initial_noise_multiplier
self.mask = None
self.nmask = None
self.image_conditioning = None
def init(self, all_prompts, all_seeds, all_subseeds):
- self.sampler = sd_samplers.create_sampler_with_index(sd_samplers.samplers_for_img2img, self.sampler_index, self.sd_model)
+ self.sampler = sd_samplers.create_sampler(self.sampler_name, self.sd_model)
crop_region = None
- if self.image_mask is not None:
- self.image_mask = self.image_mask.convert('L')
+ image_mask = self.image_mask
- if self.inpainting_mask_invert:
- self.image_mask = ImageOps.invert(self.image_mask)
+ if image_mask is not None:
+ image_mask = image_mask.convert('L')
- #self.image_unblurred_mask = self.image_mask
+ if self.inpainting_mask_invert:
+ image_mask = ImageOps.invert(image_mask)
if self.mask_blur > 0:
- self.image_mask = self.image_mask.filter(ImageFilter.GaussianBlur(self.mask_blur))
+ image_mask = image_mask.filter(ImageFilter.GaussianBlur(self.mask_blur))
if self.inpaint_full_res:
- self.mask_for_overlay = self.image_mask
- mask = self.image_mask.convert('L')
+ self.mask_for_overlay = image_mask
+ mask = image_mask.convert('L')
crop_region = masking.get_crop_region(np.array(mask), self.inpaint_full_res_padding)
crop_region = masking.expand_crop_region(crop_region, self.width, self.height, mask.width, mask.height)
x1, y1, x2, y2 = crop_region
mask = mask.crop(crop_region)
- self.image_mask = images.resize_image(2, mask, self.width, self.height)
+ image_mask = images.resize_image(2, mask, self.width, self.height)
self.paste_to = (x1, y1, x2-x1, y2-y1)
else:
- self.image_mask = images.resize_image(self.resize_mode, self.image_mask, self.width, self.height)
- np_mask = np.array(self.image_mask)
+ image_mask = images.resize_image(self.resize_mode, image_mask, self.width, self.height)
+ np_mask = np.array(image_mask)
np_mask = np.clip((np_mask.astype(np.float32)) * 2, 0, 255).astype(np.uint8)
self.mask_for_overlay = Image.fromarray(np_mask)
self.overlay_images = []
- latent_mask = self.latent_mask if self.latent_mask is not None else self.image_mask
+ latent_mask = self.latent_mask if self.latent_mask is not None else image_mask
add_color_corrections = opts.img2img_color_correction and self.color_corrections is None
if add_color_corrections:
self.color_corrections = []
imgs = []
for img in self.init_images:
- image = img.convert("RGB")
+ image = images.flatten(img, opts.img2img_background_color)
- if crop_region is None:
+ if crop_region is None and self.resize_mode != 3:
image = images.resize_image(self.resize_mode, image, self.width, self.height)
- if self.image_mask is not None:
+ if image_mask is not None:
image_masked = Image.new('RGBa', (image.width, image.height))
image_masked.paste(image.convert("RGBA").convert("RGBa"), mask=ImageOps.invert(self.mask_for_overlay.convert('L')))
self.overlay_images.append(image_masked.convert('RGBA'))
+ # crop_region is not None if we are doing inpaint full res
if crop_region is not None:
image = image.crop(crop_region)
image = images.resize_image(2, image, self.width, self.height)
- if self.image_mask is not None:
+ if image_mask is not None:
if self.inpainting_fill != 1:
image = masking.fill(image, latent_mask)
@@ -811,7 +876,10 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
self.init_latent = self.sd_model.get_first_stage_encoding(self.sd_model.encode_first_stage(image))
- if self.image_mask is not None:
+ if self.resize_mode == 3:
+ self.init_latent = torch.nn.functional.interpolate(self.init_latent, size=(self.height // opt_f, self.width // opt_f), mode="bilinear")
+
+ if image_mask is not None:
init_mask = latent_mask
latmask = init_mask.convert('RGB').resize((self.init_latent.shape[3], self.init_latent.shape[2]))
latmask = np.moveaxis(np.array(latmask, dtype=np.float32), 2, 0) / 255
@@ -828,12 +896,15 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
elif self.inpainting_fill == 3:
self.init_latent = self.init_latent * self.mask
- self.image_conditioning = self.img2img_image_conditioning(image, self.init_latent, self.image_mask)
+ self.image_conditioning = self.img2img_image_conditioning(image, self.init_latent, image_mask)
-
- def sample(self, conditioning, unconditional_conditioning, seeds, subseeds, subseed_strength):
+ def sample(self, conditioning, unconditional_conditioning, seeds, subseeds, subseed_strength, prompts):
x = create_random_tensors([opt_C, self.height // opt_f, self.width // opt_f], seeds=seeds, subseeds=subseeds, subseed_strength=self.subseed_strength, seed_resize_from_h=self.seed_resize_from_h, seed_resize_from_w=self.seed_resize_from_w, p=self)
+ if self.initial_noise_multiplier != 1.0:
+ self.extra_generation_params["Noise multiplier"] = self.initial_noise_multiplier
+ x *= self.initial_noise_multiplier
+
samples = self.sampler.sample_img2img(self, self.init_latent, x, conditioning, unconditional_conditioning, image_conditioning=self.image_conditioning)
if self.mask is not None:
@@ -842,4 +913,4 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
del x
devices.torch_gc()
- return samples \ No newline at end of file
+ return samples
diff --git a/modules/safe.py b/modules/safe.py
index 348a24fc..82d44be3 100644
--- a/modules/safe.py
+++ b/modules/safe.py
@@ -23,23 +23,30 @@ def encode(*args):
class RestrictedUnpickler(pickle.Unpickler):
+ extra_handler = None
+
def persistent_load(self, saved_id):
assert saved_id[0] == 'storage'
return TypedStorage()
def find_class(self, module, name):
+ if self.extra_handler is not None:
+ res = self.extra_handler(module, name)
+ if res is not None:
+ return res
+
if module == 'collections' and name == 'OrderedDict':
return getattr(collections, name)
- if module == 'torch._utils' and name in ['_rebuild_tensor_v2', '_rebuild_parameter']:
+ if module == 'torch._utils' and name in ['_rebuild_tensor_v2', '_rebuild_parameter', '_rebuild_device_tensor_from_numpy']:
return getattr(torch._utils, name)
- if module == 'torch' and name in ['FloatStorage', 'HalfStorage', 'IntStorage', 'LongStorage', 'DoubleStorage', 'ByteStorage']:
+ if module == 'torch' and name in ['FloatStorage', 'HalfStorage', 'IntStorage', 'LongStorage', 'DoubleStorage', 'ByteStorage', 'float32']:
return getattr(torch, name)
if module == 'torch.nn.modules.container' and name in ['ParameterDict']:
return getattr(torch.nn.modules.container, name)
- if module == 'numpy.core.multiarray' and name == 'scalar':
- return numpy.core.multiarray.scalar
- if module == 'numpy' and name == 'dtype':
- return numpy.dtype
+ if module == 'numpy.core.multiarray' and name in ['scalar', '_reconstruct']:
+ return getattr(numpy.core.multiarray, name)
+ if module == 'numpy' and name in ['dtype', 'ndarray']:
+ return getattr(numpy, name)
if module == '_codecs' and name == 'encode':
return encode
if module == "pytorch_lightning.callbacks" and name == 'model_checkpoint':
@@ -52,32 +59,37 @@ class RestrictedUnpickler(pickle.Unpickler):
return set
# Forbid everything else.
- raise pickle.UnpicklingError(f"global '{module}/{name}' is forbidden")
+ raise Exception(f"global '{module}/{name}' is forbidden")
-allowed_zip_names = ["archive/data.pkl", "archive/version"]
-allowed_zip_names_re = re.compile(r"^archive/data/\d+$")
-
+# Regular expression that accepts 'dirname/version', 'dirname/data.pkl', and 'dirname/data/<number>'
+allowed_zip_names_re = re.compile(r"^([^/]+)/((data/\d+)|version|(data\.pkl))$")
+data_pkl_re = re.compile(r"^([^/]+)/data\.pkl$")
def check_zip_filenames(filename, names):
for name in names:
- if name in allowed_zip_names:
- continue
if allowed_zip_names_re.match(name):
continue
raise Exception(f"bad file inside {filename}: {name}")
-def check_pt(filename):
+def check_pt(filename, extra_handler):
try:
# new pytorch format is a zip file
with zipfile.ZipFile(filename) as z:
check_zip_filenames(filename, z.namelist())
- with z.open('archive/data.pkl') as file:
+ # find filename of data.pkl in zip file: '<directory name>/data.pkl'
+ data_pkl_filenames = [f for f in z.namelist() if data_pkl_re.match(f)]
+ if len(data_pkl_filenames) == 0:
+ raise Exception(f"data.pkl not found in {filename}")
+ if len(data_pkl_filenames) > 1:
+ raise Exception(f"Multiple data.pkl found in {filename}")
+ with z.open(data_pkl_filenames[0]) as file:
unpickler = RestrictedUnpickler(file)
+ unpickler.extra_handler = extra_handler
unpickler.load()
except zipfile.BadZipfile:
@@ -85,33 +97,96 @@ def check_pt(filename):
# if it's not a zip file, it's an olf pytorch format, with five objects written to pickle
with open(filename, "rb") as file:
unpickler = RestrictedUnpickler(file)
+ unpickler.extra_handler = extra_handler
for i in range(5):
unpickler.load()
def load(filename, *args, **kwargs):
+ return load_with_extra(filename, extra_handler=global_extra_handler, *args, **kwargs)
+
+
+def load_with_extra(filename, extra_handler=None, *args, **kwargs):
+ """
+ this function is intended to be used by extensions that want to load models with
+ some extra classes in them that the usual unpickler would find suspicious.
+
+ Use the extra_handler argument to specify a function that takes module and field name as text,
+ and returns that field's value:
+
+ ```python
+ def extra(module, name):
+ if module == 'collections' and name == 'OrderedDict':
+ return collections.OrderedDict
+
+ return None
+
+ safe.load_with_extra('model.pt', extra_handler=extra)
+ ```
+
+ The alternative to this is just to use safe.unsafe_torch_load('model.pt'), which as the name implies is
+ definitely unsafe.
+ """
+
from modules import shared
try:
if not shared.cmd_opts.disable_safe_unpickle:
- check_pt(filename)
+ check_pt(filename, extra_handler)
except pickle.UnpicklingError:
print(f"Error verifying pickled file from {filename}:", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
- print(f"-----> !!!! The file is most likely corrupted !!!! <-----", file=sys.stderr)
- print(f"You can skip this check with --disable-safe-unpickle commandline argument, but that is not going to help you.\n\n", file=sys.stderr)
+ print("-----> !!!! The file is most likely corrupted !!!! <-----", file=sys.stderr)
+ print("You can skip this check with --disable-safe-unpickle commandline argument, but that is not going to help you.\n\n", file=sys.stderr)
return None
except Exception:
print(f"Error verifying pickled file from {filename}:", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
- print(f"\nThe file may be malicious, so the program is not going to read it.", file=sys.stderr)
- print(f"You can skip this check with --disable-safe-unpickle commandline argument.\n\n", file=sys.stderr)
+ print("\nThe file may be malicious, so the program is not going to read it.", file=sys.stderr)
+ print("You can skip this check with --disable-safe-unpickle commandline argument.\n\n", file=sys.stderr)
return None
return unsafe_torch_load(filename, *args, **kwargs)
+class Extra:
+ """
+ A class for temporarily setting the global handler for when you can't explicitly call load_with_extra
+ (because it's not your code making the torch.load call). The intended use is like this:
+
+```
+import torch
+from modules import safe
+
+def handler(module, name):
+ if module == 'torch' and name in ['float64', 'float16']:
+ return getattr(torch, name)
+
+ return None
+
+with safe.Extra(handler):
+ x = torch.load('model.pt')
+```
+ """
+
+ def __init__(self, handler):
+ self.handler = handler
+
+ def __enter__(self):
+ global global_extra_handler
+
+ assert global_extra_handler is None, 'already inside an Extra() block'
+ global_extra_handler = self.handler
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ global global_extra_handler
+
+ global_extra_handler = None
+
+
unsafe_torch_load = torch.load
torch.load = load
+global_extra_handler = None
+
diff --git a/modules/safety.py b/modules/safety.py
deleted file mode 100644
index cff4b278..00000000
--- a/modules/safety.py
+++ /dev/null
@@ -1,42 +0,0 @@
-import torch
-from diffusers.pipelines.stable_diffusion.safety_checker import StableDiffusionSafetyChecker
-from transformers import AutoFeatureExtractor
-from PIL import Image
-
-import modules.shared as shared
-
-safety_model_id = "CompVis/stable-diffusion-safety-checker"
-safety_feature_extractor = None
-safety_checker = None
-
-def numpy_to_pil(images):
- """
- Convert a numpy image or a batch of images to a PIL image.
- """
- if images.ndim == 3:
- images = images[None, ...]
- images = (images * 255).round().astype("uint8")
- pil_images = [Image.fromarray(image) for image in images]
-
- return pil_images
-
-# check and replace nsfw content
-def check_safety(x_image):
- global safety_feature_extractor, safety_checker
-
- if safety_feature_extractor is None:
- safety_feature_extractor = AutoFeatureExtractor.from_pretrained(safety_model_id)
- safety_checker = StableDiffusionSafetyChecker.from_pretrained(safety_model_id)
-
- safety_checker_input = safety_feature_extractor(numpy_to_pil(x_image), return_tensors="pt")
- x_checked_image, has_nsfw_concept = safety_checker(images=x_image, clip_input=safety_checker_input.pixel_values)
-
- return x_checked_image, has_nsfw_concept
-
-
-def censor_batch(x):
- x_samples_ddim_numpy = x.cpu().permute(0, 2, 3, 1).numpy()
- x_checked_image, has_nsfw_concept = check_safety(x_samples_ddim_numpy)
- x = torch.from_numpy(x_checked_image).permute(0, 3, 1, 2)
-
- return x
diff --git a/modules/script_callbacks.py b/modules/script_callbacks.py
index ce264690..de69fd9f 100644
--- a/modules/script_callbacks.py
+++ b/modules/script_callbacks.py
@@ -2,10 +2,12 @@ import sys
import traceback
from collections import namedtuple
import inspect
+from typing import Optional
from fastapi import FastAPI
from gradio import Blocks
+
def report_exception(c, job):
print(f"Error executing callback {job} for {c.script}", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
@@ -26,25 +28,59 @@ class ImageSaveParams:
"""dictionary with parameters for image's PNG info data; infotext will have the key 'parameters'"""
+class CFGDenoiserParams:
+ def __init__(self, x, image_cond, sigma, sampling_step, total_sampling_steps):
+ self.x = x
+ """Latent image representation in the process of being denoised"""
+
+ self.image_cond = image_cond
+ """Conditioning image"""
+
+ self.sigma = sigma
+ """Current sigma noise step value"""
+
+ self.sampling_step = sampling_step
+ """Current Sampling step number"""
+
+ self.total_sampling_steps = total_sampling_steps
+ """Total number of sampling steps planned"""
+
+
+class UiTrainTabParams:
+ def __init__(self, txt2img_preview_params):
+ self.txt2img_preview_params = txt2img_preview_params
+
+
+class ImageGridLoopParams:
+ def __init__(self, imgs, cols, rows):
+ self.imgs = imgs
+ self.cols = cols
+ self.rows = rows
+
+
ScriptCallback = namedtuple("ScriptCallback", ["script", "callback"])
-callbacks_app_started = []
-callbacks_model_loaded = []
-callbacks_ui_tabs = []
-callbacks_ui_settings = []
-callbacks_before_image_saved = []
-callbacks_image_saved = []
+callback_map = dict(
+ callbacks_app_started=[],
+ callbacks_model_loaded=[],
+ callbacks_ui_tabs=[],
+ callbacks_ui_train_tabs=[],
+ callbacks_ui_settings=[],
+ callbacks_before_image_saved=[],
+ callbacks_image_saved=[],
+ callbacks_cfg_denoiser=[],
+ callbacks_before_component=[],
+ callbacks_after_component=[],
+ callbacks_image_grid=[],
+)
def clear_callbacks():
- callbacks_model_loaded.clear()
- callbacks_ui_tabs.clear()
- callbacks_ui_settings.clear()
- callbacks_before_image_saved.clear()
- callbacks_image_saved.clear()
+ for callback_list in callback_map.values():
+ callback_list.clear()
-def app_started_callback(demo: Blocks, app: FastAPI):
- for c in callbacks_app_started:
+def app_started_callback(demo: Optional[Blocks], app: FastAPI):
+ for c in callback_map['callbacks_app_started']:
try:
c.callback(demo, app)
except Exception:
@@ -52,7 +88,7 @@ def app_started_callback(demo: Blocks, app: FastAPI):
def model_loaded_callback(sd_model):
- for c in callbacks_model_loaded:
+ for c in callback_map['callbacks_model_loaded']:
try:
c.callback(sd_model)
except Exception:
@@ -61,8 +97,8 @@ def model_loaded_callback(sd_model):
def ui_tabs_callback():
res = []
-
- for c in callbacks_ui_tabs:
+
+ for c in callback_map['callbacks_ui_tabs']:
try:
res += c.callback() or []
except Exception:
@@ -71,8 +107,16 @@ def ui_tabs_callback():
return res
+def ui_train_tabs_callback(params: UiTrainTabParams):
+ for c in callback_map['callbacks_ui_train_tabs']:
+ try:
+ c.callback(params)
+ except Exception:
+ report_exception(c, 'callbacks_ui_train_tabs')
+
+
def ui_settings_callback():
- for c in callbacks_ui_settings:
+ for c in callback_map['callbacks_ui_settings']:
try:
c.callback()
except Exception:
@@ -80,7 +124,7 @@ def ui_settings_callback():
def before_image_saved_callback(params: ImageSaveParams):
- for c in callbacks_before_image_saved:
+ for c in callback_map['callbacks_before_image_saved']:
try:
c.callback(params)
except Exception:
@@ -88,30 +132,78 @@ def before_image_saved_callback(params: ImageSaveParams):
def image_saved_callback(params: ImageSaveParams):
- for c in callbacks_image_saved:
+ for c in callback_map['callbacks_image_saved']:
try:
c.callback(params)
except Exception:
report_exception(c, 'image_saved_callback')
+def cfg_denoiser_callback(params: CFGDenoiserParams):
+ for c in callback_map['callbacks_cfg_denoiser']:
+ try:
+ c.callback(params)
+ except Exception:
+ report_exception(c, 'cfg_denoiser_callback')
+
+
+def before_component_callback(component, **kwargs):
+ for c in callback_map['callbacks_before_component']:
+ try:
+ c.callback(component, **kwargs)
+ except Exception:
+ report_exception(c, 'before_component_callback')
+
+
+def after_component_callback(component, **kwargs):
+ for c in callback_map['callbacks_after_component']:
+ try:
+ c.callback(component, **kwargs)
+ except Exception:
+ report_exception(c, 'after_component_callback')
+
+
+def image_grid_callback(params: ImageGridLoopParams):
+ for c in callback_map['callbacks_image_grid']:
+ try:
+ c.callback(params)
+ except Exception:
+ report_exception(c, 'image_grid')
+
+
def add_callback(callbacks, fun):
stack = [x for x in inspect.stack() if x.filename != __file__]
filename = stack[0].filename if len(stack) > 0 else 'unknown file'
callbacks.append(ScriptCallback(filename, fun))
+
+def remove_current_script_callbacks():
+ stack = [x for x in inspect.stack() if x.filename != __file__]
+ filename = stack[0].filename if len(stack) > 0 else 'unknown file'
+ if filename == 'unknown file':
+ return
+ for callback_list in callback_map.values():
+ for callback_to_remove in [cb for cb in callback_list if cb.script == filename]:
+ callback_list.remove(callback_to_remove)
+
+
+def remove_callbacks_for_function(callback_func):
+ for callback_list in callback_map.values():
+ for callback_to_remove in [cb for cb in callback_list if cb.callback == callback_func]:
+ callback_list.remove(callback_to_remove)
+
def on_app_started(callback):
"""register a function to be called when the webui started, the gradio `Block` component and
fastapi `FastAPI` object are passed as the arguments"""
- add_callback(callbacks_app_started, callback)
+ add_callback(callback_map['callbacks_app_started'], callback)
def on_model_loaded(callback):
"""register a function to be called when the stable diffusion model is created; the model is
passed as an argument"""
- add_callback(callbacks_model_loaded, callback)
+ add_callback(callback_map['callbacks_model_loaded'], callback)
def on_ui_tabs(callback):
@@ -124,13 +216,20 @@ def on_ui_tabs(callback):
title is tab text displayed to user in the UI
elem_id is HTML id for the tab
"""
- add_callback(callbacks_ui_tabs, callback)
+ add_callback(callback_map['callbacks_ui_tabs'], callback)
+
+
+def on_ui_train_tabs(callback):
+ """register a function to be called when the UI is creating new tabs for the train tab.
+ Create your new tabs with gr.Tab.
+ """
+ add_callback(callback_map['callbacks_ui_train_tabs'], callback)
def on_ui_settings(callback):
"""register a function to be called before UI settings are populated; add your settings
by using shared.opts.add_option(shared.OptionInfo(...)) """
- add_callback(callbacks_ui_settings, callback)
+ add_callback(callback_map['callbacks_ui_settings'], callback)
def on_before_image_saved(callback):
@@ -138,7 +237,7 @@ def on_before_image_saved(callback):
The callback is called with one argument:
- params: ImageSaveParams - parameters the image is to be saved with. You can change fields in this object.
"""
- add_callback(callbacks_before_image_saved, callback)
+ add_callback(callback_map['callbacks_before_image_saved'], callback)
def on_image_saved(callback):
@@ -146,4 +245,37 @@ def on_image_saved(callback):
The callback is called with one argument:
- params: ImageSaveParams - parameters the image was saved with. Changing fields in this object does nothing.
"""
- add_callback(callbacks_image_saved, callback)
+ add_callback(callback_map['callbacks_image_saved'], callback)
+
+
+def on_cfg_denoiser(callback):
+ """register a function to be called in the kdiffussion cfg_denoiser method after building the inner model inputs.
+ The callback is called with one argument:
+ - params: CFGDenoiserParams - parameters to be passed to the inner model and sampling state details.
+ """
+ add_callback(callback_map['callbacks_cfg_denoiser'], callback)
+
+
+def on_before_component(callback):
+ """register a function to be called before a component is created.
+ The callback is called with arguments:
+ - component - gradio component that is about to be created.
+ - **kwargs - args to gradio.components.IOComponent.__init__ function
+
+ Use elem_id/label fields of kwargs to figure out which component it is.
+ This can be useful to inject your own components somewhere in the middle of vanilla UI.
+ """
+ add_callback(callback_map['callbacks_before_component'], callback)
+
+
+def on_after_component(callback):
+ """register a function to be called after a component is created. See on_before_component for more."""
+ add_callback(callback_map['callbacks_after_component'], callback)
+
+
+def on_image_grid(callback):
+ """register a function to be called before making an image grid.
+ The callback is called with one argument:
+ - params: ImageGridLoopParams - parameters to be used for grid creation. Can be modified.
+ """
+ add_callback(callback_map['callbacks_image_grid'], callback)
diff --git a/modules/script_loading.py b/modules/script_loading.py
new file mode 100644
index 00000000..f93f0951
--- /dev/null
+++ b/modules/script_loading.py
@@ -0,0 +1,34 @@
+import os
+import sys
+import traceback
+from types import ModuleType
+
+
+def load_module(path):
+ with open(path, "r", encoding="utf8") as file:
+ text = file.read()
+
+ compiled = compile(text, path, 'exec')
+ module = ModuleType(os.path.basename(path))
+ exec(compiled, module.__dict__)
+
+ return module
+
+
+def preload_extensions(extensions_dir, parser):
+ if not os.path.isdir(extensions_dir):
+ return
+
+ for dirname in sorted(os.listdir(extensions_dir)):
+ preload_script = os.path.join(extensions_dir, dirname, "preload.py")
+ if not os.path.isfile(preload_script):
+ continue
+
+ try:
+ module = load_module(preload_script)
+ if hasattr(module, 'preload'):
+ module.preload(parser)
+
+ except Exception:
+ print(f"Error running preload() for {preload_script}", file=sys.stderr)
+ print(traceback.format_exc(), file=sys.stderr)
diff --git a/modules/scripts.py b/modules/scripts.py
index 533db45c..722f8685 100644
--- a/modules/scripts.py
+++ b/modules/scripts.py
@@ -3,11 +3,10 @@ import sys
import traceback
from collections import namedtuple
-import modules.ui as ui
import gradio as gr
from modules.processing import StableDiffusionProcessing
-from modules import shared, paths, script_callbacks, extensions
+from modules import shared, paths, script_callbacks, extensions, script_loading
AlwaysVisible = object()
@@ -18,6 +17,12 @@ class Script:
args_to = None
alwayson = False
+ is_txt2img = False
+ is_img2img = False
+
+ """A gr.Group component that has all script's UI inside it"""
+ group = None
+
infotext_fields = None
"""if set in ui(), this is a list of pairs of gradio component + text; the text will be used when
parsing infotext to set the value for the component; see ui.py's txt2img_paste_fields for an example
@@ -31,7 +36,7 @@ class Script:
def ui(self, is_img2img):
"""this function should create gradio UI elements. See https://gradio.app/docs/#components
The return value should be an array of all components that are used in processing.
- Values of those returned componenbts will be passed to run() and process() functions.
+ Values of those returned components will be passed to run() and process() functions.
"""
pass
@@ -42,7 +47,7 @@ class Script:
This function should return:
- False if the script should not be shown in UI at all
- - True if the script should be shown in UI if it's scelected in the scripts drowpdown
+ - True if the script should be shown in UI if it's selected in the scripts dropdown
- script.AlwaysVisible if the script should be shown in UI at all times
"""
@@ -70,6 +75,30 @@ class Script:
pass
+ def process_batch(self, p, *args, **kwargs):
+ """
+ Same as process(), but called for every batch.
+
+ **kwargs will have those items:
+ - batch_number - index of current batch, from 0 to number of batches-1
+ - prompts - list of prompts for current batch; you can change contents of this list but changing the number of entries will likely break things
+ - seeds - list of seeds for current batch
+ - subseeds - list of subseeds for current batch
+ """
+
+ pass
+
+ def postprocess_batch(self, p, *args, **kwargs):
+ """
+ Same as process_batch(), but called for every batch after it has been generated.
+
+ **kwargs will have same items as process_batch, and also:
+ - batch_number - index of current batch, from 0 to number of batches-1
+ - images - torch tensor with all generated images, with values ranging from 0 to 1;
+ """
+
+ pass
+
def postprocess(self, p, processed, *args):
"""
This function is called after processing ends for AlwaysVisible scripts.
@@ -78,6 +107,23 @@ class Script:
pass
+ def before_component(self, component, **kwargs):
+ """
+ Called before a component is created.
+ Use elem_id/label fields of kwargs to figure out which component it is.
+ This can be useful to inject your own components somewhere in the middle of vanilla UI.
+ You can return created components in the ui() function to add them to the list of arguments for your processing functions
+ """
+
+ pass
+
+ def after_component(self, component, **kwargs):
+ """
+ Called after a component is created. Same as above.
+ """
+
+ pass
+
def describe(self):
"""unused"""
return ""
@@ -125,7 +171,7 @@ def list_files_with_name(filename):
continue
path = os.path.join(dirpath, filename)
- if os.path.isfile(filename):
+ if os.path.isfile(path):
res.append(path)
return res
@@ -146,13 +192,7 @@ def load_scripts():
sys.path = [scriptfile.basedir] + sys.path
current_basedir = scriptfile.basedir
- with open(scriptfile.path, "r", encoding="utf8") as file:
- text = file.read()
-
- from types import ModuleType
- compiled = compile(text, scriptfile.path, 'exec')
- module = ModuleType(scriptfile.filename)
- exec(compiled, module.__dict__)
+ module = script_loading.load_module(scriptfile.path)
for key, script_class in module.__dict__.items():
if type(script_class) == type and issubclass(script_class, Script):
@@ -186,12 +226,18 @@ class ScriptRunner:
self.titles = []
self.infotext_fields = []
- def setup_ui(self, is_img2img):
+ def initialize_scripts(self, is_img2img):
+ self.scripts.clear()
+ self.alwayson_scripts.clear()
+ self.selectable_scripts.clear()
+
for script_class, path, basedir in scripts_data:
script = script_class()
script.filename = path
+ script.is_txt2img = not is_img2img
+ script.is_img2img = is_img2img
- visibility = script.show(is_img2img)
+ visibility = script.show(script.is_img2img)
if visibility == AlwaysVisible:
self.scripts.append(script)
@@ -202,6 +248,7 @@ class ScriptRunner:
self.scripts.append(script)
self.selectable_scripts.append(script)
+ def setup_ui(self):
self.titles = [wrap_call(script.title, script.filename, "title") or f"{script.filename} [error]" for script in self.selectable_scripts]
inputs = [None]
@@ -211,15 +258,13 @@ class ScriptRunner:
script.args_from = len(inputs)
script.args_to = len(inputs)
- controls = wrap_call(script.ui, script.filename, "ui", is_img2img)
+ controls = wrap_call(script.ui, script.filename, "ui", script.is_img2img)
if controls is None:
return
for control in controls:
control.custom_script_source = os.path.basename(script.filename)
- if not script.alwayson:
- control.visible = False
if script.infotext_fields is not None:
self.infotext_fields += script.infotext_fields
@@ -229,40 +274,41 @@ class ScriptRunner:
script.args_to = len(inputs)
for script in self.alwayson_scripts:
- with gr.Group():
+ with gr.Group() as group:
create_script_ui(script, inputs, inputs_alwayson)
+ script.group = group
+
dropdown = gr.Dropdown(label="Script", elem_id="script_list", choices=["None"] + self.titles, value="None", type="index")
dropdown.save_to_config = True
inputs[0] = dropdown
for script in self.selectable_scripts:
- create_script_ui(script, inputs, inputs_alwayson)
+ with gr.Group(visible=False) as group:
+ create_script_ui(script, inputs, inputs_alwayson)
+
+ script.group = group
def select_script(script_index):
- if 0 < script_index <= len(self.selectable_scripts):
- script = self.selectable_scripts[script_index-1]
- args_from = script.args_from
- args_to = script.args_to
- else:
- args_from = 0
- args_to = 0
+ selected_script = self.selectable_scripts[script_index - 1] if script_index>0 else None
- return [ui.gr_show(True if i == 0 else args_from <= i < args_to or is_alwayson) for i, is_alwayson in enumerate(inputs_alwayson)]
+ return [gr.update(visible=selected_script == s) for s in self.selectable_scripts]
def init_field(title):
+ """called when an initial value is set from ui-config.json to show script's UI components"""
+
if title == 'None':
return
+
script_index = self.titles.index(title)
- script = self.selectable_scripts[script_index]
- for i in range(script.args_from, script.args_to):
- inputs[i].visible = True
+ self.selectable_scripts[script_index].group.visible = True
dropdown.init_field = init_field
+
dropdown.change(
fn=select_script,
inputs=[dropdown],
- outputs=inputs
+ outputs=[script.group for script in self.selectable_scripts]
)
return inputs
@@ -294,6 +340,15 @@ class ScriptRunner:
print(f"Error running process: {script.filename}", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
+ def process_batch(self, p, **kwargs):
+ for script in self.alwayson_scripts:
+ try:
+ script_args = p.script_args[script.args_from:script.args_to]
+ script.process_batch(p, *script_args, **kwargs)
+ except Exception:
+ print(f"Error running process_batch: {script.filename}", file=sys.stderr)
+ print(traceback.format_exc(), file=sys.stderr)
+
def postprocess(self, p, processed):
for script in self.alwayson_scripts:
try:
@@ -303,33 +358,53 @@ class ScriptRunner:
print(f"Error running postprocess: {script.filename}", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
+ def postprocess_batch(self, p, images, **kwargs):
+ for script in self.alwayson_scripts:
+ try:
+ script_args = p.script_args[script.args_from:script.args_to]
+ script.postprocess_batch(p, *script_args, images=images, **kwargs)
+ except Exception:
+ print(f"Error running postprocess_batch: {script.filename}", file=sys.stderr)
+ print(traceback.format_exc(), file=sys.stderr)
+
+ def before_component(self, component, **kwargs):
+ for script in self.scripts:
+ try:
+ script.before_component(component, **kwargs)
+ except Exception:
+ print(f"Error running before_component: {script.filename}", file=sys.stderr)
+ print(traceback.format_exc(), file=sys.stderr)
+
+ def after_component(self, component, **kwargs):
+ for script in self.scripts:
+ try:
+ script.after_component(component, **kwargs)
+ except Exception:
+ print(f"Error running after_component: {script.filename}", file=sys.stderr)
+ print(traceback.format_exc(), file=sys.stderr)
+
def reload_sources(self, cache):
for si, script in list(enumerate(self.scripts)):
- with open(script.filename, "r", encoding="utf8") as file:
- args_from = script.args_from
- args_to = script.args_to
- filename = script.filename
- text = file.read()
+ args_from = script.args_from
+ args_to = script.args_to
+ filename = script.filename
- from types import ModuleType
+ module = cache.get(filename, None)
+ if module is None:
+ module = script_loading.load_module(script.filename)
+ cache[filename] = module
- module = cache.get(filename, None)
- if module is None:
- compiled = compile(text, filename, 'exec')
- module = ModuleType(script.filename)
- exec(compiled, module.__dict__)
- cache[filename] = module
-
- for key, script_class in module.__dict__.items():
- if type(script_class) == type and issubclass(script_class, Script):
- self.scripts[si] = script_class()
- self.scripts[si].filename = filename
- self.scripts[si].args_from = args_from
- self.scripts[si].args_to = args_to
+ for key, script_class in module.__dict__.items():
+ if type(script_class) == type and issubclass(script_class, Script):
+ self.scripts[si] = script_class()
+ self.scripts[si].filename = filename
+ self.scripts[si].args_from = args_from
+ self.scripts[si].args_to = args_to
scripts_txt2img = ScriptRunner()
scripts_img2img = ScriptRunner()
+scripts_current: ScriptRunner = None
def reload_script_body_only():
@@ -346,3 +421,22 @@ def reload_scripts():
scripts_txt2img = ScriptRunner()
scripts_img2img = ScriptRunner()
+
+def IOComponent_init(self, *args, **kwargs):
+ if scripts_current is not None:
+ scripts_current.before_component(self, **kwargs)
+
+ script_callbacks.before_component_callback(self, **kwargs)
+
+ res = original_IOComponent_init(self, *args, **kwargs)
+
+ script_callbacks.after_component_callback(self, **kwargs)
+
+ if scripts_current is not None:
+ scripts_current.after_component(self, **kwargs)
+
+ return res
+
+
+original_IOComponent_init = gr.components.IOComponent.__init__
+gr.components.IOComponent.__init__ = IOComponent_init
diff --git a/modules/sd_hijack.py b/modules/sd_hijack.py
index bc49d235..fa2cd4bb 100644
--- a/modules/sd_hijack.py
+++ b/modules/sd_hijack.py
@@ -1,61 +1,81 @@
-import math
-import os
-import sys
-import traceback
import torch
-import numpy as np
-from torch import einsum
from torch.nn.functional import silu
import modules.textual_inversion.textual_inversion
-from modules import prompt_parser, devices, sd_hijack_optimizations, shared
-from modules.shared import opts, device, cmd_opts
+from modules import devices, sd_hijack_optimizations, shared, sd_hijack_checkpoint
+from modules.hypernetworks import hypernetwork
+from modules.shared import cmd_opts
+from modules import sd_hijack_clip, sd_hijack_open_clip, sd_hijack_unet, sd_hijack_xlmr, xlmr
+
from modules.sd_hijack_optimizations import invokeAI_mps_available
import ldm.modules.attention
import ldm.modules.diffusionmodules.model
+import ldm.modules.diffusionmodules.openaimodel
+import ldm.models.diffusion.ddim
+import ldm.models.diffusion.plms
+import ldm.modules.encoders.modules
attention_CrossAttention_forward = ldm.modules.attention.CrossAttention.forward
diffusionmodules_model_nonlinearity = ldm.modules.diffusionmodules.model.nonlinearity
diffusionmodules_model_AttnBlock_forward = ldm.modules.diffusionmodules.model.AttnBlock.forward
+# new memory efficient cross attention blocks do not support hypernets and we already
+# have memory efficient cross attention anyway, so this disables SD2.0's memory efficient cross attention
+ldm.modules.attention.MemoryEfficientCrossAttention = ldm.modules.attention.CrossAttention
+ldm.modules.attention.BasicTransformerBlock.ATTENTION_MODES["softmax-xformers"] = ldm.modules.attention.CrossAttention
+
+# silence new console spam from SD2
+ldm.modules.attention.print = lambda *args: None
+ldm.modules.diffusionmodules.model.print = lambda *args: None
+
def apply_optimizations():
undo_optimizations()
ldm.modules.diffusionmodules.model.nonlinearity = silu
+ ldm.modules.diffusionmodules.openaimodel.th = sd_hijack_unet.th
+
+ optimization_method = None
if cmd_opts.force_enable_xformers or (cmd_opts.xformers and shared.xformers_available and torch.version.cuda and (6, 0) <= torch.cuda.get_device_capability(shared.device) <= (9, 0)):
print("Applying xformers cross attention optimization.")
ldm.modules.attention.CrossAttention.forward = sd_hijack_optimizations.xformers_attention_forward
ldm.modules.diffusionmodules.model.AttnBlock.forward = sd_hijack_optimizations.xformers_attnblock_forward
+ optimization_method = 'xformers'
elif cmd_opts.opt_split_attention_v1:
print("Applying v1 cross attention optimization.")
ldm.modules.attention.CrossAttention.forward = sd_hijack_optimizations.split_cross_attention_forward_v1
+ optimization_method = 'V1'
elif not cmd_opts.disable_opt_split_attention and (cmd_opts.opt_split_attention_invokeai or not torch.cuda.is_available()):
if not invokeAI_mps_available and shared.device.type == 'mps':
print("The InvokeAI cross attention optimization for MPS requires the psutil package which is not installed.")
print("Applying v1 cross attention optimization.")
ldm.modules.attention.CrossAttention.forward = sd_hijack_optimizations.split_cross_attention_forward_v1
+ optimization_method = 'V1'
else:
print("Applying cross attention optimization (InvokeAI).")
ldm.modules.attention.CrossAttention.forward = sd_hijack_optimizations.split_cross_attention_forward_invokeAI
+ optimization_method = 'InvokeAI'
elif not cmd_opts.disable_opt_split_attention and (cmd_opts.opt_split_attention or torch.cuda.is_available()):
print("Applying cross attention optimization (Doggettx).")
ldm.modules.attention.CrossAttention.forward = sd_hijack_optimizations.split_cross_attention_forward
ldm.modules.diffusionmodules.model.AttnBlock.forward = sd_hijack_optimizations.cross_attention_attnblock_forward
+ optimization_method = 'Doggettx'
+ return optimization_method
-def undo_optimizations():
- from modules.hypernetworks import hypernetwork
+def undo_optimizations():
ldm.modules.attention.CrossAttention.forward = hypernetwork.attention_CrossAttention_forward
ldm.modules.diffusionmodules.model.nonlinearity = diffusionmodules_model_nonlinearity
ldm.modules.diffusionmodules.model.AttnBlock.forward = diffusionmodules_model_AttnBlock_forward
-def get_target_prompt_token_count(token_count):
- return math.ceil(max(token_count, 1) / 75) * 75
+def fix_checkpoint():
+ ldm.modules.attention.BasicTransformerBlock.forward = sd_hijack_checkpoint.BasicTransformerBlock_forward
+ ldm.modules.diffusionmodules.openaimodel.ResBlock.forward = sd_hijack_checkpoint.ResBlock_forward
+ ldm.modules.diffusionmodules.openaimodel.AttentionBlock.forward = sd_hijack_checkpoint.AttentionBlock_forward
class StableDiffusionModelHijack:
@@ -64,18 +84,31 @@ class StableDiffusionModelHijack:
layers = None
circular_enabled = False
clip = None
+ optimization_method = None
embedding_db = modules.textual_inversion.textual_inversion.EmbeddingDatabase(cmd_opts.embeddings_dir)
def hijack(self, m):
- model_embeddings = m.cond_stage_model.transformer.text_model.embeddings
- model_embeddings.token_embedding = EmbeddingsWithFixes(model_embeddings.token_embedding, self)
- m.cond_stage_model = FrozenCLIPEmbedderWithCustomWords(m.cond_stage_model, self)
+ if type(m.cond_stage_model) == xlmr.BertSeriesModelWithTransformation:
+ model_embeddings = m.cond_stage_model.roberta.embeddings
+ model_embeddings.token_embedding = EmbeddingsWithFixes(model_embeddings.word_embeddings, self)
+ m.cond_stage_model = sd_hijack_xlmr.FrozenXLMREmbedderWithCustomWords(m.cond_stage_model, self)
- self.clip = m.cond_stage_model
+ elif type(m.cond_stage_model) == ldm.modules.encoders.modules.FrozenCLIPEmbedder:
+ model_embeddings = m.cond_stage_model.transformer.text_model.embeddings
+ model_embeddings.token_embedding = EmbeddingsWithFixes(model_embeddings.token_embedding, self)
+ m.cond_stage_model = sd_hijack_clip.FrozenCLIPEmbedderWithCustomWords(m.cond_stage_model, self)
+
+ elif type(m.cond_stage_model) == ldm.modules.encoders.modules.FrozenOpenCLIPEmbedder:
+ m.cond_stage_model.model.token_embedding = EmbeddingsWithFixes(m.cond_stage_model.model.token_embedding, self)
+ m.cond_stage_model = sd_hijack_open_clip.FrozenOpenCLIPEmbedderWithCustomWords(m.cond_stage_model, self)
- apply_optimizations()
+ self.optimization_method = apply_optimizations()
+
+ self.clip = m.cond_stage_model
+
+ fix_checkpoint()
def flatten(el):
flattened = [flatten(children) for children in el.children()]
@@ -87,15 +120,22 @@ class StableDiffusionModelHijack:
self.layers = flatten(m)
def undo_hijack(self, m):
- if type(m.cond_stage_model) == FrozenCLIPEmbedderWithCustomWords:
+
+ if type(m.cond_stage_model) == xlmr.BertSeriesModelWithTransformation:
+ m.cond_stage_model = m.cond_stage_model.wrapped
+
+ elif type(m.cond_stage_model) == sd_hijack_clip.FrozenCLIPEmbedderWithCustomWords:
m.cond_stage_model = m.cond_stage_model.wrapped
- model_embeddings = m.cond_stage_model.transformer.text_model.embeddings
- if type(model_embeddings.token_embedding) == EmbeddingsWithFixes:
- model_embeddings.token_embedding = model_embeddings.token_embedding.wrapped
+ model_embeddings = m.cond_stage_model.transformer.text_model.embeddings
+ if type(model_embeddings.token_embedding) == EmbeddingsWithFixes:
+ model_embeddings.token_embedding = model_embeddings.token_embedding.wrapped
+ elif type(m.cond_stage_model) == sd_hijack_open_clip.FrozenOpenCLIPEmbedderWithCustomWords:
+ m.cond_stage_model.wrapped.model.token_embedding = m.cond_stage_model.wrapped.model.token_embedding.wrapped
+ m.cond_stage_model = m.cond_stage_model.wrapped
+ self.apply_circular(False)
self.layers = None
- self.circular_enabled = False
self.clip = None
def apply_circular(self, enable):
@@ -112,261 +152,8 @@ class StableDiffusionModelHijack:
def tokenize(self, text):
_, remade_batch_tokens, _, _, _, token_count = self.clip.process_text([text])
- return remade_batch_tokens[0], token_count, get_target_prompt_token_count(token_count)
-
-class FrozenCLIPEmbedderWithCustomWords(torch.nn.Module):
- def __init__(self, wrapped, hijack):
- super().__init__()
- self.wrapped = wrapped
- self.hijack: StableDiffusionModelHijack = hijack
- self.tokenizer = wrapped.tokenizer
- self.token_mults = {}
-
- self.comma_token = [v for k, v in self.tokenizer.get_vocab().items() if k == ',</w>'][0]
-
- tokens_with_parens = [(k, v) for k, v in self.tokenizer.get_vocab().items() if '(' in k or ')' in k or '[' in k or ']' in k]
- for text, ident in tokens_with_parens:
- mult = 1.0
- for c in text:
- if c == '[':
- mult /= 1.1
- if c == ']':
- mult *= 1.1
- if c == '(':
- mult *= 1.1
- if c == ')':
- mult /= 1.1
-
- if mult != 1.0:
- self.token_mults[ident] = mult
-
- def tokenize_line(self, line, used_custom_terms, hijack_comments):
- id_end = self.wrapped.tokenizer.eos_token_id
-
- if opts.enable_emphasis:
- parsed = prompt_parser.parse_prompt_attention(line)
- else:
- parsed = [[line, 1.0]]
-
- tokenized = self.wrapped.tokenizer([text for text, _ in parsed], truncation=False, add_special_tokens=False)["input_ids"]
-
- fixes = []
- remade_tokens = []
- multipliers = []
- last_comma = -1
-
- for tokens, (text, weight) in zip(tokenized, parsed):
- i = 0
- while i < len(tokens):
- token = tokens[i]
-
- embedding, embedding_length_in_tokens = self.hijack.embedding_db.find_embedding_at_position(tokens, i)
-
- if token == self.comma_token:
- last_comma = len(remade_tokens)
- elif opts.comma_padding_backtrack != 0 and max(len(remade_tokens), 1) % 75 == 0 and last_comma != -1 and len(remade_tokens) - last_comma <= opts.comma_padding_backtrack:
- last_comma += 1
- reloc_tokens = remade_tokens[last_comma:]
- reloc_mults = multipliers[last_comma:]
-
- remade_tokens = remade_tokens[:last_comma]
- length = len(remade_tokens)
-
- rem = int(math.ceil(length / 75)) * 75 - length
- remade_tokens += [id_end] * rem + reloc_tokens
- multipliers = multipliers[:last_comma] + [1.0] * rem + reloc_mults
-
- if embedding is None:
- remade_tokens.append(token)
- multipliers.append(weight)
- i += 1
- else:
- emb_len = int(embedding.vec.shape[0])
- iteration = len(remade_tokens) // 75
- if (len(remade_tokens) + emb_len) // 75 != iteration:
- rem = (75 * (iteration + 1) - len(remade_tokens))
- remade_tokens += [id_end] * rem
- multipliers += [1.0] * rem
- iteration += 1
- fixes.append((iteration, (len(remade_tokens) % 75, embedding)))
- remade_tokens += [0] * emb_len
- multipliers += [weight] * emb_len
- used_custom_terms.append((embedding.name, embedding.checksum()))
- i += embedding_length_in_tokens
-
- token_count = len(remade_tokens)
- prompt_target_length = get_target_prompt_token_count(token_count)
- tokens_to_add = prompt_target_length - len(remade_tokens)
-
- remade_tokens = remade_tokens + [id_end] * tokens_to_add
- multipliers = multipliers + [1.0] * tokens_to_add
-
- return remade_tokens, fixes, multipliers, token_count
-
- def process_text(self, texts):
- used_custom_terms = []
- remade_batch_tokens = []
- hijack_comments = []
- hijack_fixes = []
- token_count = 0
-
- cache = {}
- batch_multipliers = []
- for line in texts:
- if line in cache:
- remade_tokens, fixes, multipliers = cache[line]
- else:
- remade_tokens, fixes, multipliers, current_token_count = self.tokenize_line(line, used_custom_terms, hijack_comments)
- token_count = max(current_token_count, token_count)
-
- cache[line] = (remade_tokens, fixes, multipliers)
-
- remade_batch_tokens.append(remade_tokens)
- hijack_fixes.append(fixes)
- batch_multipliers.append(multipliers)
-
- return batch_multipliers, remade_batch_tokens, used_custom_terms, hijack_comments, hijack_fixes, token_count
-
- def process_text_old(self, text):
- id_start = self.wrapped.tokenizer.bos_token_id
- id_end = self.wrapped.tokenizer.eos_token_id
- maxlen = self.wrapped.max_length # you get to stay at 77
- used_custom_terms = []
- remade_batch_tokens = []
- overflowing_words = []
- hijack_comments = []
- hijack_fixes = []
- token_count = 0
-
- cache = {}
- batch_tokens = self.wrapped.tokenizer(text, truncation=False, add_special_tokens=False)["input_ids"]
- batch_multipliers = []
- for tokens in batch_tokens:
- tuple_tokens = tuple(tokens)
-
- if tuple_tokens in cache:
- remade_tokens, fixes, multipliers = cache[tuple_tokens]
- else:
- fixes = []
- remade_tokens = []
- multipliers = []
- mult = 1.0
-
- i = 0
- while i < len(tokens):
- token = tokens[i]
-
- embedding, embedding_length_in_tokens = self.hijack.embedding_db.find_embedding_at_position(tokens, i)
-
- mult_change = self.token_mults.get(token) if opts.enable_emphasis else None
- if mult_change is not None:
- mult *= mult_change
- i += 1
- elif embedding is None:
- remade_tokens.append(token)
- multipliers.append(mult)
- i += 1
- else:
- emb_len = int(embedding.vec.shape[0])
- fixes.append((len(remade_tokens), embedding))
- remade_tokens += [0] * emb_len
- multipliers += [mult] * emb_len
- used_custom_terms.append((embedding.name, embedding.checksum()))
- i += embedding_length_in_tokens
-
- if len(remade_tokens) > maxlen - 2:
- vocab = {v: k for k, v in self.wrapped.tokenizer.get_vocab().items()}
- ovf = remade_tokens[maxlen - 2:]
- overflowing_words = [vocab.get(int(x), "") for x in ovf]
- overflowing_text = self.wrapped.tokenizer.convert_tokens_to_string(''.join(overflowing_words))
- hijack_comments.append(f"Warning: too many input tokens; some ({len(overflowing_words)}) have been truncated:\n{overflowing_text}\n")
-
- token_count = len(remade_tokens)
- remade_tokens = remade_tokens + [id_end] * (maxlen - 2 - len(remade_tokens))
- remade_tokens = [id_start] + remade_tokens[0:maxlen - 2] + [id_end]
- cache[tuple_tokens] = (remade_tokens, fixes, multipliers)
-
- multipliers = multipliers + [1.0] * (maxlen - 2 - len(multipliers))
- multipliers = [1.0] + multipliers[0:maxlen - 2] + [1.0]
-
- remade_batch_tokens.append(remade_tokens)
- hijack_fixes.append(fixes)
- batch_multipliers.append(multipliers)
- return batch_multipliers, remade_batch_tokens, used_custom_terms, hijack_comments, hijack_fixes, token_count
-
- def forward(self, text):
- use_old = opts.use_old_emphasis_implementation
- if use_old:
- batch_multipliers, remade_batch_tokens, used_custom_terms, hijack_comments, hijack_fixes, token_count = self.process_text_old(text)
- else:
- batch_multipliers, remade_batch_tokens, used_custom_terms, hijack_comments, hijack_fixes, token_count = self.process_text(text)
-
- self.hijack.comments += hijack_comments
-
- if len(used_custom_terms) > 0:
- self.hijack.comments.append("Used embeddings: " + ", ".join([f'{word} [{checksum}]' for word, checksum in used_custom_terms]))
-
- if use_old:
- self.hijack.fixes = hijack_fixes
- return self.process_tokens(remade_batch_tokens, batch_multipliers)
-
- z = None
- i = 0
- while max(map(len, remade_batch_tokens)) != 0:
- rem_tokens = [x[75:] for x in remade_batch_tokens]
- rem_multipliers = [x[75:] for x in batch_multipliers]
-
- self.hijack.fixes = []
- for unfiltered in hijack_fixes:
- fixes = []
- for fix in unfiltered:
- if fix[0] == i:
- fixes.append(fix[1])
- self.hijack.fixes.append(fixes)
-
- tokens = []
- multipliers = []
- for j in range(len(remade_batch_tokens)):
- if len(remade_batch_tokens[j]) > 0:
- tokens.append(remade_batch_tokens[j][:75])
- multipliers.append(batch_multipliers[j][:75])
- else:
- tokens.append([self.wrapped.tokenizer.eos_token_id] * 75)
- multipliers.append([1.0] * 75)
-
- z1 = self.process_tokens(tokens, multipliers)
- z = z1 if z is None else torch.cat((z, z1), axis=-2)
-
- remade_batch_tokens = rem_tokens
- batch_multipliers = rem_multipliers
- i += 1
-
- return z
-
- def process_tokens(self, remade_batch_tokens, batch_multipliers):
- if not opts.use_old_emphasis_implementation:
- remade_batch_tokens = [[self.wrapped.tokenizer.bos_token_id] + x[:75] + [self.wrapped.tokenizer.eos_token_id] for x in remade_batch_tokens]
- batch_multipliers = [[1.0] + x[:75] + [1.0] for x in batch_multipliers]
-
- tokens = torch.asarray(remade_batch_tokens).to(device)
- outputs = self.wrapped.transformer(input_ids=tokens, output_hidden_states=-opts.CLIP_stop_at_last_layers)
-
- if opts.CLIP_stop_at_last_layers > 1:
- z = outputs.hidden_states[-opts.CLIP_stop_at_last_layers]
- z = self.wrapped.transformer.text_model.final_layer_norm(z)
- else:
- z = outputs.last_hidden_state
-
- # restoring original mean is likely not correct, but it seems to work well to prevent artifacts that happen otherwise
- batch_multipliers_of_same_length = [x + [1.0] * (75 - len(x)) for x in batch_multipliers]
- batch_multipliers = torch.asarray(batch_multipliers_of_same_length).to(device)
- original_mean = z.mean()
- z *= batch_multipliers.reshape(batch_multipliers.shape + (1,)).expand(z.shape)
- new_mean = z.mean()
- z *= original_mean / new_mean
-
- return z
+ return remade_batch_tokens[0], token_count, sd_hijack_clip.get_target_prompt_token_count(token_count)
class EmbeddingsWithFixes(torch.nn.Module):
@@ -406,3 +193,19 @@ def add_circular_option_to_conv_2d():
model_hijack = StableDiffusionModelHijack()
+
+
+def register_buffer(self, name, attr):
+ """
+ Fix register buffer bug for Mac OS.
+ """
+
+ if type(attr) == torch.Tensor:
+ if attr.device != devices.device:
+ attr = attr.to(device=devices.device, dtype=(torch.float32 if devices.device.type == 'mps' else None))
+
+ setattr(self, name, attr)
+
+
+ldm.models.diffusion.ddim.DDIMSampler.register_buffer = register_buffer
+ldm.models.diffusion.plms.PLMSSampler.register_buffer = register_buffer
diff --git a/modules/sd_hijack_checkpoint.py b/modules/sd_hijack_checkpoint.py
new file mode 100644
index 00000000..5712972f
--- /dev/null
+++ b/modules/sd_hijack_checkpoint.py
@@ -0,0 +1,10 @@
+from torch.utils.checkpoint import checkpoint
+
+def BasicTransformerBlock_forward(self, x, context=None):
+ return checkpoint(self._forward, x, context)
+
+def AttentionBlock_forward(self, x):
+ return checkpoint(self._forward, x)
+
+def ResBlock_forward(self, x, emb):
+ return checkpoint(self._forward, x, emb) \ No newline at end of file
diff --git a/modules/sd_hijack_clip.py b/modules/sd_hijack_clip.py
new file mode 100644
index 00000000..ca92b142
--- /dev/null
+++ b/modules/sd_hijack_clip.py
@@ -0,0 +1,303 @@
+import math
+
+import torch
+
+from modules import prompt_parser, devices
+from modules.shared import opts
+
+def get_target_prompt_token_count(token_count):
+ return math.ceil(max(token_count, 1) / 75) * 75
+
+
+class FrozenCLIPEmbedderWithCustomWordsBase(torch.nn.Module):
+ def __init__(self, wrapped, hijack):
+ super().__init__()
+ self.wrapped = wrapped
+ self.hijack = hijack
+
+ def tokenize(self, texts):
+ raise NotImplementedError
+
+ def encode_with_transformers(self, tokens):
+ raise NotImplementedError
+
+ def encode_embedding_init_text(self, init_text, nvpt):
+ raise NotImplementedError
+
+ def tokenize_line(self, line, used_custom_terms, hijack_comments):
+ if opts.enable_emphasis:
+ parsed = prompt_parser.parse_prompt_attention(line)
+ else:
+ parsed = [[line, 1.0]]
+
+ tokenized = self.tokenize([text for text, _ in parsed])
+
+ fixes = []
+ remade_tokens = []
+ multipliers = []
+ last_comma = -1
+
+ for tokens, (text, weight) in zip(tokenized, parsed):
+ i = 0
+ while i < len(tokens):
+ token = tokens[i]
+
+ embedding, embedding_length_in_tokens = self.hijack.embedding_db.find_embedding_at_position(tokens, i)
+
+ if token == self.comma_token:
+ last_comma = len(remade_tokens)
+ elif opts.comma_padding_backtrack != 0 and max(len(remade_tokens), 1) % 75 == 0 and last_comma != -1 and len(remade_tokens) - last_comma <= opts.comma_padding_backtrack:
+ last_comma += 1
+ reloc_tokens = remade_tokens[last_comma:]
+ reloc_mults = multipliers[last_comma:]
+
+ remade_tokens = remade_tokens[:last_comma]
+ length = len(remade_tokens)
+
+ rem = int(math.ceil(length / 75)) * 75 - length
+ remade_tokens += [self.id_end] * rem + reloc_tokens
+ multipliers = multipliers[:last_comma] + [1.0] * rem + reloc_mults
+
+ if embedding is None:
+ remade_tokens.append(token)
+ multipliers.append(weight)
+ i += 1
+ else:
+ emb_len = int(embedding.vec.shape[0])
+ iteration = len(remade_tokens) // 75
+ if (len(remade_tokens) + emb_len) // 75 != iteration:
+ rem = (75 * (iteration + 1) - len(remade_tokens))
+ remade_tokens += [self.id_end] * rem
+ multipliers += [1.0] * rem
+ iteration += 1
+ fixes.append((iteration, (len(remade_tokens) % 75, embedding)))
+ remade_tokens += [0] * emb_len
+ multipliers += [weight] * emb_len
+ used_custom_terms.append((embedding.name, embedding.checksum()))
+ i += embedding_length_in_tokens
+
+ token_count = len(remade_tokens)
+ prompt_target_length = get_target_prompt_token_count(token_count)
+ tokens_to_add = prompt_target_length - len(remade_tokens)
+
+ remade_tokens = remade_tokens + [self.id_end] * tokens_to_add
+ multipliers = multipliers + [1.0] * tokens_to_add
+
+ return remade_tokens, fixes, multipliers, token_count
+
+ def process_text(self, texts):
+ used_custom_terms = []
+ remade_batch_tokens = []
+ hijack_comments = []
+ hijack_fixes = []
+ token_count = 0
+
+ cache = {}
+ batch_multipliers = []
+ for line in texts:
+ if line in cache:
+ remade_tokens, fixes, multipliers = cache[line]
+ else:
+ remade_tokens, fixes, multipliers, current_token_count = self.tokenize_line(line, used_custom_terms, hijack_comments)
+ token_count = max(current_token_count, token_count)
+
+ cache[line] = (remade_tokens, fixes, multipliers)
+
+ remade_batch_tokens.append(remade_tokens)
+ hijack_fixes.append(fixes)
+ batch_multipliers.append(multipliers)
+
+ return batch_multipliers, remade_batch_tokens, used_custom_terms, hijack_comments, hijack_fixes, token_count
+
+ def process_text_old(self, texts):
+ id_start = self.id_start
+ id_end = self.id_end
+ maxlen = self.wrapped.max_length # you get to stay at 77
+ used_custom_terms = []
+ remade_batch_tokens = []
+ hijack_comments = []
+ hijack_fixes = []
+ token_count = 0
+
+ cache = {}
+ batch_tokens = self.tokenize(texts)
+ batch_multipliers = []
+ for tokens in batch_tokens:
+ tuple_tokens = tuple(tokens)
+
+ if tuple_tokens in cache:
+ remade_tokens, fixes, multipliers = cache[tuple_tokens]
+ else:
+ fixes = []
+ remade_tokens = []
+ multipliers = []
+ mult = 1.0
+
+ i = 0
+ while i < len(tokens):
+ token = tokens[i]
+
+ embedding, embedding_length_in_tokens = self.hijack.embedding_db.find_embedding_at_position(tokens, i)
+
+ mult_change = self.token_mults.get(token) if opts.enable_emphasis else None
+ if mult_change is not None:
+ mult *= mult_change
+ i += 1
+ elif embedding is None:
+ remade_tokens.append(token)
+ multipliers.append(mult)
+ i += 1
+ else:
+ emb_len = int(embedding.vec.shape[0])
+ fixes.append((len(remade_tokens), embedding))
+ remade_tokens += [0] * emb_len
+ multipliers += [mult] * emb_len
+ used_custom_terms.append((embedding.name, embedding.checksum()))
+ i += embedding_length_in_tokens
+
+ if len(remade_tokens) > maxlen - 2:
+ vocab = {v: k for k, v in self.wrapped.tokenizer.get_vocab().items()}
+ ovf = remade_tokens[maxlen - 2:]
+ overflowing_words = [vocab.get(int(x), "") for x in ovf]
+ overflowing_text = self.wrapped.tokenizer.convert_tokens_to_string(''.join(overflowing_words))
+ hijack_comments.append(f"Warning: too many input tokens; some ({len(overflowing_words)}) have been truncated:\n{overflowing_text}\n")
+
+ token_count = len(remade_tokens)
+ remade_tokens = remade_tokens + [id_end] * (maxlen - 2 - len(remade_tokens))
+ remade_tokens = [id_start] + remade_tokens[0:maxlen - 2] + [id_end]
+ cache[tuple_tokens] = (remade_tokens, fixes, multipliers)
+
+ multipliers = multipliers + [1.0] * (maxlen - 2 - len(multipliers))
+ multipliers = [1.0] + multipliers[0:maxlen - 2] + [1.0]
+
+ remade_batch_tokens.append(remade_tokens)
+ hijack_fixes.append(fixes)
+ batch_multipliers.append(multipliers)
+ return batch_multipliers, remade_batch_tokens, used_custom_terms, hijack_comments, hijack_fixes, token_count
+
+ def forward(self, text):
+ use_old = opts.use_old_emphasis_implementation
+ if use_old:
+ batch_multipliers, remade_batch_tokens, used_custom_terms, hijack_comments, hijack_fixes, token_count = self.process_text_old(text)
+ else:
+ batch_multipliers, remade_batch_tokens, used_custom_terms, hijack_comments, hijack_fixes, token_count = self.process_text(text)
+
+ self.hijack.comments += hijack_comments
+
+ if len(used_custom_terms) > 0:
+ self.hijack.comments.append("Used embeddings: " + ", ".join([f'{word} [{checksum}]' for word, checksum in used_custom_terms]))
+
+ if use_old:
+ self.hijack.fixes = hijack_fixes
+ return self.process_tokens(remade_batch_tokens, batch_multipliers)
+
+ z = None
+ i = 0
+ while max(map(len, remade_batch_tokens)) != 0:
+ rem_tokens = [x[75:] for x in remade_batch_tokens]
+ rem_multipliers = [x[75:] for x in batch_multipliers]
+
+ self.hijack.fixes = []
+ for unfiltered in hijack_fixes:
+ fixes = []
+ for fix in unfiltered:
+ if fix[0] == i:
+ fixes.append(fix[1])
+ self.hijack.fixes.append(fixes)
+
+ tokens = []
+ multipliers = []
+ for j in range(len(remade_batch_tokens)):
+ if len(remade_batch_tokens[j]) > 0:
+ tokens.append(remade_batch_tokens[j][:75])
+ multipliers.append(batch_multipliers[j][:75])
+ else:
+ tokens.append([self.id_end] * 75)
+ multipliers.append([1.0] * 75)
+
+ z1 = self.process_tokens(tokens, multipliers)
+ z = z1 if z is None else torch.cat((z, z1), axis=-2)
+
+ remade_batch_tokens = rem_tokens
+ batch_multipliers = rem_multipliers
+ i += 1
+
+ return z
+
+ def process_tokens(self, remade_batch_tokens, batch_multipliers):
+ if not opts.use_old_emphasis_implementation:
+ remade_batch_tokens = [[self.id_start] + x[:75] + [self.id_end] for x in remade_batch_tokens]
+ batch_multipliers = [[1.0] + x[:75] + [1.0] for x in batch_multipliers]
+
+ tokens = torch.asarray(remade_batch_tokens).to(devices.device)
+
+ if self.id_end != self.id_pad:
+ for batch_pos in range(len(remade_batch_tokens)):
+ index = remade_batch_tokens[batch_pos].index(self.id_end)
+ tokens[batch_pos, index+1:tokens.shape[1]] = self.id_pad
+
+ z = self.encode_with_transformers(tokens)
+
+ # restoring original mean is likely not correct, but it seems to work well to prevent artifacts that happen otherwise
+ batch_multipliers_of_same_length = [x + [1.0] * (75 - len(x)) for x in batch_multipliers]
+ batch_multipliers = torch.asarray(batch_multipliers_of_same_length).to(devices.device)
+ original_mean = z.mean()
+ z *= batch_multipliers.reshape(batch_multipliers.shape + (1,)).expand(z.shape)
+ new_mean = z.mean()
+ z *= original_mean / new_mean
+
+ return z
+
+
+class FrozenCLIPEmbedderWithCustomWords(FrozenCLIPEmbedderWithCustomWordsBase):
+ def __init__(self, wrapped, hijack):
+ super().__init__(wrapped, hijack)
+ self.tokenizer = wrapped.tokenizer
+
+ vocab = self.tokenizer.get_vocab()
+
+ self.comma_token = vocab.get(',</w>', None)
+
+ self.token_mults = {}
+ tokens_with_parens = [(k, v) for k, v in vocab.items() if '(' in k or ')' in k or '[' in k or ']' in k]
+ for text, ident in tokens_with_parens:
+ mult = 1.0
+ for c in text:
+ if c == '[':
+ mult /= 1.1
+ if c == ']':
+ mult *= 1.1
+ if c == '(':
+ mult *= 1.1
+ if c == ')':
+ mult /= 1.1
+
+ if mult != 1.0:
+ self.token_mults[ident] = mult
+
+ self.id_start = self.wrapped.tokenizer.bos_token_id
+ self.id_end = self.wrapped.tokenizer.eos_token_id
+ self.id_pad = self.id_end
+
+ def tokenize(self, texts):
+ tokenized = self.wrapped.tokenizer(texts, truncation=False, add_special_tokens=False)["input_ids"]
+
+ return tokenized
+
+ def encode_with_transformers(self, tokens):
+ outputs = self.wrapped.transformer(input_ids=tokens, output_hidden_states=-opts.CLIP_stop_at_last_layers)
+
+ if opts.CLIP_stop_at_last_layers > 1:
+ z = outputs.hidden_states[-opts.CLIP_stop_at_last_layers]
+ z = self.wrapped.transformer.text_model.final_layer_norm(z)
+ else:
+ z = outputs.last_hidden_state
+
+ return z
+
+ def encode_embedding_init_text(self, init_text, nvpt):
+ embedding_layer = self.wrapped.transformer.text_model.embeddings
+ ids = self.wrapped.tokenizer(init_text, max_length=nvpt, return_tensors="pt", add_special_tokens=False)["input_ids"]
+ embedded = embedding_layer.token_embedding.wrapped(ids.to(embedding_layer.token_embedding.wrapped.weight.device)).squeeze(0)
+
+ return embedded
diff --git a/modules/sd_hijack_inpainting.py b/modules/sd_hijack_inpainting.py
index fd92a335..31d2c898 100644
--- a/modules/sd_hijack_inpainting.py
+++ b/modules/sd_hijack_inpainting.py
@@ -1,3 +1,4 @@
+import os
import torch
from einops import repeat
@@ -11,196 +12,11 @@ from ldm.models.diffusion.ddpm import LatentDiffusion
from ldm.models.diffusion.plms import PLMSSampler
from ldm.models.diffusion.ddim import DDIMSampler, noise_like
-# =================================================================================================
-# Monkey patch DDIMSampler methods from RunwayML repo directly.
-# Adapted from:
-# https://github.com/runwayml/stable-diffusion/blob/main/ldm/models/diffusion/ddim.py
-# =================================================================================================
-@torch.no_grad()
-def sample_ddim(self,
- S,
- batch_size,
- shape,
- conditioning=None,
- callback=None,
- normals_sequence=None,
- img_callback=None,
- quantize_x0=False,
- eta=0.,
- mask=None,
- x0=None,
- temperature=1.,
- noise_dropout=0.,
- score_corrector=None,
- corrector_kwargs=None,
- verbose=True,
- x_T=None,
- log_every_t=100,
- unconditional_guidance_scale=1.,
- unconditional_conditioning=None,
- # this has to come in the same format as the conditioning, # e.g. as encoded tokens, ...
- **kwargs
- ):
- if conditioning is not None:
- if isinstance(conditioning, dict):
- ctmp = conditioning[list(conditioning.keys())[0]]
- while isinstance(ctmp, list):
- ctmp = ctmp[0]
- cbs = ctmp.shape[0]
- if cbs != batch_size:
- print(f"Warning: Got {cbs} conditionings but batch-size is {batch_size}")
- else:
- if conditioning.shape[0] != batch_size:
- print(f"Warning: Got {conditioning.shape[0]} conditionings but batch-size is {batch_size}")
-
- self.make_schedule(ddim_num_steps=S, ddim_eta=eta, verbose=verbose)
- # sampling
- C, H, W = shape
- size = (batch_size, C, H, W)
- print(f'Data shape for DDIM sampling is {size}, eta {eta}')
-
- samples, intermediates = self.ddim_sampling(conditioning, size,
- callback=callback,
- img_callback=img_callback,
- quantize_denoised=quantize_x0,
- mask=mask, x0=x0,
- ddim_use_original_steps=False,
- noise_dropout=noise_dropout,
- temperature=temperature,
- score_corrector=score_corrector,
- corrector_kwargs=corrector_kwargs,
- x_T=x_T,
- log_every_t=log_every_t,
- unconditional_guidance_scale=unconditional_guidance_scale,
- unconditional_conditioning=unconditional_conditioning,
- )
- return samples, intermediates
-
-@torch.no_grad()
-def p_sample_ddim(self, x, c, t, index, repeat_noise=False, use_original_steps=False, quantize_denoised=False,
- temperature=1., noise_dropout=0., score_corrector=None, corrector_kwargs=None,
- unconditional_guidance_scale=1., unconditional_conditioning=None):
- b, *_, device = *x.shape, x.device
-
- if unconditional_conditioning is None or unconditional_guidance_scale == 1.:
- e_t = self.model.apply_model(x, t, c)
- else:
- x_in = torch.cat([x] * 2)
- t_in = torch.cat([t] * 2)
- if isinstance(c, dict):
- assert isinstance(unconditional_conditioning, dict)
- c_in = dict()
- for k in c:
- if isinstance(c[k], list):
- c_in[k] = [
- torch.cat([unconditional_conditioning[k][i], c[k][i]])
- for i in range(len(c[k]))
- ]
- else:
- c_in[k] = torch.cat([unconditional_conditioning[k], c[k]])
- else:
- c_in = torch.cat([unconditional_conditioning, c])
- e_t_uncond, e_t = self.model.apply_model(x_in, t_in, c_in).chunk(2)
- e_t = e_t_uncond + unconditional_guidance_scale * (e_t - e_t_uncond)
-
- if score_corrector is not None:
- assert self.model.parameterization == "eps"
- e_t = score_corrector.modify_score(self.model, e_t, x, t, c, **corrector_kwargs)
-
- alphas = self.model.alphas_cumprod if use_original_steps else self.ddim_alphas
- alphas_prev = self.model.alphas_cumprod_prev if use_original_steps else self.ddim_alphas_prev
- sqrt_one_minus_alphas = self.model.sqrt_one_minus_alphas_cumprod if use_original_steps else self.ddim_sqrt_one_minus_alphas
- sigmas = self.model.ddim_sigmas_for_original_num_steps if use_original_steps else self.ddim_sigmas
- # select parameters corresponding to the currently considered timestep
- a_t = torch.full((b, 1, 1, 1), alphas[index], device=device)
- a_prev = torch.full((b, 1, 1, 1), alphas_prev[index], device=device)
- sigma_t = torch.full((b, 1, 1, 1), sigmas[index], device=device)
- sqrt_one_minus_at = torch.full((b, 1, 1, 1), sqrt_one_minus_alphas[index],device=device)
-
- # current prediction for x_0
- pred_x0 = (x - sqrt_one_minus_at * e_t) / a_t.sqrt()
- if quantize_denoised:
- pred_x0, _, *_ = self.model.first_stage_model.quantize(pred_x0)
- # direction pointing to x_t
- dir_xt = (1. - a_prev - sigma_t**2).sqrt() * e_t
- noise = sigma_t * noise_like(x.shape, device, repeat_noise) * temperature
- if noise_dropout > 0.:
- noise = torch.nn.functional.dropout(noise, p=noise_dropout)
- x_prev = a_prev.sqrt() * pred_x0 + dir_xt + noise
- return x_prev, pred_x0
-
-
-# =================================================================================================
-# Monkey patch PLMSSampler methods.
-# This one was not actually patched correctly in the RunwayML repo, but we can replicate the changes.
-# Adapted from:
-# https://github.com/CompVis/stable-diffusion/blob/main/ldm/models/diffusion/plms.py
-# =================================================================================================
-@torch.no_grad()
-def sample_plms(self,
- S,
- batch_size,
- shape,
- conditioning=None,
- callback=None,
- normals_sequence=None,
- img_callback=None,
- quantize_x0=False,
- eta=0.,
- mask=None,
- x0=None,
- temperature=1.,
- noise_dropout=0.,
- score_corrector=None,
- corrector_kwargs=None,
- verbose=True,
- x_T=None,
- log_every_t=100,
- unconditional_guidance_scale=1.,
- unconditional_conditioning=None,
- # this has to come in the same format as the conditioning, # e.g. as encoded tokens, ...
- **kwargs
- ):
- if conditioning is not None:
- if isinstance(conditioning, dict):
- ctmp = conditioning[list(conditioning.keys())[0]]
- while isinstance(ctmp, list):
- ctmp = ctmp[0]
- cbs = ctmp.shape[0]
- if cbs != batch_size:
- print(f"Warning: Got {cbs} conditionings but batch-size is {batch_size}")
- else:
- if conditioning.shape[0] != batch_size:
- print(f"Warning: Got {conditioning.shape[0]} conditionings but batch-size is {batch_size}")
-
- self.make_schedule(ddim_num_steps=S, ddim_eta=eta, verbose=verbose)
- # sampling
- C, H, W = shape
- size = (batch_size, C, H, W)
- print(f'Data shape for PLMS sampling is {size}')
-
- samples, intermediates = self.plms_sampling(conditioning, size,
- callback=callback,
- img_callback=img_callback,
- quantize_denoised=quantize_x0,
- mask=mask, x0=x0,
- ddim_use_original_steps=False,
- noise_dropout=noise_dropout,
- temperature=temperature,
- score_corrector=score_corrector,
- corrector_kwargs=corrector_kwargs,
- x_T=x_T,
- log_every_t=log_every_t,
- unconditional_guidance_scale=unconditional_guidance_scale,
- unconditional_conditioning=unconditional_conditioning,
- )
- return samples, intermediates
-
@torch.no_grad()
def p_sample_plms(self, x, c, t, index, repeat_noise=False, use_original_steps=False, quantize_denoised=False,
- temperature=1., noise_dropout=0., score_corrector=None, corrector_kwargs=None,
- unconditional_guidance_scale=1., unconditional_conditioning=None, old_eps=None, t_next=None):
+ temperature=1., noise_dropout=0., score_corrector=None, corrector_kwargs=None,
+ unconditional_guidance_scale=1., unconditional_conditioning=None, old_eps=None, t_next=None, dynamic_threshold=None):
b, *_, device = *x.shape, x.device
def get_model_output(x, t):
@@ -209,7 +25,7 @@ def p_sample_plms(self, x, c, t, index, repeat_noise=False, use_original_steps=F
else:
x_in = torch.cat([x] * 2)
t_in = torch.cat([t] * 2)
-
+
if isinstance(c, dict):
assert isinstance(unconditional_conditioning, dict)
c_in = dict()
@@ -249,6 +65,8 @@ def p_sample_plms(self, x, c, t, index, repeat_noise=False, use_original_steps=F
pred_x0 = (x - sqrt_one_minus_at * e_t) / a_t.sqrt()
if quantize_denoised:
pred_x0, _, *_ = self.model.first_stage_model.quantize(pred_x0)
+ if dynamic_threshold is not None:
+ pred_x0 = norm_thresholding(pred_x0, dynamic_threshold)
# direction pointing to x_t
dir_xt = (1. - a_prev - sigma_t**2).sqrt() * e_t
noise = sigma_t * noise_like(x.shape, device, repeat_noise) * temperature
@@ -276,56 +94,18 @@ def p_sample_plms(self, x, c, t, index, repeat_noise=False, use_original_steps=F
x_prev, pred_x0 = get_x_prev_and_pred_x0(e_t_prime, index)
return x_prev, pred_x0, e_t
-
-# =================================================================================================
-# Monkey patch LatentInpaintDiffusion to load the checkpoint with a proper config.
-# Adapted from:
-# https://github.com/runwayml/stable-diffusion/blob/main/ldm/models/diffusion/ddpm.py
-# =================================================================================================
-
-@torch.no_grad()
-def get_unconditional_conditioning(self, batch_size, null_label=None):
- if null_label is not None:
- xc = null_label
- if isinstance(xc, ListConfig):
- xc = list(xc)
- if isinstance(xc, dict) or isinstance(xc, list):
- c = self.get_learned_conditioning(xc)
- else:
- if hasattr(xc, "to"):
- xc = xc.to(self.device)
- c = self.get_learned_conditioning(xc)
- else:
- # todo: get null label from cond_stage_model
- raise NotImplementedError()
- c = repeat(c, "1 ... -> b ...", b=batch_size).to(self.device)
- return c
-class LatentInpaintDiffusion(LatentDiffusion):
- def __init__(
- self,
- concat_keys=("mask", "masked_image"),
- masked_image_key="masked_image",
- *args,
- **kwargs,
- ):
- super().__init__(*args, **kwargs)
- self.masked_image_key = masked_image_key
- assert self.masked_image_key in concat_keys
- self.concat_keys = concat_keys
+def should_hijack_inpainting(checkpoint_info):
+ from modules import sd_models
+ ckpt_basename = os.path.basename(checkpoint_info.filename).lower()
+ cfg_basename = os.path.basename(sd_models.find_checkpoint_config(checkpoint_info)).lower()
-def should_hijack_inpainting(checkpoint_info):
- return str(checkpoint_info.filename).endswith("inpainting.ckpt") and not checkpoint_info.config.endswith("inpainting.yaml")
+ return "inpainting" in ckpt_basename and not "inpainting" in cfg_basename
def do_inpainting_hijack():
- ldm.models.diffusion.ddpm.get_unconditional_conditioning = get_unconditional_conditioning
- ldm.models.diffusion.ddpm.LatentInpaintDiffusion = LatentInpaintDiffusion
-
- ldm.models.diffusion.ddim.DDIMSampler.p_sample_ddim = p_sample_ddim
- ldm.models.diffusion.ddim.DDIMSampler.sample = sample_ddim
+ # p_sample_plms is needed because PLMS can't work with dicts as conditionings
ldm.models.diffusion.plms.PLMSSampler.p_sample_plms = p_sample_plms
- ldm.models.diffusion.plms.PLMSSampler.sample = sample_plms \ No newline at end of file
diff --git a/modules/sd_hijack_open_clip.py b/modules/sd_hijack_open_clip.py
new file mode 100644
index 00000000..f733e852
--- /dev/null
+++ b/modules/sd_hijack_open_clip.py
@@ -0,0 +1,37 @@
+import open_clip.tokenizer
+import torch
+
+from modules import sd_hijack_clip, devices
+from modules.shared import opts
+
+tokenizer = open_clip.tokenizer._tokenizer
+
+
+class FrozenOpenCLIPEmbedderWithCustomWords(sd_hijack_clip.FrozenCLIPEmbedderWithCustomWordsBase):
+ def __init__(self, wrapped, hijack):
+ super().__init__(wrapped, hijack)
+
+ self.comma_token = [v for k, v in tokenizer.encoder.items() if k == ',</w>'][0]
+ self.id_start = tokenizer.encoder["<start_of_text>"]
+ self.id_end = tokenizer.encoder["<end_of_text>"]
+ self.id_pad = 0
+
+ def tokenize(self, texts):
+ assert not opts.use_old_emphasis_implementation, 'Old emphasis implementation not supported for Open Clip'
+
+ tokenized = [tokenizer.encode(text) for text in texts]
+
+ return tokenized
+
+ def encode_with_transformers(self, tokens):
+ # set self.wrapped.layer_idx here according to opts.CLIP_stop_at_last_layers
+ z = self.wrapped.encode_with_transformer(tokens)
+
+ return z
+
+ def encode_embedding_init_text(self, init_text, nvpt):
+ ids = tokenizer.encode(init_text)
+ ids = torch.asarray([ids], device=devices.device, dtype=torch.int)
+ embedded = self.wrapped.model.token_embedding.wrapped(ids).squeeze(0)
+
+ return embedded
diff --git a/modules/sd_hijack_optimizations.py b/modules/sd_hijack_optimizations.py
index 98123fbf..02c87f40 100644
--- a/modules/sd_hijack_optimizations.py
+++ b/modules/sd_hijack_optimizations.py
@@ -127,7 +127,7 @@ def check_for_psutil():
invokeAI_mps_available = check_for_psutil()
-# -- Taken from https://github.com/invoke-ai/InvokeAI --
+# -- Taken from https://github.com/invoke-ai/InvokeAI and modified --
if invokeAI_mps_available:
import psutil
mem_total_gb = psutil.virtual_memory().total // (1 << 30)
@@ -152,14 +152,16 @@ def einsum_op_slice_1(q, k, v, slice_size):
return r
def einsum_op_mps_v1(q, k, v):
- if q.shape[1] <= 4096: # (512x512) max q.shape[1]: 4096
+ if q.shape[0] * q.shape[1] <= 2**16: # (512x512) max q.shape[1]: 4096
return einsum_op_compvis(q, k, v)
else:
slice_size = math.floor(2**30 / (q.shape[0] * q.shape[1]))
+ if slice_size % 4096 == 0:
+ slice_size -= 1
return einsum_op_slice_1(q, k, v, slice_size)
def einsum_op_mps_v2(q, k, v):
- if mem_total_gb > 8 and q.shape[1] <= 4096:
+ if mem_total_gb > 8 and q.shape[0] * q.shape[1] <= 2**16:
return einsum_op_compvis(q, k, v)
else:
return einsum_op_slice_0(q, k, v, 1)
@@ -188,7 +190,7 @@ def einsum_op(q, k, v):
return einsum_op_cuda(q, k, v)
if q.device.type == 'mps':
- if mem_total_gb >= 32:
+ if mem_total_gb >= 32 and q.shape[0] % 32 != 0 and q.shape[0] * q.shape[1] < 2**18:
return einsum_op_mps_v1(q, k, v)
return einsum_op_mps_v2(q, k, v)
diff --git a/modules/sd_hijack_unet.py b/modules/sd_hijack_unet.py
new file mode 100644
index 00000000..18daf8c1
--- /dev/null
+++ b/modules/sd_hijack_unet.py
@@ -0,0 +1,30 @@
+import torch
+
+
+class TorchHijackForUnet:
+ """
+ This is torch, but with cat that resizes tensors to appropriate dimensions if they do not match;
+ this makes it possible to create pictures with dimensions that are multiples of 8 rather than 64
+ """
+
+ def __getattr__(self, item):
+ if item == 'cat':
+ return self.cat
+
+ if hasattr(torch, item):
+ return getattr(torch, item)
+
+ raise AttributeError("'{}' object has no attribute '{}'".format(type(self).__name__, item))
+
+ def cat(self, tensors, *args, **kwargs):
+ if len(tensors) == 2:
+ a, b = tensors
+ if a.shape[-2:] != b.shape[-2:]:
+ a = torch.nn.functional.interpolate(a, b.shape[-2:], mode="nearest")
+
+ tensors = (a, b)
+
+ return torch.cat(tensors, *args, **kwargs)
+
+
+th = TorchHijackForUnet()
diff --git a/modules/sd_hijack_xlmr.py b/modules/sd_hijack_xlmr.py
new file mode 100644
index 00000000..4ac51c38
--- /dev/null
+++ b/modules/sd_hijack_xlmr.py
@@ -0,0 +1,34 @@
+import open_clip.tokenizer
+import torch
+
+from modules import sd_hijack_clip, devices
+from modules.shared import opts
+
+
+class FrozenXLMREmbedderWithCustomWords(sd_hijack_clip.FrozenCLIPEmbedderWithCustomWords):
+ def __init__(self, wrapped, hijack):
+ super().__init__(wrapped, hijack)
+
+ self.id_start = wrapped.config.bos_token_id
+ self.id_end = wrapped.config.eos_token_id
+ self.id_pad = wrapped.config.pad_token_id
+
+ self.comma_token = self.tokenizer.get_vocab().get(',', None) # alt diffusion doesn't have </w> bits for comma
+
+ def encode_with_transformers(self, tokens):
+ # there's no CLIP Skip here because all hidden layers have size of 1024 and the last one uses a
+ # trained layer to transform those 1024 into 768 for unet; so you can't choose which transformer
+ # layer to work with - you have to use the last
+
+ attention_mask = (tokens != self.id_pad).to(device=tokens.device, dtype=torch.int64)
+ features = self.wrapped(input_ids=tokens, attention_mask=attention_mask)
+ z = features['projection_state']
+
+ return z
+
+ def encode_embedding_init_text(self, init_text, nvpt):
+ embedding_layer = self.wrapped.roberta.embeddings
+ ids = self.wrapped.tokenizer(init_text, max_length=nvpt, return_tensors="pt", add_special_tokens=False)["input_ids"]
+ embedded = embedding_layer.token_embedding.wrapped(ids.to(devices.device)).squeeze(0)
+
+ return embedded
diff --git a/modules/sd_models.py b/modules/sd_models.py
index 90007da3..76a89e88 100644
--- a/modules/sd_models.py
+++ b/modules/sd_models.py
@@ -5,18 +5,22 @@ import gc
from collections import namedtuple
import torch
import re
+import safetensors.torch
from omegaconf import OmegaConf
+from os import mkdir
+from urllib import request
+import ldm.modules.midas as midas
from ldm.util import instantiate_from_config
-from modules import shared, modelloader, devices, script_callbacks
+from modules import shared, modelloader, devices, script_callbacks, sd_vae
from modules.paths import models_path
from modules.sd_hijack_inpainting import do_inpainting_hijack, should_hijack_inpainting
model_dir = "Stable-diffusion"
model_path = os.path.abspath(os.path.join(models_path, model_dir))
-CheckpointInfo = namedtuple("CheckpointInfo", ['filename', 'title', 'hash', 'model_name', 'config'])
+CheckpointInfo = namedtuple("CheckpointInfo", ['filename', 'title', 'hash', 'model_name'])
checkpoints_list = {}
checkpoints_loaded = collections.OrderedDict()
@@ -35,6 +39,7 @@ def setup_model():
os.makedirs(model_path)
list_models()
+ enable_midas_autodownload()
def checkpoint_tiles():
@@ -43,9 +48,17 @@ def checkpoint_tiles():
return sorted([x.title for x in checkpoints_list.values()], key = alphanumeric_key)
+def find_checkpoint_config(info):
+ config = os.path.splitext(info.filename)[0] + ".yaml"
+ if os.path.exists(config):
+ return config
+
+ return shared.cmd_opts.config
+
+
def list_models():
checkpoints_list.clear()
- model_list = modelloader.load_models(model_path=model_path, command_path=shared.cmd_opts.ckpt_dir, ext_filter=[".ckpt"])
+ model_list = modelloader.load_models(model_path=model_path, command_path=shared.cmd_opts.ckpt_dir, ext_filter=[".ckpt", ".safetensors"])
def modeltitle(path, shorthash):
abspath = os.path.abspath(path)
@@ -68,7 +81,7 @@ def list_models():
if os.path.exists(cmd_ckpt):
h = model_hash(cmd_ckpt)
title, short_model_name = modeltitle(cmd_ckpt, h)
- checkpoints_list[title] = CheckpointInfo(cmd_ckpt, title, h, short_model_name, shared.cmd_opts.config)
+ checkpoints_list[title] = CheckpointInfo(cmd_ckpt, title, h, short_model_name)
shared.opts.data['sd_model_checkpoint'] = title
elif cmd_ckpt is not None and cmd_ckpt != shared.default_sd_model_file:
print(f"Checkpoint in --ckpt argument not found (Possible it was moved to {model_path}: {cmd_ckpt}", file=sys.stderr)
@@ -76,12 +89,7 @@ def list_models():
h = model_hash(filename)
title, short_model_name = modeltitle(filename, h)
- basename, _ = os.path.splitext(filename)
- config = basename + ".yaml"
- if not os.path.exists(config):
- config = shared.cmd_opts.config
-
- checkpoints_list[title] = CheckpointInfo(filename, title, h, short_model_name, config)
+ checkpoints_list[title] = CheckpointInfo(filename, title, h, short_model_name)
def get_closet_checkpoint_match(searchString):
@@ -106,18 +114,19 @@ def model_hash(filename):
def select_checkpoint():
model_checkpoint = shared.opts.sd_model_checkpoint
+
checkpoint_info = checkpoints_list.get(model_checkpoint, None)
if checkpoint_info is not None:
return checkpoint_info
if len(checkpoints_list) == 0:
- print(f"No checkpoints found. When searching for checkpoints, looked at:", file=sys.stderr)
+ print("No checkpoints found. When searching for checkpoints, looked at:", file=sys.stderr)
if shared.cmd_opts.ckpt is not None:
print(f" - file {os.path.abspath(shared.cmd_opts.ckpt)}", file=sys.stderr)
print(f" - directory {model_path}", file=sys.stderr)
if shared.cmd_opts.ckpt_dir is not None:
print(f" - directory {os.path.abspath(shared.cmd_opts.ckpt_dir)}", file=sys.stderr)
- print(f"Can't run without a checkpoint. Find and place a .ckpt file into any of those locations. The program will exit.", file=sys.stderr)
+ print("Can't run without a checkpoint. Find and place a .ckpt file into any of those locations. The program will exit.", file=sys.stderr)
exit(1)
checkpoint_info = next(iter(checkpoints_list.values()))
@@ -143,8 +152,8 @@ def transform_checkpoint_dict_key(k):
def get_state_dict_from_checkpoint(pl_sd):
- if "state_dict" in pl_sd:
- pl_sd = pl_sd["state_dict"]
+ pl_sd = pl_sd.pop("state_dict", pl_sd)
+ pl_sd.pop("state_dict", None)
sd = {}
for k, v in pl_sd.items():
@@ -159,67 +168,130 @@ def get_state_dict_from_checkpoint(pl_sd):
return pl_sd
-vae_ignore_keys = {"model_ema.decay", "model_ema.num_updates"}
+def read_state_dict(checkpoint_file, print_global_state=False, map_location=None):
+ _, extension = os.path.splitext(checkpoint_file)
+ if extension.lower() == ".safetensors":
+ device = map_location or shared.weight_load_location
+ if device is None:
+ device = devices.get_cuda_device_string() if torch.cuda.is_available() else "cpu"
+ pl_sd = safetensors.torch.load_file(checkpoint_file, device=device)
+ else:
+ pl_sd = torch.load(checkpoint_file, map_location=map_location or shared.weight_load_location)
+
+ if print_global_state and "global_step" in pl_sd:
+ print(f"Global Step: {pl_sd['global_step']}")
+
+ sd = get_state_dict_from_checkpoint(pl_sd)
+ return sd
-def load_model_weights(model, checkpoint_info):
+def load_model_weights(model, checkpoint_info, vae_file="auto"):
checkpoint_file = checkpoint_info.filename
sd_model_hash = checkpoint_info.hash
- if checkpoint_info not in checkpoints_loaded:
- print(f"Loading weights [{sd_model_hash}] from {checkpoint_file}")
+ cache_enabled = shared.opts.sd_checkpoint_cache > 0
- pl_sd = torch.load(checkpoint_file, map_location=shared.weight_load_location)
- if "global_step" in pl_sd:
- print(f"Global Step: {pl_sd['global_step']}")
+ if cache_enabled and checkpoint_info in checkpoints_loaded:
+ # use checkpoint cache
+ print(f"Loading weights [{sd_model_hash}] from cache")
+ model.load_state_dict(checkpoints_loaded[checkpoint_info])
+ else:
+ # load from file
+ print(f"Loading weights [{sd_model_hash}] from {checkpoint_file}")
- sd = get_state_dict_from_checkpoint(pl_sd)
- del pl_sd
+ sd = read_state_dict(checkpoint_file)
model.load_state_dict(sd, strict=False)
del sd
+
+ if cache_enabled:
+ # cache newly loaded model
+ checkpoints_loaded[checkpoint_info] = model.state_dict().copy()
if shared.cmd_opts.opt_channelslast:
model.to(memory_format=torch.channels_last)
if not shared.cmd_opts.no_half:
+ vae = model.first_stage_model
+
+ # with --no-half-vae, remove VAE from model when doing half() to prevent its weights from being converted to float16
+ if shared.cmd_opts.no_half_vae:
+ model.first_stage_model = None
+
model.half()
+ model.first_stage_model = vae
devices.dtype = torch.float32 if shared.cmd_opts.no_half else torch.float16
devices.dtype_vae = torch.float32 if shared.cmd_opts.no_half or shared.cmd_opts.no_half_vae else torch.float16
- vae_file = os.path.splitext(checkpoint_file)[0] + ".vae.pt"
-
- if not os.path.exists(vae_file) and shared.cmd_opts.vae_path is not None:
- vae_file = shared.cmd_opts.vae_path
-
- if os.path.exists(vae_file):
- print(f"Loading VAE weights from: {vae_file}")
- vae_ckpt = torch.load(vae_file, map_location=shared.weight_load_location)
- vae_dict = {k: v for k, v in vae_ckpt["state_dict"].items() if k[0:4] != "loss" and k not in vae_ignore_keys}
- model.first_stage_model.load_state_dict(vae_dict)
-
model.first_stage_model.to(devices.dtype_vae)
- if shared.opts.sd_checkpoint_cache > 0:
- checkpoints_loaded[checkpoint_info] = model.state_dict().copy()
- while len(checkpoints_loaded) > shared.opts.sd_checkpoint_cache:
- checkpoints_loaded.popitem(last=False) # LRU
- else:
- print(f"Loading weights [{sd_model_hash}] from cache")
- checkpoints_loaded.move_to_end(checkpoint_info)
- model.load_state_dict(checkpoints_loaded[checkpoint_info])
+ # clean up cache if limit is reached
+ if cache_enabled:
+ while len(checkpoints_loaded) > shared.opts.sd_checkpoint_cache + 1: # we need to count the current model
+ checkpoints_loaded.popitem(last=False) # LRU
model.sd_model_hash = sd_model_hash
model.sd_model_checkpoint = checkpoint_file
model.sd_checkpoint_info = checkpoint_info
+ model.logvar = model.logvar.to(devices.device) # fix for training
+
+ sd_vae.delete_base_vae()
+ sd_vae.clear_loaded_vae()
+ vae_file = sd_vae.resolve_vae(checkpoint_file, vae_file=vae_file)
+ sd_vae.load_vae(model, vae_file)
+
+
+def enable_midas_autodownload():
+ """
+ Gives the ldm.modules.midas.api.load_model function automatic downloading.
+
+ When the 512-depth-ema model, and other future models like it, is loaded,
+ it calls midas.api.load_model to load the associated midas depth model.
+ This function applies a wrapper to download the model to the correct
+ location automatically.
+ """
+
+ midas_path = os.path.join(models_path, 'midas')
+
+ # stable-diffusion-stability-ai hard-codes the midas model path to
+ # a location that differs from where other scripts using this model look.
+ # HACK: Overriding the path here.
+ for k, v in midas.api.ISL_PATHS.items():
+ file_name = os.path.basename(v)
+ midas.api.ISL_PATHS[k] = os.path.join(midas_path, file_name)
+
+ midas_urls = {
+ "dpt_large": "https://github.com/intel-isl/DPT/releases/download/1_0/dpt_large-midas-2f21e586.pt",
+ "dpt_hybrid": "https://github.com/intel-isl/DPT/releases/download/1_0/dpt_hybrid-midas-501f0c75.pt",
+ "midas_v21": "https://github.com/AlexeyAB/MiDaS/releases/download/midas_dpt/midas_v21-f6b98070.pt",
+ "midas_v21_small": "https://github.com/AlexeyAB/MiDaS/releases/download/midas_dpt/midas_v21_small-70d6b9c8.pt",
+ }
+
+ midas.api.load_model_inner = midas.api.load_model
+
+ def load_model_wrapper(model_type):
+ path = midas.api.ISL_PATHS[model_type]
+ if not os.path.exists(path):
+ if not os.path.exists(midas_path):
+ mkdir(midas_path)
+
+ print(f"Downloading midas model weights for {model_type} to {path}")
+ request.urlretrieve(midas_urls[model_type], path)
+ print(f"{model_type} downloaded")
+
+ return midas.api.load_model_inner(model_type)
+
+ midas.api.load_model = load_model_wrapper
+
def load_model(checkpoint_info=None):
from modules import lowvram, sd_hijack
checkpoint_info = checkpoint_info or select_checkpoint()
+ checkpoint_config = find_checkpoint_config(checkpoint_info)
- if checkpoint_info.config != shared.cmd_opts.config:
- print(f"Loading config from: {checkpoint_info.config}")
+ if checkpoint_config != shared.cmd_opts.config:
+ print(f"Loading config from: {checkpoint_config}")
if shared.sd_model:
sd_hijack.model_hijack.undo_hijack(shared.sd_model)
@@ -227,21 +299,25 @@ def load_model(checkpoint_info=None):
gc.collect()
devices.torch_gc()
- sd_config = OmegaConf.load(checkpoint_info.config)
+ sd_config = OmegaConf.load(checkpoint_config)
if should_hijack_inpainting(checkpoint_info):
# Hardcoded config for now...
sd_config.model.target = "ldm.models.diffusion.ddpm.LatentInpaintDiffusion"
- sd_config.model.params.use_ema = False
sd_config.model.params.conditioning_key = "hybrid"
sd_config.model.params.unet_config.params.in_channels = 9
+ sd_config.model.params.finetune_keys = None
- # Create a "fake" config with a different name so that we know to unload it when switching models.
- checkpoint_info = checkpoint_info._replace(config=checkpoint_info.config.replace(".yaml", "-inpainting.yaml"))
+ if not hasattr(sd_config.model.params, "use_ema"):
+ sd_config.model.params.use_ema = False
do_inpainting_hijack()
+ if shared.cmd_opts.no_half:
+ sd_config.model.params.unet_config.params.use_fp16 = False
+
sd_model = instantiate_from_config(sd_config.model)
+
load_model_weights(sd_model, checkpoint_info)
if shared.cmd_opts.lowvram or shared.cmd_opts.medvram:
@@ -254,9 +330,12 @@ def load_model(checkpoint_info=None):
sd_model.eval()
shared.sd_model = sd_model
+ sd_hijack.model_hijack.embedding_db.load_textual_inversion_embeddings(force_reload=True) # Reload embeddings after model load as they may or may not fit the model
+
script_callbacks.model_loaded_callback(sd_model)
- print(f"Model loaded.")
+ print("Model loaded.")
+
return sd_model
@@ -267,10 +346,13 @@ def reload_model_weights(sd_model=None, info=None):
if not sd_model:
sd_model = shared.sd_model
+ current_checkpoint_info = sd_model.sd_checkpoint_info
+ checkpoint_config = find_checkpoint_config(current_checkpoint_info)
+
if sd_model.sd_model_checkpoint == checkpoint_info.filename:
return
- if sd_model.sd_checkpoint_info.config != checkpoint_info.config or should_hijack_inpainting(checkpoint_info) != should_hijack_inpainting(sd_model.sd_checkpoint_info):
+ if checkpoint_config != find_checkpoint_config(checkpoint_info) or should_hijack_inpainting(checkpoint_info) != should_hijack_inpainting(sd_model.sd_checkpoint_info):
del sd_model
checkpoints_loaded.clear()
load_model(checkpoint_info)
@@ -283,13 +365,19 @@ def reload_model_weights(sd_model=None, info=None):
sd_hijack.model_hijack.undo_hijack(sd_model)
- load_model_weights(sd_model, checkpoint_info)
+ try:
+ load_model_weights(sd_model, checkpoint_info)
+ except Exception as e:
+ print("Failed to load checkpoint, restoring previous")
+ load_model_weights(sd_model, current_checkpoint_info)
+ raise
+ finally:
+ sd_hijack.model_hijack.hijack(sd_model)
+ script_callbacks.model_loaded_callback(sd_model)
- sd_hijack.model_hijack.hijack(sd_model)
- script_callbacks.model_loaded_callback(sd_model)
+ if not shared.cmd_opts.lowvram and not shared.cmd_opts.medvram:
+ sd_model.to(devices.device)
- if not shared.cmd_opts.lowvram and not shared.cmd_opts.medvram:
- sd_model.to(devices.device)
+ print("Weights loaded.")
- print(f"Weights loaded.")
return sd_model
diff --git a/modules/sd_samplers.py b/modules/sd_samplers.py
index 8772db56..e904d860 100644
--- a/modules/sd_samplers.py
+++ b/modules/sd_samplers.py
@@ -1,4 +1,4 @@
-from collections import namedtuple
+from collections import namedtuple, deque
import numpy as np
from math import floor
import torch
@@ -6,28 +6,36 @@ import tqdm
from PIL import Image
import inspect
import k_diffusion.sampling
+import torchsde._brownian.brownian_interval
import ldm.models.diffusion.ddim
import ldm.models.diffusion.plms
-from modules import prompt_parser, devices, processing, images
+from modules import prompt_parser, devices, processing, images, sd_vae_approx
from modules.shared import opts, cmd_opts, state
import modules.shared as shared
+from modules.script_callbacks import CFGDenoiserParams, cfg_denoiser_callback
SamplerData = namedtuple('SamplerData', ['name', 'constructor', 'aliases', 'options'])
samplers_k_diffusion = [
- ('Euler a', 'sample_euler_ancestral', ['k_euler_a'], {}),
+ ('Euler a', 'sample_euler_ancestral', ['k_euler_a', 'k_euler_ancestral'], {}),
('Euler', 'sample_euler', ['k_euler'], {}),
('LMS', 'sample_lms', ['k_lms'], {}),
('Heun', 'sample_heun', ['k_heun'], {}),
- ('DPM2', 'sample_dpm_2', ['k_dpm_2'], {}),
- ('DPM2 a', 'sample_dpm_2_ancestral', ['k_dpm_2_a'], {}),
+ ('DPM2', 'sample_dpm_2', ['k_dpm_2'], {'discard_next_to_last_sigma': True}),
+ ('DPM2 a', 'sample_dpm_2_ancestral', ['k_dpm_2_a'], {'discard_next_to_last_sigma': True}),
+ ('DPM++ 2S a', 'sample_dpmpp_2s_ancestral', ['k_dpmpp_2s_a'], {}),
+ ('DPM++ 2M', 'sample_dpmpp_2m', ['k_dpmpp_2m'], {}),
+ ('DPM++ SDE', 'sample_dpmpp_sde', ['k_dpmpp_sde'], {}),
('DPM fast', 'sample_dpm_fast', ['k_dpm_fast'], {}),
('DPM adaptive', 'sample_dpm_adaptive', ['k_dpm_ad'], {}),
('LMS Karras', 'sample_lms', ['k_lms_ka'], {'scheduler': 'karras'}),
- ('DPM2 Karras', 'sample_dpm_2', ['k_dpm_2_ka'], {'scheduler': 'karras'}),
- ('DPM2 a Karras', 'sample_dpm_2_ancestral', ['k_dpm_2_a_ka'], {'scheduler': 'karras'}),
+ ('DPM2 Karras', 'sample_dpm_2', ['k_dpm_2_ka'], {'scheduler': 'karras', 'discard_next_to_last_sigma': True}),
+ ('DPM2 a Karras', 'sample_dpm_2_ancestral', ['k_dpm_2_a_ka'], {'scheduler': 'karras', 'discard_next_to_last_sigma': True}),
+ ('DPM++ 2S a Karras', 'sample_dpmpp_2s_ancestral', ['k_dpmpp_2s_a_ka'], {'scheduler': 'karras'}),
+ ('DPM++ 2M Karras', 'sample_dpmpp_2m', ['k_dpmpp_2m_ka'], {'scheduler': 'karras'}),
+ ('DPM++ SDE Karras', 'sample_dpmpp_sde', ['k_dpmpp_sde_ka'], {'scheduler': 'karras'}),
]
samplers_data_k_diffusion = [
@@ -41,16 +49,24 @@ all_samplers = [
SamplerData('DDIM', lambda model: VanillaStableDiffusionSampler(ldm.models.diffusion.ddim.DDIMSampler, model), [], {}),
SamplerData('PLMS', lambda model: VanillaStableDiffusionSampler(ldm.models.diffusion.plms.PLMSSampler, model), [], {}),
]
+all_samplers_map = {x.name: x for x in all_samplers}
samplers = []
samplers_for_img2img = []
+samplers_map = {}
-def create_sampler_with_index(list_of_configs, index, model):
- config = list_of_configs[index]
+def create_sampler(name, model):
+ if name is not None:
+ config = all_samplers_map.get(name, None)
+ else:
+ config = all_samplers[0]
+
+ assert config is not None, f'bad sampler name: {name}'
+
sampler = config.constructor(model)
sampler.config = config
-
+
return sampler
@@ -63,6 +79,12 @@ def set_samplers():
samplers = [x for x in all_samplers if x.name not in hidden]
samplers_for_img2img = [x for x in all_samplers if x.name not in hidden_img2img]
+ samplers_map.clear()
+ for sampler in all_samplers:
+ samplers_map[sampler.name.lower()] = sampler.name
+ for alias in sampler.aliases:
+ samplers_map[alias.lower()] = sampler.name
+
set_samplers()
@@ -84,20 +106,32 @@ def setup_img2img_steps(p, steps=None):
return steps, t_enc
-def single_sample_to_image(sample):
- x_sample = processing.decode_first_stage(shared.sd_model, sample.unsqueeze(0))[0]
+approximation_indexes = {"Full": 0, "Approx NN": 1, "Approx cheap": 2}
+
+
+def single_sample_to_image(sample, approximation=None):
+ if approximation is None:
+ approximation = approximation_indexes.get(opts.show_progress_type, 0)
+
+ if approximation == 2:
+ x_sample = sd_vae_approx.cheap_approximation(sample)
+ elif approximation == 1:
+ x_sample = sd_vae_approx.model()(sample.to(devices.device, devices.dtype).unsqueeze(0))[0].detach()
+ else:
+ x_sample = processing.decode_first_stage(shared.sd_model, sample.unsqueeze(0))[0]
+
x_sample = torch.clamp((x_sample + 1.0) / 2.0, min=0.0, max=1.0)
x_sample = 255. * np.moveaxis(x_sample.cpu().numpy(), 0, 2)
x_sample = x_sample.astype(np.uint8)
return Image.fromarray(x_sample)
-def sample_to_image(samples):
- return single_sample_to_image(samples[0])
+def sample_to_image(samples, index=0, approximation=None):
+ return single_sample_to_image(samples[index], approximation)
-def samples_to_image_grid(samples):
- return images.image_grid([single_sample_to_image(sample) for sample in samples])
+def samples_to_image_grid(samples, approximation=None):
+ return images.image_grid([single_sample_to_image(sample, approximation) for sample in samples])
def store_latent(decoded):
@@ -115,7 +149,8 @@ class InterruptedException(BaseException):
class VanillaStableDiffusionSampler:
def __init__(self, constructor, sd_model):
self.sampler = constructor(sd_model)
- self.orig_p_sample_ddim = self.sampler.p_sample_ddim if hasattr(self.sampler, 'p_sample_ddim') else self.sampler.p_sample_plms
+ self.is_plms = hasattr(self.sampler, 'p_sample_plms')
+ self.orig_p_sample_ddim = self.sampler.p_sample_plms if self.is_plms else self.sampler.p_sample_ddim
self.mask = None
self.nmask = None
self.init_latent = None
@@ -206,7 +241,6 @@ class VanillaStableDiffusionSampler:
self.mask = p.mask if hasattr(p, 'mask') else None
self.nmask = p.nmask if hasattr(p, 'nmask') else None
-
def adjust_steps_if_invalid(self, p, num_steps):
if (self.config.name == 'DDIM' and p.ddim_discretize == 'uniform') or (self.config.name == 'PLMS'):
valid_step = 999 / (1000 // num_steps)
@@ -215,7 +249,6 @@ class VanillaStableDiffusionSampler:
return num_steps
-
def sample_img2img(self, p, x, noise, conditioning, unconditional_conditioning, steps=None, image_conditioning=None):
steps, t_enc = setup_img2img_steps(p, steps)
steps = self.adjust_steps_if_invalid(p, steps)
@@ -248,9 +281,10 @@ class VanillaStableDiffusionSampler:
steps = self.adjust_steps_if_invalid(p, steps or p.steps)
# Wrap the conditioning models with additional image conditioning for inpainting model
+ # dummy_for_plms is needed because PLMS code checks the first item in the dict to have the right shape
if image_conditioning is not None:
- conditioning = {"c_concat": [image_conditioning], "c_crossattn": [conditioning]}
- unconditional_conditioning = {"c_concat": [image_conditioning], "c_crossattn": [unconditional_conditioning]}
+ conditioning = {"dummy_for_plms": np.zeros((conditioning.shape[0],)), "c_crossattn": [conditioning], "c_concat": [image_conditioning]}
+ unconditional_conditioning = {"c_crossattn": [unconditional_conditioning], "c_concat": [image_conditioning]}
samples_ddim = self.launch_sampling(steps, lambda: self.sampler.sample(S=steps, conditioning=conditioning, batch_size=int(x.shape[0]), shape=x[0].shape, verbose=False, unconditional_guidance_scale=p.cfg_scale, unconditional_conditioning=unconditional_conditioning, x_T=x, eta=self.eta)[0])
@@ -266,6 +300,16 @@ class CFGDenoiser(torch.nn.Module):
self.init_latent = None
self.step = 0
+ def combine_denoised(self, x_out, conds_list, uncond, cond_scale):
+ denoised_uncond = x_out[-uncond.shape[0]:]
+ denoised = torch.clone(denoised_uncond)
+
+ for i, conds in enumerate(conds_list):
+ for cond_index, weight in conds:
+ denoised[i] += (x_out[cond_index] - denoised_uncond[i]) * (weight * cond_scale)
+
+ return denoised
+
def forward(self, x, sigma, uncond, cond, cond_scale, image_cond):
if state.interrupted or state.skipped:
raise InterruptedException
@@ -280,6 +324,12 @@ class CFGDenoiser(torch.nn.Module):
image_cond_in = torch.cat([torch.stack([image_cond[i] for _ in range(n)]) for i, n in enumerate(repeats)] + [image_cond])
sigma_in = torch.cat([torch.stack([sigma[i] for _ in range(n)]) for i, n in enumerate(repeats)] + [sigma])
+ denoiser_params = CFGDenoiserParams(x_in, image_cond_in, sigma_in, state.sampling_step, state.sampling_steps)
+ cfg_denoiser_callback(denoiser_params)
+ x_in = denoiser_params.x
+ image_cond_in = denoiser_params.image_cond
+ sigma_in = denoiser_params.sigma
+
if tensor.shape[1] == uncond.shape[1]:
cond_in = torch.cat([tensor, uncond])
@@ -301,12 +351,7 @@ class CFGDenoiser(torch.nn.Module):
x_out[-uncond.shape[0]:] = self.inner_model(x_in[-uncond.shape[0]:], sigma_in[-uncond.shape[0]:], cond={"c_crossattn": [uncond], "c_concat": [image_cond_in[-uncond.shape[0]:]]})
- denoised_uncond = x_out[-uncond.shape[0]:]
- denoised = torch.clone(denoised_uncond)
-
- for i, conds in enumerate(conds_list):
- for cond_index, weight in conds:
- denoised[i] += (x_out[cond_index] - denoised_uncond[i]) * (weight * cond_scale)
+ denoised = self.combine_denoised(x_out, conds_list, uncond, cond_scale)
if self.mask is not None:
denoised = self.init_latent * self.mask + self.nmask * denoised
@@ -317,28 +362,55 @@ class CFGDenoiser(torch.nn.Module):
class TorchHijack:
- def __init__(self, kdiff_sampler):
- self.kdiff_sampler = kdiff_sampler
+ def __init__(self, sampler_noises):
+ # Using a deque to efficiently receive the sampler_noises in the same order as the previous index-based
+ # implementation.
+ self.sampler_noises = deque(sampler_noises)
def __getattr__(self, item):
if item == 'randn_like':
- return self.kdiff_sampler.randn_like
+ return self.randn_like
if hasattr(torch, item):
return getattr(torch, item)
raise AttributeError("'{}' object has no attribute '{}'".format(type(self).__name__, item))
+ def randn_like(self, x):
+ if self.sampler_noises:
+ noise = self.sampler_noises.popleft()
+ if noise.shape == x.shape:
+ return noise
+
+ if x.device.type == 'mps':
+ return torch.randn_like(x, device=devices.cpu).to(x.device)
+ else:
+ return torch.randn_like(x)
+
+
+# MPS fix for randn in torchsde
+def torchsde_randn(size, dtype, device, seed):
+ if device.type == 'mps':
+ generator = torch.Generator(devices.cpu).manual_seed(int(seed))
+ return torch.randn(size, dtype=dtype, device=devices.cpu, generator=generator).to(device)
+ else:
+ generator = torch.Generator(device).manual_seed(int(seed))
+ return torch.randn(size, dtype=dtype, device=device, generator=generator)
+
+
+torchsde._brownian.brownian_interval._randn = torchsde_randn
+
class KDiffusionSampler:
def __init__(self, funcname, sd_model):
- self.model_wrap = k_diffusion.external.CompVisDenoiser(sd_model, quantize=shared.opts.enable_quantization)
+ denoiser = k_diffusion.external.CompVisVDenoiser if sd_model.parameterization == "v" else k_diffusion.external.CompVisDenoiser
+
+ self.model_wrap = denoiser(sd_model, quantize=shared.opts.enable_quantization)
self.funcname = funcname
self.func = getattr(k_diffusion.sampling, self.funcname)
self.extra_params = sampler_extra_params.get(funcname, [])
self.model_wrap_cfg = CFGDenoiser(self.model_wrap)
self.sampler_noises = None
- self.sampler_noise_index = 0
self.stop_at = None
self.eta = None
self.default_eta = 1.0
@@ -371,26 +443,13 @@ class KDiffusionSampler:
def number_of_needed_noises(self, p):
return p.steps
- def randn_like(self, x):
- noise = self.sampler_noises[self.sampler_noise_index] if self.sampler_noises is not None and self.sampler_noise_index < len(self.sampler_noises) else None
-
- if noise is not None and x.shape == noise.shape:
- res = noise
- else:
- res = torch.randn_like(x)
-
- self.sampler_noise_index += 1
- return res
-
def initialize(self, p):
self.model_wrap_cfg.mask = p.mask if hasattr(p, 'mask') else None
self.model_wrap_cfg.nmask = p.nmask if hasattr(p, 'nmask') else None
self.model_wrap.step = 0
- self.sampler_noise_index = 0
self.eta = p.eta or opts.eta_ancestral
- if self.sampler_noises is not None:
- k_diffusion.sampling.torch = TorchHijack(self)
+ k_diffusion.sampling.torch = TorchHijack(self.sampler_noises if self.sampler_noises is not None else [])
extra_params_kwargs = {}
for param_name in self.extra_params:
@@ -402,16 +461,26 @@ class KDiffusionSampler:
return extra_params_kwargs
- def sample_img2img(self, p, x, noise, conditioning, unconditional_conditioning, steps=None, image_conditioning=None):
- steps, t_enc = setup_img2img_steps(p, steps)
-
+ def get_sigmas(self, p, steps):
if p.sampler_noise_scheduler_override:
sigmas = p.sampler_noise_scheduler_override(steps)
elif self.config is not None and self.config.options.get('scheduler', None) == 'karras':
- sigmas = k_diffusion.sampling.get_sigmas_karras(n=steps, sigma_min=0.1, sigma_max=10, device=shared.device)
+ sigma_min, sigma_max = (0.1, 10) if opts.use_old_karras_scheduler_sigmas else (self.model_wrap.sigmas[0].item(), self.model_wrap.sigmas[-1].item())
+
+ sigmas = k_diffusion.sampling.get_sigmas_karras(n=steps, sigma_min=sigma_min, sigma_max=sigma_max, device=shared.device)
else:
sigmas = self.model_wrap.get_sigmas(steps)
+ if self.config is not None and self.config.options.get('discard_next_to_last_sigma', False):
+ sigmas = torch.cat([sigmas[:-2], sigmas[-1:]])
+
+ return sigmas
+
+ def sample_img2img(self, p, x, noise, conditioning, unconditional_conditioning, steps=None, image_conditioning=None):
+ steps, t_enc = setup_img2img_steps(p, steps)
+
+ sigmas = self.get_sigmas(p, steps)
+
sigma_sched = sigmas[steps - t_enc - 1:]
xi = x + noise * sigma_sched[0]
@@ -443,12 +512,7 @@ class KDiffusionSampler:
def sample(self, p, x, conditioning, unconditional_conditioning, steps=None, image_conditioning = None):
steps = steps or p.steps
- if p.sampler_noise_scheduler_override:
- sigmas = p.sampler_noise_scheduler_override(steps)
- elif self.config is not None and self.config.options.get('scheduler', None) == 'karras':
- sigmas = k_diffusion.sampling.get_sigmas_karras(n=steps, sigma_min=0.1, sigma_max=10, device=shared.device)
- else:
- sigmas = self.model_wrap.get_sigmas(steps)
+ sigmas = self.get_sigmas(p, steps)
x = x * sigmas[0]
diff --git a/modules/sd_vae.py b/modules/sd_vae.py
new file mode 100644
index 00000000..ac71d62d
--- /dev/null
+++ b/modules/sd_vae.py
@@ -0,0 +1,231 @@
+import torch
+import os
+import collections
+from collections import namedtuple
+from modules import shared, devices, script_callbacks
+from modules.paths import models_path
+import glob
+from copy import deepcopy
+
+
+model_dir = "Stable-diffusion"
+model_path = os.path.abspath(os.path.join(models_path, model_dir))
+vae_dir = "VAE"
+vae_path = os.path.abspath(os.path.join(models_path, vae_dir))
+
+
+vae_ignore_keys = {"model_ema.decay", "model_ema.num_updates"}
+
+
+default_vae_dict = {"auto": "auto", "None": None, None: None}
+default_vae_list = ["auto", "None"]
+
+
+default_vae_values = [default_vae_dict[x] for x in default_vae_list]
+vae_dict = dict(default_vae_dict)
+vae_list = list(default_vae_list)
+first_load = True
+
+
+base_vae = None
+loaded_vae_file = None
+checkpoint_info = None
+
+checkpoints_loaded = collections.OrderedDict()
+
+def get_base_vae(model):
+ if base_vae is not None and checkpoint_info == model.sd_checkpoint_info and model:
+ return base_vae
+ return None
+
+
+def store_base_vae(model):
+ global base_vae, checkpoint_info
+ if checkpoint_info != model.sd_checkpoint_info:
+ assert not loaded_vae_file, "Trying to store non-base VAE!"
+ base_vae = deepcopy(model.first_stage_model.state_dict())
+ checkpoint_info = model.sd_checkpoint_info
+
+
+def delete_base_vae():
+ global base_vae, checkpoint_info
+ base_vae = None
+ checkpoint_info = None
+
+
+def restore_base_vae(model):
+ global loaded_vae_file
+ if base_vae is not None and checkpoint_info == model.sd_checkpoint_info:
+ print("Restoring base VAE")
+ _load_vae_dict(model, base_vae)
+ loaded_vae_file = None
+ delete_base_vae()
+
+
+def get_filename(filepath):
+ return os.path.splitext(os.path.basename(filepath))[0]
+
+
+def refresh_vae_list(vae_path=vae_path, model_path=model_path):
+ global vae_dict, vae_list
+ res = {}
+ candidates = [
+ *glob.iglob(os.path.join(model_path, '**/*.vae.ckpt'), recursive=True),
+ *glob.iglob(os.path.join(model_path, '**/*.vae.pt'), recursive=True),
+ *glob.iglob(os.path.join(vae_path, '**/*.ckpt'), recursive=True),
+ *glob.iglob(os.path.join(vae_path, '**/*.pt'), recursive=True)
+ ]
+ if shared.cmd_opts.vae_path is not None and os.path.isfile(shared.cmd_opts.vae_path):
+ candidates.append(shared.cmd_opts.vae_path)
+ for filepath in candidates:
+ name = get_filename(filepath)
+ res[name] = filepath
+ vae_list.clear()
+ vae_list.extend(default_vae_list)
+ vae_list.extend(list(res.keys()))
+ vae_dict.clear()
+ vae_dict.update(res)
+ vae_dict.update(default_vae_dict)
+ return vae_list
+
+
+def get_vae_from_settings(vae_file="auto"):
+ # else, we load from settings, if not set to be default
+ if vae_file == "auto" and shared.opts.sd_vae is not None:
+ # if saved VAE settings isn't recognized, fallback to auto
+ vae_file = vae_dict.get(shared.opts.sd_vae, "auto")
+ # if VAE selected but not found, fallback to auto
+ if vae_file not in default_vae_values and not os.path.isfile(vae_file):
+ vae_file = "auto"
+ print(f"Selected VAE doesn't exist: {vae_file}")
+ return vae_file
+
+
+def resolve_vae(checkpoint_file=None, vae_file="auto"):
+ global first_load, vae_dict, vae_list
+
+ # if vae_file argument is provided, it takes priority, but not saved
+ if vae_file and vae_file not in default_vae_list:
+ if not os.path.isfile(vae_file):
+ print(f"VAE provided as function argument doesn't exist: {vae_file}")
+ vae_file = "auto"
+ # for the first load, if vae-path is provided, it takes priority, saved, and failure is reported
+ if first_load and shared.cmd_opts.vae_path is not None:
+ if os.path.isfile(shared.cmd_opts.vae_path):
+ vae_file = shared.cmd_opts.vae_path
+ shared.opts.data['sd_vae'] = get_filename(vae_file)
+ else:
+ print(f"VAE provided as command line argument doesn't exist: {vae_file}")
+ # fallback to selector in settings, if vae selector not set to act as default fallback
+ if not shared.opts.sd_vae_as_default:
+ vae_file = get_vae_from_settings(vae_file)
+ # vae-path cmd arg takes priority for auto
+ if vae_file == "auto" and shared.cmd_opts.vae_path is not None:
+ if os.path.isfile(shared.cmd_opts.vae_path):
+ vae_file = shared.cmd_opts.vae_path
+ print(f"Using VAE provided as command line argument: {vae_file}")
+ # if still not found, try look for ".vae.pt" beside model
+ model_path = os.path.splitext(checkpoint_file)[0]
+ if vae_file == "auto":
+ vae_file_try = model_path + ".vae.pt"
+ if os.path.isfile(vae_file_try):
+ vae_file = vae_file_try
+ print(f"Using VAE found similar to selected model: {vae_file}")
+ # if still not found, try look for ".vae.ckpt" beside model
+ if vae_file == "auto":
+ vae_file_try = model_path + ".vae.ckpt"
+ if os.path.isfile(vae_file_try):
+ vae_file = vae_file_try
+ print(f"Using VAE found similar to selected model: {vae_file}")
+ # No more fallbacks for auto
+ if vae_file == "auto":
+ vae_file = None
+ # Last check, just because
+ if vae_file and not os.path.exists(vae_file):
+ vae_file = None
+
+ return vae_file
+
+
+def load_vae(model, vae_file=None):
+ global first_load, vae_dict, vae_list, loaded_vae_file
+ # save_settings = False
+
+ cache_enabled = shared.opts.sd_vae_checkpoint_cache > 0
+
+ if vae_file:
+ if cache_enabled and vae_file in checkpoints_loaded:
+ # use vae checkpoint cache
+ print(f"Loading VAE weights [{get_filename(vae_file)}] from cache")
+ store_base_vae(model)
+ _load_vae_dict(model, checkpoints_loaded[vae_file])
+ else:
+ assert os.path.isfile(vae_file), f"VAE file doesn't exist: {vae_file}"
+ print(f"Loading VAE weights from: {vae_file}")
+ store_base_vae(model)
+ vae_ckpt = torch.load(vae_file, map_location=shared.weight_load_location)
+ vae_dict_1 = {k: v for k, v in vae_ckpt["state_dict"].items() if k[0:4] != "loss" and k not in vae_ignore_keys}
+ _load_vae_dict(model, vae_dict_1)
+
+ if cache_enabled:
+ # cache newly loaded vae
+ checkpoints_loaded[vae_file] = vae_dict_1.copy()
+
+ # clean up cache if limit is reached
+ if cache_enabled:
+ while len(checkpoints_loaded) > shared.opts.sd_vae_checkpoint_cache + 1: # we need to count the current model
+ checkpoints_loaded.popitem(last=False) # LRU
+
+ # If vae used is not in dict, update it
+ # It will be removed on refresh though
+ vae_opt = get_filename(vae_file)
+ if vae_opt not in vae_dict:
+ vae_dict[vae_opt] = vae_file
+ vae_list.append(vae_opt)
+ elif loaded_vae_file:
+ restore_base_vae(model)
+
+ loaded_vae_file = vae_file
+
+ first_load = False
+
+
+# don't call this from outside
+def _load_vae_dict(model, vae_dict_1):
+ model.first_stage_model.load_state_dict(vae_dict_1)
+ model.first_stage_model.to(devices.dtype_vae)
+
+def clear_loaded_vae():
+ global loaded_vae_file
+ loaded_vae_file = None
+
+def reload_vae_weights(sd_model=None, vae_file="auto"):
+ from modules import lowvram, devices, sd_hijack
+
+ if not sd_model:
+ sd_model = shared.sd_model
+
+ checkpoint_info = sd_model.sd_checkpoint_info
+ checkpoint_file = checkpoint_info.filename
+ vae_file = resolve_vae(checkpoint_file, vae_file=vae_file)
+
+ if loaded_vae_file == vae_file:
+ return
+
+ if shared.cmd_opts.lowvram or shared.cmd_opts.medvram:
+ lowvram.send_everything_to_cpu()
+ else:
+ sd_model.to(devices.cpu)
+
+ sd_hijack.model_hijack.undo_hijack(sd_model)
+
+ load_vae(sd_model, vae_file)
+
+ sd_hijack.model_hijack.hijack(sd_model)
+ script_callbacks.model_loaded_callback(sd_model)
+
+ if not shared.cmd_opts.lowvram and not shared.cmd_opts.medvram:
+ sd_model.to(devices.device)
+
+ print("VAE Weights loaded.")
+ return sd_model
diff --git a/modules/sd_vae_approx.py b/modules/sd_vae_approx.py
new file mode 100644
index 00000000..0a58542d
--- /dev/null
+++ b/modules/sd_vae_approx.py
@@ -0,0 +1,58 @@
+import os
+
+import torch
+from torch import nn
+from modules import devices, paths
+
+sd_vae_approx_model = None
+
+
+class VAEApprox(nn.Module):
+ def __init__(self):
+ super(VAEApprox, self).__init__()
+ self.conv1 = nn.Conv2d(4, 8, (7, 7))
+ self.conv2 = nn.Conv2d(8, 16, (5, 5))
+ self.conv3 = nn.Conv2d(16, 32, (3, 3))
+ self.conv4 = nn.Conv2d(32, 64, (3, 3))
+ self.conv5 = nn.Conv2d(64, 32, (3, 3))
+ self.conv6 = nn.Conv2d(32, 16, (3, 3))
+ self.conv7 = nn.Conv2d(16, 8, (3, 3))
+ self.conv8 = nn.Conv2d(8, 3, (3, 3))
+
+ def forward(self, x):
+ extra = 11
+ x = nn.functional.interpolate(x, (x.shape[2] * 2, x.shape[3] * 2))
+ x = nn.functional.pad(x, (extra, extra, extra, extra))
+
+ for layer in [self.conv1, self.conv2, self.conv3, self.conv4, self.conv5, self.conv6, self.conv7, self.conv8, ]:
+ x = layer(x)
+ x = nn.functional.leaky_relu(x, 0.1)
+
+ return x
+
+
+def model():
+ global sd_vae_approx_model
+
+ if sd_vae_approx_model is None:
+ sd_vae_approx_model = VAEApprox()
+ sd_vae_approx_model.load_state_dict(torch.load(os.path.join(paths.models_path, "VAE-approx", "model.pt")))
+ sd_vae_approx_model.eval()
+ sd_vae_approx_model.to(devices.device, devices.dtype)
+
+ return sd_vae_approx_model
+
+
+def cheap_approximation(sample):
+ # https://discuss.huggingface.co/t/decoding-latents-to-rgb-without-upscaling/23204/2
+
+ coefs = torch.tensor([
+ [0.298, 0.207, 0.208],
+ [0.187, 0.286, 0.173],
+ [-0.158, 0.189, 0.264],
+ [-0.184, -0.271, -0.473],
+ ]).to(sample.device)
+
+ x_sample = torch.einsum("lxy,lr -> rxy", sample, coefs)
+
+ return x_sample
diff --git a/modules/shared.py b/modules/shared.py
index 1ccb269a..54a6ba23 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -3,25 +3,27 @@ import datetime
import json
import os
import sys
-from collections import OrderedDict
+import time
+from PIL import Image
import gradio as gr
import tqdm
import modules.artists
import modules.interrogate
import modules.memmon
-import modules.sd_models
import modules.styles
import modules.devices as devices
-from modules import sd_samplers, sd_models, localization
-from modules.hypernetworks import hypernetwork
+from modules import localization, sd_vae, extensions, script_loading, errors
from modules.paths import models_path, script_path, sd_path
+
+demo = None
+
sd_model_file = os.path.join(script_path, 'model.ckpt')
default_sd_model_file = sd_model_file
parser = argparse.ArgumentParser()
-parser.add_argument("--config", type=str, default=os.path.join(sd_path, "configs/stable-diffusion/v1-inference.yaml"), help="path to config which constructs model",)
+parser.add_argument("--config", type=str, default=os.path.join(script_path, "configs/v1-inference.yaml"), help="path to config which constructs model",)
parser.add_argument("--ckpt", type=str, default=sd_model_file, help="path to checkpoint of stable diffusion model; if specified, this checkpoint will be added to the list of checkpoints and loaded",)
parser.add_argument("--ckpt-dir", type=str, default=None, help="Path to directory with stable diffusion checkpoints")
parser.add_argument("--gfpgan-dir", type=str, help="GFPGAN directory", default=('./src/gfpgan' if os.path.exists('./src/gfpgan') else './GFPGAN'))
@@ -43,23 +45,21 @@ parser.add_argument("--precision", type=str, help="evaluate at this precision",
parser.add_argument("--share", action='store_true', help="use share=True for gradio and make the UI accessible through their site")
parser.add_argument("--ngrok", type=str, help="ngrok authtoken, alternative to gradio --share", default=None)
parser.add_argument("--ngrok-region", type=str, help="The region in which ngrok should start.", default="us")
+parser.add_argument("--enable-insecure-extension-access", action='store_true', help="enable extensions tab regardless of other options")
parser.add_argument("--codeformer-models-path", type=str, help="Path to directory with codeformer model file(s).", default=os.path.join(models_path, 'Codeformer'))
parser.add_argument("--gfpgan-models-path", type=str, help="Path to directory with GFPGAN model file(s).", default=os.path.join(models_path, 'GFPGAN'))
parser.add_argument("--esrgan-models-path", type=str, help="Path to directory with ESRGAN model file(s).", default=os.path.join(models_path, 'ESRGAN'))
parser.add_argument("--bsrgan-models-path", type=str, help="Path to directory with BSRGAN model file(s).", default=os.path.join(models_path, 'BSRGAN'))
parser.add_argument("--realesrgan-models-path", type=str, help="Path to directory with RealESRGAN model file(s).", default=os.path.join(models_path, 'RealESRGAN'))
-parser.add_argument("--scunet-models-path", type=str, help="Path to directory with ScuNET model file(s).", default=os.path.join(models_path, 'ScuNET'))
-parser.add_argument("--swinir-models-path", type=str, help="Path to directory with SwinIR model file(s).", default=os.path.join(models_path, 'SwinIR'))
-parser.add_argument("--ldsr-models-path", type=str, help="Path to directory with LDSR model file(s).", default=os.path.join(models_path, 'LDSR'))
parser.add_argument("--clip-models-path", type=str, help="Path to directory with CLIP model file(s).", default=None)
parser.add_argument("--xformers", action='store_true', help="enable xformers for cross attention layers")
parser.add_argument("--force-enable-xformers", action='store_true', help="enable xformers for cross attention layers regardless of whether the checking code thinks you can run it; do not make bug reports if this fails to work")
-parser.add_argument("--deepdanbooru", action='store_true', help="enable deepdanbooru interrogator")
+parser.add_argument("--deepdanbooru", action='store_true', help="does not do anything")
parser.add_argument("--opt-split-attention", action='store_true', help="force-enables Doggettx's cross-attention layer optimization. By default, it's on for torch cuda.")
parser.add_argument("--opt-split-attention-invokeai", action='store_true', help="force-enables InvokeAI's cross-attention layer optimization. By default, it's on when cuda is unavailable.")
parser.add_argument("--opt-split-attention-v1", action='store_true', help="enable older version of split attention optimization that does not consume all the VRAM it can find")
parser.add_argument("--disable-opt-split-attention", action='store_true', help="force-disables cross-attention layer optimization")
-parser.add_argument("--use-cpu", nargs='+',choices=['all', 'sd', 'interrogate', 'gfpgan', 'swinir', 'esrgan', 'scunet', 'codeformer'], help="use CPU as torch device for specified modules", default=[], type=str.lower)
+parser.add_argument("--use-cpu", nargs='+', help="use CPU as torch device for specified modules", default=[], type=str.lower)
parser.add_argument("--listen", action='store_true', help="launch gradio with 0.0.0.0 as server name, allowing to respond to network requests")
parser.add_argument("--port", type=int, help="launch gradio with given server port, you need root/admin rights for ports < 1024, defaults to 7860 if available", default=None)
parser.add_argument("--show-negative-prompt", action='store_true', help="does not do anything", default=False)
@@ -70,6 +70,7 @@ parser.add_argument("--ui-settings-file", type=str, help="filename to use for ui
parser.add_argument("--gradio-debug", action='store_true', help="launch gradio with --debug option")
parser.add_argument("--gradio-auth", type=str, help='set gradio authentication like "username:password"; or comma-delimit multiple like "u1:p1,u2:p2,u3:p3"', default=None)
parser.add_argument("--gradio-img2img-tool", type=str, help='gradio image uploader tool: can be either editor for ctopping, or color-sketch for drawing', choices=["color-sketch", "editor"], default="editor")
+parser.add_argument("--gradio-inpaint-tool", type=str, choices=["sketch", "color-sketch"], default="sketch", help="gradio inpainting editor: can be either sketch to only blur/noise the input, or color-sketch to paint over it")
parser.add_argument("--opt-channelslast", action='store_true', help="change memory type for stable diffusion to channels last")
parser.add_argument("--styles-file", type=str, help="filename to use for styles", default=os.path.join(script_path, 'styles.csv'))
parser.add_argument("--autolaunch", action='store_true', help="open the webui URL in the system's default browser upon launch", default=False)
@@ -79,13 +80,24 @@ parser.add_argument("--disable-console-progressbars", action='store_true', help=
parser.add_argument("--enable-console-prompts", action='store_true', help="print prompts to console when generating with txt2img and img2img", default=False)
parser.add_argument('--vae-path', type=str, help='Path to Variational Autoencoders model', default=None)
parser.add_argument("--disable-safe-unpickle", action='store_true', help="disable checking pytorch models for malicious code", default=False)
-parser.add_argument("--api", action='store_true', help="use api=True to launch the api with the webui")
-parser.add_argument("--nowebui", action='store_true', help="use api=True to launch the api instead of the webui")
+parser.add_argument("--api", action='store_true', help="use api=True to launch the API together with the webui (use --nowebui instead for only the API)")
+parser.add_argument("--api-auth", type=str, help='Set authentication for API like "username:password"; or comma-delimit multiple like "u1:p1,u2:p2,u3:p3"', default=None)
+parser.add_argument("--api-log", action='store_true', help="use api-log=True to enable logging of all API requests")
+parser.add_argument("--nowebui", action='store_true', help="use api=True to launch the API instead of the webui")
parser.add_argument("--ui-debug-mode", action='store_true', help="Don't load model to quickly launch UI")
parser.add_argument("--device-id", type=str, help="Select the default CUDA device to use (export CUDA_VISIBLE_DEVICES=0,1,etc might be needed before)", default=None)
parser.add_argument("--administrator", action='store_true', help="Administrator rights", default=False)
+parser.add_argument("--cors-allow-origins", type=str, help="Allowed CORS origin(s) in the form of a comma-separated list (no spaces)", default=None)
+parser.add_argument("--cors-allow-origins-regex", type=str, help="Allowed CORS origin(s) in the form of a single regular expression", default=None)
+parser.add_argument("--tls-keyfile", type=str, help="Partially enables TLS, requires --tls-certfile to fully function", default=None)
+parser.add_argument("--tls-certfile", type=str, help="Partially enables TLS, requires --tls-keyfile to fully function", default=None)
+parser.add_argument("--server-name", type=str, help="Sets hostname of server", default=None)
+
+script_loading.preload_extensions(extensions.extensions_dir, parser)
+script_loading.preload_extensions(extensions.extensions_builtin_dir, parser)
cmd_opts = parser.parse_args()
+
restricted_opts = {
"samples_filename_pattern",
"directories_filename_pattern",
@@ -98,10 +110,21 @@ restricted_opts = {
"outdir_save",
}
-cmd_opts.disable_extension_access = cmd_opts.share or cmd_opts.listen
+ui_reorder_categories = [
+ "sampler",
+ "dimensions",
+ "cfg",
+ "seed",
+ "checkboxes",
+ "hires_fix",
+ "batch",
+ "scripts",
+]
+
+cmd_opts.disable_extension_access = (cmd_opts.share or cmd_opts.listen or cmd_opts.server_name) and not cmd_opts.enable_insecure_extension_access
-devices.device, devices.device_interrogate, devices.device_gfpgan, devices.device_swinir, devices.device_esrgan, devices.device_scunet, devices.device_codeformer = \
-(devices.cpu if any(y in cmd_opts.use_cpu for y in [x, 'all']) else devices.get_optimal_device() for x in ['sd', 'interrogate', 'gfpgan', 'swinir', 'esrgan', 'scunet', 'codeformer'])
+devices.device, devices.device_interrogate, devices.device_gfpgan, devices.device_esrgan, devices.device_codeformer = \
+ (devices.cpu if any(y in cmd_opts.use_cpu for y in [x, 'all']) else devices.get_optimal_device() for x in ['sd', 'interrogate', 'gfpgan', 'esrgan', 'codeformer'])
device = devices.device
weight_load_location = None if cmd_opts.lowram else "cpu"
@@ -112,10 +135,12 @@ xformers_available = False
config_filename = cmd_opts.ui_settings_file
os.makedirs(cmd_opts.hypernetwork_dir, exist_ok=True)
-hypernetworks = hypernetwork.list_hypernetworks(cmd_opts.hypernetwork_dir)
+hypernetworks = {}
loaded_hypernetwork = None
+
def reload_hypernetworks():
+ from modules.hypernetworks import hypernetwork
global hypernetworks
hypernetworks = hypernetwork.list_hypernetworks(cmd_opts.hypernetwork_dir)
@@ -135,6 +160,7 @@ class State:
current_image = None
current_image_sampling_step = 0
textinfo = None
+ time_start = None
need_restart = False
def skip(self):
@@ -144,6 +170,9 @@ class State:
self.interrupted = True
def nextjob(self):
+ if opts.show_progress_every_n_steps == -1:
+ self.do_set_current_image()
+
self.job_no += 1
self.sampling_step = 0
self.current_image_sampling_step = 0
@@ -151,9 +180,10 @@ class State:
def dict(self):
obj = {
"skipped": self.skipped,
- "interrupted": self.skipped,
+ "interrupted": self.interrupted,
"job": self.job,
"job_count": self.job_count,
+ "job_timestamp": self.job_timestamp,
"job_no": self.job_no,
"sampling_step": self.sampling_step,
"sampling_steps": self.sampling_steps,
@@ -172,6 +202,7 @@ class State:
self.skipped = False
self.interrupted = False
self.textinfo = None
+ self.time_start = time.time()
devices.torch_gc()
@@ -181,6 +212,27 @@ class State:
devices.torch_gc()
+ """sets self.current_image from self.current_latent if enough sampling steps have been made after the last call to this"""
+ def set_current_image(self):
+ if not parallel_processing_allowed:
+ return
+
+ if self.sampling_step - self.current_image_sampling_step >= opts.show_progress_every_n_steps and opts.show_progress_every_n_steps > 0:
+ self.do_set_current_image()
+
+ def do_set_current_image(self):
+ if self.current_latent is None:
+ return
+
+ import modules.sd_samplers
+ if opts.show_progress_grid:
+ self.current_image = modules.sd_samplers.samples_to_image_grid(self.current_latent)
+ else:
+ self.current_image = modules.sd_samplers.sample_to_image(self.current_latent)
+
+ self.current_image_sampling_step = self.sampling_step
+
+
state = State()
artist_db = modules.artists.ArtistsDatabase(os.path.join(script_path, 'artists.csv'))
@@ -192,8 +244,6 @@ interrogator = modules.interrogate.InterrogateModels("interrogate")
face_restorers = []
-localization.list_localizations(cmd_opts.localizations_dir)
-
def realesrgan_models_names():
import modules.realesrgan_model
@@ -218,6 +268,21 @@ def options_section(section_identifier, options_dict):
return options_dict
+def list_checkpoint_tiles():
+ import modules.sd_models
+ return modules.sd_models.checkpoint_tiles()
+
+
+def refresh_checkpoints():
+ import modules.sd_models
+ return modules.sd_models.list_models()
+
+
+def list_samplers():
+ import modules.sd_samplers
+ return modules.sd_samplers.all_samplers
+
+
hide_dirs = {"visible": not cmd_opts.hide_ui_dir_config}
options_templates = {}
@@ -238,12 +303,19 @@ options_templates.update(options_section(('saving-images', "Saving images/grids"
"enable_pnginfo": OptionInfo(True, "Save text information about generation parameters as chunks to png files"),
"save_txt": OptionInfo(False, "Create a text file next to every image with generation parameters."),
"save_images_before_face_restoration": OptionInfo(False, "Save a copy of image before doing face restoration."),
+ "save_images_before_highres_fix": OptionInfo(False, "Save a copy of image before applying highres fix."),
+ "save_images_before_color_correction": OptionInfo(False, "Save a copy of image before applying color correction to img2img results"),
"jpeg_quality": OptionInfo(80, "Quality for saved jpeg images", gr.Slider, {"minimum": 1, "maximum": 100, "step": 1}),
"export_for_4chan": OptionInfo(True, "If PNG image is larger than 4MB or any dimension is larger than 4000, downscale and save copy as JPG"),
"use_original_name_batch": OptionInfo(False, "Use original name for output filename during batch process in extras tab"),
+ "use_upscaler_name_as_suffix": OptionInfo(False, "Use upscaler name as filename suffix in the extras tab"),
"save_selected_only": OptionInfo(True, "When using 'Save' button, only save a single selected image"),
"do_not_add_watermark": OptionInfo(False, "Do not add watermark to images"),
+
+ "temp_dir": OptionInfo("", "Directory for temporary images; leave empty for default"),
+ "clean_temp_dir_at_start": OptionInfo(False, "Cleanup non-default temporary directory when starting webui"),
+
}))
options_templates.update(options_section(('saving-paths', "Paths for saving"), {
@@ -268,12 +340,8 @@ options_templates.update(options_section(('saving-to-dirs', "Saving to a directo
options_templates.update(options_section(('upscaling', "Upscaling"), {
"ESRGAN_tile": OptionInfo(192, "Tile size for ESRGAN upscalers. 0 = no tiling.", gr.Slider, {"minimum": 0, "maximum": 512, "step": 16}),
"ESRGAN_tile_overlap": OptionInfo(8, "Tile overlap, in pixels for ESRGAN upscalers. Low values = visible seam.", gr.Slider, {"minimum": 0, "maximum": 48, "step": 1}),
- "realesrgan_enabled_models": OptionInfo(["R-ESRGAN x4+", "R-ESRGAN x4+ Anime6B"], "Select which Real-ESRGAN models to show in the web UI. (Requires restart)", gr.CheckboxGroup, lambda: {"choices": realesrgan_models_names()}),
- "SWIN_tile": OptionInfo(192, "Tile size for all SwinIR.", gr.Slider, {"minimum": 16, "maximum": 512, "step": 16}),
- "SWIN_tile_overlap": OptionInfo(8, "Tile overlap, in pixels for SwinIR. Low values = visible seam.", gr.Slider, {"minimum": 0, "maximum": 48, "step": 1}),
- "ldsr_steps": OptionInfo(100, "LDSR processing steps. Lower = faster", gr.Slider, {"minimum": 1, "maximum": 200, "step": 1}),
+ "realesrgan_enabled_models": OptionInfo(["R-ESRGAN 4x+", "R-ESRGAN 4x+ Anime6B"], "Select which Real-ESRGAN models to show in the web UI. (Requires restart)", gr.CheckboxGroup, lambda: {"choices": realesrgan_models_names()}),
"upscaler_for_img2img": OptionInfo(None, "Upscaler for img2img", gr.Dropdown, lambda: {"choices": [x.name for x in sd_upscalers]}),
- "use_scale_latent_for_hires_fix": OptionInfo(False, "Upscale latent space image when doing hires. fix"),
}))
options_templates.update(options_section(('face-restoration', "Face restoration"), {
@@ -290,6 +358,8 @@ options_templates.update(options_section(('system', "System"), {
options_templates.update(options_section(('training', "Training"), {
"unload_models_when_training": OptionInfo(False, "Move VAE and CLIP to RAM when training if possible. Saves VRAM."),
+ "pin_memory": OptionInfo(False, "Turn on pin_memory for DataLoader. Makes training slightly faster but can increase memory usage."),
+ "save_optimizer_state": OptionInfo(False, "Saves Optimizer state as separate *.optim file. Training of embedding or HN can be resumed with the matching optim file."),
"dataset_filename_word_regex": OptionInfo("", "Filename word regex"),
"dataset_filename_join_string": OptionInfo(" ", "Filename join string"),
"training_image_repeats_per_epoch": OptionInfo(1, "Number of repeats for a single input image per epoch; used only for displaying epoch number", gr.Number, {"precision": 0}),
@@ -298,24 +368,31 @@ options_templates.update(options_section(('training', "Training"), {
}))
options_templates.update(options_section(('sd', "Stable Diffusion"), {
- "sd_model_checkpoint": OptionInfo(None, "Stable Diffusion checkpoint", gr.Dropdown, lambda: {"choices": modules.sd_models.checkpoint_tiles()}, refresh=sd_models.list_models),
+ "sd_model_checkpoint": OptionInfo(None, "Stable Diffusion checkpoint", gr.Dropdown, lambda: {"choices": list_checkpoint_tiles()}, refresh=refresh_checkpoints),
"sd_checkpoint_cache": OptionInfo(0, "Checkpoints to cache in RAM", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1}),
+ "sd_vae_checkpoint_cache": OptionInfo(0, "VAE Checkpoints to cache in RAM", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1}),
+ "sd_vae": OptionInfo("auto", "SD VAE", gr.Dropdown, lambda: {"choices": sd_vae.vae_list}, refresh=sd_vae.refresh_vae_list),
+ "sd_vae_as_default": OptionInfo(False, "Ignore selected VAE for stable diffusion checkpoints that have their own .vae.pt next to them"),
"sd_hypernetwork": OptionInfo("None", "Hypernetwork", gr.Dropdown, lambda: {"choices": ["None"] + [x for x in hypernetworks.keys()]}, refresh=reload_hypernetworks),
"sd_hypernetwork_strength": OptionInfo(1.0, "Hypernetwork strength", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.001}),
"inpainting_mask_weight": OptionInfo(1.0, "Inpainting conditioning mask strength", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}),
+ "initial_noise_multiplier": OptionInfo(1.0, "Noise multiplier for img2img", gr.Slider, {"minimum": 0.5, "maximum": 1.5, "step": 0.01 }),
"img2img_color_correction": OptionInfo(False, "Apply color correction to img2img results to match original colors."),
- "save_images_before_color_correction": OptionInfo(False, "Save a copy of image before applying color correction to img2img results"),
"img2img_fix_steps": OptionInfo(False, "With img2img, do exactly the amount of steps the slider specifies (normally you'd do less with less denoising)."),
+ "img2img_background_color": OptionInfo("#ffffff", "With img2img, fill image's transparent parts with this color.", gr.ColorPicker, {}),
"enable_quantization": OptionInfo(False, "Enable quantization in K samplers for sharper and cleaner results. This may change existing seeds. Requires restart to apply."),
"enable_emphasis": OptionInfo(True, "Emphasis: use (text) to make model pay more attention to text and [text] to make it pay less attention"),
- "use_old_emphasis_implementation": OptionInfo(False, "Use old emphasis implementation. Can be useful to reproduce old seeds."),
"enable_batch_seeds": OptionInfo(True, "Make K-diffusion samplers produce same images in a batch as when making a single image"),
"comma_padding_backtrack": OptionInfo(20, "Increase coherency by padding from the last comma within n tokens when using more than 75 tokens", gr.Slider, {"minimum": 0, "maximum": 74, "step": 1 }),
- "filter_nsfw": OptionInfo(False, "Filter NSFW content"),
- 'CLIP_stop_at_last_layers': OptionInfo(1, "Stop At last layers of CLIP model", gr.Slider, {"minimum": 1, "maximum": 12, "step": 1}),
+ 'CLIP_stop_at_last_layers': OptionInfo(1, "Clip skip", gr.Slider, {"minimum": 1, "maximum": 12, "step": 1}),
"random_artist_categories": OptionInfo([], "Allowed categories for random artists selection when using the Roll button", gr.CheckboxGroup, {"choices": artist_db.categories()}),
}))
+options_templates.update(options_section(('compatibility', "Compatibility"), {
+ "use_old_emphasis_implementation": OptionInfo(False, "Use old emphasis implementation. Can be useful to reproduce old seeds."),
+ "use_old_karras_scheduler_sigmas": OptionInfo(False, "Use old karras scheduler sigmas (0.1 to 10)."),
+}))
+
options_templates.update(options_section(('interrogate', "Interrogate Options"), {
"interrogate_keep_models_in_memory": OptionInfo(False, "Interrogate: keep models in VRAM"),
"interrogate_use_builtin_artists": OptionInfo(True, "Interrogate: use artists from artists.csv"),
@@ -328,11 +405,13 @@ options_templates.update(options_section(('interrogate', "Interrogate Options"),
"deepbooru_sort_alpha": OptionInfo(True, "Interrogate: deepbooru sort alphabetically"),
"deepbooru_use_spaces": OptionInfo(False, "use spaces for tags in deepbooru"),
"deepbooru_escape": OptionInfo(True, "escape (\\) brackets in deepbooru (so they are used as literal brackets and not for emphasis)"),
+ "deepbooru_filter_tags": OptionInfo("", "filter out those tags from deepbooru output (separated by comma)"),
}))
options_templates.update(options_section(('ui', "User interface"), {
"show_progressbar": OptionInfo(True, "Show progressbar"),
- "show_progress_every_n_steps": OptionInfo(0, "Show image creation progress every N sampling steps. Set 0 to disable.", gr.Slider, {"minimum": 0, "maximum": 32, "step": 1}),
+ "show_progress_every_n_steps": OptionInfo(0, "Show image creation progress every N sampling steps. Set to 0 to disable. Set to -1 to show after completion of batch.", gr.Slider, {"minimum": -1, "maximum": 32, "step": 1}),
+ "show_progress_type": OptionInfo("Full", "Image creation progress preview mode", gr.Radio, {"choices": ["Full", "Approx NN", "Approx cheap"]}),
"show_progress_grid": OptionInfo(True, "Show previews of all images generated in a batch as a grid"),
"return_grid": OptionInfo(True, "Show grid in results for web"),
"do_not_show_images": OptionInfo(False, "Do not show any images in results for web"),
@@ -340,16 +419,20 @@ options_templates.update(options_section(('ui', "User interface"), {
"add_model_name_to_info": OptionInfo(False, "Add model name to generation information"),
"disable_weights_auto_swap": OptionInfo(False, "When reading generation parameters from text into UI (from PNG info or pasted text), do not change the selected model/checkpoint."),
"send_seed": OptionInfo(True, "Send seed when sending prompt or image to other interface"),
+ "send_size": OptionInfo(True, "Send size when sending prompt or image to another interface"),
"font": OptionInfo("", "Font for image grids that have text"),
"js_modal_lightbox": OptionInfo(True, "Enable full page image viewer"),
"js_modal_lightbox_initially_zoomed": OptionInfo(True, "Show images zoomed in by default in full page image viewer"),
"show_progress_in_title": OptionInfo(True, "Show generation progress in window title."),
+ "samplers_in_dropdown": OptionInfo(True, "Use dropdown for sampler selection instead of radio group"),
+ "dimensions_and_batch_together": OptionInfo(True, "Show Witdth/Height and Batch sliders in same row"),
'quicksettings': OptionInfo("sd_model_checkpoint", "Quicksettings list"),
+ 'ui_reorder': OptionInfo(", ".join(ui_reorder_categories), "txt2img/ing2img UI item order"),
'localization': OptionInfo("None", "Localization (requires restart)", gr.Dropdown, lambda: {"choices": ["None"] + list(localization.localizations.keys())}, refresh=lambda: localization.list_localizations(cmd_opts.localizations_dir)),
}))
options_templates.update(options_section(('sampler-params', "Sampler parameters"), {
- "hide_samplers": OptionInfo([], "Hide samplers in user interface (requires restart)", gr.CheckboxGroup, lambda: {"choices": [x.name for x in sd_samplers.all_samplers]}),
+ "hide_samplers": OptionInfo([], "Hide samplers in user interface (requires restart)", gr.CheckboxGroup, lambda: {"choices": [x.name for x in list_samplers()]}),
"eta_ddim": OptionInfo(0.0, "eta (noise multiplier) for DDIM", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}),
"eta_ancestral": OptionInfo(1.0, "eta (noise multiplier) for ancestral samplers", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}),
"ddim_discretize": OptionInfo('uniform', "img2img DDIM discretize", gr.Radio, {"choices": ['uniform', 'quad']}),
@@ -377,6 +460,16 @@ class Options:
def __setattr__(self, key, value):
if self.data is not None:
if key in self.data or key in self.data_labels:
+ assert not cmd_opts.freeze_settings, "changing settings is disabled"
+
+ info = opts.data_labels.get(key, None)
+ comp_args = info.component_args if info else None
+ if isinstance(comp_args, dict) and comp_args.get('visible', True) is False:
+ raise RuntimeError(f"not possible to set {key} because it is restricted")
+
+ if cmd_opts.hide_ui_dir_config and key in restricted_opts:
+ raise RuntimeError(f"not possible to set {key} because it is restricted")
+
self.data[key] = value
return
@@ -392,7 +485,31 @@ class Options:
return super(Options, self).__getattribute__(item)
+ def set(self, key, value):
+ """sets an option and calls its onchange callback, returning True if the option changed and False otherwise"""
+
+ oldval = self.data.get(key, None)
+ if oldval == value:
+ return False
+
+ try:
+ setattr(self, key, value)
+ except RuntimeError:
+ return False
+
+ if self.data_labels[key].onchange is not None:
+ try:
+ self.data_labels[key].onchange()
+ except Exception as e:
+ errors.display(e, f"changing setting {key} to {value}")
+ setattr(self, key, oldval)
+ return False
+
+ return True
+
def save(self, filename):
+ assert not cmd_opts.freeze_settings, "saving settings is disabled"
+
with open(filename, "w", encoding="utf8") as file:
json.dump(self.data, file, indent=4)
@@ -419,11 +536,12 @@ class Options:
if bad_settings > 0:
print(f"The program is likely to not work with bad settings.\nSettings file: {filename}\nEither fix the file, or delete it and restart.", file=sys.stderr)
- def onchange(self, key, func):
+ def onchange(self, key, func, call=True):
item = self.data_labels.get(key)
item.onchange = func
- func()
+ if call:
+ func()
def dumpjson(self):
d = {k: self.data.get(k, self.data_labels.get(k).default) for k in self.data_labels.keys()}
@@ -448,6 +566,15 @@ opts = Options()
if os.path.exists(config_filename):
opts.load(config_filename)
+latent_upscale_default_mode = "Latent"
+latent_upscale_modes = {
+ "Latent": {"mode": "bilinear", "antialias": False},
+ "Latent (antialiased)": {"mode": "bilinear", "antialias": True},
+ "Latent (bicubic)": {"mode": "bicubic", "antialias": False},
+ "Latent (bicubic antialiased)": {"mode": "bicubic", "antialias": True},
+ "Latent (nearest)": {"mode": "nearest", "antialias": False},
+}
+
sd_upscalers = []
sd_model = None
diff --git a/modules/styles.py b/modules/styles.py
index 3bf5c5b6..ce6e71ca 100644
--- a/modules/styles.py
+++ b/modules/styles.py
@@ -65,17 +65,6 @@ class StyleDatabase:
def apply_negative_styles_to_prompt(self, prompt, styles):
return apply_styles_to_prompt(prompt, [self.styles.get(x, self.no_style).negative_prompt for x in styles])
- def apply_styles(self, p: StableDiffusionProcessing) -> None:
- if isinstance(p.prompt, list):
- p.prompt = [self.apply_styles_to_prompt(prompt, p.styles) for prompt in p.prompt]
- else:
- p.prompt = self.apply_styles_to_prompt(p.prompt, p.styles)
-
- if isinstance(p.negative_prompt, list):
- p.negative_prompt = [self.apply_negative_styles_to_prompt(prompt, p.styles) for prompt in p.negative_prompt]
- else:
- p.negative_prompt = self.apply_negative_styles_to_prompt(p.negative_prompt, p.styles)
-
def save_styles(self, path: str) -> None:
# Write to temporary file first, so we don't nuke the file if something goes wrong
fd, temp_path = tempfile.mkstemp(".csv")
diff --git a/modules/textual_inversion/autocrop.py b/modules/textual_inversion/autocrop.py
index 9859974a..68e1103c 100644
--- a/modules/textual_inversion/autocrop.py
+++ b/modules/textual_inversion/autocrop.py
@@ -276,8 +276,8 @@ def poi_average(pois, settings):
weight += poi.weight
x += poi.x * poi.weight
y += poi.y * poi.weight
- avg_x = round(x / weight)
- avg_y = round(y / weight)
+ avg_x = round(weight and x / weight)
+ avg_y = round(weight and y / weight)
return PointOfInterest(avg_x, avg_y)
@@ -338,4 +338,4 @@ class Settings:
self.face_points_weight = face_points_weight
self.annotate_image = annotate_image
self.destop_view_image = False
- self.dnn_model_path = dnn_model_path \ No newline at end of file
+ self.dnn_model_path = dnn_model_path
diff --git a/modules/textual_inversion/dataset.py b/modules/textual_inversion/dataset.py
index ad726577..88d68c76 100644
--- a/modules/textual_inversion/dataset.py
+++ b/modules/textual_inversion/dataset.py
@@ -3,7 +3,7 @@ import numpy as np
import PIL
import torch
from PIL import Image
-from torch.utils.data import Dataset
+from torch.utils.data import Dataset, DataLoader
from torchvision import transforms
import random
@@ -11,25 +11,28 @@ import tqdm
from modules import devices, shared
import re
+from ldm.modules.distributions.distributions import DiagonalGaussianDistribution
+
re_numbers_at_start = re.compile(r"^[-\d]+\s*")
class DatasetEntry:
- def __init__(self, filename=None, latent=None, filename_text=None):
+ def __init__(self, filename=None, filename_text=None, latent_dist=None, latent_sample=None, cond=None, cond_text=None, pixel_values=None):
self.filename = filename
- self.latent = latent
self.filename_text = filename_text
- self.cond = None
- self.cond_text = None
+ self.latent_dist = latent_dist
+ self.latent_sample = latent_sample
+ self.cond = cond
+ self.cond_text = cond_text
+ self.pixel_values = pixel_values
class PersonalizedBase(Dataset):
- def __init__(self, data_root, width, height, repeats, flip_p=0.5, placeholder_token="*", model=None, device=None, template_file=None, include_cond=False, batch_size=1):
+ def __init__(self, data_root, width, height, repeats, flip_p=0.5, placeholder_token="*", model=None, cond_model=None, device=None, template_file=None, include_cond=False, batch_size=1, gradient_step=1, shuffle_tags=False, tag_drop_out=0, latent_sampling_method='once'):
re_word = re.compile(shared.opts.dataset_filename_word_regex) if len(shared.opts.dataset_filename_word_regex) > 0 else None
self.placeholder_token = placeholder_token
- self.batch_size = batch_size
self.width = width
self.height = height
self.flip = transforms.RandomHorizontalFlip(p=flip_p)
@@ -45,11 +48,16 @@ class PersonalizedBase(Dataset):
assert os.path.isdir(data_root), "Dataset directory doesn't exist"
assert os.listdir(data_root), "Dataset directory is empty"
- cond_model = shared.sd_model.cond_stage_model
-
self.image_paths = [os.path.join(data_root, file_path) for file_path in os.listdir(data_root)]
+
+
+ self.shuffle_tags = shuffle_tags
+ self.tag_drop_out = tag_drop_out
+
print("Preparing dataset...")
for path in tqdm.tqdm(self.image_paths):
+ if shared.state.interrupted:
+ raise Exception("interrupted")
try:
image = Image.open(path).convert('RGB').resize((self.width, self.height), PIL.Image.BICUBIC)
except Exception:
@@ -71,53 +79,94 @@ class PersonalizedBase(Dataset):
npimage = np.array(image).astype(np.uint8)
npimage = (npimage / 127.5 - 1.0).astype(np.float32)
- torchdata = torch.from_numpy(npimage).to(device=device, dtype=torch.float32)
- torchdata = torch.moveaxis(torchdata, 2, 0)
-
- init_latent = model.get_first_stage_encoding(model.encode_first_stage(torchdata.unsqueeze(dim=0))).squeeze()
- init_latent = init_latent.to(devices.cpu)
-
- entry = DatasetEntry(filename=path, filename_text=filename_text, latent=init_latent)
-
- if include_cond:
+ torchdata = torch.from_numpy(npimage).permute(2, 0, 1).to(device=device, dtype=torch.float32)
+ latent_sample = None
+
+ with devices.autocast():
+ latent_dist = model.encode_first_stage(torchdata.unsqueeze(dim=0))
+
+ if latent_sampling_method == "once" or (latent_sampling_method == "deterministic" and not isinstance(latent_dist, DiagonalGaussianDistribution)):
+ latent_sample = model.get_first_stage_encoding(latent_dist).squeeze().to(devices.cpu)
+ latent_sampling_method = "once"
+ entry = DatasetEntry(filename=path, filename_text=filename_text, latent_sample=latent_sample)
+ elif latent_sampling_method == "deterministic":
+ # Works only for DiagonalGaussianDistribution
+ latent_dist.std = 0
+ latent_sample = model.get_first_stage_encoding(latent_dist).squeeze().to(devices.cpu)
+ entry = DatasetEntry(filename=path, filename_text=filename_text, latent_sample=latent_sample)
+ elif latent_sampling_method == "random":
+ entry = DatasetEntry(filename=path, filename_text=filename_text, latent_dist=latent_dist)
+
+ if not (self.tag_drop_out != 0 or self.shuffle_tags):
entry.cond_text = self.create_text(filename_text)
- entry.cond = cond_model([entry.cond_text]).to(devices.cpu).squeeze(0)
- self.dataset.append(entry)
-
- assert len(self.dataset) > 0, "No images have been found in the dataset."
- self.length = len(self.dataset) * repeats // batch_size
+ if include_cond and not (self.tag_drop_out != 0 or self.shuffle_tags):
+ with devices.autocast():
+ entry.cond = cond_model([entry.cond_text]).to(devices.cpu).squeeze(0)
- self.dataset_length = len(self.dataset)
- self.indexes = None
- self.shuffle()
+ self.dataset.append(entry)
+ del torchdata
+ del latent_dist
+ del latent_sample
- def shuffle(self):
- self.indexes = np.random.permutation(self.dataset_length)
+ self.length = len(self.dataset)
+ assert self.length > 0, "No images have been found in the dataset."
+ self.batch_size = min(batch_size, self.length)
+ self.gradient_step = min(gradient_step, self.length // self.batch_size)
+ self.latent_sampling_method = latent_sampling_method
def create_text(self, filename_text):
text = random.choice(self.lines)
+ tags = filename_text.split(',')
+ if self.tag_drop_out != 0:
+ tags = [t for t in tags if random.random() > self.tag_drop_out]
+ if self.shuffle_tags:
+ random.shuffle(tags)
+ text = text.replace("[filewords]", ','.join(tags))
text = text.replace("[name]", self.placeholder_token)
- text = text.replace("[filewords]", filename_text)
return text
def __len__(self):
return self.length
def __getitem__(self, i):
- res = []
-
- for j in range(self.batch_size):
- position = i * self.batch_size + j
- if position % len(self.indexes) == 0:
- self.shuffle()
-
- index = self.indexes[position % len(self.indexes)]
- entry = self.dataset[index]
-
- if entry.cond is None:
- entry.cond_text = self.create_text(entry.filename_text)
-
- res.append(entry)
-
- return res
+ entry = self.dataset[i]
+ if self.tag_drop_out != 0 or self.shuffle_tags:
+ entry.cond_text = self.create_text(entry.filename_text)
+ if self.latent_sampling_method == "random":
+ entry.latent_sample = shared.sd_model.get_first_stage_encoding(entry.latent_dist).to(devices.cpu)
+ return entry
+
+class PersonalizedDataLoader(DataLoader):
+ def __init__(self, dataset, latent_sampling_method="once", batch_size=1, pin_memory=False):
+ super(PersonalizedDataLoader, self).__init__(dataset, shuffle=True, drop_last=True, batch_size=batch_size, pin_memory=pin_memory)
+ if latent_sampling_method == "random":
+ self.collate_fn = collate_wrapper_random
+ else:
+ self.collate_fn = collate_wrapper
+
+
+class BatchLoader:
+ def __init__(self, data):
+ self.cond_text = [entry.cond_text for entry in data]
+ self.cond = [entry.cond for entry in data]
+ self.latent_sample = torch.stack([entry.latent_sample for entry in data]).squeeze(1)
+ #self.emb_index = [entry.emb_index for entry in data]
+ #print(self.latent_sample.device)
+
+ def pin_memory(self):
+ self.latent_sample = self.latent_sample.pin_memory()
+ return self
+
+def collate_wrapper(batch):
+ return BatchLoader(batch)
+
+class BatchLoaderRandom(BatchLoader):
+ def __init__(self, data):
+ super().__init__(data)
+
+ def pin_memory(self):
+ return self
+
+def collate_wrapper_random(batch):
+ return BatchLoaderRandom(batch) \ No newline at end of file
diff --git a/modules/textual_inversion/preprocess.py b/modules/textual_inversion/preprocess.py
index e13b1894..feb876c6 100644
--- a/modules/textual_inversion/preprocess.py
+++ b/modules/textual_inversion/preprocess.py
@@ -6,12 +6,10 @@ import sys
import tqdm
import time
-from modules import shared, images
+from modules import shared, images, deepbooru
from modules.paths import models_path
from modules.shared import opts, cmd_opts
from modules.textual_inversion import autocrop
-if cmd_opts.deepdanbooru:
- import modules.deepbooru as deepbooru
def preprocess(process_src, process_dst, process_width, process_height, preprocess_txt_action, process_flip, process_split, process_caption, process_caption_deepbooru=False, split_threshold=0.5, overlap_ratio=0.2, process_focal_crop=False, process_focal_crop_face_weight=0.9, process_focal_crop_entropy_weight=0.3, process_focal_crop_edges_weight=0.5, process_focal_crop_debug=False):
@@ -20,9 +18,7 @@ def preprocess(process_src, process_dst, process_width, process_height, preproce
shared.interrogator.load()
if process_caption_deepbooru:
- db_opts = deepbooru.create_deepbooru_opts()
- db_opts[deepbooru.OPT_INCLUDE_RANKS] = False
- deepbooru.create_deepbooru_process(opts.interrogate_deepbooru_score_threshold, db_opts)
+ deepbooru.model.start()
preprocess_work(process_src, process_dst, process_width, process_height, preprocess_txt_action, process_flip, process_split, process_caption, process_caption_deepbooru, split_threshold, overlap_ratio, process_focal_crop, process_focal_crop_face_weight, process_focal_crop_entropy_weight, process_focal_crop_edges_weight, process_focal_crop_debug)
@@ -32,9 +28,87 @@ def preprocess(process_src, process_dst, process_width, process_height, preproce
shared.interrogator.send_blip_to_ram()
if process_caption_deepbooru:
- deepbooru.release_process()
+ deepbooru.model.stop()
+def listfiles(dirname):
+ return os.listdir(dirname)
+
+
+class PreprocessParams:
+ src = None
+ dstdir = None
+ subindex = 0
+ flip = False
+ process_caption = False
+ process_caption_deepbooru = False
+ preprocess_txt_action = None
+
+
+def save_pic_with_caption(image, index, params: PreprocessParams, existing_caption=None):
+ caption = ""
+
+ if params.process_caption:
+ caption += shared.interrogator.generate_caption(image)
+
+ if params.process_caption_deepbooru:
+ if len(caption) > 0:
+ caption += ", "
+ caption += deepbooru.model.tag_multi(image)
+
+ filename_part = params.src
+ filename_part = os.path.splitext(filename_part)[0]
+ filename_part = os.path.basename(filename_part)
+
+ basename = f"{index:05}-{params.subindex}-{filename_part}"
+ image.save(os.path.join(params.dstdir, f"{basename}.png"))
+
+ if params.preprocess_txt_action == 'prepend' and existing_caption:
+ caption = existing_caption + ' ' + caption
+ elif params.preprocess_txt_action == 'append' and existing_caption:
+ caption = caption + ' ' + existing_caption
+ elif params.preprocess_txt_action == 'copy' and existing_caption:
+ caption = existing_caption
+
+ caption = caption.strip()
+
+ if len(caption) > 0:
+ with open(os.path.join(params.dstdir, f"{basename}.txt"), "w", encoding="utf8") as file:
+ file.write(caption)
+
+ params.subindex += 1
+
+
+def save_pic(image, index, params, existing_caption=None):
+ save_pic_with_caption(image, index, params, existing_caption=existing_caption)
+
+ if params.flip:
+ save_pic_with_caption(ImageOps.mirror(image), index, params, existing_caption=existing_caption)
+
+
+def split_pic(image, inverse_xy, width, height, overlap_ratio):
+ if inverse_xy:
+ from_w, from_h = image.height, image.width
+ to_w, to_h = height, width
+ else:
+ from_w, from_h = image.width, image.height
+ to_w, to_h = width, height
+ h = from_h * to_w // from_w
+ if inverse_xy:
+ image = image.resize((h, to_w))
+ else:
+ image = image.resize((to_w, h))
+
+ split_count = math.ceil((h - to_h * overlap_ratio) / (to_h * (1.0 - overlap_ratio)))
+ y_step = (h - to_h) / (split_count - 1)
+ for i in range(split_count):
+ y = int(y_step * i)
+ if inverse_xy:
+ splitted = image.crop((y, 0, y + to_h, to_w))
+ else:
+ splitted = image.crop((0, y, to_w, y + to_h))
+ yield splitted
+
def preprocess_work(process_src, process_dst, process_width, process_height, preprocess_txt_action, process_flip, process_split, process_caption, process_caption_deepbooru=False, split_threshold=0.5, overlap_ratio=0.2, process_focal_crop=False, process_focal_crop_face_weight=0.9, process_focal_crop_entropy_weight=0.3, process_focal_crop_edges_weight=0.5, process_focal_crop_debug=False):
width = process_width
@@ -48,82 +122,29 @@ def preprocess_work(process_src, process_dst, process_width, process_height, pre
os.makedirs(dst, exist_ok=True)
- files = os.listdir(src)
+ files = listfiles(src)
+ shared.state.job = "preprocess"
shared.state.textinfo = "Preprocessing..."
shared.state.job_count = len(files)
- def save_pic_with_caption(image, index, existing_caption=None):
- caption = ""
-
- if process_caption:
- caption += shared.interrogator.generate_caption(image)
-
- if process_caption_deepbooru:
- if len(caption) > 0:
- caption += ", "
- caption += deepbooru.get_tags_from_process(image)
-
- filename_part = filename
- filename_part = os.path.splitext(filename_part)[0]
- filename_part = os.path.basename(filename_part)
-
- basename = f"{index:05}-{subindex[0]}-{filename_part}"
- image.save(os.path.join(dst, f"{basename}.png"))
-
- if preprocess_txt_action == 'prepend' and existing_caption:
- caption = existing_caption + ' ' + caption
- elif preprocess_txt_action == 'append' and existing_caption:
- caption = caption + ' ' + existing_caption
- elif preprocess_txt_action == 'copy' and existing_caption:
- caption = existing_caption
-
- caption = caption.strip()
-
- if len(caption) > 0:
- with open(os.path.join(dst, f"{basename}.txt"), "w", encoding="utf8") as file:
- file.write(caption)
-
- subindex[0] += 1
-
- def save_pic(image, index, existing_caption=None):
- save_pic_with_caption(image, index, existing_caption=existing_caption)
-
- if process_flip:
- save_pic_with_caption(ImageOps.mirror(image), index, existing_caption=existing_caption)
-
- def split_pic(image, inverse_xy):
- if inverse_xy:
- from_w, from_h = image.height, image.width
- to_w, to_h = height, width
- else:
- from_w, from_h = image.width, image.height
- to_w, to_h = width, height
- h = from_h * to_w // from_w
- if inverse_xy:
- image = image.resize((h, to_w))
- else:
- image = image.resize((to_w, h))
-
- split_count = math.ceil((h - to_h * overlap_ratio) / (to_h * (1.0 - overlap_ratio)))
- y_step = (h - to_h) / (split_count - 1)
- for i in range(split_count):
- y = int(y_step * i)
- if inverse_xy:
- splitted = image.crop((y, 0, y + to_h, to_w))
- else:
- splitted = image.crop((0, y, to_w, y + to_h))
- yield splitted
-
+ params = PreprocessParams()
+ params.dstdir = dst
+ params.flip = process_flip
+ params.process_caption = process_caption
+ params.process_caption_deepbooru = process_caption_deepbooru
+ params.preprocess_txt_action = preprocess_txt_action
for index, imagefile in enumerate(tqdm.tqdm(files)):
- subindex = [0]
+ params.subindex = 0
filename = os.path.join(src, imagefile)
try:
img = Image.open(filename).convert("RGB")
except Exception:
continue
+ params.src = filename
+
existing_caption = None
existing_caption_filename = os.path.splitext(filename)[0] + '.txt'
if os.path.exists(existing_caption_filename):
@@ -143,8 +164,8 @@ def preprocess_work(process_src, process_dst, process_width, process_height, pre
process_default_resize = True
if process_split and ratio < 1.0 and ratio <= split_threshold:
- for splitted in split_pic(img, inverse_xy):
- save_pic(splitted, index, existing_caption=existing_caption)
+ for splitted in split_pic(img, inverse_xy, width, height, overlap_ratio):
+ save_pic(splitted, index, params, existing_caption=existing_caption)
process_default_resize = False
if process_focal_crop and img.height != img.width:
@@ -165,11 +186,11 @@ def preprocess_work(process_src, process_dst, process_width, process_height, pre
dnn_model_path = dnn_model_path,
)
for focal in autocrop.crop_image(img, autocrop_settings):
- save_pic(focal, index, existing_caption=existing_caption)
+ save_pic(focal, index, params, existing_caption=existing_caption)
process_default_resize = False
if process_default_resize:
img = images.resize_image(1, img, width, height)
- save_pic(img, index, existing_caption=existing_caption)
+ save_pic(img, index, params, existing_caption=existing_caption)
- shared.state.nextjob() \ No newline at end of file
+ shared.state.nextjob()
diff --git a/modules/textual_inversion/textual_inversion.py b/modules/textual_inversion/textual_inversion.py
index 2630c7c9..5421a758 100644
--- a/modules/textual_inversion/textual_inversion.py
+++ b/modules/textual_inversion/textual_inversion.py
@@ -10,7 +10,7 @@ import csv
from PIL import Image, PngImagePlugin
-from modules import shared, devices, sd_hijack, processing, sd_models, images
+from modules import shared, devices, sd_hijack, processing, sd_models, images, sd_samplers
import modules.textual_inversion.dataset
from modules.textual_inversion.learn_schedule import LearnRateScheduler
@@ -23,9 +23,12 @@ class Embedding:
self.vec = vec
self.name = name
self.step = step
+ self.shape = None
+ self.vectors = 0
self.cached_checksum = None
self.sd_checkpoint = None
self.sd_checkpoint_name = None
+ self.optimizer_state_dict = None
def save(self, filename):
embedding_data = {
@@ -39,6 +42,13 @@ class Embedding:
torch.save(embedding_data, filename)
+ if shared.opts.save_optimizer_state and self.optimizer_state_dict is not None:
+ optimizer_saved_dict = {
+ 'hash': self.checksum(),
+ 'optimizer_state_dict': self.optimizer_state_dict,
+ }
+ torch.save(optimizer_saved_dict, filename + '.optim')
+
def checksum(self):
if self.cached_checksum is not None:
return self.cached_checksum
@@ -57,14 +67,17 @@ class EmbeddingDatabase:
def __init__(self, embeddings_dir):
self.ids_lookup = {}
self.word_embeddings = {}
+ self.skipped_embeddings = {}
self.dir_mtime = None
self.embeddings_dir = embeddings_dir
+ self.expected_shape = -1
def register_embedding(self, embedding, model):
self.word_embeddings[embedding.name] = embedding
- ids = model.cond_stage_model.tokenizer([embedding.name], add_special_tokens=False)['input_ids'][0]
+ # TODO changing between clip and open clip changes tokenization, which will cause embeddings to stop working
+ ids = model.cond_stage_model.tokenize([embedding.name])[0]
first_id = ids[0]
if first_id not in self.ids_lookup:
@@ -74,21 +87,26 @@ class EmbeddingDatabase:
return embedding
- def load_textual_inversion_embeddings(self):
+ def get_expected_shape(self):
+ vec = shared.sd_model.cond_stage_model.encode_embedding_init_text(",", 1)
+ return vec.shape[1]
+
+ def load_textual_inversion_embeddings(self, force_reload = False):
mt = os.path.getmtime(self.embeddings_dir)
- if self.dir_mtime is not None and mt <= self.dir_mtime:
+ if not force_reload and self.dir_mtime is not None and mt <= self.dir_mtime:
return
self.dir_mtime = mt
self.ids_lookup.clear()
self.word_embeddings.clear()
+ self.skipped_embeddings.clear()
+ self.expected_shape = self.get_expected_shape()
def process_file(path, filename):
- name = os.path.splitext(filename)[0]
+ name, ext = os.path.splitext(filename)
+ ext = ext.upper()
- data = []
-
- if os.path.splitext(filename.upper())[-1] in ['.PNG', '.WEBP', '.JXL', '.AVIF']:
+ if ext in ['.PNG', '.WEBP', '.JXL', '.AVIF']:
embed_image = Image.open(path)
if hasattr(embed_image, 'text') and 'sd-ti-embedding' in embed_image.text:
data = embedding_from_b64(embed_image.text['sd-ti-embedding'])
@@ -96,8 +114,10 @@ class EmbeddingDatabase:
else:
data = extract_image_data_embed(embed_image)
name = data.get('name', name)
- else:
+ elif ext in ['.BIN', '.PT']:
data = torch.load(path, map_location="cpu")
+ else:
+ return
# textual inversion embeddings
if 'string_to_param' in data:
@@ -121,7 +141,13 @@ class EmbeddingDatabase:
embedding.step = data.get('step', None)
embedding.sd_checkpoint = data.get('sd_checkpoint', None)
embedding.sd_checkpoint_name = data.get('sd_checkpoint_name', None)
- self.register_embedding(embedding, shared.sd_model)
+ embedding.vectors = vec.shape[0]
+ embedding.shape = vec.shape[-1]
+
+ if self.expected_shape == -1 or self.expected_shape == embedding.shape:
+ self.register_embedding(embedding, shared.sd_model)
+ else:
+ self.skipped_embeddings[name] = embedding
for fn in os.listdir(self.embeddings_dir):
try:
@@ -132,12 +158,13 @@ class EmbeddingDatabase:
process_file(fullfn, fn)
except Exception:
- print(f"Error loading emedding {fn}:", file=sys.stderr)
+ print(f"Error loading embedding {fn}:", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
continue
- print(f"Loaded a total of {len(self.word_embeddings)} textual inversion embeddings.")
- print("Embeddings:", ', '.join(self.word_embeddings.keys()))
+ print(f"Textual inversion embeddings loaded({len(self.word_embeddings)}): {', '.join(self.word_embeddings.keys())}")
+ if len(self.skipped_embeddings) > 0:
+ print(f"Textual inversion embeddings skipped({len(self.skipped_embeddings)}): {', '.join(self.skipped_embeddings.keys())}")
def find_embedding_at_position(self, tokens, offset):
token = tokens[offset]
@@ -155,13 +182,11 @@ class EmbeddingDatabase:
def create_embedding(name, num_vectors_per_token, overwrite_old, init_text='*'):
cond_model = shared.sd_model.cond_stage_model
- embedding_layer = cond_model.wrapped.transformer.text_model.embeddings
with devices.autocast():
cond_model([""]) # will send cond model to GPU if lowvram/medvram is active
- ids = cond_model.tokenizer(init_text, max_length=num_vectors_per_token, return_tensors="pt", add_special_tokens=False)["input_ids"]
- embedded = embedding_layer.token_embedding.wrapped(ids.to(devices.device)).squeeze(0)
+ embedded = cond_model.encode_embedding_init_text(init_text, num_vectors_per_token)
vec = torch.zeros((num_vectors_per_token, embedded.shape[1]), device=devices.device)
for i in range(num_vectors_per_token):
@@ -184,7 +209,7 @@ def write_loss(log_directory, filename, step, epoch_len, values):
if shared.opts.training_write_csv_every == 0:
return
- if (step + 1) % shared.opts.training_write_csv_every != 0:
+ if step % shared.opts.training_write_csv_every != 0:
return
write_csv_header = False if os.path.exists(os.path.join(log_directory, filename)) else True
@@ -194,21 +219,23 @@ def write_loss(log_directory, filename, step, epoch_len, values):
if write_csv_header:
csv_writer.writeheader()
- epoch = step // epoch_len
- epoch_step = step % epoch_len
+ epoch = (step - 1) // epoch_len
+ epoch_step = (step - 1) % epoch_len
csv_writer.writerow({
- "step": step + 1,
+ "step": step,
"epoch": epoch,
- "epoch_step": epoch_step + 1,
+ "epoch_step": epoch_step,
**values,
})
-def validate_train_inputs(model_name, learn_rate, batch_size, data_root, template_file, steps, save_model_every, create_image_every, log_directory, name="embedding"):
+def validate_train_inputs(model_name, learn_rate, batch_size, gradient_step, data_root, template_file, steps, save_model_every, create_image_every, log_directory, name="embedding"):
assert model_name, f"{name} not selected"
assert learn_rate, "Learning rate is empty or 0"
assert isinstance(batch_size, int), "Batch size must be integer"
assert batch_size > 0, "Batch size must be positive"
+ assert isinstance(gradient_step, int), "Gradient accumulation step must be integer"
+ assert gradient_step > 0, "Gradient accumulation step must be positive"
assert data_root, "Dataset directory is empty"
assert os.path.isdir(data_root), "Dataset directory doesn't exist"
assert os.listdir(data_root), "Dataset directory is empty"
@@ -244,11 +271,12 @@ def create_dummy_mask(x, width=None, height=None):
return image_conditioning
-def train_embedding(embedding_name, learn_rate, batch_size, data_root, log_directory, training_width, training_height, steps, create_image_every, save_embedding_every, template_file, save_image_with_stored_embedding, preview_from_txt2img, preview_prompt, preview_negative_prompt, preview_steps, preview_sampler_index, preview_cfg_scale, preview_seed, preview_width, preview_height):
+def train_embedding(embedding_name, learn_rate, batch_size, gradient_step, data_root, log_directory, training_width, training_height, steps, shuffle_tags, tag_drop_out, latent_sampling_method, create_image_every, save_embedding_every, template_file, save_image_with_stored_embedding, preview_from_txt2img, preview_prompt, preview_negative_prompt, preview_steps, preview_sampler_index, preview_cfg_scale, preview_seed, preview_width, preview_height):
save_embedding_every = save_embedding_every or 0
create_image_every = create_image_every or 0
- validate_train_inputs(embedding_name, learn_rate, batch_size, data_root, template_file, steps, save_embedding_every, create_image_every, log_directory, name="embedding")
+ validate_train_inputs(embedding_name, learn_rate, batch_size, gradient_step, data_root, template_file, steps, save_embedding_every, create_image_every, log_directory, name="embedding")
+ shared.state.job = "train-embedding"
shared.state.textinfo = "Initializing textual inversion training..."
shared.state.job_count = steps
@@ -275,31 +303,58 @@ def train_embedding(embedding_name, learn_rate, batch_size, data_root, log_direc
else:
images_embeds_dir = None
- cond_model = shared.sd_model.cond_stage_model
-
hijack = sd_hijack.model_hijack
embedding = hijack.embedding_db.word_embeddings[embedding_name]
checkpoint = sd_models.select_checkpoint()
- ititial_step = embedding.step or 0
- if ititial_step >= steps:
- shared.state.textinfo = f"Model has already been trained beyond specified max steps"
+ initial_step = embedding.step or 0
+ if initial_step >= steps:
+ shared.state.textinfo = "Model has already been trained beyond specified max steps"
return embedding, filename
-
- scheduler = LearnRateScheduler(learn_rate, steps, ititial_step)
+ scheduler = LearnRateScheduler(learn_rate, steps, initial_step)
# dataset loading may take a while, so input validations and early returns should be done before this
shared.state.textinfo = f"Preparing dataset from {html.escape(data_root)}..."
- with torch.autocast("cuda"):
- ds = modules.textual_inversion.dataset.PersonalizedBase(data_root=data_root, width=training_width, height=training_height, repeats=shared.opts.training_image_repeats_per_epoch, placeholder_token=embedding_name, model=shared.sd_model, device=devices.device, template_file=template_file, batch_size=batch_size)
+ old_parallel_processing_allowed = shared.parallel_processing_allowed
+
+ pin_memory = shared.opts.pin_memory
+
+ ds = modules.textual_inversion.dataset.PersonalizedBase(data_root=data_root, width=training_width, height=training_height, repeats=shared.opts.training_image_repeats_per_epoch, placeholder_token=embedding_name, model=shared.sd_model, cond_model=shared.sd_model.cond_stage_model, device=devices.device, template_file=template_file, batch_size=batch_size, gradient_step=gradient_step, shuffle_tags=shuffle_tags, tag_drop_out=tag_drop_out, latent_sampling_method=latent_sampling_method)
+
+ latent_sampling_method = ds.latent_sampling_method
+
+ dl = modules.textual_inversion.dataset.PersonalizedDataLoader(ds, latent_sampling_method=latent_sampling_method, batch_size=ds.batch_size, pin_memory=pin_memory)
+
if unload:
+ shared.parallel_processing_allowed = False
shared.sd_model.first_stage_model.to(devices.cpu)
embedding.vec.requires_grad = True
- optimizer = torch.optim.AdamW([embedding.vec], lr=scheduler.learn_rate)
-
- losses = torch.zeros((32,))
+ optimizer = torch.optim.AdamW([embedding.vec], lr=scheduler.learn_rate, weight_decay=0.0)
+ if shared.opts.save_optimizer_state:
+ optimizer_state_dict = None
+ if os.path.exists(filename + '.optim'):
+ optimizer_saved_dict = torch.load(filename + '.optim', map_location='cpu')
+ if embedding.checksum() == optimizer_saved_dict.get('hash', None):
+ optimizer_state_dict = optimizer_saved_dict.get('optimizer_state_dict', None)
+
+ if optimizer_state_dict is not None:
+ optimizer.load_state_dict(optimizer_state_dict)
+ print("Loaded existing optimizer from checkpoint")
+ else:
+ print("No saved optimizer exists in checkpoint")
+
+
+ scaler = torch.cuda.amp.GradScaler()
+
+ batch_size = ds.batch_size
+ gradient_step = ds.gradient_step
+ # n steps = batch_size * gradient_step * n image processed
+ steps_per_epoch = len(ds) // batch_size // gradient_step
+ max_steps_per_epoch = len(ds) // batch_size - (len(ds) // batch_size) % gradient_step
+ loss_step = 0
+ _loss_step = 0 #internal
last_saved_file = "<none>"
last_saved_image = "<none>"
@@ -307,138 +362,166 @@ def train_embedding(embedding_name, learn_rate, batch_size, data_root, log_direc
embedding_yet_to_be_embedded = False
img_c = None
- pbar = tqdm.tqdm(enumerate(ds), total=steps-ititial_step)
- for i, entries in pbar:
- embedding.step = i + ititial_step
-
- scheduler.apply(optimizer, embedding.step)
- if scheduler.finished:
- break
-
- if shared.state.interrupted:
- break
-
- with torch.autocast("cuda"):
- c = cond_model([entry.cond_text for entry in entries])
- if img_c is None:
- img_c = create_dummy_mask(c, training_width, training_height)
-
- x = torch.stack([entry.latent for entry in entries]).to(devices.device)
- cond = {"c_concat": [img_c], "c_crossattn": [c]}
- loss = shared.sd_model(x, cond)[0]
- del x
-
- losses[embedding.step % losses.shape[0]] = loss.item()
-
- optimizer.zero_grad()
- loss.backward()
- optimizer.step()
-
- steps_done = embedding.step + 1
-
- epoch_num = embedding.step // len(ds)
- epoch_step = embedding.step % len(ds)
-
- pbar.set_description(f"[Epoch {epoch_num}: {epoch_step+1}/{len(ds)}]loss: {losses.mean():.7f}")
-
- if embedding_dir is not None and steps_done % save_embedding_every == 0:
- # Before saving, change name to match current checkpoint.
- embedding_name_every = f'{embedding_name}-{steps_done}'
- last_saved_file = os.path.join(embedding_dir, f'{embedding_name_every}.pt')
- save_embedding(embedding, checkpoint, embedding_name_every, last_saved_file, remove_cached_checksum=True)
- embedding_yet_to_be_embedded = True
-
- write_loss(log_directory, "textual_inversion_loss.csv", embedding.step, len(ds), {
- "loss": f"{losses.mean():.7f}",
- "learn_rate": scheduler.learn_rate
- })
-
- if images_dir is not None and steps_done % create_image_every == 0:
- forced_filename = f'{embedding_name}-{steps_done}'
- last_saved_image = os.path.join(images_dir, forced_filename)
-
- shared.sd_model.first_stage_model.to(devices.device)
-
- p = processing.StableDiffusionProcessingTxt2Img(
- sd_model=shared.sd_model,
- do_not_save_grid=True,
- do_not_save_samples=True,
- do_not_reload_embeddings=True,
- )
-
- if preview_from_txt2img:
- p.prompt = preview_prompt
- p.negative_prompt = preview_negative_prompt
- p.steps = preview_steps
- p.sampler_index = preview_sampler_index
- p.cfg_scale = preview_cfg_scale
- p.seed = preview_seed
- p.width = preview_width
- p.height = preview_height
- else:
- p.prompt = entries[0].cond_text
- p.steps = 20
- p.width = training_width
- p.height = training_height
-
- preview_text = p.prompt
-
- processed = processing.process_images(p)
- image = processed.images[0]
-
- if unload:
- shared.sd_model.first_stage_model.to(devices.cpu)
-
- shared.state.current_image = image
-
- if save_image_with_stored_embedding and os.path.exists(last_saved_file) and embedding_yet_to_be_embedded:
-
- last_saved_image_chunks = os.path.join(images_embeds_dir, f'{embedding_name}-{steps_done}.png')
-
- info = PngImagePlugin.PngInfo()
- data = torch.load(last_saved_file)
- info.add_text("sd-ti-embedding", embedding_to_b64(data))
-
- title = "<{}>".format(data.get('name', '???'))
-
- try:
- vectorSize = list(data['string_to_param'].values())[0].shape[0]
- except Exception as e:
- vectorSize = '?'
-
- checkpoint = sd_models.select_checkpoint()
- footer_left = checkpoint.model_name
- footer_mid = '[{}]'.format(checkpoint.hash)
- footer_right = '{}v {}s'.format(vectorSize, steps_done)
-
- captioned_image = caption_image_overlay(image, title, footer_left, footer_mid, footer_right)
- captioned_image = insert_image_data_embed(captioned_image, data)
-
- captioned_image.save(last_saved_image_chunks, "PNG", pnginfo=info)
- embedding_yet_to_be_embedded = False
-
- last_saved_image, last_text_info = images.save_image(image, images_dir, "", p.seed, p.prompt, shared.opts.samples_format, processed.infotexts[0], p=p, forced_filename=forced_filename, save_to_dirs=False)
- last_saved_image += f", prompt: {preview_text}"
-
- shared.state.job_no = embedding.step
-
- shared.state.textinfo = f"""
+ pbar = tqdm.tqdm(total=steps - initial_step)
+ try:
+ for i in range((steps-initial_step) * gradient_step):
+ if scheduler.finished:
+ break
+ if shared.state.interrupted:
+ break
+ for j, batch in enumerate(dl):
+ # works as a drop_last=True for gradient accumulation
+ if j == max_steps_per_epoch:
+ break
+ scheduler.apply(optimizer, embedding.step)
+ if scheduler.finished:
+ break
+ if shared.state.interrupted:
+ break
+
+ with devices.autocast():
+ # c = stack_conds(batch.cond).to(devices.device)
+ # mask = torch.tensor(batch.emb_index).to(devices.device, non_blocking=pin_memory)
+ # print(mask)
+ # c[:, 1:1+embedding.vec.shape[0]] = embedding.vec.to(devices.device, non_blocking=pin_memory)
+
+
+ if img_c is None:
+ img_c = create_dummy_mask(c, training_width, training_height)
+
+ x = batch.latent_sample.to(devices.device, non_blocking=pin_memory)
+ c = shared.sd_model.cond_stage_model(batch.cond_text)
+ cond = {"c_concat": [img_c], "c_crossattn": [c]}
+ loss = shared.sd_model(x, cond)[0] / gradient_step
+ del x
+
+ _loss_step += loss.item()
+ scaler.scale(loss).backward()
+
+ # go back until we reach gradient accumulation steps
+ if (j + 1) % gradient_step != 0:
+ continue
+ scaler.step(optimizer)
+ scaler.update()
+ embedding.step += 1
+ pbar.update()
+ optimizer.zero_grad(set_to_none=True)
+ loss_step = _loss_step
+ _loss_step = 0
+
+ steps_done = embedding.step + 1
+
+ epoch_num = embedding.step // steps_per_epoch
+ epoch_step = embedding.step % steps_per_epoch
+
+ pbar.set_description(f"[Epoch {epoch_num}: {epoch_step+1}/{steps_per_epoch}]loss: {loss_step:.7f}")
+ if embedding_dir is not None and steps_done % save_embedding_every == 0:
+ # Before saving, change name to match current checkpoint.
+ embedding_name_every = f'{embedding_name}-{steps_done}'
+ last_saved_file = os.path.join(embedding_dir, f'{embedding_name_every}.pt')
+ save_embedding(embedding, optimizer, checkpoint, embedding_name_every, last_saved_file, remove_cached_checksum=True)
+ embedding_yet_to_be_embedded = True
+
+ write_loss(log_directory, "textual_inversion_loss.csv", embedding.step, steps_per_epoch, {
+ "loss": f"{loss_step:.7f}",
+ "learn_rate": scheduler.learn_rate
+ })
+
+ if images_dir is not None and steps_done % create_image_every == 0:
+ forced_filename = f'{embedding_name}-{steps_done}'
+ last_saved_image = os.path.join(images_dir, forced_filename)
+
+ shared.sd_model.first_stage_model.to(devices.device)
+
+ p = processing.StableDiffusionProcessingTxt2Img(
+ sd_model=shared.sd_model,
+ do_not_save_grid=True,
+ do_not_save_samples=True,
+ do_not_reload_embeddings=True,
+ )
+
+ if preview_from_txt2img:
+ p.prompt = preview_prompt
+ p.negative_prompt = preview_negative_prompt
+ p.steps = preview_steps
+ p.sampler_name = sd_samplers.samplers[preview_sampler_index].name
+ p.cfg_scale = preview_cfg_scale
+ p.seed = preview_seed
+ p.width = preview_width
+ p.height = preview_height
+ else:
+ p.prompt = batch.cond_text[0]
+ p.steps = 20
+ p.width = training_width
+ p.height = training_height
+
+ preview_text = p.prompt
+
+ processed = processing.process_images(p)
+ image = processed.images[0] if len(processed.images) > 0 else None
+
+ if unload:
+ shared.sd_model.first_stage_model.to(devices.cpu)
+
+ if image is not None:
+ shared.state.current_image = image
+ last_saved_image, last_text_info = images.save_image(image, images_dir, "", p.seed, p.prompt, shared.opts.samples_format, processed.infotexts[0], p=p, forced_filename=forced_filename, save_to_dirs=False)
+ last_saved_image += f", prompt: {preview_text}"
+
+ if save_image_with_stored_embedding and os.path.exists(last_saved_file) and embedding_yet_to_be_embedded:
+
+ last_saved_image_chunks = os.path.join(images_embeds_dir, f'{embedding_name}-{steps_done}.png')
+
+ info = PngImagePlugin.PngInfo()
+ data = torch.load(last_saved_file)
+ info.add_text("sd-ti-embedding", embedding_to_b64(data))
+
+ title = "<{}>".format(data.get('name', '???'))
+
+ try:
+ vectorSize = list(data['string_to_param'].values())[0].shape[0]
+ except Exception as e:
+ vectorSize = '?'
+
+ checkpoint = sd_models.select_checkpoint()
+ footer_left = checkpoint.model_name
+ footer_mid = '[{}]'.format(checkpoint.hash)
+ footer_right = '{}v {}s'.format(vectorSize, steps_done)
+
+ captioned_image = caption_image_overlay(image, title, footer_left, footer_mid, footer_right)
+ captioned_image = insert_image_data_embed(captioned_image, data)
+
+ captioned_image.save(last_saved_image_chunks, "PNG", pnginfo=info)
+ embedding_yet_to_be_embedded = False
+
+ last_saved_image, last_text_info = images.save_image(image, images_dir, "", p.seed, p.prompt, shared.opts.samples_format, processed.infotexts[0], p=p, forced_filename=forced_filename, save_to_dirs=False)
+ last_saved_image += f", prompt: {preview_text}"
+
+ shared.state.job_no = embedding.step
+
+ shared.state.textinfo = f"""
<p>
-Loss: {losses.mean():.7f}<br/>
-Step: {embedding.step}<br/>
-Last prompt: {html.escape(entries[0].cond_text)}<br/>
+Loss: {loss_step:.7f}<br/>
+Step: {steps_done}<br/>
+Last prompt: {html.escape(batch.cond_text[0])}<br/>
Last saved embedding: {html.escape(last_saved_file)}<br/>
Last saved image: {html.escape(last_saved_image)}<br/>
</p>
"""
-
- filename = os.path.join(shared.cmd_opts.embeddings_dir, f'{embedding_name}.pt')
- save_embedding(embedding, checkpoint, embedding_name, filename, remove_cached_checksum=True)
- shared.sd_model.first_stage_model.to(devices.device)
+ filename = os.path.join(shared.cmd_opts.embeddings_dir, f'{embedding_name}.pt')
+ save_embedding(embedding, optimizer, checkpoint, embedding_name, filename, remove_cached_checksum=True)
+ except Exception:
+ print(traceback.format_exc(), file=sys.stderr)
+ pass
+ finally:
+ pbar.leave = False
+ pbar.close()
+ shared.sd_model.first_stage_model.to(devices.device)
+ shared.parallel_processing_allowed = old_parallel_processing_allowed
return embedding, filename
-def save_embedding(embedding, checkpoint, embedding_name, filename, remove_cached_checksum=True):
+def save_embedding(embedding, optimizer, checkpoint, embedding_name, filename, remove_cached_checksum=True):
old_embedding_name = embedding.name
old_sd_checkpoint = embedding.sd_checkpoint if hasattr(embedding, "sd_checkpoint") else None
old_sd_checkpoint_name = embedding.sd_checkpoint_name if hasattr(embedding, "sd_checkpoint_name") else None
@@ -449,6 +532,7 @@ def save_embedding(embedding, checkpoint, embedding_name, filename, remove_cache
if remove_cached_checksum:
embedding.cached_checksum = None
embedding.name = embedding_name
+ embedding.optimizer_state_dict = optimizer.state_dict()
embedding.save(filename)
except:
embedding.sd_checkpoint = old_sd_checkpoint
diff --git a/modules/textual_inversion/ui.py b/modules/textual_inversion/ui.py
index d679e6f4..35c4feef 100644
--- a/modules/textual_inversion/ui.py
+++ b/modules/textual_inversion/ui.py
@@ -18,7 +18,7 @@ def create_embedding(name, initialization_text, nvpt, overwrite_old):
def preprocess(*args):
modules.textual_inversion.preprocess.preprocess(*args)
- return "Preprocessing finished.", ""
+ return f"Preprocessing {'interrupted' if shared.state.interrupted else 'finished'}.", ""
def train_embedding(*args):
diff --git a/modules/txt2img.py b/modules/txt2img.py
index c9d5a090..e189a899 100644
--- a/modules/txt2img.py
+++ b/modules/txt2img.py
@@ -1,4 +1,5 @@
import modules.scripts
+from modules import sd_samplers
from modules.processing import StableDiffusionProcessing, Processed, StableDiffusionProcessingTxt2Img, \
StableDiffusionProcessingImg2Img, process_images
from modules.shared import opts, cmd_opts
@@ -7,7 +8,7 @@ import modules.processing as processing
from modules.ui import plaintext_to_html
-def txt2img(prompt: str, negative_prompt: str, prompt_style: str, prompt_style2: str, steps: int, sampler_index: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, enable_hr: bool, denoising_strength: float, firstphase_width: int, firstphase_height: int, *args):
+def txt2img(prompt: str, negative_prompt: str, prompt_style: str, prompt_style2: str, steps: int, sampler_index: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, enable_hr: bool, denoising_strength: float, hr_scale: float, hr_upscaler: str, *args):
p = StableDiffusionProcessingTxt2Img(
sd_model=shared.sd_model,
outpath_samples=opts.outdir_samples or opts.outdir_txt2img_samples,
@@ -21,7 +22,7 @@ def txt2img(prompt: str, negative_prompt: str, prompt_style: str, prompt_style2:
seed_resize_from_h=seed_resize_from_h,
seed_resize_from_w=seed_resize_from_w,
seed_enable_extras=seed_enable_extras,
- sampler_index=sampler_index,
+ sampler_name=sd_samplers.samplers[sampler_index].name,
batch_size=batch_size,
n_iter=n_iter,
steps=steps,
@@ -32,8 +33,8 @@ def txt2img(prompt: str, negative_prompt: str, prompt_style: str, prompt_style2:
tiling=tiling,
enable_hr=enable_hr,
denoising_strength=denoising_strength if enable_hr else None,
- firstphase_width=firstphase_width if enable_hr else None,
- firstphase_height=firstphase_height if enable_hr else None,
+ hr_scale=hr_scale,
+ hr_upscaler=hr_upscaler,
)
p.scripts = modules.scripts.scripts_txt2img
@@ -47,6 +48,8 @@ def txt2img(prompt: str, negative_prompt: str, prompt_style: str, prompt_style2:
if processed is None:
processed = process_images(p)
+ p.close()
+
shared.total_tqdm.clear()
generation_info_js = processed.js()
@@ -56,4 +59,4 @@ def txt2img(prompt: str, negative_prompt: str, prompt_style: str, prompt_style2:
if opts.do_not_show_images:
processed.images = []
- return processed.images, generation_info_js, plaintext_to_html(processed.info)
+ return processed.images, generation_info_js, plaintext_to_html(processed.info), plaintext_to_html(processed.comments)
diff --git a/modules/ui.py b/modules/ui.py
index 2c15abb7..bfc93634 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -17,21 +17,18 @@ import gradio.routes
import gradio.utils
import numpy as np
from PIL import Image, PngImagePlugin
+from modules.call_queue import wrap_gradio_gpu_call, wrap_queued_call, wrap_gradio_call
-
-from modules import sd_hijack, sd_models, localization, script_callbacks, ui_extensions
+from modules import sd_hijack, sd_models, localization, script_callbacks, ui_extensions, deepbooru
+from modules.ui_components import FormRow, FormGroup, ToolButton
from modules.paths import script_path
from modules.shared import opts, cmd_opts, restricted_opts
-if cmd_opts.deepdanbooru:
- from modules.deepbooru import get_deepbooru_tags
-
import modules.codeformer_model
import modules.generation_parameters_copypaste as parameters_copypaste
import modules.gfpgan_model
import modules.hypernetworks.ui
-import modules.ldsr_model
import modules.scripts
import modules.shared as shared
import modules.styles
@@ -53,10 +50,14 @@ if not cmd_opts.share and not cmd_opts.listen:
gradio.utils.version_check = lambda: None
gradio.utils.get_local_ip_address = lambda: '127.0.0.1'
-if cmd_opts.ngrok != None:
+if cmd_opts.ngrok is not None:
import modules.ngrok as ngrok
print('ngrok authtoken detected, trying to connect...')
- ngrok.connect(cmd_opts.ngrok, cmd_opts.port if cmd_opts.port != None else 7860, cmd_opts.ngrok_region)
+ ngrok.connect(
+ cmd_opts.ngrok,
+ cmd_opts.port if cmd_opts.port is not None else 7860,
+ cmd_opts.ngrok_region
+ )
def gr_show(visible=True):
@@ -69,20 +70,23 @@ sample_img2img = sample_img2img if os.path.exists(sample_img2img) else None
css_hide_progressbar = """
.wrap .m-12 svg { display:none!important; }
.wrap .m-12::before { content:"Loading..." }
+.wrap .z-20 svg { display:none!important; }
+.wrap .z-20::before { content:"Loading..." }
.progress-bar { display:none!important; }
.meta-text { display:none!important; }
+.meta-text-center { display:none!important; }
"""
# Using constants for these since the variation selector isn't visible.
# Important that they exactly match script.js for tooltip to work.
random_symbol = '\U0001f3b2\ufe0f' # 🎲️
reuse_symbol = '\u267b\ufe0f' # ♻️
-art_symbol = '\U0001f3a8' # 🎨
paste_symbol = '\u2199\ufe0f' # ↙
folder_symbol = '\U0001f4c2' # 📂
refresh_symbol = '\U0001f504' # 🔄
save_style_symbol = '\U0001f4be' # 💾
apply_style_symbol = '\U0001f4cb' # 📋
+clear_prompt_symbol = '\U0001F5D1' # 🗑️
def plaintext_to_html(text):
@@ -142,7 +146,7 @@ def save_files(js_data, images, do_make_zip, index):
filenames.append(os.path.basename(txt_fullfn))
fullfns.append(txt_fullfn)
- writer.writerow([data["prompt"], data["seed"], data["width"], data["height"], data["sampler"], data["cfg_scale"], data["steps"], filenames[0], data["negative_prompt"]])
+ writer.writerow([data["prompt"], data["seed"], data["width"], data["height"], data["sampler_name"], data["cfg_scale"], data["steps"], filenames[0], data["negative_prompt"]])
# Make Zip
if do_make_zip:
@@ -155,83 +159,9 @@ def save_files(js_data, images, do_make_zip, index):
zip_file.writestr(filenames[i], f.read())
fullfns.insert(0, zip_filepath)
- return gr.File.update(value=fullfns, visible=True), '', '', plaintext_to_html(f"Saved: {filenames[0]}")
-
-def save_pil_to_file(pil_image, dir=None):
- use_metadata = False
- metadata = PngImagePlugin.PngInfo()
- for key, value in pil_image.info.items():
- if isinstance(key, str) and isinstance(value, str):
- metadata.add_text(key, value)
- use_metadata = True
-
- file_obj = tempfile.NamedTemporaryFile(delete=False, suffix=".png", dir=dir)
- pil_image.save(file_obj, pnginfo=(metadata if use_metadata else None))
- return file_obj
-
-
-# override save to file function so that it also writes PNG info
-gr.processing_utils.save_pil_to_file = save_pil_to_file
-
-
-def wrap_gradio_call(func, extra_outputs=None):
- def f(*args, extra_outputs_array=extra_outputs, **kwargs):
- run_memmon = opts.memmon_poll_rate > 0 and not shared.mem_mon.disabled
- if run_memmon:
- shared.mem_mon.monitor()
- t = time.perf_counter()
-
- try:
- res = list(func(*args, **kwargs))
- except Exception as e:
- # When printing out our debug argument list, do not print out more than a MB of text
- max_debug_str_len = 131072 # (1024*1024)/8
-
- print("Error completing request", file=sys.stderr)
- argStr = f"Arguments: {str(args)} {str(kwargs)}"
- print(argStr[:max_debug_str_len], file=sys.stderr)
- if len(argStr) > max_debug_str_len:
- print(f"(Argument list truncated at {max_debug_str_len}/{len(argStr)} characters)", file=sys.stderr)
-
- print(traceback.format_exc(), file=sys.stderr)
-
- shared.state.job = ""
- shared.state.job_count = 0
-
- if extra_outputs_array is None:
- extra_outputs_array = [None, '']
-
- res = extra_outputs_array + [f"<div class='error'>{plaintext_to_html(type(e).__name__+': '+str(e))}</div>"]
-
- elapsed = time.perf_counter() - t
- elapsed_m = int(elapsed // 60)
- elapsed_s = elapsed % 60
- elapsed_text = f"{elapsed_s:.2f}s"
- if (elapsed_m > 0):
- elapsed_text = f"{elapsed_m}m "+elapsed_text
-
- if run_memmon:
- mem_stats = {k: -(v//-(1024*1024)) for k, v in shared.mem_mon.stop().items()}
- active_peak = mem_stats['active_peak']
- reserved_peak = mem_stats['reserved_peak']
- sys_peak = mem_stats['system_peak']
- sys_total = mem_stats['total']
- sys_pct = round(sys_peak/max(sys_total, 1) * 100, 2)
-
- vram_html = f"<p class='vram'>Torch active/reserved: {active_peak}/{reserved_peak} MiB, <wbr>Sys VRAM: {sys_peak}/{sys_total} MiB ({sys_pct}%)</p>"
- else:
- vram_html = ''
-
- # last item is always HTML
- res[-1] += f"<div class='performance'><p class='time'>Time taken: <wbr>{elapsed_text}</p>{vram_html}</div>"
-
- shared.state.skipped = False
- shared.state.interrupted = False
- shared.state.job_count = 0
+ return gr.File.update(value=fullfns, visible=True), plaintext_to_html(f"Saved: {filenames[0]}")
- return tuple(res)
- return f
def calc_time_left(progress, threshold, label, force_display):
@@ -276,16 +206,8 @@ def check_progress_call(id_part):
image = gr_show(False)
preview_visibility = gr_show(False)
- if opts.show_progress_every_n_steps > 0:
- if shared.parallel_processing_allowed:
-
- if shared.state.sampling_step - shared.state.current_image_sampling_step >= opts.show_progress_every_n_steps and shared.state.current_latent is not None:
- if opts.show_progress_grid:
- shared.state.current_image = modules.sd_samplers.samples_to_image_grid(shared.state.current_latent)
- else:
- shared.state.current_image = modules.sd_samplers.sample_to_image(shared.state.current_latent)
- shared.state.current_image_sampling_step = shared.state.sampling_step
-
+ if opts.show_progress_every_n_steps != 0:
+ shared.state.set_current_image()
image = shared.state.current_image
if image is None:
@@ -312,13 +234,6 @@ def check_progress_call_initial(id_part):
return check_progress_call(id_part)
-def roll_artist(prompt):
- allowed_cats = set([x for x in shared.artist_db.categories() if len(opts.random_artist_categories)==0 or x in opts.random_artist_categories])
- artist = random.choice([x for x in shared.artist_db.artists if x.category in allowed_cats])
-
- return prompt + ", " + artist.name if prompt != '' else artist.name
-
-
def visit(x, func, path=""):
if hasattr(x, 'children'):
for c in x.children:
@@ -348,45 +263,41 @@ def apply_styles(prompt, prompt_neg, style1_name, style2_name):
def interrogate(image):
- prompt = shared.interrogator.interrogate(image)
+ prompt = shared.interrogator.interrogate(image.convert("RGB"))
return gr_show(True) if prompt is None else prompt
def interrogate_deepbooru(image):
- prompt = get_deepbooru_tags(image)
+ prompt = deepbooru.model.tag(image)
return gr_show(True) if prompt is None else prompt
-def create_seed_inputs():
- with gr.Row():
- with gr.Box():
- with gr.Row(elem_id='seed_row'):
- seed = (gr.Textbox if cmd_opts.use_textbox_seed else gr.Number)(label='Seed', value=-1)
- seed.style(container=False)
- random_seed = gr.Button(random_symbol, elem_id='random_seed')
- reuse_seed = gr.Button(reuse_symbol, elem_id='reuse_seed')
+def create_seed_inputs(target_interface):
+ with FormRow(elem_id=target_interface + '_seed_row'):
+ seed = (gr.Textbox if cmd_opts.use_textbox_seed else gr.Number)(label='Seed', value=-1, elem_id=target_interface + '_seed')
+ seed.style(container=False)
+ random_seed = gr.Button(random_symbol, elem_id=target_interface + '_random_seed')
+ reuse_seed = gr.Button(reuse_symbol, elem_id=target_interface + '_reuse_seed')
- with gr.Box(elem_id='subseed_show_box'):
- seed_checkbox = gr.Checkbox(label='Extra', elem_id='subseed_show', value=False)
+ with gr.Group(elem_id=target_interface + '_subseed_show_box'):
+ seed_checkbox = gr.Checkbox(label='Extra', elem_id=target_interface + '_subseed_show', value=False)
# Components to show/hide based on the 'Extra' checkbox
seed_extras = []
- with gr.Row(visible=False) as seed_extra_row_1:
+ with FormRow(visible=False, elem_id=target_interface + '_subseed_row') as seed_extra_row_1:
seed_extras.append(seed_extra_row_1)
- with gr.Box():
- with gr.Row(elem_id='subseed_row'):
- subseed = gr.Number(label='Variation seed', value=-1)
- subseed.style(container=False)
- random_subseed = gr.Button(random_symbol, elem_id='random_subseed')
- reuse_subseed = gr.Button(reuse_symbol, elem_id='reuse_subseed')
- subseed_strength = gr.Slider(label='Variation strength', value=0.0, minimum=0, maximum=1, step=0.01)
-
- with gr.Row(visible=False) as seed_extra_row_2:
+ subseed = gr.Number(label='Variation seed', value=-1, elem_id=target_interface + '_subseed')
+ subseed.style(container=False)
+ random_subseed = gr.Button(random_symbol, elem_id=target_interface + '_random_subseed')
+ reuse_subseed = gr.Button(reuse_symbol, elem_id=target_interface + '_reuse_subseed')
+ subseed_strength = gr.Slider(label='Variation strength', value=0.0, minimum=0, maximum=1, step=0.01, elem_id=target_interface + '_subseed_strength')
+
+ with FormRow(visible=False) as seed_extra_row_2:
seed_extras.append(seed_extra_row_2)
- seed_resize_from_w = gr.Slider(minimum=0, maximum=2048, step=64, label="Resize seed from width", value=0)
- seed_resize_from_h = gr.Slider(minimum=0, maximum=2048, step=64, label="Resize seed from height", value=0)
+ seed_resize_from_w = gr.Slider(minimum=0, maximum=2048, step=8, label="Resize seed from width", value=0, elem_id=target_interface + '_seed_resize_from_w')
+ seed_resize_from_h = gr.Slider(minimum=0, maximum=2048, step=8, label="Resize seed from height", value=0, elem_id=target_interface + '_seed_resize_from_h')
random_seed.click(fn=lambda: -1, show_progress=False, inputs=[], outputs=[seed])
random_subseed.click(fn=lambda: -1, show_progress=False, inputs=[], outputs=[subseed])
@@ -399,6 +310,17 @@ def create_seed_inputs():
return seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox
+
+def connect_clear_prompt(button):
+ """Given clear button, prompt, and token_counter objects, setup clear prompt button click event"""
+ button.click(
+ _js="clear_prompt",
+ fn=None,
+ inputs=[],
+ outputs=[],
+ )
+
+
def connect_reuse_seed(seed: gr.Number, reuse_seed: gr.Button, generation_info: gr.Textbox, dummy_component, is_subseed):
""" Connects a 'reuse (sub)seed' button's click event so that it copies last used
(sub)seed value from generation info the to the seed field. If copying subseed and subseed strength
@@ -470,22 +392,26 @@ def create_toprow(is_img2img):
)
with gr.Column(scale=1, elem_id="roll_col"):
- roll = gr.Button(value=art_symbol, elem_id="roll", visible=len(shared.artist_db.artists) > 0)
paste = gr.Button(value=paste_symbol, elem_id="paste")
save_style = gr.Button(value=save_style_symbol, elem_id="style_create")
prompt_style_apply = gr.Button(value=apply_style_symbol, elem_id="style_apply")
-
+ clear_prompt_button = gr.Button(value=clear_prompt_symbol, elem_id=f"{id_part}_clear_prompt")
token_counter = gr.HTML(value="<span></span>", elem_id=f"{id_part}_token_counter")
token_button = gr.Button(visible=False, elem_id=f"{id_part}_token_button")
+ clear_prompt_button.click(
+ fn=lambda *x: x,
+ _js="confirm_clear_prompt",
+ inputs=[prompt, negative_prompt],
+ outputs=[prompt, negative_prompt],
+ )
+
button_interrogate = None
button_deepbooru = None
if is_img2img:
with gr.Column(scale=1, elem_id="interrogate_col"):
button_interrogate = gr.Button('Interrogate\nCLIP', elem_id="interrogate")
-
- if cmd_opts.deepdanbooru:
- button_deepbooru = gr.Button('Interrogate\nDeepBooru', elem_id="deepbooru")
+ button_deepbooru = gr.Button('Interrogate\nDeepBooru', elem_id="deepbooru")
with gr.Column(scale=1):
with gr.Row():
@@ -514,7 +440,7 @@ def create_toprow(is_img2img):
prompt_style2 = gr.Dropdown(label="Style 2", elem_id=f"{id_part}_style2_index", choices=[k for k, v in shared.prompt_styles.styles.items()], value=next(iter(shared.prompt_styles.styles.keys())))
prompt_style2.save_to_config = True
- return prompt, roll, prompt_style, negative_prompt, prompt_style2, submit, button_interrogate, button_deepbooru, prompt_style_apply, save_style, paste, token_counter, token_button
+ return prompt, prompt_style, negative_prompt, prompt_style2, submit, button_interrogate, button_deepbooru, prompt_style_apply, save_style, paste, token_counter, token_button
def setup_progressbar(progressbar, preview, id_part, textinfo=None):
@@ -562,7 +488,7 @@ def apply_setting(key, value):
return
valtype = type(opts.data_labels[key].default)
- oldval = opts.data[key]
+ oldval = opts.data.get(key, None)
opts.data[key] = valtype(value) if valtype != type(None) else value
if oldval != value and opts.data_labels[key].onchange is not None:
opts.data_labels[key].onchange()
@@ -571,6 +497,19 @@ def apply_setting(key, value):
return value
+def update_generation_info(args):
+ generation_info, html_info, img_index = args
+ try:
+ generation_info = json.loads(generation_info)
+ if img_index < 0 or img_index >= len(generation_info["infotexts"]):
+ return html_info
+ return plaintext_to_html(generation_info["infotexts"][img_index])
+ except Exception:
+ pass
+ # if the json parse or anything else fails, just return the old html_info
+ return html_info
+
+
def create_refresh_button(refresh_component, refresh_method, refreshed_args, elem_id):
def refresh():
refresh_method()
@@ -581,7 +520,7 @@ def create_refresh_button(refresh_component, refresh_method, refreshed_args, ele
return gr.update(**(args or {}))
- refresh_button = gr.Button(value=refresh_symbol, elem_id=elem_id)
+ refresh_button = ToolButton(value=refresh_symbol, elem_id=elem_id)
refresh_button.click(
fn=refresh,
inputs=[],
@@ -619,13 +558,14 @@ Requested path was: {f}
generation_info = None
with gr.Column():
- with gr.Row():
+ with gr.Row(elem_id=f"image_buttons_{tabname}"):
+ open_folder_button = gr.Button(folder_symbol, elem_id="hidden_element" if shared.cmd_opts.hide_ui_dir_config else 'open_folder')
+
if tabname != "extras":
save = gr.Button('Save', elem_id=f'save_{tabname}')
+ save_zip = gr.Button('Zip', elem_id=f'save_zip_{tabname}')
buttons = parameters_copypaste.create_buttons(["img2img", "inpaint", "extras"])
- button_id = "hidden_element" if shared.cmd_opts.hide_ui_dir_config else 'open_folder'
- open_folder_button = gr.Button(folder_symbol, elem_id=button_id)
open_folder_button.click(
fn=lambda: open_folder(opts.outdir_samples or outdir),
@@ -635,46 +575,97 @@ Requested path was: {f}
if tabname != "extras":
with gr.Row():
- do_make_zip = gr.Checkbox(label="Make Zip when Save?", value=False)
-
- with gr.Row():
download_files = gr.File(None, file_count="multiple", interactive=False, show_label=False, visible=False)
with gr.Group():
html_info = gr.HTML()
+ html_log = gr.HTML()
+
generation_info = gr.Textbox(visible=False)
+ if tabname == 'txt2img' or tabname == 'img2img':
+ generation_info_button = gr.Button(visible=False, elem_id=f"{tabname}_generation_info_button")
+ generation_info_button.click(
+ fn=update_generation_info,
+ _js="(x, y) => [x, y, selected_gallery_index()]",
+ inputs=[generation_info, html_info],
+ outputs=[html_info],
+ preprocess=False
+ )
save.click(
fn=wrap_gradio_call(save_files),
- _js="(x, y, z, w) => [x, y, z, selected_gallery_index()]",
+ _js="(x, y, z, w) => [x, y, false, selected_gallery_index()]",
inputs=[
generation_info,
result_gallery,
- do_make_zip,
+ html_info,
html_info,
],
outputs=[
download_files,
+ html_log,
+ ]
+ )
+
+ save_zip.click(
+ fn=wrap_gradio_call(save_files),
+ _js="(x, y, z, w) => [x, y, true, selected_gallery_index()]",
+ inputs=[
+ generation_info,
+ result_gallery,
html_info,
html_info,
- html_info,
+ ],
+ outputs=[
+ download_files,
+ html_log,
]
)
+
else:
html_info_x = gr.HTML()
html_info = gr.HTML()
+ html_log = gr.HTML()
+
parameters_copypaste.bind_buttons(buttons, result_gallery, "txt2img" if tabname == "txt2img" else None)
- return result_gallery, generation_info if tabname != "extras" else html_info_x, html_info
+ return result_gallery, generation_info if tabname != "extras" else html_info_x, html_info, html_log
-def create_ui(wrap_gradio_gpu_call):
+def create_sampler_and_steps_selection(choices, tabname):
+ if opts.samplers_in_dropdown:
+ with FormRow(elem_id=f"sampler_selection_{tabname}"):
+ sampler_index = gr.Dropdown(label='Sampling method', elem_id=f"{tabname}_sampling", choices=[x.name for x in choices], value=choices[0].name, type="index")
+ sampler_index.save_to_config = True
+ steps = gr.Slider(minimum=1, maximum=150, step=1, elem_id=f"{tabname}_steps", label="Sampling Steps", value=20)
+ else:
+ with FormGroup(elem_id=f"sampler_selection_{tabname}"):
+ steps = gr.Slider(minimum=1, maximum=150, step=1, elem_id=f"{tabname}_steps", label="Sampling Steps", value=20)
+ sampler_index = gr.Radio(label='Sampling method', elem_id=f"{tabname}_sampling", choices=[x.name for x in choices], value=choices[0].name, type="index")
+
+ return steps, sampler_index
+
+
+def ordered_ui_categories():
+ user_order = {x.strip(): i for i, x in enumerate(shared.opts.ui_reorder.split(","))}
+
+ for i, category in sorted(enumerate(shared.ui_reorder_categories), key=lambda x: user_order.get(x[1], x[0] + 1000)):
+ yield category
+
+
+def create_ui():
import modules.img2img
import modules.txt2img
+ reload_javascript()
+
parameters_copypaste.reset()
+ modules.scripts.scripts_current = modules.scripts.scripts_txt2img
+ modules.scripts.scripts_txt2img.initialize_scripts(is_img2img=False)
+
with gr.Blocks(analytics_enabled=False) as txt2img_interface:
- txt2img_prompt, roll, txt2img_prompt_style, txt2img_negative_prompt, txt2img_prompt_style2, submit, _, _, txt2img_prompt_style_apply, txt2img_save_style, txt2img_paste, token_counter, token_button = create_toprow(is_img2img=False)
+ txt2img_prompt, txt2img_prompt_style, txt2img_negative_prompt, txt2img_prompt_style2, submit, _, _,txt2img_prompt_style_apply, txt2img_save_style, txt2img_paste, token_counter, token_button = create_toprow(is_img2img=False)
+
dummy_component = gr.Label(visible=False)
txt_prompt_img = gr.File(label="", elem_id="txt2img_prompt_image", file_count="single", type="bytes", visible=False)
@@ -688,43 +679,58 @@ def create_ui(wrap_gradio_gpu_call):
setup_progressbar(progressbar, txt2img_preview, 'txt2img')
with gr.Row().style(equal_height=False):
- with gr.Column(variant='panel'):
- steps = gr.Slider(minimum=1, maximum=150, step=1, label="Sampling Steps", value=20)
- sampler_index = gr.Radio(label='Sampling method', elem_id="txt2img_sampling", choices=[x.name for x in samplers], value=samplers[0].name, type="index")
-
- with gr.Group():
- width = gr.Slider(minimum=64, maximum=2048, step=64, label="Width", value=512)
- height = gr.Slider(minimum=64, maximum=2048, step=64, label="Height", value=512)
-
- with gr.Row():
- restore_faces = gr.Checkbox(label='Restore faces', value=False, visible=len(shared.face_restorers) > 1)
- tiling = gr.Checkbox(label='Tiling', value=False)
- enable_hr = gr.Checkbox(label='Highres. fix', value=False)
-
- with gr.Row(visible=False) as hr_options:
- firstphase_width = gr.Slider(minimum=0, maximum=1024, step=64, label="Firstpass width", value=0)
- firstphase_height = gr.Slider(minimum=0, maximum=1024, step=64, label="Firstpass height", value=0)
- denoising_strength = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Denoising strength', value=0.7)
-
- with gr.Row(equal_height=True):
- batch_count = gr.Slider(minimum=1, step=1, label='Batch count', value=1)
- batch_size = gr.Slider(minimum=1, maximum=8, step=1, label='Batch size', value=1)
-
- cfg_scale = gr.Slider(minimum=1.0, maximum=30.0, step=0.5, label='CFG Scale', value=7.0)
-
- seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox = create_seed_inputs()
-
- with gr.Group():
- custom_inputs = modules.scripts.scripts_txt2img.setup_ui(is_img2img=False)
-
- txt2img_gallery, generation_info, html_info = create_output_panel("txt2img", opts.outdir_txt2img_samples)
+ with gr.Column(variant='panel', elem_id="txt2img_settings"):
+ for category in ordered_ui_categories():
+ if category == "sampler":
+ steps, sampler_index = create_sampler_and_steps_selection(samplers, "txt2img")
+
+ elif category == "dimensions":
+ with FormRow():
+ with gr.Column(elem_id="txt2img_column_size", scale=4):
+ width = gr.Slider(minimum=64, maximum=2048, step=8, label="Width", value=512, elem_id="txt2img_width")
+ height = gr.Slider(minimum=64, maximum=2048, step=8, label="Height", value=512, elem_id="txt2img_height")
+
+ if opts.dimensions_and_batch_together:
+ with gr.Column(elem_id="txt2img_column_batch"):
+ batch_count = gr.Slider(minimum=1, step=1, label='Batch count', value=1, elem_id="txt2img_batch_count")
+ batch_size = gr.Slider(minimum=1, maximum=8, step=1, label='Batch size', value=1, elem_id="txt2img_batch_size")
+
+ elif category == "cfg":
+ cfg_scale = gr.Slider(minimum=1.0, maximum=30.0, step=0.5, label='CFG Scale', value=7.0, elem_id="txt2img_cfg_scale")
+
+ elif category == "seed":
+ seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox = create_seed_inputs('txt2img')
+
+ elif category == "checkboxes":
+ with FormRow(elem_id="txt2img_checkboxes"):
+ restore_faces = gr.Checkbox(label='Restore faces', value=False, visible=len(shared.face_restorers) > 1, elem_id="txt2img_restore_faces")
+ tiling = gr.Checkbox(label='Tiling', value=False, elem_id="txt2img_tiling")
+ enable_hr = gr.Checkbox(label='Hires. fix', value=False, elem_id="txt2img_enable_hr")
+
+ elif category == "hires_fix":
+ with FormRow(visible=False, elem_id="txt2img_hires_fix") as hr_options:
+ hr_upscaler = gr.Dropdown(label="Upscaler", elem_id="txt2img_hr_upscaler", choices=[*shared.latent_upscale_modes, *[x.name for x in shared.sd_upscalers]], value=shared.latent_upscale_default_mode)
+ hr_scale = gr.Slider(minimum=1.0, maximum=4.0, step=0.05, label="Upscale by", value=2.0, elem_id="txt2img_hr_scale")
+ denoising_strength = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Denoising strength', value=0.7, elem_id="txt2img_denoising_strength")
+
+ elif category == "batch":
+ if not opts.dimensions_and_batch_together:
+ with FormRow(elem_id="txt2img_column_batch"):
+ batch_count = gr.Slider(minimum=1, step=1, label='Batch count', value=1, elem_id="txt2img_batch_count")
+ batch_size = gr.Slider(minimum=1, maximum=8, step=1, label='Batch size', value=1, elem_id="txt2img_batch_size")
+
+ elif category == "scripts":
+ with FormGroup(elem_id="txt2img_script_container"):
+ custom_inputs = modules.scripts.scripts_txt2img.setup_ui()
+
+ txt2img_gallery, generation_info, html_info, html_log = create_output_panel("txt2img", opts.outdir_txt2img_samples)
parameters_copypaste.bind_buttons({"txt2img": txt2img_paste}, None, txt2img_prompt)
connect_reuse_seed(seed, reuse_seed, generation_info, dummy_component, is_subseed=False)
connect_reuse_seed(subseed, reuse_subseed, generation_info, dummy_component, is_subseed=True)
txt2img_args = dict(
- fn=wrap_gradio_gpu_call(modules.txt2img.txt2img),
+ fn=wrap_gradio_gpu_call(modules.txt2img.txt2img, extra_outputs=[None, '', '']),
_js="submit",
inputs=[
txt2img_prompt,
@@ -744,14 +750,15 @@ def create_ui(wrap_gradio_gpu_call):
width,
enable_hr,
denoising_strength,
- firstphase_width,
- firstphase_height,
+ hr_scale,
+ hr_upscaler,
] + custom_inputs,
outputs=[
txt2img_gallery,
generation_info,
- html_info
+ html_info,
+ html_log,
],
show_progress=False,
)
@@ -776,17 +783,6 @@ def create_ui(wrap_gradio_gpu_call):
outputs=[hr_options],
)
- roll.click(
- fn=roll_artist,
- _js="update_txt2img_tokens",
- inputs=[
- txt2img_prompt,
- ],
- outputs=[
- txt2img_prompt,
- ]
- )
-
txt2img_paste_fields = [
(txt2img_prompt, "Prompt"),
(txt2img_negative_prompt, "Negative prompt"),
@@ -805,8 +801,8 @@ def create_ui(wrap_gradio_gpu_call):
(denoising_strength, "Denoising strength"),
(enable_hr, lambda d: "Denoising strength" in d),
(hr_options, lambda d: gr.Row.update(visible="Denoising strength" in d)),
- (firstphase_width, "First pass size-1"),
- (firstphase_height, "First pass size-2"),
+ (hr_scale, "Hires upscale"),
+ (hr_upscaler, "Hires upscaler"),
*modules.scripts.scripts_txt2img.infotext_fields
]
parameters_copypaste.add_paste_fields("txt2img", None, txt2img_paste_fields)
@@ -822,10 +818,13 @@ def create_ui(wrap_gradio_gpu_call):
height,
]
- token_button.click(fn=update_token_counter, inputs=[txt2img_prompt, steps], outputs=[token_counter])
+ token_button.click(fn=wrap_queued_call(update_token_counter), inputs=[txt2img_prompt, steps], outputs=[token_counter])
+
+ modules.scripts.scripts_current = modules.scripts.scripts_img2img
+ modules.scripts.scripts_img2img.initialize_scripts(is_img2img=True)
with gr.Blocks(analytics_enabled=False) as img2img_interface:
- img2img_prompt, roll, img2img_prompt_style, img2img_negative_prompt, img2img_prompt_style2, submit, img2img_interrogate, img2img_deepbooru, img2img_prompt_style_apply, img2img_save_style, img2img_paste, token_counter, token_button = create_toprow(is_img2img=True)
+ img2img_prompt, img2img_prompt_style, img2img_negative_prompt, img2img_prompt_style2, submit, img2img_interrogate, img2img_deepbooru, img2img_prompt_style_apply, img2img_save_style, img2img_paste,token_counter, token_button = create_toprow(is_img2img=True)
with gr.Row(elem_id='img2img_progress_row'):
img2img_prompt_img = gr.File(label="", elem_id="img2img_prompt_image", file_count="single", type="bytes", visible=False)
@@ -838,65 +837,97 @@ def create_ui(wrap_gradio_gpu_call):
img2img_preview = gr.Image(elem_id='img2img_preview', visible=False)
setup_progressbar(progressbar, img2img_preview, 'img2img')
- with gr.Row().style(equal_height=False):
- with gr.Column(variant='panel'):
+ with FormRow().style(equal_height=False):
+ with gr.Column(variant='panel', elem_id="img2img_settings"):
with gr.Tabs(elem_id="mode_img2img") as tabs_img2img_mode:
- with gr.TabItem('img2img', id='img2img'):
- init_img = gr.Image(label="Image for img2img", elem_id="img2img_image", show_label=False, source="upload", interactive=True, type="pil", tool=cmd_opts.gradio_img2img_tool).style(height=480)
+ with gr.TabItem('img2img', id='img2img', elem_id="img2img_img2img_tab"):
+ init_img = gr.Image(label="Image for img2img", elem_id="img2img_image", show_label=False, source="upload", interactive=True, type="pil", tool=cmd_opts.gradio_img2img_tool, image_mode="RGBA").style(height=480)
+
+ with gr.TabItem('Inpaint', id='inpaint', elem_id="img2img_inpaint_tab"):
+ init_img_with_mask = gr.Image(label="Image for inpainting with mask", show_label=False, elem_id="img2maskimg", source="upload", interactive=True, type="pil", tool=cmd_opts.gradio_inpaint_tool, image_mode="RGBA").style(height=480)
+ init_img_with_mask_orig = gr.State(None)
+
+ use_color_sketch = cmd_opts.gradio_inpaint_tool == "color-sketch"
+ if use_color_sketch:
+ def update_orig(image, state):
+ if image is not None:
+ same_size = state is not None and state.size == image.size
+ has_exact_match = np.any(np.all(np.array(image) == np.array(state), axis=-1))
+ edited = same_size and has_exact_match
+ return image if not edited or state is None else state
- with gr.TabItem('Inpaint', id='inpaint'):
- init_img_with_mask = gr.Image(label="Image for inpainting with mask", show_label=False, elem_id="img2maskimg", source="upload", interactive=True, type="pil", tool="sketch", image_mode="RGBA").style(height=480)
+ init_img_with_mask.change(update_orig, [init_img_with_mask, init_img_with_mask_orig], init_img_with_mask_orig)
init_img_inpaint = gr.Image(label="Image for img2img", show_label=False, source="upload", interactive=True, type="pil", visible=False, elem_id="img_inpaint_base")
init_mask_inpaint = gr.Image(label="Mask", source="upload", interactive=True, type="pil", visible=False, elem_id="img_inpaint_mask")
- mask_blur = gr.Slider(label='Mask blur', minimum=0, maximum=64, step=1, value=4)
+ with FormRow():
+ mask_blur = gr.Slider(label='Mask blur', minimum=0, maximum=64, step=1, value=4, elem_id="img2img_mask_blur")
+ mask_alpha = gr.Slider(label="Mask transparency", interactive=use_color_sketch, visible=use_color_sketch, elem_id="img2img_mask_alpha")
- with gr.Row():
- mask_mode = gr.Radio(label="Mask mode", show_label=False, choices=["Draw mask", "Upload mask"], type="index", value="Draw mask", elem_id="mask_mode")
- inpainting_mask_invert = gr.Radio(label='Masking mode', show_label=False, choices=['Inpaint masked', 'Inpaint not masked'], value='Inpaint masked', type="index")
+ with FormRow():
+ mask_mode = gr.Radio(label="Mask source", choices=["Draw mask", "Upload mask"], type="index", value="Draw mask", elem_id="mask_mode")
+ inpainting_mask_invert = gr.Radio(label='Mask mode', choices=['Inpaint masked', 'Inpaint not masked'], value='Inpaint masked', type="index", elem_id="img2img_mask_mode")
- inpainting_fill = gr.Radio(label='Masked content', choices=['fill', 'original', 'latent noise', 'latent nothing'], value='original', type="index")
+ with FormRow():
+ inpainting_fill = gr.Radio(label='Masked content', choices=['fill', 'original', 'latent noise', 'latent nothing'], value='original', type="index", elem_id="img2img_inpainting_fill")
- with gr.Row():
- inpaint_full_res = gr.Checkbox(label='Inpaint at full resolution', value=False)
- inpaint_full_res_padding = gr.Slider(label='Inpaint at full resolution padding, pixels', minimum=0, maximum=256, step=4, value=32)
+ with FormRow():
+ with gr.Column():
+ inpaint_full_res = gr.Radio(label="Inpaint area", choices=["Whole picture", "Only masked"], type="index", value="Whole picture", elem_id="img2img_inpaint_full_res")
- with gr.TabItem('Batch img2img', id='batch'):
+ with gr.Column(scale=4):
+ inpaint_full_res_padding = gr.Slider(label='Only masked padding, pixels', minimum=0, maximum=256, step=4, value=32, elem_id="img2img_inpaint_full_res_padding")
+
+ with gr.TabItem('Batch img2img', id='batch', elem_id="img2img_batch_tab"):
hidden = '<br>Disabled when launched with --hide-ui-dir-config.' if shared.cmd_opts.hide_ui_dir_config else ''
gr.HTML(f"<p class=\"text-gray-500\">Process images in a directory on the same machine where the server is running.<br>Use an empty output directory to save pictures normally instead of writing to the output directory.{hidden}</p>")
- img2img_batch_input_dir = gr.Textbox(label="Input directory", **shared.hide_dirs)
- img2img_batch_output_dir = gr.Textbox(label="Output directory", **shared.hide_dirs)
-
- with gr.Row():
- resize_mode = gr.Radio(label="Resize mode", elem_id="resize_mode", show_label=False, choices=["Just resize", "Crop and resize", "Resize and fill"], type="index", value="Just resize")
-
- steps = gr.Slider(minimum=1, maximum=150, step=1, label="Sampling Steps", value=20)
- sampler_index = gr.Radio(label='Sampling method', choices=[x.name for x in samplers_for_img2img], value=samplers_for_img2img[0].name, type="index")
-
- with gr.Group():
- width = gr.Slider(minimum=64, maximum=2048, step=64, label="Width", value=512, elem_id="img2img_width")
- height = gr.Slider(minimum=64, maximum=2048, step=64, label="Height", value=512, elem_id="img2img_height")
-
- with gr.Row():
- restore_faces = gr.Checkbox(label='Restore faces', value=False, visible=len(shared.face_restorers) > 1)
- tiling = gr.Checkbox(label='Tiling', value=False)
-
- with gr.Row():
- batch_count = gr.Slider(minimum=1, step=1, label='Batch count', value=1)
- batch_size = gr.Slider(minimum=1, maximum=8, step=1, label='Batch size', value=1)
-
- with gr.Group():
- cfg_scale = gr.Slider(minimum=1.0, maximum=30.0, step=0.5, label='CFG Scale', value=7.0)
- denoising_strength = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Denoising strength', value=0.75)
-
- seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox = create_seed_inputs()
-
- with gr.Group():
- custom_inputs = modules.scripts.scripts_img2img.setup_ui(is_img2img=True)
-
- img2img_gallery, generation_info, html_info = create_output_panel("img2img", opts.outdir_img2img_samples)
+ img2img_batch_input_dir = gr.Textbox(label="Input directory", **shared.hide_dirs, elem_id="img2img_batch_input_dir")
+ img2img_batch_output_dir = gr.Textbox(label="Output directory", **shared.hide_dirs, elem_id="img2img_batch_output_dir")
+
+ with FormRow():
+ resize_mode = gr.Radio(label="Resize mode", elem_id="resize_mode", choices=["Just resize", "Crop and resize", "Resize and fill", "Just resize (latent upscale)"], type="index", value="Just resize")
+
+ for category in ordered_ui_categories():
+ if category == "sampler":
+ steps, sampler_index = create_sampler_and_steps_selection(samplers_for_img2img, "img2img")
+
+ elif category == "dimensions":
+ with FormRow():
+ with gr.Column(elem_id="img2img_column_size", scale=4):
+ width = gr.Slider(minimum=64, maximum=2048, step=8, label="Width", value=512, elem_id="img2img_width")
+ height = gr.Slider(minimum=64, maximum=2048, step=8, label="Height", value=512, elem_id="img2img_height")
+
+ if opts.dimensions_and_batch_together:
+ with gr.Column(elem_id="img2img_column_batch"):
+ batch_count = gr.Slider(minimum=1, step=1, label='Batch count', value=1, elem_id="img2img_batch_count")
+ batch_size = gr.Slider(minimum=1, maximum=8, step=1, label='Batch size', value=1, elem_id="img2img_batch_size")
+
+ elif category == "cfg":
+ with FormGroup():
+ cfg_scale = gr.Slider(minimum=1.0, maximum=30.0, step=0.5, label='CFG Scale', value=7.0, elem_id="img2img_cfg_scale")
+ denoising_strength = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Denoising strength', value=0.75, elem_id="img2img_denoising_strength")
+
+ elif category == "seed":
+ seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox = create_seed_inputs('img2img')
+
+ elif category == "checkboxes":
+ with FormRow(elem_id="img2img_checkboxes"):
+ restore_faces = gr.Checkbox(label='Restore faces', value=False, visible=len(shared.face_restorers) > 1, elem_id="img2img_restore_faces")
+ tiling = gr.Checkbox(label='Tiling', value=False, elem_id="img2img_tiling")
+
+ elif category == "batch":
+ if not opts.dimensions_and_batch_together:
+ with FormRow(elem_id="img2img_column_batch"):
+ batch_count = gr.Slider(minimum=1, step=1, label='Batch count', value=1, elem_id="img2img_batch_count")
+ batch_size = gr.Slider(minimum=1, maximum=8, step=1, label='Batch size', value=1, elem_id="img2img_batch_size")
+
+ elif category == "scripts":
+ with FormGroup(elem_id="img2img_script_container"):
+ custom_inputs = modules.scripts.scripts_img2img.setup_ui()
+
+ img2img_gallery, generation_info, html_info, html_log = create_output_panel("img2img", opts.outdir_img2img_samples)
parameters_copypaste.bind_buttons({"img2img": img2img_paste}, None, img2img_prompt)
connect_reuse_seed(seed, reuse_seed, generation_info, dummy_component, is_subseed=False)
@@ -928,7 +959,7 @@ def create_ui(wrap_gradio_gpu_call):
)
img2img_args = dict(
- fn=wrap_gradio_gpu_call(modules.img2img.img2img),
+ fn=wrap_gradio_gpu_call(modules.img2img.img2img, extra_outputs=[None, '', '']),
_js="submit_img2img",
inputs=[
dummy_component,
@@ -938,12 +969,14 @@ def create_ui(wrap_gradio_gpu_call):
img2img_prompt_style2,
init_img,
init_img_with_mask,
+ init_img_with_mask_orig,
init_img_inpaint,
init_mask_inpaint,
mask_mode,
steps,
sampler_index,
mask_blur,
+ mask_alpha,
inpainting_fill,
restore_faces,
tiling,
@@ -965,7 +998,8 @@ def create_ui(wrap_gradio_gpu_call):
outputs=[
img2img_gallery,
generation_info,
- html_info
+ html_info,
+ html_log,
],
show_progress=False,
)
@@ -979,23 +1013,10 @@ def create_ui(wrap_gradio_gpu_call):
outputs=[img2img_prompt],
)
- if cmd_opts.deepdanbooru:
- img2img_deepbooru.click(
- fn=interrogate_deepbooru,
- inputs=[init_img],
- outputs=[img2img_prompt],
- )
-
-
- roll.click(
- fn=roll_artist,
- _js="update_img2img_tokens",
- inputs=[
- img2img_prompt,
- ],
- outputs=[
- img2img_prompt,
- ]
+ img2img_deepbooru.click(
+ fn=interrogate_deepbooru,
+ inputs=[init_img],
+ outputs=[img2img_prompt],
)
prompts = [(txt2img_prompt, txt2img_negative_prompt), (img2img_prompt, img2img_negative_prompt)]
@@ -1038,59 +1059,62 @@ def create_ui(wrap_gradio_gpu_call):
(seed_resize_from_w, "Seed resize from-1"),
(seed_resize_from_h, "Seed resize from-2"),
(denoising_strength, "Denoising strength"),
+ (mask_blur, "Mask blur"),
*modules.scripts.scripts_img2img.infotext_fields
]
parameters_copypaste.add_paste_fields("img2img", init_img, img2img_paste_fields)
parameters_copypaste.add_paste_fields("inpaint", init_img_with_mask, img2img_paste_fields)
+ modules.scripts.scripts_current = None
+
with gr.Blocks(analytics_enabled=False) as extras_interface:
with gr.Row().style(equal_height=False):
with gr.Column(variant='panel'):
with gr.Tabs(elem_id="mode_extras"):
- with gr.TabItem('Single Image'):
- extras_image = gr.Image(label="Source", source="upload", interactive=True, type="pil")
+ with gr.TabItem('Single Image', elem_id="extras_single_tab"):
+ extras_image = gr.Image(label="Source", source="upload", interactive=True, type="pil", elem_id="extras_image")
- with gr.TabItem('Batch Process'):
- image_batch = gr.File(label="Batch Process", file_count="multiple", interactive=True, type="file")
+ with gr.TabItem('Batch Process', elem_id="extras_batch_process_tab"):
+ image_batch = gr.File(label="Batch Process", file_count="multiple", interactive=True, type="file", elem_id="extras_image_batch")
- with gr.TabItem('Batch from Directory'):
- extras_batch_input_dir = gr.Textbox(label="Input directory", **shared.hide_dirs, placeholder="A directory on the same machine where the server is running.")
- extras_batch_output_dir = gr.Textbox(label="Output directory", **shared.hide_dirs, placeholder="Leave blank to save images to the default path.")
- show_extras_results = gr.Checkbox(label='Show result images', value=True)
+ with gr.TabItem('Batch from Directory', elem_id="extras_batch_directory_tab"):
+ extras_batch_input_dir = gr.Textbox(label="Input directory", **shared.hide_dirs, placeholder="A directory on the same machine where the server is running.", elem_id="extras_batch_input_dir")
+ extras_batch_output_dir = gr.Textbox(label="Output directory", **shared.hide_dirs, placeholder="Leave blank to save images to the default path.", elem_id="extras_batch_output_dir")
+ show_extras_results = gr.Checkbox(label='Show result images', value=True, elem_id="extras_show_extras_results")
+
+ submit = gr.Button('Generate', elem_id="extras_generate", variant='primary')
with gr.Tabs(elem_id="extras_resize_mode"):
- with gr.TabItem('Scale by'):
- upscaling_resize = gr.Slider(minimum=1.0, maximum=4.0, step=0.05, label="Resize", value=2)
- with gr.TabItem('Scale to'):
+ with gr.TabItem('Scale by', elem_id="extras_scale_by_tab"):
+ upscaling_resize = gr.Slider(minimum=1.0, maximum=8.0, step=0.05, label="Resize", value=4, elem_id="extras_upscaling_resize")
+ with gr.TabItem('Scale to', elem_id="extras_scale_to_tab"):
with gr.Group():
with gr.Row():
- upscaling_resize_w = gr.Number(label="Width", value=512, precision=0)
- upscaling_resize_h = gr.Number(label="Height", value=512, precision=0)
- upscaling_crop = gr.Checkbox(label='Crop to fit', value=True)
+ upscaling_resize_w = gr.Number(label="Width", value=512, precision=0, elem_id="extras_upscaling_resize_w")
+ upscaling_resize_h = gr.Number(label="Height", value=512, precision=0, elem_id="extras_upscaling_resize_h")
+ upscaling_crop = gr.Checkbox(label='Crop to fit', value=True, elem_id="extras_upscaling_crop")
with gr.Group():
extras_upscaler_1 = gr.Radio(label='Upscaler 1', elem_id="extras_upscaler_1", choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name, type="index")
with gr.Group():
extras_upscaler_2 = gr.Radio(label='Upscaler 2', elem_id="extras_upscaler_2", choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name, type="index")
- extras_upscaler_2_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.001, label="Upscaler 2 visibility", value=1)
+ extras_upscaler_2_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.001, label="Upscaler 2 visibility", value=1, elem_id="extras_upscaler_2_visibility")
with gr.Group():
- gfpgan_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.001, label="GFPGAN visibility", value=0, interactive=modules.gfpgan_model.have_gfpgan)
+ gfpgan_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.001, label="GFPGAN visibility", value=0, interactive=modules.gfpgan_model.have_gfpgan, elem_id="extras_gfpgan_visibility")
with gr.Group():
- codeformer_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.001, label="CodeFormer visibility", value=0, interactive=modules.codeformer_model.have_codeformer)
- codeformer_weight = gr.Slider(minimum=0.0, maximum=1.0, step=0.001, label="CodeFormer weight (0 = maximum effect, 1 = minimum effect)", value=0, interactive=modules.codeformer_model.have_codeformer)
+ codeformer_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.001, label="CodeFormer visibility", value=0, interactive=modules.codeformer_model.have_codeformer, elem_id="extras_codeformer_visibility")
+ codeformer_weight = gr.Slider(minimum=0.0, maximum=1.0, step=0.001, label="CodeFormer weight (0 = maximum effect, 1 = minimum effect)", value=0, interactive=modules.codeformer_model.have_codeformer, elem_id="extras_codeformer_weight")
with gr.Group():
- upscale_before_face_fix = gr.Checkbox(label='Upscale Before Restoring Faces', value=False)
+ upscale_before_face_fix = gr.Checkbox(label='Upscale Before Restoring Faces', value=False, elem_id="extras_upscale_before_face_fix")
- submit = gr.Button('Generate', elem_id="extras_generate", variant='primary')
-
- result_images, html_info_x, html_info = create_output_panel("extras", opts.outdir_extras_samples)
+ result_images, html_info_x, html_info, html_log = create_output_panel("extras", opts.outdir_extras_samples)
submit.click(
- fn=wrap_gradio_gpu_call(modules.extras.run_extras),
+ fn=wrap_gradio_gpu_call(modules.extras.run_extras, extra_outputs=[None, '']),
_js="get_extras_tab_index",
inputs=[
dummy_component,
@@ -1132,7 +1156,7 @@ def create_ui(wrap_gradio_gpu_call):
with gr.Column(variant='panel'):
html = gr.HTML()
- generation_info = gr.Textbox(visible=False)
+ generation_info = gr.Textbox(visible=False, elem_id="pnginfo_generation_info")
html2 = gr.HTML()
with gr.Row():
buttons = parameters_copypaste.create_buttons(["txt2img", "img2img", "inpaint", "extras"])
@@ -1144,27 +1168,35 @@ def create_ui(wrap_gradio_gpu_call):
outputs=[html, generation_info, html2],
)
- with gr.Blocks() as modelmerger_interface:
+ with gr.Blocks(analytics_enabled=False) as modelmerger_interface:
with gr.Row().style(equal_height=False):
with gr.Column(variant='panel'):
gr.HTML(value="<p>A merger of the two checkpoints will be generated in your <b>checkpoint</b> directory.</p>")
with gr.Row():
primary_model_name = gr.Dropdown(modules.sd_models.checkpoint_tiles(), elem_id="modelmerger_primary_model_name", label="Primary model (A)")
+ create_refresh_button(primary_model_name, modules.sd_models.list_models, lambda: {"choices": modules.sd_models.checkpoint_tiles()}, "refresh_checkpoint_A")
+
secondary_model_name = gr.Dropdown(modules.sd_models.checkpoint_tiles(), elem_id="modelmerger_secondary_model_name", label="Secondary model (B)")
+ create_refresh_button(secondary_model_name, modules.sd_models.list_models, lambda: {"choices": modules.sd_models.checkpoint_tiles()}, "refresh_checkpoint_B")
+
tertiary_model_name = gr.Dropdown(modules.sd_models.checkpoint_tiles(), elem_id="modelmerger_tertiary_model_name", label="Tertiary model (C)")
- custom_name = gr.Textbox(label="Custom Name (Optional)")
- interp_amount = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Multiplier (M) - set to 0 to get model A', value=0.3)
- interp_method = gr.Radio(choices=["Weighted sum", "Add difference"], value="Weighted sum", label="Interpolation Method")
- save_as_half = gr.Checkbox(value=False, label="Save as float16")
+ create_refresh_button(tertiary_model_name, modules.sd_models.list_models, lambda: {"choices": modules.sd_models.checkpoint_tiles()}, "refresh_checkpoint_C")
+
+ custom_name = gr.Textbox(label="Custom Name (Optional)", elem_id="modelmerger_custom_name")
+ interp_amount = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Multiplier (M) - set to 0 to get model A', value=0.3, elem_id="modelmerger_interp_amount")
+ interp_method = gr.Radio(choices=["Weighted sum", "Add difference"], value="Weighted sum", label="Interpolation Method", elem_id="modelmerger_interp_method")
+
+ with gr.Row():
+ checkpoint_format = gr.Radio(choices=["ckpt", "safetensors"], value="ckpt", label="Checkpoint format", elem_id="modelmerger_checkpoint_format")
+ save_as_half = gr.Checkbox(value=False, label="Save as float16", elem_id="modelmerger_save_as_half")
+
modelmerger_merge = gr.Button(elem_id="modelmerger_merge", label="Merge", variant='primary')
with gr.Column(variant='panel'):
submit_result = gr.Textbox(elem_id="modelmerger_result", show_label=False)
- sd_hijack.model_hijack.embedding_db.load_textual_inversion_embeddings()
-
- with gr.Blocks() as train_interface:
+ with gr.Blocks(analytics_enabled=False) as train_interface:
with gr.Row().style(equal_height=False):
gr.HTML(value="<p style='margin-bottom: 0.7em'>See <b><a href=\"https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Textual-Inversion\">wiki</a></b> for detailed explanation.</p>")
@@ -1172,65 +1204,67 @@ def create_ui(wrap_gradio_gpu_call):
with gr.Tabs(elem_id="train_tabs"):
with gr.Tab(label="Create embedding"):
- new_embedding_name = gr.Textbox(label="Name")
- initialization_text = gr.Textbox(label="Initialization text", value="*")
- nvpt = gr.Slider(label="Number of vectors per token", minimum=1, maximum=75, step=1, value=1)
- overwrite_old_embedding = gr.Checkbox(value=False, label="Overwrite Old Embedding")
+ new_embedding_name = gr.Textbox(label="Name", elem_id="train_new_embedding_name")
+ initialization_text = gr.Textbox(label="Initialization text", value="*", elem_id="train_initialization_text")
+ nvpt = gr.Slider(label="Number of vectors per token", minimum=1, maximum=75, step=1, value=1, elem_id="train_nvpt")
+ overwrite_old_embedding = gr.Checkbox(value=False, label="Overwrite Old Embedding", elem_id="train_overwrite_old_embedding")
with gr.Row():
with gr.Column(scale=3):
gr.HTML(value="")
with gr.Column():
- create_embedding = gr.Button(value="Create embedding", variant='primary')
+ create_embedding = gr.Button(value="Create embedding", variant='primary', elem_id="train_create_embedding")
with gr.Tab(label="Create hypernetwork"):
- new_hypernetwork_name = gr.Textbox(label="Name")
- new_hypernetwork_sizes = gr.CheckboxGroup(label="Modules", value=["768", "320", "640", "1280"], choices=["768", "320", "640", "1280"])
- new_hypernetwork_layer_structure = gr.Textbox("1, 2, 1", label="Enter hypernetwork layer structure", placeholder="1st and last digit must be 1. ex:'1, 2, 1'")
- new_hypernetwork_activation_func = gr.Dropdown(value="linear", label="Select activation function of hypernetwork", choices=modules.hypernetworks.ui.keys)
- new_hypernetwork_initialization_option = gr.Dropdown(value = "Normal", label="Select Layer weights initialization. relu-like - Kaiming, sigmoid-like - Xavier is recommended", choices=["Normal", "KaimingUniform", "KaimingNormal", "XavierUniform", "XavierNormal"])
- new_hypernetwork_add_layer_norm = gr.Checkbox(label="Add layer normalization")
- new_hypernetwork_use_dropout = gr.Checkbox(label="Use dropout")
- overwrite_old_hypernetwork = gr.Checkbox(value=False, label="Overwrite Old Hypernetwork")
+ new_hypernetwork_name = gr.Textbox(label="Name", elem_id="train_new_hypernetwork_name")
+ new_hypernetwork_sizes = gr.CheckboxGroup(label="Modules", value=["768", "320", "640", "1280"], choices=["768", "1024", "320", "640", "1280"], elem_id="train_new_hypernetwork_sizes")
+ new_hypernetwork_layer_structure = gr.Textbox("1, 2, 1", label="Enter hypernetwork layer structure", placeholder="1st and last digit must be 1. ex:'1, 2, 1'", elem_id="train_new_hypernetwork_layer_structure")
+ new_hypernetwork_activation_func = gr.Dropdown(value="linear", label="Select activation function of hypernetwork. Recommended : Swish / Linear(none)", choices=modules.hypernetworks.ui.keys, elem_id="train_new_hypernetwork_activation_func")
+ new_hypernetwork_initialization_option = gr.Dropdown(value = "Normal", label="Select Layer weights initialization. Recommended: Kaiming for relu-like, Xavier for sigmoid-like, Normal otherwise", choices=["Normal", "KaimingUniform", "KaimingNormal", "XavierUniform", "XavierNormal"], elem_id="train_new_hypernetwork_initialization_option")
+ new_hypernetwork_add_layer_norm = gr.Checkbox(label="Add layer normalization", elem_id="train_new_hypernetwork_add_layer_norm")
+ new_hypernetwork_use_dropout = gr.Checkbox(label="Use dropout", elem_id="train_new_hypernetwork_use_dropout")
+ overwrite_old_hypernetwork = gr.Checkbox(value=False, label="Overwrite Old Hypernetwork", elem_id="train_overwrite_old_hypernetwork")
with gr.Row():
with gr.Column(scale=3):
gr.HTML(value="")
with gr.Column():
- create_hypernetwork = gr.Button(value="Create hypernetwork", variant='primary')
+ create_hypernetwork = gr.Button(value="Create hypernetwork", variant='primary', elem_id="train_create_hypernetwork")
with gr.Tab(label="Preprocess images"):
- process_src = gr.Textbox(label='Source directory')
- process_dst = gr.Textbox(label='Destination directory')
- process_width = gr.Slider(minimum=64, maximum=2048, step=64, label="Width", value=512)
- process_height = gr.Slider(minimum=64, maximum=2048, step=64, label="Height", value=512)
- preprocess_txt_action = gr.Dropdown(label='Existing Caption txt Action', value="ignore", choices=["ignore", "copy", "prepend", "append"])
+ process_src = gr.Textbox(label='Source directory', elem_id="train_process_src")
+ process_dst = gr.Textbox(label='Destination directory', elem_id="train_process_dst")
+ process_width = gr.Slider(minimum=64, maximum=2048, step=8, label="Width", value=512, elem_id="train_process_width")
+ process_height = gr.Slider(minimum=64, maximum=2048, step=8, label="Height", value=512, elem_id="train_process_height")
+ preprocess_txt_action = gr.Dropdown(label='Existing Caption txt Action', value="ignore", choices=["ignore", "copy", "prepend", "append"], elem_id="train_preprocess_txt_action")
with gr.Row():
- process_flip = gr.Checkbox(label='Create flipped copies')
- process_split = gr.Checkbox(label='Split oversized images')
- process_focal_crop = gr.Checkbox(label='Auto focal point crop')
- process_caption = gr.Checkbox(label='Use BLIP for caption')
- process_caption_deepbooru = gr.Checkbox(label='Use deepbooru for caption', visible=True if cmd_opts.deepdanbooru else False)
+ process_flip = gr.Checkbox(label='Create flipped copies', elem_id="train_process_flip")
+ process_split = gr.Checkbox(label='Split oversized images', elem_id="train_process_split")
+ process_focal_crop = gr.Checkbox(label='Auto focal point crop', elem_id="train_process_focal_crop")
+ process_caption = gr.Checkbox(label='Use BLIP for caption', elem_id="train_process_caption")
+ process_caption_deepbooru = gr.Checkbox(label='Use deepbooru for caption', visible=True, elem_id="train_process_caption_deepbooru")
with gr.Row(visible=False) as process_split_extra_row:
- process_split_threshold = gr.Slider(label='Split image threshold', value=0.5, minimum=0.0, maximum=1.0, step=0.05)
- process_overlap_ratio = gr.Slider(label='Split image overlap ratio', value=0.2, minimum=0.0, maximum=0.9, step=0.05)
+ process_split_threshold = gr.Slider(label='Split image threshold', value=0.5, minimum=0.0, maximum=1.0, step=0.05, elem_id="train_process_split_threshold")
+ process_overlap_ratio = gr.Slider(label='Split image overlap ratio', value=0.2, minimum=0.0, maximum=0.9, step=0.05, elem_id="train_process_overlap_ratio")
with gr.Row(visible=False) as process_focal_crop_row:
- process_focal_crop_face_weight = gr.Slider(label='Focal point face weight', value=0.9, minimum=0.0, maximum=1.0, step=0.05)
- process_focal_crop_entropy_weight = gr.Slider(label='Focal point entropy weight', value=0.15, minimum=0.0, maximum=1.0, step=0.05)
- process_focal_crop_edges_weight = gr.Slider(label='Focal point edges weight', value=0.5, minimum=0.0, maximum=1.0, step=0.05)
- process_focal_crop_debug = gr.Checkbox(label='Create debug image')
+ process_focal_crop_face_weight = gr.Slider(label='Focal point face weight', value=0.9, minimum=0.0, maximum=1.0, step=0.05, elem_id="train_process_focal_crop_face_weight")
+ process_focal_crop_entropy_weight = gr.Slider(label='Focal point entropy weight', value=0.15, minimum=0.0, maximum=1.0, step=0.05, elem_id="train_process_focal_crop_entropy_weight")
+ process_focal_crop_edges_weight = gr.Slider(label='Focal point edges weight', value=0.5, minimum=0.0, maximum=1.0, step=0.05, elem_id="train_process_focal_crop_edges_weight")
+ process_focal_crop_debug = gr.Checkbox(label='Create debug image', elem_id="train_process_focal_crop_debug")
with gr.Row():
with gr.Column(scale=3):
gr.HTML(value="")
with gr.Column():
- run_preprocess = gr.Button(value="Preprocess", variant='primary')
+ with gr.Row():
+ interrupt_preprocessing = gr.Button("Interrupt", elem_id="train_interrupt_preprocessing")
+ run_preprocess = gr.Button(value="Preprocess", variant='primary', elem_id="train_run_preprocess")
process_split.change(
fn=lambda show: gr_show(show),
@@ -1253,25 +1287,35 @@ def create_ui(wrap_gradio_gpu_call):
train_hypernetwork_name = gr.Dropdown(label='Hypernetwork', elem_id="train_hypernetwork", choices=[x for x in shared.hypernetworks.keys()])
create_refresh_button(train_hypernetwork_name, shared.reload_hypernetworks, lambda: {"choices": sorted([x for x in shared.hypernetworks.keys()])}, "refresh_train_hypernetwork_name")
with gr.Row():
- embedding_learn_rate = gr.Textbox(label='Embedding Learning rate', placeholder="Embedding Learning rate", value="0.005")
- hypernetwork_learn_rate = gr.Textbox(label='Hypernetwork Learning rate', placeholder="Hypernetwork Learning rate", value="0.00001")
-
- batch_size = gr.Number(label='Batch size', value=1, precision=0)
- dataset_directory = gr.Textbox(label='Dataset directory', placeholder="Path to directory with input images")
- log_directory = gr.Textbox(label='Log directory', placeholder="Path to directory where to write outputs", value="textual_inversion")
- template_file = gr.Textbox(label='Prompt template file', value=os.path.join(script_path, "textual_inversion_templates", "style_filewords.txt"))
- training_width = gr.Slider(minimum=64, maximum=2048, step=64, label="Width", value=512)
- training_height = gr.Slider(minimum=64, maximum=2048, step=64, label="Height", value=512)
- steps = gr.Number(label='Max steps', value=100000, precision=0)
- create_image_every = gr.Number(label='Save an image to log directory every N steps, 0 to disable', value=500, precision=0)
- save_embedding_every = gr.Number(label='Save a copy of embedding to log directory every N steps, 0 to disable', value=500, precision=0)
- save_image_with_stored_embedding = gr.Checkbox(label='Save images with embedding in PNG chunks', value=True)
- preview_from_txt2img = gr.Checkbox(label='Read parameters (prompt, etc...) from txt2img tab when making previews', value=False)
+ embedding_learn_rate = gr.Textbox(label='Embedding Learning rate', placeholder="Embedding Learning rate", value="0.005", elem_id="train_embedding_learn_rate")
+ hypernetwork_learn_rate = gr.Textbox(label='Hypernetwork Learning rate', placeholder="Hypernetwork Learning rate", value="0.00001", elem_id="train_hypernetwork_learn_rate")
+
+ batch_size = gr.Number(label='Batch size', value=1, precision=0, elem_id="train_batch_size")
+ gradient_step = gr.Number(label='Gradient accumulation steps', value=1, precision=0, elem_id="train_gradient_step")
+ dataset_directory = gr.Textbox(label='Dataset directory', placeholder="Path to directory with input images", elem_id="train_dataset_directory")
+ log_directory = gr.Textbox(label='Log directory', placeholder="Path to directory where to write outputs", value="textual_inversion", elem_id="train_log_directory")
+ template_file = gr.Textbox(label='Prompt template file', value=os.path.join(script_path, "textual_inversion_templates", "style_filewords.txt"), elem_id="train_template_file")
+ training_width = gr.Slider(minimum=64, maximum=2048, step=8, label="Width", value=512, elem_id="train_training_width")
+ training_height = gr.Slider(minimum=64, maximum=2048, step=8, label="Height", value=512, elem_id="train_training_height")
+ steps = gr.Number(label='Max steps', value=100000, precision=0, elem_id="train_steps")
+ create_image_every = gr.Number(label='Save an image to log directory every N steps, 0 to disable', value=500, precision=0, elem_id="train_create_image_every")
+ save_embedding_every = gr.Number(label='Save a copy of embedding to log directory every N steps, 0 to disable', value=500, precision=0, elem_id="train_save_embedding_every")
+ save_image_with_stored_embedding = gr.Checkbox(label='Save images with embedding in PNG chunks', value=True, elem_id="train_save_image_with_stored_embedding")
+ preview_from_txt2img = gr.Checkbox(label='Read parameters (prompt, etc...) from txt2img tab when making previews', value=False, elem_id="train_preview_from_txt2img")
+ with gr.Row():
+ shuffle_tags = gr.Checkbox(label="Shuffle tags by ',' when creating prompts.", value=False, elem_id="train_shuffle_tags")
+ tag_drop_out = gr.Slider(minimum=0, maximum=1, step=0.1, label="Drop out tags when creating prompts.", value=0, elem_id="train_tag_drop_out")
+ with gr.Row():
+ latent_sampling_method = gr.Radio(label='Choose latent sampling method', value="once", choices=['once', 'deterministic', 'random'], elem_id="train_latent_sampling_method")
with gr.Row():
- interrupt_training = gr.Button(value="Interrupt")
- train_hypernetwork = gr.Button(value="Train Hypernetwork", variant='primary')
- train_embedding = gr.Button(value="Train Embedding", variant='primary')
+ interrupt_training = gr.Button(value="Interrupt", elem_id="train_interrupt_training")
+ train_hypernetwork = gr.Button(value="Train Hypernetwork", variant='primary', elem_id="train_train_hypernetwork")
+ train_embedding = gr.Button(value="Train Embedding", variant='primary', elem_id="train_train_embedding")
+
+ params = script_callbacks.UiTrainTabParams(txt2img_preview_params)
+
+ script_callbacks.ui_train_tabs_callback(params)
with gr.Column():
progressbar = gr.HTML(elem_id="ti_progressbar")
@@ -1351,11 +1395,15 @@ def create_ui(wrap_gradio_gpu_call):
train_embedding_name,
embedding_learn_rate,
batch_size,
+ gradient_step,
dataset_directory,
log_directory,
training_width,
training_height,
steps,
+ shuffle_tags,
+ tag_drop_out,
+ latent_sampling_method,
create_image_every,
save_embedding_every,
template_file,
@@ -1376,11 +1424,15 @@ def create_ui(wrap_gradio_gpu_call):
train_hypernetwork_name,
hypernetwork_learn_rate,
batch_size,
+ gradient_step,
dataset_directory,
log_directory,
training_width,
training_height,
steps,
+ shuffle_tags,
+ tag_drop_out,
+ latent_sampling_method,
create_image_every,
save_embedding_every,
template_file,
@@ -1399,6 +1451,12 @@ def create_ui(wrap_gradio_gpu_call):
outputs=[],
)
+ interrupt_preprocessing.click(
+ fn=lambda: shared.state.interrupt(),
+ inputs=[],
+ outputs=[],
+ )
+
def create_setting_component(key, is_quicksettings=False):
def fun():
return opts.data[key] if key in opts.data else opts.data_labels[key].default
@@ -1423,15 +1481,14 @@ def create_ui(wrap_gradio_gpu_call):
if info.refresh is not None:
if is_quicksettings:
- res = comp(label=info.label, value=fun, elem_id=elem_id, **(args or {}))
+ res = comp(label=info.label, value=fun(), elem_id=elem_id, **(args or {}))
create_refresh_button(res, info.refresh, info.component_args, "refresh_" + key)
else:
- with gr.Row(variant="compact"):
- res = comp(label=info.label, value=fun, elem_id=elem_id, **(args or {}))
+ with FormRow():
+ res = comp(label=info.label, value=fun(), elem_id=elem_id, **(args or {}))
create_refresh_button(res, info.refresh, info.component_args, "refresh_" + key)
else:
- res = comp(label=info.label, value=fun, elem_id=elem_id, **(args or {}))
-
+ res = comp(label=info.label, value=fun(), elem_id=elem_id, **(args or {}))
return res
@@ -1442,94 +1499,66 @@ def create_ui(wrap_gradio_gpu_call):
opts.reorder()
def run_settings(*args):
- changed = 0
-
- assert not shared.cmd_opts.freeze_settings, "changing settings is disabled"
+ changed = []
for key, value, comp in zip(opts.data_labels.keys(), args, components):
- if comp != dummy_component and not opts.same_type(value, opts.data_labels[key].default):
- return f"Bad value for setting {key}: {value}; expecting {type(opts.data_labels[key].default).__name__}", opts.dumpjson()
+ assert comp == dummy_component or opts.same_type(value, opts.data_labels[key].default), f"Bad value for setting {key}: {value}; expecting {type(opts.data_labels[key].default).__name__}"
for key, value, comp in zip(opts.data_labels.keys(), args, components):
if comp == dummy_component:
continue
- comp_args = opts.data_labels[key].component_args
- if comp_args and isinstance(comp_args, dict) and comp_args.get('visible') is False:
- continue
-
- if cmd_opts.hide_ui_dir_config and key in restricted_opts:
- continue
-
- oldval = opts.data.get(key, None)
- opts.data[key] = value
-
- if oldval != value:
- if opts.data_labels[key].onchange is not None:
- opts.data_labels[key].onchange()
+ if opts.set(key, value):
+ changed.append(key)
- changed += 1
-
- opts.save(shared.config_filename)
-
- return f'{changed} settings changed.', opts.dumpjson()
+ try:
+ opts.save(shared.config_filename)
+ except RuntimeError:
+ return opts.dumpjson(), f'{len(changed)} settings changed without save: {", ".join(changed)}.'
+ return opts.dumpjson(), f'{len(changed)} settings changed{": " if len(changed) > 0 else ""}{", ".join(changed)}.'
def run_settings_single(value, key):
- assert not shared.cmd_opts.freeze_settings, "changing settings is disabled"
-
if not opts.same_type(value, opts.data_labels[key].default):
return gr.update(visible=True), opts.dumpjson()
- oldval = opts.data.get(key, None)
- if cmd_opts.hide_ui_dir_config and key in restricted_opts:
- return gr.update(value=oldval), opts.dumpjson()
-
- opts.data[key] = value
-
- if oldval != value:
- if opts.data_labels[key].onchange is not None:
- opts.data_labels[key].onchange()
+ if not opts.set(key, value):
+ return gr.update(value=getattr(opts, key)), opts.dumpjson()
opts.save(shared.config_filename)
return gr.update(value=value), opts.dumpjson()
with gr.Blocks(analytics_enabled=False) as settings_interface:
- settings_submit = gr.Button(value="Apply settings", variant='primary')
- result = gr.HTML()
+ with gr.Row():
+ with gr.Column(scale=6):
+ settings_submit = gr.Button(value="Apply settings", variant='primary', elem_id="settings_submit")
+ with gr.Column():
+ restart_gradio = gr.Button(value='Reload UI', variant='primary', elem_id="settings_restart_gradio")
- settings_cols = 3
- items_per_col = int(len(opts.data_labels) * 0.9 / settings_cols)
+ result = gr.HTML(elem_id="settings_result")
quicksettings_names = [x.strip() for x in opts.quicksettings.split(",")]
- quicksettings_names = set(x for x in quicksettings_names if x != 'quicksettings')
+ quicksettings_names = {x: i for i, x in enumerate(quicksettings_names) if x != 'quicksettings'}
quicksettings_list = []
- cols_displayed = 0
- items_displayed = 0
previous_section = None
- column = None
- with gr.Row(elem_id="settings").style(equal_height=False):
+ current_tab = None
+ with gr.Tabs(elem_id="settings"):
for i, (k, item) in enumerate(opts.data_labels.items()):
section_must_be_skipped = item.section[0] is None
if previous_section != item.section and not section_must_be_skipped:
- if cols_displayed < settings_cols and (items_displayed >= items_per_col or previous_section is None):
- if column is not None:
- column.__exit__()
+ elem_id, text = item.section
- column = gr.Column(variant='panel')
- column.__enter__()
+ if current_tab is not None:
+ current_tab.__exit__()
- items_displayed = 0
- cols_displayed += 1
+ current_tab = gr.TabItem(elem_id="settings_{}".format(elem_id), label=text)
+ current_tab.__enter__()
previous_section = item.section
- elem_id, text = item.section
- gr.HTML(elem_id="settings_header_text_{}".format(elem_id), value='<h1 class="gr-button-lg">{}</h1>'.format(text))
-
if k in quicksettings_names and not shared.cmd_opts.freeze_settings:
quicksettings_list.append((i, k, item))
components.append(dummy_component)
@@ -1539,15 +1568,21 @@ def create_ui(wrap_gradio_gpu_call):
component = create_setting_component(k)
component_dict[k] = component
components.append(component)
- items_displayed += 1
- with gr.Row():
- request_notifications = gr.Button(value='Request browser notifications', elem_id="request_notifications")
- download_localization = gr.Button(value='Download localization template', elem_id="download_localization")
+ if current_tab is not None:
+ current_tab.__exit__()
- with gr.Row():
- reload_script_bodies = gr.Button(value='Reload custom script bodies (No ui updates, No restart)', variant='secondary')
- restart_gradio = gr.Button(value='Restart Gradio and Refresh components (Custom Scripts, ui.py, js and css only)', variant='primary')
+ with gr.TabItem("Actions"):
+ request_notifications = gr.Button(value='Request browser notifications', elem_id="request_notifications")
+ download_localization = gr.Button(value='Download localization template', elem_id="download_localization")
+ reload_script_bodies = gr.Button(value='Reload custom script bodies (No ui updates, No restart)', variant='secondary', elem_id="settings_reload_script_bodies")
+
+ if os.path.exists("html/licenses.html"):
+ with open("html/licenses.html", encoding="utf8") as file:
+ with gr.TabItem("Licenses"):
+ gr.HTML(file.read(), elem_id="licenses")
+
+ gr.Button(value="Show all pages", elem_id="settings_show_all_pages")
request_notifications.click(
fn=lambda: None,
@@ -1570,8 +1605,7 @@ def create_ui(wrap_gradio_gpu_call):
reload_script_bodies.click(
fn=reload_scripts,
inputs=[],
- outputs=[],
- _js='function(){}'
+ outputs=[]
)
def request_restart():
@@ -1579,16 +1613,12 @@ def create_ui(wrap_gradio_gpu_call):
shared.state.need_restart = True
restart_gradio.click(
-
fn=request_restart,
+ _js='restart_reload',
inputs=[],
outputs=[],
- _js='function(){restart_reload()}'
)
- if column is not None:
- column.__exit__()
-
interfaces = [
(txt2img_interface, "txt2img", "txt2img"),
(img2img_interface, "img2img", "img2img"),
@@ -1622,7 +1652,7 @@ def create_ui(wrap_gradio_gpu_call):
with gr.Blocks(css=css, analytics_enabled=False, title="Stable Diffusion") as demo:
with gr.Row(elem_id="quicksettings"):
- for i, k, item in quicksettings_list:
+ for i, k, item in sorted(quicksettings_list, key=lambda x: quicksettings_names.get(x[1], x[0])):
component = create_setting_component(k, is_quicksettings=True)
component_dict[k] = component
@@ -1637,11 +1667,15 @@ def create_ui(wrap_gradio_gpu_call):
if os.path.exists(os.path.join(script_path, "notification.mp3")):
audio_notification = gr.Audio(interactive=False, value=os.path.join(script_path, "notification.mp3"), elem_id="audio_notification", visible=False)
+ if os.path.exists("html/footer.html"):
+ with open("html/footer.html", encoding="utf8") as file:
+ gr.HTML(file.read(), elem_id="footer")
+
text_settings = gr.Textbox(elem_id="settings_json", value=lambda: opts.dumpjson(), visible=False)
settings_submit.click(
- fn=run_settings,
+ fn=wrap_gradio_call(run_settings, extra_outputs=[gr.update()]),
inputs=components,
- outputs=[result, text_settings],
+ outputs=[text_settings, result],
)
for i, k, item in quicksettings_list:
@@ -1653,6 +1687,17 @@ def create_ui(wrap_gradio_gpu_call):
outputs=[component, text_settings],
)
+ component_keys = [k for k in opts.data_labels.keys() if k in component_dict]
+
+ def get_settings_values():
+ return [getattr(opts, key) for key in component_keys]
+
+ demo.load(
+ fn=get_settings_values,
+ inputs=[],
+ outputs=[component_dict[k] for k in component_keys],
+ )
+
def modelmerger(*args):
try:
results = modules.extras.run_modelmerger(*args)
@@ -1660,7 +1705,7 @@ def create_ui(wrap_gradio_gpu_call):
print("Error loading/saving model file:", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
modules.sd_models.list_models() # to remove the potentially missing models from the list
- return ["Error loading/saving model file. It doesn't exist or the name contains illegal characters"] + [gr.Dropdown.update(choices=modules.sd_models.checkpoint_tiles()) for _ in range(3)]
+ return [f"Error merging checkpoints: {e}"] + [gr.Dropdown.update(choices=modules.sd_models.checkpoint_tiles()) for _ in range(4)]
return results
modelmerger_merge.click(
@@ -1673,6 +1718,7 @@ def create_ui(wrap_gradio_gpu_call):
interp_amount,
save_as_half,
custom_name,
+ checkpoint_format,
],
outputs=[
submit_result,
@@ -1756,7 +1802,7 @@ def create_ui(wrap_gradio_gpu_call):
return demo
-def load_javascript(raw_response):
+def reload_javascript():
with open(os.path.join(script_path, "script.js"), "r", encoding="utf8") as jsfile:
javascript = f'<script>{jsfile.read()}</script>'
@@ -1772,7 +1818,7 @@ def load_javascript(raw_response):
javascript += f"\n<script>{localization.localization_js(shared.opts.localization)}</script>"
def template_response(*args, **kwargs):
- res = raw_response(*args, **kwargs)
+ res = shared.GradioTemplateResponseOriginal(*args, **kwargs)
res.body = res.body.replace(
b'</head>', f'{javascript}</head>'.encode("utf8"))
res.init_headers()
@@ -1781,5 +1827,5 @@ def load_javascript(raw_response):
gradio.routes.templates.TemplateResponse = template_response
-reload_javascript = partial(load_javascript, gradio.routes.templates.TemplateResponse)
-reload_javascript()
+if not hasattr(shared, 'GradioTemplateResponseOriginal'):
+ shared.GradioTemplateResponseOriginal = gradio.routes.templates.TemplateResponse
diff --git a/modules/ui_components.py b/modules/ui_components.py
new file mode 100644
index 00000000..91eb0e3d
--- /dev/null
+++ b/modules/ui_components.py
@@ -0,0 +1,25 @@
+import gradio as gr
+
+
+class ToolButton(gr.Button, gr.components.FormComponent):
+ """Small button with single emoji as text, fits inside gradio forms"""
+
+ def __init__(self, **kwargs):
+ super().__init__(variant="tool", **kwargs)
+
+ def get_block_name(self):
+ return "button"
+
+
+class FormRow(gr.Row, gr.components.FormComponent):
+ """Same as gr.Row but fits inside gradio forms"""
+
+ def get_block_name(self):
+ return "row"
+
+
+class FormGroup(gr.Group, gr.components.FormComponent):
+ """Same as gr.Row but fits inside gradio forms"""
+
+ def get_block_name(self):
+ return "group"
diff --git a/modules/ui_extensions.py b/modules/ui_extensions.py
index ab807722..eec9586f 100644
--- a/modules/ui_extensions.py
+++ b/modules/ui_extensions.py
@@ -9,6 +9,8 @@ import git
import gradio as gr
import html
+import shutil
+import errno
from modules import extensions, shared, paths
@@ -17,7 +19,7 @@ available_extensions = {"extensions": []}
def check_access():
- assert not shared.cmd_opts.disable_extension_access, "extension access disabed because of commandline flags"
+ assert not shared.cmd_opts.disable_extension_access, "extension access disabled because of command line flags"
def apply_and_restart(disable_list, update_list):
@@ -36,9 +38,9 @@ def apply_and_restart(disable_list, update_list):
continue
try:
- ext.pull()
+ ext.fetch_and_reset_hard()
except Exception:
- print(f"Error pulling updates for {ext.name}:", file=sys.stderr)
+ print(f"Error getting updates for {ext.name}:", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
shared.opts.disabled_extensions = disabled
@@ -78,6 +80,12 @@ def extension_table():
"""
for ext in extensions.extensions:
+ remote = ""
+ if ext.is_builtin:
+ remote = "built-in"
+ elif ext.remote:
+ remote = f"""<a href="{html.escape(ext.remote or '')}" target="_blank">{html.escape("built-in" if ext.is_builtin else ext.remote or '')}</a>"""
+
if ext.can_update:
ext_status = f"""<label><input class="gr-check-radio gr-checkbox" name="update_{html.escape(ext.name)}" checked="checked" type="checkbox">{html.escape(ext.status)}</label>"""
else:
@@ -86,7 +94,7 @@ def extension_table():
code += f"""
<tr>
<td><label><input class="gr-check-radio gr-checkbox" name="enable_{html.escape(ext.name)}" type="checkbox" {'checked="checked"' if ext.enabled else ''}>{html.escape(ext.name)}</label></td>
- <td><a href="{html.escape(ext.remote or '')}">{html.escape(ext.remote or '')}</a></td>
+ <td>{remote}</td>
<td{' class="extension_status"' if ext.remote is not None else ''}>{ext_status}</td>
</tr>
"""
@@ -132,7 +140,21 @@ def install_extension_from_url(dirname, url):
repo = git.Repo.clone_from(url, tmpdir)
repo.remote().fetch()
- os.rename(tmpdir, target_dir)
+ try:
+ os.rename(tmpdir, target_dir)
+ except OSError as err:
+ # TODO what does this do on windows? I think it'll be a different error code but I don't have a system to check it
+ # Shouldn't cause any new issues at least but we probably want to handle it there too.
+ if err.errno == errno.EXDEV:
+ # Cross device link, typical in docker or when tmp/ and extensions/ are on different file systems
+ # Since we can't use a rename, do the slower but more versitile shutil.move()
+ shutil.move(tmpdir, target_dir)
+ else:
+ # Something else, not enough free space, permissions, etc. rethrow it so that it gets handled.
+ raise(err)
+
+ import launch
+ launch.run_extension_installer(target_dir)
extensions.list_extensions()
return [extension_table(), html.escape(f"Installed into {target_dir}. Use Installed tab to restart.")]
@@ -140,13 +162,15 @@ def install_extension_from_url(dirname, url):
shutil.rmtree(tmpdir, True)
-def install_extension_from_index(url):
+def install_extension_from_index(url, hide_tags):
ext_table, message = install_extension_from_url(None, url)
- return refresh_available_extensions_from_data(), ext_table, message
+ code, _ = refresh_available_extensions_from_data(hide_tags)
+ return code, ext_table, message
-def refresh_available_extensions(url):
+
+def refresh_available_extensions(url, hide_tags):
global available_extensions
import urllib.request
@@ -155,13 +179,25 @@ def refresh_available_extensions(url):
available_extensions = json.loads(text)
- return url, refresh_available_extensions_from_data(), ''
+ code, tags = refresh_available_extensions_from_data(hide_tags)
+
+ return url, code, gr.CheckboxGroup.update(choices=tags), ''
-def refresh_available_extensions_from_data():
+def refresh_available_extensions_for_tags(hide_tags):
+ code, _ = refresh_available_extensions_from_data(hide_tags)
+
+ return code, ''
+
+
+def refresh_available_extensions_from_data(hide_tags):
extlist = available_extensions["extensions"]
installed_extension_urls = {normalize_git_url(extension.remote): extension.name for extension in extensions.extensions}
+ tags = available_extensions.get("tags", {})
+ tags_to_hide = set(hide_tags)
+ hidden = 0
+
code = f"""<!-- {time.time()} -->
<table id="available_extensions">
<thead>
@@ -178,28 +214,43 @@ def refresh_available_extensions_from_data():
name = ext.get("name", "noname")
url = ext.get("url", None)
description = ext.get("description", "")
+ extension_tags = ext.get("tags", [])
if url is None:
continue
existing = installed_extension_urls.get(normalize_git_url(url), None)
+ extension_tags = extension_tags + ["installed"] if existing else extension_tags
+
+ if len([x for x in extension_tags if x in tags_to_hide]) > 0:
+ hidden += 1
+ continue
install_code = f"""<input onclick="install_extension_from_index(this, '{html.escape(url)}')" type="button" value="{"Install" if not existing else "Installed"}" {"disabled=disabled" if existing else ""} class="gr-button gr-button-lg gr-button-secondary">"""
+ tags_text = ", ".join([f"<span class='extension-tag' title='{tags.get(x, '')}'>{x}</span>" for x in extension_tags])
+
code += f"""
<tr>
- <td><a href="{html.escape(url)}">{html.escape(name)}</a></td>
+ <td><a href="{html.escape(url)}" target="_blank">{html.escape(name)}</a><br />{tags_text}</td>
<td>{html.escape(description)}</td>
<td>{install_code}</td>
</tr>
- """
+
+ """
+
+ for tag in [x for x in extension_tags if x not in tags]:
+ tags[tag] = tag
code += """
</tbody>
</table>
"""
- return code
+ if hidden > 0:
+ code += f"<p>Extension hidden: {hidden}</p>"
+
+ return code, list(tags)
def create_ui():
@@ -238,21 +289,30 @@ def create_ui():
extension_to_install = gr.Text(elem_id="extension_to_install", visible=False)
install_extension_button = gr.Button(elem_id="install_extension_button", visible=False)
+ with gr.Row():
+ hide_tags = gr.CheckboxGroup(value=["ads", "localization", "installed"], label="Hide extensions with tags", choices=["script", "ads", "localization", "installed"])
+
install_result = gr.HTML()
available_extensions_table = gr.HTML()
refresh_available_extensions_button.click(
- fn=modules.ui.wrap_gradio_call(refresh_available_extensions, extra_outputs=[gr.update(), gr.update()]),
- inputs=[available_extensions_index],
- outputs=[available_extensions_index, available_extensions_table, install_result],
+ fn=modules.ui.wrap_gradio_call(refresh_available_extensions, extra_outputs=[gr.update(), gr.update(), gr.update()]),
+ inputs=[available_extensions_index, hide_tags],
+ outputs=[available_extensions_index, available_extensions_table, hide_tags, install_result],
)
install_extension_button.click(
fn=modules.ui.wrap_gradio_call(install_extension_from_index, extra_outputs=[gr.update(), gr.update()]),
- inputs=[extension_to_install],
+ inputs=[extension_to_install, hide_tags],
outputs=[available_extensions_table, extensions_table, install_result],
)
+ hide_tags.change(
+ fn=modules.ui.wrap_gradio_call(refresh_available_extensions_for_tags, extra_outputs=[gr.update()]),
+ inputs=[hide_tags],
+ outputs=[available_extensions_table, install_result]
+ )
+
with gr.TabItem("Install from URL"):
install_url = gr.Text(label="URL for extension's git repository")
install_dirname = gr.Text(label="Local directory name", placeholder="Leave empty for auto")
diff --git a/modules/ui_tempdir.py b/modules/ui_tempdir.py
new file mode 100644
index 00000000..21945235
--- /dev/null
+++ b/modules/ui_tempdir.py
@@ -0,0 +1,82 @@
+import os
+import tempfile
+from collections import namedtuple
+from pathlib import Path
+
+import gradio as gr
+
+from PIL import PngImagePlugin
+
+from modules import shared
+
+
+Savedfile = namedtuple("Savedfile", ["name"])
+
+
+def register_tmp_file(gradio, filename):
+ if hasattr(gradio, 'temp_file_sets'): # gradio 3.15
+ gradio.temp_file_sets[0] = gradio.temp_file_sets[0] | {os.path.abspath(filename)}
+
+ if hasattr(gradio, 'temp_dirs'): # gradio 3.9
+ gradio.temp_dirs = gradio.temp_dirs | {os.path.abspath(os.path.dirname(filename))}
+
+
+def check_tmp_file(gradio, filename):
+ if hasattr(gradio, 'temp_file_sets'):
+ return any([filename in fileset for fileset in gradio.temp_file_sets])
+
+ if hasattr(gradio, 'temp_dirs'):
+ return any(Path(temp_dir).resolve() in Path(filename).resolve().parents for temp_dir in gradio.temp_dirs)
+
+ return False
+
+
+def save_pil_to_file(pil_image, dir=None):
+ already_saved_as = getattr(pil_image, 'already_saved_as', None)
+ if already_saved_as and os.path.isfile(already_saved_as):
+ register_tmp_file(shared.demo, already_saved_as)
+
+ file_obj = Savedfile(already_saved_as)
+ return file_obj
+
+ if shared.opts.temp_dir != "":
+ dir = shared.opts.temp_dir
+
+ use_metadata = False
+ metadata = PngImagePlugin.PngInfo()
+ for key, value in pil_image.info.items():
+ if isinstance(key, str) and isinstance(value, str):
+ metadata.add_text(key, value)
+ use_metadata = True
+
+ file_obj = tempfile.NamedTemporaryFile(delete=False, suffix=".png", dir=dir)
+ pil_image.save(file_obj, pnginfo=(metadata if use_metadata else None))
+ return file_obj
+
+
+# override save to file function so that it also writes PNG info
+gr.processing_utils.save_pil_to_file = save_pil_to_file
+
+
+def on_tmpdir_changed():
+ if shared.opts.temp_dir == "" or shared.demo is None:
+ return
+
+ os.makedirs(shared.opts.temp_dir, exist_ok=True)
+
+ register_tmp_file(shared.demo, os.path.join(shared.opts.temp_dir, "x"))
+
+
+def cleanup_tmpdr():
+ temp_dir = shared.opts.temp_dir
+ if temp_dir == "" or not os.path.isdir(temp_dir):
+ return
+
+ for root, dirs, files in os.walk(temp_dir, topdown=False):
+ for name in files:
+ _, extension = os.path.splitext(name)
+ if extension != ".png":
+ continue
+
+ filename = os.path.join(root, name)
+ os.remove(filename)
diff --git a/modules/upscaler.py b/modules/upscaler.py
index 6ab2fb40..231680cb 100644
--- a/modules/upscaler.py
+++ b/modules/upscaler.py
@@ -10,6 +10,7 @@ import modules.shared
from modules import modelloader, shared
LANCZOS = (Image.Resampling.LANCZOS if hasattr(Image, 'Resampling') else Image.LANCZOS)
+NEAREST = (Image.Resampling.NEAREST if hasattr(Image, 'Resampling') else Image.NEAREST)
from modules.paths import models_path
@@ -52,14 +53,22 @@ class Upscaler:
def do_upscale(self, img: PIL.Image, selected_model: str):
return img
- def upscale(self, img: PIL.Image, scale: int, selected_model: str = None):
+ def upscale(self, img: PIL.Image, scale, selected_model: str = None):
self.scale = scale
- dest_w = img.width * scale
- dest_h = img.height * scale
+ dest_w = int(img.width * scale)
+ dest_h = int(img.height * scale)
+
for i in range(3):
+ shape = (img.width, img.height)
+
+ img = self.do_upscale(img, selected_model)
+
+ if shape == (img.width, img.height):
+ break
+
if img.width >= dest_w and img.height >= dest_h:
break
- img = self.do_upscale(img, selected_model)
+
if img.width != dest_w or img.height != dest_h:
img = img.resize((int(dest_w), int(dest_h)), resample=LANCZOS)
@@ -120,3 +129,17 @@ class UpscalerLanczos(Upscaler):
self.name = "Lanczos"
self.scalers = [UpscalerData("Lanczos", None, self)]
+
+class UpscalerNearest(Upscaler):
+ scalers = []
+
+ def do_upscale(self, img, selected_model=None):
+ return img.resize((int(img.width * self.scale), int(img.height * self.scale)), resample=NEAREST)
+
+ def load_model(self, _):
+ pass
+
+ def __init__(self, dirname=None):
+ super().__init__(False)
+ self.name = "Nearest"
+ self.scalers = [UpscalerData("Nearest", None, self)] \ No newline at end of file
diff --git a/modules/xlmr.py b/modules/xlmr.py
new file mode 100644
index 00000000..beab3fdf
--- /dev/null
+++ b/modules/xlmr.py
@@ -0,0 +1,137 @@
+from transformers import BertPreTrainedModel,BertModel,BertConfig
+import torch.nn as nn
+import torch
+from transformers.models.xlm_roberta.configuration_xlm_roberta import XLMRobertaConfig
+from transformers import XLMRobertaModel,XLMRobertaTokenizer
+from typing import Optional
+
+class BertSeriesConfig(BertConfig):
+ def __init__(self, vocab_size=30522, hidden_size=768, num_hidden_layers=12, num_attention_heads=12, intermediate_size=3072, hidden_act="gelu", hidden_dropout_prob=0.1, attention_probs_dropout_prob=0.1, max_position_embeddings=512, type_vocab_size=2, initializer_range=0.02, layer_norm_eps=1e-12, pad_token_id=0, position_embedding_type="absolute", use_cache=True, classifier_dropout=None,project_dim=512, pooler_fn="average",learn_encoder=False,model_type='bert',**kwargs):
+
+ super().__init__(vocab_size, hidden_size, num_hidden_layers, num_attention_heads, intermediate_size, hidden_act, hidden_dropout_prob, attention_probs_dropout_prob, max_position_embeddings, type_vocab_size, initializer_range, layer_norm_eps, pad_token_id, position_embedding_type, use_cache, classifier_dropout, **kwargs)
+ self.project_dim = project_dim
+ self.pooler_fn = pooler_fn
+ self.learn_encoder = learn_encoder
+
+class RobertaSeriesConfig(XLMRobertaConfig):
+ def __init__(self, pad_token_id=1, bos_token_id=0, eos_token_id=2,project_dim=512,pooler_fn='cls',learn_encoder=False, **kwargs):
+ super().__init__(pad_token_id=pad_token_id, bos_token_id=bos_token_id, eos_token_id=eos_token_id, **kwargs)
+ self.project_dim = project_dim
+ self.pooler_fn = pooler_fn
+ self.learn_encoder = learn_encoder
+
+
+class BertSeriesModelWithTransformation(BertPreTrainedModel):
+
+ _keys_to_ignore_on_load_unexpected = [r"pooler"]
+ _keys_to_ignore_on_load_missing = [r"position_ids", r"predictions.decoder.bias"]
+ config_class = BertSeriesConfig
+
+ def __init__(self, config=None, **kargs):
+ # modify initialization for autoloading
+ if config is None:
+ config = XLMRobertaConfig()
+ config.attention_probs_dropout_prob= 0.1
+ config.bos_token_id=0
+ config.eos_token_id=2
+ config.hidden_act='gelu'
+ config.hidden_dropout_prob=0.1
+ config.hidden_size=1024
+ config.initializer_range=0.02
+ config.intermediate_size=4096
+ config.layer_norm_eps=1e-05
+ config.max_position_embeddings=514
+
+ config.num_attention_heads=16
+ config.num_hidden_layers=24
+ config.output_past=True
+ config.pad_token_id=1
+ config.position_embedding_type= "absolute"
+
+ config.type_vocab_size= 1
+ config.use_cache=True
+ config.vocab_size= 250002
+ config.project_dim = 768
+ config.learn_encoder = False
+ super().__init__(config)
+ self.roberta = XLMRobertaModel(config)
+ self.transformation = nn.Linear(config.hidden_size,config.project_dim)
+ self.pre_LN=nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
+ self.tokenizer = XLMRobertaTokenizer.from_pretrained('xlm-roberta-large')
+ self.pooler = lambda x: x[:,0]
+ self.post_init()
+
+ def encode(self,c):
+ device = next(self.parameters()).device
+ text = self.tokenizer(c,
+ truncation=True,
+ max_length=77,
+ return_length=False,
+ return_overflowing_tokens=False,
+ padding="max_length",
+ return_tensors="pt")
+ text["input_ids"] = torch.tensor(text["input_ids"]).to(device)
+ text["attention_mask"] = torch.tensor(
+ text['attention_mask']).to(device)
+ features = self(**text)
+ return features['projection_state']
+
+ def forward(
+ self,
+ input_ids: Optional[torch.Tensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ token_type_ids: Optional[torch.Tensor] = None,
+ position_ids: Optional[torch.Tensor] = None,
+ head_mask: Optional[torch.Tensor] = None,
+ inputs_embeds: Optional[torch.Tensor] = None,
+ encoder_hidden_states: Optional[torch.Tensor] = None,
+ encoder_attention_mask: Optional[torch.Tensor] = None,
+ output_attentions: Optional[bool] = None,
+ return_dict: Optional[bool] = None,
+ output_hidden_states: Optional[bool] = None,
+ ) :
+ r"""
+ """
+
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
+
+
+ outputs = self.roberta(
+ input_ids=input_ids,
+ attention_mask=attention_mask,
+ token_type_ids=token_type_ids,
+ position_ids=position_ids,
+ head_mask=head_mask,
+ inputs_embeds=inputs_embeds,
+ encoder_hidden_states=encoder_hidden_states,
+ encoder_attention_mask=encoder_attention_mask,
+ output_attentions=output_attentions,
+ output_hidden_states=True,
+ return_dict=return_dict,
+ )
+
+ # last module outputs
+ sequence_output = outputs[0]
+
+
+ # project every module
+ sequence_output_ln = self.pre_LN(sequence_output)
+
+ # pooler
+ pooler_output = self.pooler(sequence_output_ln)
+ pooler_output = self.transformation(pooler_output)
+ projection_state = self.transformation(outputs.last_hidden_state)
+
+ return {
+ 'pooler_output':pooler_output,
+ 'last_hidden_state':outputs.last_hidden_state,
+ 'hidden_states':outputs.hidden_states,
+ 'attentions':outputs.attentions,
+ 'projection_state':projection_state,
+ 'sequence_out': sequence_output
+ }
+
+
+class RobertaSeriesModelWithTransformation(BertSeriesModelWithTransformation):
+ base_model_prefix = 'roberta'
+ config_class= RobertaSeriesConfig \ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index a53522f3..4f09385f 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,14 +1,15 @@
+blendmodes
+accelerate
basicsr
-diffusers
fairscale==0.4.4
fonts
font-roboto
gfpgan
-gradio==3.5
+gradio==3.15.0
invisible-watermark
numpy
omegaconf
-opencv-python
+opencv-contrib-python
requests
piexif
Pillow
@@ -27,3 +28,6 @@ kornia
lark
inflection
GitPython
+torchsde
+safetensors
+psutil; sys_platform == 'darwin'
diff --git a/requirements_versions.txt b/requirements_versions.txt
index 41f2501f..975102d9 100644
--- a/requirements_versions.txt
+++ b/requirements_versions.txt
@@ -1,8 +1,9 @@
+blendmodes==2022
transformers==4.19.2
-diffusers==0.3.0
+accelerate==0.12.0
basicsr==1.4.2
gfpgan==1.3.8
-gradio==3.5
+gradio==3.15.0
numpy==1.23.3
Pillow==9.2.0
realesrgan==0.3.0
@@ -24,3 +25,6 @@ kornia==0.6.7
lark==1.1.2
inflection==0.5.1
GitPython==3.1.27
+torchsde==0.2.5
+safetensors==0.2.7
+httpcore<=0.15
diff --git a/script.js b/script.js
index 8b3b67e3..0e117d06 100644
--- a/script.js
+++ b/script.js
@@ -1,9 +1,10 @@
-function gradioApp(){
- return document.getElementsByTagName('gradio-app')[0].shadowRoot;
+function gradioApp() {
+ const gradioShadowRoot = document.getElementsByTagName('gradio-app')[0].shadowRoot
+ return !!gradioShadowRoot ? gradioShadowRoot : document;
}
function get_uiCurrentTab() {
- return gradioApp().querySelector('.tabs button:not(.border-transparent)')
+ return gradioApp().querySelector('#tabs button:not(.border-transparent)')
}
function get_uiCurrentTabContent() {
@@ -82,4 +83,4 @@ function uiElementIsVisible(el) {
}
}
return isVisible;
-} \ No newline at end of file
+}
diff --git a/scripts/custom_code.py b/scripts/custom_code.py
index a9b10c09..22e7b77a 100644
--- a/scripts/custom_code.py
+++ b/scripts/custom_code.py
@@ -14,7 +14,7 @@ class Script(scripts.Script):
return cmd_opts.allow_code
def ui(self, is_img2img):
- code = gr.Textbox(label="Python code", visible=False, lines=1)
+ code = gr.Textbox(label="Python code", lines=1)
return [code]
diff --git a/scripts/img2imgalt.py b/scripts/img2imgalt.py
index 88abc093..1229f61b 100644
--- a/scripts/img2imgalt.py
+++ b/scripts/img2imgalt.py
@@ -157,7 +157,7 @@ class Script(scripts.Script):
def run(self, p, _, override_sampler, override_prompt, original_prompt, original_negative_prompt, override_steps, st, override_strength, cfg, randomness, sigma_adjustment):
# Override
if override_sampler:
- p.sampler_index = [sampler.name for sampler in sd_samplers.samplers].index("Euler")
+ p.sampler_name = "Euler"
if override_prompt:
p.prompt = original_prompt
p.negative_prompt = original_negative_prompt
@@ -166,8 +166,7 @@ class Script(scripts.Script):
if override_strength:
p.denoising_strength = 1.0
-
- def sample_extra(conditioning, unconditional_conditioning, seeds, subseeds, subseed_strength):
+ def sample_extra(conditioning, unconditional_conditioning, seeds, subseeds, subseed_strength, prompts):
lat = (p.init_latent.cpu().numpy() * 10).astype(int)
same_params = self.cache is not None and self.cache.cfg_scale == cfg and self.cache.steps == st \
@@ -192,7 +191,7 @@ class Script(scripts.Script):
combined_noise = ((1 - randomness) * rec_noise + randomness * rand_noise) / ((randomness**2 + (1-randomness)**2) ** 0.5)
- sampler = sd_samplers.create_sampler_with_index(sd_samplers.samplers, p.sampler_index, p.sd_model)
+ sampler = sd_samplers.create_sampler(p.sampler_name, p.sd_model)
sigmas = sampler.model_wrap.get_sigmas(p.steps)
diff --git a/scripts/outpainting_mk_2.py b/scripts/outpainting_mk_2.py
index 2afd4aa5..cf71cb92 100644
--- a/scripts/outpainting_mk_2.py
+++ b/scripts/outpainting_mk_2.py
@@ -132,7 +132,7 @@ class Script(scripts.Script):
info = gr.HTML("<p style=\"margin-bottom:0.75em\">Recommended settings: Sampling Steps: 80-100, Sampler: Euler a, Denoising strength: 0.8</p>")
pixels = gr.Slider(label="Pixels to expand", minimum=8, maximum=256, step=8, value=128)
- mask_blur = gr.Slider(label='Mask blur', minimum=0, maximum=64, step=1, value=8, visible=False)
+ mask_blur = gr.Slider(label='Mask blur', minimum=0, maximum=64, step=1, value=8)
direction = gr.CheckboxGroup(label="Outpainting direction", choices=['left', 'right', 'up', 'down'], value=['left', 'right', 'up', 'down'])
noise_q = gr.Slider(label="Fall-off exponent (lower=higher detail)", minimum=0.0, maximum=4.0, step=0.01, value=1.0)
color_variation = gr.Slider(label="Color variation", minimum=0.0, maximum=1.0, step=0.01, value=0.05)
diff --git a/scripts/poor_mans_outpainting.py b/scripts/poor_mans_outpainting.py
index b0469110..ea45beb0 100644
--- a/scripts/poor_mans_outpainting.py
+++ b/scripts/poor_mans_outpainting.py
@@ -22,8 +22,8 @@ class Script(scripts.Script):
return None
pixels = gr.Slider(label="Pixels to expand", minimum=8, maximum=256, step=8, value=128)
- mask_blur = gr.Slider(label='Mask blur', minimum=0, maximum=64, step=1, value=4, visible=False)
- inpainting_fill = gr.Radio(label='Masked content', choices=['fill', 'original', 'latent noise', 'latent nothing'], value='fill', type="index", visible=False)
+ mask_blur = gr.Slider(label='Mask blur', minimum=0, maximum=64, step=1, value=4)
+ inpainting_fill = gr.Radio(label='Masked content', choices=['fill', 'original', 'latent noise', 'latent nothing'], value='fill', type="index")
direction = gr.CheckboxGroup(label="Outpainting direction", choices=['left', 'right', 'up', 'down'], value=['left', 'right', 'up', 'down'])
return [pixels, mask_blur, inpainting_fill, direction]
diff --git a/scripts/prompt_matrix.py b/scripts/prompt_matrix.py
index e49c9b20..4c79eaef 100644
--- a/scripts/prompt_matrix.py
+++ b/scripts/prompt_matrix.py
@@ -18,7 +18,7 @@ def draw_xy_grid(xs, ys, x_label, y_label, cell):
ver_texts = [[images.GridAnnotation(y_label(y))] for y in ys]
hor_texts = [[images.GridAnnotation(x_label(x))] for x in xs]
- first_pocessed = None
+ first_processed = None
state.job_count = len(xs) * len(ys)
@@ -27,17 +27,17 @@ def draw_xy_grid(xs, ys, x_label, y_label, cell):
state.job = f"{ix + iy * len(xs) + 1} out of {len(xs) * len(ys)}"
processed = cell(x, y)
- if first_pocessed is None:
- first_pocessed = processed
+ if first_processed is None:
+ first_processed = processed
res.append(processed.images[0])
grid = images.image_grid(res, rows=len(ys))
grid = images.draw_grid_annotations(grid, res[0].width, res[0].height, hor_texts, ver_texts)
- first_pocessed.images = [grid]
+ first_processed.images = [grid]
- return first_pocessed
+ return first_processed
class Script(scripts.Script):
@@ -46,10 +46,11 @@ class Script(scripts.Script):
def ui(self, is_img2img):
put_at_start = gr.Checkbox(label='Put variable parts at start of prompt', value=False)
+ different_seeds = gr.Checkbox(label='Use different seed for each picture', value=False)
- return [put_at_start]
+ return [put_at_start, different_seeds]
- def run(self, p, put_at_start):
+ def run(self, p, put_at_start, different_seeds):
modules.processing.fix_seed(p)
original_prompt = p.prompt[0] if type(p.prompt) == list else p.prompt
@@ -73,15 +74,17 @@ class Script(scripts.Script):
print(f"Prompt matrix will create {len(all_prompts)} images using a total of {p.n_iter} batches.")
p.prompt = all_prompts
- p.seed = [p.seed for _ in all_prompts]
+ p.seed = [p.seed + (i if different_seeds else 0) for i in range(len(all_prompts))]
p.prompt_for_display = original_prompt
processed = process_images(p)
grid = images.image_grid(processed.images, p.batch_size, rows=1 << ((len(prompt_matrix_parts) - 1) // 2))
grid = images.draw_prompt_matrix(grid, p.width, p.height, prompt_matrix_parts)
processed.images.insert(0, grid)
+ processed.index_of_first_image = 1
+ processed.infotexts.insert(0, processed.infotexts[0])
if opts.grid_save:
- images.save_image(processed.images[0], p.outpath_grids, "prompt_matrix", prompt=original_prompt, seed=processed.seed, grid=True, p=p)
+ images.save_image(processed.images[0], p.outpath_grids, "prompt_matrix", extension=opts.grid_format, prompt=original_prompt, seed=processed.seed, grid=True, p=p)
return processed
diff --git a/scripts/prompts_from_file.py b/scripts/prompts_from_file.py
index 1be22960..e8386ed2 100644
--- a/scripts/prompts_from_file.py
+++ b/scripts/prompts_from_file.py
@@ -9,6 +9,7 @@ import shlex
import modules.scripts as scripts
import gradio as gr
+from modules import sd_samplers
from modules.processing import Processed, process_images
from PIL import Image
from modules.shared import opts, cmd_opts, state
@@ -44,6 +45,7 @@ prompt_tags = {
"seed_resize_from_h": process_int_tag,
"seed_resize_from_w": process_int_tag,
"sampler_index": process_int_tag,
+ "sampler_name": process_string_tag,
"batch_size": process_int_tag,
"n_iter": process_int_tag,
"steps": process_int_tag,
@@ -66,14 +68,28 @@ def cmdargs(line):
arg = args[pos]
assert arg.startswith("--"), f'must start with "--": {arg}'
+ assert pos+1 < len(args), f'missing argument for command line option {arg}'
+
tag = arg[2:]
+ if tag == "prompt" or tag == "negative_prompt":
+ pos += 1
+ prompt = args[pos]
+ pos += 1
+ while pos < len(args) and not args[pos].startswith("--"):
+ prompt += " "
+ prompt += args[pos]
+ pos += 1
+ res[tag] = prompt
+ continue
+
+
func = prompt_tags.get(tag, None)
assert func, f'unknown commandline option: {arg}'
- assert pos+1 < len(args), f'missing argument for command line option {arg}'
-
val = args[pos+1]
+ if tag == "sampler_name":
+ val = sd_samplers.samplers_map.get(val.lower(), None)
res[tag] = func(val)
@@ -83,19 +99,21 @@ def cmdargs(line):
def load_prompt_file(file):
- if (file is None):
+ if file is None:
lines = []
else:
lines = [x.strip() for x in file.decode('utf8', errors='ignore').split("\n")]
return None, "\n".join(lines), gr.update(lines=7)
+
class Script(scripts.Script):
def title(self):
return "Prompts from file or textbox"
def ui(self, is_img2img):
checkbox_iterate = gr.Checkbox(label="Iterate seed every line", value=False)
+ checkbox_iterate_batch = gr.Checkbox(label="Use same random seed for all lines", value=False)
prompt_txt = gr.Textbox(label="List of prompt inputs", lines=1)
file = gr.File(label="Upload prompt inputs", type='bytes')
@@ -106,9 +124,9 @@ class Script(scripts.Script):
# We don't shrink back to 1, because that causes the control to ignore [enter], and it may
# be unclear to the user that shift-enter is needed.
prompt_txt.change(lambda tb: gr.update(lines=7) if ("\n" in tb) else gr.update(lines=2), inputs=[prompt_txt], outputs=[prompt_txt])
- return [checkbox_iterate, file, prompt_txt]
+ return [checkbox_iterate, checkbox_iterate_batch, prompt_txt]
- def run(self, p, checkbox_iterate, file, prompt_txt: str):
+ def run(self, p, checkbox_iterate, checkbox_iterate_batch, prompt_txt: str):
lines = [x.strip() for x in prompt_txt.splitlines()]
lines = [x for x in lines if len(x) > 0]
@@ -122,7 +140,7 @@ class Script(scripts.Script):
try:
args = cmdargs(line)
except Exception:
- print(f"Error parsing line [line] as commandline:", file=sys.stderr)
+ print(f"Error parsing line {line} as commandline:", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
args = {"prompt": line}
else:
@@ -137,12 +155,14 @@ class Script(scripts.Script):
jobs.append(args)
print(f"Will process {len(lines)} lines in {job_count} jobs.")
- if (checkbox_iterate and p.seed == -1):
+ if (checkbox_iterate or checkbox_iterate_batch) and p.seed == -1:
p.seed = int(random.randrange(4294967294))
state.job_count = job_count
images = []
+ all_prompts = []
+ infotexts = []
for n, args in enumerate(jobs):
state.job = f"{state.job_no + 1} out of {state.job_count}"
@@ -153,8 +173,9 @@ class Script(scripts.Script):
proc = process_images(copy_p)
images += proc.images
- if (checkbox_iterate):
+ if checkbox_iterate:
p.seed = p.seed + (p.batch_size * p.n_iter)
+ all_prompts += proc.all_prompts
+ infotexts += proc.infotexts
-
- return Processed(p, images, p.seed, "") \ No newline at end of file
+ return Processed(p, images, p.seed, "", all_prompts=all_prompts, infotexts=infotexts)
diff --git a/scripts/sd_upscale.py b/scripts/sd_upscale.py
index cb37ff7e..9739545c 100644
--- a/scripts/sd_upscale.py
+++ b/scripts/sd_upscale.py
@@ -17,13 +17,14 @@ class Script(scripts.Script):
return is_img2img
def ui(self, is_img2img):
- info = gr.HTML("<p style=\"margin-bottom:0.75em\">Will upscale the image to twice the dimensions; use width and height sliders to set tile size</p>")
- overlap = gr.Slider(minimum=0, maximum=256, step=16, label='Tile overlap', value=64, visible=False)
- upscaler_index = gr.Radio(label='Upscaler', choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name, type="index", visible=False)
+ info = gr.HTML("<p style=\"margin-bottom:0.75em\">Will upscale the image by the selected scale factor; use width and height sliders to set tile size</p>")
+ overlap = gr.Slider(minimum=0, maximum=256, step=16, label='Tile overlap', value=64)
+ scale_factor = gr.Slider(minimum=1.0, maximum=4.0, step=0.05, label='Scale Factor', value=2.0)
+ upscaler_index = gr.Radio(label='Upscaler', choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name, type="index")
- return [info, overlap, upscaler_index]
+ return [info, overlap, upscaler_index, scale_factor]
- def run(self, p, _, overlap, upscaler_index):
+ def run(self, p, _, overlap, upscaler_index, scale_factor):
processing.fix_seed(p)
upscaler = shared.sd_upscalers[upscaler_index]
@@ -34,9 +35,10 @@ class Script(scripts.Script):
seed = p.seed
init_img = p.init_images[0]
-
- if(upscaler.name != "None"):
- img = upscaler.scaler.upscale(init_img, 2, upscaler.data_path)
+ init_img = images.flatten(init_img, opts.img2img_background_color)
+
+ if upscaler.name != "None":
+ img = upscaler.scaler.upscale(init_img, scale_factor, upscaler.data_path)
else:
img = init_img
@@ -69,7 +71,7 @@ class Script(scripts.Script):
work_results = []
for i in range(batch_count):
p.batch_size = batch_size
- p.init_images = work[i*batch_size:(i+1)*batch_size]
+ p.init_images = work[i * batch_size:(i + 1) * batch_size]
state.job = f"Batch {i + 1 + n * batch_count} out of {state.job_count}"
processed = processing.process_images(p)
diff --git a/scripts/xy_grid.py b/scripts/xy_grid.py
index f5255786..f92f9776 100644
--- a/scripts/xy_grid.py
+++ b/scripts/xy_grid.py
@@ -10,13 +10,16 @@ import numpy as np
import modules.scripts as scripts
import gradio as gr
-from modules import images
+from modules import images, paths, sd_samplers
from modules.hypernetworks import hypernetwork
-from modules.processing import process_images, Processed, get_correct_sampler, StableDiffusionProcessingTxt2Img
+from modules.processing import process_images, Processed, StableDiffusionProcessingTxt2Img
from modules.shared import opts, cmd_opts, state
import modules.shared as shared
import modules.sd_samplers
import modules.sd_models
+import modules.sd_vae
+import glob
+import os
import re
@@ -58,29 +61,19 @@ def apply_order(p, x, xs):
prompt_tmp += part
prompt_tmp += x[idx]
p.prompt = prompt_tmp + p.prompt
-
-
-def build_samplers_dict(p):
- samplers_dict = {}
- for i, sampler in enumerate(get_correct_sampler(p)):
- samplers_dict[sampler.name.lower()] = i
- for alias in sampler.aliases:
- samplers_dict[alias.lower()] = i
- return samplers_dict
def apply_sampler(p, x, xs):
- sampler_index = build_samplers_dict(p).get(x.lower(), None)
- if sampler_index is None:
+ sampler_name = sd_samplers.samplers_map.get(x.lower(), None)
+ if sampler_name is None:
raise RuntimeError(f"Unknown sampler: {x}")
- p.sampler_index = sampler_index
+ p.sampler_name = sampler_name
def confirm_samplers(p, xs):
- samplers_dict = build_samplers_dict(p)
for x in xs:
- if x.lower() not in samplers_dict.keys():
+ if x.lower() not in sd_samplers.samplers_map:
raise RuntimeError(f"Unknown sampler: {x}")
@@ -124,6 +117,38 @@ def apply_clip_skip(p, x, xs):
opts.data["CLIP_stop_at_last_layers"] = x
+def apply_upscale_latent_space(p, x, xs):
+ if x.lower().strip() != '0':
+ opts.data["use_scale_latent_for_hires_fix"] = True
+ else:
+ opts.data["use_scale_latent_for_hires_fix"] = False
+
+
+def find_vae(name: str):
+ if name.lower() in ['auto', 'none']:
+ return name
+ else:
+ vae_path = os.path.abspath(os.path.join(paths.models_path, 'VAE'))
+ found = glob.glob(os.path.join(vae_path, f'**/{name}.*pt'), recursive=True)
+ if found:
+ return found[0]
+ else:
+ return 'auto'
+
+
+def apply_vae(p, x, xs):
+ if x.lower().strip() == 'none':
+ modules.sd_vae.reload_vae_weights(shared.sd_model, vae_file='None')
+ else:
+ found = find_vae(x)
+ if found:
+ v = modules.sd_vae.reload_vae_weights(shared.sd_model, vae_file=found)
+
+
+def apply_styles(p: StableDiffusionProcessingTxt2Img, x: str, _):
+ p.styles = x.split(',')
+
+
def format_value_add_label(p, opt, x):
if type(x) == float:
x = round(x, 8)
@@ -177,7 +202,10 @@ axis_options = [
AxisOption("Eta", float, apply_field("eta"), format_value_add_label, None),
AxisOption("Clip skip", int, apply_clip_skip, format_value_add_label, None),
AxisOption("Denoising", float, apply_field("denoising_strength"), format_value_add_label, None),
+ AxisOption("Hires upscaler", str, apply_field("hr_upscaler"), format_value_add_label, None),
AxisOption("Cond. Image Mask Weight", float, apply_field("inpainting_mask_weight"), format_value_add_label, None),
+ AxisOption("VAE", str, apply_vae, format_value_add_label, None),
+ AxisOption("Styles", str, apply_styles, format_value_add_label, None),
]
@@ -239,9 +267,11 @@ class SharedSettingsStackHelper(object):
self.CLIP_stop_at_last_layers = opts.CLIP_stop_at_last_layers
self.hypernetwork = opts.sd_hypernetwork
self.model = shared.sd_model
+ self.vae = opts.sd_vae
def __exit__(self, exc_type, exc_value, tb):
modules.sd_models.reload_model_weights(self.model)
+ modules.sd_vae.reload_vae_weights(self.model, vae_file=find_vae(self.vae))
hypernetwork.load_hypernetwork(self.hypernetwork)
hypernetwork.apply_strength()
@@ -263,12 +293,12 @@ class Script(scripts.Script):
current_axis_options = [x for x in axis_options if type(x) == AxisOption or type(x) == AxisOptionImg2Img and is_img2img]
with gr.Row():
- x_type = gr.Dropdown(label="X type", choices=[x.label for x in current_axis_options], value=current_axis_options[1].label, visible=False, type="index", elem_id="x_type")
- x_values = gr.Textbox(label="X values", visible=False, lines=1)
+ x_type = gr.Dropdown(label="X type", choices=[x.label for x in current_axis_options], value=current_axis_options[1].label, type="index", elem_id="x_type")
+ x_values = gr.Textbox(label="X values", lines=1)
with gr.Row():
- y_type = gr.Dropdown(label="Y type", choices=[x.label for x in current_axis_options], value=current_axis_options[0].label, visible=False, type="index", elem_id="y_type")
- y_values = gr.Textbox(label="Y values", visible=False, lines=1)
+ y_type = gr.Dropdown(label="Y type", choices=[x.label for x in current_axis_options], value=current_axis_options[0].label, type="index", elem_id="y_type")
+ y_values = gr.Textbox(label="Y values", lines=1)
draw_legend = gr.Checkbox(label='Draw legend', value=True)
include_lone_images = gr.Checkbox(label='Include Separate Images', value=False)
@@ -393,6 +423,6 @@ class Script(scripts.Script):
)
if opts.grid_save:
- images.save_image(processed.images[0], p.outpath_grids, "xy_grid", prompt=p.prompt, seed=processed.seed, grid=True, p=p)
+ images.save_image(processed.images[0], p.outpath_grids, "xy_grid", extension=opts.grid_format, prompt=p.prompt, seed=processed.seed, grid=True, p=p)
return processed
diff --git a/style.css b/style.css
index dfef0dc5..2116ec3c 100644
--- a/style.css
+++ b/style.css
@@ -73,8 +73,9 @@
margin-right: auto;
}
-#random_seed, #random_subseed, #reuse_seed, #reuse_subseed, #open_folder{
- min-width: auto;
+[id$=_random_seed], [id$=_random_subseed], [id$=_reuse_seed], [id$=_reuse_subseed], #open_folder{
+ min-width: 2.3em;
+ height: 2.5em;
flex-grow: 0;
padding-left: 0.25em;
padding-right: 0.25em;
@@ -84,27 +85,28 @@
display: none;
}
-#seed_row, #subseed_row{
+[id$=_seed_row], [id$=_subseed_row]{
gap: 0.5rem;
+ padding: 0.6em;
}
-#subseed_show_box{
+[id$=_subseed_show_box]{
min-width: auto;
flex-grow: 0;
}
-#subseed_show_box > div{
+[id$=_subseed_show_box] > div{
border: 0;
height: 100%;
}
-#subseed_show{
+[id$=_subseed_show]{
min-width: auto;
flex-grow: 0;
padding: 0;
}
-#subseed_show label{
+[id$=_subseed_show] label{
height: 100%;
}
@@ -114,7 +116,7 @@
padding: 0.4em 0;
}
-#roll, #paste, #style_create, #style_apply{
+#roll_col > button {
min-width: 2em;
min-height: 2em;
max-width: 2em;
@@ -206,24 +208,24 @@ button{
fieldset span.text-gray-500, .gr-block.gr-box span.text-gray-500, label.block span{
position: absolute;
- top: -0.6em;
+ top: -0.7em;
line-height: 1.2em;
- padding: 0 0.5em;
- margin: 0;
+ padding: 0;
+ margin: 0 0.5em;
background-color: white;
- border-top: 1px solid #eee;
- border-left: 1px solid #eee;
- border-right: 1px solid #eee;
+ box-shadow: 6px 0 6px 0px white, -6px 0 6px 0px white;
z-index: 300;
}
.dark fieldset span.text-gray-500, .dark .gr-block.gr-box span.text-gray-500, .dark label.block span{
background-color: rgb(31, 41, 55);
- border-top: 1px solid rgb(55 65 81);
- border-left: 1px solid rgb(55 65 81);
- border-right: 1px solid rgb(55 65 81);
+ box-shadow: 6px 0 6px 0px rgb(31, 41, 55), -6px 0 6px 0px rgb(31, 41, 55);
+}
+
+#txt2img_column_batch, #img2img_column_batch{
+ min-width: min(13.5em, 100%) !important;
}
#settings fieldset span.text-gray-500, #settings .gr-block.gr-box span.text-gray-500, #settings label.block span{
@@ -232,22 +234,40 @@ fieldset span.text-gray-500, .gr-block.gr-box span.text-gray-500, label.block s
margin-right: 8em;
}
-.gr-panel div.flex-col div.justify-between label span{
- margin: 0;
-}
-
#settings .gr-panel div.flex-col div.justify-between div{
position: relative;
z-index: 200;
}
-input[type="range"]{
- margin: 0.5em 0 -0.3em 0;
+#settings{
+ display: block;
+}
+
+#settings > div{
+ border: none;
+ margin-left: 10em;
+}
+
+#settings > div.flex-wrap{
+ float: left;
+ display: block;
+ margin-left: 0;
+ width: 10em;
+}
+
+#settings > div.flex-wrap button{
+ display: block;
+ border: none;
+ text-align: left;
}
-#txt2img_sampling label{
- padding-left: 0.6em;
- padding-right: 0.6em;
+#settings_result{
+ height: 1.4em;
+ margin: 0 1.2em;
+}
+
+input[type="range"]{
+ margin: 0.5em 0 -0.3em 0;
}
#mask_bug_info {
@@ -260,6 +280,16 @@ input[type="range"]{
#txt2img_negative_prompt, #img2img_negative_prompt{
}
+/* gradio 3.8 adds opacity to progressbar which makes it blink; disable it here */
+.transition.opacity-20 {
+ opacity: 1 !important;
+}
+
+/* more gradio's garbage cleanup */
+.min-h-\[4rem\] {
+ min-height: unset !important;
+}
+
#txt2img_progressbar, #img2img_progressbar, #ti_progressbar{
position: absolute;
z-index: 1000;
@@ -491,13 +521,6 @@ input[type="range"]{
padding: 0;
}
-#refresh_sd_model_checkpoint, #refresh_sd_hypernetwork, #refresh_train_hypernetwork_name, #refresh_train_embedding_name, #refresh_localization{
- max-width: 2.5em;
- min-width: 2.5em;
- height: 2.4em;
-}
-
-
canvas[key="mask"] {
z-index: 12 !important;
filter: invert();
@@ -511,7 +534,7 @@ canvas[key="mask"] {
position: absolute;
right: 0.5em;
top: -0.6em;
- z-index: 200;
+ z-index: 400;
width: 8em;
}
#quicksettings .gr-box > div > div > input.gr-text-input {
@@ -553,6 +576,58 @@ img2maskimg, #img2maskimg > .h-60, #img2maskimg > .h-60 > div, #img2maskimg > .h
opacity: 0.5;
}
+.extension-tag{
+ font-weight: bold;
+ font-size: 95%;
+}
+
+#image_buttons_txt2img button, #image_buttons_img2img button, #image_buttons_extras button{
+ min-width: auto;
+ padding-left: 0.5em;
+ padding-right: 0.5em;
+}
+
+.gr-form{
+ background-color: white;
+}
+
+.dark .gr-form{
+ background-color: rgb(31 41 55 / var(--tw-bg-opacity));
+}
+
+.gr-button-tool{
+ max-width: 2.5em;
+ min-width: 2.5em !important;
+ height: 2.4em;
+ margin: 0.55em 0;
+}
+
+#quicksettings .gr-button-tool{
+ margin: 0;
+}
+
+
+#img2img_settings > div.gr-form, #txt2img_settings > div.gr-form {
+ padding-top: 0.9em;
+}
+
+#img2img_settings div.gr-form .gr-form, #txt2img_settings div.gr-form .gr-form{
+ border: none;
+ padding-bottom: 0.5em;
+}
+
+footer {
+ display: none !important;
+}
+
+#footer{
+ text-align: center;
+}
+
+#footer div{
+ display: inline-block;
+}
+
/* The following handles localization for right-to-left (RTL) languages like Arabic.
The rtl media type will only be activated by the logic in javascript/localization.js.
If you change anything above, you need to make sure it is RTL compliant by just running
diff --git a/test/advanced_features/__init__.py b/test/advanced_features/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/advanced_features/__init__.py
diff --git a/test/extras_test.py b/test/advanced_features/extras_test.py
index 9b8ce0f0..8763f8ed 100644
--- a/test/extras_test.py
+++ b/test/advanced_features/extras_test.py
@@ -11,8 +11,8 @@ class TestExtrasWorking(unittest.TestCase):
"codeformer_visibility": 0,
"codeformer_weight": 0,
"upscaling_resize": 2,
- "upscaling_resize_w": 512,
- "upscaling_resize_h": 512,
+ "upscaling_resize_w": 128,
+ "upscaling_resize_h": 128,
"upscaling_crop": True,
"upscaler_1": "None",
"upscaler_2": "None",
diff --git a/test/advanced_features/txt2img_test.py b/test/advanced_features/txt2img_test.py
new file mode 100644
index 00000000..36ed7b9a
--- /dev/null
+++ b/test/advanced_features/txt2img_test.py
@@ -0,0 +1,47 @@
+import unittest
+import requests
+
+
+class TestTxt2ImgWorking(unittest.TestCase):
+ def setUp(self):
+ self.url_txt2img = "http://localhost:7860/sdapi/v1/txt2img"
+ self.simple_txt2img = {
+ "enable_hr": False,
+ "denoising_strength": 0,
+ "firstphase_width": 0,
+ "firstphase_height": 0,
+ "prompt": "example prompt",
+ "styles": [],
+ "seed": -1,
+ "subseed": -1,
+ "subseed_strength": 0,
+ "seed_resize_from_h": -1,
+ "seed_resize_from_w": -1,
+ "batch_size": 1,
+ "n_iter": 1,
+ "steps": 3,
+ "cfg_scale": 7,
+ "width": 64,
+ "height": 64,
+ "restore_faces": False,
+ "tiling": False,
+ "negative_prompt": "",
+ "eta": 0,
+ "s_churn": 0,
+ "s_tmax": 0,
+ "s_tmin": 0,
+ "s_noise": 1,
+ "sampler_index": "Euler a"
+ }
+
+ def test_txt2img_with_restore_faces_performed(self):
+ self.simple_txt2img["restore_faces"] = True
+ self.assertEqual(requests.post(self.url_txt2img, json=self.simple_txt2img).status_code, 200)
+
+
+class TestTxt2ImgCorrectness(unittest.TestCase):
+ pass
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/test/basic_features/__init__.py b/test/basic_features/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/basic_features/__init__.py
diff --git a/test/img2img_test.py b/test/basic_features/img2img_test.py
index 012a9580..0a9c1e8a 100644
--- a/test/img2img_test.py
+++ b/test/basic_features/img2img_test.py
@@ -51,9 +51,5 @@ class TestImg2ImgWorking(unittest.TestCase):
self.assertEqual(requests.post(self.url_img2img, json=self.simple_img2img).status_code, 200)
-class TestImg2ImgCorrectness(unittest.TestCase):
- pass
-
-
if __name__ == "__main__":
unittest.main()
diff --git a/test/txt2img_test.py b/test/basic_features/txt2img_test.py
index 1936e07e..1c2674b2 100644
--- a/test/txt2img_test.py
+++ b/test/basic_features/txt2img_test.py
@@ -49,26 +49,20 @@ class TestTxt2ImgWorking(unittest.TestCase):
self.simple_txt2img["enable_hr"] = True
self.assertEqual(requests.post(self.url_txt2img, json=self.simple_txt2img).status_code, 200)
- def test_txt2img_with_restore_faces_performed(self):
- self.simple_txt2img["restore_faces"] = True
- self.assertEqual(requests.post(self.url_txt2img, json=self.simple_txt2img).status_code, 200)
-
- def test_txt2img_with_tiling_faces_performed(self):
+ def test_txt2img_with_tiling_performed(self):
self.simple_txt2img["tiling"] = True
self.assertEqual(requests.post(self.url_txt2img, json=self.simple_txt2img).status_code, 200)
def test_txt2img_with_vanilla_sampler_performed(self):
self.simple_txt2img["sampler_index"] = "PLMS"
self.assertEqual(requests.post(self.url_txt2img, json=self.simple_txt2img).status_code, 200)
+ self.simple_txt2img["sampler_index"] = "DDIM"
+ self.assertEqual(requests.post(self.url_txt2img, json=self.simple_txt2img).status_code, 200)
def test_txt2img_multiple_batches_performed(self):
self.simple_txt2img["n_iter"] = 2
self.assertEqual(requests.post(self.url_txt2img, json=self.simple_txt2img).status_code, 200)
-class TestTxt2ImgCorrectness(unittest.TestCase):
- pass
-
-
if __name__ == "__main__":
unittest.main()
diff --git a/test/basic_features/utils_test.py b/test/basic_features/utils_test.py
new file mode 100644
index 00000000..765470c9
--- /dev/null
+++ b/test/basic_features/utils_test.py
@@ -0,0 +1,53 @@
+import unittest
+import requests
+
+class UtilsTests(unittest.TestCase):
+ def setUp(self):
+ self.url_options = "http://localhost:7860/sdapi/v1/options"
+ self.url_cmd_flags = "http://localhost:7860/sdapi/v1/cmd-flags"
+ self.url_samplers = "http://localhost:7860/sdapi/v1/samplers"
+ self.url_upscalers = "http://localhost:7860/sdapi/v1/upscalers"
+ self.url_sd_models = "http://localhost:7860/sdapi/v1/sd-models"
+ self.url_hypernetworks = "http://localhost:7860/sdapi/v1/hypernetworks"
+ self.url_face_restorers = "http://localhost:7860/sdapi/v1/face-restorers"
+ self.url_realesrgan_models = "http://localhost:7860/sdapi/v1/realesrgan-models"
+ self.url_prompt_styles = "http://localhost:7860/sdapi/v1/prompt-styles"
+ self.url_artist_categories = "http://localhost:7860/sdapi/v1/artist-categories"
+ self.url_artists = "http://localhost:7860/sdapi/v1/artists"
+
+ def test_options_get(self):
+ self.assertEqual(requests.get(self.url_options).status_code, 200)
+
+ def test_cmd_flags(self):
+ self.assertEqual(requests.get(self.url_cmd_flags).status_code, 200)
+
+ def test_samplers(self):
+ self.assertEqual(requests.get(self.url_samplers).status_code, 200)
+
+ def test_upscalers(self):
+ self.assertEqual(requests.get(self.url_upscalers).status_code, 200)
+
+ def test_sd_models(self):
+ self.assertEqual(requests.get(self.url_sd_models).status_code, 200)
+
+ def test_hypernetworks(self):
+ self.assertEqual(requests.get(self.url_hypernetworks).status_code, 200)
+
+ def test_face_restorers(self):
+ self.assertEqual(requests.get(self.url_face_restorers).status_code, 200)
+
+ def test_realesrgan_models(self):
+ self.assertEqual(requests.get(self.url_realesrgan_models).status_code, 200)
+
+ def test_prompt_styles(self):
+ self.assertEqual(requests.get(self.url_prompt_styles).status_code, 200)
+
+ def test_artist_categories(self):
+ self.assertEqual(requests.get(self.url_artist_categories).status_code, 200)
+
+ def test_artists(self):
+ self.assertEqual(requests.get(self.url_artists).status_code, 200)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/test/server_poll.py b/test/server_poll.py
index eeefb7eb..d4df697b 100644
--- a/test/server_poll.py
+++ b/test/server_poll.py
@@ -3,7 +3,7 @@ import requests
import time
-def run_tests():
+def run_tests(proc, test_dir):
timeout_threshold = 240
start_time = time.time()
while time.time()-start_time < timeout_threshold:
@@ -11,9 +11,14 @@ def run_tests():
requests.head("http://localhost:7860/")
break
except requests.exceptions.ConnectionError:
- pass
- if time.time()-start_time < timeout_threshold:
- suite = unittest.TestLoader().discover('', pattern='*_test.py')
+ if proc.poll() is not None:
+ break
+ if proc.poll() is None:
+ if test_dir is None:
+ test_dir = ""
+ suite = unittest.TestLoader().discover(test_dir, pattern="*_test.py", top_level_dir="test")
result = unittest.TextTestRunner(verbosity=2).run(suite)
+ return len(result.failures) + len(result.errors)
else:
print("Launch unsuccessful")
+ return 1
diff --git a/test/test_files/empty.pt b/test/test_files/empty.pt
new file mode 100644
index 00000000..c6ac59eb
--- /dev/null
+++ b/test/test_files/empty.pt
Binary files differ
diff --git a/v2-inference-v.yaml b/v2-inference-v.yaml
new file mode 100644
index 00000000..513cd635
--- /dev/null
+++ b/v2-inference-v.yaml
@@ -0,0 +1,68 @@
+model:
+ base_learning_rate: 1.0e-4
+ target: ldm.models.diffusion.ddpm.LatentDiffusion
+ params:
+ parameterization: "v"
+ linear_start: 0.00085
+ linear_end: 0.0120
+ num_timesteps_cond: 1
+ log_every_t: 200
+ timesteps: 1000
+ first_stage_key: "jpg"
+ cond_stage_key: "txt"
+ image_size: 64
+ channels: 4
+ cond_stage_trainable: false
+ conditioning_key: crossattn
+ monitor: val/loss_simple_ema
+ scale_factor: 0.18215
+ use_ema: False # we set this to false because this is an inference only config
+
+ unet_config:
+ target: ldm.modules.diffusionmodules.openaimodel.UNetModel
+ params:
+ use_checkpoint: True
+ use_fp16: True
+ image_size: 32 # unused
+ in_channels: 4
+ out_channels: 4
+ model_channels: 320
+ attention_resolutions: [ 4, 2, 1 ]
+ num_res_blocks: 2
+ channel_mult: [ 1, 2, 4, 4 ]
+ num_head_channels: 64 # need to fix for flash-attn
+ use_spatial_transformer: True
+ use_linear_in_transformer: True
+ transformer_depth: 1
+ context_dim: 1024
+ legacy: False
+
+ first_stage_config:
+ target: ldm.models.autoencoder.AutoencoderKL
+ params:
+ embed_dim: 4
+ monitor: val/rec_loss
+ ddconfig:
+ #attn_type: "vanilla-xformers"
+ double_z: true
+ z_channels: 4
+ resolution: 256
+ in_channels: 3
+ out_ch: 3
+ ch: 128
+ ch_mult:
+ - 1
+ - 2
+ - 4
+ - 4
+ num_res_blocks: 2
+ attn_resolutions: []
+ dropout: 0.0
+ lossconfig:
+ target: torch.nn.Identity
+
+ cond_stage_config:
+ target: ldm.modules.encoders.modules.FrozenOpenCLIPEmbedder
+ params:
+ freeze: True
+ layer: "penultimate" \ No newline at end of file
diff --git a/webui-macos-env.sh b/webui-macos-env.sh
new file mode 100644
index 00000000..95ca9c55
--- /dev/null
+++ b/webui-macos-env.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+####################################################################
+# macOS defaults #
+# Please modify webui-user.sh to change these instead of this file #
+####################################################################
+
+if [[ -x "$(command -v python3.10)" ]]
+then
+ python_cmd="python3.10"
+fi
+
+export install_dir="$HOME"
+export COMMANDLINE_ARGS="--skip-torch-cuda-test --no-half --use-cpu interrogate"
+export TORCH_COMMAND="pip install torch==1.12.1 torchvision==0.13.1"
+export K_DIFFUSION_REPO="https://github.com/brkirch/k-diffusion.git"
+export K_DIFFUSION_COMMIT_HASH="51c9778f269cedb55a4d88c79c0246d35bdadb71"
+export PYTORCH_ENABLE_MPS_FALLBACK=1
+
+####################################################################
diff --git a/webui-user.sh b/webui-user.sh
index 30646f5c..bfa53cb7 100644
--- a/webui-user.sh
+++ b/webui-user.sh
@@ -10,7 +10,7 @@
#clone_dir="stable-diffusion-webui"
# Commandline arguments for webui.py, for example: export COMMANDLINE_ARGS="--medvram --opt-split-attention"
-export COMMANDLINE_ARGS=""
+#export COMMANDLINE_ARGS=""
# python3 executable
#python_cmd="python3"
@@ -40,4 +40,7 @@ export COMMANDLINE_ARGS=""
#export CODEFORMER_COMMIT_HASH=""
#export BLIP_COMMIT_HASH=""
+# Uncomment to enable accelerated launch
+#export ACCELERATE="True"
+
###########################################
diff --git a/webui.bat b/webui.bat
index a38a28bb..d4d626e2 100644
--- a/webui.bat
+++ b/webui.bat
@@ -28,15 +28,27 @@ goto :show_stdout_stderr
:activate_venv
set PYTHON="%~dp0%VENV_DIR%\Scripts\Python.exe"
echo venv %PYTHON%
+if [%ACCELERATE%] == ["True"] goto :accelerate
goto :launch
:skip_venv
+:accelerate
+echo "Checking for accelerate"
+set ACCELERATE="%~dp0%VENV_DIR%\Scripts\accelerate.exe"
+if EXIST %ACCELERATE% goto :accelerate_launch
+
:launch
%PYTHON% launch.py %*
pause
exit /b
+:accelerate_launch
+echo "Accelerating"
+%ACCELERATE% launch --num_cpu_threads_per_process=6 launch.py
+pause
+exit /b
+
:show_stdout_stderr
echo.
diff --git a/webui.py b/webui.py
index 84e5c1fd..13375e71 100644
--- a/webui.py
+++ b/webui.py
@@ -1,15 +1,19 @@
import os
+import sys
import threading
import time
import importlib
import signal
import threading
from fastapi import FastAPI
+from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.gzip import GZipMiddleware
+from modules import import_hook, errors
+from modules.call_queue import wrap_queued_call, queue_lock, wrap_gradio_gpu_call
from modules.paths import script_path
-from modules import devices, sd_samplers, upscaler, extensions
+from modules import shared, devices, sd_samplers, upscaler, extensions, localization, ui_tempdir
import modules.codeformer_model as codeformer
import modules.extras
import modules.face_restoration
@@ -21,47 +25,25 @@ import modules.paths
import modules.scripts
import modules.sd_hijack
import modules.sd_models
-import modules.shared as shared
+import modules.sd_vae
import modules.txt2img
import modules.script_callbacks
import modules.ui
-from modules import devices
from modules import modelloader
-from modules.paths import script_path
from modules.shared import cmd_opts
import modules.hypernetworks.hypernetwork
-queue_lock = threading.Lock()
-
-
-def wrap_queued_call(func):
- def f(*args, **kwargs):
- with queue_lock:
- res = func(*args, **kwargs)
-
- return res
-
- return f
-
-
-def wrap_gradio_gpu_call(func, extra_outputs=None):
- def f(*args, **kwargs):
- shared.state.begin()
-
- with queue_lock:
- res = func(*args, **kwargs)
-
- shared.state.end()
-
- return res
-
- return modules.ui.wrap_gradio_call(f, extra_outputs=extra_outputs)
+if cmd_opts.server_name:
+ server_name = cmd_opts.server_name
+else:
+ server_name = "0.0.0.0" if cmd_opts.listen else None
def initialize():
extensions.list_extensions()
+ localization.list_localizations(cmd_opts.localizations_dir)
if cmd_opts.ui_debug_mode:
shared.sd_upscalers = upscaler.UpscalerLanczos().scalers
@@ -73,14 +55,40 @@ def initialize():
codeformer.setup_model(cmd_opts.codeformer_models_path)
gfpgan.setup_model(cmd_opts.gfpgan_models_path)
shared.face_restorers.append(modules.face_restoration.FaceRestoration())
- modelloader.load_upscalers()
+ modelloader.list_builtin_upscalers()
modules.scripts.load_scripts()
+ modelloader.load_upscalers()
+
+ modules.sd_vae.refresh_vae_list()
+
+ try:
+ modules.sd_models.load_model()
+ except Exception as e:
+ errors.display(e, "loading stable diffusion model")
+ print("", file=sys.stderr)
+ print("Stable diffusion model failed to load, exiting", file=sys.stderr)
+ exit(1)
- modules.sd_models.load_model()
shared.opts.onchange("sd_model_checkpoint", wrap_queued_call(lambda: modules.sd_models.reload_model_weights()))
- shared.opts.onchange("sd_hypernetwork", wrap_queued_call(lambda: modules.hypernetworks.hypernetwork.load_hypernetwork(shared.opts.sd_hypernetwork)))
+ shared.opts.onchange("sd_vae", wrap_queued_call(lambda: modules.sd_vae.reload_vae_weights()), call=False)
+ shared.opts.onchange("sd_vae_as_default", wrap_queued_call(lambda: modules.sd_vae.reload_vae_weights()), call=False)
+ shared.opts.onchange("sd_hypernetwork", wrap_queued_call(lambda: shared.reload_hypernetworks()))
shared.opts.onchange("sd_hypernetwork_strength", modules.hypernetworks.hypernetwork.apply_strength)
+ shared.opts.onchange("temp_dir", ui_tempdir.on_tmpdir_changed)
+
+ if cmd_opts.tls_keyfile is not None and cmd_opts.tls_keyfile is not None:
+
+ try:
+ if not os.path.exists(cmd_opts.tls_keyfile):
+ print("Invalid path to TLS keyfile given")
+ if not os.path.exists(cmd_opts.tls_certfile):
+ print(f"Invalid path to TLS certfile: '{cmd_opts.tls_certfile}'")
+ except TypeError:
+ cmd_opts.tls_keyfile = cmd_opts.tls_certfile = None
+ print("TLS setup invalid, running webui without TLS")
+ else:
+ print("Running with TLS")
# make the program just exit at ctrl+c without waiting for anything
def sigint_handler(sig, frame):
@@ -90,6 +98,15 @@ def initialize():
signal.signal(signal.SIGINT, sigint_handler)
+def setup_cors(app):
+ if cmd_opts.cors_allow_origins and cmd_opts.cors_allow_origins_regex:
+ app.add_middleware(CORSMiddleware, allow_origins=cmd_opts.cors_allow_origins.split(','), allow_origin_regex=cmd_opts.cors_allow_origins_regex, allow_methods=['*'])
+ elif cmd_opts.cors_allow_origins:
+ app.add_middleware(CORSMiddleware, allow_origins=cmd_opts.cors_allow_origins.split(','), allow_methods=['*'])
+ elif cmd_opts.cors_allow_origins_regex:
+ app.add_middleware(CORSMiddleware, allow_origin_regex=cmd_opts.cors_allow_origins_regex, allow_methods=['*'])
+
+
def create_api(app):
from modules.api.api import Api
api = Api(app, queue_lock)
@@ -111,9 +128,12 @@ def api_only():
initialize()
app = FastAPI()
+ setup_cors(app)
app.add_middleware(GZipMiddleware, minimum_size=1000)
api = create_api(app)
+ modules.script_callbacks.app_started_callback(None, app)
+
api.launch(server_name="0.0.0.0" if cmd_opts.listen else "127.0.0.1", port=cmd_opts.port if cmd_opts.port else 7861)
@@ -122,12 +142,17 @@ def webui():
initialize()
while 1:
- demo = modules.ui.create_ui(wrap_gradio_gpu_call=wrap_gradio_gpu_call)
+ if shared.opts.clean_temp_dir_at_start:
+ ui_tempdir.cleanup_tmpdr()
+
+ shared.demo = modules.ui.create_ui()
- app, local_url, share_url = demo.launch(
+ app, local_url, share_url = shared.demo.queue(default_enabled=False).launch(
share=cmd_opts.share,
- server_name="0.0.0.0" if cmd_opts.listen else None,
+ server_name=server_name,
server_port=cmd_opts.port,
+ ssl_keyfile=cmd_opts.tls_keyfile,
+ ssl_certfile=cmd_opts.tls_certfile,
debug=cmd_opts.gradio_debug,
auth=[tuple(cred.split(':')) for cred in cmd_opts.gradio_auth.strip('"').split(',')] if cmd_opts.gradio_auth else None,
inbrowser=cmd_opts.autolaunch,
@@ -136,26 +161,39 @@ def webui():
# after initial launch, disable --autolaunch for subsequent restarts
cmd_opts.autolaunch = False
+ # gradio uses a very open CORS policy via app.user_middleware, which makes it possible for
+ # an attacker to trick the user into opening a malicious HTML page, which makes a request to the
+ # running web ui and do whatever the attacker wants, including installing an extension and
+ # running its code. We disable this here. Suggested by RyotaK.
+ app.user_middleware = [x for x in app.user_middleware if x.cls.__name__ != 'CORSMiddleware']
+
+ setup_cors(app)
+
app.add_middleware(GZipMiddleware, minimum_size=1000)
if launch_api:
create_api(app)
- modules.script_callbacks.app_started_callback(demo, app)
+ modules.script_callbacks.app_started_callback(shared.demo, app)
+ modules.script_callbacks.app_started_callback(shared.demo, app)
- wait_on_server(demo)
+ wait_on_server(shared.demo)
+ print('Restarting UI...')
sd_samplers.set_samplers()
- print('Reloading extensions')
extensions.list_extensions()
- print('Reloading custom scripts')
+
+ localization.list_localizations(cmd_opts.localizations_dir)
+
+ modelloader.forbid_loaded_nonbuiltin_upscalers()
modules.scripts.reload_scripts()
- print('Reloading modules: modules.ui')
- importlib.reload(modules.ui)
- print('Refreshing Model List')
+ modelloader.load_upscalers()
+
+ for module in [module for name, module in sys.modules.items() if name.startswith("modules.ui")]:
+ importlib.reload(module)
+
modules.sd_models.list_models()
- print('Restarting Gradio')
if __name__ == "__main__":
diff --git a/webui.sh b/webui.sh
index cc06f344..04ecbf76 100755
--- a/webui.sh
+++ b/webui.sh
@@ -1,8 +1,17 @@
-#!/bin/bash
+#!/usr/bin/env bash
#################################################
# Please do not make any changes to this file, #
# change the variables in webui-user.sh instead #
#################################################
+
+# If run from macOS, load defaults from webui-macos-env.sh
+if [[ "$OSTYPE" == "darwin"* ]]; then
+ if [[ -f webui-macos-env.sh ]]
+ then
+ source ./webui-macos-env.sh
+ fi
+fi
+
# Read variables from webui-user.sh
# shellcheck source=/dev/null
if [[ -f webui-user.sh ]]
@@ -46,6 +55,18 @@ then
LAUNCH_SCRIPT="launch.py"
fi
+# this script cannot be run as root by default
+can_run_as_root=0
+
+# read any command line flags to the webui.sh script
+while getopts "f" flag > /dev/null 2>&1
+do
+ case ${flag} in
+ f) can_run_as_root=1;;
+ *) break;;
+ esac
+done
+
# Disable sentry logging
export ERROR_REPORTING=FALSE
@@ -61,7 +82,7 @@ printf "\e[1m\e[34mTested on Debian 11 (Bullseye)\e[0m"
printf "\n%s\n" "${delimiter}"
# Do not run as root
-if [[ $(id -u) -eq 0 ]]
+if [[ $(id -u) -eq 0 && can_run_as_root -eq 0 ]]
then
printf "\n%s\n" "${delimiter}"
printf "\e[1m\e[31mERROR: This script must not be launched as root, aborting...\e[0m"
@@ -134,7 +155,15 @@ else
exit 1
fi
-printf "\n%s\n" "${delimiter}"
-printf "Launching launch.py..."
-printf "\n%s\n" "${delimiter}"
-"${python_cmd}" "${LAUNCH_SCRIPT}" "$@"
+if [[ ! -z "${ACCELERATE}" ]] && [ ${ACCELERATE}="True" ] && [ -x "$(command -v accelerate)" ]
+then
+ printf "\n%s\n" "${delimiter}"
+ printf "Accelerating launch.py..."
+ printf "\n%s\n" "${delimiter}"
+ accelerate launch --num_cpu_threads_per_process=6 "${LAUNCH_SCRIPT}" "$@"
+else
+ printf "\n%s\n" "${delimiter}"
+ printf "Launching launch.py..."
+ printf "\n%s\n" "${delimiter}"
+ "${python_cmd}" "${LAUNCH_SCRIPT}" "$@"
+fi